diff options
Diffstat (limited to 'src/pcm_utils.c')
-rw-r--r-- | src/pcm_utils.c | 106 |
1 files changed, 58 insertions, 48 deletions
diff --git a/src/pcm_utils.c b/src/pcm_utils.c index 90856fa1d..a798223c7 100644 --- a/src/pcm_utils.c +++ b/src/pcm_utils.c @@ -24,12 +24,32 @@ #include "conf.h" #include "os_compat.h" +static inline int +pcm_dither(void) +{ + return (rand() & 511) - (rand() & 511); +} + +/** + * Check if the value is within the range of the provided bit size, + * and caps it if necessary. + */ +static int32_t +pcm_range(int32_t sample, unsigned bits) +{ + if (mpd_unlikely(sample < (-1 << (bits - 1)))) + return -1 << (bits - 1); + if (mpd_unlikely(sample >= (1 << (bits - 1)))) + return (1 << (bits - 1)) - 1; + return sample; +} + void pcm_volumeChange(char *buffer, int bufferSize, const AudioFormat * format, int volume) { - mpd_sint32 temp32; - mpd_sint8 *buffer8 = (mpd_sint8 *) buffer; - mpd_sint16 *buffer16 = (mpd_sint16 *) buffer; + int32_t temp32; + int8_t *buffer8 = (int8_t *) buffer; + int16_t *buffer16 = (int16_t *) buffer; if (volume >= 1000) return; @@ -44,12 +64,10 @@ void pcm_volumeChange(char *buffer, int bufferSize, const AudioFormat * format, while (bufferSize > 0) { temp32 = *buffer16; temp32 *= volume; - temp32 += rand() & 511; - temp32 -= rand() & 511; + temp32 += pcm_dither(); temp32 += 500; temp32 /= 1000; - *buffer16 = temp32 > 32767 ? 32767 : - (temp32 < -32768 ? -32768 : temp32); + *buffer16 = pcm_range(temp32, 16); buffer16++; bufferSize -= 2; } @@ -58,12 +76,10 @@ void pcm_volumeChange(char *buffer, int bufferSize, const AudioFormat * format, while (bufferSize > 0) { temp32 = *buffer8; temp32 *= volume; - temp32 += rand() & 511; - temp32 -= rand() & 511; + temp32 += pcm_dither(); temp32 += 500; temp32 /= 1000; - *buffer8 = temp32 > 127 ? 127 : - (temp32 < -128 ? -128 : temp32); + *buffer8 = pcm_range(temp32, 8); buffer8++; bufferSize--; } @@ -78,11 +94,11 @@ static void pcm_add(char *buffer1, const char *buffer2, size_t bufferSize1, size_t bufferSize2, int vol1, int vol2, const AudioFormat * format) { - mpd_sint32 temp32; - mpd_sint8 *buffer8_1 = (mpd_sint8 *) buffer1; - const mpd_sint8 *buffer8_2 = (const mpd_sint8 *) buffer2; - mpd_sint16 *buffer16_1 = (mpd_sint16 *) buffer1; - const mpd_sint16 *buffer16_2 = (const mpd_sint16 *) buffer2; + int32_t temp32; + int8_t *buffer8_1 = (int8_t *) buffer1; + const int8_t *buffer8_2 = (const int8_t *) buffer2; + int16_t *buffer16_1 = (int16_t *) buffer1; + const int16_t *buffer16_2 = (const int16_t *) buffer2; switch (format->bits) { case 16: @@ -90,13 +106,10 @@ static void pcm_add(char *buffer1, const char *buffer2, size_t bufferSize1, temp32 = (vol1 * (*buffer16_1) + vol2 * (*buffer16_2)); - temp32 += rand() & 511; - temp32 -= rand() & 511; + temp32 += pcm_dither(); temp32 += 500; temp32 /= 1000; - *buffer16_1 = - temp32 > 32767 ? 32767 : (temp32 < - -32768 ? -32768 : temp32); + *buffer16_1 = pcm_range(temp32, 16); buffer16_1++; buffer16_2++; bufferSize1 -= 2; @@ -109,13 +122,10 @@ static void pcm_add(char *buffer1, const char *buffer2, size_t bufferSize1, while (bufferSize1 > 0 && bufferSize2 > 0) { temp32 = (vol1 * (*buffer8_1) + vol2 * (*buffer8_2)); - temp32 += rand() & 511; - temp32 -= rand() & 511; + temp32 += pcm_dither(); temp32 += 500; temp32 /= 1000; - *buffer8_1 = - temp32 > 127 ? 127 : (temp32 < - -128 ? -128 : temp32); + *buffer8_1 = pcm_range(temp32, 8); buffer8_1++; buffer8_2++; bufferSize1--; @@ -182,9 +192,9 @@ out: #endif #ifdef HAVE_LIBSAMPLERATE -static size_t pcm_convertSampleRate(mpd_sint8 channels, mpd_uint32 inSampleRate, +static size_t pcm_convertSampleRate(int8_t channels, uint32_t inSampleRate, const char *inBuffer, size_t inSize, - mpd_uint32 outSampleRate, char *outBuffer, + uint32_t outSampleRate, char *outBuffer, size_t outSize, ConvState *convState) { static int convalgo = -1; @@ -258,19 +268,19 @@ static size_t pcm_convertSampleRate(mpd_sint8 channels, mpd_uint32 inSampleRate, } #else /* !HAVE_LIBSAMPLERATE */ /* resampling code blatantly ripped from ESD */ -static size_t pcm_convertSampleRate(mpd_sint8 channels, mpd_uint32 inSampleRate, +static size_t pcm_convertSampleRate(int8_t channels, uint32_t inSampleRate, const char *inBuffer, mpd_unused size_t inSize, - mpd_uint32 outSampleRate, char *outBuffer, + uint32_t outSampleRate, char *outBuffer, size_t outSize, mpd_unused ConvState *convState) { - mpd_uint32 rd_dat = 0; - mpd_uint32 wr_dat = 0; - mpd_sint16 *in = (mpd_sint16 *)inBuffer; - mpd_sint16 *out = (mpd_sint16 *)outBuffer; - mpd_uint32 nlen = outSize / 2; - mpd_sint16 lsample, rsample; + uint32_t rd_dat = 0; + uint32_t wr_dat = 0; + int16_t *in = (int16_t *)inBuffer; + int16_t *out = (int16_t *)outBuffer; + uint32_t nlen = outSize / 2; + int16_t lsample, rsample; switch (channels) { case 1: @@ -300,14 +310,14 @@ static size_t pcm_convertSampleRate(mpd_sint8 channels, mpd_uint32 inSampleRate, } #endif /* !HAVE_LIBSAMPLERATE */ -static char *pcm_convertChannels(mpd_sint8 channels, const char *inBuffer, +static char *pcm_convertChannels(int8_t channels, const char *inBuffer, size_t inSize, size_t *outSize) { static char *buf; static size_t len; char *outBuffer = NULL; - const mpd_sint16 *in; - mpd_sint16 *out; + const int16_t *in; + int16_t *out; int inSamples, i; switch (channels) { @@ -321,8 +331,8 @@ static char *pcm_convertChannels(mpd_sint8 channels, const char *inBuffer, outBuffer = buf; inSamples = inSize >> 1; - in = (const mpd_sint16 *)inBuffer; - out = (mpd_sint16 *)outBuffer; + in = (const int16_t *)inBuffer; + out = (int16_t *)outBuffer; for (i = 0; i < inSamples; i++) { *out++ = *in; *out++ = *in++; @@ -339,8 +349,8 @@ static char *pcm_convertChannels(mpd_sint8 channels, const char *inBuffer, outBuffer = buf; inSamples = inSize >> 2; - in = (const mpd_sint16 *)inBuffer; - out = (mpd_sint16 *)outBuffer; + in = (const int16_t *)inBuffer; + out = (int16_t *)outBuffer; for (i = 0; i < inSamples; i++) { *out = (*in++) / 2; *out++ += (*in++) / 2; @@ -354,14 +364,14 @@ static char *pcm_convertChannels(mpd_sint8 channels, const char *inBuffer, return outBuffer; } -static const char *pcm_convertTo16bit(mpd_sint8 bits, const char *inBuffer, +static const char *pcm_convertTo16bit(int8_t bits, const char *inBuffer, size_t inSize, size_t *outSize) { static char *buf; static size_t len; char *outBuffer = NULL; - const mpd_sint8 *in; - mpd_sint16 *out; + const int8_t *in; + int16_t *out; size_t i; switch (bits) { @@ -373,8 +383,8 @@ static const char *pcm_convertTo16bit(mpd_sint8 bits, const char *inBuffer, } outBuffer = buf; - in = (const mpd_sint8 *)inBuffer; - out = (mpd_sint16 *)outBuffer; + in = (const int8_t *)inBuffer; + out = (int16_t *)outBuffer; for (i = 0; i < inSize; i++) *out++ = (*in++) << 8; |