Incorrect audio device being selected using SDL_OpenAudioDeviceName()


#1

I am trying to select the default audio device, but I’m running into a problem where the wrong device is being selected. I believe this has something to do with the fact that the names are identical for both of my connected monitors, but I could be wrong.

QAudioDeviceInfo ad_info(QAudioDeviceInfo::defaultOutputDevice());
std::string default_audio_device_name = ad_info.deviceName().toStdString();
printf("Default audio device name: %s\n", default_audio_device_name.c_str());

printf("Enumerating audio devices...\n");
int default_id = NULL;
for (int i = 0; i < SDL_GetNumAudioDevices(0); i++)
{
    printf("Id (%d) Audio device name: %s\n", i, SDL_GetAudioDeviceName(i, 0));

    if (default_audio_device_name.compare(SDL_GetAudioDeviceName(i, 0)) == 0)
    {
        printf("    Found default id (%d)\n", i, SDL_GetAudioDeviceName(i, 0));

        default_id = i;
        break;
    }
}

int playback_device_id = SDL_OpenAudioDevice(SDL_GetAudioDeviceName(default_id, 0), 0, &_audio_spec_desired, &_audio_spec_obtained, 0);
printf("Selected audio device: %s\n", SDL_GetAudioDeviceName(playback_device_id, 0));

This code produces the following output and selects the incorrect device:

Default audio device name: Speakers (Realtek® Audio)
Enumerating audio devices…
Id (0) Audio device name: Realtek Digital Output (Realtek® Audio)
Id (1) Audio device name: BenQ GW2765 (NVIDIA High Definition Audio)
Id (2) Audio device name: BenQ GW2765 (NVIDIA High Definition Audio) (2)
Id (3) Audio device name: Speakers (Realtek® Audio)
Found default id (3)
Selected audio device: BenQ GW2765 (NVIDIA High Definition Audio) (2)
Successfully opened audio device: BenQ GW2765 (NVIDIA High Definition Audio) (2)

Device 1 and 2 are monitors with the same name. If I unplug one of the monitors, the default device is properly selected.

Any help would be appreciated.

Version: SDL2-2.0.9-win32-x64 (which I downloaded from the website last night 12/4/2018)

As a side note, is there any way get the current default device without having to go through what is above? It happens to work for me, but I have to include an entire Qt module just to use that QAudioDeviceInfo class. Using SDL_OpenAudio() or passing NULL as the argument to SDL_OpenAudioDevice() returns the wrong device.


#2

int playback_device_id = SDL_OpenAudioDevice(SDL_GetAudioDeviceName(default_id, 0), 0, &_audio_spec_desired, &_audio_spec_obtained, 0);
printf("Selected audio device: %s\n", SDL_GetAudioDeviceName(playback_device_id, 0));

SDL_OpenAudioDevice() does not return an index that can be used with SDL_GetAudioDeviceName().

It returns a device handle that happens to be a number >= 2 on success (because the legacy API from 1.2 uses device handle 1 on success, and everything else is treated as invalid).

If you called SDL_OpenAudioDevice() with a specific string instead of NULL, you should have gotten exactly that device (all the strings returned by SDL are unique, which is why one of them has a " (2)" at the end).

I don’t know what QAudioDeviceInfo does, but it’s likely it won’t match SDL’s device list exactly.