SwiftUIで録音した音声を平均化FFTするアプリをつくってみた

  • このエントリーをはてなブックマークに追加

今回もiOSアプリ制作シリーズです。これまで学んだ録音・再生・フーリエ変換・オーバーラップ・窓関数・聴感補正・dB変換を全部盛りにしてSwiftUIによる平均化FFTを実行するアプリを作ってみます。まずは個別のコードを紹介し、最後にコピペ可能な全コードを載せて実行結果を説明します。

こんにちは。wat(@watlablog)です。ここではSwiftによる平均化FFT計算を使った音声処理アプリ制作の例を紹介します

これまでのあらすじ

この記事は過去記事の内容をふんだんに引き継いでいます。WATLABブログでは過去に以下の記事で録音や再生、フーリエ変換やその他雑多な処理を紹介してきました。

SwiftでiOSデバイスのマイクを使って録音機能を追加する方法
SwiftUIとAVFoundationで音声を再生する方法
Swiftで高速フーリエ変換(FFT)を実装する方法

今回はこのページで平均化FFTを行うためのまとまったコードを紹介してみます!

SwiftUIによる平均化FFTアプリの例

Audio関係のクラス

Audio.swiftの内容は「SwiftUIとAVFoundationで音声を再生する方法」と変更はありません。
詳細はこちらの記事をご覧ください。

信号処理関係のクラス

信号処理関係のクラスはDSP.swiftに集約していますが、ここに色々過去記事からの追加があります。ここでは改めて関数群を紹介します。

複素数演算

フーリエ変換には複素数の計算が必須ですが、Swiftは複素数型を持ちません。そのため以下の関数で複素数の演算方法を定義する必要があります。Swiftで新しい型を定義する時は構造体(struct)を使います。

FFT

FFTはAccelerateというライブラリで行います。AccelerateのvDSPメソッドを使って信号を高速フーリエ変換します。詳細は「Swiftで高速フーリエ変換(FFT)を実装する方法」をご覧ください。

オーバーラップ

長時間信号の平均化FFTをするために、時間信号をフレームで抽出するオーバーラップ処理を実装します。オーバーラップ処理については「Swiftで時間波形をオーバーラップ抽出するコード」をご覧ください。

dB変換

dB(デシベル)変換も実施します。dB変換は必ずしもなくても良いのですが、Chartでグラフ表示する場合に軸を対数に設定しなくても波形が見やすくなるというメリットを持ちます。Pythonの記事ですが、詳細は「Pythonで音圧のデシベル(dB)変換式と逆変換式!」をご覧ください。

聴感補正

こちらも特になくても良いのですが、せっかく音声処理をするということで、聴感補正(A特性)も実装してみましょう。聴感補正の詳細もPython記事ではありますが、「Pythonで聴感補正(A特性)の曲線を作る!」をご覧ください。

窓関数

フーリエ変換時の漏れ誤差(リーケージエラー)を防ぐために窓関数処理を実装します。こちらも詳しくは「SwiftUIで時間波形に窓関数をかけてグラフ表示する方法」をご覧ください。

平均化FFT

そして本記事のメインである平均化FFTのコードがこちらです。平均化FFTはPythonで一度作っているので、詳細は「PythonでFFT実装!SciPyのフーリエ変換まとめ」の記事に任せます。今回はそのSwift版というわけです。

GUI関係(メインファイルのコード)

最後にメインのGUI関係をまとめたContentView.swiftを紹介します。3画面構成です。最初の画面に録音と再生機能、2ページ目に録音波形の平均化FFT結果表示、最後のページにFFT設定を配置しています。

初期画面構成

実行結果

下図が実行結果です。Start Recordingボタンを押し、口笛を吹いてみた結果です。録音を止めるにはStop Recordingボタンを押します。

実行結果

もちろんiOSデバイスでも動作します!
それにしても、このブログを始めてから口笛がうまくなったと思います。

まとめ

今回はここまで!

この記事のアプリはサンプリングレートが12800Hzで固定されていますが、変更したい場合はAudio.swiftのsampleRateを変更します。

実際に操作してみるとわかりますが、まだまだ動作が重いような。。もっとスムーズに動かせればリリースも視野に入れたいのですが、もう少しかかりそうですね。

とはいえこの記事ではSwiftによる平均化FFTのコード実装を扱いました。なかなか検索ではやりたいことがヒットせず苦労しましたが、少しずつできるようになってきたようです。

SwiftとPythonで平均化高速フーリエ変換を実装することができました!
Twitter(今はXと呼ぶ?)でも関連情報をつぶやいているので、wat(@watlablog)のフォローお待ちしています!

  • このエントリーをはてなブックマークに追加

SNSでもご購読できます。

コメントを残す

*