Apparently this _can_ happen under load, or maybe some other weird condition.
Hopefully this will encourage PipeWire to fire output_callback again, and
we'll just try again later.
Reference Issue #14916.
Caps the sample rate at 200kHz so that SDL's mixer will downsample any streams which are higher than that.
My Mega Drive emulator outputs at 223721Hz (the sample rate of the PSG chip), and `SDL_OpenAudioDeviceStream` fails due to DirectSound's `CreateSoundBuffer` returning an 'invalid parameter' error code. Lowering the sample rate makes the error go away.
Reported to me by @B3HKO in this issue:
https://github.com/Clownacy/clownmdemu-frontend/issues/60
The 200kHz limit is documented here:
https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ee419022(v=vs.85)
DirectSound's Wikipedia article mentions that problems may occur with sample rates above 192kHz, but no source is provided, so I am unsure whether to take it seriously.
with this, applications can do something like this:
SDL_SetHint(SDL_HINT_AUDIO_DEVICE_STREAM_NAME, "current song")
and this will be reflected in the Audio Devices Plasmoid, pavucontrol etc
also cleaned up PW_KEY_MEDIA_NAME and PW_KEY_NODE_NAME; setting them to the
same appears string appears to break convention, as it results in redundant
titles in PipeWire application lists.
In SDL_audio.c:OpenPhysicalAudioDevice, an attempt is made to SDL_CreateThread
if ProvidesOwnCallbackThread is false, but SDL_CreateThreadWithPropertiesRuntime
is not implemented for Emscripten, so this always fails. I'm not sure if/when
this ever worked, but it simply cannot work in its current state.
Wireplumber now exposes a list of session services, so check the "session.services" property for an "audio" entry to determine whether Pipewire is configured for audio playback/capture.
This upsets things, because you end up calling a javascript function with
more arguments than it expects, and if asserts are enabled, Emscripten notices
this and aborts the program when you hit this code.
Reference Issue #14670.
pa_channel_map_init_auto() with PA_CHANNEL_MAP_WAVEEX does the wrong
thing as it just takes the lest significant bits of
WAVEFORMATEXTENSIBLE's dwChannelMask in order. This doesn't match SDL's
chosen channel ordering.
The implementation here mirrors what we do for PipeWire.
Setting AudioCategory_GameChat breaks audio on several devices, including Behringer U-PHORIA UM2 and RODE NT-USB Mini. We'll disable this for now until we understand more about what's happening.
This is probably something we already cleaned up that has something running
in an unexpected order now that we've moved disconnect work to the main thread.
This avoids situations like:
- PulseAudio holds its own lock in the hotplug thread.
- The hotplug thread notices a device went away.
- The hotplug thread calls SDL_AudioDeviceDisconnected().
- SDL_AudioDeviceDisconnected() tries to grab the device lock.
- The device thread is holding the device lock...
- ...but is currently waiting on PulseAudio's lock to release.
In short: deadlock. It's better to queue this work to run on the main thread,
where we can guarantee a start with _none_ of the audio subsystem locks held.
snd_pcm_recover() puts the device back in SND_PCM_STATE_PREPARED state; you
have to explicitly restart the device afterwards with snd_pcm_start().
Fixes#13761.