質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2521閲覧

Python3で音の識別を行いたい

maguro2020

総合スコア34

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2020/05/14 11:17

編集2020/05/14 14:54

前提・実現したいこと

はてなブログ Webデータレポート 生活音を機械学習してみた

上記のリンクを参考にPython3を用いて、音声(wav)の機械学習をしたいと考えております。wavファイルのスペクトグラムや振幅の表示はできたのですが、MFCC(メル周波数ケプストラム係数)のあたりから上手くいかず、wavファイルからベクトルを生成することができません。

発生している問題・エラーメッセージ

Error: unknown format: 65534

該当のソースコード

Python3

1#coding:utf-8 2import wave 3import numpy as np 4import scipy.signal 5import scipy.fftpack 6import scipy.fftpack.realtransforms 7import scipy.io.wavfile 8 9def wavread(filename): 10 wf = wave.open(filename, "r") 11 fs = wf.getframerate() 12 x = wf.readframes(wf.getnframes()) 13 x = np.frombuffer(x, dtype="int16") / 32768.0 # (-1, 1)に正規化 14 wf.close() 15 return x, float(fs) 16 17def hz2mel(f): 18 """Hzをmelに変換""" 19 return 1127.01048 * np.log(f / 700.0 + 1.0) 20 21def mel2hz(m): 22 """melをhzに変換""" 23 return 700.0 * (np.exp(m / 1127.01048) - 1.0) 24 25def melFilterBank(fs, nfft, numChannels): 26 """メルフィルタバンクを作成""" 27 # ナイキスト周波数(Hz) 28 fmax = fs / 2 29 # ナイキスト周波数(mel) 30 melmax = hz2mel(fmax) 31 # 周波数インデックスの最大数 32 nmax = nfft / 2 33 # 周波数解像度(周波数インデックス1あたりのHz幅) 34 df = fs / nfft 35 # メル尺度における各フィルタの中心周波数を求める 36 dmel = melmax / (numChannels + 1) 37 melcenters = np.arange(1, numChannels + 1) * dmel 38 # 各フィルタの中心周波数をHzに変換 39 fcenters = mel2hz(melcenters) 40 # 各フィルタの中心周波数を周波数インデックスに変換 41 indexcenter = np.round(fcenters / df) 42 # 各フィルタの開始位置のインデックス 43 indexstart = np.hstack(([0], indexcenter[0:numChannels - 1])) 44 # 各フィルタの終了位置のインデックス 45 indexstop = np.hstack((indexcenter[1:numChannels], [nmax])) 46 47 filterbank = np.zeros((numChannels, nmax)) 48 for c in np.arange(0, numChannels): 49 # 三角フィルタの左の直線の傾きから点を求める 50 increment= 1.0 / (indexcenter[c] - indexstart[c]) 51 for i in np.arange(indexstart[c], indexcenter[c]): 52 i=int(i) 53 filterbank[c, i] = (i - indexstart[c]) * increment 54 # 三角フィルタの右の直線の傾きから点を求める 55 decrement = 1.0 / (indexstop[c] - indexcenter[c]) 56 for i in np.arange(indexcenter[c], indexstop[c]): 57 i=int(i) 58 filterbank[c, i] = 1.0 - ((i - indexcenter[c]) * decrement) 59 60 return filterbank, fcenters 61 62def preEmphasis(signal, p): 63 """プリエンファシスフィルタ""" 64 # 係数 (1.0, -p) のFIRフィルタを作成 65 return scipy.signal.lfilter([1.0, -p], 1, signal) 66 67def mfcc(signal, nfft, fs, nceps): 68 """信号のMFCCパラメータを求める 69 signal: 音声信号 70 nfft : FFTのサンプル数 71 nceps : MFCCの次元""" 72 # プリエンファシスフィルタをかける 73 p = 0.97 # プリエンファシス係数 74 signal = preEmphasis(signal, p) 75 76 # ハミング窓をかける 77 hammingWindow = np.hamming(len(signal)) 78 signal = signal * hammingWindow 79 80 # 振幅スペクトルを求める 81 spec = np.abs(np.fft.fft(signal, nfft))[:nfft/2] 82 fscale = np.fft.fftfreq(nfft, d = 1.0 / fs)[:nfft/2] 83 84 # メルフィルタバンクを作成 85 numChannels = 20 # メルフィルタバンクのチャネル数 86 df = fs / nfft # 周波数解像度(周波数インデックス1あたりのHz幅) 87 filterbank, fcenters = melFilterBank(fs, nfft, numChannels) 88 89 90 # 定義通りに書いた場合 91 # 振幅スペクトルに対してフィルタバンクの各フィルタをかけ、振幅の和の対数をとる 92 mspec = np.log10(np.dot(spec, filterbank.T)) 93 94 95 # 離散コサイン変換 96 ceps = scipy.fftpack.realtransforms.dct(mspec, type=2, norm="ortho", axis=-1) 97 98 # 低次成分からnceps個の係数を返す 99 return ceps[:nceps] 100 101#wavファイルと次元数を入れてMFCCを抽出 102# nfft:FFTのサンプル数 1024, 2048, 4096 103# nceps:MFCCの次元数 大体12次元が多い 104# ※ fs * cuttime >= nfft/2 を満たす値を与えなければいけない 105def get_feature(wavfile,nfft,nceps): 106 # 音声をロード 107 wav, fs = wavread(wavfile) 108 t = np.arange(0.0, len(wav) / fs, 1/fs) 109 110 # 音声波形の中心部分を切り出す 111 center = len(wav) / 2 # 中心のサンプル番号 112 cuttime = 0.8 # 切り出す長さ [s] 113 wavdata = wav[int(center - cuttime/2*fs) : int(center + cuttime/2*fs)] 114 115 ceps = mfcc(wavdata, nfft, fs, nceps) 116 return ceps.tolist() 117 118if __name__ == "__main__": 119 wavfile= "call01.wav" #1 120 nfft=2048 121 nceps=12 122 tmp = get_feature(wavfile,nfft,nceps) 123 print (tmp) #2 124 125

