2012-04-19 18 views
6

私はFFTで作業していましたが、現在はFFTでファイルからサウンド波形を取得しようとしていますが、最終的に変更しますが、その変更された波形をファイルに出力します。私は、音波のFFTを取得し、それに逆FFT関数を使用しましたが、出力ファイルはまったく発音されません。私は波形をフィルタリングしていません。周波数データを取得してファイルに戻してテストしています。同じように聞こえるはずですが、大きく違った発音になります。何か案は?Python NumPy - FFTと逆FFT?

- 編集 - 私は以来、このプロジェクトビットに取り組んできたが、まだ望ましい結果を得ていない

。出力されたサウンドファイルはノイズが多く(元のファイルには存在しなかった余分なノイズだけでなく)、もう1つのチャネルのサウンドは以前は無音だった他のチャネルにリークされています。入力サウンドファイルは、ステレオの2チャンネルファイルで、サウンドは1つのチャンネルからしか得られません。私のコードは次のとおりです:

import scipy 
import wave 
import struct 
import numpy 
import pylab 

from scipy.io import wavfile 

rate, data = wavfile.read('./TriLeftChannel.wav') 

filtereddata = numpy.fft.rfft(data, axis=0) 

print (data) 

filteredwrite = numpy.fft.irfft(filtereddata, axis=0) 

print (filteredwrite) 

wavfile.write('TestFiltered.wav', rate, filteredwrite) 

私はこれがうまくいかない理由はよく分かりません... ...?

EDIT:問題を解決するのに役立つ場合は、.pyファイルとオーディオファイルを圧縮しました。here

+3

あなたが –

+0

@Bagoを保存する前に '' filteredwrite = numpy.round(filteredwrite).astype( 'INT16')を追加してみてください - ありがとうございました!それは問題を完全に解決しました。私は、フィルタリングされたifftを 'int16'に強制して16ビット深度のサウンドファイルにすることを意味しているのだろうかと疑問に思っていましたか? – SolarLune

+0

私はwavファイルについてあまりよく分かりませんが、私はいつもそれらが圧縮されていない生データであると仮定していましたが、確かに知るためにはwavフォーマット仕様を読んでおく必要があります。 –

答えて

4
>>> import numpy as np 
>>> a = np.vstack([np.ones(11), np.arange(11)]) 

# We have two channels along axis 0, the signals are along axis 1 
>>> a 
array([[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], 
     [ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]]) 
>>> np.fft.irfft(np.fft.rfft(a, axis=1), axis=1) 
array([[ 1.1  , 1.1  , 1.1  , 1.1  , 
      1.1  , 1.1  , 1.1  , 1.1  , 
      1.1  , 1.1  ], 
     [ 0.55  , 1.01836542, 2.51904294, 3.57565618, 
      4.86463721, 6.05  , 7.23536279, 8.52434382, 
      9.58095706, 11.08163458]]) 
# irfft returns an even number along axis=1, even though a was (2, 11) 

# When a is even along axis 1, we get a back after the irfft. 
>>> a = np.vstack([np.ones(10), np.arange(10)]) 
>>> np.fft.irfft(np.fft.rfft(a, axis=1), axis=1) 
array([[ 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 
      1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 
      1.00000000e+00, 1.00000000e+00, 1.00000000e+00, 
      1.00000000e+00], 
     [ 7.10542736e-16, 1.00000000e+00, 2.00000000e+00, 
      3.00000000e+00, 4.00000000e+00, 5.00000000e+00, 
      6.00000000e+00, 7.00000000e+00, 8.00000000e+00, 
      9.00000000e+00]]) 

# It seems like you signals are along axis 0, here is an example where the signals are on axis 0 
>>> a = np.vstack([np.ones(10), np.arange(10)]).T 
>>> a 
array([[ 1., 0.], 
     [ 1., 1.], 
     [ 1., 2.], 
     [ 1., 3.], 
     [ 1., 4.], 
     [ 1., 5.], 
     [ 1., 6.], 
     [ 1., 7.], 
     [ 1., 8.], 
     [ 1., 9.]]) 
>>> np.fft.irfft(np.fft.rfft(a, axis=0), axis=0) 
array([[ 1.00000000e+00, 7.10542736e-16], 
     [ 1.00000000e+00, 1.00000000e+00], 
     [ 1.00000000e+00, 2.00000000e+00], 
     [ 1.00000000e+00, 3.00000000e+00], 
     [ 1.00000000e+00, 4.00000000e+00], 
     [ 1.00000000e+00, 5.00000000e+00], 
     [ 1.00000000e+00, 6.00000000e+00], 
     [ 1.00000000e+00, 7.00000000e+00], 
     [ 1.00000000e+00, 8.00000000e+00], 
     [ 1.00000000e+00, 9.00000000e+00]]) 
6
  1. あなたはおそらくfft(ポストフィルタリング)のifftを取りたい
  2. ここに任意のフィルタを適用するためには表示されません、ない入力波形の。
4

このようにはなりませんか?

filtereddata = numpy.fft.fft(data) 
# do fft stuff to filtereddata 
filteredwrite = numpy.fft.ifft(filtereddata) 
wavfile.write('TestFiltered.wav', rate, filteredwrite) 
+0

@wim - そのことについて申し訳ありません。 – SolarLune

2

2つの問題。

2チャンネルのデータをFFTします。 FFTの結果を得るためには、モノラルデータの1チャンネルだけをFFTして、通常の意味で理解してください。 2チャンネルのステレオデータを処理する場合は、各チャンネルを別々にIFFT(FFT())する必要があります。

実際のfftを使用しています。これは情報を捨てて、fftを非可逆にします。

反転したい場合、複雑な結果を生成するFFTを使用し、この複素周波数領域ベクトルをIFFTして時間領域に戻す必要があります。周波数領域のベクトルを修正する場合は、厳密に実際の結果(数値ノイズを引いたもの)が必要な場合は共役対称のままであることを確認してください。

+0

マルチチャネルデータを扱うには、2次元配列を使用し、axisキーワードが正しく設定されていることを確認する必要があります(デフォルトで-1)。また、 'irfft(rfft(n))'はn )。 –

+0

n.shape [axis]が偶数であれば、 'irfft(rfft(n))'が最も良く動作するようです。 –

+0

@Bago - このことについてはとても長い時間をかけて申し訳ありませんが、あなたが何を意味するのか少し分かりますか? 「2次元配列を使用する」とはどういう意味ですか?あなたはNumPy配列を意味します、そうですか? – SolarLune