【问题标题】:Using Praat scripting, how can I split a wav file by silence and then concatenate the speech clips into smaller wav files?使用 Praat 脚本,如何通过静音分割 wav 文件,然后将语音剪辑连接成更小的 wav 文件?
【发布时间】:2016-02-24 17:29:11
【问题描述】:

我正在编写一个 Praat 脚本以:

1-打开一个wav文件

2-根据静音分割wav文件

3- 根据持续时间连接间隔,以便新的 wav 片段文件每个

4- 将新的 wav 片段写入单独的 wav 文件

我在让这个脚本工作方面取得了一些进展,但我遇到了两个主要问题:

1- 在我连接段以创建前 15 秒剪辑后,我的输出停止,因此我在输出中缺少部分 wav 文件

2- 剪辑以相反的顺序连接

到目前为止,这是我的脚本。请帮忙!我是 Praat 脚本的新手,我完全被难住了..

Read from file... Desktop/englishTest.wav
name$ = selected$("Sound", 1)
outputDir$ = "Desktop/praat_output/"
To TextGrid (silences)... 100 0 -25 0.3 0.1 silent sounding
plus Sound 'name$'
Extract intervals where... 1 no "is equal to" sounding

n = numberOfSelected("Sound")

for i to n
    soundObject'i'=selected("Sound", i)
endfor

topSound = soundObject1
select topSound
durTop = Get total duration

i = 2
for i to n
    select soundObject'i'
    dur = Get total duration
    if durTop + dur <= 15
        select topSound
        plus soundObject'i'
        topSound = Concatenate
        select topSound
        durTop = Get total duration
    else
        select topSound
        Save as WAV file... 'outputDir$''name$'_'i'.wav
        topSound = soundObject'i'
        durTop = dur
    endif
endfor

【问题讨论】:

  • 如果某些探测间隔超过 15 秒会怎样?
  • @jja 如果探测间隔超过 15 秒,我希望将它们保存到自己的 wav 文件中。

标签: audio concatenation wav praat


【解决方案1】:

让我们一点一点地看一下你的脚本:

i = 2
for i to n

此处第一行将不起作用,因为for 循环默认将其控制变量初始化为1。你应该改写for i from 2 to n

select topSound
plus soundObject'i'
topSound = Concatenate

这就是您的声音以错误的顺序连接的原因。在 Praat 中,Concatenate 加入声音按照它们在对象列表中出现的顺序。不幸的是,没有简单的方法可以在对象列表中移动对象。但是你可以通过复制对象来解决这个问题,因为新创建的对象总是出现在列表的底部。

selectObject: soundObject[i]           ; Select the sound
tmp = Copy: selected$("Sound")         ; Copy (= move to bottom)
removeObject: soundObject[i]           ; Remove the original
soundObject[i] = tmp                   ; Update the object ID
selectObject: topSound, soundObject[i] ; Select the new objects
topSound = Concatenate                 ; Concatenate in the right order

通过这两个更改,您的脚本几乎就在那里。剩下的问题是,因为您在文件超过最大持续时间时保存文件,所以最后一部分(其余部分可能会更短)永远不会被保存。您需要记住在循环结束后单独保存该部分。

我做了一些其他的小改动,比如添加一个表单、将变量更改为更合适的数组以及更新一般的语法(selectObject 而不是select),但我试图在不清楚时对其进行注释。把所有这些放在一起,你会得到这样的东西

form Reticulate splines...
    sentence Sound_path  Desktop/englishTest.wav
    sentence Output_path Desktop/praat_output/
endform

sound = Read from file: sound_path$
sound$ = selected$("Sound")
silences = To TextGrid (silences):
  ... 100, 0, -25, 0.3, 0.1, "silent", "sounding"

selectObject: sound, silences
Extract intervals where:
    ... 1, "no", "is equal to", "sounding"
n = numberOfSelected("Sound")

for i to n
    soundObject[i] = selected("Sound", i)
endfor

topSound = soundObject[1]
selectObject: topSound
durTop = Get total duration

# new is a counter for the new objects we'll be making
new = 0
# Start for loop from second position
for i from 2 to n
    selectObject: soundObject[i]
    dur = Get total duration
    if durTop + dur <= 15
        # Rearrange objects in object list
        tmp = soundObject[i]
        selectObject: soundObject[i]
        soundObject[i] = Copy: selected$("Sound")
        removeObject: tmp
        previous = topSound
        selectObject: topSound, soundObject[i]
        topSound = Concatenate
        durTop = Get total duration

        # Remember to remove unwanted objects!
        removeObject: previous, soundObject[i]
    else
        # Save an array of new indices
        new += 1
        final[new] = topSound
        topSound = soundObject[i]
        durTop = dur
    endif
endfor
# Remember to add the last sound
new += 1
final[new] = topSound

# Clean up unwanted objects
removeObject: silences

# Loop through the array to rename them
nocheck selectObject: undefined
for i to new
    selectObject: final[i]
    Rename: sound$ + "_" + string$(i)

    ## You can save the objects automatically here
    ## but this is not the best design in my opinion
    # Save as WAV file: output_path$ + selected$("Sound")
endfor

# Select the newly extracted parts
nocheck selectObject: undefined
for i to new
    plusObject: final[i]
endfor

这可以通过例如零填充文件名中的数字来进一步改进,但这超出了范围。 :)

更新:Here's 一种改进的可能性,使用稍微不同的算法,将较长的块分成不大于指定最大值的片段。

【讨论】:

    猜你喜欢
    • 2011-12-12
    • 1970-01-01
    • 2017-05-14
    • 2014-12-16
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    • 1970-01-01
    • 2019-07-21
    相关资源
    最近更新 更多