1

以下は、サンプルごとに 16 ビットおよび 32 ビットの wav を読み取るために使用したコードで、問題なく動作します。

私の質問は、残りの 8 ビットの符号なし、24 ビットの符号付き、および 32 ビットの浮動小数点wavをどのように読み取ることができるかということです。

16 ビット符号付き wav の 1 つのサンプルを読み取ります。

short buffer;

file.read( ( char * ) &readbuffer, 2 );

32 ビットの符号付き wav の 1 つのサンプルを読み取ります。

int buffer;

file.read( ( char * ) &readbuffer, 4 );
4

1 に答える 1

1

ターゲット マシンについていくつかの仮定を立てています。Microsoft WAV フォーマットに従って、すべてのサンプル データはリトルエンディアンです。また、さまざまなデータ型が必要なサイズであることを期待していますが、常にそうであるとは限りません。

しかし、あなたの現在のルーチンはあなたのために機能するので、当面はそれに焦点を当てることはしません (ただし、おそらくこれらのことはいつか修正する必要があります)。

32 ビット浮動小数点数

恐るべきエンディアン性と非標準の型サイズを忘れると、32 ビット float のケースは、他のコードをテンプレートとして使用して比較的簡単になります。

float buffer;
file.read( ( char * ) &buffer, 4 );

この質問では、バイナリ ソースからのフロートの読み取りについて、より詳細に説明しています。

x ビット符号なし

お使いのマシンが 16 ビットと 32 ビットのケースを正しく解釈していることがわかっているので、リトル エンディアンであると推測できます。つまり、ゼロに初期化された unsigned int にすべてを読み込むことができ、残りのバイトはすでに正しくパディングされています。

unsigned int buffer = 0;
file.read( ( char * ) &buffer, 1 );   // 8bit unsigned integer

buffer = 0;
file.read( ( char * ) &buffer, 3 );   // 24bit unsigned integer

x ビット符号付き

最後に、符号付き整数を読み取る場合は、読み取った数値の値に応じて、バッファ変数の残りのバイトをパディングする必要があります。

  • 数値が正の場合は、0 で埋めることができます
  • 数値が負の場合 (最上位バイトの最上位ビットが設定されている場合)、\xFF バイトでパディングします。

このコードは、24 ビットの符号付き整数で機能します。

long buffer;
int number_of_bytes = 3;             // 24 bit signed integer

file.read( (char *) &buffer, number_of_bytes);

// Determine the padding byte
unsigned char padding_byte = 0;
if ( ((char*) &buffer)[number_of_bytes - 1] & 128) {
    padding_byte = 255;
}

// Pad the data
for (int i = number_of_bytes; i < sizeof(buffer); i++) {
    ((char*) &buffer)[i] = padding_byte;
}

繰り返しますが、エンディアンをチェックしていないため、一部のマシンではこのコードが失敗することを指摘しておく必要があると思います。ただし、これを修正するために必要なのは、コードを実行しているマシンのエンディアンをチェックし、ビッグ エンディアンのマシンを使用している場合はバイトの順序を逆にすることだけです。

于 2013-01-01T15:32:27.717 に答える