如何在对象列表中保存被操纵的WAV文件?

时间:2016-09-16 15:06:36

标签: audio scripting praat

我有以下问题:我想低通过滤240个WAV文件。该脚本仅在创建低通滤波声音并显示在对象列表中时运行(" ..._ band")。但是,Praat不会将它们导出为WAV文件。选择输出文件夹后,我收到警告信息"命令'获取字符串数量'不适用于当前选择"。

简而言之,我的问题是如何使用新文件名单独保存对象列表中的WAV声音?另请参阅Screenshot

脚本见下文。

非常感谢你的帮助!

问候,

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

1 个答案:

答案 0 :(得分: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感兴趣,并编写了尝试并最小化这种样板文件(完全免责声明:我写了插件)。我也写了一篇更长的blog post