Commit graph

119 commits

Author SHA1 Message Date
Sam Lantinga
8538f75119 Added a staging buffer to the audio stream so that we can accumulate small amounts of data if needed when resampling 2017-10-18 19:26:36 -07:00
Sam Lantinga
f36e701b48 Added audio stream conversion functions:
SDL_NewAudioStream
    SDL_AudioStreamPut
    SDL_AudioStreamGet
    SDL_AudioStreamAvailable
    SDL_AudioStreamClear
    SDL_FreeAudioStream
2017-10-18 15:54:05 -07:00
Sam Lantinga
27da65637f Fixed compiler warning 2017-10-12 13:55:35 -07:00
Ryan C. Gordon
31c80a081d audio: Turns out the accumulation errors sound better. :/
Moving to double fixed the overflows, but using "time = i * incr" instead of
"time += incr" causes clicks in the output.
2017-10-11 12:07:43 -04:00
Ryan C. Gordon
9faffcc24c audio: Moved the resampler state up to double precision.
Fixes more buffer overflows.
2017-10-11 11:51:14 -04:00
Ryan C. Gordon
a5e57de5e3 audio: calculate resampling time directly, don't increment (thanks, Eric!).
Fixes buffer overruns as floating point errors accumulate.

Partially fixes Bugzilla #3848.
2017-10-11 11:43:35 -04:00
Ryan C. Gordon
0b41f9e1e9 audio: clamp resampler interpolation values to prevent buffer overflow.
Partially fixes Bugzilla #3848.
2017-10-11 02:33:55 -04:00
Ryan C. Gordon
94b758a288 audio: Moved unchanging variable out of loop. 2017-10-11 02:31:58 -04:00
Ryan C. Gordon
e19182e933 audio: Make sure audio stream resampling doesn't overflow buffers. 2017-10-11 02:03:05 -04:00
Ryan C. Gordon
87e6384fe0 audio: Fixed check for minimum audio stream put size.
--HG--
extra : rebase_source : c46940d87a4f506c0866e8f086e2874a19d0265d
2017-10-11 01:37:11 -04:00
Ryan C. Gordon
324676172e audio: SDL_ResampleCVT() should use memmove instead of memcpy.
This copy can overlap.

Fixes Bugzilla #3849.

--HG--
extra : rebase_source : 0ef5350523b489b091d2d3354b2fe57664cf4725
2017-10-10 22:31:02 -04:00
Ryan C. Gordon
b233e909a4 audio: Don't stack-allocate resampler padding.
(I thought padding size ranged from 5 frames to ~30 frames (based around
RESAMPLER_ZERO_CROSSINGS, which is 5), but it's actually between 512 and
several thousands (based on RESAMPLER_SAMPLES_PER_ZERO_CROSSING)). It gets
big fast when downsampling.

--HG--
extra : rebase_source : 17870d2f7b9e1cf9657ead1969cfe090c4a9e094
2017-10-10 22:18:46 -04:00
Ryan C. Gordon
63e57f5a48 audio: reworked audio streams to have right-hand resampling padding available.
Fixes Bugzilla #3851.
2017-10-10 16:12:56 -04:00
Ryan C. Gordon
25f80b473f audio: Fixed compiler warning on Visual Studio. 2017-09-22 22:28:21 -04:00
Sam Lantinga
d58b502fad Fixed memory leak when HAVE_ALLOCA isn't defined 2017-09-22 08:51:45 -07:00
Ryan C. Gordon
d06b6e98c5 audio: Stream resampling now saves some samples from previous run for padding.
Previously, the padding was silence, which was a problem when streaming since
you would sample a little bit of this silence between each buffer.

We still need a means to get padding data for the right hand side, but this
patch makes the resampler output more correct.

--HG--
extra : amend_source : 0cc91e0b0d6c2314a435a252d88c123c8fa58bfc
2017-09-22 07:42:24 -04:00
Ryan C. Gordon
4509de166f audio: Replaced the resampler. Again.
This time it's using real math from a real whitepaper instead of my previous
amateur, fast-but-low-quality attempt. The new resampler does "bandlimited
interpolation," as described here: https://ccrma.stanford.edu/~jos/resample/

