Audio device hotplug

Perhaps a little too boldly, the audio subsystem got ripped up a lot
while we’re trying to stabilize 2.0.4, so, uh, sorry about that.

SDL now supports hotplugging of audio devices. Here are the basic notes
on it.

  • You can listen for SDL_AUDIODEVICEADDED and SDL_AUDIODEVICEREMOVED
    events, like any other event.

  • ADDED events are always sent (unless you have the events specifically
    disabled, of course), REMOVED events only come through for devices you
    have opened at the moment. ADDED will tell you the new device index, so
    you can do SDL_GetAudioDeviceName($NEWINDEX) right away. REMOVED will
    tell you the SDL_AudioDeviceID of the opened device, so you can properly
    close it.

  • During audio subsystem initialization, all available devices are
    detected and ADDED events are sent for each, in case you would rather
    use that interface exclusively instead of calling SDL_GetNumAudioDevices().

  • If an opened device is removed or fails, SDL will keep firing the
    app’s audio callback at a regular interval and throwing away the
    supplied audio data, in case your app is counting on this callback to
    make progress. This means that existing apps will keep going properly
    (albeit without audio output) if you are using a USB headset and yank
    out its cable. This is a change from before, where behavior was undefined.

  • The device list from SDL_GetNumAudioDevices()/SDL_GetAudioDeviceName()
    remains stable until you call SDL_GetNumAudioDevices() again. This means
    that a removed device will still report its name at the same index, and
    added devices are appended to this list without changing the existing
    elements. Previously, full device redetection happened on each call to
    SDL_GetNumAudioDevices(), now the hotplug code manages that in
    increments. Note that device indices may change (because a removed
    device leaves the list) once you call GetNumAudioDevices() again,
    though. This should, however, protect existing programs from breakage,
    while making the pathological ones slightly faster.

  • All the existing backends support this. For audio targets that only
    support a default output device, SDL will fake a single ADDED event.
    Anything that notices when it fails to write to a device will send the
    REMOVED event. True, honest-to-god hotplug support is fully implemented
    for Mac OS X CoreAudio, and PulseAudio. A few others can support it but
    currently don’t: ALSA can hook up to udev on Linux, for example, but it
    isn’t written at the moment (if anyone wants to beat me to this, let me
    know and check out how we did this with the joystick udev support).

  • PulseAudio now reports human-readable device names to the app
    (“Built-in Audio Analog Stereo”) instead of device nodes
    (“alsa_output.pci-0000_00_1b.0.analog-stereo”).

  • Other cleanups, improvements, and optimizations were done. A lot of
    annoyances in the audio code are gone now, hooray. Not all of them,
    though. :slight_smile:

Questions, comments, or bug reports? Let me know.

–ryan.

currently don’t: ALSA can hook up to udev on Linux, for example, but it
isn’t written at the moment (if anyone wants to beat me to this, let me
know and check out how we did this with the joystick udev support).

(Uh, libasound might provide device events of some sort, actually, I
don’t know. Old school /dev/dsp stuff would need udev.)

–ryan.

Hi Ryan,

This sounds quite useful! Always nice to have the ability to react to
events like this.

I have two questions:

  1. You had mentioned that you wanted to improve the resampling code. Is
    this something that you are looking at for 2.0.4, or is this a later task?

  2. I would be very excited to see the recording feature being
    implemented. How far in the future would you estimate that this is?

Kind regards,

Philip BennefallOn 3/20/2015 5:28 AM, Ryan C. Gordon wrote:

Perhaps a little too boldly, the audio subsystem got ripped up a lot
while we’re trying to stabilize 2.0.4, so, uh, sorry about that.

