Let's go through your script bit by bit:
i = 2
for i to n
Here the first line will have no effect, because the for
loop initialises its control variable to 1
by default. You should write instead for i from 2 to n
.
select topSound
plus soundObject'i'
topSound = Concatenate
This is why your sounds are being concatenated in the wrong order. In Praat, Concatenate
joins sounds in the order they appear in the Object list. Unfortunately, there are no easy ways to move objects about in the Object list. But you can solve this by copying objects, since newly created objects always appear at the bottom of the list.
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
With these two changes, your script is almost there. The remaining problem is that, because you save your files when they exceed your maximum duration, the last part (which as the remainder, will likely be shorter) never gets saved. You need to remember to save that part separately after the loop ends.
I made some other small changes, like adding a form, changing your variables into more proper arrays and updating the syntax in general (selectObject
instead of select
), but I tried to annotate them when not clear. Putting all of this together, you get something like this
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
This could further be improved by, for instance, zero-padding the numbers in your filenames, but that's out of scope. :)
Update: Here's one possibility for improvement, with a slightly different algorithm, and breaking up longer chunks into fragments no larger than your specified maximum.