All devices are in a single hash, whether playback or capture, or physical
or logical. Lookups are keyed on device ID and map to either
`SDL_AudioDevice *` for physical devices or `SDL_LogicalAudioDevice *` for
logical devices (as an implementation detail, you can determine which object
type you have by checking a specific bit in the device ID).
This simplifies a bunch of code, makes some cases significantly more
efficient, and solves the problem of having to lock each physical
device while the device list rwlock is held to find logical devices by ID.
Device IDs hash perfectly evenly, too, being incrementing integers.
The following objects now have properties that can be user modified:
* SDL_AudioStream
* SDL_Gamepad
* SDL_Joystick
* SDL_RWops
* SDL_Renderer
* SDL_Sensor
* SDL_Surface
* SDL_Texture
* SDL_Window
We need to do this early in the file, so that it will be taken into
account when deciding whether to define NEED_SCALAR_CONVERTER_FALLBACKS
and therefore provide a non-SIMD fallback.
Mitigates: https://github.com/libsdl-org/SDL/issues/8352
Signed-off-by: Simon McVittie <smcv@collabora.com>
This is an attempt to centralize all the error handling, instead of
implicitly counting on WaitDevice implementations to disconnect the device
to report an error.
This should retry until GetCurrentPosition succeeds. Otherwise, we would be
going on to the next iteration too soon.
Also generally streamlined the code while I was in here.
This prevents catastrophe if someone tries to close the device in an event
filter in response to the event.
Note that this means SDL_GetAudioStreamDevice() for any stream on this
device will return 0 during the event filter!
Fixes#8331.
Android claims to work with multiple devices, but doesn't actually appear to
(at least, afaict), and it will report tons of devices that all just seem
to play to the current default output, so for now, turn this off and only
expose a default device.
And then, with that default output, attempt to recover on errors by throwing
away the current AAudioStream and building a new one.
This let me plug/unplug a set of headphones from the headphone jack and audio
would switch correctly to the new output.
Now we sleep the thread in WaitDevice until ALSA reawakens it because it
needs more data, and we feed it exactly as much as it can take at that
point.
Like the recent PulseAudio changes, this is both more efficient, reliable,
and consistent.
In practice, this seems to buffer a little upfront and then gives a pretty
consistent request flow after that of 1/4 of the requested buffer size without
variation, which is significantly better than the previous code that would
vary a little each frame.
Plus, as long as the device asks for _anything_, we won't block forever, and
if it asks for more than our expected buffer size, we'll run multiple times
to satisfy it, so this is likely more robust against dropouts in general, too.
This reverts commit 6fd0613ac8.
Turns out that the Steam Runtime is still on PulseAudio 1.1, and the only
thing we (currently) need a newer Pulse for is pa_threaded_mainloop_set_name,
so let's just go back to treating that symbol as optional.
We might need to force a higher version at some point, but it's not worth it
over this.
Otherwise, we get into situations where all bound streams need to change
their output formats when a device pauses...and it makes the fast case
slow: when pausing a single input, it needs to silence and then convert a
silent buffer, instead of just zeroing out the device buffer and being done.
Since these get proxied to a different thread, if we wait for that thread
to finish while holding the lock, and the management thread _also_ requests
the lock, we're screwed.
WaitDevice never holds the lock by design, so just mark devices as failed
and clean up or recover them in there.
The audio processing thread isn't scheduled in lock-step with the audio callback so sometimes the callback would consume the same data twice and sometimes the audio processing thread would write to the same buffer twice.
Also handle variable sizes in the audio callback so the Android audio system doesn't have to do additional buffering to match our buffer size requirements.
Saves locks and copies during audio thread iteration. We've added asserts
that can evaporate out in release mode to make sure everything stays in sync.