【问题标题】:How to save manipulated WAV files in object list?如何在对象列表中保存操纵的 WAV 文件?
【发布时间】:2016-09-16 15:06:36
【问题描述】:

我有以下问题:我想低通过滤 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.

【问题讨论】:

    标签: audio scripting praat


    【解决方案1】:

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

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

    因此,即使您删除了列表中Remove 所在的行,您在第二次运行Get number of strings 时也会遇到问题,因为此时您已经更改了选择。即使您删除了该行(您实际上并不需要),当您在选择 Strings 对象后运行 selected("Sound") 时,您仍然会遇到问题,因为到那时您不会有任何选定的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

    【讨论】:

    • 感谢您的回答。很遗憾,它不符合您的建议。
    • 我已经正确地确定了问题的根源,但没有确定问题的程度。事实证明,您的脚本在选择方面存在很多问题。我用您的脚本的工作版本和一些指向其他资源的链接更新了我的答案。
    • 非常感谢您的帮助,jja!现在它正在工作,我唯一改变的是以下内容,因为它保存了没有文件类型结尾的声音:Save as WAV file: output_dir$ + "/" + selected$("Sound") + ".wav"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 2013-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    相关资源
    最近更新 更多