Friday, August 1, 2014

Perk,RMSメーターと、FFTのVisualizerを作った

前からあったけど、ちゃんと説明していなかったし、また見た目もしっかり作りこんでなかったので報告をしていなかったのですが、ひとまずまずまずの見た目が確保できたので報告しておきます。





下のイコライザー部分とメディア・コントロール部分はまだ手付かずなのでスルーしておいてほしいのですが、上部のVisualizer部分がひとまず出来ました。

左側が、FFTの値を周波数毎にわけて、最大値を表示している部分です。
右側の2本のバーがPeak,RMSの値です。

FFTの部分はAndoridのAudioFXから値をリスニングし、取得した値をサンプリングレートによる周波数情報を元に振幅を求め、値を周波数毎に16個に分割したものから、最大値を取得しています。
下記の式は振幅を求めるときの計算処理です。

float amplitude = (float) Math.sqrt(Math.pow((float) data.bytes[i * 2], 2) + bandFftData[num] Math.pow((float) data.bytes[i * 2 + 1], 2));

取得した振幅は画面のサイズに合わせて最大値を下記の式で求めdBを求めています。

float peakMax = (128 * Math.sqrt(2));
float dB = (float) (20.0f * Math.log10(max(bandFftData[i]) / peakMax));

この数値で割った値をバーに表示しています。
ただこれだけだと、振幅が突然0にになったりするデータが含まれているので画面が点滅してしまいます。
ですので、簡単ですが過去3回までの値からもっとも大きい値を選択するようにしています。

それから、Peak,RMSですが、、予め言っておきますが、Peak,RMSの値を取得するAPIはKitKatからサポートされているため、それより前の端末では動作しません。
KitKatより古い端末を使っていて、期待されていた方はごめんなさい。

動いても動かなくても興味あれば読んでいただければと思います。

Peak,RMSは音の音圧を現すdBをベースにした音の情報です。
この数値は、単純にボリュームではなく人間の耳に聞こえる範囲の音としてどれだけ大きい音かどうかを現すために使われます。
いわゆるLoudnessというやつです。
KitKatからLoudnessEnhancerというAPIが追加されたため、上記数値をもとに適切なLoudnessを設定することが可能になりました。

これが意味することは、サンプリングした曲によって音の大きさが違ってくる問題を解決することを助けてくれます。
つまり、音楽アプリのなかでいうReplyGainという機能の実装ができそうです。

しかし、これには問題がありAndroidのPeak,RMSは端末のボリュームに比例して大きくなります。
ですので、単純にその曲を計測するだけではうまくいきそうにないです、だからこのメーターは飾りです。
散々引っ張っておいて、このオチはひどいとはおもってます、、
まぁ、使えるとして、イコライザーなどを設定するときにこのメーターをみながら最適なイコライザセッティングをするといったことぐらいでしょうか。
もっとも、設定するのであれば細かい数値を入力できないといけないでしょう。

では、どうやって、ReplayGainを実装するのかというと、音楽を取り込むアプリなどで、タグ情報に最大Peak,Rmsと最小Peak,Rms、それとアルバム単位における平均のPeak,Rmsを埋め込んでもらい、それをもとに設定することになります。

いまのところ、このようなことができるツールは foobar2000ぐらいしか思いつかないのですが、
http://www.forest.impress.co.jp/library/software/foobar2000/

Macは何があるのかな?

このツールをつかえば、アルバム単位で適切なPeak,Rmsの値を設定することができそうです。
だけど、これ独自フォーマットなんですよね。
もしくは、Androidアプリ側でなにか設定するアプリを準備するか、、JUST PLAYERでやる?
この場合、MediaPlayerをつかわないで、AudioTrackをつかうことになるのかなぁ、コーデック処理が難しそうだなぁ、、
うーん、うーん

No comments:

Post a Comment