AndroidでFFTはJTransformsが楽だった

[投稿日] 2016年11月11日
[最終更新] 2017年2月21日

最近Androidアプリの開発をいまさらながらはじめました。今回作ったのは、音声をAndroidスマートフォンに入力し特定の音が鳴っていないか検出するアプリ。FFTで周波数解析して、周波数領域でピーク検出をするのが簡単そうです(時系列データだとノイズの影響が大きく難しそうだった)。それで、AndroidでFFTって、何がいいのかな…と調べると、標準APIのVisualizerの話がよく出てきました。…が、単純にFFTするだけなら、JTransformsが使いやすかった、という記事です。

スポンサーリンク

AndroidでFFTをするには

周波数解析といえばなんといってもフーリエ変換(フーリエ解析)です。フーリエ変換とは、かいつまんで言うとあらゆる波をsin波とcos波で表現しましょうというものです。1秒間で一回りするsin波を1Hzと表現し、1秒間に10周するsin波を10Hzといいます。そういう無数の○○Hzを組み合わせると、人の音声など複雑な波形も作ることができますよと、そういう話です。

フーリエ変換を実際にコンピュータで用いるときはFFT(Fast Fourier Transform,高速フーリエ変換)というアルゴリズムが用いられます。アルゴリズムなので実装は色々あります。ライブラリもいっぱいあります。何を使うか、悩ましい。

FFTとは、DFT(Discrete Fourier Transform, 離散フーリエ変換)を高速にしたものです。DFTとは、フーリエ変換を離散的に表現したもので、離散があるように連続フーリエ変換もあります。しかし、コンピュータは突き詰めると0と1です。連続的な表現は擬似的にしかできません。したがって、コンピュータでは連続ではなく離散フーリエ変換が使われます。

まぁ細かい話は置いといて、要は音声信号をFFTで周波数解析したいけれど、Android初めてだし、自分で実装とか嫌だし、どのライブラリを使えばよいのかなと、そういう話です。

標準のAPIがあるが…

調べていると、どうやらAndroidは標準のAPIでFFTができるらしい。なんと素晴らしい。「Visualizer | Android Developers」です。ふむふむ……ふむ……。

うーん、正直ちょっと扱いづらいなぁ、と。私はshort型の配列に取り込んだデータをFFTしたいだけなんですが、オーディオ用のライブラリということもあってか、オーディオのオブジェクトから作成する感じで取り扱いが面倒臭い。あとgetFftメソッドで「The capture is an 8-bit magnitude FFT」ってマジかや……今回の目的からは8-bitでもいいっちゃいいんだけど、うーん。

なんだかなーと思っていたところ、「Android/JavaでFFT(高速フーリエ変換) | Androidアプリ開発日誌 | WEB道」の記事でJTransformsというライブラリの使用例がありました。おお、なんてシンプル。配列にデータ突っ込んで引数に取るだけ、まさにこんなのを求めていました。たいへんに参考になりました。

ということで、「JTransforms – Piotr Wendykier」よりjarファイルをダウンロードして、「androidstudioにライブラリ用のjarファイルを追加する方法 – うさがにっき」にしたがいインポートしました。パッケージはorg.jtransforms.fft.FloatFFT_1Dを使わせてもらいました。変換後はデータの並びが実数、虚数、実数、虚数…でサンプリング周波数の半分まで(サンプリング周波数の半分までしか使えません。詳しくはサンプリング定理で調べる)しっかりとありました。

ということで、AndroidでFFTするならJTransformsが使いやすいですよという話でした。ちょっとマニアックだろうか。

初Androidアプリ開発。色々なことが初めてづくしで苦労しました……音声を取り込んでFFTはそれなりに需要もあるように思うので、そのうちまとめて記事にしたいですね。

関連コンテンツ

関連記事

スポンサーリンク

コメントを残す

メールアドレスが公開されることはありません。