web-dev-qa-db-ja.com

wavioを使用して、2チャネルのwavファイルの各チャネルを2つの異なるファイルにどのように分離しますか?または別のライブラリ?

次のスクリプトは元のファイルを正常に再生します。各チャネルを明白な方法で分離しようとしますが、機能しません。

import os
import wavio
import numpy
import pyglet

file_name = "guitarup_full.wav"

# I get the file !
File = wavio.read(file_name)
rate = File.rate
# it looks good
print File.data.shape
print rate
# and then the channels:
channel_1 = File.data[:,0]
channel_2 = File.data[:,1]
wavio.write("guitar_channel_1.wav", channel_1, rate )
wavio.write("guitar_channel_2.wav", channel_2, rate )

# now we try to play:
source =  pyglet.resource.media(file_name, streaming=False)
source_ch1 =  pyglet.resource.media("guitar_channel_1.wav", streaming=False)
source_ch2 =  pyglet.resource.media("guitar_channel_2.wav", streaming=False)

#uncomment the one you want to listen.
source.play()
#source_ch1.play()
#source_ch2.play()

pyglet.app.run()

最初はギターのように聞こえ、2番目と3番目はガウスノイズのように聞こえます。誰かがそれの何が悪いのか教えてもらえますか?

私が使用したオーディオファイルは次のとおりです。 https://www.freesounds.info/global/wav.php?fileid=11

データの形状は次のとおりです:(88471、2)レートは:44100

また、別のプレーヤーでファイルを再生すると、ガウシアンノイズという同じ結果になります。

注:pygletの使用は問題にとって不必要です。これを使用してこの問題を調査する場合は、ファイルがリソースフォルダーに登録されているフォルダーにあることを確認してください。それを行うには:

pyglet.resource.path.append("your_sounds_location")
pyglet.resource.reindex()
6
mm_

wavioコードの何が問題なのかわかりませんが、標準のPython module wave(これも使用されています)を使用してWAVチャネルを分離する方法は次のとおりですwavioによる)とnumpy:

import wave
import numpy as np

def save_wav_channel(fn, wav, channel):
    '''
    Take Wave_read object as an input and save one of its
    channels into a separate .wav file.
    '''
    # Read data
    nch   = wav.getnchannels()
    depth = wav.getsampwidth()
    wav.setpos(0)
    sdata = wav.readframes(wav.getnframes())

    # Extract channel data (24-bit data not supported)
    typ = { 1: np.uint8, 2: np.uint16, 4: np.uint32 }.get(depth)
    if not typ:
        raise ValueError("sample width {} not supported".format(depth))
    if channel >= nch:
        raise ValueError("cannot extract channel {} out of {}".format(channel+1, nch))
    print ("Extracting channel {} out of {} channels, {}-bit depth".format(channel+1, nch, depth*8))
    data = np.fromstring(sdata, dtype=typ)
    ch_data = data[channel::nch]

    # Save channel to a separate file
    outwav = wave.open(fn, 'w')
    outwav.setparams(wav.getparams())
    outwav.setnchannels(1)
    outwav.writeframes(ch_data.tostring())
    outwav.close()

wav = wave.open(WAV_FILENAME)
save_wav_channel('ch1.wav', wav, 0)
save_wav_channel('ch2.wav', wav, 1)
7
Andriy Makukha

コマンドラインでffmpegを試してください:

ステレオ入力の各チャネルを個別のモノラルファイルに出力します。

ffmpeg -i stereo.wav -map_channel 0.0.0 left.wav -map_channel 0.0.1 right.wav

私はあなたのファイルでそれを試しました、そしてそれはうまくいくようです。

pythonプログラムに含める必要がある場合は、os.system(cmd)を使用してください)

4
Marichyasana

方法1(ffmpegを使用)

Ffmpegを使用して、次のようにnチャネルの.wavを分割できます。

ffmpeg -i input.wav -map 0:1 1.wav -map 0:2 2.wav -map 0:3 3.wav........

これはpythonを使用して実行できます:

import os
os.system(ffmpeg -i 14ch.mov -map 0:1 1.wav -map 0:2 2.wav -map 0:3 3.wav........)

方法2(soxを使用)

ここ からsoxをインストールします

次にこれを試してください:

sox infile.wav outfile_left.wav remix 1
sox infile.wav outfile_right.wav remix 2

もう一度、これをpython os.systemを使用して実行できます。

2
Agile_Eagle

私のスクリプトを読んで実行するために時間を割いてくれたみんなに感謝します。ようやく解決策を見つけました。次の順序で手順を実行します。

まず、次の方法でwavioをアンインストールします。

pip uninstall wavio

次に、numpyもアンインストールします。

pip uninstall numpy

最後に、もう一度wavioをインストールします。 numpyは依存関係としてインストールされます:

pip install wavio

numpyは依存関係としてインストールされます。

Installing collected packages: numpy, wavio
Successfully installed numpy-1.14.5 wavio-0.0.4

その後、私の元のスクリプトが必要なソリューションを提供します。

@Marichyasanaが示唆するようにffmpegを使用することは、適切な回避策です。ただし、pythonライブラリ(pyglet、pythonオーディオツールなど))では、これらの出力ファイルを読み戻すときに問題が発生します。

私は人々がこの解決策が役に立てば幸いです!

2
mm_

あなたはそれを必要以上に複雑にしようとしていると思います。チャネルの分離よりもscipyの使用を気にしない場合は、次のようになります。

from scipy.io import wavfile

fs, data = wavfile.read('guitarup_full.wav')            # reading the file

wavfile.write('guitar_channel_1.wav', fs, data[:, 0])   # saving first column which corresponds to channel 1
wavfile.write('guitar_channel_2.wav', fs, data[:, 1])   # saving second column which corresponds to channel 2
1
machnic