前提・実現したいこと
今回実現させたいことは、下のウェブサイトを参考にしながら、FFTをかけたwavファイルにハイパスフィルタをかけて、時間信号に戻すことです。
https://algorithm.joho.info/programming/python/numpy-fast-fourier-transform/#toc3
発生している問題・エラーメッセージ
発生している問題としては、周波数信号(before)から周波数信号(after)はy軸を揃えるとうまくプロットされたが、周波数信号(after)から時間信号(after)に戻したときに時間信号(before)と比べてグラフが全く違います。
”振幅を元のスケールに戻す”というところで、(サンプル数)=(サンプリング周波数)(wavファイルの再生時間)=160003=48000ということで、サンプル数は間違っていないと思います。
こちらの画像の説明です
左上→時間信号(前)
右上→周波数信号(前)
左下→時間信号(後)
右下→周波数信号(後)
該当のソースコード
import sys import scipy.io.wavfile from scipy.fftpack import rfft,irfft,fftfreq import numpy as np import matplotlib.pyplot as plt #音声ファイル読み込み args = sys.argv wav_filename = args[1] rate, data = scipy.io.wavfile.read(wav_filename) #縦軸(振幅)の配列を作成 data = data / 32768 #横軸(時間)の配列を作成 time = np.arange(0, data.shape[0]/rate, 1/rate) #縦軸:dataを高速フーリエ変換する(時間領域から周波数領域に変換する) fft_data = np.abs(np.fft.fft(data)) #横軸:周波数の取得 #np.fft.fftfreq(データ点数, サンプリング周期) freqList = np.fft.fftfreq(data.shape[0], d=1.0/rate) # 正規化 + 交流成分2倍 fft_data = fft_data/24000 #サンプル数/2 fft_data[0] = fft_data[0]/2 # 配列fft_dataをコピー fft_data2 = fft_data.copy() # ハイパス処理(カットオフ周波数未満の帯域と、右半分の帯域の周波数信号を0にする) fft_data2[(freqList < 100)] = 0 #fc = 100 #カットオフ周波数 #fft_data2[(freqList > 1/(0.0000625*2))] = 0 #dt = 0.0000625 #サンプリング間隔 # 高速逆フーリエ変換(時間信号に戻す) data2 = np.fft.ifft(fft_data2) # 振幅を元のスケールに戻す data2 = np.real(data2*48000) #N = 16000*3 #サンプル数 #データプロット #時間信号(before) plt.subplot(221) plt.plot(time,data) #周波数信号(before) plt.subplot(222) plt.plot(freqList, fft_data) plt.xlim(0, 1000) #0~4000Hzまで表示 #時間信号(after) plt.subplot(223) plt.plot(time,data2) #周波数成分(after) plt.subplot(224) plt.plot(freqList,fft_data2) plt.xlim(0,1000) plt.show()
実行例:python ~.py ~.wav
補足情報(FW/ツールのバージョンなど)
anakonda3を使用
回答1件
あなたの回答
tips
プレビュー