Topics

Divide soundfiles into equal chunks of predetermined duration and write as wav files

Irene dlCP
 

Hi,

I am trying to pull all the wav files in a folder, divide each file into chunks of a predefined duration (e.g., 160 ms) and write the resulting part-sounds as new wav files. I started from one of J.J. Atria's scripts made public (thank you!) and modified it. The altered script creates the wav parts, but only the first one actually has sound.
I'd be grateful for any input on what the problem with the script is. I imagine it has to do with this command: end = if p = number_of_parts then total_duration else part_length * p fi
The original script allowed for splitting the file based on length as well as on a predefined number of parts. I got rid of the latter option in previous parts of the script, but my attempts to do so here have not been successful.
Thank you for your help.

clearinfo

form Enter directory and search string

sentence Path /XXXX/

endform

 

form Split Sounds...

option length (s)

endform

 

Create Strings as file list... fileList 'path$'/*.wav

numberOfFiles = Get number of strings

 

for i to numberOfFiles

select Strings fileList

name$ = Get string... i

Read from file... 'path$'/'name$'

object_name$ = selected$ ("Sound")

total_duration = Get total duration

split_by$ = "length (s)"

part_length = 0.16

number_of_parts = ceiling(total_duration / part_length)

 

end = 0

for p to number_of_parts

start = end

end = if p = number_of_parts then total_duration else part_length * p fi

part_name$ = object_name$ + "_" + string$(p)

Extract part: start, end,"rectangular", 1, 0

Write to WAV file... 'part_name$'.wav

endfor

select all

minus Strings fileList

Remove

endfor

select Strings fileList

Remove

Boersma Paul
 

On 19 Nov 2019, at 11:20, irenedlcp <idelacruzpavia@...> wrote:

I am trying to pull all the wav files in a folder, divide each file into chunks of a predefined duration (e.g., 160 ms) and write the resulting part-sounds as new wav files.
Thanks for asking the first question on the renewed Praat User List.

The script has several problems. The first is that it is hard to read because it doesn't indent inside the loops. If my edits have the same problem, it must be due to groups.io.

A problem is your attempt to have two forms instead of one. A script can have only one fixed form (and perhaps some pause forms), so you do:

form Split sounds
sentence Path /XXXX/ [I was using a leading tab here]
positive Part_length_(s) 0.16 [I was using four leading spaces here]
endform

Also note that have Part_length as an "option" makes no sense; please read sections 1 and 2 of the scripting tutorial.

split_by$ = "length (s)"
This is not used.

part_length = 0.16
This is now superfluous, as part_length now comes directly from the form, as you intended.

number_of_parts = ceiling(total_duration / part_length)
correct.

end = 0

for p to number_of_parts

start = end

end = if p = number_of_parts then total_duration else part_length * p fi
This logic seems correct.

part_name$ = object_name$ + "_" + string$(p)
Why not just use name$ instead of object_name$?

Write to WAV file... 'part_name$'.wav
Please note that this is written to the directory of the script, not to the directory of the other sound files.

select all

minus Strings fileList

Remove
Combining "select all" with "Remove' is always incorrect. This throws away not just the sounds that you just created, but also whatever else was in the objects list when you started the script. The script writer assumed an empty list to start with, i.e. not the case of a user working interactively with objects.

As for the cause of the empty sounds (which did you mean: zero duration, or all zero amplitudes?): you should start debugging. Insert an "exitScript()" just before Remove, so that you can see whether all the Sound parts are 0.16 seconds long, which ones of them are empty, and so on. Create the smallest form of the script that will generate the error (perhaps one with a single loop), and study this. If you still don't see what is going on, ask us again.

_____

Paul Boersma
Professor of Phonetic Sciences, University of Amsterdam

Visiting address: Spuistraat 134, room 632, Amsterdam
Mail: P.O. Box 1642, 1000BP Amsterdam, The Netherlands
Website: http://www.fon.hum.uva.nl/paul/

Boersma Paul
 

On 19 Nov 2019, at 11:20, irenedlcp <idelacruzpavia@...> wrote:

Read from file... 'path$'/'name$'

...
end = 0

for p to number_of_parts

start = end

end = if p = number_of_parts then total_duration else part_length * p fi

part_name$ = object_name$ + "_" + string$(p)

Extract part: start, end,"rectangular", 1, 0

Write to WAV file... 'part_name$'.wav

endfor
The second time that you're extracting, you're extracting the part of 0.16 to 0.32 seconds from the sound that stands currently selected, which is not the original sound but the part you extracted the first time, so you get a zero-amplitude sound 0.16 seconds long.

So you have to re-select the original sound just before extracting:

form Split sounds
sentence Path /XXXX
positive Part_length_(s) 0.16
endform
fileList = Create Strings as file list: "fileList", path$ + "/*.wav"
numberOfFiles = Get number of strings
for ifile to numberOfFiles
selectObject: fileList
name$ = Get string: ifile
sound = Read from file: path$ + "/" + name$
totalDuration = Get total duration
numberOfParts = ceiling (totalDuration / part_length)
end = 0
for ipart to numberOfParts
start = end
end = if ipart = numberOfParts then totalDuration else part_length * ipart fi
selectObject: sound
part = Extract part: start, end, "rectangular", 1.0, "no"
Save as WAV file: name$ - ".wav" + "_" + string$ (ipart) + ".wav"
Remove
endfor
removeObject: sound
endfor
removeObject: fileList

This solution also takes care of the "select all" problem, by removing all objects as soon as they are no longer needed.
__

Paul Boersma
Professor of Phonetic Sciences, University of Amsterdam

Visiting address: Spuistraat 134, room 632, Amsterdam
Mail: P.O. Box 1642, 1000BP Amsterdam, The Netherlands
Website: http://www.fon.hum.uva.nl/paul/

Irene dlCP
 

Got it, thank you so much for the help and the explanations, Paul. 
Copy-pasting the script had indeed removed the indentations.

Best regards,

irene