The output appears to sound cleaner, especially at high frequencies, and of
course works with non-power-of-two rate conversions.

There are some obvious optimizations to be done to this still, and there is
other fallout: this doesn't resample a buffer in-place, the 2-channels-Sint16
fast path is gone because this resampler does a _lot_ of floating point math.
There is a nasty hack to make it work with SDL_AudioCVT.

It's possible these issues are solvable, but they aren't solved as of yet.
Still, I hope this effort is slouching in the right direction.

--HG--
extra : rebase_source : 2178d7f422d118dfb76608964f63d290b18c7408
extra : histedit_source : 5461b7f3025ed6c09213910a563318c95d185bf3%2C4a6a6c4c38784b4bc5f241d963c0d752c73ea5b9
2017-09-21 02:51:14 -04:00
Sam Lantinga
a86f7e738e Fixed bug 3662 - Error message when using the audio conversion setup without an initialized audio subsystem is a bit vague
Simon Hug

This issue actually raises the question if this API change (requirement of initialized audio subsystem) is breaking backwards compatibility. I don't see the documentation saying it is needed in 2.0.5.
2017-08-28 21:42:39 -07:00
Ryan C. Gordon
70aacb0db9 audio: A whole bunch of improvements to audio conversion (thanks, Solra!).
"Major changes, roughly in order of appearance:

- Use float math everywhere, instead of promoting to double and casting back
all the time.
- Conserve sound energy when downmixing any channel into two other channels.
- Add a QuadToStereo filter. (The previous technique of reusing StereoToMono
never worked, since it assumed an incorrect channel layout for 4.0.)
- Add a 71to51 filter. This removes just under half of the cases the previous
code would silently break in.
- Add a QuadTo51 filter. More silent breakage fixed.
- Add a 51to71 filter, removing another almost-half of the silently broken
cases.
- Add 8 to the list of values SDL_SupportedChannelCount will accept.
- Change SDL_BuildAudioCVT's channel-related logic to handle every case, and
to actually fail if it fails instead of silently corrupting sound data and/or
crashing down the road."

(Note that SDL doesn't otherwise support 7.1 audio yet, but hopefully it will
soon and the 7.1 converters are an important piece of that.  --ryan.)

Fixes Bugzilla #3727.

--HG--
extra : rebase_source : c61476a6434b4cfe1655f5d30332280cb4cd7af9
2017-08-29 00:41:45 -04:00
Ryan C. Gordon
b44189aee2 audio: better docs on conversion APIs, error if not init'd (thanks, Simon!).
Fixes Bugzilla #3662.
2017-08-18 16:52:19 -04:00
Ryan C. Gordon
a40e02b690 audio: trying to pacify static analysis. 2017-07-05 12:04:37 -04:00
Ryan C. Gordon
7f3b12d6e7 audio: Converter now checks a strict list of channels and formats we support. 2017-06-12 21:35:24 -04:00
Sam Lantinga
e19ba502b2 Fixed bug 3668 - Overflow of SDL_AudioCVT.filters with some downmixes
Simon Hug

There's a chance that an audio conversion from many channels to a few can use more than 9 audio filters. SDL_AudioCVT has 10 SDL_AudioFilter pointers of which one has to be the terminating NULL pointer. The SDL code has no checks for this limit. If it overflows there can be stack or heap corruption or a call to 0xa.

Attached patch adds a function that checks for this limit and throws an error if it is reached. Also adds some documentation.

Test parameters that trigger this issue:
AUDIO_U16MSB with 224 channels at 46359 Hz
                 V
AUDIO_S16MSB with 6 channels at 27463 Hz

