pcm_utils: pass only one buffer size to pcm_mix()
pcm_mix() might overflow the destination buffer if it is smaller than the second buffer. This is ok because the physical buffer size passed by cross_fade_apply() is always big enough, but clutters pcm_mix() with complicated length checks and contains a dangerous buffer overflow pitfall. Simplify pcm_mix()/pcm_add() and pass only the smaller buffer size; let cross_fade_apply() do the memcpy().
This commit is contained in:
parent
6e21e24cae
commit
c85b570ad7
@ -49,14 +49,28 @@ void cross_fade_apply(ob_chunk * a, const ob_chunk * b,
|
||||
const struct audio_format *format,
|
||||
unsigned int current_chunk, unsigned int num_chunks)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
assert(current_chunk <= num_chunks);
|
||||
|
||||
size = b->chunkSize > a->chunkSize
|
||||
? a->chunkSize
|
||||
: b->chunkSize;
|
||||
|
||||
pcm_mix(a->data,
|
||||
b->data,
|
||||
a->chunkSize,
|
||||
b->chunkSize,
|
||||
size,
|
||||
format,
|
||||
((float)current_chunk) / num_chunks);
|
||||
if (b->chunkSize > a->chunkSize)
|
||||
|
||||
if (b->chunkSize > a->chunkSize) {
|
||||
/* the second buffer is larger than the first one:
|
||||
there is unmixed rest at the end. Copy it over.
|
||||
The output buffer API guarantees that there is
|
||||
enough room in a->data. */
|
||||
memcpy(a->data + a->chunkSize,
|
||||
b->data + a->chunkSize,
|
||||
b->chunkSize - a->chunkSize);
|
||||
a->chunkSize = b->chunkSize;
|
||||
}
|
||||
}
|
||||
|
@ -90,8 +90,8 @@ void pcm_volumeChange(char *buffer, int bufferSize,
|
||||
}
|
||||
}
|
||||
|
||||
static void pcm_add(char *buffer1, const char *buffer2, size_t bufferSize1,
|
||||
size_t bufferSize2, int vol1, int vol2,
|
||||
static void pcm_add(char *buffer1, const char *buffer2, size_t size,
|
||||
int vol1, int vol2,
|
||||
const struct audio_format *format)
|
||||
{
|
||||
int32_t temp32;
|
||||
@ -102,7 +102,7 @@ static void pcm_add(char *buffer1, const char *buffer2, size_t bufferSize1,
|
||||
|
||||
switch (format->bits) {
|
||||
case 16:
|
||||
while (bufferSize1 > 0 && bufferSize2 > 0) {
|
||||
while (size > 0) {
|
||||
temp32 =
|
||||
(vol1 * (*buffer16_1) +
|
||||
vol2 * (*buffer16_2));
|
||||
@ -112,14 +112,11 @@ static void pcm_add(char *buffer1, const char *buffer2, size_t bufferSize1,
|
||||
*buffer16_1 = pcm_range(temp32, 16);
|
||||
buffer16_1++;
|
||||
buffer16_2++;
|
||||
bufferSize1 -= 2;
|
||||
bufferSize2 -= 2;
|
||||
size -= 2;
|
||||
}
|
||||
if (bufferSize2 > 0)
|
||||
memcpy(buffer16_1, buffer16_2, bufferSize2);
|
||||
break;
|
||||
case 8:
|
||||
while (bufferSize1 > 0 && bufferSize2 > 0) {
|
||||
while (size > 0) {
|
||||
temp32 =
|
||||
(vol1 * (*buffer8_1) + vol2 * (*buffer8_2));
|
||||
temp32 += pcm_dither();
|
||||
@ -128,20 +125,16 @@ static void pcm_add(char *buffer1, const char *buffer2, size_t bufferSize1,
|
||||
*buffer8_1 = pcm_range(temp32, 8);
|
||||
buffer8_1++;
|
||||
buffer8_2++;
|
||||
bufferSize1--;
|
||||
bufferSize2--;
|
||||
size--;
|
||||
}
|
||||
if (bufferSize2 > 0)
|
||||
memcpy(buffer8_1, buffer8_2, bufferSize2);
|
||||
break;
|
||||
default:
|
||||
FATAL("%i bits not supported by pcm_add!\n", format->bits);
|
||||
}
|
||||
}
|
||||
|
||||
void pcm_mix(char *buffer1, const char *buffer2, size_t bufferSize1,
|
||||
size_t bufferSize2, const struct audio_format *format,
|
||||
float portion1)
|
||||
void pcm_mix(char *buffer1, const char *buffer2, size_t size,
|
||||
const struct audio_format *format, float portion1)
|
||||
{
|
||||
int vol1;
|
||||
float s = sin(M_PI_2 * portion1);
|
||||
@ -150,8 +143,7 @@ void pcm_mix(char *buffer1, const char *buffer2, size_t bufferSize1,
|
||||
vol1 = s * 1000 + 0.5;
|
||||
vol1 = vol1 > 1000 ? 1000 : (vol1 < 0 ? 0 : vol1);
|
||||
|
||||
pcm_add(buffer1, buffer2, bufferSize1, bufferSize2, vol1, 1000 - vol1,
|
||||
format);
|
||||
pcm_add(buffer1, buffer2, size, vol1, 1000 - vol1, format);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBSAMPLERATE
|
||||
|
@ -47,8 +47,8 @@ typedef struct _ConvState {
|
||||
void pcm_volumeChange(char *buffer, int bufferSize, const struct audio_format *format,
|
||||
int volume);
|
||||
|
||||
void pcm_mix(char *buffer1, const char *buffer2, size_t bufferSize1,
|
||||
size_t bufferSize2, const struct audio_format *format, float portion1);
|
||||
void pcm_mix(char *buffer1, const char *buffer2, size_t size,
|
||||
const struct audio_format *format, float portion1);
|
||||
|
||||
size_t pcm_convertAudioFormat(const struct audio_format *inFormat,
|
||||
const char *inBuffer, size_t inSize,
|
||||
|
Loading…
Reference in New Issue
Block a user