前提・実現したいこと
python2のコードを3に書き換えたい
pythonで音声認識をしたいです。
そこでMFCCのサンプルコードを見つけたのですが、
python2のバージョンだったのでpython3に書き換えたいです
発生している問題・エラーメッセージ
Traceback (most recent call last): File "mfcc3.py", line 124, in <module> tmp = get_feature(wavfile,nfft,nceps) File "mfcc3.py", line 117, in get_feature ceps = mfcc(wavdata, nfft, fs, nceps) File "mfcc3.py", line 76, in mfcc signal = preEmphasis(signal, p) File "mfcc3.py", line 67, in preEmphasis return scipy.signal.lfilter([1.0, -p], 1, signal) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/signal/signaltools.py", line 1337, in lfilter out_full = np.apply_along_axis(lambda y: np.convolve(b, y), axis, x) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numpy/lib/shape_base.py", line 357, in apply_along_axis res = asanyarray(func1d(inarr_view[ind0], *args, **kwargs)) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/signal/signaltools.py", line 1337, in <lambda> out_full = np.apply_along_axis(lambda y: np.convolve(b, y), axis, x) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/numpy/core/numeric.py", line 1043, in convolve raise ValueError('v cannot be empty') ValueError: v cannot be empty
該当のソースコード
python
1#coding:utf-8 2import wave 3import numpy as np 4import scipy.signal 5import scipy.fftpack 6import scipy.fftpack.realtransforms 7 8 9 10 11def wavread(filename): 12 wf = wave.open(filename, "r") 13 fs = wf.getframerate() 14 x = wf.readframes(wf.getnframes()) 15 x = np.frombuffer(x, dtype="int16") // 32768.0 # (-1, 1)に正規化 16 wf.close() 17 return x, float(fs) 18 19def hz2mel(f): 20 """Hzをmelに変換""" 21 return 1127.01048 * np.log(f // 700.0 + 1.0) 22 23def mel2hz(m): 24 """melをhzに変換""" 25 return 700.0 * (np.exp(m // 1127.01048) - 1.0) 26 27def melFilterBank(fs, nfft, numChannels): 28 """メルフィルタバンクを作成""" 29 # ナイキスト周波数(Hz) 30 fmax = fs // 2 31 # ナイキスト周波数(mel) 32 melmax = hz2mel(fmax) 33 # 周波数インデックスの最大数 34 nmax = nfft // 2 35 # 周波数解像度(周波数インデックス1あたりのHz幅) 36 df = fs // nfft 37 # メル尺度における各フィルタの中心周波数を求める 38 dmel = melmax // (numChannels + 1) 39 melcenters = np.arange(1, numChannels + 1) * dmel 40 # 各フィルタの中心周波数をHzに変換 41 fcenters = mel2hz(melcenters) 42 # 各フィルタの中心周波数を周波数インデックスに変換 43 indexcenter = np.round(fcenters // df) 44 # 各フィルタの開始位置のインデックス 45 indexstart = np.hstack(([0], indexcenter[0:numChannels - 1])) 46 # 各フィルタの終了位置のインデックス 47 indexstop = np.hstack((indexcenter[1:numChannels], [nmax])) 48 49 filterbank = np.zeros((numChannels, nmax)) 50 for c in np.arange(0, numChannels): 51 # 三角フィルタの左の直線の傾きから点を求める 52 increment= 1.0 // (indexcenter[c] - indexstart[c]) 53 for i in np.arange(indexstart[c], indexcenter[c]): 54 i=int(i) 55 filterbank[c, i] = (i - indexstart[c]) * increment 56 # 三角フィルタの右の直線の傾きから点を求める 57 decrement = 1.0 // (indexstop[c] - indexcenter[c]) 58 for i in np.arange(indexcenter[c], indexstop[c]): 59 i=int(i) 60 filterbank[c, i] = 1.0 - ((i - indexcenter[c]) * decrement) 61 62 return filterbank, fcenters 63 64def preEmphasis(signal, p): 65 """プリエンファシスフィルタ""" 66 # 係数 (1.0, -p) のFIRフィルタを作成 67 return scipy.signal.lfilter([1.0, -p], 1, signal) 68 69def mfcc(signal, nfft, fs, nceps): 70 """信号のMFCCパラメータを求める 71 signal: 音声信号 72 nfft : FFTのサンプル数 73 nceps : MFCCの次元""" 74 # プリエンファシスフィルタをかける 75 p = 0.97 # プリエンファシス係数 76 signal = preEmphasis(signal, p) 77 78 # ハミング窓をかける 79 hammingWindow = np.hamming(len(signal)) 80 signal = signal * hammingWindow 81 82 # 振幅スペクトルを求める 83 spec = np.abs(np.fft.fft(signal, nfft))[:nfft//2] 84 fscale = np.fft.fftfreq(nfft, d = 1.0 // fs)[:nfft//2] 85 86 # メルフィルタバンクを作成 87 numChannels = 20 # メルフィルタバンクのチャネル数 88 df = fs // nfft # 周波数解像度(周波数インデックス1あたりのHz幅) 89 filterbank, fcenters = melFilterBank(fs, nfft, numChannels) 90 91 92 # 定義通りに書いた場合 93 # 振幅スペクトルに対してフィルタバンクの各フィルタをかけ、振幅の和の対数をとる 94 mspec = np.log10(np.dot(spec, filterbank.T)) 95 96 97 # 離散コサイン変換 98 ceps = scipy.fftpack.realtransforms.dct(mspec, type=2, norm="ortho", axis=-1) 99 100 # 低次成分からnceps個の係数を返す 101 return ceps[:nceps] 102 103#wavファイルと次元数を入れてMFCCを抽出 104# nfft:FFTのサンプル数 1024, 2048, 4096 105# nceps:MFCCの次元数 大体12次元が多い 106# ※ fs * cuttime >= nfft/2 を満たす値を与えなければいけない 107def get_feature(wavfile,nfft,nceps): 108 # 音声をロード 109 wav, fs = wavread(wavfile) 110 t = np.arange(0.0, len(wav) // fs, 1/fs) 111 112 # 音声波形の中心部分を切り出す 113 center = len(wav) // 2 # 中心のサンプル番号 114 cuttime = 0.8 # 切り出す長さ [s] 115 wavdata = wav[int(center - cuttime//2*fs) : int(center + cuttime//2*fs)] 116 117 ceps = mfcc(wavdata, nfft, fs, nceps) 118 return ceps.tolist() 119 120if __name__ == "__main__": 121 wavfile="warai.wav" 122 nfft=2048 123 nceps=12 124 tmp = get_feature(wavfile,nfft,nceps) 125 print(tmp) 126 127
試したこと
一度2to3を実行した後に、余算演算の変更 '/'(python2) → '//'(python3)を行いました。
のちに上記のエラーがでたのですが、理解をすることができません。
どのようにエラーを処理していけば解決できるでしょうか?
補足情報(FW/ツールのバージョンなど)
python 3.7.0