From 655a83c5c54c7e604f9d9f53fbf34bc85149d392 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 1 Feb 2008 08:17:57 -0800 Subject: [PATCH] Use WAVEFORMATEXTENSIBLE for multichannel dsound output, and don't create a primary buffer --- Alc/dsound.c | 69 ++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/Alc/dsound.c b/Alc/dsound.c index 41248961..313284c6 100644 --- a/Alc/dsound.c +++ b/Alc/dsound.c @@ -20,12 +20,14 @@ #include "config.h" +#define INITGUID #include #include #include #include #include +#include #include #include "alMain.h" @@ -36,6 +38,8 @@ #define DSSPEAKER_7POINT1 7 #endif +DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); + typedef struct { // DirectSound Playback Device LPDIRECTSOUND lpDS; @@ -118,7 +122,7 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam { DSBUFFERDESC DSBDescription; DSoundData *pData = NULL; - WAVEFORMATEX OutputType; + WAVEFORMATEXTENSIBLE OutputType; DWORD speakers; HRESULT hr; @@ -139,7 +143,7 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam else device->szDeviceName = DeviceList[0]; - memset(&OutputType, 0, sizeof(WAVEFORMATEX)); + memset(&OutputType, 0, sizeof(OutputType)); //Initialise requested device @@ -185,6 +189,10 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam device->Format = AL_FORMAT_QUAD8; else device->Format = AL_FORMAT_QUAD16; + OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | + SPEAKER_FRONT_RIGHT | + SPEAKER_BACK_LEFT | + SPEAKER_BACK_RIGHT; } else if(speakers == DSSPEAKER_5POINT1) { @@ -192,6 +200,12 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam device->Format = AL_FORMAT_51CHN8; else device->Format = AL_FORMAT_51CHN16; + OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | + SPEAKER_FRONT_RIGHT | + SPEAKER_FRONT_CENTER | + SPEAKER_LOW_FREQUENCY | + SPEAKER_BACK_LEFT | + SPEAKER_BACK_RIGHT; } else if(speakers == DSSPEAKER_7POINT1) { @@ -199,28 +213,46 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam device->Format = AL_FORMAT_71CHN8; else device->Format = AL_FORMAT_71CHN16; + OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | + SPEAKER_FRONT_RIGHT | + SPEAKER_FRONT_CENTER | + SPEAKER_LOW_FREQUENCY | + SPEAKER_BACK_LEFT | + SPEAKER_BACK_RIGHT | + SPEAKER_SIDE_LEFT | + SPEAKER_SIDE_RIGHT; } device->FrameSize = aluBytesFromFormat(device->Format) * aluChannelsFromFormat(device->Format); - OutputType.wFormatTag = WAVE_FORMAT_PCM; - OutputType.nChannels = aluChannelsFromFormat(device->Format); - OutputType.wBitsPerSample = aluBytesFromFormat(device->Format) * 8; - OutputType.nBlockAlign = OutputType.nChannels*OutputType.wBitsPerSample/8; - OutputType.nSamplesPerSec = device->Frequency; - OutputType.nAvgBytesPerSec = OutputType.nSamplesPerSec*OutputType.nBlockAlign; - OutputType.cbSize = 0; + OutputType.Format.wFormatTag = WAVE_FORMAT_PCM; + OutputType.Format.nChannels = aluChannelsFromFormat(device->Format); + OutputType.Format.wBitsPerSample = aluBytesFromFormat(device->Format) * 8; + OutputType.Format.nBlockAlign = OutputType.Format.nChannels*OutputType.Format.wBitsPerSample/8; + OutputType.Format.nSamplesPerSec = device->Frequency; + OutputType.Format.nAvgBytesPerSec = OutputType.Format.nSamplesPerSec*OutputType.Format.nBlockAlign; + OutputType.Format.cbSize = 0; } - if(SUCCEEDED(hr)) + if(OutputType.Format.nChannels > 2) { - memset(&DSBDescription,0,sizeof(DSBUFFERDESC)); - DSBDescription.dwSize=sizeof(DSBUFFERDESC); - DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER; - hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSpbuffer, NULL); + OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample; + OutputType.Format.cbSize = 22; + OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + } + else + { + if(SUCCEEDED(hr)) + { + memset(&DSBDescription,0,sizeof(DSBUFFERDESC)); + DSBDescription.dwSize=sizeof(DSBUFFERDESC); + DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER; + hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSpbuffer, NULL); + } + if(SUCCEEDED(hr)) + hr = IDirectSoundBuffer_SetFormat(pData->DSpbuffer,&OutputType.Format); } - if(SUCCEEDED(hr)) - hr = IDirectSoundBuffer_SetFormat(pData->DSpbuffer,&OutputType); if(SUCCEEDED(hr)) { @@ -228,7 +260,7 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam DSBDescription.dwSize=sizeof(DSBUFFERDESC); DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2; DSBDescription.dwBufferBytes=device->UpdateFreq * device->FrameSize; - DSBDescription.lpwfxFormat=&OutputType; + DSBDescription.lpwfxFormat=&OutputType.Format; hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL); } @@ -264,7 +296,8 @@ static void DSoundClosePlayback(ALCdevice *device) StopThread(pData->thread); IDirectSoundBuffer_Release(pData->DSsbuffer); - IDirectSoundBuffer_Release(pData->DSpbuffer); + if (pData->DSpbuffer) + IDirectSoundBuffer_Release(pData->DSpbuffer); IDirectSound_Release(pData->lpDS); //Deinit COM -- 2.11.4.GIT