SDL now supports hotplugging of audio devices. Here are the basic
notes on it.

  • You can listen for SDL_AUDIODEVICEADDED and SDL_AUDIODEVICEREMOVED
    events, like any other event.

  • ADDED events are always sent (unless you have the events
    specifically disabled, of course), REMOVED events only come through
    for devices you have opened at the moment. ADDED will tell you the new
    device index, so you can do SDL_GetAudioDeviceName($NEWINDEX) right
    away. REMOVED will tell you the SDL_AudioDeviceID of the opened
    device, so you can properly close it.

  • During audio subsystem initialization, all available devices are
    detected and ADDED events are sent for each, in case you would rather
    use that interface exclusively instead of calling
    SDL_GetNumAudioDevices().

  • If an opened device is removed or fails, SDL will keep firing the
    app’s audio callback at a regular interval and throwing away the
    supplied audio data, in case your app is counting on this callback to
    make progress. This means that existing apps will keep going properly
    (albeit without audio output) if you are using a USB headset and yank
    out its cable. This is a change from before, where behavior was
    undefined.

  • The device list from
    SDL_GetNumAudioDevices()/SDL_GetAudioDeviceName() remains stable until
    you call SDL_GetNumAudioDevices() again. This means that a removed
    device will still report its name at the same index, and added devices
    are appended to this list without changing the existing elements.
    Previously, full device redetection happened on each call to
    SDL_GetNumAudioDevices(), now the hotplug code manages that in
    increments. Note that device indices may change (because a removed
    device leaves the list) once you call GetNumAudioDevices() again,
    though. This should, however, protect existing programs from breakage,
    while making the pathological ones slightly faster.

  • All the existing backends support this. For audio targets that only
    support a default output device, SDL will fake a single ADDED event.
    Anything that notices when it fails to write to a device will send the
    REMOVED event. True, honest-to-god hotplug support is fully
    implemented for Mac OS X CoreAudio, and PulseAudio. A few others can
    support it but currently don’t: ALSA can hook up to udev on Linux, for
    example, but it isn’t written at the moment (if anyone wants to beat
    me to this, let me know and check out how we did this with the
    joystick udev support).

  • PulseAudio now reports human-readable device names to the app
    (“Built-in Audio Analog Stereo”) instead of device nodes
    (“alsa_output.pci-0000_00_1b.0.analog-stereo”).

  • Other cleanups, improvements, and optimizations were done. A lot of
    annoyances in the audio code are gone now, hooray. Not all of them,
    though. :slight_smile:

Questions, comments, or bug reports? Let me know.

–ryan.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
.

Two comments:

  • Great work!
  • Put all this on a README/Changelog/Wiki :slight_smile:

2015-03-20 1:28 GMT-03:00 Ryan C. Gordon :>

Perhaps a little too boldly, the audio subsystem got ripped up a lot while
we’re trying to stabilize 2.0.4, so, uh, sorry about that.

SDL now supports hotplugging of audio devices. Here are the basic notes on
it.

  • You can listen for SDL_AUDIODEVICEADDED and SDL_AUDIODEVICEREMOVED
    events, like any other event.

  • ADDED events are always sent (unless you have the events specifically
    disabled, of course), REMOVED events only come through for devices you have
    opened at the moment. ADDED will tell you the new device index, so you can
    do SDL_GetAudioDeviceName($NEWINDEX) right away. REMOVED will tell you
    the SDL_AudioDeviceID of the opened device, so you can properly close it.

  • During audio subsystem initialization, all available devices are
    detected and ADDED events are sent for each, in case you would rather use
    that interface exclusively instead of calling SDL_GetNumAudioDevices().

  • If an opened device is removed or fails, SDL will keep firing the app’s
    audio callback at a regular interval and throwing away the supplied audio
    data, in case your app is counting on this callback to make progress. This
    means that existing apps will keep going properly (albeit without audio
    output) if you are using a USB headset and yank out its cable. This is a
    change from before, where behavior was undefined.

  • The device list from SDL_GetNumAudioDevices()/SDL_GetAudioDeviceName()
    remains stable until you call SDL_GetNumAudioDevices() again. This means
    that a removed device will still report its name at the same index, and
    added devices are appended to this list without changing the existing
    elements. Previously, full device redetection happened on each call to
    SDL_GetNumAudioDevices(), now the hotplug code manages that in increments.
    Note that device indices may change (because a removed device leaves the
    list) once you call GetNumAudioDevices() again, though. This should,
    however, protect existing programs from breakage, while making the
    pathological ones slightly faster.

  • All the existing backends support this. For audio targets that only
    support a default output device, SDL will fake a single ADDED event.
    Anything that notices when it fails to write to a device will send the
    REMOVED event. True, honest-to-god hotplug support is fully implemented for
    Mac OS X CoreAudio, and PulseAudio. A few others can support it but
    currently don’t: ALSA can hook up to udev on Linux, for example, but it
    isn’t written at the moment (if anyone wants to beat me to this, let me
    know and check out how we did this with the joystick udev support).

  • PulseAudio now reports human-readable device names to the app (“Built-in
    Audio Analog Stereo”) instead of device nodes (“alsa_output.pci-0000_00_1b.
    0.analog-stereo”).

  • Other cleanups, improvements, and optimizations were done. A lot of
    annoyances in the audio code are gone now, hooray. Not all of them,
    though. :slight_smile:

Questions, comments, or bug reports? Let me know.

–ryan.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Gabriel.

  1. You had mentioned that you wanted to improve the resampling code. Is
    this something that you are looking at for 2.0.4, or is this a later task?

  2. I would be very excited to see the recording feature being
    implemented. How far in the future would you estimate that this is?

In a perfect world, both are in 2.0.5 and need no API changes or
additions (the API already has support for recording, but nothing
implements it…resampling obviously just needs to not be lousy internally).

