1

I have a praat script that creates text grids, zooms in to a specific time, and then pauses to allow me to annotate the text grid. However, there are multiple instances in each sound file that need annotation. When I save the text grid, it only saves the last annotation, and not all of the annotations. How do I get praat to save all annotations in each text grid? Here is my script:

@instance: "s0101b", 23.295323, "file path"
@instance: "s0101b", 40.343423, "file path"
@instance: "s0101c", 80.295323, "file path"
@instance: "s0101c", 90.343423, "file path"


procedure instance: .file_name$, start_time, .dir_name$

# create a list of wav files

    strings = Create Strings as file list: "list", .dir_name$ + "/*.wav"
        numberOfFiles = Get number of strings
        for ifile to numberOfFiles
            selectObject: strings
            fileName$ = Get string: ifile
            Read from file: .dir_name$ + "/" + fileName$
        endfor
    selectObject:strings
    Remove

windowstart = start_time - 0.05
windowend = start_time + 0.50

selectObject: "Sound '.file_name$'"
To TextGrid: "annotation", "bell"

select TextGrid '.file_name$'
plus Sound '.file_name$'
View & Edit
editor TextGrid '.file_name$'

    Select... 'windowstart' 'windowend'
    Zoom to selection
    pause Add boundaries, and record
    Close


endeditor
select TextGrid '.file_name$'
Write to text file... file path/'.file_name$'_editedtext.TextGrid

endproc

writeInfoLine: "Finished!"
select all
Remove
1

Okay, so I think I see where the problem is, but I'm not completely sure about my answer. I'll give it a shot.

So it looks like everything from

selectObject: "Sound '.file_name$’” 

and down is the part where it zooms in on a sound and stuff happens, right? And the for loop before it with the strings object is just getting the list of files and whatnot, yes?

So where is .file_name$ coming from? It looks like that variable is storing the name of the file in every iteration of the strings for loop. Well, once the code has moved past the for loop, the variable is still there but only the file name in the last iteration is stored there. Basically, there’s a scope issue.

I think a solution to the problem would be to move everything before endproc into the strings for loop, just after the

Read from file: .dir_name$ + "/" + fileName$ 

line. I don’t know Praat scripting well enough to know what’ll happen if you do that, and it very well might blow up the program. But I know the solution to the problem would be to do all the editor stuff inside of at least some for loop that cycles through all the filenames. Perhaps something like this:

strings = Create Strings as file list: "list", .dir_name$ + "/*.wav"
    numberOfFiles = Get number of strings
    for ifile to numberOfFiles
        selectObject: strings
        fileName$ = Get string: ifile
        Read from file: .dir_name$ + "/" + fileName$

        windowstart = start_time - 0.05
        windowend = start_time + 0.50

        selectObject: "Sound '.file_name$'"
        To TextGrid: "annotation", "bell"

        select TextGrid '.file_name$'
        plus Sound '.file_name$'
        View & Edit
        editor TextGrid '.file_name$'

            Select... 'windowstart' 'windowend'
            Zoom to selection
            pause Add boundaries, and record
            Close

        endeditor
        select TextGrid '.file_name$'
        Write to text file... file path/'.file_name$'_editedtext.TextGrid

    endfor
selectObject:strings
Remove
0

There are a couple of problems in the design of your script, but the fundamental problem is that your procedure is doing this:

  1. Open file A
  2. Edit
  3. Save as A-edited

So when you run that procedure more than once, you are always editing the same (unmodified) file and always saving it to the same location (every time with a single change).

A better way to do this would be to separate the editing from the reading and writing of files, so you do

  1. Read file
  2. Edit file (as many times as you need, as a Praat object, not saving to disk)
  3. Save file
  4. Go to next file

This should also be more efficient, as you are reducing the number of times you are writing to disk, which is slow.

Shameless plug: it might be overkill, but you might want to take a look at some of the CPrAN plugins, some of which were written to make it easier to do this sort of thing. In particular, you might want to look at vieweach. There is also a blog post I wrote with an example use case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.