Как сохранить измененные файлы WAV в списке объектов?

У меня следующая проблема: я хочу фильтровать 240 файлов WAV. Скрипт выполняется только до тех пор, пока не будут созданы и показаны в списке объектов ("..._band") звуки, прошедшие фильтрацию нижних частот. Однако Praat не экспортирует их в виде файлов WAV. После выбора выходной папки я получаю предупреждающее сообщение «Команда «Получить количество строк» ​​недоступна для текущего выбора».

Короче говоря, мой вопрос: как я могу сохранить звуки WAV в списке объектов по отдельности с их новыми именами файлов? См. также скриншот.

Скрипт смотрите ниже.

Большое спасибо за Вашу помощь!

Привет,

#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.

person username    schedule 16.09.2016    source источник


Ответы (1)


На первый взгляд, команда недоступна, потому что, когда вы дойдете до этой точки в сценарии, выбор будет пустым. Он пуст, потому что в конце первого цикла вы выбираете свой Strings объект, а затем Remove его.

В более общем случае ваш сценарий неправильно обрабатывает выбор объекта, что является большой проблемой в Praat, поскольку доступные команды меняются в зависимости от активного выбора.

Таким образом, даже если вы удалите строку, где вы Remove список, вы столкнетесь с проблемой при втором запуске Get number of strings, потому что к тому времени вы изменили выбор. И даже если вы удалите эту строку (которая вам на самом деле не нужна), вы все равно столкнетесь с проблемой при запуске selected("Sound") после выбора объекта Strings, потому что к тому времени у вас не будет любые выбранные Sound объекты (все равно у вас их раньше не было).

Более идиоматическая версия вашего скрипта, которая также работает в одном цикле, где звуки считываются, фильтруются и удаляются один за другим (что также более эффективно использует память), будет выглядеть так:

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

Хотя вам может быть интересно узнать, что, если вам не нужно автоматическое чтение и сохранение файла (т. е. если вы согласны с тем, что ваш сценарий работает с объектами из списка), ваш сценарий может быть сокращен до

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

который работает с несколькими выбранными объектами Sound.

Если вам абсолютно необходимо зацикливание (например, если вы будете работать с действительно большими наборами файлов), вы также можете заинтересоваться использованием vieweach plugin, with был написан, чтобы попытаться свести к минимуму этот тип шаблона (полный отказ от ответственности: я написал плагин). Я также написал об этом более длинный запись в блоге.

person jja    schedule 17.09.2016
comment
Спасибо за ваш ответ. К сожалению, это не работает с вашим предложением. - person username; 26.09.2016
comment
Я правильно определил источник проблемы, но не ее масштабы. Оказывается, у вашего скрипта было множество проблем с выбором. Я обновил свой ответ рабочей версией вашего сценария и некоторыми ссылками на дополнительные ресурсы. - person jja; 27.09.2016
comment
Большое спасибо за помощь, jja!! Теперь он работает, единственное, что я изменил, это следующее, потому что он сохранил звуки без окончания типа файла: Save as WAV file: output_dir$ + "/" + selected$("Sound") + ".wav" - person username; 29.09.2016