Python でのFFTライブラリィは選り取り見取り。
“FFT scipy vs numpy” で検索したら
python - What is the difference between numpy.fft and scipy.fftpackとか出て来た。 scipy と numpy だと、scipy がずっと速いという人がいたり (僕には「ちょっと」としか思えなかった)、 多次元だと numpy の方が速いとか、 FFTW を使う方が速いとか。
https://stackoverflow.com/questions/6363154/what-is-the-difference-between-numpy-fft-and-scipy-fftpack
スピード競争は好きな人に任せる。 某授業で Mathematica でやったことをほぼそのまま後追いしてみる。
| spectrum.py |
# coding:utf-8
# spectrum.py --- WAVEファイルを読んで離散フーリエ変換する
# https://docs.python.jp/3/library/wave.html
# http://aidiary.hatenablog.com/entry/20110618/1308367728
import wave
import numpy as np
import scipy.fftpack # サブパッケージは一々 import する
import matplotlib
import matplotlib.pyplot as plt #
# WAVE ファイルをオープンする
wf = wave.open("guitar-5-3.wav", "r")
# サンプリング・レートを得る (Python 的には frame rate という)
sr = wf.getframerate()
# チャンネル数を得る (モノラルか
nchannels = wf.getnchannels()
# サンプルあたりのバイト数
samplewidth = wf.getsampwidth()
# フレームの総数
nframes = wf.getnframes()
# すべてのフレームを読み込む
snd = wf.readframes(nframes) # snd=wf.readframes(wf.getnframes()) とも出来る
# もう閉じていいでしょう
wf.close()
#
if samplewidth == 2:
tbl=np.frombuffer(snd, dtype="int16")/32768.0
elif samplewidth == 4:
tbl=np.frombuffer(snd, dtype="int32")/2147483648.0
# ステレオの場合は左チャンネルだけ
if nchannels == 2:
tbl = tbl[::2] # tbl=tbl[1::2] とすると右チャンネル
elif nchannerls == 1:
print(u"モノラル")
else:
print(u"あれ?チャンネル数=", nchannels)
# とりあえず先頭から3秒分プロットしてみる
plt.plot(tbl[:3*sr])
plt.show()
# 62800番目から1秒分取り出してプロットする (そうすると周波数簡単)
start=62800
N = sr
plt.plot(tbl[start:start+N])
plt.show()
#
c=scipy.fftpack.fft(tbl[start:start+N])
# c = np.fft.fft(tbl[start:start+N])
plt.plot(abs(c))
plt.show()
# n1からn2までの範囲で図示
def graph(c,n1,n2):
plt.plot(np.array(range(n1,n2)),abs(c[n1:n2]))
plt.xlabel('Frequency')
plt.ylabel('Amplitude Spectrum')
return
graph(c,1,1600)
plt.show()
graph(c,120,140)
plt.show()
|