0

New to Praat Scripting here, so I am not entirely sure if I am going about this in the most efficient manner. I am using a Praat script to extract formant values at specific time intervals like 10%, 20%, 30% ... 100%. The original script is here: https://web.mit.edu/zqi/www/uploads/1/4/8/9/14891652/get_measurements.praat

I modified the script to suit my needs: -

##get measurements.praat
##original script created by Christan Kroos, Rikke Bundgaard-Nielsen, Michael Tyler
##modified by Mark Antoniou
## C 2010 MARCS Auditory Laboratories

## edited by waterMargin_39  

===============================================================
#  1. Because of a bug in Praat 'Show intensity' cannot be scripted.
#  Open an editor on an abritrary sound and make sure that 'Show intensity' is ticked before you run this script
#  2. The comma-separated file is a .txt file. Import this into Excel and use the text import wizard to change columns to text format where necessary.
#  ================================================================

#create list of filenames
clearinfo

form Parameters
    comment Directory that contains the original stimuli
    sentence inDirectory /Users/zqi/Dropbox/BILD/MMN/experiment/Stimuli/normalized/da_s
    comment Name of the output csv file with the measurements
    sentence outFile measurements
    
endform

Create Strings as file list... fileList 'inDirectory$'/*.TextGrid

fileappend 'inDirectory$'/'outFile$'.txt sound name,
           ...segment,word,start,end,duration,
        ...10_cursor,10_F1,10_F2,10_F3,
        ...20_cursor,20_F1,20_F2,20_F3,
            ...30_cursor,30_F1,30_F2,30_F3,
        ...40_cursor,40_F1,40_F2,40_F3,
           ...50_cursor,50_F1,50_F2,50_F3,
        ...60_cursor,60_F1,60_F2,60_F3,
        ...70_cursor,70_F1,70_F2,70_F3,
        ...80_cursor,80_F1,80_F2,80_F3,
        ...90_cursor,90_F1,90_F2,90_F3,
        ...100_cursor,100_F1,100_F2,100_F3,
           ...'newline$'

#loop for all files 
nFiles = Get number of strings
for d from 1 to nFiles


    #read in sound file (aif) and textgrid
    select Strings fileList
    fileName$ = Get string... d
    dotInd = rindex(fileName$, ".")
    soundName$ = left$(fileName$, dotInd - 1)
    printline Processing file 'soundName$'...
    Read from file... 'inDirectory$'/'soundName$'.wav
    Read from file... 'inDirectory$'/'soundName$'.Textgrid



    #Get relevant information from the textgrid (exclude non-labeled segments) and do measurements

    select TextGrid 'soundName$'
    number_of_intervals = Get number of intervals... 2

    select Sound 'soundName$'
        To Formant (burg)... 0.0025 5 5500 0.025 50


    for s from 1 to 'number_of_intervals'
        select TextGrid 'soundName$'
        segment$ = Get label of interval... 2 s
    word$ = Get label of interval... 1 s

if segment$ <> ""
        startSeg = Get starting point... 2 s
            endSeg = Get end point... 2 s
            durSeg = 'endSeg' - 'startSeg'
        cursor_10 = 'startSeg' + ('durSeg' * 0.10)
        cursor_20 = 'startSeg' + ('durSeg' * 0.20)
        cursor_30 = 'startSeg' + ('durSeg' * 0.30)
        cursor_40 = 'startSeg' + ('durSeg' * 0.40)
            cursor_50 = 'startSeg' + ('durSeg' * 0.5)
        cursor_60 = 'startSeg' + ('durSeg' * 0.60)
        cursor_70 = 'startSeg' + ('durSeg' * 0.70)
        cursor_80 = 'startSeg' + ('durSeg' * 0.80)
        cursor_90 = 'startSeg' + ('durSeg' * 0.90)
        cursor_100 = 'startSeg' + ('durSeg' * 1)

            
            select Formant 'soundName$'
            
            f1_10 = Get value at time... 1 'cursor_10' Hertz Linear
            f2_10 = Get value at time... 2 'cursor_10' Hertz Linear
            f3_10 = Get value at time... 3 'cursor_10' Hertz Linear

            
            f1_20 = Get value at time... 1 'cursor_20' Hertz Linear
            f2_20 = Get value at time... 2 'cursor_20' Hertz Linear
            f3_20 = Get value at time... 3 'cursor_20' Hertz Linear

            f1_30 = Get value at time... 1 'cursor_30' Hertz Linear
            f2_30 = Get value at time... 2 'cursor_30' Hertz Linear
            f3_30 = Get value at time... 3 'cursor_30' Hertz Linear


            f1_40 = Get value at time... 1 'cursor_40' Hertz Linear
            f2_40 = Get value at time... 2 'cursor_40' Hertz Linear
            f3_40 = Get value at time... 3 'cursor_40' Hertz Linear

            f1_50 = Get value at time... 1 'cursor_50' Hertz Linear
            f2_50 = Get value at time... 2 'cursor_50' Hertz Linear
            f3_50 = Get value at time... 3 'cursor_50' Hertz Linear

            f1_60 = Get value at time... 1 'cursor_60' Hertz Linear
            f2_60 = Get value at time... 2 'cursor_60' Hertz Linear
            f3_60 = Get value at time... 3 'cursor_60' Hertz Linear


            f1_70 = Get value at time... 1 'cursor_70' Hertz Linear
            f2_70 = Get value at time... 2 'cursor­_70' Hertz Linear
            f3_70 = Get value at time... 3 'cursor_70' Hertz Linear


            f1_80 = Get value at time... 1 'cursor_80' Hertz Linear
            f2_80 = Get value at time... 2 'cursor_80' Hertz Linear
            f3_80 = Get value at time... 3 'cursor_80' Hertz Linear

            f1_90 = Get value at time... 1 'cursor_90' Hertz Linear
            f2_90 = Get value at time... 2 'cursor_90' Hertz Linear
            f3_90 = Get value at time... 3 'cursor_90' Hertz Linear

Linear

            f1_100 = Get value at time... 1 'cursor_100' Hertz Linear
            f2_100 = Get value at time... 2 'cursor_100' Hertz Linear
            f3_100 = Get value at time... 3 'cursor_100' Hertz Linear

            fileappend 'inDirectory$'/'outFile$'.txt 'soundName$',
                 ...'segment$','word$','startSeg','endSeg','durSeg',
                 ...'cursor_10','dB_10','f0_10','f1_10','f2_10','f3_10',
                 ...'cursor_20','dB_20','f0_20','f1_20','f2_20','f3_20',
                 ...'cursor_30','dB_30','f0_30','f1_30','f2_30','f3_30',
                 ...'cursor_40','dB_40','f0_40','f1_40','f2_40','f3_40',
                 ...'cursor_50','dB_50','f0_50','f1_50','f2_50','f3_50',
                 ...'cursor_60','dB_60','f0_60','f1_60','f2_60','f3_60',
                 ...'cursor_70','dB_70','f0_70','f1_70','f2_70','f3_70',
                 ...'cursor_80','dB_80','f0_80','f1_80','f2_80','f3_80',
                 ...'cursor_90','dB_90','f0_90','f1_90','f2_90','f3_90',
                 ...'cursor_100','dB_100','f0_100','f1_100','f2_100','f3_100',               ...'newline$'
        else
        endif
    endfor
    

    #clean object list 
    select all
    minus Strings fileList
    Remove
endfor

#clean object list
select all
Remove
printline --------------------------------
printline Processed all 'filetype$' files in 'inDirectory$'
fileappend 'inDirectory$'/'outFile$'.txt Processed all files in 'inDirectory$'

As for the files, I have .wav files and .TextGrid files (with matching names) in the same folder. The .TextGrid files consist of 2 tiers: Tier 1 > word, Tier 2 > phonemes. Here is an example: -

File type = "ooTextFile"
Object class = "TextGrid"

xmin = 0 
xmax = 0.8849206349206349 
tiers? <exists> 
size = 2 
item []: 
    item [1]:
        class = "IntervalTier" 
        name = "word" 
        xmin = 0 
        xmax = 0.8849206349206349 
        intervals: size = 3 
        intervals [1]:
            xmin = 0 
            xmax = 0.19022951509946012 
            text = "" 
        intervals [2]:
            xmin = 0.19022951509946012 
            xmax = 0.7314059382143127 
            text = "cat" 
        intervals [3]:
            xmin = 0.7314059382143127 
            xmax = 0.8849206349206349 
            text = "" 
    item [2]:
        class = "IntervalTier" 
        name = "phonemes" 
        xmin = 0 
        xmax = 0.8849206349206349 
        intervals: size = 6 
        intervals [1]:
            xmin = 0 
            xmax = 0.19022951509946012 
            text = "" 
        intervals [2]:
            xmin = 0.19022951509946012 
            xmax = 0.2570504845749711 
            text = "kh" 
        intervals [3]:
            xmin = 0.2570504845749711 
            xmax = 0.5603148845022901 
            text = "æ" 
        intervals [4]:
            xmin = 0.5603148845022901 
            xmax = 0.669725043313841 
            text = "x" 
        intervals [5]:
            xmin = 0.669725043313841 
            xmax = 0.7314059382143127 
            text = "t" 
        intervals [6]:
            xmin = 0.7314059382143127 
            xmax = 0.8849206349206349 
            text = "" 

However, upon running the script, this error message keeps cropping up, and I am not really sure how to debug it: -

Unknown symbol: Don't understand contents of field "Time". « ' Script line 115 not performed or completed: « f2_70 = Get value at time... 2 'cursor-_70' Hertz Linear » Please change something in the command window "Run script: Parameters", or click Cancel in that window.

I'd really appreciate it if someone could point out how to get around this (or suggest a better way to extract formant values).

1 Answer 1

1

The error message tells you almost everything you need: it gives you the line number 115 and the command that failed: f2_70 = Get value at time... 2 'cursor-_70' Hertz Linear. So you know which part of the script isn’t working. The trick is then to find why it isn’t working. The error message actually tells you that, too, but it’s so subtle it’s very, very easy to miss.

If you edit your script in the built-in Praat script editor, which is a simple, plain-text editor with no syntax highlighting or anything like that, you could probably hunt for the error forever without seeing it, but if you open your script in a real editor like Visual Studio Code (free and open-source, and there’s a Praat extension that will give you syntax highlighting), you’ll quickly see that on line 115 (actually line 117 in the file itself), there’s an invisible character that shouldn’t be there:

Invisible character

See the yellow square between cursor and _70? That’s a soft or discretionary hyphen, which is useful in typesetting (it tells the application where a word may be hyphenated at the end of a line), but has no business in coding.

If you look closely at the error message, you’ll see that in fact it says the command that failed has cursor-_70 – it’s converted the soft hyphen into a normal hyphen, and when you see it, it’s obvious it looks different from what your script looks like. But you’re easily forgiven for not spotting a rogue hyphen in an error message – we’ve all been there and done that.

The soft hyphen is clearly tripping up the parser, which seemingly converts it to a regular hyphen and then breaks down because cursor-_70 isn’t valid. If you simply remove the hyphen, the code should work (assuming there’s nothing else wrong with it, which of course I can’t verify).

This is one of the many reasons why using a designated code editor for all your scripting needs is strongly recommended.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.