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にバイト配列が入っている。