前提・実現したいこと
今回以下のような流れでプログラムをつくっています。
wavファイルを読み込み→FFT→バンドパスフィルタ処理→iFFT→処理後の時間信号がプロットされたか確認→wavファイル書き出し
発生している問題・エラーメッセージ
処理後の時間信号がプロットされたか確認は既にできていて、wavファイルが形としては出力されているのですが、音声が再生されない状態です。出力されたwavファイルの再生時間を確認したところ入力データと一緒でした。
今回こちらのサイトを参照
https://water2litter.net/rum/post/python_scipy_wavfile_write/
追加:
もう一つこちらのサイトを参考にしてもう一つbandpassのプログラムを改良して作ってみました。
http://tacky0612.hatenablog.com/entry/2017/11/28/133103
こちらの場合は、wavファイルが出力されるのですが、再生時間が0秒と書いてあり再生できない状態です。
bandpassの下にソースコードを記載しておきます。
該当のソースコード
bandpass
1import sys 2import scipy.io.wavfile 3from scipy.io.wavfile import write 4from scipy.io.wavfile import read 5from scipy.fftpack import rfft,irfft,fftfreq 6import numpy as np 7import matplotlib.pyplot as plt 8 9#音声ファイル読み込み 10args = sys.argv 11wav_filename = args[1] 12rate, data = scipy.io.wavfile.read(wav_filename) 13 14print(data) 15 16#縦軸(振幅)の配列を作成 17data = data / 32768 18#横軸(時間)の配列を作成 #np.arange(初項, 等差数列の終点, 等差) 19time = np.arange(0, data.shape[0]/rate, 1/rate) 20 21 22#縦軸:dataを高速フーリエ変換する(時間領域から周波数領域に変換する) 23fft_data = np.fft.fft(data) 24#横軸:周波数の取得 #np.fft.fftfreq(データ点数, サンプリング周期) 25freqList = np.fft.fftfreq(data.shape[0], d=1.0/rate) 26 27# 正規化 + 交流成分2倍 28fft_data = fft_data/24000 #サンプル数/2 29#fft_data[0] = fft_data[0]/2 30 31# 配列fft_dataをコピー 32fft_data2 = fft_data.copy() 33 34# bandpass処理 35fft_data2[(freqList < 300)&(freqList > -300)] = 0 #highpass 36fft_data2[(freqList > 3300)|(freqList < -3300)] = 0 #lowpass 37 38# 高速逆フーリエ変換(時間信号に戻す) 39data2 = np.fft.ifft(fft_data2) 40#data2 = np.array(data2,dtype = np.int16) #戻しておかないとすごい音がする 41 42# 振幅を元のスケールに戻す 43data2 = np.real(data2*48000) #N = 16000*3 44 45############################################### 46#### 画像をプロットするプログラムは長いため省略 #### 47############################################### 48 49data.flags.writeable = True 50write('out.wav',rate,data2)
実行例: python ~.py ~.wav
###追加のソースコード
bandpass2
1import numpy as np 2import sys 3from scipy.fftpack import rfft,irfft,fftfreq 4import wave 5import matplotlib.pyplot as plt 6 7# ファイルを読み出し 8args = sys.argv 9wav_filename = args[1] 10wf = wave.open(wav_filename,"r") 11 12rate = wf.getframerate() 13nframes = wf.getnframes() 14width = wf.getsampwidth() 15 16amp = (2**8) ** width / 2 #??? 17data = wf.readframes(nframes) #frameの読み込み 18wf.close() 19data = np.frombuffer(data,'int16') # intに変換 20data = data / amp # 振幅正規化(-1~1) 21 22# make time axis 23time = np.arange(0, nframes/rate, 1.0/rate) 24 25fft_data = np.fft.fft(data) 26freq = np.fft.fftfreq(nframes,1.0/rate) 27 28#正規化 29fft_data = fft_data/(nframes/2) 30 31#配列fft_dataをコピー 32fft_data2 = fft_data.copy() 33 34# bandpass処理 35fft_data2[(freq < 300)&(freq > -300)] = 0 #highpass 36fft_data2[(freq > 3300)|(freq < -3300)] = 0 #lowpass 37 38# 高速逆フーリエ変換(時間信号に戻す) 39data2 = np.fft.ifft(fft_data2) 40#data2 = np.array(data2,'int16') 41 42# 振幅を元のスケールに戻す 43data2 = np.real(data2*nframes) 44 45############################################### 46#### 画像をプロットするプログラムは長いため省略 #### 47############################################### 48 49###ファイル書き込み### 50write_wave = wave.open("1.wav","wb") 51write_wave.setparams(wf.getparams()) 52write_wave.writeframes(data2) 53write_wave.close() 54
試したこと
サイトの通り読み込んだデータは書き込み禁止らしいので、
data.flags.writeable = True
を追加した。
補足情報(FW/ツールのバージョンなど)
anaconda3を使用
回答1件
あなたの回答
tips
プレビュー