- drop unnecessary hascapture check
- call SDL_InvalidParamError and return -1 in case the index is out of range
- do not zfill SDL_AudioSpec
- adjust documentation to reflect the behavior
- use SDL_bool if possible
- assume NULL/SDL_FALSE filled impl
- skip zfill of current_audio at the beginning of SDL_AudioInit (done before the init() calls)
The recent change to make SDL_AUDIODRIVER support comma-separated lists
broke the previous behavior where an SDL_AUDIODRIVER that was empty
behaved the same as if it was not set at all. This old behavior was
necessary to paper over differences in platforms where SDL_setenv may
or may not actually delete the env var if an empty string is specified.
This patch just adds a simple check to ensure SDL_AUDIODRIVER is not
empty before using it, restoring the old interpretation of the empty
var.
Originally, SDL 1.2 used "pulse" as the name for its PulseAudio driver.
While it now supports "pulseaudio" as well for compatibility with SDL
2.0 [1], there are still scripts and distro packages which set
SDL_AUDIODRIVER=pulse [2]. While it's possible to remove this in most
circumstances or replace it with "pulseaudio" or a comma-separated list,
this may still conflict if the environment variable is set globally and
old binary builds of SDL 1.2 (e.g. packaged with older games) are being
used.
To fix this on SDL 2.0, add a hardcoded check for "pulse" as an audio
driver name, and replace it with "pulseaudio". This mimics what SDL 1.2
does (but in reverse). Note that setting driver_attempt{,_len} is safe
here as they're reset correctly based on driver_attempt_end on the next
loop.
[1] d951409784
[2] https://bugzilla.opensuse.org/show_bug.cgi?id=1189778
Without this change, driver names don't get matched correctly;
for example "a" can get matched with "alsa" since it only checks
whether the string matches up to the length of the requested
driver name.
While we should normally expect _something_ from the stream based on the
AudioStreamAvailable check, it's possible for a device change to flush the
stream at an inconvenient time, causing this function to return 0.
Thing is, this is harmless. Either data will be NULL and the result won't matter
anyway, or the data buffer will be zeroed out and the output will just be
silence for the brief moment that the device change is occurring. Both scenarios
work themselves out, and testing on Windows shows that this behavior is safe.
When converting audio from signed to unsigned values of vice-versa
the silence value chosen by SDL was the value of the device, not
of the stream that the data was being put into. After conversion
this would lead to a very high or low value, making the speaker
jump to a extreme positon, leading to an audible noise whenever
creating, destroying or playing scilence on a device that reqired
such conversion.
Cameron Gutman
I was trying to use SDL_GetQueuedAudioSize() to ensure my audio latency didn't get too high while streaming data in from the network. If I get more than N frames of audio queued, I know that the network is giving me more data than I can play and I need to drop some to keep latency low.
This doesn't work well on WASAPI out of the box, due to the addition of GetPendingBytes() to the amount of queued data. As a terrible hack, I loop 100 times calling SDL_Delay(10) and SDL_GetQueuedAudioSize() before I ever call SDL_QueueAudio() to get a "baseline" amount that I then subtract from SDL_GetQueuedAudioSize() later. However, because this value isn't actually a constant, this hack can cause SDL_GetQueuedAudioSize() - baselineSize to be < 0. This means I have no accurate way of determining how much data is actually queued in SDL's audio buffer queue.
The SDL_GetQueuedAudioSize() documentation says: "This is the number of bytes that have been queued for playback with SDL_QueueAudio(), but have not yet been sent to the hardware." Yet, SDL_GetQueuedAudioSize() returns > 0 value when SDL_QueueAudio() has never been called.
Based on that documentation, I believe the current behavior contradicts the documented behavior of this function and should be changed in line with Boris's patch.
I understand that exposing the IAudioClient::GetCurrentPadding() value is useful, but a solution there needs to take into account what of that data is silence inserted by SDL and what is actual data queued by the user with SDL_QueueAudio(). Until that happens, I think the best approach is to remove the GetPendingBytes() call until SDL is able to keep track of queued data to make sense of it. This would make SDL_GetQueuedAudioSize() possible to use accurately with WASAPI.
This was meant to migrate CoreAudio onto the same SDL_RunAudio() path that
most other audio drivers are on, but it introduced a bug because it doesn't
deal with dropped audio buffers...and fixing that properly just introduces
latency.
I might revisit this later, perhaps by reworking SDL_RunAudio to allow for
this sort of API better, or redesigning the whole subsystem or something, I
don't know. I'm not super-thrilled that this has to exist outside of the usual
codepaths, though.
Fixes Bugzilla #4481.
SDLActivity thread priority is unchanged, by default -10 (THREAD_PRIORITY_VIDEO).
SDLAudio thread priority was -4 (SDL_SetThreadPriority was ignored) and is now -16 (THREAD_PRIORITY_AUDIO).
SDLThread thread priority was 0 (THREAD_PRIORITY_DEFAULT) and is -4 (THREAD_PRIORITY_DISPLAY).
This means that if you have two devices named "Soundblaster Pro" in your
machine, one will be reported as "Soundblaster Pro" and the other as
"Soundblaster Pro (2)".
This makes it so you can't into a position where one of your devices can't
be opened because another is sitting on the same name.
Author: Anthony Pesch <inolen@gmail.com>
Date: Fri May 4 20:21:21 2018 -0400
Added SDL_AUDIO_ALLOW_SAMPLES_CHANGE flag enabling users of SDL_OpenAudioDevice to get
the sample size of the actual hardware buffer vs having a stream created to handle the
delta