AudioRecord (続

ええと、直前エントリにコメント頂いてる件についてフォローなエントリです。
以下な実装にしてみました、と書いた所

          int bufferSize = AudioRecord.getMinBufferSize(this.getFrequency(),
                    this.getChannelConfiguration(), 
                    this.getAudioEncoding());
          AudioRecord recordInstance = new AudioRecord(
                    MediaRecorder.AudioSource.MIC, 
                    this.getFrequency(), 
                    this.getChannelConfiguration(), 
                    this.getAudioEncoding(),
                    4 * bufferSize);
          short[] tempBuffer = new short[bufferSize];

以下なフォローを id:t-doi さんから頂きました。

  • バッファサイズを 2 倍するのではなく tempBuffer のサイズをもっと小さく (1/4 とかそれ以下) した方が良い
  • おそらくは AudioRecord も別 thread で動作しててバッファサイズが同一だと問題があるのではないか
    • ActiveRecord が一杯になるのと tempBuffer への読み込みが同じになる

整理してみる

ええと、上記のコードが書いてある部分も一つの thread として動いてます。AudioRecord の read というメソドを使って、上記 tempBuffer な領域に音声なデータ列を読み込んで変換処理を、という形。読み込み処理の呼び出し部分では mutex な同期とかはしてません。
てか、こんな期待しちゃダメでしょ、ってツッコミ入りそうですが、AudioRecord の中で

  • read メソド呼び出し時
  • 音声データを内部バッファに投入する時

には同期をとって処理してるんだろう、と。(を
で、基本的に read 呼び出し時には

  • mutex 取って
  • 4 * bufferSize な (おそらくはリングバッファ) 領域から指定されたサイズをメソドに渡された配列にコピーしてコピー元のバッファの後始末
  • mutex 手放す

ってコトをしてるのではと類推。音声データを取り込む時にも mutex を取って内部バッファに追加してるのだと見てます。
あと、AudioRecord の使い方については_このスレッド_を参考にしてるんですが、この例では AudioRecord のコンストラクタに渡すバッファサイズ (おそらくは AudioRecord が持つ内部バッファのサイズと類推) と read に渡すバッファサイズが同一になってます。
読み込んだ後の処理マターかと思うんですが、こうした形を取ってると buffer overflow なログが出力される頻度が増えまず。AudioRecord が持ってる内部バッファが溢れてるのだろう、と見ています。
あ、あと上記の処理を書いてる thread ですが、基本的に一つしか thread は kick されません。ので排他制御はしてないです。

N1 不具合

今日、N1 と HT-03A のサンプリングレートが異なる事を確認してます。変換エンジンでサンプリングレートの指定があるので、これが原因なのかも、と。

上記のよれば HT-03A は 44.1kHz で N1 は 48kHz との事。サンプリングレートの変換に挑む方向だったりなんかして。

最後に

色々とフォローありがとうございます。> t-doi さん
正直申し上げて java は門外漢なのでいつも参考になります。