3

私が理解しているように、私が使用しているオーディオ バイト配列 (PCM ステレオ 16 ビット) は、サンプルあたり 4 バイトです。バイト値を反転すると (つまり、-128 から 128 および 128 から -128)、サラウンド チャンネルにサウンドが配置されないことに気付きました。同じように聞こえます(フロントオーディオ)。すべてのバイトではなく、1 つおきのバイト (2 バイトごと) を反転して実験したところ、サラウンド サウンドのようなものが得られましたが、非常に汚れていて途切れ途切れです。オーディオがサラウンド チャンネルに配置されるように、通常の PCM 16 ビット ステレオ WAV ファイル (バイト配列形式) を正確に操作するにはどうすればよいですか?

私のコード:

public byte[] putInSurround(byte[] audio) {
        for (int i = 0; i < audio.length; i += 4) {
            int i0 = audio[i + 0];
            int i1 = audio[i + 1];
            int i2 = audio[i + 2];
            int i3 = audio[i + 3];
            if (0 > audio[i + 0]) {
                i0 = Math.abs(audio[i + 0]);
            }
            if (0 < audio[i + 0]) {
                i0 = 0 - audio[i + 0];
            }
            if (0 > audio[i + 1]) {
                i1 = Math.abs(audio[i + 1]);
            }
            if (0 < audio[i + 1]) {
                i1 = 0 - audio[i + 1];
            }
            if (0 > audio[i + 2]) {
                i2 = Math.abs(audio[i + 2]);
            }
            if (0 < audio[i + 2]) {
                i2 = 0 - audio[i + 2];
            }
            if (0 > audio[i + 3]) {
                i3 = Math.abs(audio[i + 3]);
            }
            if (0 < audio[i + 3]) {
                i3 = 0 - audio[i + 3];
            }
            audio[i + 0] = (byte) i0;
            //audio[i + 1] = (byte) i1; <-- Commented Out For Every Other Byte.
            //audio[i + 2] = (byte) i2; <-- Commented Out For Every Other Byte.
            audio[i + 3] = (byte) i3;
        }
        return audio;
    }
4

1 に答える 1

0

私は決して DSP の専門家ではありませんが、役立つかもしれないいくつかの観察があります。

  • 配列を 4 バイト単位で解析します。これは、1 つの 16 ビット ステレオ サウンド サンプルに正しく対応します: 2 channels * 16 bits = 32 bits = 4 bytes.

    さて、あなたが何をしようとしているのか理解できないかもしれませんが、現代のサラウンド オーディオでは、通常、サラウンド チャンネルは互いに独立しています。つまり、サラウンド オーディオ サンプルごとに 4 バイト以上が必要になります。たとえば、チャネルが 5 つある場合、サンプルあたり 10 バイトが必要になります。これはおそらく、コード内で入力配列と出力配列を分離する必要があることを意味します。

    Dolby SurroundDolby Pro Logicなど、サラウンド チャネルを 2 つのステレオ チャネルにマトリックス エンコードする方法がありますが、関連する DSP 数学は、コードにあるものよりもはるかに複雑です。特別なデコーダーの必要性と、そのような方法によって暗示される品質の損失は言うまでもありません。

  • 2 バイトのサンプルの各バイトを反転しても意味がありません。1000d のサンプル値は -744d になります。このようなビット演算は、DSP ではほとんど使用されません。

  • 通常、オーディオ サンプルは符号付き 2 の補数の 2 進数として格納されます。そのため、Java などの符号なし数値やポインター キャストがない言語では特に、バイト単位での処理が非常に複雑になります。バイト配列をshortorの配列に変換するintか、C++ などの別のプログラミング言語を使用することをお勧めします。

  • -128 を反転すると +128 が生成されますが、Java で使用されるように、符号付きバイトに格納することはできません。

  • 「互いにバイトを反転する」場合は、 andまたはandの代わりにi + 0andの反転を格納します。i + 3i + 0i + 2i + 1i + 3

  • お互いのバイトを反転した結果は、まだ意味がありませんが、オーディオ表現がリトルエンディアンかビッグエンディアンかによって、異なる効果があります。RIFF WAV ファイルは、リトル エンディアンのバイト順を使用します。

    バイト 0 と 2 を反転すると、サンプルの LSB が変更されます。これは、オーディオ クリップのダイナミック レンジが制限されている場合に、高振幅のノイズと完全な歪みを追加するだけです。

    バイト 1 と 3 を反転すると、サンプル全体が高振幅で反転し、ダイナミック レンジが制限されたクリップに多くの歪みが追加されます。

  • 個々のバイトではなくサンプル全体を反転することは、180 度の位相シフトの近似値です。どこで使えるかわかりませんが…

これ以上のヘルプが必要な場合は、正確に何をしようとしているのかをお知らせください。少なくとも、予想される出力と、使用している DSP アルゴリズムについて言及する必要があります。

于 2011-04-09T10:10:47.023 に答える