Androidで音声の録音を実行しようとした際にAudioRecordを使用したのですが、setRecordPositionUpdateListenerのonPeriodicNotificationが正しく呼ばれずに録音が継続的に行わえないという問題が発生して苦戦してしまいました。そのときの忘備録もかねてまとめたいと思います。
起きていた現象
AudioRecordではsetPositionNotificationPeriodで呼び出される間隔の指定、そしてsetRecordPositionUpdateListenerでリスナーを設定することでreadを行った際に一定間隔でコールバック関数が呼ぶように設定することができます。コールバック関数内で再度readを呼びだしたり、他の処理を記載することで継続的に録音を行うことや決められた処理を実行することができます。
今回起きた現象としては、setPositionNotificationPeriod、setRecordPositionUpdateListenerを設定したのにも関わらずコールバック関数が呼ばれないという現象でした。
原因
録音したデータを格納する変数の型とAudioRecordのaudio dataのencodingの型が一致していなかったため、コールバック関数が呼ばれなくなっていましたのが原因でした。エラーも出力されておらず原因を特定するのに時間がかかってしまいました…
Android developersのAudioRecordのreadの説明を見てみるとここに説明が記載されていました。
Reads audio data from the audio hardware for recording into a byte array. The format specified in the AudioRecord constructor should be AudioFormat.ENCODING_PCM_8BIT to correspond to the data in the array.
readの第一引数にbyte配列を指定する場合には、AudioRecordのコンストラクタにてAudioFormat.ENCODING_PCM_8BITを指定する必要がありました。しかし、私はここでAudioFormat.ENCODING_PCM_16BITを指定してしまっていたためコールバック関数が呼ばれなくなってしまいました。
正しくはbyteかつAudioFormat.ENCODING_PCM_8BIT、もしくはshort[]かつAudioFormat.ENCODING_PCM_16BITにする必要がありました。これを設定することでコールバック関数が呼ばれるようになりました。
他にも同じような現象が起きていないか調べてみたところ、コールバック関数の呼び出し間隔の設定が正しくないと同じようにコールバック関数の呼び出しに問題が発生するようでした。
まとめ
AudioRecordの設定をしっかりと確認するのが一番と学びました。
AudioRecordは特に設定する個所が多く混乱が起きやすかったので、より注意深く確認することが大事と学びました。
(今回、録音と再生を行おうとしたので、さらに設定が増えてしまい、混乱してしまっていました…反省…)
コンパイル時もしくは実行時にエラーが出力されることの偉大さに今回の件でひしひしと感じました。