The hotplug stuff was a fairly dramatic change that became necessary for
one of my clients, otherwise I would have pushed that after 2.0.4
shipped. Mostly I want to focus on resolving some bugs and shipping
2.0.4, now.

The current 2.0.4 TODO list is here:

 https://bitly.com/sdl204-triage

(we’ll move from triaging to a final “we’re fixing these things and
that’s all!” list soon. Many of those 140 bugs might not get fixed for
2.0.4.)

–ryan.

Hi Ryan,

Thanks for the update. For me personally, both of these features are
important so I would be happy to contribute in whatever way I can if
this would speed up the work. If there’s anything that I could assist
with, let me know and I’ll give it a shot.

Kind regards,

Philip BennefallOn 3/20/2015 4:39 PM, Ryan C. Gordon wrote:

  1. You had mentioned that you wanted to improve the resampling code. Is
    this something that you are looking at for 2.0.4, or is this a later
    task?

  2. I would be very excited to see the recording feature being
    implemented. How far in the future would you estimate that this is?

In a perfect world, both are in 2.0.5 and need no API changes or
additions (the API already has support for recording, but nothing
implements it…resampling obviously just needs to not be lousy
internally).

The hotplug stuff was a fairly dramatic change that became necessary
for one of my clients, otherwise I would have pushed that after 2.0.4
shipped. Mostly I want to focus on resolving some bugs and shipping
2.0.4, now.

The current 2.0.4 TODO list is here:

https://bitly.com/sdl204-triage

(we’ll move from triaging to a final “we’re fixing these things and
that’s all!” list soon. Many of those 140 bugs might not get fixed for
2.0.4.)

–ryan.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
.

Hi once again,

I read through the original email once more and had a question about the
removal event. You say that this event only fires for devices that are
currently open, but what if I want to update the device list
automatically whenever any device is unplugged? It would be nice to be
able to receive unplugged device events even for devices that I haven’t
opened, for some extra flexibility and control.

Kind regards,

Philip BennefallOn 3/20/2015 5:28 AM, Ryan C. Gordon wrote:

Perhaps a little too boldly, the audio subsystem got ripped up a lot
while we’re trying to stabilize 2.0.4, so, uh, sorry about that.

SDL now supports hotplugging of audio devices. Here are the basic
notes on it.

  • You can listen for SDL_AUDIODEVICEADDED and SDL_AUDIODEVICEREMOVED
    events, like any other event.

  • ADDED events are always sent (unless you have the events
    specifically disabled, of course), REMOVED events only come through
    for devices you have opened at the moment. ADDED will tell you the new
    device index, so you can do SDL_GetAudioDeviceName($NEWINDEX) right
    away. REMOVED will tell you the SDL_AudioDeviceID of the opened
    device, so you can properly close it.

  • During audio subsystem initialization, all available devices are
    detected and ADDED events are sent for each, in case you would rather
    use that interface exclusively instead of calling
    SDL_GetNumAudioDevices().

  • If an opened device is removed or fails, SDL will keep firing the
    app’s audio callback at a regular interval and throwing away the
    supplied audio data, in case your app is counting on this callback to
    make progress. This means that existing apps will keep going properly
    (albeit without audio output) if you are using a USB headset and yank
    out its cable. This is a change from before, where behavior was
    undefined.

  • The device list from
    SDL_GetNumAudioDevices()/SDL_GetAudioDeviceName() remains stable until
    you call SDL_GetNumAudioDevices() again. This means that a removed
    device will still report its name at the same index, and added devices
    are appended to this list without changing the existing elements.
    Previously, full device redetection happened on each call to
    SDL_GetNumAudioDevices(), now the hotplug code manages that in
    increments. Note that device indices may change (because a removed
    device leaves the list) once you call GetNumAudioDevices() again,
    though. This should, however, protect existing programs from breakage,
    while making the pathological ones slightly faster.

  • All the existing backends support this. For audio targets that only
    support a default output device, SDL will fake a single ADDED event.
    Anything that notices when it fails to write to a device will send the
    REMOVED event. True, honest-to-god hotplug support is fully
    implemented for Mac OS X CoreAudio, and PulseAudio. A few others can
    support it but currently don’t: ALSA can hook up to udev on Linux, for
    example, but it isn’t written at the moment (if anyone wants to beat
    me to this, let me know and check out how we did this with the
    joystick udev support).

  • PulseAudio now reports human-readable device names to the app
    (“Built-in Audio Analog Stereo”) instead of device nodes
    (“alsa_output.pci-0000_00_1b.0.analog-stereo”).

  • Other cleanups, improvements, and optimizations were done. A lot of
    annoyances in the audio code are gone now, hooray. Not all of them,
    though. :slight_smile:

Questions, comments, or bug reports? Let me know.

–ryan.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
.