前提・実現したいこと
wavファイルにFFTをかけてスペクトルを表示するコードを
PythonとRの2パターンで書きました。
発生している問題・エラーメッセージ
Pythonでは以下のスペクトルが表示されました。
Rでは以下のスペクトルが表示されました。
どちらも同じような形のスペクトルが表示されているのですが、
ピークが出ている周波数に倍くらいズレが出ています。
Pythonでは140Hzあたりに一番大きなピークがあるのですが、
Rでは280Hzあたりに一番大きなピークが出ています。
どちらのコードが間違っているかわからず、困っている状況です。
該当のソースコード
Python
1import wave 2import numpy as np 3import scipy.fftpack 4import matplotlib.pyplot as plt 5 6wf = wave.open("~~~.wav" , "r" ) 7fs = wf.getframerate() # サンプリング周波数 8x = wf.readframes(wf.getnframes()) 9x = np.frombuffer(x, dtype= "int16") / 32768.0 # -1 - +1に正規化 10wf.close() 11 12start = 0 # サンプリングする開始位置 13N = 1550000 # FFTのサンプル数 14 15X = np.fft.fft(x[start:start+N]) # FFT 16 17freqList = np.fft.fftfreq(N, d=1.0/fs) # 周波数軸の値を計算 18 19plt.title("FFT-wheeze") 20plt.plot(freqList,abs(X)) 21plt.axis([0,600,0,max(abs(X))+500]) 22 23plt.show()
R
1install.packages("tuneR") 2library(tuneR) 3 4# ファイルの読み込み 5wavobj <- readWave("~~~.wav") 6x <- wavobj@left # 左チャンネルだけを使う(wavobj@.Dataを使う場合も) 7fs <- wavobj@samp.rate # 標本化周波数 8nbits <- wavobj@bit # 量子化ビット数 9 10x <- x[1:(fs*5)] # 先頭の5秒間だけを分析対象として抜き出す 11 12y <- fft(x) 13 14y.tmp <- Mod(y) # 複素数の絶対値を計算 15 16# 振幅スペクトル(amplitude spectrum)の計算 17y.tmp <- Mod(y) # 複素数の絶対値を計算 18y.ampspec <- y.tmp[1:(length(y)/2+1)] # DC〜ナイキストの範囲 19y.ampspec[2:(length(y)/2)] <- y.ampspec[2:(length(y)/2)] * 2 20 21# 対応する周波数の計算(DC〜ナイキストの範囲をビン数で均等割) 22f <- seq(from=0, to=fs/2, length=length(y)/2+1) 23 24# グラフ作成 25plot(f, y.ampspec, type="h", xlab="Frequency (Hz)", ylab="Amplitude Spectrum", xlim=c(0, 600)) 26grid()
回答1件
あなたの回答
tips
プレビュー