# clear debug output of previous runs clearinfo form Settings # sentence Interval_tiers Mary John # sentence Point_tiers bell # optionmenu If_TextGrid_already_exists: 1 # option skip the sound file # option create a TextGrid with a different filename # option open and edit the existing TextGrid word Sound_file_extension .wav comment Press OK to choose a directory of sound files to annotate. endform # select directory to read from directory$ = chooseDirectory$: "Choose a directory with 'sound_file_extension$' ... files to annotate." @getFiles: directory$, sound_file_extension$ # Create the output file and write the first line. outputPath$ = directory$+"/formants.csv" #appendInfoLine: outputPath$ writeFileLine: "'outputPath$'", "file,midpoint,duration,phoneme,F1_20,F1_50,F1_80,F2_20,F2_50,F2_80,F3_20,F3_50,F3_80" # loop through files for i to getFiles.length soundfile = Read from file: getFiles.files$ [i] @getTextGrid: getFiles.files$ [i] selectObject: soundfile, getTextGrid.textgrid # Do analysis here # Extract the names of the Praat objects thisSound$ = selected$("Sound") thisTextGrid$ = selected$("TextGrid") # Extract the number of intervals in the phoneme tier select TextGrid 'thisTextGrid$' numberOfPhonemes = Get number of intervals: 1 appendInfoLine: "There are ", numberOfPhonemes, " intervals." # Create the Formant Object select Sound 'thisSound$' To Formant (burg)... 0 5 5000 0.025 50 # Loop through each interval on the phoneme tier. for thisInterval from 1 to numberOfPhonemes #appendInfoLine: thisInterval # Get the label of the interval select TextGrid 'thisTextGrid$' thisPhoneme$ = Get label of interval: 1, thisInterval # check for monophthongs # can't do this elegantly due to the limits of Praat Scripts #monophthongs$# = { "AA", "AE" } #if index_regex (thisPhoneme$, "(AA|AE)") #lexical_set$ = "a1|a2|a3|a4|a5|aa|ai1|ai2|ai3|ai4|ai5|an1|an2|an3|an4|an5|ang1|ang2|ang3|ang4|ang5|ao1|ao2|ao3|ao4|ao5|b|c|ch|d|e1|e2|e3|e4|e5|ee|ei1|ei2|ei3|ei4|ei5|en1|en2|en3|en4|en5|eng1|eng2|eng3|eng4|eng5|er2|er3|er4|er5|f|g|h|i1|i2|i3|i4|i5|ia1|ia2|ia3|ia4|ia5|ian1|ian2|ian3|ian4|ian5|iang1|iang2|iang3|iang4|iang5|iao1|iao2|iao3|iao4|iao5|ie1|ie2|ie3|ie4|ie5|ii|in1|in2|in3|in4|in5|ing1|ing2|ing3|ing4|ing5|iong1|iong2|iong3|iong4|iong5|iu1|iu2|iu3|iu4|iu5|ix1|ix2|ix3|ix4|ix5|iy1|iy2|iy3|iy4|iy5|iz4|iz5|j|k|l|m|n|o1|o2|o3|o4|o5|ong1|ong2|ong3|ong4|ong5|oo|ou1|ou2|ou3|ou4|ou5|p|q|r|s|sh|t|u1|u2|u3|u4|u5|ua1|ua2|ua3|ua4|ua5|uai1|uai2|uai3|uai4|uai5|uan1|uan2|uan3|uan4|uan5|uang1|uang2|uang3|uang4|uang5|ueng1|ueng3|ueng4|ueng5|ui1|ui2|ui3|ui4|ui5|un1|un2|un3|un4|un5|uo1|uo2|uo3|uo4|uo5|uu|v1|v2|v3|v4|v5|van1|van2|van3|van4|van5|ve1|ve2|ve3|ve4|ve5|vn1|vn2|vn3|vn4|vn5|vv|x|z|zh" #lexical_set$= "AA|AE|AH|AO|AW|AX|AY|EH|ER|EY|IH|IX|IY|OW|OY|UH|UW|UX" lexical_set$="AH|IH|IY|ER|EH|AE|AA|AO|UW|UH" if index_regex (thisPhoneme$, "'lexical_set$'") #if startsWith(thisPhoneme$, "AA") = 1 or startsWith(thisPhoneme$, "AE") = 1 #appendInfoLine: thisPhoneme$ # Find the midpoint. # we're using proportional distance now (20, 50, 80 percent duration) thisPhonemeStartTime = Get start point: 1, thisInterval thisPhonemeEndTime = Get end point: 1, thisInterval duration = thisPhonemeEndTime - thisPhonemeStartTime point20 = thisPhonemeStartTime + 0.2 * duration point80 = thisPhonemeStartTime + 0.8 * duration point50 = thisPhonemeStartTime + duration/2 # Extract formant measurements select Formant 'thisSound$' f1_20 = Get value at time... 1 point20 Hertz Linear f1_50 = Get value at time... 1 point50 Hertz Linear f1_80 = Get value at time... 1 point80 Hertz Linear f2_20 = Get value at time... 2 point20 Hertz Linear f2_50 = Get value at time... 2 point50 Hertz Linear f2_80 = Get value at time... 2 point80 Hertz Linear f3_20 = Get value at time... 3 point20 Hertz Linear f3_50 = Get value at time... 3 point50 Hertz Linear f3_80 = Get value at time... 3 point80 Hertz Linear #f2 = Get value at time... 2 midpoint Hertz Linear #f3 = Get value at time... 3 midpoint Hertz Linear # Get the word interval and then the label select TextGrid 'thisTextGrid$' # thisWordInterval = Get interval at time: 1, point50 # thisWord$ = Get label of interval: 1, thisWordInterval # Save to a spreadsheet appendFileLine: "'outputPath$'", ...thisSound$, ",", ...point50, ",", ...duration, ",", ...thisPhoneme$, ",", ...f1_20, ",", ...f1_50, ",", ...f1_80, ",", ...f2_20, ",", ...f2_50, ",", ...f2_80, ",", ...f3_20, ",", ...f3_50, ",", ...f3_80 # ...f2, ",", # ...f3 endif endfor # This is stupid, but I don't know a better way to remove the formant object select Formant 'thisSound$' Remove removeObject: getTextGrid.textgrid removeObject: soundfile endfor procedure getTextGrid: .soundfile$ .path$ = replace$: .soundfile$, sound_file_extension$, ".TextGrid", 0 .textgrid = Read from file: .path$ endproc procedure getFiles: .dir$, .ext$ .obj = Create Strings as file list: "files", .dir$ + "/*" + .ext$ .length = Get number of strings for .i to .length .fname$ = Get string: .i .files$ [.i] = .dir$ + "/" + .fname$ endfor removeObject: .obj endproc