0

WAVEFORMATEXWindows でオーディオを再生するために WaveOut を使用していWAVE_FORMAT_IEEE_FLOATます。プログラムは C++ で書かれ、MinGW でコンパイルされます。これはすべて正しく機能しています:

https://github.com/Raptor007/AutoDJ/blob/60f4debca2103e669a5d1b822b04c73cdcdaf05b/AutoDJ.cpp#L2412-L2435

今、私はクアドラフォニックマルチチャンネル出力に拡張しようとしてWAVEFORMATEXTENSIBLEいますWAVEFORMATEX. これらの変更が適用された関連コードは次のとおりです。

WAVEFORMATEXTENSIBLE wfx;
memset( &wfx, 0, sizeof(wfx) );
wfx.Format.nChannels = want.channels;
wfx.dwChannelMask = (want.channels == 4) ? 0x33 : ((want.channels == 1) ? 0x4 : 0x3);
wfx.Format.nSamplesPerSec = want.freq;
wfx.Format.cbSize = sizeof(wfx) - sizeof(wfx.Format);
MMRESULT wave_out_result = ~MMSYSERR_NOERROR;
if( userdata.HighRes )
{
    wfx.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
    wfx.SubFormat = {0x00000003,0x0000,0x0010,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}; //KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
    wfx.Format.wBitsPerSample = 32;
    wfx.Samples.wValidBitsPerSample = wfx.Format.wBitsPerSample;
    wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
    wfx.Format.nAvgBytesPerSec = wfx.Format.nBlockAlign * wfx.Format.nSamplesPerSec;
    wave_out_result = waveOutOpen( &WaveOutHandle, WAVE_MAPPER, &(wfx.Format), (DWORD_PTR) &WaveOutCallback, 0, CALLBACK_FUNCTION );
}
if( wave_out_result != MMSYSERR_NOERROR )
{
    if( userdata.HighRes )
        fprintf( stderr, "waveOutOpen returned %i%s when attempting float output\n", wave_out_result, (wave_out_result == WAVERR_BADFORMAT)?" (WAVERR_BADFORMAT)":"" );
    wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
    wfx.SubFormat = {0x00000001,0x0000,0x0010,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}; //KSDATAFORMAT_SUBTYPE_PCM
    wfx.Format.wBitsPerSample = 16;
    wfx.Samples.wValidBitsPerSample = wfx.Format.wBitsPerSample;
    wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
    wfx.Format.nAvgBytesPerSec = wfx.Format.nBlockAlign * wfx.Format.nSamplesPerSec;
    wave_out_result = waveOutOpen( &WaveOutHandle, WAVE_MAPPER, &(wfx.Format), (DWORD_PTR) &WaveOutCallback, 0, CALLBACK_FUNCTION );
    if( wave_out_result == MMSYSERR_NOERROR )
        userdata.HighRes = false;
    else
        fprintf( stderr, "waveOutOpen returned %i%s when attempting int16 output\n", wave_out_result, (wave_out_result == WAVERR_BADFORMAT)?" (WAVERR_BADFORMAT)":"" );
}

Format.nChannels = 2; dwChannelMask = 0x3;ステレオに設定すると、 waveOutOpenIEEE-float 形式を使用した最初の試みは return codeWAVERR_BADFORMATで失敗しますが、PCM 形式を使用した 2 回目の試みは成功します。

Quadraphonicを試しFormat.nChannels = 4; dwChannelMask = 0x33;てみると、IEEE-float と PCM の両方のwaveOutOpen試行が で失敗しWAVERR_BADFORMATます。

ただし、設定Format.cbSize = 0;すると、いずれかの形式の 2 チャネルですべてが正しく機能します。これは、基本的に以前に行っていたことであるため、理にかなっていWAVEFORMATEXます。ただし、これは 4 チャンネルでは機能しません。

ここで何が間違っていますか? 私の最終的な目標は、クアドラフォニックまたは IEEE-float 形式の 5.1 サラウンド出力です。ステレオ IEEE-float 出力を使用して動作させることさえできない理由に特に困惑してWAVEFORMATEXTENSIBLEいますが、 では完全に動作しWAVEFORMATEXます。

4

1 に答える 1

1

構造体を使用している場合はWAVEFORMATEXTENSIBLE、「base」に正しい形式タグを設定して、それを示す必要がありますWAVEFORMATEX

wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;

WAVEFORMATEXTENSIBLEの Format メンバーのドキュメントを参照してください。

これにより、呼び出されたコード ( へのポインターのみを持つ) が、 を扱っているか構造体WAVEFORMATEXを扱っているかを識別できるようになります。 実際のオーディオ形式の場合、メンバーによって一意に識別されます。WAVEFORMATEXWAVEFORMATEXTENSIBLE
WAVEFORMATEXTENSIBLESubFormat

于 2021-01-27T12:21:38.553 に答える