2013-12-19 7 views
5

.wavファイルからデータを読み込もうとしています。Python Waveバイトデータ

import wave 
wr = wave.open("~/01 Road.wav", 'r') 
# sample width is 2 bytes 
# number of channels is 2 
wave_data = wr.readframes(1) 
print(wave_data) 

これは与える:曲の "最初のフレーム" である

b'\x00\x00\x00\x00' 

を。これらの4バイトは明らかに1フレームあたりの(2チャンネル* 2バイトのサンプル幅)バイトに対応しますが、各バイトは何に対応していますか?

特に、私はそれをモノ振幅信号に変換しようとしています。

答えて

16

「フレーム」を理解したい場合は、標準のwaveファイル形式を読んでください。その文書からhttps://web.archive.org/web/20140221054954/http://home.roadrunner.com/~jgglatt/tech/wave.htm

:たとえば

「演奏」することを意味しているサンプル点すなわち、アナログコンバータ(DAC)に送信されると同時に、まとめサンプルフレームと呼ばれています。ステレオ波形の例では、2つのサンプルポイントごとに別のサンプルフレームが作成されます。これは、そのステレオの例で以下に示されています。

sample  sample    sample 
frame 0  frame 1    frame N 
_____ _____ _____ _____   _____ _____ 
| ch1 | ch2 | ch1 | ch2 | . . . | ch1 | ch2 | 
|_____|_____|_____|_____|  |_____|_____| 
_____ 
|  | = one sample point 
|_____| 

あなたはこのような何かを行うことができモノラルに変換するには、

import wave 

def stereo_to_mono(hex1, hex2): 
    """average two hex string samples""" 
    return hex((ord(hex1) + ord(hex2))/2) 

wr = wave.open('piano2.wav','r') 

nchannels, sampwidth, framerate, nframes, comptype, compname = wr.getparams() 

ww = wave.open('piano_mono.wav','wb') 
ww.setparams((1,sampwidth,framerate,nframes,comptype,compname)) 

frames = wr.readframes(wr.getnframes()-1) 

new_frames = '' 

for (s1, s2) in zip(frames[0::2],frames[1::2]): 
    new_frames += stereo_to_mono(s1,s2)[2:].zfill(2).decode('hex') 

ww.writeframes(new_frames) 

は、ステレオからモノラルに行くには何の明確な方法はありません。あなたはただ一つのチャンネルを落とすことができます。上の、私はチャンネルを平均しています。それはあなたのアプリケーションによって異なります。

+0

ありがとうございました、このリンクは非常に参考になり、面白かったです。 – jameh

+1

私はちょっとした投票や受け入れられた答えの愛を得ることができますか? –

2

あなたの質問への直接的な答えとして、2バイトは、「通常の」方法で1つの16ビット整数値を作成します。これは明示的な公式で与えられます:value = ord(data[0]) + 256 * ord(data[1])。我々は私はwavファイルでのケースだと思います 16ビット整数を(署名したい場合は、

import struct 
print(struct.unpack("HH", b"\x00\x00\x00\x00")) 
# -> gives a 2-tuple of integers, here (0, 0) 

か:しかしstructモジュールを使用すると、デコードするためのより良い方法(以降再エンコード)などのマルチバイトの整数でありますファイル)では、"HH"の代わりに"hh"を使用してください。 (私はあなたに2バイトが-32768から32767までの整数値をどのようにエンコードできるかを計算することを任せます:-)

+0

この場合、 'struct'モジュールは非常に便利です。私の答えではhex/ord/decodingの混乱よりずっと優れています。私はそれが存在していることを知らなかった。 –

+1

私はバイトがリトルエンディアンであると信じています。そのためには、 'struct構造体を使用する必要があります。unpack( " jameh

3

私はscipyを使うことをお勧めします。おそらくwavファイルを読むのは難しいかもしれませんが、一般的にWAVを読んだ後に、下流の処理を行う方が簡単です。

import scipy.io.wavfile 
fs1, y1 = scipy.io.wavfile.read(filename) 

ここから、データy1はNサンプル長であり、各列がチャネルに対応するZ列を有することになる。モノラルのwavファイルに変換するには、その変換をどのようにしたいかは言わないでください。あなたは平均を取ることができます。平均使用の場合

monoChannel = y1.mean(axis=1) 
関連する問題