### Description ## This script loops through all textgrids in a folder, within each textgrid through all intervals of a specified tier ## For either all labelled intervals or for all intervals with a specified label, ## it extracts ## (1) the beginning and the end of the interval ## (2) its durations, in milliseconds ## (3) the peak intensity (max_dB) ## (4) the minimum intensity (min_dB) ## (5) the mean intensity (mean_dB) ## (6) the time of intensity minimum and maximum ## (7) the same intensity measures (except time) for only the centre 50% of the vowel duration ## (8) the minimum f0 (in Hz) ## (9) the maximum f0 (in Hz) ##(10) the time of the f0 minimum and maximum, respectively ##(11) f0 at 10 equidistant points (can be used to create avarage time-normalized f0 contours) ##(12) time for these 10 equidistant points ##(13) optionally: the labels of parallel intervals on two other tiers, ## for example, when measuring vowels, you might want to record which words and syllables they belong to. ## In this case, the script also measures beginning, end and duration of those intervals. ## ## To run this script, you will have to have sound files with accompanying textgrids (in the same or different folders). ## Optionally, the script can also use (manually edited) pitch objects. ## Where no pitch objects exist, the script will create them. ## The script assumes that the file name (minus the extension) is the exact same for ## corresponding sounds, textgrids and (where they exist) pitch objects. ## Newly created pitch objects will be saved. ## ###End of description ## Based on MeasureIntensity-5.txt, downloaded from http://www.holgermitterer.eu/HM/duration_max_min_mean_intensity_MPI.script ## This script is adapted from Catherine Crosswhite's webpage and modified by Taehogn Cho and Holger Mitterer. ###### # Anja's changes # - Also measures intensity for only the centre of the segment (mid 50%) # - Also records time of intensity min and max # - Added measurements of f0 maximum, minimum and f0 at 10 equidistant point (for average contours) # - Also records labels on other tiers, so that we can for example output the word and syllable labels when measuring vowels # - Made it possible to have two different directories for sounds and textgrids # - Made textgrid the primary object (since we might have some sounds we don't want # to analyse and for which we accordingly didn't make any textgrids) # - Made measurements possible for other tiers than tier 1 # - The user has to define the name and location of the output file # - To fit the procedure, made variable referring to individual files in the file list # called string$, not object_name$ # - Changed writing output command, because fileappend does not work for me for some reason # Anja Arnhold, October 2018 ### # Updated November 2023 # - Script now also measures mean f0 over the whole interval, as well as during the mid 50% # - Script also puts out the interval number of the "word" and of the "syllable" in which the measured segment is located ### ############### ### Begin script ## Specify the directory containing your sound files in the next line: form Specify_path comment Where are the text grids (and sounds)? sentence directory YourPathHere comment Where are the sounds? - Leave empty if they are in the same directory sentence sound_path comment If there are pitch objects, where are they? sentence pitch_path comment In which tier are the relevant units segmented? positive tier comment Do you want measurements for all labelled intervals? boolean measureAllLabelled 1 comment If not, what is the label of intervals you want measured? sentence labelToBeMeasured comment Are there other labels you want to record (e.g. in which word or syllable the phoneme occurs)? comment If there are no other labels, leave this at 99. positive wordtier 99 positive sylltier 99 comment Pitch analysis parameters (Will be used to create pitch objects unless they exist already) positive Time_step 0.001 positive Minimum_pitch_(Hz) 70 positive Maximum_pitch_(Hz) 550 comment Give the location and the general name of the output file (".txt" is added automatically). sentence outputpath sentence output_file prosodyMeasurements comment ACHTUNG! An existing file of the same name will be deleted. endform if pitch_path$ = "" pitch_path$ = directory$ endif if measureAllLabelled = 0 and labelToBeMeasured$ = "" pause Intensity will be measured only for unlabelled intervals - Is this what you want? endif # Delete existing output file filedelete 'outputpath$'/'output_file$'.txt header_row$ = "Filename'tab$'Word'tab$'WordInterval'tab$'Syllable'tab$'SylInterval'tab$'SegIntervalNr'tab$'Vowel'tab$'Begin'tab$'End'tab$'Duration_in_ms'tab$' ...Max_dB'tab$'Min_dB'tab$'TimeMax_dB'tab$'TimeMin_dB'tab$'Mean_dB'tab$'Centre_mean_dB'tab$'Centre_max_dB'tab$'Centre_min_dB'tab$'Word_beg'tab$'Word_end'tab$'Word_dur_ms'tab$' ...Syl_beg'tab$'Syl_end'tab$'Syl_dur_ms'tab$'MaxF0Hz'tab$'TimeF0Max'tab$'MinF0Hz'tab$'TimeF0Min'tab$'MeanF0'tab$'Centre_MeanF0'tab$' ...TimeF0AtPoint1'tab$'TimeF0AtPoint2'tab$'TimeF0AtPoint3'tab$'TimeF0AtPoint4'tab$'TimeF0AtPoint5'tab$'TimeF0AtPoint6'tab$' ...TimeF0AtPoint7'tab$'TimeF0AtPoint8'tab$'TimeF0AtPoint9'tab$'TimeF0AtPoint10'tab$' ...F0AtPoint1'tab$'F0AtPoint2'tab$'F0AtPoint3'tab$'F0AtPoint4'tab$'F0AtPoint5'tab$'F0AtPoint6'tab$' ...F0AtPoint7'tab$'F0AtPoint8'tab$'F0AtPoint9'tab$'F0AtPoint10'newline$'" #header_row$ = "Speaker" + tab$ + "Word" + tab$ + "Syllable" + tab$ + "SyllNr" + tab$ + "Vowel" + tab$ + "Begin" + tab$ + "End" + tab$ + "Duration_in_ms" + tab$ + "Max_dB" + tab$ + "Min_dB" + tab$ + "Mean_dB" + tab$ + "Centre_mean_dB" + tab$ + "Centre_max_dB" + tab$ + "Word_beg" + tab$ + "Word_end" + tab$ + "Word_dur_ms" + tab$ + "Syl_beg" + tab$ + "Syl_end" + tab$ + "Syl_dur_ms" + newline$ header_row$ > 'outputpath$'/'output_file$'.txt ## Now we make a list of all the text grids in the directory we're using, and put the number of ## filenames into the variable "number_of_files": Create Strings as file list... list 'directory$'/*.TextGrid number_files = Get number of strings for j from 1 to number_files select Strings list current_token$ = Get string... 'j' Read from file... 'directory$'/'current_token$' string$ = selected$ ("TextGrid") ### Open sound (from same or different directory) if sound_path$ = "" Read from file... 'directory$'/'string$'.wav else Read from file... 'sound_path$'/'string$'.wav endif ### Open pitch object if existing, or create it pitchfile$ = "'pitch_path$'/'string$'.Pitch" if fileReadable (pitchfile$) Read from file... 'pitchfile$' else To Pitch... time_step minimum_pitch maximum_pitch select Pitch 'string$' Write to binary file... 'pitch_path$'/'string$'.Pitch endif ### Make intensity object select Sound 'string$' To Intensity... 50 0 ### Identify interval for which duration and itensity are to be measured select TextGrid 'string$' number_of_intervals = Get number of intervals... tier for b from 1 to number_of_intervals select TextGrid 'string$' interval_label$ = Get label of interval... tier 'b' labelStart$ = left$(interval_label$,1) if measureAllLabelled = 1 and interval_label$ <> "" and labelStart$ <> "." measure = 1 elsif measureAllLabelled = 0 and interval_label$ = labelToBeMeasured$ measure = 1 else measure = 0 endif ### Measurements ### Duration if measure = 1 begin_vowel = Get starting point... tier 'b' end_vowel = Get end point... tier 'b' duration = (end_vowel - begin_vowel) * 1000 ### Get labels of parallel intervals (e.g. word and syllable) if selected if wordtier <> 99 parallelwordinterval = Get interval at time... wordtier end_vowel-0.000000001 word$ = Get label of interval... wordtier parallelwordinterval w_beg = Get starting point... wordtier parallelwordinterval w_end = Get end point... wordtier parallelwordinterval wDur = (w_end - w_beg) * 1000 endif if sylltier <> 99 parallelsyllinterval = Get interval at time... sylltier end_vowel-0.000000001 syll$ = Get label of interval... sylltier parallelsyllinterval s_beg = Get starting point... sylltier parallelsyllinterval s_end = Get end point... sylltier parallelsyllinterval sDur = (s_end - s_beg) * 1000 endif ### Get timing for mid 50% begin_centre = begin_vowel + ((end_vowel - begin_vowel) / 4) end_centre = end_vowel - ((end_vowel - begin_vowel) / 4) ### Pitch ## Part 1: Maximum and minimum during interval select Pitch 'string$' pitchmax = Get maximum... begin_vowel end_vowel Hertz Parabolic maxTime = Get time of maximum... begin_vowel end_vowel Hertz Parabolic pitchmin = Get minimum... begin_vowel end_vowel Hertz Parabolic minTime = Get time of minimum... begin_vowel end_vowel Hertz Parabolic ## Part 2: Measure at 10 points during interval durationInSec = duration/1000 oneNinth = durationInSec/9 for t from 0 to 9 timef0Point = begin_vowel+t*oneNinth select Pitch 'string$' x = t+1 f0Point'x' = Get value at time... timef0Point Hertz Linear timeF0Point'x' = timef0Point endfor ## Part 3: Mean f0 during whole interval and for middle 50% select Pitch 'string$' meanF0 = Get mean... begin_vowel end_vowel Hertz centre_meanF0 = Get mean... begin_centre end_centre Hertz ### Intensity select Intensity 'string$' max_dB = Get maximum... begin_vowel end_vowel Parabolic timeMax_dB = Get time of maximum... begin_vowel end_vowel Parabolic min_dB = Get minimum... begin_vowel end_vowel Parabolic timeMin_dB = Get time of minimum... begin_vowel end_vowel Parabolic mean_dB = Get mean... begin_vowel end_vowel ### Intensity for centre / mid 50% # Measure select Intensity 'string$' centre_max_dB = Get maximum... begin_centre end_centre Parabolic centre_min_dB = Get minimum... begin_centre end_centre Parabolic centre_mean_dB = Get mean... begin_centre end_centre measurements$ = "'string$''tab$''word$''tab$''parallelwordinterval''tab$''syll$''tab$''parallelsyllinterval''tab$''b''tab$''interval_label$''tab$' ...'begin_vowel''tab$''end_vowel''tab$''duration''tab$''max_dB''tab$''min_dB''tab$''timeMax_dB''tab$''timeMin_dB''tab$''mean_dB''tab$' ...'centre_mean_dB''tab$''centre_max_dB''tab$''centre_min_dB''tab$''w_beg''tab$''w_end''tab$''wDur''tab$' ...'s_beg''tab$''s_end''tab$''sDur''tab$''pitchmax''tab$''maxTime''tab$''pitchmin''tab$''minTime''tab$''meanF0''tab$''centre_meanF0''tab$' ...'timeF0Point1''tab$''timeF0Point2''tab$''timeF0Point3''tab$''timeF0Point4''tab$''timeF0Point5''tab$''timeF0Point6''tab$' ...'timeF0Point7''tab$''timeF0Point8''tab$''timeF0Point9''tab$''timeF0Point10''tab$' ...'f0Point1''tab$''f0Point2''tab$''f0Point3''tab$''f0Point4''tab$''f0Point5''tab$''f0Point6''tab$' ...'f0Point7''tab$''f0Point8''tab$''f0Point9''tab$''f0Point10''newline$'" measurements$ >> 'outputpath$'/'output_file$'.txt endif endfor # By this point, we have gone through all the intervals for the current # textgrid, and written all the appropriate values to our log file. We are now ready to go on to # the next file, so we can get rid of any objects we no longer need, and end our for loop select all minus Strings list Remove endfor # And at the end, a little bit of clean up and a message to let you know that it's all done. select all Remove clearinfo print All 'number_files' files have been processed. ## written by Katherine Crosswhite & modified by Taehong Cho & Holger Mitterer & Anja Arnhold