The fuzzer program I uploaded in bug 3667 has more of them.
2017-06-12 16:39:15 -07:00
Ryan C. Gordon
82d0a04881 Fix some more compiler warnings on armcc. 2017-03-03 16:38:17 -05:00
Ryan C. Gordon
04142af157 Some patches to make SDL compile with armcc (ARM's C compiler). 2017-03-02 13:33:04 -05:00
Ryan C. Gordon
df1251ae4c audio: SDL_AudioStream's *_sample_frame_size should be in bytes, not bits.
Fixes failures where SDL_AudioStreamGet() incorrectly thinks it got a partial
sample frame request.

--HG--
extra : rebase_source : e3c0970c4f954a1296220ebc4b04c8e95a32d5f3
2017-02-13 16:56:41 -05:00
Ryan C. Gordon
eeec5705e0 audio: libsamplerate can't resample in-place; make space for a copy if needed. 2017-01-24 20:30:48 -05:00
Ryan C. Gordon
0dc13f56ec audio: Offer a hint for libsamplerate quality/speed tradeoff.
This defaults to the internal SDL resampler, since that's the likely default
without a system-wide install of libsamplerate, but those that need more can
tweak this.

--HG--
extra : amend_source : 804f3d3dc636b5f28f7194b48b492c6c3fe05bf5
2017-01-24 15:52:22 -05:00
Ryan C. Gordon
dc15193eb5 audio: Fix static analysis concerns about a dead assignment. 2017-01-24 10:09:29 -05:00
Ryan C. Gordon
ca2ab5780a audio: Make sure SDL_AudioStream's work buffer is 16-byte aligned, for SIMD.
Note the giantic FIXME, though!
2017-01-24 00:51:33 -05:00
Ryan C. Gordon
30238b8676 audio: Streams now resample in-place. Removed second allocated buffer. 2017-01-24 00:17:40 -05:00
Ryan C. Gordon
2471f581c6 audio: allow stereo Sint16 resampling fast path in SDL_AudioStream.
This currently favors libsamplerate over the fast path (quality over speed),
but I'm not sure that's the correct approach, as there may be surprising
changes in performance metrics depending on what packages are available on
a user's system. That being said, currently, the only thing with access to
SDL_AudioStream is an SDL audio device's thread, and it might be mostly idle
otherwise, so maybe this is generally good.
2017-01-24 00:08:24 -05:00
Ryan C. Gordon
6b1e0a7cd2 audio: Fixed off-by-one error in upsampling. 2017-01-24 00:03:36 -05:00
Ryan C. Gordon
8850103510 audio: Resampler now special-cases stereo and mono processing.
Turns out that iterating from 0 to channels-1 was a serious performance hit!

These cases now tend to match or beat the original audio resampler's speed!
2017-01-23 16:45:50 -05:00
Ryan C. Gordon
c869f0418a audio: Fixed incorrect pointer in SDL_ResampleCVT_si16_c2().
Forgot to update this when we changed this to process in-place. Whoops!
2017-01-23 16:42:47 -05:00
Ryan C. Gordon
6e1edca849 audio: Wired up new SSE code to build system.
--HG--
extra : rebase_source : 3c94cdc92b94864eb43d7429032724227b798cf2
2017-01-23 01:05:44 -05:00
Ryan C. Gordon
c46db55d26 audio: Special case for resampling stereo AUDIO_S16SYS audio data.
This is a fairly common case, so we avoid the conversion to/from float here.

--HG--
extra : rebase_source : 46d6e38d06da451b8c2e836ae36cd1ddba02e510
2017-01-22 20:27:48 -05:00
Ryan C. Gordon
50bb6473ed audio: Make the simple resampler operate in-place.
This allows us to avoid an extra copy, allocate less memory and reduce cache
pressure. On the downside: we have to do a lot of tapdancing to resample the
buffer in reverse when the output is growing.

--HG--
extra : rebase_source : cab98b19216722eae3749cc1e1429d1c802e9782
2017-01-22 23:48:15 -05:00
Ryan C. Gordon
6ceacbdc4a audio: Added SSE3 implementation of SDL_ConvertStereoToMono().
--HG--
extra : rebase_source : 92882c4fdf5dc4a326057f577ccb4c29c32f938e
2017-01-23 00:57:19 -05:00
Ryan C. Gordon
8af7561815 audio: don't cast to double in SDL_ConvertStereoToMono().
It's expensive and (hopefully) unnecessary. If this becomes an overflow
problem, we could multiply both values by 0.5f before adding them, but let's
see if we can get by without the extra multiplication first.

--HG--
extra : rebase_source : b7b47e961eb974510e133882548ea36b40f6d7e3
2017-01-22 20:18:59 -05:00
Ryan C. Gordon
34fe29bc62 audio: removed conditional from simple resampler's inner loop.
We never seem to overflow the source buffer now; this might have been a
leftover from a bug that was covered by Vitaly's fixes?

Removing this conditional makes the resampler 10-20% faster. Left an
assert in there for debug builds, in case this still happens.

--HG--
extra : rebase_source : c05a536f5a80f065c0872b35d77d4f70a56b4e3e
2017-01-20 16:26:24 -05:00
Ryan C. Gordon
adb1d6888f audio: Several fixes to "simple" resampler (thanks, Vitaly!).
Fixes Bugzilla #3551.
2017-01-18 02:11:56 -05:00
Ryan C. Gordon
c40d568133 audio: Some fixes to the audio data type converter code.
Removed some needless things ("len / sizeof (Uint8)"), and made sure the
int32 -> float code uses doubles to avoid working with large integer values
in a 32-bit float.

--HG--
extra : rebase_source : c803b416ec487b8c0feba780ac06f8d11e90879b
2017-01-15 05:01:59 -05:00
Sam Lantinga
8eb437d4e7 Fixed bug 3552 - Building SDL in release mode fails under VS 2017 RC
Lukasz Biel

Tried to compile SDL2 using newest version of VS.

Got:
SDL_audiocvt.obj : error LNK2019: unresolved external symbol memcpy referenced in function SDL_ResampleCVT
1>E:\Users\dotPo\Lib\SDL\VisualC\x64\Release\SDL2.dll : fatal error LNK1120: 1 unresolved externals

whole compilation process: http://pastebin.com/eWDAvBce

Steps to reproduce:
clone http://hg.libsdl.org/SDL using tortoise hg,
open SDL\VisualC\SDL.sln,
when promted if should retarget solution click ok,
select release x64 build type,
Build/Build Solution

attempt 2, using Visual Studio cmake support:
open folder SDL\
select release x64 build type,
run CMake\Build CMakeLists.txt
build fails

When switched to debug build type, buils succeeds in both cases.
VS 2017 is still beta.
2017-01-09 20:37:52 -08:00
Ryan C. Gordon
27737db314 audio: Don't ever use libsamplerate in the SDL_AudioCVT codepath.
It causes audio pops if you're converting in chunks (and needs to
allocate/initialize/free on each convert). We'll either adjust this interface
when we break ABI for 2.1 to make this usable, or publish the SDL_AudioStream
API for those that want a streaming solution.

