SPH0645LM4Hの録音フォーマットの問題

SPH0645LM4Hの二つのマイクからステレオ録音ができるようになった。再生すればきちんと音を再生できる。ただ、ここで問題が発生した。SPH0645LM4Hは、32ビットSampleSizeInBitsでしか録音できないのだ。arecordのコマンドラインで行くと、
arecord -D dmic_sv -c2 -r 44100 -f S32_LE -t wav -V stereo -v file8.wav
で録音する。この、S32_LEが32ビットリトルエンディアンのフォーマットでの録音になるのである。これをS16_LEで録音しようとすると、そのフォーマットではできないよというエラーになる。

32ビットは、高い質の録画になるのであるが、これをデータでとらえる必要があ流。4バイトが、intになるのかfloatになるのか、二つの場合があるらしい。ただし、データで読むとき、4バイトの、バイト配列で取り出せるのだが、どう変換してもきちんとしたデータに変換できない。16ビット、2バイトの音源の場合はデータ化できるのだが、32ビットだとできないのである。朝からずっとこれをどうやったら変換できるのかをやっていた。

結局どうしてもできないので、soxで元の32ビットの音源を16ビットに変換することにした。変換のコマンドラインは次のようになる。
sox -v 0.99 file8.wav -b 16 file8-16-1.wav
元ファイルの前に、 -v 0.99 をつけないと
sox WARN dither: dither clipped 5768 samples; decrease volume?
という警告が出る。元音源のボリュームが大きすぎるものがいくつかあるよというエラーらしい。若干ボリュームを下げるオプションらしい。
という、データが取れる(ごく1部だ)
青が、レベルが高いので、音源に近い方で、そちらが微妙に先についているように見える。厳密には計算して見なければならない。
バイト配列の計算部分は、

short left, right;
for (int i = 0; i < data.length; i += 4) {
left = (short)((short)data[i] & 0xff | ((short)data[i+1] << 8));
right = (short)((short)data[i+2] & 0xff | ((short)data[i+3] << 8));
System.out.println("" + left + " " + right);
}

となる。
dataにバイト配列が入っている。

SPH0645LM4H搭載 I2S MEMSマイクモジュールを動かす

アクリルロボットHAL2の頭の両脇に耳をつけて、音の到着時間さで音が聞こえてくる方向を決めようと思っている。そのために、音声をデジタル変換して差を求めなけれがならない。

結構長い時間どうするのかを探ったが、SPH0645LM4H搭載 I2S MEMSマイクモジュールが最適だと結論に至った。これは、スイッチサイエンスがアマゾンで972円で売り出している。(Amazon)これを二つ買った。(マイクの方向に気をつけて、ピンをはんだ付けすること)

これの接続や、カーネルのコンパイルについては、極めて簡単で(1)こちら のサイトをそのまま実行すれば良い。(厳密には、私は、コンパイルは、同じSPH0645LM4H を扱っている (2)こちら を参照して、自動起動がうまくいかなかったので、そこは(1)を参照した。別に物で試すと、コンパイルは(1)の通りやるとうまくいかなかった。(2)でコンパイルして、後半は(1)を参照するのがベストか)

録音できるところまでは順調だったが、マイクのゲインが低すぎた。これについては、(1)の最後に書いてあるものが、一番よくわかる。