diff options
Diffstat (limited to 'src/pcm_volume.c')
-rw-r--r-- | src/pcm_volume.c | 64 |
1 files changed, 39 insertions, 25 deletions
diff --git a/src/pcm_volume.c b/src/pcm_volume.c index 240c779d8..49c86026f 100644 --- a/src/pcm_volume.c +++ b/src/pcm_volume.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2010 The Music Player Daemon Project + * Copyright (C) 2003-2011 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -31,9 +31,9 @@ #define G_LOG_DOMAIN "pcm_volume" static void -pcm_volume_change_8(int8_t *buffer, unsigned num_samples, int volume) +pcm_volume_change_8(int8_t *buffer, const int8_t *end, int volume) { - while (num_samples > 0) { + while (buffer < end) { int32_t sample = *buffer; sample = (sample * volume + pcm_volume_dither() + @@ -41,14 +41,13 @@ pcm_volume_change_8(int8_t *buffer, unsigned num_samples, int volume) / PCM_VOLUME_1; *buffer++ = pcm_range(sample, 8); - --num_samples; } } static void -pcm_volume_change_16(int16_t *buffer, unsigned num_samples, int volume) +pcm_volume_change_16(int16_t *buffer, const int16_t *end, int volume) { - while (num_samples > 0) { + while (buffer < end) { int32_t sample = *buffer; sample = (sample * volume + pcm_volume_dither() + @@ -56,7 +55,6 @@ pcm_volume_change_16(int16_t *buffer, unsigned num_samples, int volume) / PCM_VOLUME_1; *buffer++ = pcm_range(sample, 16); - --num_samples; } } @@ -92,9 +90,9 @@ pcm_volume_sample_24(int32_t sample, int32_t volume, G_GNUC_UNUSED int32_t dithe #endif static void -pcm_volume_change_24(int32_t *buffer, unsigned num_samples, int volume) +pcm_volume_change_24(int32_t *buffer, const int32_t *end, int volume) { - while (num_samples > 0) { + while (buffer < end) { #ifdef __i386__ /* assembly version for i386 */ int32_t sample = *buffer; @@ -110,14 +108,13 @@ pcm_volume_change_24(int32_t *buffer, unsigned num_samples, int volume) / PCM_VOLUME_1; #endif *buffer++ = pcm_range(sample, 24); - --num_samples; } } static void -pcm_volume_change_32(int32_t *buffer, unsigned num_samples, int volume) +pcm_volume_change_32(int32_t *buffer, const int32_t *end, int volume) { - while (num_samples > 0) { + while (buffer < end) { #ifdef __i386__ /* assembly version for i386 */ int32_t sample = *buffer; @@ -132,14 +129,22 @@ pcm_volume_change_32(int32_t *buffer, unsigned num_samples, int volume) / PCM_VOLUME_1; *buffer++ = pcm_range_64(sample, 32); #endif + } +} - --num_samples; +static void +pcm_volume_change_float(float *buffer, const float *end, float volume) +{ + while (buffer < end) { + float sample = *buffer; + sample *= volume; + *buffer++ = sample; } } bool -pcm_volume(void *buffer, int length, - const struct audio_format *format, +pcm_volume(void *buffer, size_t length, + enum sample_format format, int volume) { if (volume == PCM_VOLUME_1) @@ -150,27 +155,36 @@ pcm_volume(void *buffer, int length, return true; } - switch (format->format) { + const void *end = pcm_end_pointer(buffer, length); + switch (format) { + case SAMPLE_FORMAT_UNDEFINED: + case SAMPLE_FORMAT_DSD: + /* not implemented */ + return false; + case SAMPLE_FORMAT_S8: - pcm_volume_change_8((int8_t *)buffer, length, volume); + pcm_volume_change_8(buffer, end, volume); return true; case SAMPLE_FORMAT_S16: - pcm_volume_change_16((int16_t *)buffer, length / 2, - volume); + pcm_volume_change_16(buffer, end, volume); return true; case SAMPLE_FORMAT_S24_P32: - pcm_volume_change_24((int32_t*)buffer, length / 4, - volume); + pcm_volume_change_24(buffer, end, volume); return true; case SAMPLE_FORMAT_S32: - pcm_volume_change_32((int32_t*)buffer, length / 4, - volume); + pcm_volume_change_32(buffer, end, volume); return true; - default: - return false; + case SAMPLE_FORMAT_FLOAT: + pcm_volume_change_float(buffer, end, + pcm_volume_to_float(volume)); + return true; } + + /* unreachable */ + assert(false); + return false; } |