android.media.AudioRecord

ここで見つけたサンプルを元に動作検証用のコードをでっち上げて確認中。
なんですが、AudioRecord な thread が buffer overflow 云々なメセジが LogCat に出ててどうにもならない状況。てか、あまり AudioRecord なドキュメント読んでなかったりして、色々確認しつつメモを残す。

糸口がない

てか、このスレッドが微妙に気になる

ええと上記スレッドに以下な記述がある。

I suspect the problem is the interval you chose: 50 frames @ 8KHz is
6.25 msecs. Your app is not going to be able to handle a callback
every 6.25 msecs. Try something more reasonable like 50 msecs (400
frames) and see if that works.

上記の所以は以下のコードかと。

           recorder.setPositionNotificationPeriod(50);

なんで 8KHz (秒単位で 8000 のサンプル) で 50 frames だと 6.25msec なのかが良く分からんあたりが微妙。
あと勘違いしてたのは OnRecordPositionUpdateListener の抽象メソドの実装で、例えば onMarkerReached メソドであれば引数で渡される AudioRecord オブジェクトから読みこまないと微妙な模様。

                public void onMarkerReached(AudioRecord arg0) {
                        // read PCM buffer
                        byte[] audioBuffer = new byte[AUDIO_SAMPLE_FREQ];
                        arg0.read(audioBuffer, 0, AUDIO_SAMPLE_FREQ);
                }

むむむ

で、gauche で色々値をあてはめてみました。8KHz (8000Hz) で 50frames だと 6.25msec な所以。

gosh> (* 0.00625 8000)
50.0
gosh> 

ええと、逆に言うと

gosh> (/ 50 8000.0)
0.00625
gosh> 

ってカンジでフレームの数でサンプルレートを割れば良いのか。400 程度のフレームで云々を 44100 ならどうなるか、というと

gosh> (/ 400 44100.0)
0.009070294784580499
gosh> 

50 msec 程度で云々だとすると約 6 倍?

gosh> (/ 2400 44100.0)
0.05442176870748299
gosh> 

44.1KHz だと 2400 位が妥当な数値ってコトになるのでしょうか。

なんとなくな現時点の結論としては

  • コールバックは両方指定
    • onMarkerReached
    • onPeriodicNotification
  • リスナをナニするトリガも両方指定
    • setPositionNotificationPeriod
      • 上記なフレームの数を指定
    • setNotificationMarkerPosition
      • サンプルレートを指定するのがビンゴかどうかは微妙
  • 一回サンプルレート分 read してナニ
    • read した結果はステになるはず

そろそろ寝ます。
emacs に入力した瞬間 firefox が死亡。ので、投入が午前様。