Scripting 7.2. Scripting an editor from within

This section will show how you can permanently extend the functionality of an editor.

As an example, consider the following problem: you want to see a graphic representation of the spectrum of the sound around the cursor position in the SoundEditor. To achieve this, follow these steps:

1. Create a Sound.
2. View it in a SoundEditor by clicking View & Edit.
3. Choose New editor script from the File menu in the SoundEditor. The resulting ScriptEditor will have a name like "untitled script [Sound hallo]".
4. Type the following lines into the ScriptEditor:
       cursor = Get cursor
       Select: cursor - 0.02, cursor + 0.02
       Extract selected sound (windowed): "slice", "Kaiser2", 2, "no"
    endeditor
    To Spectrum: "yes"
    View & Edit

If you choose Run from the Run menu in the ScriptEditor, a region of 40 milliseconds around the current cursor position in the SoundEditor will become selected. This piece will be copied to the list of objects, after applying a double Kaiser window (total length 80 ms). Thus, a Sound named "slice" will appear in the list. Subsequently, a Spectrum object also called "slice" will appear in the list, and a SpectrumEditor titled "Spectrum slice" will finally appear on your screen.

5. Save the script to disk, e.g. as /us/miep/spectrum.praat. The title of the ScriptEditor will change accordingly.
6. Since you will want this script to be available in all future SoundEditors, you choose Add to menu... from the File menu. For the Window, you specify "SoundEditor" (this is preset). For the Menu, you may want to choose "Spectrum" instead of the preset value ("File"). For the name of the Command, you type something like "Show spectrum at cursor" (instead of "Do it..."). Then you click OK.

The command will be visible in every SoundEditor that you create from now on. To see this, close the one visible SoundEditor, select the original Sound, choose View & Edit again, and inspect the Spectrum menu. You can now view the spectrum around the cursor just by choosing this menu command.

After you leave Praat and start it again, the command will continue to appear in the SoundEditor. If you don't like the command any longer, you can remove it with the ButtonEditor, which you can start by choosing Buttons from the Preferences submenu of the Praat menu.

Improving your script

The above spectrum-viewing example has a number of disadvantages. It clutters the object list with a number of indiscriminable Sounds and Spectra called "slice", and the spectrum is shown up to the Nyquist frequency while we may just be interested in the lower 5000 Hz. Furthermore, the original selection in the SoundEditor is lost.

To improve the script, we open it again with Open editor script... from the File menu in the SoundEditor. After every change, we can run it with Run from the Run menu again; alternatively, we could save it (with Save from the File menu) and choose our new "Show spectrum at cursor" button (this button will always run the version on disk, never the one viewed in a ScriptEditor).

To zoom in on the first 5000 Hz, we add the following code at the end of our script:

editor: "Spectrum slice"
    Zoom: 0, 5000

To get rid of the "Sound slice", we can add:

endeditor
removeObject: "Sound slice"

Note that endeditor is needed to change from the environment of a SpectrumEditor to the environment of the object & picture windows.

If you now choose the "Show spectrum at cursor" button for several cursor positions, you will notice that all those editors have the same name. To remedy the ambiguity of the line editor Spectrum slice, we give each slice a better name. For example, if the cursor was at 635 milliseconds, the slice could be named "635ms". We can achieve this by changing the extraction in the following way:

milliseconds = round (cursor*1000)
Extract selection sound (windowed): string$ (milliseconds) + "ms", "Kaiser2", 2, "no"

The names of the Sound and Spectrum objects will now have more chance of being unique. Two lines will have to be edited trivially.

Finally, we will reset the selection to the original. At the top of the script, we add two lines to remember the positions of the selection markers:

start = Get start of selection
end = Get end of selection

At the bottom, we reset the selection:

editor
    Select: start, end

Note that the editor directive if not followed by the name of an editor, returns the script to the original environment.

The complete script is:

    start = Get start of selection
    end = Get end of selection
    cursor = Get cursor
    Select: cursor - 0.02, cursor + 0.02
    # Create a name. E.g. "670ms" means at 670 milliseconds.
    milliseconds = round (cursor*1000)
    Extract windowed selection: string$ (milliseconds) + "ms", "Kaiser2", 2, "no"
endeditor
To Spectrum: "yes"
View & Edit
editor: "Spectrum " + string$ (milliseconds) + "ms"
    Zoom: 0, 5000
endeditor
removeObject: "Sound " + string$ (milliseconds) + "ms"
editor
    Select: start, end

This script is useful as it stands. It is good enough for safe use. For instance, if the created Sound object has the same name as an already existing Sound object, it will be the newly created Sound object that will be removed by removeObject, because in case of ambiguity removeObject always removes the most recently created object of that name.

Links to this page


© ppgb, January 13, 2014