###前提・実現したいこと
録音したPCMデータから単位時間ごとに周波数算出したいと考えております。
###発生している問題・エラーメッセージ
以下のようになコードを作成しまして1buffer単位の最大周波数を算出したいと考えておりますが
想定しているデータを違う結果が出力されてしまいます。
###該当のソースコード
swift
1 //オーディオデータの取得 2 let audioFile = try AVAudioFile(forReading: url) 3 // オーディオのサンプルレートの取得 4 let sampleRate = audioFile.fileFormat.sampleRate 5 6 let fft = EZAudioFFTRolling.fftWithWindowSize(fftWindowSize, historyBufferSize: fftWindowSize , sampleRate: Float(sampleRate)) 7 8 //オーディオファイルから、PCMBufferにオーディオデータを取得して、フーリエ変換した周波数配列を求める 9 let perCount: Int = 2 10 let totalSampleFrames = Int(audioFile.length) 11 // 取得したい周波数の配列 12 var frequencies = [Float]() 13 14 15 for _ in 0 ..< totalSampleFrames { 16 17 // バッファーの取得 18 let buffer = AVAudioPCMBuffer(PCMFormat: audioFile.processingFormat, frameCapacity: AVAudioFrameCount(totalSampleFrames)) 19 20 // 一部取得 21 try audioFile.readIntoBuffer(buffer, frameCount: AVAudioFrameCount(perCount)) 22 let bufferSize = UInt32(buffer.frameLength) 23 // FFT 24 fft.computeFFTWithBuffer(buffer.floatChannelData[0], withBufferSize: bufferSize) 25 26 frequencies.append(fft.maxFrequency) 27 } 28 // 結果の出力 29 for _ in 0 < frequencies.count { 30 print("周波数:\(fft.maxFrequency)") 31 } 32 ....
上記FFTの結果をグラフ出力
fft.maxFrequency // → 緑のライン
buffer.floatChannelData[0].memory // → 赤いライン
###補足情報(言語/FW/ツール等のバージョンなど)
Swift 2.1
XCode 7
EXAudioを使用しています。
グラフ出力はどのタイミングでやっていますか?都度出力です?それとも、ファイルに書き出して後で出力していますか?
issei様
閲覧いただきありがとうございます。
グラフですが実際には動作を確認するためにExcelで結果をcsvにしてそれをグラフにしておりますのでプログラムでは出力しておりません。。
ですのでプログラム上で必要なのはmaxFrequencyの時系列データのみとなります。
※わかりにくかったのでコードを追加させていただきました。
よろしくお願いいたします。
ありがとうございます。それなら、出力の時間スケールがずれていることはなさそうです。むしろ、FFT取っている範囲の幅がバッファーサイズで200前後だから、高周波の範囲の後ろ側200個分は最大値が大きくなるだけでは?
こちらこそありがとうございます。現状
fft.computeFFTWithBuffer(buffer.floatChannelData[0], withBufferSize: bufferSize)
の関数でまとめて処理をしているのですが後ろ200個分....のくだりがよく理解できておりません。申し訳ございませんがご教授いただけますでしょうか?
buffer.floatChannelData[0]を先頭に、bufferSize個のデータでFFTをやっていると思います。まず、bufferSize個は200個前後なのでは?
現在のbufferSizeが1が入っておりまして,256に設定させていただき動作確認しました。ですが最大周波数は0で全域で算出されませんでした。
ちなみにBuffersizeですが1,2,100,200,256,512,1024を入れても同様に周波数が算出されませんでした。
なるほど。すみません誤解しておりました。buffer1つに対して時系列データがあるという認識で正しいでしょうか?
↑これで認識が正しいという仮定のもとで、ドキュメント( http://cocoadocs.org/docsets/EZAudio/1.1.2/Classes/EZAudioFFT.html#//api/name/maxFrequency )を見ると、「last FFT calculation」の最大値とあるので、多分画面に出力するタイミングが正しくないのだと思います。
bufferにデータがある認識です。issei様のご指摘通りですとmaxfrepuencyは使えず、自作で計算しないといけないということでしょうか?
はい。frequenciesの配列から最大値を計算するメソッドないしロジックが必要です。。
回答1件
あなたの回答
tips
プレビュー