static ALCboolean DSoundResetPlayback(ALCdevice *device) { DSoundPlaybackData *data = (DSoundPlaybackData*)device->ExtraData; DSBUFFERDESC DSBDescription; WAVEFORMATEXTENSIBLE OutputType; DWORD speakers; HRESULT hr; memset(&OutputType, 0, sizeof(OutputType)); if(data->Notifies) IDirectSoundNotify_Release(data->Notifies); data->Notifies = NULL; if(data->Buffer) IDirectSoundBuffer_Release(data->Buffer); data->Buffer = NULL; if(data->PrimaryBuffer != NULL) IDirectSoundBuffer_Release(data->PrimaryBuffer); data->PrimaryBuffer = NULL; switch(device->FmtType) { case DevFmtByte: device->FmtType = DevFmtUByte; break; case DevFmtFloat: if((device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)) break; /* fall-through */ case DevFmtUShort: device->FmtType = DevFmtShort; break; case DevFmtUInt: device->FmtType = DevFmtInt; break; case DevFmtUByte: case DevFmtShort: case DevFmtInt: break; } hr = IDirectSound_GetSpeakerConfig(data->DS, &speakers); if(SUCCEEDED(hr)) { if(!(device->Flags&DEVICE_CHANNELS_REQUEST)) { speakers = DSSPEAKER_CONFIG(speakers); if(speakers == DSSPEAKER_MONO) device->FmtChans = DevFmtMono; else if(speakers == DSSPEAKER_STEREO || speakers == DSSPEAKER_HEADPHONE) device->FmtChans = DevFmtStereo; else if(speakers == DSSPEAKER_QUAD) device->FmtChans = DevFmtQuad; else if(speakers == DSSPEAKER_5POINT1) device->FmtChans = DevFmtX51; else if(speakers == DSSPEAKER_7POINT1) device->FmtChans = DevFmtX71; else ERR("Unknown system speaker config: 0x%lx\n", speakers); } switch(device->FmtChans) { case DevFmtMono: OutputType.dwChannelMask = SPEAKER_FRONT_CENTER; break; case DevFmtStereo: OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; break; case DevFmtQuad: OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; break; case DevFmtX51: OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; break; case DevFmtX51Side: OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT; break; case DevFmtX61: OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_CENTER | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT; break; case DevFmtX71: 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; break; } retry_open: hr = S_OK; OutputType.Format.wFormatTag = WAVE_FORMAT_PCM; OutputType.Format.nChannels = ChannelsFromDevFmt(device->FmtChans); OutputType.Format.wBitsPerSample = BytesFromDevFmt(device->FmtType) * 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(OutputType.Format.nChannels > 2 || device->FmtType == DevFmtFloat) { OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample; OutputType.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); if(device->FmtType == DevFmtFloat) OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; else OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; if(data->PrimaryBuffer) IDirectSoundBuffer_Release(data->PrimaryBuffer); data->PrimaryBuffer = NULL; } else { if(SUCCEEDED(hr) && !data->PrimaryBuffer) { memset(&DSBDescription,0,sizeof(DSBUFFERDESC)); DSBDescription.dwSize=sizeof(DSBUFFERDESC); DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER; hr = IDirectSound_CreateSoundBuffer(data->DS, &DSBDescription, &data->PrimaryBuffer, NULL); } if(SUCCEEDED(hr)) hr = IDirectSoundBuffer_SetFormat(data->PrimaryBuffer,&OutputType.Format); } if(SUCCEEDED(hr)) { if(device->NumUpdates > MAX_UPDATES) { device->UpdateSize = (device->UpdateSize*device->NumUpdates + MAX_UPDATES-1) / MAX_UPDATES; device->NumUpdates = MAX_UPDATES; } memset(&DSBDescription,0,sizeof(DSBUFFERDESC)); DSBDescription.dwSize=sizeof(DSBUFFERDESC); DSBDescription.dwFlags=DSBCAPS_CTRLPOSITIONNOTIFY|DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_GLOBALFOCUS; DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates * OutputType.Format.nBlockAlign; DSBDescription.lpwfxFormat=&OutputType.Format; hr = IDirectSound_CreateSoundBuffer(data->DS, &DSBDescription, &data->Buffer, NULL); if(FAILED(hr) && device->FmtType == DevFmtFloat) { device->FmtType = DevFmtShort; goto retry_open; } } if(SUCCEEDED(hr)) { hr = IDirectSoundBuffer_QueryInterface(data->Buffer, &IID_IDirectSoundNotify, (LPVOID *)&data->Notifies); if(SUCCEEDED(hr)) { DSBPOSITIONNOTIFY notifies[MAX_UPDATES]; ALuint i; for(i = 0;i < device->NumUpdates;++i) { notifies[i].dwOffset = i * device->UpdateSize * OutputType.Format.nBlockAlign; notifies[i].hEventNotify = data->NotifyEvent; } if(IDirectSoundNotify_SetNotificationPositions(data->Notifies, device->NumUpdates, notifies) != DS_OK) hr = E_FAIL; } } if(FAILED(hr)) { if(data->Notifies != NULL) IDirectSoundNotify_Release(data->Notifies); data->Notifies = NULL; if(data->Buffer != NULL) IDirectSoundBuffer_Release(data->Buffer); data->Buffer = NULL; if(data->PrimaryBuffer != NULL) IDirectSoundBuffer_Release(data->PrimaryBuffer); data->PrimaryBuffer = NULL; return ALC_FALSE; } ResetEvent(data->NotifyEvent); SetDefaultWFXChannelOrder(device); return ALC_TRUE; }
static void IDirectSound_test(LPDIRECTSOUND dso, BOOL initialized, LPCGUID lpGuid) { HRESULT rc; DSCAPS dscaps; int ref; IUnknown * unknown; IDirectSound * ds; IDirectSound8 * ds8; DWORD speaker_config, new_speaker_config; /* Try to Query for objects */ rc=IDirectSound_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown); ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IUnknown) failed: %s\n", DXGetErrorString8(rc)); if (rc==DS_OK) IDirectSound_Release(unknown); rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds); ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IDirectSound) failed: %s\n", DXGetErrorString8(rc)); if (rc==DS_OK) IDirectSound_Release(ds); rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8); ok(rc==E_NOINTERFACE,"IDirectSound_QueryInterface(IID_IDirectSound8) " "should have failed: %s\n",DXGetErrorString8(rc)); if (rc==DS_OK) IDirectSound8_Release(ds8); if (initialized == FALSE) { /* try unitialized object */ rc=IDirectSound_GetCaps(dso,0); ok(rc==DSERR_UNINITIALIZED,"IDirectSound_GetCaps(NULL) " "should have returned DSERR_UNINITIALIZED, returned: %s\n", DXGetErrorString8(rc)); rc=IDirectSound_GetCaps(dso,&dscaps); ok(rc==DSERR_UNINITIALIZED,"IDirectSound_GetCaps() " "should have returned DSERR_UNINITIALIZED, returned: %s\n", DXGetErrorString8(rc)); rc=IDirectSound_Compact(dso); ok(rc==DSERR_UNINITIALIZED,"IDirectSound_Compact() " "should have returned DSERR_UNINITIALIZED, returned: %s\n", DXGetErrorString8(rc)); rc=IDirectSound_GetSpeakerConfig(dso,&speaker_config); ok(rc==DSERR_UNINITIALIZED,"IDirectSound_GetSpeakerConfig() " "should have returned DSERR_UNINITIALIZED, returned: %s\n", DXGetErrorString8(rc)); rc=IDirectSound_Initialize(dso,lpGuid); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, "IDirectSound_Initialize() failed: %s\n",DXGetErrorString8(rc)); if (rc==DSERR_NODRIVER) { trace(" No Driver\n"); goto EXIT; } else if (rc==E_FAIL) { trace(" No Device\n"); goto EXIT; } else if (rc==DSERR_ALLOCATED) { trace(" Already In Use\n"); goto EXIT; } } rc=IDirectSound_Initialize(dso,lpGuid); ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSound_Initialize() " "should have returned DSERR_ALREADYINITIALIZED: %s\n", DXGetErrorString8(rc)); /* DSOUND: Error: Invalid caps buffer */ rc=IDirectSound_GetCaps(dso,0); ok(rc==DSERR_INVALIDPARAM,"IDirectSound_GetCaps(NULL) " "should have returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc)); ZeroMemory(&dscaps, sizeof(dscaps)); /* DSOUND: Error: Invalid caps buffer */ rc=IDirectSound_GetCaps(dso,&dscaps); ok(rc==DSERR_INVALIDPARAM,"IDirectSound_GetCaps() " "should have returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc)); dscaps.dwSize=sizeof(dscaps); /* DSOUND: Running on a certified driver */ rc=IDirectSound_GetCaps(dso,&dscaps); ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc)); rc=IDirectSound_Compact(dso); ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound_Compact() failed: %s\n", DXGetErrorString8(rc)); rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n", DXGetErrorString8(rc)); rc=IDirectSound_Compact(dso); ok(rc==DS_OK,"IDirectSound_Compact() failed: %s\n",DXGetErrorString8(rc)); rc=IDirectSound_GetSpeakerConfig(dso,0); ok(rc==DSERR_INVALIDPARAM,"IDirectSound_GetSpeakerConfig(NULL) " "should have returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc)); rc=IDirectSound_GetSpeakerConfig(dso,&speaker_config); ok(rc==DS_OK,"IDirectSound_GetSpeakerConfig() failed: %s\n", DXGetErrorString8(rc)); speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_WIDE); rc=IDirectSound_SetSpeakerConfig(dso,speaker_config); ok(rc==DS_OK,"IDirectSound_SetSpeakerConfig() failed: %s\n", DXGetErrorString8(rc)); if (rc==DS_OK) { rc=IDirectSound_GetSpeakerConfig(dso,&new_speaker_config); ok(rc==DS_OK,"IDirectSound_GetSpeakerConfig() failed: %s\n", DXGetErrorString8(rc)); if (rc==DS_OK && speaker_config!=new_speaker_config) trace("IDirectSound_GetSpeakerConfig() failed to set speaker " "config: expected 0x%08lx, got 0x%08lx\n", speaker_config,new_speaker_config); } EXIT: ref=IDirectSound_Release(dso); ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); }
static ALCboolean DSoundResetPlayback(ALCdevice *device) { DSoundData *pData = (DSoundData*)device->ExtraData; DSBUFFERDESC DSBDescription; WAVEFORMATEXTENSIBLE OutputType; DWORD speakers; HRESULT hr; memset(&OutputType, 0, sizeof(OutputType)); switch(device->FmtType) { case DevFmtByte: device->FmtType = DevFmtUByte; break; case DevFmtUShort: device->FmtType = DevFmtShort; break; case DevFmtUByte: case DevFmtShort: case DevFmtFloat: break; } hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers); if(SUCCEEDED(hr) && ConfigValueExists(NULL, "format")) { switch(device->FmtChans) { case DevFmtMono: speakers = DSSPEAKER_COMBINED(DSSPEAKER_MONO, 0); break; case DevFmtStereo: speakers = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, 0); break; case DevFmtQuad: speakers = DSSPEAKER_COMBINED(DSSPEAKER_QUAD, 0); break; case DevFmtX51: speakers = DSSPEAKER_COMBINED(DSSPEAKER_5POINT1, 0); break; case DevFmtX61: /* ??? */ ; break; case DevFmtX71: speakers = DSSPEAKER_COMBINED(DSSPEAKER_7POINT1, 0); break; } } if(SUCCEEDED(hr)) { speakers = DSSPEAKER_CONFIG(speakers); if(speakers == DSSPEAKER_MONO) { device->FmtChans = DevFmtMono; OutputType.dwChannelMask = SPEAKER_FRONT_CENTER; } else if(speakers == DSSPEAKER_STEREO || speakers == DSSPEAKER_HEADPHONE) { device->FmtChans = DevFmtStereo; OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; } else if(speakers == DSSPEAKER_QUAD) { device->FmtChans = DevFmtQuad; OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; } else if(speakers == DSSPEAKER_5POINT1) { device->FmtChans = DevFmtX51; 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) { device->FmtChans = DevFmtX71; 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; } OutputType.Format.wFormatTag = WAVE_FORMAT_PCM; OutputType.Format.nChannels = ChannelsFromDevFmt(device->FmtChans); OutputType.Format.wBitsPerSample = BytesFromDevFmt(device->FmtType) * 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(OutputType.Format.nChannels > 2 || OutputType.Format.wBitsPerSample > 16) { OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample; OutputType.Format.cbSize = 22; if(OutputType.Format.wBitsPerSample == 32) OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; else 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)) { memset(&DSBDescription,0,sizeof(DSBUFFERDESC)); DSBDescription.dwSize=sizeof(DSBUFFERDESC); DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2; DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates * OutputType.Format.nBlockAlign; DSBDescription.lpwfxFormat=&OutputType.Format; hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL); } if(SUCCEEDED(hr)) { SetDefaultWFXChannelOrder(device); pData->thread = StartThread(DSoundProc, device); if(!pData->thread) hr = E_FAIL; } if(FAILED(hr)) { if (pData->DSsbuffer) IDirectSoundBuffer_Release(pData->DSsbuffer); pData->DSsbuffer = NULL; if (pData->DSpbuffer) IDirectSoundBuffer_Release(pData->DSpbuffer); pData->DSpbuffer = NULL; return ALC_FALSE; } return ALC_TRUE; }
static ALCboolean DSoundResetPlayback(ALCdevice *device) { DSoundData *pData = (DSoundData*)device->ExtraData; DSBUFFERDESC DSBDescription; WAVEFORMATEXTENSIBLE OutputType; DWORD frameSize = 0; ALenum format = 0; DWORD speakers; HRESULT hr; memset(&OutputType, 0, sizeof(OutputType)); hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers); if(SUCCEEDED(hr) && ConfigValueExists(NULL, "format")) { if(aluChannelsFromFormat(device->Format) == 1) speakers = DSSPEAKER_COMBINED(DSSPEAKER_MONO, 0); else if(aluChannelsFromFormat(device->Format) == 2) speakers = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, 0); else if(aluChannelsFromFormat(device->Format) == 4) speakers = DSSPEAKER_COMBINED(DSSPEAKER_QUAD, 0); else if(aluChannelsFromFormat(device->Format) == 6) speakers = DSSPEAKER_COMBINED(DSSPEAKER_5POINT1, 0); else if(aluChannelsFromFormat(device->Format) == 8) speakers = DSSPEAKER_COMBINED(DSSPEAKER_7POINT1, 0); else { AL_PRINT("Unknown format: 0x%x\n", device->Format); return ALC_FALSE; } } if(SUCCEEDED(hr)) { speakers = DSSPEAKER_CONFIG(speakers); if(speakers == DSSPEAKER_MONO) { if(aluBytesFromFormat(device->Format) == 1) format = AL_FORMAT_MONO8; else if(aluBytesFromFormat(device->Format) == 2) format = AL_FORMAT_MONO16; else if(aluBytesFromFormat(device->Format) == 4) format = AL_FORMAT_MONO_FLOAT32; OutputType.dwChannelMask = SPEAKER_FRONT_CENTER; } else if(speakers == DSSPEAKER_STEREO) { if(aluBytesFromFormat(device->Format) == 1) format = AL_FORMAT_STEREO8; else if(aluBytesFromFormat(device->Format) == 2) format = AL_FORMAT_STEREO16; else if(aluBytesFromFormat(device->Format) == 4) format = AL_FORMAT_STEREO_FLOAT32; OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; } else if(speakers == DSSPEAKER_QUAD) { if(aluBytesFromFormat(device->Format) == 1) format = AL_FORMAT_QUAD8; else if(aluBytesFromFormat(device->Format) == 2) format = AL_FORMAT_QUAD16; else if(aluBytesFromFormat(device->Format) == 4) format = AL_FORMAT_QUAD32; OutputType.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; } else if(speakers == DSSPEAKER_5POINT1) { if(aluBytesFromFormat(device->Format) == 1) format = AL_FORMAT_51CHN8; else if(aluBytesFromFormat(device->Format) == 2) format = AL_FORMAT_51CHN16; else if(aluBytesFromFormat(device->Format) == 4) format = AL_FORMAT_51CHN32; 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) { if(aluBytesFromFormat(device->Format) == 1) format = AL_FORMAT_71CHN8; else if(aluBytesFromFormat(device->Format) == 2) format = AL_FORMAT_71CHN16; else if(aluBytesFromFormat(device->Format) == 4) format = AL_FORMAT_71CHN32; 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; } else format = device->Format; frameSize = aluFrameSizeFromFormat(format); OutputType.Format.wFormatTag = WAVE_FORMAT_PCM; OutputType.Format.nChannels = aluChannelsFromFormat(format); OutputType.Format.wBitsPerSample = aluBytesFromFormat(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(OutputType.Format.nChannels > 2 || OutputType.Format.wBitsPerSample > 16) { OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample; OutputType.Format.cbSize = 22; if(OutputType.Format.wBitsPerSample == 32) OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; else 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)) { memset(&DSBDescription,0,sizeof(DSBUFFERDESC)); DSBDescription.dwSize=sizeof(DSBUFFERDESC); DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2; DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates * frameSize; DSBDescription.lpwfxFormat=&OutputType.Format; hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL); } if(SUCCEEDED(hr)) hr = IDirectSoundBuffer_Play(pData->DSsbuffer, 0, 0, DSBPLAY_LOOPING); if(SUCCEEDED(hr)) { device->Format = format; SetDefaultWFXChannelOrder(device); pData->thread = StartThread(DSoundProc, device); if(!pData->thread) hr = E_FAIL; } if(FAILED(hr)) { if (pData->DSsbuffer) IDirectSoundBuffer_Release(pData->DSsbuffer); pData->DSsbuffer = NULL; if (pData->DSpbuffer) IDirectSoundBuffer_Release(pData->DSpbuffer); pData->DSpbuffer = NULL; return ALC_FALSE; } return ALC_TRUE; }
static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName) { DSBUFFERDESC DSBDescription; DSoundData *pData = NULL; WAVEFORMATEXTENSIBLE OutputType; DWORD frameSize = 0; LPGUID guid = NULL; DWORD speakers; HRESULT hr; if(deviceName) { int i; for(i = 0;DeviceList[i].name;i++) { if(strcmp(deviceName, DeviceList[i].name) == 0) { device->szDeviceName = DeviceList[i].name; if(i > 0) guid = &DeviceList[i].guid; break; } } if(!DeviceList[i].name) return ALC_FALSE; } else device->szDeviceName = DeviceList[0].name; memset(&OutputType, 0, sizeof(OutputType)); //Initialise requested device pData = calloc(1, sizeof(DSoundData)); if(!pData) { SetALCError(ALC_OUT_OF_MEMORY); return ALC_FALSE; } //DirectSound Init code hr = DirectSoundCreate(guid, &pData->lpDS, NULL); if(SUCCEEDED(hr)) hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY); if(SUCCEEDED(hr)) hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers); if(SUCCEEDED(hr)) { speakers = DSSPEAKER_CONFIG(speakers); if(speakers == DSSPEAKER_MONO) { if(aluBytesFromFormat(device->Format) == 1) device->Format = AL_FORMAT_MONO8; else device->Format = AL_FORMAT_MONO16; } else if(speakers == DSSPEAKER_STEREO) { if(aluBytesFromFormat(device->Format) == 1) device->Format = AL_FORMAT_STEREO8; else device->Format = AL_FORMAT_STEREO16; } else if(speakers == DSSPEAKER_QUAD) { if(aluBytesFromFormat(device->Format) == 1) 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) { if(aluBytesFromFormat(device->Format) == 1) 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) { if(aluBytesFromFormat(device->Format) == 1) 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; } frameSize = aluBytesFromFormat(device->Format) * aluChannelsFromFormat(device->Format); 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; device->UpdateSize /= DS_FRAGS; } if(OutputType.Format.nChannels > 2) { 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)) { memset(&DSBDescription,0,sizeof(DSBUFFERDESC)); DSBDescription.dwSize=sizeof(DSBUFFERDESC); DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2; DSBDescription.dwBufferBytes=device->UpdateSize * DS_FRAGS * frameSize; DSBDescription.lpwfxFormat=&OutputType.Format; hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL); } if(SUCCEEDED(hr)) hr = IDirectSoundBuffer_Play(pData->DSsbuffer, 0, 0, DSBPLAY_LOOPING); device->ExtraData = pData; pData->thread = StartThread(DSoundProc, device); if(!pData->thread) hr = E_FAIL; if(FAILED(hr)) { if (pData->DSsbuffer) IDirectSoundBuffer_Release(pData->DSsbuffer); if (pData->DSpbuffer) IDirectSoundBuffer_Release(pData->DSpbuffer); if (pData->lpDS) IDirectSound_Release(pData->lpDS); free(pData); return ALC_FALSE; } return ALC_TRUE; }