pcm_utils: moved code to special 8/16 bit functions
Moved code into separate bit specific functions: - pcm_volumeChange() -> pcm_volume_change_X() - pcm_add() -> pcm_add_X() - pcm_convertTo16bit() -> pcm_convert_8_to_16()
This commit is contained in:
parent
c85b570ad7
commit
ac6bc76cdb
165
src/pcm_utils.c
165
src/pcm_utils.c
@ -43,14 +43,38 @@ pcm_range(int32_t sample, unsigned bits)
|
|||||||
return sample;
|
return sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pcm_volume_change_8(int8_t *buffer, unsigned num_samples,
|
||||||
|
unsigned volume)
|
||||||
|
{
|
||||||
|
while (num_samples > 0) {
|
||||||
|
int32_t sample = *buffer;
|
||||||
|
|
||||||
|
sample = (sample * volume + pcm_dither() + 500) / 1000;
|
||||||
|
|
||||||
|
*buffer++ = pcm_range(sample, 8);
|
||||||
|
--num_samples;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pcm_volume_change_16(int16_t *buffer, unsigned num_samples,
|
||||||
|
unsigned volume)
|
||||||
|
{
|
||||||
|
while (num_samples > 0) {
|
||||||
|
int32_t sample = *buffer;
|
||||||
|
|
||||||
|
sample = (sample * volume + pcm_dither() + 500) / 1000;
|
||||||
|
|
||||||
|
*buffer++ = pcm_range(sample, 16);
|
||||||
|
--num_samples;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void pcm_volumeChange(char *buffer, int bufferSize,
|
void pcm_volumeChange(char *buffer, int bufferSize,
|
||||||
const struct audio_format *format,
|
const struct audio_format *format,
|
||||||
int volume)
|
int volume)
|
||||||
{
|
{
|
||||||
int32_t temp32;
|
|
||||||
int8_t *buffer8 = (int8_t *) buffer;
|
|
||||||
int16_t *buffer16 = (int16_t *) buffer;
|
|
||||||
|
|
||||||
if (volume >= 1000)
|
if (volume >= 1000)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -60,74 +84,68 @@ void pcm_volumeChange(char *buffer, int bufferSize,
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (format->bits) {
|
switch (format->bits) {
|
||||||
case 16:
|
|
||||||
while (bufferSize > 0) {
|
|
||||||
temp32 = *buffer16;
|
|
||||||
temp32 *= volume;
|
|
||||||
temp32 += pcm_dither();
|
|
||||||
temp32 += 500;
|
|
||||||
temp32 /= 1000;
|
|
||||||
*buffer16 = pcm_range(temp32, 16);
|
|
||||||
buffer16++;
|
|
||||||
bufferSize -= 2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 8:
|
case 8:
|
||||||
while (bufferSize > 0) {
|
pcm_volume_change_8((int8_t *)buffer, bufferSize, volume);
|
||||||
temp32 = *buffer8;
|
|
||||||
temp32 *= volume;
|
|
||||||
temp32 += pcm_dither();
|
|
||||||
temp32 += 500;
|
|
||||||
temp32 /= 1000;
|
|
||||||
*buffer8 = pcm_range(temp32, 8);
|
|
||||||
buffer8++;
|
|
||||||
bufferSize--;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 16:
|
||||||
|
pcm_volume_change_16((int16_t *)buffer, bufferSize / 2,
|
||||||
|
volume);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FATAL("%i bits not supported by pcm_volumeChange!\n",
|
FATAL("%i bits not supported by pcm_volumeChange!\n",
|
||||||
format->bits);
|
format->bits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pcm_add_8(int8_t *buffer1, const int8_t *buffer2,
|
||||||
|
unsigned num_samples, int volume1, int volume2)
|
||||||
|
{
|
||||||
|
while (num_samples > 0) {
|
||||||
|
int32_t sample1 = *buffer1;
|
||||||
|
int32_t sample2 = *buffer2++;
|
||||||
|
|
||||||
|
sample1 = ((sample1 * volume1 + sample2 * volume2) +
|
||||||
|
pcm_dither() + 500) / 1000;
|
||||||
|
|
||||||
|
*buffer1++ = pcm_range(sample1, 8);
|
||||||
|
--num_samples;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pcm_add_16(int16_t *buffer1, const int16_t *buffer2,
|
||||||
|
unsigned num_samples, int volume1, int volume2)
|
||||||
|
{
|
||||||
|
while (num_samples > 0) {
|
||||||
|
int32_t sample1 = *buffer1;
|
||||||
|
int32_t sample2 = *buffer2++;
|
||||||
|
|
||||||
|
sample1 = ((sample1 * volume1 + sample2 * volume2) +
|
||||||
|
pcm_dither() + 500) / 1000;
|
||||||
|
|
||||||
|
*buffer1++ = pcm_range(sample1, 16);
|
||||||
|
--num_samples;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void pcm_add(char *buffer1, const char *buffer2, size_t size,
|
static void pcm_add(char *buffer1, const char *buffer2, size_t size,
|
||||||
int vol1, int vol2,
|
int vol1, int vol2,
|
||||||
const struct audio_format *format)
|
const struct audio_format *format)
|
||||||
{
|
{
|
||||||
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) {
|
switch (format->bits) {
|
||||||
case 16:
|
|
||||||
while (size > 0) {
|
|
||||||
temp32 =
|
|
||||||
(vol1 * (*buffer16_1) +
|
|
||||||
vol2 * (*buffer16_2));
|
|
||||||
temp32 += pcm_dither();
|
|
||||||
temp32 += 500;
|
|
||||||
temp32 /= 1000;
|
|
||||||
*buffer16_1 = pcm_range(temp32, 16);
|
|
||||||
buffer16_1++;
|
|
||||||
buffer16_2++;
|
|
||||||
size -= 2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 8:
|
case 8:
|
||||||
while (size > 0) {
|
pcm_add_8((int8_t *)buffer1, (const int8_t *)buffer2,
|
||||||
temp32 =
|
size, vol1, vol2);
|
||||||
(vol1 * (*buffer8_1) + vol2 * (*buffer8_2));
|
|
||||||
temp32 += pcm_dither();
|
|
||||||
temp32 += 500;
|
|
||||||
temp32 /= 1000;
|
|
||||||
*buffer8_1 = pcm_range(temp32, 8);
|
|
||||||
buffer8_1++;
|
|
||||||
buffer8_2++;
|
|
||||||
size--;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 16:
|
||||||
|
pcm_add_16((int16_t *)buffer1, (const int16_t *)buffer2,
|
||||||
|
size / 2, vol1, vol2);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FATAL("%i bits not supported by pcm_add!\n", format->bits);
|
FATAL("%i bits not supported by pcm_add!\n", format->bits);
|
||||||
}
|
}
|
||||||
@ -357,41 +375,44 @@ static char *pcm_convertChannels(int8_t channels, const char *inBuffer,
|
|||||||
return outBuffer;
|
return outBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pcm_convert_8_to_16(int16_t *out, const int8_t *in,
|
||||||
|
unsigned num_samples)
|
||||||
|
{
|
||||||
|
while (num_samples > 0) {
|
||||||
|
*out++ = *in++ << 8;
|
||||||
|
--num_samples;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const char *pcm_convertTo16bit(int8_t bits, const char *inBuffer,
|
static const char *pcm_convertTo16bit(int8_t bits, const char *inBuffer,
|
||||||
size_t inSize, size_t *outSize)
|
size_t inSize, size_t *outSize)
|
||||||
{
|
{
|
||||||
static char *buf;
|
static char *buf;
|
||||||
static size_t len;
|
static size_t len;
|
||||||
char *outBuffer = NULL;
|
unsigned num_samples;
|
||||||
const int8_t *in;
|
|
||||||
int16_t *out;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
switch (bits) {
|
switch (bits) {
|
||||||
case 8:
|
case 8:
|
||||||
|
num_samples = inSize;
|
||||||
*outSize = inSize << 1;
|
*outSize = inSize << 1;
|
||||||
if (*outSize > len) {
|
if (*outSize > len) {
|
||||||
len = *outSize;
|
len = *outSize;
|
||||||
buf = xrealloc(buf, len);
|
buf = xrealloc(buf, len);
|
||||||
}
|
}
|
||||||
outBuffer = buf;
|
|
||||||
|
|
||||||
in = (const int8_t *)inBuffer;
|
pcm_convert_8_to_16((int16_t *)buf,
|
||||||
out = (int16_t *)outBuffer;
|
(const int8_t *)inBuffer,
|
||||||
for (i = 0; i < inSize; i++)
|
num_samples);
|
||||||
*out++ = (*in++) << 8;
|
return buf;
|
||||||
|
|
||||||
break;
|
|
||||||
case 16:
|
case 16:
|
||||||
*outSize = inSize;
|
*outSize = inSize;
|
||||||
return inBuffer;
|
return inBuffer;
|
||||||
case 24:
|
|
||||||
/* put dithering code from mp3_decode here */
|
|
||||||
default:
|
|
||||||
ERROR("only 8 or 16 bits are supported for conversion!\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return outBuffer;
|
ERROR("only 8 or 16 bits are supported for conversion!\n");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* outFormat bits must be 16 and channels must be 1 or 2! */
|
/* outFormat bits must be 16 and channels must be 1 or 2! */
|
||||||
|
Loading…
Reference in New Issue
Block a user