web-dev-qa-db-ja.com

Pythonを使用して2つのwavファイルを結合する方法は?

pythonプログラミング言語を使用しています。他のwavファイルの最後にあるwavファイルに参加したいですか?フォーラムに質問があり、2つのwavファイルをマージする方法を提案しています。特定のオフセットで1つのwavファイルの内容ですが、2つのwavファイルを互いに最後に結合したい...

また、winsoundモジュールを使用して自分のwavファイルを再生する可能性がありました。サウンドを再生できましたが、Windowsサウンドを再生する前に一定時間time.sleepを使用しました。これは、時間より長く鳴ります。sleep(N)、N秒も、N秒がwinsound nd stopを再生した後、ウィンドウの音が重なります。

誰か助けてもらえますか??これらの問題を解決する方法を親切に提案してください...

前もって感謝します

23
kaushik

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)
2
Steve Tjoa

Pythonには、必要なことを実行する wave モジュールが付属しています。以下の例は、ファイルの詳細(モノラルまたはステレオ、フレームレートなど)が同じ場合に機能します。

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])
output.writeframes(data[0][1])
output.writeframes(data[1][1])
output.close()
46
tom10

私は pydub のメンテナーです。これは、この種のことを簡単にするように設計されています。

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")

注:pydubはaudioopの軽いラッパーです。つまり、舞台裏では、Tom10が言及したことを本質的に行っています。

21
Jiaaro

@ tom10の答えに基づいて構築するだけです:

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()))

すべてのデータを保存して最後に一度に書き込むのではなく、少しずつ書き込みます。また、contextlib.closeを使用するため、ファイルを閉じる必要はありません。

3
eggbert

私は使用しました pysox

ウェーブモジュールや他の多くのモジュールは、mu-lawwavをサポートしていないようです。

pysoxは、インストールする必要があります SoX そして、インストール先のディレクトリを含むようにPATHを更新します。

import sox    
cbn=sox.Combiner()
sounds=[]
#PROCESS SOUND PATHS TO AN ARRAY
if len(sounds)>=2:
    print(sounds)
    cbn.build(sounds,'outputfilepath.ext','concatenate')
2
Charles Hacker

Python 3ソリューション:
tom10とeggbertの回答に示されているように、標準ライブラリを使用してこれを行うことができます。
以下は短いバージョンです:

  1. 最初のWaveファイルのパラメータのみを書き込みます。 wav_outファイルの長さをテストして、まだ書き込んでいないかどうかを確認できます。ウェーブパラメータを一度だけ記述していない場合。
  2. 次に、wav_inから読み取られるフレームをwav_outに書き込みます。

    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()))
    
2
spacether

私は使うだろう librosa.loadおよびlibrosa.write_wav。ドキュメントをチェックしてください ここ

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))

出力:

xの形==>(110250、)

yの形==>(110250、)

x + yの形状= z ==>(220500、)

ロードされたzの形状==>(220500、)

1
penduDev

私はSOX [1]ライブラリを使用して、次のように呼び出します。

>>> 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/

0
user348258