### 444.praat # mail@cgrauer.de # 30.05.2024 # All rights reserved # (c) copyright 2024 Christian Grauer ### # get the command line parameters form Input word speaker_id SSB1918 word sample_idx 0011 word pos 0 word len 0 sentence pinyin _ endform sample_id$ = speaker_id$ + sample_idx$ target_id$ = sample_id$ + "_" + pos$ # add target id to dataset csv$ = target_id$ @log: target_id$ + " - " + "New Target: " + speaker_id$ + "|" + sample_idx$ + "|" + pos$ # init global variables pathSamples$ = "../Data/SLR93.LOC/audio" pathTargets$ = "../Data/Targets" pathData$ = "../Data/Targets" truncpathTarget$ = pathTargets$ + "/" + target_id$ + "/" + target_id$ ext$ = "wav" fpSample$ = pathSamples$ + "/" + speaker_id$ + "/" + sample_id$ + "." + ext$ fpTarget$ = truncpathTarget$ + "." + ext$ fpSyllable1$ = truncpathTarget$ + "_s1" + "." + ext$ fpSyllable2$ = truncpathTarget$ + "_s2" + "." + ext$ fpSyllable3$ = truncpathTarget$ + "_s3" + "." + ext$ fpTargetData$ = truncpathTarget$ + "." + "csv" fpData$ = pathData$ + "/" + "444.csv" fpTargetsDone$ = pathData$ + "/" + "targets_done.csv" fpPhpFlag$ = "./php.stop.flag" # create the target folder if not existing createFolder: pathTargets$ createFolder: pathTargets$ + "/" + target_id$ # read sample to be analyzed @log: target_id$ + " - " + "Sample: " + fpSample$ sample = Read from file: fpSample$ # analyze sound sample and store retrieved values @analyzeSyllable: sample, "sample" # WAV im Editor anzeigen @toEditor: sample # Script pausieren, damit der User das zu isolierende Target markieren kann @userInteraction: "Target markieren: " + pinyin$ + " - Pos.: " + pos$ + " - Length: " + len$ # Start und Ende des markierten Targets ermitteln targetStart = Get start of selection targetEnd = Get end of selection @toShell # extract and store the selected sound sample (target) target = Extract part: targetStart, targetEnd, "rectangular", 1, "no" selectObject: target Save as WAV file: fpTarget$ targetStart$ = string$: targetStart targetEnd$ = string$: targetEnd @log: target_id$ + " - " + "Target: " + fpTarget$ + "|" + targetStart$ + "|" + targetEnd$ # analyze sound samples (target) and store retrieved values @analyzeSyllable: target, "target" @log: target_id$ + " - " + "Target stored as: " + fpTarget$) # open target sound in editor @toEditor: target # pause the script to mark the first syllable boundary @userInteraction: "Markiere die erste Silbengrenze" # store first syllable boundary boundary1 = Get cursor # pause the script to mark the second syllable boundary @userInteraction: "Markiere die zweite Silbengrenze" # store second syllable boundary boundary2 = Get cursor boundary1$ = string$: boundary1 boundary2$ = string$: boundary2 @log: target_id$ + " - " + "Syllable boundaries: " + boundary1$ + "|" + boundary2$ @toShell @getStartEnd: target # cut out the three sound samples (syllables) selectObject: target syllable1 = Extract part: getStartEnd.start, boundary1, "rectangular", 1, "no" selectObject: target syllable2 = Extract part: boundary1, boundary2, "rectangular", 1, "no" selectObject: target syllable3 = Extract part: boundary2, getStartEnd.end, "rectangular", 1, "no" # store the three sound samples (syllables) selectObject: syllable1 Save as WAV file: fpSyllable1$ selectObject: syllable2 Save as WAV file: fpSyllable2$ selectObject: syllable3 Save as WAV file: fpSyllable3$ # analyze sound samples and store retrieved values @analyzeSyllable: syllable1, "s1" @analyzeSyllable: syllable2, "s2" @analyzeSyllable: syllable3, "s3" # write target_id to targets-done-file appendFileLine: fpTargetsDone$, target_id$ # Alle Objekte schließen @close: sample @close: target @close: syllable1 @close: syllable2 @close: syllable3 # # Prozeduren # # # analyzes a sound object for pitch data, stores pitch listing # procedure analyzeSyllable: .object, .idx$ # prepare variables # fpPitchListing$ = truncpathTarget$ + "_" + .idx$ + "_pitch" + ".csv" # fpTimesListing$ = truncpathTarget$ + "_" + .idx$ + "_times" + ".csv" fpPitchListing$ = truncpathTarget$ + "_" + .idx$ + "_data" + ".csv" fpPicture$ = truncpathTarget$ + "_" + .idx$ + "_picture" + ".png" # get parameters from sound object for pitch range # cf. Looze (2010) select .object To Pitch... 0.01 60 700 lower = Get quantile... 0 0 0.25 Hertz mmin = 0.75 * lower upper = Get quantile... 0 0 0.75 Hertz mmax = 2 * upper Remove # get pitch and intensity objects select .object .objectPitch = To Pitch: 0.001, mmin, mmax select .object .objectIntensity = To Intensity: mmin, 0.001 # loop through 0.01-sec-frames and get time, pitch and intensity select .object @getStartEnd: .object tmax = getStartEnd.end tmin = getStartEnd.start for i to (tmax-tmin)/0.01 time = tmin + i * 0.01 selectObject: .objectPitch pitch = Get value at time: time, "Hertz", "linear" selectObject: .objectIntensity intensity = Get value at time: time, "cubic" listItem$ = fixed$(time, 2) + "|" + fixed$(pitch, 3) + "|" + fixed$(intensity, 3) appendFileLine: fpPitchListing$, listItem$ endfor # get min/max from pitch object select .objectPitch .min = Get minimum: 0, 0, "Hertz", "none" .max = Get maximum: 0, 0, "Hertz", "none" .minPos = Get time of minimum: 0, 0, "Hertz", "none" .maxPos = Get time of maximum: 0, 0, "Hertz", "none" # # get and store pitch/time listing # pitchListing# = List values in all frames... Hertz # timesListing# = List all frame times # get min/max from intensity object select .objectIntensity .minI = Get minimum: 0, 0, "parabolic" .maxI = Get maximum: 0, 0, "parabolic" .minPosI = Get time of minimum: 0, 0, "parabolic" .maxPosI = Get time of maximum: 0, 0, "parabolic" # draw pitch select .objectPitch Solid line Line width... 3 Blue Draw: 0, 0, mmin, mmax, "yes" # draw intensity select .objectIntensity Dashed line Line width... 3 Green Draw: 0, 0, 50, 80, "no" @printPicture: fpPicture$ # prepare retrieved data .min$ = string$: .min .max$ = string$: .max .minPos$ = string$: .minPos .maxPos$ = string$: .maxPos mmin$ = string$: mmin mmax$ = string$: mmax duration$ = string$: getStartEnd.duration .csv$ = target_id$ + "|" + .idx$ + "|" + duration$ + "|" + mmin$ + "|" + mmax$ + "|" + .maxPos$ + "|" + .max$ + "|" + .minPos$ + "|" + .min$ + "|" + date$() # store data to files appendFileLine: fpData$, .csv$ appendFileLine: fpTargetData$, .csv$ # time/pitch/intensity stored already above in loop @close: .objectIntensity @close: .objectPitch endproc # # pauses the script for interaction or for exiting # procedure userInteraction: .message$ beginPause: .message$ .action = endPause: "Exit", "Abbrechen", "Weiter", 3 if .action == 1 @log: target_id$ + " - " + "System script abort by user!" @phpStop exitScript() elsif .action == 2 @log: target_id$ + " - " + "Praat script abort by user!" exitScript() endif endproc # # get start and end time of a sound object # procedure getStartEnd: .object @toEditor: .object .soundinfo$ = Sound info .start = extractNumber (.soundinfo$, "Start time:") .end = extractNumber (.soundinfo$, "End time:") .duration = .end - .start @toShell endproc # # select a sound object and switch to the editor # procedure toEditor: .object # Sample im Editor aktivieren selectObject: .object View & Edit editor: .object endproc # # switch back to the shell (Praat objects window) # procedure toShell Close endeditor endproc # # save picture content to file and clean it # procedure printPicture: .fp$ Save as 600-dpi PNG file: .fp$ Erase all endproc # # close a given object and remove it from Praat objects window # procedure close: .object selectObject: .object Remove endproc # # write given content to a log file # procedure log: .content$ appendFileLine("444.log", date$() + ": " + .content$) endproc # # create a file as flag for PHP to stop execution # procedure phpStop: appendFileLine(fpPhpFlag$, "System script abort by user!") endproc