0

I have the following problem: I want to low-pass filter 240 WAV files. The script is running only till the low-pass filtered sounds are created and shown in the object list ("..._band"). However, Praat does not export them as WAV files. After choosing the output folder, I get the warning message "Command 'Get number of strings' not available for current selection".

In short, my question is how can I save the WAV sounds in the object list individually with their new file names? See also Screenshot.

Script see below.

Thank you very much for your help!

Greetings,

#determine praat version
ver1$ = left$(praatVersion$, (rindex(praatVersion$, ".")-1));
ver1 = 'ver1$'
if ver1 < 5.2
    exit Please download a more recent version of Praat
endif

if ver1 == 5.2
    ver2$ = right$(praatVersion$, length(praatVersion$) - (rindex(praatVersion$, ".")));
    ver2 = 'ver2$'
    if ver2 < 4
        exit Please download a more recent version of Praat (minor)
    endif
endif

beginPause ("Low-Pass Filter Instructions")
    comment ("1. Select a folder containing the wave files to be low-pass filtered")
    comment ("2. Wave files will be low-pass filtered (0 - 400 Hz)")
    comment ("3. Select an output folder for the low-pass filtered wave files to be saved to")
    comment ("Click 'Next' to begin")
clicked = endPause("Next", 1);

#wavefile folder path
sourceDir$ = chooseDirectory$ ("Select folder containing wave files")
if sourceDir$ == ""
    exit Script exited. You did not select a folder.
else
    sourceDir$ = sourceDir$ + "/";
endif

Create Strings as file list... list 'sourceDir$'/*.wav

numberOfFiles = Get number of strings
levels$ = ""
for ifile to numberOfFiles
    select Strings list
    currentList = selected ("Strings")
    filename$ = Get string... ifile
    Read from file... 'sourceDir$'/'filename$'
    currentSound = selected ("Sound")
    filterFreqRange = Filter (pass Hann band)... 0 400 20

    select currentSound
    Remove

endfor

select currentList
Remove

#output folder path  - where the wave files get saved
outputDir$ = chooseDirectory$ ("Select folder to save wave files")
if outputDir$ == ""
    exit Script exited. You did not select a folder.
else
    outputDir$ = outputDir$ + "/";
endif

numberOfFiles = Get number of strings
for ifile to numberOfFiles
    select Strings list
    currentList = selected ("Strings")
    filename$ = Get string... ifile
    currentSound = selected ("Sound")
    endif
    Save as WAV file... 'outputDir$'/'filename$'
    select currentSound
    Remove
endfor

#clean up
select currentList
Remove

#clear the info window
clearinfo
#print success message
printline Successfully low-pass filtered 'numberOfFiles' wave files.
username
  • 3
  • 3

1 Answers1

1

At a glance, the command is not available because when you get to that point in the script the selection is empty. It is empty because at the end of the first loop, you select your Strings object and then Remove it.

More generally, your script is not handling the object selection properly, which is a big problem in Praat because available commands change depending on the active selection.

So even if you remove the line where you Remove the list, you will bump into a problem the second time you run Get number of strings because by then you have changed the selection. And even if you remove that line (which you don't really need), you'll still bump into a problem when you run selected("Sound") after selecting the Strings object, because by then you won't have any selected Sound objects (you didn't have them before anyway).

A more idiomatic version of your script, which also runs on a single loop where sounds are read, filtered, and removed one by one (which is also more memory efficient) would look like this:

form Low-Pass Filter...
    real From_frequency_(Hz) 0
    real To_frequency_(Hz) 400
    real Smoothing_(Hz) 20
    comment Leave paths empty for GUI selectors
    sentence Source_dir 
    sentence Output_dir 
endform

if praatVersion < 5204
  exitScript: "Please download a more recent version of Praat"
endif

if source_dir$ == ""
    source_dir$ = chooseDirectory$("Select folder containing wave files")
    if source_dir$ == ""
        exit
    endif
endif

if output_dir$ == ""
    output_dir$ = chooseDirectory$("Select folder to save filtered files")
    if output_dir$ == ""
        exit
    endif
endif

list = Create Strings as file list: "list", source_dir$ + "/*.wav"
numberOfFiles = Get number of strings
levels$ = ""

for i to numberOfFiles
    selectObject: list
    filename$ = Get string: i
    sound = Read from file: source_dir$ + "/" + filename$
    filtered = Filter (pass Hann band): from_frequency, to_frequency, smoothing

    Save as WAV file: output_dir$ + "/" + selected$("Sound")
    removeObject: sound, filtered
endfor

Although you might be interested to know that, if you do not need the automatic file reading and saving (ie, if you are OK with having your script work on objects from the list) your script could be reduced to

Filter (pass Hann band): 0, 400, 20

which works on multiple selected Sound objects.

If you absolutely need the looping (ie, if you'll be working on really large sets of files) you might also be interested in using the vieweach plugin, with was written to try and minimise this sort of boilerplate (full disclaimer: I wrote the plugin). I wrote a longer blog post about it as well.

jja
  • 2,058
  • 14
  • 27
  • Thank you for your answer. Unfortunately, it's not working with your suggestion. – username Sep 26 '16 at 14:31
  • I had correctly identified the source of the problem, but not its extent. It turns out your script had loads of problems with the selection. I updated my answer with a working version of your script and some links to additional resources. – jja Sep 27 '16 at 17:05
  • Thank you very much for your help, jja!! Now it is working, the only thing I changed was the following, because it saved the sounds without file type ending: `Save as WAV file: output_dir$ + "/" + selected$("Sound") + ".wav"` – username Sep 29 '16 at 07:59