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

How to save manipulated WAV files in object list?

我遇到以下问题:我想对 240 个 WAV 文件进行低通滤波。该脚本 运行 仅在创建低通滤波声音并显示在对象列表(“..._band”)中之前。但是,Praat 不会将它们导出为 WAV 文件。选择输出文件夹后,我收到警告消息 "Command 'Get number of strings' not available for current selection"。

简而言之,我的问题是如何使用新文件名将 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.

乍一看,该命令不可用,因为当您到达脚本中的那个点时,selection 是空的。它是空的,因为在第一个循环结束时,您 select 您的 Strings 对象然后 Remove 它。

更一般地说,您的脚本没有正确处理对象 selection,这在 Praat 中是一个大问题,因为可用的命令会根据活动的 selection 而变化。

因此,即使您删除了 Remove 列表所在的行,您在第二次 运行 Get number of strings 时也会遇到问题,因为到那时您已经更改了 select离子。即使您删除了该行(您并不真正需要),当您在 运行 selected("Sound") 之后 仍然 遇到问题38=]ing Strings 对象,因为到那时你将没有任何 selected Sound 对象(无论如何你之前没有它们)。

您的脚本的一个更惯用的版本,它也在一个循环中 运行s,其中声音被一个一个地读取、过滤和删除(这也更节省内存)看起来像这样:

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

适用于多个 selected Sound 对象。

如果您绝对需要循环(即,如果您要处理非常大的文件集),您可能也有兴趣使用 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