3

問題があります。Java では、wav ファイルからサンプルを読み取る必要があります。ファイル形式は次のとおりです。wav、PCM_SIGNED、2 バイトの符号付き整数 = 16 ビット、リトル エンディアン... オブジェクトはオーディオ サンプルを BYTES 単位で読み取り、この 2 バイトを 1 つの double 値に変換する必要があります。この式を使用しようとしましたが、完全には正しくありません。

mono = (double)((audioBytes[k] & 0xFF) | (audioBytes[k + 1] << 8));

結果を Matlab と比較すると、Matlab の実際の値と Java で変換された値の違いにいつも気付きます。誰でも私を助けてもらえますか?ありがとう、デイブ

4

3 に答える 3

3

MatlabとJavaで異なる結果が得られる理由を知るのに十分な情報を提供していない。通常、短チャネルデータ[-32768..32767]を[-1..1]の範囲の2倍にスケーリングします。これは、実行しようとしているように見えます。Javaの結果:-3.0517578125E-5は、短い値-1:-1/32768に対して正しいです。Matlabの結果が異なる理由がわかりません。Matlabの結果にどのように到達しているかを示していません。

バイトのシーケンスが大きく(私はあなたがそうしていると思います)、BIG-ENDIANとLITTLE-ENDIAN、またはビットとバイトのシフトについて心配したくない場合は、javaに処理させてください。

import java.nio.*;
...
ByteBuffer buf = ByteBuffer.wrap(audioBytes);
buf.order(ByteOrder.LITTLE_ENDIAN);

while (buf.remaining() >= 2) {
    short s = buf.getShort();
    double mono = (double) s;
    double mono_norm = mono / 32768.0;
    ...
}

ByteBuffer.getShort()は、バッファーの次の2バイトを読み取り、リトルエンディアンの順序を処理し、バイトをshortに変換して、次のgetXXX()呼び出しのために自身を配置します。

于 2011-01-06T20:58:58.563 に答える
0

これは正しい方法です:

double sampleValue = (double)(( bytes[0]<<8 ) | ( bytes[1]&0x00FF ));

(小さい/大きいを交換するためにインデックスを変更します)

于 2011-01-06T18:09:18.263 に答える
-1

most_significant byte * 256 + least_significant_byte を実行してから double にキャストできませんか?

于 2011-01-06T15:18:39.283 に答える