Commit Graph

347 Commits

Author SHA1 Message Date
Ryan C. Gordon
8fa0746d4a audio: Fix postmix state when migrating to new default devices.
Otherwise buffers might not be allocated, etc.
2023-11-15 14:17:13 -05:00
Ryan C. Gordon
0efb3d90e0 audio: removed a fixed FIXME comment. 2023-11-12 23:41:22 -05:00
Sylvain Becker
04b6b2979f Re-add SDL_assert() with non boolean ptr syntax (#8530) 2023-11-11 12:28:24 +03:00
Sylvain
d8600f717e Pointer as bool (libsdl-org#7214) 2023-11-09 14:18:36 -08:00
Sam Lantinga
fea2504a37 Prioritize the pipewire audio driver over ALSA
ALSA is used very rarely anymore and the pipewire ALSA emulation isn't as good as using pipewire directly. The Pulseaudio emulation is very good, and Pulseaudio is still commonly available on Linux systems, so we'll default to that first and fall back to pipewire if it's not available. We'll finally try ALSA, to handle very old systems.

Fixes https://github.com/libsdl-org/SDL/issues/7541
2023-11-07 22:02:27 -08:00
Sam Lantinga
f3261fedcc Code cleanup now that SDL_bool is equivalent to a C boolean expression 2023-11-03 09:54:04 -07:00
Ryan C. Gordon
759cdf6159 audio: Fixed GetFirstAudioDeviceAdded().
It forgot to check for the type of device needed.
2023-11-01 00:39:51 -04:00
Ryan C. Gordon
0e614d9179 audio: Massive reworking on thread locking.
This cleans up a ton of race conditions, and starts moving towards something
we can use with Clang's -Wthread-safety (but that has a ways to go still).
2023-11-01 00:10:25 -04:00
Ryan C. Gordon
40fb76196c audio: Don't let simplified audio streams bind to new devices.
This can happen if you close the stream's underlying device directly, which
removes the binding but doesn't destroy the object.

In this case, the stream remains valid until destroyed, but still should not
be able to be bound to a new device.
2023-10-31 10:52:50 -04:00
Ryan C. Gordon
24e3328cca audio: Don't reset device ID counter on subsystem init/quit.
Otherwise you risk a buggy app holding an obsolete device ID that now refers
to a different device after reinit.
2023-10-31 10:50:37 -04:00
Ryan C. Gordon
9cb259e865 audio: Never SDL_PushEvent from anywhere but SDL_UpdateAudio().
Fixes some corner-case deadlocks.
2023-10-30 13:08:10 -04:00
Ryan C. Gordon
ce3be02b48 wasapi: If device is marked as a zombie, don't try to resuscitate it. 2023-10-27 01:27:22 -04:00
Ryan C. Gordon
c45b5121ce audio: Fixed potential race condition.
We need to check if the device is ready to close before releasing the lock,
in case other things are messing with the list of logical devices.
2023-10-26 23:03:27 -04:00
Sam Lantinga
124a0050b6 Fixed warning: no previous prototype for function 'SDL_UpdateAudio' 2023-10-24 14:22:41 -07:00
Sam Lantinga
5ba03d377a Revert "Fixed audio device removed events for ALSA"
This reverts commit e57fef8f0b.

We actually need to match on a unique handle
2023-10-23 19:05:27 -07:00
Sam Lantinga
e57fef8f0b Fixed audio device removed events for ALSA 2023-10-23 18:42:48 -07:00
Ryan C. Gordon
43d41c9dcb audio: Another attempt to make device add/remove work vs event watchers.
This patch reverts the previous reversion, and then adds code to queue up
events to be sent the next time SDL pumps the event queue. This guarantees
that the event watcher/filter _never_ runs from an SDL audio device thread
or some other backend-specific internal thread.
2023-10-23 00:38:41 -04:00
Ryan C. Gordon
9abc692156 audio: Another attempt to deal with device destruction from device thread.
This only happens when closing a device from an event watcher, when the
device reports failure from its own thread.
2023-10-22 17:01:49 -04:00
Ryan C. Gordon
33c9eeec7c Revert "audio: Device threads don't increment physical device refcounts."
This reverts commit 76f81797b7.

This worked in the normal cases, but:

A device thread that calls SDL_DisconnectAudioDevice due to failure will fire
the disconnect event from the device thread...and if there's an event watcher
that uses that moment to close the device, we still end up in the same
situation, where the device thread tries to join on itself.

Better solutions are still pending.
2023-10-22 16:15:27 -04:00
Ryan C. Gordon
76f81797b7 audio: Device threads don't increment physical device refcounts.
Otherwise, they risk the device thread joining on itself.

Now we make sure the reference is held at the logical device level until
the physical device is closed, so it can't destroy the device in normal
usage until the thread is joined, etc.
2023-10-19 15:47:29 -04:00
Ryan C. Gordon
797b70877d audio: Remove stub header SDL_audio_c.h.
It was a leftover, that just included SDL_sysaudio.h, in modern times.
2023-10-18 15:46:07 -04:00
Ryan C. Gordon
442e84916a opensles: Fixed capitalization to match other SDL backends. 2023-10-18 13:57:32 -04:00
Ryan C. Gordon
7a52f7b3fd audio: Split Deinitialize into two stages.
First stage happens before we destroy objects, and is generally used to
shut down hotplug. The second stage is the usual deinit, which cleans up
the lowlevel API, unloads shared libraries, etc.
2023-10-18 10:43:45 -04:00
Ryan C. Gordon
b733adb503 audio: Fix device refcounting vs ProvidesOwnCallbackThread backends. 2023-10-16 20:17:04 -04:00
Ryan C. Gordon
8c39269279 audio: Fix audio stream format when binding to a capture device.
Fixes #8402.
2023-10-16 13:34:40 -04:00
Ryan C. Gordon
063cb0df6b audio: Fixed comment typo. "deref" should be "unref" 2023-10-16 13:09:55 -04:00
Ryan C. Gordon
a17f3ba916 audio: Reworked audio device disconnect management.
- No more tapdance to either join the audio device thread or have it detach
itself. Significant simplication of and fixes to the locking code to prevent
deadlocks.
- Physical devices now keep a refcount. Each logical device increments it,
as does the existence of a device thread, etc. Last unref destroys the
device and takes it out of the device_hash. Since there's a lot of moving
parts that might be holding a reference to a physical device, this seemed
like a safer way to protect the object.
- Disconnected devices now continue to function as zombie devices. Playback
devices will still consume data (and just throw it away), and capture devices
will continue to produce data (which always be silence). This helps apps
that don't handle disconnect events; the device still stops playing/capturing,
but bound audio streams will still consume data so they don't allocate more
data infinitely, and apps that depend on an audio callback firing regularly
to make progress won't hang.

Please note that disconnected audio devices must now be explicitly closed!
They always _should_ have been, but before this commit, SDL3 would destroy the
disconnected device for you (and manually closing afterwards was a safe no-op).

Reference Issue #8331.
Fixes #8386.

(and probably others).
2023-10-16 10:04:02 -04:00
Ryan C. Gordon
b22ffb9797 audio: Fix some logic errors in the new device hashtable code.
Fixes #8395.
2023-10-14 23:11:10 -04:00
Ryan C. Gordon
8ac5c84ad1 audio: device thread shouldn't touch thread_alive after object is free'd.
Reference Issue #8386.
2023-10-14 13:49:08 -04:00
Ryan C. Gordon
7f408e57ee audio: Keep all available devices in a hashtable instead of linked lists.
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.
2023-10-14 13:34:42 -04:00
Ryan C. Gordon
95a9271dbf audio: Never lock a device while holding the device_list_lock.
Fixes various not-necessarily-corner cases ending in deadlock.
2023-10-13 14:18:21 -04:00
Ryan C. Gordon
2bca4671a6 audio: Allow audio streams to be created when the subsystem isn't initialized.
You are on your own to destroy them, though!
2023-10-11 22:43:53 -04:00
Sam Lantinga
0d5cad91b1 We need audio converters initialized in SDL_InitAudio()
These are used separately from audio streams, e.g. SDL_OutputAudioThreadIterate(), so they should always be initialized when audio is initialized.
2023-10-11 15:11:34 -07:00
Ryan C. Gordon
1c3a0ade74 audio: Whoops, this stream format change is only for capture devices. 2023-10-11 15:11:20 -04:00
Sam Lantinga
c552cc6847 We don't require the audio system to be initialized for audio format conversion
This is helpful for tools pipelines where audio devices are never used.
2023-10-11 09:23:23 -07:00
Ryan C. Gordon
044046bc50 audio: Fixed assertions when capture devices have wrong audio formats.
Fixes #8376.
2023-10-11 10:37:28 -04:00
Ryan C. Gordon
55a1458ed0 audio: Changes to one logical device must update all sibling logical devices.
Fixes #8226.
2023-10-09 20:28:58 -04:00
Ryan C. Gordon
ff57867516 audio: Fixed copy/paste error that was checking wrong variable.
Fixes #8342.
2023-10-03 14:58:24 -04:00
Ryan C. Gordon
d2d4914ac3 audio: WaitDevice/WaitCaptureDevice now returns a result.
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.
2023-10-03 10:35:18 -04:00
Ryan C. Gordon
f1fc198278 audio: Destroy the logical audio device before sending DEVICE_REMOVED event.
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.
2023-10-02 22:12:28 -04:00
Ryan C. Gordon
de5068f4e4 audio: Commented out a currently-incorrect assert.
Fixes #8326.
2023-10-02 19:41:48 -04:00
Ryan C. Gordon
4db2b968af audio: simple-copy path should check if device is paused.
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.
2023-09-27 16:24:33 -04:00
Ryan C. Gordon
505dc4c39c wasapi: Deal with device failures when we aren't holding the device lock.
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.
2023-09-27 14:33:09 -04:00
Ryan C. Gordon
a5175e5ed0 audio: Fixed bug when setting up mixing formats.
Reference Issue #8226.
2023-09-27 11:50:23 -04:00
Sam Lantinga
2e92e94ebb Make sure we update device->sample_frames in SDL_AudioDeviceFormatChangedAlreadyLocked()
WASAPI_GetDeviceBuf() will fail if we don't request the correct buffer size
2023-09-21 11:32:37 -07:00
Ryan C. Gordon
a541e2ac10 audio: Change a few SDL_memcpy calls to SDL_copyp. 2023-09-20 17:02:44 -04:00
Ryan C. Gordon
54125c1408 audio: Only update bound audiostreams' formats when necessary.
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.
2023-09-20 17:02:44 -04:00
Ryan C. Gordon
f8fdb20d8f audio: Destroy all existing SDL_AudioStreams on shutdown. 2023-09-20 10:47:11 -04:00
Ryan C. Gordon
23206b9e3f audio: Added SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED
This fires if an opened device changes formats (which it can on Windows,
if the user changes this in the system control panel, and WASAPI can
report), or if a default device migrates to new hardware and the format
doesn't match.

This will fire for all logical devices on a physical device (and if it's
a format change and not a default device change, it'll fire for the
physical device too, but that's honestly not that useful and might change).

Fixes #8267.
2023-09-20 10:12:10 -04:00
Ryan C. Gordon
87ec6acf2d audio: Added a FIXME 2023-09-20 10:04:19 -04:00