mirror of https://github.com/encounter/SDL.git
audio: libsamplerate can't resample in-place; make space for a copy if needed.
This commit is contained in:
parent
1b3327edd0
commit
47e2f4e950
|
@ -867,7 +867,6 @@ struct SDL_AudioStream
|
|||
SDL_AudioCVT cvt_before_resampling;
|
||||
SDL_AudioCVT cvt_after_resampling;
|
||||
SDL_DataQueue *queue;
|
||||
Uint8 *work_buffer; /* always aligned to 16 bytes. */
|
||||
Uint8 *work_buffer_base; /* maybe unaligned pointer from SDL_realloc(). */
|
||||
int work_buffer_len;
|
||||
int src_sample_frame_size;
|
||||
|
@ -887,6 +886,29 @@ struct SDL_AudioStream
|
|||
SDL_CleanupAudioStreamResamplerFunc cleanup_resampler_func;
|
||||
};
|
||||
|
||||
static Uint8 *
|
||||
EnsureStreamBufferSize(SDL_AudioStream *stream, const int newlen)
|
||||
{
|
||||
Uint8 *ptr;
|
||||
size_t offset;
|
||||
|
||||
if (stream->work_buffer_len >= newlen) {
|
||||
ptr = stream->work_buffer_base;
|
||||
} else {
|
||||
ptr = (Uint8 *) SDL_realloc(stream->work_buffer_base, newlen + 32);
|
||||
if (!ptr) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
/* Make sure we're aligned to 16 bytes for SIMD code. */
|
||||
stream->work_buffer_base = ptr;
|
||||
stream->work_buffer_len = newlen;
|
||||
}
|
||||
|
||||
offset = ((size_t) ptr) & 15;
|
||||
return offset ? ptr + (16 - offset) : ptr;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBSAMPLERATE_H
|
||||
static int
|
||||
SDL_ResampleAudioStream_SRC(SDL_AudioStream *stream, const void *_inbuf, const int inbuflen, void *_outbuf, const int outbuflen)
|
||||
|
@ -898,6 +920,17 @@ SDL_ResampleAudioStream_SRC(SDL_AudioStream *stream, const void *_inbuf, const i
|
|||
SRC_DATA data;
|
||||
int result;
|
||||
|
||||
if (inbuf == ((const float *) outbuf)) { /* libsamplerate can't work in-place. */
|
||||
Uint8 *ptr = EnsureStreamBufferSize(stream, inbuflen + outbuflen);
|
||||
if (ptr == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
return 0;
|
||||
}
|
||||
SDL_memcpy(ptr + outbuflen, ptr, inbuflen);
|
||||
inbuf = (const float *) (ptr + outbuflen);
|
||||
outbuf = (float *) ptr;
|
||||
}
|
||||
|
||||
data.data_in = (float *)inbuf; /* Older versions of libsamplerate had a non-const pointer, but didn't write to it */
|
||||
data.input_frames = inbuflen / framelen;
|
||||
data.input_frames_used = 0;
|
||||
|
@ -1125,24 +1158,6 @@ SDL_NewAudioStream(const SDL_AudioFormat src_format,
|
|||
return retval;
|
||||
}
|
||||
|
||||
static Uint8 *
|
||||
EnsureStreamBufferSize(SDL_AudioStream *stream, const int newlen)
|
||||
{
|
||||
if (stream->work_buffer_len < newlen) {
|
||||
Uint8 *ptr = (Uint8 *) SDL_realloc(stream->work_buffer_base, newlen + 32);
|
||||
const size_t offset = ((size_t) ptr) & 15;
|
||||
if (!ptr) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
/* Make sure we're aligned to 16 bytes for SIMD code. */
|
||||
stream->work_buffer = offset ? ptr + (16 - offset) : ptr;
|
||||
stream->work_buffer_base = ptr;
|
||||
stream->work_buffer_len = newlen;
|
||||
}
|
||||
return stream->work_buffer;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _buflen)
|
||||
{
|
||||
|
@ -1190,11 +1205,14 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _bufle
|
|||
if (workbuf == NULL) {
|
||||
return -1; /* probably out of memory. */
|
||||
}
|
||||
if (buf == origbuf) { /* copy if we haven't before. */
|
||||
SDL_memcpy(workbuf, buf, buflen);
|
||||
/* don't SDL_memcpy(workbuf, buf, buflen) here; our resampler can work inplace or not,
|
||||
libsamplerate needs buffers to be separate; either way, avoid a copy here if possible. */
|
||||
if (buf != origbuf) {
|
||||
buf = workbuf; /* in case we realloc()'d the pointer. */
|
||||
}
|
||||
buflen = stream->resampler_func(stream, workbuf, buflen, workbuf, workbuflen);
|
||||
buf = workbuf;
|
||||
buflen = stream->resampler_func(stream, buf, buflen, workbuf, workbuflen);
|
||||
buf = EnsureStreamBufferSize(stream, workbuflen);
|
||||
SDL_assert(buf != NULL); /* shouldn't be growing, just aligning. */
|
||||
}
|
||||
|
||||
if (stream->cvt_after_resampling.needed) {
|
||||
|
|
Loading…
Reference in New Issue