In the meantime, the "simple" resampler produces "good enough" audio without
pops and doesn't have to be initialized, so that'll do for now on the
SDL_AudioCVT interface.

--HG--
extra : rebase_source : 4c5656de3d1de9f88d6368e5ca363d834fc93af1
2017-01-09 16:31:57 -05:00
Ryan C. Gordon
2f283c2beb audio: Replaced older resamplers in SDL_AudioCVT with the new ones.
--HG--
extra : rebase_source : a4df0c56d61d9927e97bbd738c12a3043f44742e
2017-01-09 06:00:58 -05:00
Ryan C. Gordon
9268415b53 audio: Improvements in channel conversion code.
--HG--
extra : amend_source : 521d4d1f25bba02be473faa4d573928ea9007452
2017-01-08 16:18:49 -05:00
Ryan C. Gordon
d8f718f75d audio: Patched to compile with libsamplerate support. 2017-01-08 14:23:15 -05:00
Ryan C. Gordon
f904fecce3 audio: libsamplerate loading now happens once at init time.
--HG--
extra : rebase_source : b88014744534e382d6b6ea004554ffcebe5caffe
2017-01-08 14:18:03 -05:00
Ryan C. Gordon
d81fb0038f Fixed coding style on a function signature.
--HG--
extra : rebase_source : ccbcdf0c433bac0ad213f4a377674363b1fab87e
2017-01-08 14:17:09 -05:00