試したこと

前回の質問より、ほとんどリンク元のコードのまま実行してみました。変更点といたしましては、下から5行目(#1)と1行目(#2)のコードの
1.参照するファイル名の変更
2.printに()をつけたこと。(リンク元のコードがPython2.7のため)
を行いました。

少し調べてみたところ、
Why GitHub? wave.Error: unknown format: 65534 #129
上記でも似たようなエラーで困っている人を見つけ、色々とコードをいじってみてはいるのですが、上手くいきません。

補足情報(FW/ツールのバージョンなど)

Python3.6.5です

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meg_

2020/05/14 11:29

・リンクは「リンクの挿入」で記入してください。 ・コードは「コードの挿入」で記入してください。
maguro2020

2020/05/14 12:11

大変失礼いたしました。質問を編集いたしました。
meg_

2020/05/14 12:22

「上から8行目のdef wavread(filename):をdef wavread():に書き換えました。」とありますが、何故書き換えたのですか? エラーはエラーメッセージの通りです。
meg_

2020/05/14 12:23

それから、エラーメッセージは可能な限り全文載せてください。(ユーザー名等は隠してもらって構いません)
maguro2020

2020/05/14 12:36

元のdef wavread(filename):の「filename」のところを'call01.wav'に変更いたしましたところ、 SyntaxError: invalid syntax というエラーメッセージが表示され、「filename」のままですと NameError: name 'wf' is not defined と表示されたため、書き換えを行いました。 Python以前に、自分のプログラミングの知識不足で「引数」がどの部分なのかもわからず、未だにコードを調べている途中でした。中途半端かつわかりづらい質問をしてしまい申し訳ありません。もう少し自分で調べてみたいと思います。
meg_

2020/05/14 14:56

「Error: unknown format: 65534」 上記はエラーメッセージの全文ですか?
maguro2020

2020/05/14 15:04

「Error: unknown format: 65534」の上記にはとても細かく約56行ほどのコードが出てきており、 '''#コード Error Traceback (most recent call last) <ipython-input-134-fdf415abea31> in <module> 3 nfft=2048 4 nceps=12 ----> 5 tmp = get_feature(wavfile,nfft,nceps) 6 print (tmp) <ipython-input-132-13313078b2d6> in get_feature(wavfile, nfft, nceps) 5 def get_feature(wavfile,nfft,nceps): 6 # 音声をロード ----> 7 wav, fs = wavread(wavfile) 8 t = np.arange(0.0, len(wav) / fs, 1/fs) 9 <ipython-input-130-fbc23ac4b9eb> in wavread(filename) 1 def wavread(filename): ----> 2 wf = wave.open(filename, "r") 3 fs = wf.getframerate() 4 x = wf.readframes(wf.getnframes()) 5 x = np.frombuffer(x, dtype="int16") / 32768.0 # (-1, 1)に正規化 ~/.pyenv/versions/3.6.5/lib/python3.6/wave.py in open(f, mode) 497 mode = 'rb' 498 if mode in ('r', 'rb'): --> 499 return Wave_read(f) 500 elif mode in ('w', 'wb'): 501 return Wave_write(f) ~/.pyenv/versions/3.6.5/lib/python3.6/wave.py in __init__(self, f) 161 # else, assume it is an open file object already 162 try: --> 163 self.initfp(f) 164 except: 165 if self._i_opened_the_file: ~/.pyenv/versions/3.6.5/lib/python3.6/wave.py in initfp(self, file) 141 chunkname = chunk.getname() 142 if chunkname == b'fmt ': --> 143 self._read_fmt_chunk(chunk) 144 self._fmt_chunk_read = 1 145 elif chunkname == b'data': ~/.pyenv/versions/3.6.5/lib/python3.6/wave.py in _read_fmt_chunk(self, chunk) 258 self._sampwidth = (sampwidth + 7) // 8 259 else: --> 260 raise Error('unknown format: %r' % (wFormatTag,)) 261 self._framesize = self._nchannels * self._sampwidth 262 self._comptype = 'NONE'  Error: unknown format: 65534 ''' となっております。見づらくなってしまい申し訳ありません。
guest

回答1

0

ベストアンサー

Python

1def wavread(): #1 2 wf = wave.open('call01.wav', "r") #2

Python

1def get_feature(wavfile,nfft,nceps): 2 # 音声をロード 3 wav, fs = wavread('call01.wav')

を元に戻しましょう。

Python

1def wavread(filename): 2 wf = wave.open(filename, "r")

Python

1def get_feature(wavfile,nfft,nceps): 2 # 音声をロード 3 wav, fs = wavread(wavfile)

参照元のコードのままでエラーが出る場合は、そのときにまた質問してください。

投稿2020/05/14 12:46

meg_

総合スコア10580

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maguro2020

2020/05/14 14:57

わざわざ回答していただき、ありがとうございます。ほとんどリンク元のコードで実行致しましたところ、エラーが発生いたしましたので、質問を編集しました。
meg_

2020/05/14 15:54

最初の質問に書いてあったかと思いましたが、scipy.io.wavfileの方で読み込みできそうですね。 参考:https://github.com/jiaaro/pydub/issues/134 ※fnielsenさんの回答のところ
maguro2020

2020/05/14 16:10

返信が遅れてしまい申し訳ありません。wavファイルの解析を行なっていましたところ、call01.wavからcall07.wavの7つのファイルが私の手元にあるのですが、7つのファイルのうち、call01.wavとcall02.wavのファイルだけが96kHzでPCM形式に変換することができませんでした。call05.wavだけは48kHzでしたが、あとのファイルは44.1kHzでしたのでPCM形式に変換することができました。変換は下記のサイト様を使わせていただきました。 https://www.petitmonte.com/labo/wave-format/ とりあえず、call01.wavとcall02.wavは置いておいて他のファイルでコードの実行を試みましたところ、 TypeError: slice indices must be integers or None or have an __index__ method というエラーが発生し、下記のサイト様より少し調べておりました。 https://teratail.com/questions/76964 どうやらPython3では「/」では実数除算らしく「//」を用いたほうが良いとのことで、コードのどこを変化させれば良いのかで頭を悩ませております。
meg_

2020/05/14 16:21

どの行で「TypeError: slice indices must be integers or None or have an __index__ method」のエラーが発生しているのでしょうか? ※情報がないとこちらでは何も分かりません。
maguro2020

2020/05/15 00:24

返信遅くなり申し訳ありません。エラーメッセージの全文を記載いたします。 TypeError Traceback (most recent call last) <ipython-input-211-861046850ea1> in <module> 3 nfft=2048 4 nceps=12 ----> 5 tmp = get_feature(wavfile,nfft,nceps) 6 print (tmp) <ipython-input-210-78439af9a47a> in get_feature(wavfile, nfft, nceps) 13 wavdata = wav[int(center - cuttime/2*fs) : int(center + cuttime/2*fs)] 14 ---> 15 ceps = mfcc(wavdata, nfft, fs, nceps) 16 return ceps.tolist() <ipython-input-209-f7a2f4347928> in mfcc(signal, nfft, fs, nceps) 63 64 # 振幅スペクトルを求める ---> 65 spec = np.abs(np.fft.fft(signal, nfft))[:nfft/2] 66 fscale = np.fft.fftfreq(nfft, d = 1.0 / fs)[:nfft/2] 67 TypeError: slice indices must be integers or None or have an __index__ method
meg_

2020/05/15 01:41

fscale = np.fft.fftfreq(nfft, d = 1.0 / fs)[:nfft/2] を fscale = np.fft.fftfreq(nfft, d = 1.0 / fs)[:nfft//2] にすれば良いでしょう。
maguro2020

2020/05/15 01:50

お答えいただきありがとうございます。自分もそのように描けば動くのではないかと思い実行致しましたところ、 TypeError Traceback (most recent call last) <ipython-input-234-861046850ea1> in <module> 3 nfft=2048 4 nceps=12 ----> 5 tmp = get_feature(wavfile,nfft,nceps) 6 print (tmp) <ipython-input-233-78439af9a47a> in get_feature(wavfile, nfft, nceps) 13 wavdata = wav[int(center - cuttime/2*fs) : int(center + cuttime/2*fs)] 14 ---> 15 ceps = mfcc(wavdata, nfft, fs, nceps) 16 return ceps.tolist() <ipython-input-232-015e65042c92> in mfcc(signal, nfft, fs, nceps) 64 # 振幅スペクトルを求める 65 spec = np.abs(np.fft.fft(signal, nfft))[:nfft//2] ---> 66 fscale = np.fft.fftfreq(nfft, d = 1.0 / fs)[:nfft/2] 67 68 # メルフィルタバンクを作成 TypeError: slice indices must be integers or None or have an __index__ method というエラーが発生したため、65行目の fscale = np.fft.fftfreq(nfft, d = 1.0 / fs)[:nfft/2] から fscale = np.fft.fftfreq(nfft, d = 1.0 / fs)[:nfft//2] に変更し、実行致しました。その結果、 TypeError Traceback (most recent call last) <ipython-input-237-861046850ea1> in <module> 3 nfft=2048 4 nceps=12 ----> 5 tmp = get_feature(wavfile,nfft,nceps) 6 print (tmp) <ipython-input-236-78439af9a47a> in get_feature(wavfile, nfft, nceps) 13 wavdata = wav[int(center - cuttime/2*fs) : int(center + cuttime/2*fs)] 14 ---> 15 ceps = mfcc(wavdata, nfft, fs, nceps) 16 return ceps.tolist() <ipython-input-235-fe0fd4e73824> in mfcc(signal, nfft, fs, nceps) 69 numChannels = 20 # メルフィルタバンクのチャネル数 70 df = fs / nfft # 周波数解像度(周波数インデックス1あたりのHz幅) ---> 71 filterbank, fcenters = melFilterBank(fs, nfft, numChannels) 72 73 <ipython-input-235-fe0fd4e73824> in melFilterBank(fs, nfft, numChannels) 29 indexstop = np.hstack((indexcenter[1:numChannels], [nmax])) 30 ---> 31 filterbank = np.zeros((numChannels, nmax)) 32 for c in np.arange(0, numChannels): 33 # 三角フィルタの左の直線の傾きから点を求める TypeError: 'float' object cannot be interpreted as an integer というエラーが発生し、ただいまこのエラーについて調べておりました。
meg_

2020/05/15 03:03

エラーが発生したときのnumChannels, nmaxの値を調べれば原因が分かるでしょう。 filterbank = np.zeros((numChannels, nmax))の行の直前でnumChannels, nmaxの値をprint()で確かめてください。
meg_

2020/05/15 03:06

たぶんここですね。 def melFilterBank(fs, nfft, numChannels) 関数内の「nmax = nfft / 2」を「nmax = nfft //2」にすれば良いかと思います。
maguro2020

2020/05/15 05:04

重ね重ねご指摘いただきありがとうございます。ただいまmeg様に指摘されたところを変更し、実行致しましたところ12次ベクトルを取り出すことに成功致しました。お忙しい中、自分の質問に真摯に答えてくださり、誠にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問