Search code examples
concatenationwavpraat

praat - combine multiple wav files


I have 136 wav files named numerically (1.wav to 136. wav), plus a wav file that contains 2 seconds of silence. I would like to combine them as follows, generating several other files:

1 + silence + 2 + silence (copy) + 3 
1 + silence + 2 + silence (copy) + 4
2 + silence + 1 + silence (copy) + 3 
2 + silence + 1 + silence (copy) + 4

5 + silence + 6 + silence + (copy) + 7
5 + silence + 6 + silence + (copy) + 8
6 + silence + 5 + silence + (copy) + 7
6 + silence + 5 + silence + (copy) + 8

I have the script below, which combines the files as follows:

1 + silence + 2 + silence + (copy) + 1 (copy)
1 + silence + 2 + silence + (copy) + 2 (copy)
2 + silence + 1 + silence + (copy) + 1 (copy)
2 + silence + 1 + silence + (copy) + 1 (copy)


3 + silence + 4 + silence + (copy) + 2 (copy)
3 + silence + 4 + silence + (copy) + 3 (copy)
4 + silence + 3 + silence + (copy) + 3 (copy)
4 + silence + 3 + silence + (copy) + 4 (copy)



str = Create Strings as file list... soundlist 'directory$'/*.wav
num_file = Get number of strings

#writeInfoLine: num_file

#Copy... silence2
for i to num_file
    selectObject: str
    fileName$ = Get string: i
    #writeInfoLine: fileName$
    n_fn$ = fileName$
    num_c = number(n_fn$ - ".wav")
    n_sound_file$ = string$(num_c+1) + ".wav"


    if num_c mod 2 == 1
        cp_f1$ = fileName$ - ".wav" + "cp"
        cp_f2$ = n_sound_file$ - ".wav" + "cp"
        cp_sil1$ = "sil1"
        f_file$ = "Sound " + fileName$ - ".wav"
        s_file$ = "Sound " + n_sound_file$ - ".wav"
        f_file2$ = "Sound " + cp_f1$
        s_file2$ = "Sound " + cp_f2$
        sil_file$ = "Sound " + "silence"
        sil_file2$ = "Sound " + "sil1"
        writeInfoLine: cp_f1$
        new_f1$ = "Sound " + f_file$ + "_sil_" + s_file$ + "_sil_" + f_file$+".wav"
        new_f2$ = "Sound " + f_file$ + "_sil_" + s_file$ + "_sil_" + s_file$ + ".wav"
        new_f3$ = "Sound " + s_file$ + "_sil_" + f_file$ + "_sil_" + f_file$ + ".wav"
        new_f4$ = "Sound " + s_file$ + "_sil_" + f_file$ + "_sil_" + s_file$ + ".wav"

#########
        Read from file: directory$+ "/" + fileName$
        Read from file: directory$+ "/" + "silence.wav" 
        Read from file: directory$+ "/" + n_sound_file$
        selectObject: sil_file$
        Copy... sil1
        selectObject: f_file$
        Copy... 'cp_f1$'

        selectObject: f_file$
        plusObject: sil_file$
        plusObject: s_file$
        plusObject: sil_file2$
        plusObject: f_file2$

        Concatenate
        Save as WAV file... 'directory$'/'new_f1$'
        removeObject: f_file$, sil_file$,sil_file2$,f_file2$
#########

        Read from file: directory$+ "/" + fileName$
        Read from file: directory$+ "/" + "silence.wav" 
        Read from file: directory$+ "/" + n_sound_file$
        selectObject: sil_file$
        Copy... sil1
        selectObject: s_file$
        Copy... 'cp_f2$'




        selectObject: f_file$
        plusObject: sil_file$
        plusObject: s_file$
        plusObject: sil_file2$
        plusObject: s_file2$

        Concatenate
        Save as WAV file... 'directory$'/'new_f2$'
        removeObject: f_file$, sil_file$,sil_file2$,s_file2$

#####
        Read from file: directory$+ "/" + n_sound_file$
        Read from file: directory$+ "/" + "silence.wav" 
        Read from file: directory$+ "/" + fileName$
        selectObject: sil_file$
        Copy... sil1
        selectObject: s_file$
        Copy... 'cp_f2$'




        selectObject: s_file$
        plusObject: sil_file$
        plusObject: f_file$
        plusObject: sil_file2$
        plusObject: s_file2$

        Concatenate
        Save as WAV file... 'directory$'/'new_f3$'
        removeObject: s_file$, sil_file$,sil_file2$,s_file2$
####

        Read from file: directory$+ "/" + n_sound_file$
        Read from file: directory$+ "/" + "silence.wav" 
        Read from file: directory$+ "/" + fileName$
        selectObject: sil_file$
        Copy... sil1
        selectObject: f_file$
        Copy... 'cp_f1$'




        selectObject: s_file$
        plusObject: sil_file$
        plusObject: f_file$
        plusObject: sil_file2$
        plusObject: f_file2$

        Concatenate
        Save as WAV file... 'directory$'/'new_f4$'





    endif   

endfor

select all
    Remove

The script that I have so far divides the files into file named as an odd number and an even number. For my current purpose, the algorithm would be more complex. I would be grateful if I could get some help!


Solution

  • [Disclaimer: I am the author of the mentioned Parselmouth library]

    I am not an expert on Praat scripting, but if you are willing to use Python (and the Parselmouth library to access Praat functionality from Python), the following Python code seems to work for me:

    import glob
    import parselmouth
    
    directory = "/the/directory/of/your/choice"
    output_directory = "/the/directory/of/your/choice/output"
    
    all_files = glob.glob(directory + "/*.wav")
    n_files = len(all_files) - 1 # Number of files minus 'silence.wav'
    
    def concatenate_and_save(first, second, third):
        silence = parselmouth.Sound(directory + "/silence.wav")
        sound1 = parselmouth.Sound(directory + "/" + str(first) + ".wav")
        sound2 = parselmouth.Sound(directory + "/" + str(second) + ".wav")
        sound3 = parselmouth.Sound(directory + "/" + str(third) + ".wav")
        concatenated = parselmouth.Sound.concatenate([sound1, silence, sound2, silence, sound3])
        concatenated.save(output_directory + "/" + str(first) + "_sil_" + str(second) + "_sil_" + str(third) + ".wav", "WAV")
    
    for i in range(1, n_files+1, 4):
        concatenate_and_save(i, i+1, i+2)
        concatenate_and_save(i, i+1, i+3)
        concatenate_and_save(i+1, i, i+2)
        concatenate_and_save(i+1, i, i+3)
    

    Apologies if you needed the code as Praat script, but I do expect it will be possible and straightforward to replicate the idea of this algorithm (i.e., going in steps of 4 through the number of files and then using the right combinations of i, i+1, i+2, and i+3, and maybe use a function to not repeat yourself) in a Praat script?