2012-03-13 3 views
4

FFTを使用して信号の周波数を取得しようとしていましたが、これに対処するのに問題があります。私は、Python 2.7でそれを実装する問題に遭遇しましたPythonでFFTを使用してオーディオ信号を分析しよう

http://macdevcenter.com/pub/a/python/2001/01/31/numerically.html?page=2

しかし:私はここで、信号を分析し、プロットするためにFFTを使用しての話サイトを見つけました。編集私は改善されたバージョンでコードを更新しました。これは実際には動作し、グラフに波形をゆっくりとプロットします。私はこれがフレームを読み取る正しい方法であるかどうか疑問に思っています。 - 偶数番号の配列インデックスは左チャンネル用です(奇数番号は右用です)。

だから、私は多くのフレームを読んでくださいが、それをサンプルの幅で割って、ステレオならば左チャンネルのフレームを1つおきにサンプリングするのでしょうか?

import scipy 
import wave 
import struct 
import numpy 
import pylab 

fp = wave.open('./music.wav', 'rb') 

samplerate = fp.getframerate() 
totalsamples = fp.getnframes() 
fft_length = 256 # Guess 
num_fft = (totalsamples/fft_length) - 2 

#print (samplerate) 

temp = numpy.zeros((num_fft, fft_length), float) 

leftchannel = numpy.zeros((num_fft, fft_length), float) 
rightchannel = numpy.zeros((num_fft, fft_length), float) 

for i in range(num_fft): 

tempb = fp.readframes(fft_length/fp.getnchannels()/fp.getsampwidth()); 

up = (struct.unpack("%dB"%(fft_length), tempb)) 

temp[i,:] = numpy.array(up, float) - 128.0 

temp = temp * numpy.hamming(fft_length) 

temp.shape = (-1, fp.getnchannels()) 

fftd = numpy.fft.fft(temp) 

pylab.plot(abs(fftd[:,1])) 

pylab.show() 

私がロードしている音楽は、自分で作ったものです。

EDIT:これで、オーディオファイルを読み込み、現在の数をチャンネル数と1フレームあたりのビット数で割ります。私はこれを行うことによってデータを失っていますか?これは、私がすべてのデータを得ることができる唯一の方法です。そうしないと、ファイルハンドラがstruct.unpack関数を読み込むためのデータが多すぎます。また、私は右チャンネルから左チャンネルを分離しようとしています(各チャンネルのFFTデータを取得します)。これをどうやってやりますか?

+0

'len(tempb)'のチェックを実装してみてください。 http://docs.python.org/library/struct.html#struct.unpackによれば正確に正しい長さでなければならず、 'readframes'は' fft_length'バイトまで読むでしょう。 – bkconrad

答えて

0

私はscipyのバージョンのnumpy/numarrayを長時間使っていませんが、関数frombufferを探しています。 struct.unpackですべてのデータをシャッフルしようとするよりも使いやすいです。例はnumpyを使用してデータを読み込む:

fp = wave.open('./music.wav', 'rb') 
assert fp.getnchannels() == 1, "Assumed 1 channel" 
assert fp.getsampwidth() == 2, "Assuming int16 data" 
numpy.frombuffer(fp.getnframes(fp.readframes()), 'i2') 

ファイルは、それらの異なるデータ型と複数のチャンネルを持っているので、開梱時にその認識することができ、波があることに留意してください。

+0

提案していただきありがとうございます。私はこれを試しましたが、別のエラーが発生しました - ValueError:オペランドをシェイプと共にブロードキャストできませんでした(512)(256)<その他の提案ですか?私はおそらく正方形から始めて、バッファにサウンドファイルを読み込むコア機能の詳細を学ぶ必要があります... – SolarLune

+0

私は正方形から始めることについては知らないが、APIについて少し学ぶのは良いでしょう。彼らが何をしているのかを試しています。前述のエラーを処理するには、配列に対してスライスを実行し、 '.shape'属性を適切に設定することができます。 –

+0

シェーンの提案をありがとう、私は少し読んで、それを動作させることができた。しかし、私は別々の左右のチャンネルを読むことができるようにしたいと思います - あなたはそれがどのように正確に動作するか知っていますか?私がファイルからフレームを読み取ることができた唯一の方法は、フレームの総数をバイト数とチャンネル数で除算してモノラルにすることでした...?または結果の配列がまだステレオになっていますか? – SolarLune

関連する問題