@@ -120,7 +120,7 @@ void SDL_IMMDevice_FreeDeviceHandle(SDL_AudioDevice *device)
120
120
}
121
121
}
122
122
123
- static SDL_AudioDevice * SDL_IMMDevice_Add (const bool recording , const char * devname , WAVEFORMATEXTENSIBLE * fmt , LPCWSTR devid , GUID * dsoundguid )
123
+ static SDL_AudioDevice * SDL_IMMDevice_Add (const bool recording , const char * devname , WAVEFORMATEXTENSIBLE * fmt , LPCWSTR devid , GUID * dsoundguid , SDL_AudioFormat force_format )
124
124
{
125
125
/* You can have multiple endpoints on a device that are mutually exclusive ("Speakers" vs "Line Out" or whatever).
126
126
In a perfect world, things that are unplugged won't be in this collection. The only gotcha is probably for
@@ -162,7 +162,7 @@ static SDL_AudioDevice *SDL_IMMDevice_Add(const bool recording, const char *devn
162
162
SDL_zero (spec );
163
163
spec .channels = (Uint8 )fmt -> Format .nChannels ;
164
164
spec .freq = fmt -> Format .nSamplesPerSec ;
165
- spec .format = SDL_WaveFormatExToSDLFormat ((WAVEFORMATEX * )fmt );
165
+ spec .format = ( force_format != SDL_AUDIO_UNKNOWN ) ? force_format : SDL_WaveFormatExToSDLFormat ((WAVEFORMATEX * )fmt );
166
166
167
167
device = SDL_AddAudioDevice (recording , devname , & spec , handle );
168
168
if (!device ) {
@@ -183,6 +183,7 @@ typedef struct SDLMMNotificationClient
183
183
{
184
184
const IMMNotificationClientVtbl * lpVtbl ;
185
185
SDL_AtomicInt refcount ;
186
+ SDL_AudioFormat force_format ;
186
187
} SDLMMNotificationClient ;
187
188
188
189
static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_QueryInterface (IMMNotificationClient * client , REFIID iid , void * * ppv )
@@ -241,6 +242,7 @@ static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceRemoved(IMMNoti
241
242
242
243
static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceStateChanged (IMMNotificationClient * iclient , LPCWSTR pwstrDeviceId , DWORD dwNewState )
243
244
{
245
+ SDLMMNotificationClient * client = (SDLMMNotificationClient * )iclient ;
244
246
IMMDevice * device = NULL ;
245
247
246
248
if (SUCCEEDED (IMMDeviceEnumerator_GetDevice (enumerator , pwstrDeviceId , & device ))) {
@@ -255,7 +257,7 @@ static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceStateChanged(IM
255
257
GUID dsoundguid ;
256
258
GetMMDeviceInfo (device , & utf8dev , & fmt , & dsoundguid );
257
259
if (utf8dev ) {
258
- SDL_IMMDevice_Add (recording , utf8dev , & fmt , pwstrDeviceId , & dsoundguid );
260
+ SDL_IMMDevice_Add (recording , utf8dev , & fmt , pwstrDeviceId , & dsoundguid , client -> force_format );
259
261
SDL_free (utf8dev );
260
262
}
261
263
} else {
@@ -286,7 +288,7 @@ static const IMMNotificationClientVtbl notification_client_vtbl = {
286
288
SDLMMNotificationClient_OnPropertyValueChanged
287
289
};
288
290
289
- static SDLMMNotificationClient notification_client = { & notification_client_vtbl , { 1 } };
291
+ static SDLMMNotificationClient notification_client = { & notification_client_vtbl , { 1 }, SDL_AUDIO_UNKNOWN };
290
292
291
293
bool SDL_IMMDevice_Init (const SDL_IMMDevice_callbacks * callbacks )
292
294
{
@@ -363,7 +365,7 @@ bool SDL_IMMDevice_Get(SDL_AudioDevice *device, IMMDevice **immdevice, bool reco
363
365
return true;
364
366
}
365
367
366
- static void EnumerateEndpointsForFlow (const bool recording , SDL_AudioDevice * * default_device )
368
+ static void EnumerateEndpointsForFlow (const bool recording , SDL_AudioDevice * * default_device , SDL_AudioFormat force_format )
367
369
{
368
370
/* Note that WASAPI separates "adapter devices" from "audio endpoint devices"
369
371
...one adapter device ("SoundBlaster Pro") might have multiple endpoint devices ("Speakers", "Line-Out"). */
@@ -405,7 +407,7 @@ static void EnumerateEndpointsForFlow(const bool recording, SDL_AudioDevice **de
405
407
SDL_zero (dsoundguid );
406
408
GetMMDeviceInfo (immdevice , & devname , & fmt , & dsoundguid );
407
409
if (devname ) {
408
- SDL_AudioDevice * sdldevice = SDL_IMMDevice_Add (recording , devname , & fmt , devid , & dsoundguid );
410
+ SDL_AudioDevice * sdldevice = SDL_IMMDevice_Add (recording , devname , & fmt , devid , & dsoundguid , force_format );
409
411
if (default_device && default_devid && SDL_wcscmp (default_devid , devid ) == 0 ) {
410
412
* default_device = sdldevice ;
411
413
}
@@ -422,10 +424,12 @@ static void EnumerateEndpointsForFlow(const bool recording, SDL_AudioDevice **de
422
424
IMMDeviceCollection_Release (collection );
423
425
}
424
426
425
- void SDL_IMMDevice_EnumerateEndpoints (SDL_AudioDevice * * default_playback , SDL_AudioDevice * * default_recording )
427
+ void SDL_IMMDevice_EnumerateEndpoints (SDL_AudioDevice * * default_playback , SDL_AudioDevice * * default_recording , SDL_AudioFormat force_format )
426
428
{
427
- EnumerateEndpointsForFlow (false, default_playback );
428
- EnumerateEndpointsForFlow (true, default_recording );
429
+ EnumerateEndpointsForFlow (false, default_playback , force_format );
430
+ EnumerateEndpointsForFlow (true, default_recording , force_format );
431
+
432
+ notification_client .force_format = force_format ;
429
433
430
434
// if this fails, we just won't get hotplug events. Carry on anyhow.
431
435
IMMDeviceEnumerator_RegisterEndpointNotificationCallback (enumerator , (IMMNotificationClient * )& notification_client );
0 commit comments