Anthony Pesch
The previous code first configured the period size using snd_pcm_hw_par-
ams_set_period_size_near. Then, it further narrowed the configuration
space by calling snd_pcm_hw_params_set_buffer_size_near using a buffer
size of 2 times the _requested_ period size in order to try and get a
configuration with only 2 periods. If the configured period size was
larger than the requested size, the second call could inadvertently
narrow the configuration space to contain only a single period.
Rather than fixing the call to snd_pcm_hw_params_set_buffer_size_near
to use a size of 2 times the configured period size, the code has been
changed to use snd_pcm_hw_params_set_periods_min in order to more
clearly explain the intent.
(technically, this function never returns an error at this point, but since
it _does_ have an "uhoh, is this corrupt data?" comment that it ignores, we
should probably make sure we handle error cases in the future. :) )
LinGao
We build SDL with Visual studio 2017 compiler on Windows Server 2016, but it failed to build due to error LNK2019: unresolved external symbol _memset referenced in function _IMA_ADPCM_Decode on latest default branch. And we found that it can be first reproduced on ca7283111ad0 changeset. Could you please help have a look about this issue? Thanks in advance!
Simon Hug
Attached is a minor cleanup patch. It changes the option name of one hint to something better, puts one or two more checks in, and adds explicit casting where warnings could appear otherwise.
I hope the naming of the hints and their options is acceptable. It would be kind of awkward to change them after they get released with an official SDL version.
Simon Hug
I had a look at this and made some additions to SDL_wave.c.
The attached patch adds many checks and error messages. For some reason I also added A-law and ?-law decoders. Forgot exactly why... but hey, they're small.
The WAVE format is seriously underspecified (at least by the documents that are publicly available on the internet) and it's a shame Microsoft never put something better out there. The language used in them is so loose at times, it's not surprising the encoders and decoders behave very differently. The Windows Media Player doesn't even support MS ADPCM correctly.
The patch also adds some hints to make the decoder more strict at the cost of compatibility with weird WAVE files.
I still think it needs a bit of cleaning up (Not happy with the MultiplySize function. Don't like the name and other SDL code may want to use something like this too.) and some duplicated code may be folded together. It does work in this state and I have thrown all kinds of WAVE files at it. The AFL files also pass with it and some even play (obviously just noise). Crafty little fuzzer.
Any critique would be welcome. I have a fork of SDL with a audio-loadwav branch over here if someone wants to use the commenting feature of Bitbucket:
https://bitbucket.org/ChliHug/SDL
I also cobbled some Lua scripts together to create WAVE test files:
https://bitbucket.org/ChliHug/gendat
janisozaur
There are many cases which are not able to be handled by SDL's audio conversion routines, including too low (negative) rate, too high rate (impossible to allocate).
This patch aims to report such issues early and handle others in a graceful manner. The "INT32_MAX / RESAMPLER_SAMPLES_PER_ZERO_CROSSING" value is the conservative approach in terms of what can _technically_ be supported, but its value is 4'194'303, or just shy of 4.2MHz. I highly doubt any sane person would use such rates, especially in SDL2, so I would like to drive this limit further down, but would need some assistance to do that, as doing so would have to introduce an arbitrary value. Are you OK with such approach? What would a good value be? Wikipedia (https://en.wikipedia.org/wiki/High-resolution_audio) lists 96kHz as the highest sampling rate in use, even if I quadruple it for a good measure, to 384kHz it's still an order of magnitude lower than 4MHz.
If IMA ADPCM format chunk was too short, InitIMA_ADPCM() parsing it
could read past the end of chunk data. This patch fixes it.
CVE-2019-7578
https://bugzilla.libsdl.org/show_bug.cgi?id=4494
Signed-off-by: Petr P?sa? <ppisar@redhat.com>
Matt Brocklehurst
We've noticed that if you are playing audio on Windows via the WASAPI interface and you unplug and reconnect the device a few times the program hangs.
We've debugged the problem down to
static void
WASAPI_WaitDevice(_THIS)
{
... snip ...
if (WaitForSingleObjectEx(this->hidden->event, INFINITE, FALSE) == WAIT_OBJECT_0) {
... snip ...
}
This WaitForSingleObjectEx does not havbe a time out defined, so it hangs there forever.
Our suggested fix we found was to include a time out of say 200mSec
We have done quite a bit of testing with this fix in place on various hardware configurations and it seems to have resolved the issue.
Nia Alarie
The NetBSD audio driver has a few problems. Lots of obsolete code, and extremely bad performance and stuttering.
I have a patch in NetBSD's package system to improve it. This is my attempt to upstream it.
The changes include:
* Removing references to defines which are never used.
* Using the correct structures for playback and recording, previously they were the wrong way around.
* Using the correct types ('struct audio_prinfo' in contrast to 'audio_prinfo')
* Removing the use of non-blocking I/O, as suggested in #3177.
* Removing workarounds for driver bugs on systems that don't exist or use this driver any more.
* Removing all usage of SDL_Delay(1)
* Removing pointless use of AUDIO_INITINFO and tests that expect AUDIO_SETINFO to fail when it can't.
These changes bring its performance in line with the DSP audio driver.
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.
Anthony Pesch
Fix snd_device_name_hint return value check
According to the ALSA documentation, snd_device_name_hint returns 0 on
success, otherwise a negative error code. The code previously only
considered -1 to be an error, which let other error codes through
resulting in a segfault when hints (which was NULL) was dereferenced