How to join two wav files using python?

Question:

I am using python programming language,I want to join to wav file one at the end of other wav file?
I have a Question in the forum which suggest how to merge two wav file i.e add the contents of one wav file at certain offset,but i want to join two wav file at the end of each other…

And also i had a prob playing the my own wav file,using winsound module..I was able to play the sound but using the time.sleep for certain time before playin any windows sound,disadvantage wit this is if i wanted to play a sound longer thn time.sleep(N),N sec also,the windows sound wil jst overlap after N sec play the winsound nd stop..

Can anyone help??please kindly suggest to how to solve these prob…

Thanks in advance

Asked By: kaushik

||

Answers:

You could use audiolab:

import audiolab, scipy
a, fs, enc = audiolab.wavread('file1.wav')
b, fs, enc = audiolab.wavread('file2.wav')
c = scipy.vstack((a,b))
audiolab.wavwrite(c, 'file3.wav', fs, enc)
Answered By: Steve Tjoa

i use the SOX [1] library and then call it like

>>> import subprocess
>>> sound_output_path = /tmp
>>> sox_filenames = ['file.wav', 'file1.wav']
>>> subprocess.call(['sox'] + sox_filenames + ['%s/out.wav' % sound_output_path])

[1] http://sox.sourceforge.net/

Answered By: user348258

Python ships with the wave module that will do what you need. The example below works when the details of the files (mono or stereo, frame rates, etc) are the same:

import wave

infiles = ["sound_1.wav", "sound_2.wav"]
outfile = "sounds.wav"

data= []
for infile in infiles:
    w = wave.open(infile, 'rb')
    data.append( [w.getparams(), w.readframes(w.getnframes())] )
    w.close()
    
output = wave.open(outfile, 'wb')
output.setparams(data[0][0])
for i in range(len(data)):
    output.writeframes(data[i][1])
output.close()
Answered By: tom10

I’m the maintainer of pydub, which is designed to make this sort of thing easy.

from pydub import AudioSegment

sound1 = AudioSegment.from_wav("/path/to/file1.wav")
sound2 = AudioSegment.from_wav("/path/to/file2.wav")

combined_sounds = sound1 + sound2
combined_sounds.export("/output/path.wav", format="wav")

note: pydub is a light wrapper around audioop. So behind the scenes, it’s doing essentially what Tom10 mentioned

Answered By: Jiaaro

Just to build on @tom10’s answer:

from contextlib import closing

with closing(wave.open(outfile, 'wb')) as output:

    # find sample rate from first file
    with closing(wave.open(wav_files[0])) as w:
        output.setparams(w.getparams())

    # write each file to output
    for infile in wav_files:
        with closing(wave.open(infile)) as w:
            output.writeframes(w.readframes(w.getnframes()))

Instead of storing all the data then writing it at the end in one go, it writes it bit by bit. It also uses contextlib.close so you don’t have to close files.

Answered By: eggbert

I would use librosa.load and librosa.write_wav.
Check out the doc here

import librosa
import numpy as np
import librosa.display

example_audio = librosa.util.example_audio_file()
x, sr = librosa.load(example_audio, duration=5)
print('shape of x ==> ' + str(x.shape))
y, sr = librosa.load(example_audio, duration=5)
print('shape of y ==> ' + str(y.shape))
z = np.append(x,y)
print('shape of x+y = z ==> ' + str(z.shape))
librosa.output.write_wav('joined_file.wav', z, sr)

z_loaded, sr = librosa.load('joined_file.wav')
print('shape of z loaded ==> ' + str(z_loaded.shape))

Output:

shape of x ==> (110250,)

shape of y ==> (110250,)

shape of x+y = z ==> (220500,)

shape of z loaded ==> (220500,)

Answered By: penduDev

Python 3 solution:
We can do this with the standard library as shown by tom10 and eggbert’s answers.
Below is a shorter version:

  1. Only write the parameters for the first wave file. We can test the wav_out file length to see if we haven’t yet written to it. If we haven’t write the wave parameters once only.
  2. Then write frames to the wav_out as they are read from the wav_in.

    with wave.open(outfile, 'wb') as wav_out:
        for wav_path in infiles:
            with wave.open(wav_path, 'rb') as wav_in:
                if not wav_out.getnframes():
                    wav_out.setparams(wav_in.getparams())
                wav_out.writeframes(wav_in.readframes(wav_in.getnframes()))
    
Answered By: spacether

I used pysox

The wave module and many others don’t seem to support mu-law wavs.

pysox reqs that you install SoX
and update your PATH to include the directory it’s installed to.

import sox    
cbn=sox.Combiner()
sounds=[]
#PROCESS SOUND PATHS TO AN ARRAY
if len(sounds)>=2:
    print(sounds)
    cbn.build(sounds,'outputfilepath.ext','concatenate')
Answered By: Charles Hacker
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.