Давайте пройдемся по вашему сценарию по частям:
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
Это можно было бы дополнительно улучшить, например, заполнив нулями числа в ваших именах файлов, но это выходит за рамки. :)
Обновление: вот один из вариантов улучшения с немного другим алгоритмом и нарушением разбивайте более длинные куски на фрагменты, размер которых не превышает указанного вами максимума.
person
jja
schedule
26.02.2016