We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 4202 - [Feature Request] Make getting the default audio device consistent
Summary: [Feature Request] Make getting the default audio device consistent
Status: RESOLVED WONTFIX
Alias: None
Product: SDL
Classification: Unclassified
Component: audio (show other bugs)
Version: HG 2.0
Hardware: All All
: P2 major
Assignee: Ryan C. Gordon
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-06-15 16:29 UTC by Ethan Lee
Modified: 2018-06-19 16:38 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ethan Lee 2018-06-15 16:29:38 UTC
At the moment there is no way to determine which device is the default in SDL's audio device list. While some backends do this for you, on Windows/macOS it is possible to have other devices get the first spot. The easiest example is to plug a laptop to a TV/receiver via HDMI, set the HDMI output as default, and run this:

/* Set want/have to whatever... */
SDL_OpenAudioDevice(
    SDL_GetAudioDeviceName(0),
    0,
    &want,
    &have,
    0
);

You'll probably get the laptop speakers instead of the HDMI output!

This is particularly painful for libraries that expose the device list and thus always expect a device index (meaning 0 is usually the default):

https://github.com/flibitijibibo/FACT/commit/048e7f5372d3e315fca24101e1c34051ad320077

There are two ways we can fix this:

1. Forcibly make device 0 the OS' default device. This is the easiest from the user end but could be ugly in the backend (especially when hotplugging gets involved).

2. Add SDL_GetDefaultAudioDeviceName(int iscapture), which just gives us the name of the global default. This is easier to implement but means we're adding another function, so legacy applications will still have the issue.

I'm leaning towards #1, but I'm biased because it would map well to how XAudio2 enumerates devices and #2 would just make me want to pile on stuff like XAudio2 device roles:

https://github.com/flibitijibibo/FACT/blob/048e7f5372d3e315fca24101e1c34051ad320077/src/FAudio.h#L57
Comment 1 Ryan C. Gordon 2018-06-19 16:38:18 UTC
The problems we have here:

1) SDL doesn't usually know which device is the default in its list.
2) The default might not even be _in the list_.
3) The default can change (if a device is disconnected or the user changed it in their system preferences, etc).
4) Lots of platforms treat the "default" differently (CoreAudio, for example, will let you explicitly open what happens to be the default device by name, and if it's disconnected, you'll lose output, but if you open the "default" device without naming it, it'll seamlessly switch to the new default when there are changes).

In the example you give, you don't want to use SDL_GetAudioDeviceName(0), you want to use NULL, and let SDL (and the OS) figure it out for you.

My recommendation is that you expose a fake device in FACT called '[System Default]' and if the app picks that, pass a NULL to SDL_OpenAudioDevice(). In many cases, in any API--SDL or otherwise--specifically picking a device is the wrong move.


--ryan.