diff options
author | Lennart Poettering <lennart@poettering.net> | 2004-06-29 20:37:24 +0000 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2004-06-29 20:37:24 +0000 |
commit | d571be6f5109ff5b256e4c14f391c916264f0a8e (patch) | |
tree | 6d0a90457b7f807fbd9f2b187240ab78f7c32637 /src/sample-util.c | |
parent | e31bac02573cc3090cac5816bea62a2fea888399 (diff) |
volume work
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@42 fefdeb5f-60dc-0310-8127-8f9354f1896f
Diffstat (limited to 'src/sample-util.c')
-rw-r--r-- | src/sample-util.c | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/src/sample-util.c b/src/sample-util.c index ff14548c..09511a3c 100644 --- a/src/sample-util.c +++ b/src/sample-util.c @@ -1,3 +1,4 @@ +#include <stdio.h> #include <string.h> #include <assert.h> @@ -46,7 +47,7 @@ void silence_memory(void *p, size_t length, struct pa_sample_spec *spec) { memset(p, c, length); } -size_t mix_chunks(struct mix_info channels[], unsigned nchannels, void *data, size_t length, struct pa_sample_spec *spec, uint8_t volume) { +size_t mix_chunks(struct mix_info channels[], unsigned nchannels, void *data, size_t length, struct pa_sample_spec *spec, uint32_t volume) { unsigned c, d; assert(channels && data && length && spec); assert(spec->format == PA_SAMPLE_S16NE); @@ -59,27 +60,27 @@ size_t mix_chunks(struct mix_info channels[], unsigned nchannels, void *data, si for (c = 0; c < nchannels; c++) { int32_t v; - uint8_t volume = channels[c].volume; + uint32_t volume = channels[c].volume; if (d >= channels[c].chunk.length) return d; - if (volume == 0) + if (volume == VOLUME_MUTE) v = 0; else { v = *((int16_t*) (channels[c].chunk.memblock->data + channels[c].chunk.index + d)); - if (volume != 0xFF) - v = v*volume/0xFF; + if (volume != VOLUME_NORM) + v = (int32_t) ((float)v*volume/VOLUME_NORM); } sum += v; } - if (volume == 0) + if (volume == VOLUME_MUTE) sum = 0; - else if (volume != 0xFF) - sum = sum*volume/0xFF; + else if (volume != VOLUME_NORM) + sum = (int32_t) ((float) sum*volume/VOLUME_NORM); if (sum < -0x8000) sum = -0x8000; if (sum > 0x7FFF) sum = 0x7FFF; @@ -88,3 +89,40 @@ size_t mix_chunks(struct mix_info channels[], unsigned nchannels, void *data, si data += sizeof(int16_t); } } + + +void volume_memchunk(struct memchunk*c, struct pa_sample_spec *spec, uint32_t volume) { + int16_t *d; + size_t n; + assert(c && spec && (c->length % pa_sample_size(spec) == 0)); + assert(spec->format == PA_SAMPLE_S16NE); + memblock_assert_exclusive(c->memblock); + + if (volume == VOLUME_NORM) + return; + + if (volume == VOLUME_MUTE) { + silence_memchunk(c, spec); + return; + } + + for (d = (c->memblock->data+c->index), n = c->length/sizeof(int16_t); n > 0; d++, n--) { + int32_t t = (int32_t)(*d); + + t *= volume; + t /= VOLUME_NORM; + + if (t < -0x8000) t = -0x8000; + if (t > 0x7FFF) t = 0x7FFF; + + *d = (int16_t) t; + } +} + +uint32_t volume_multiply(uint32_t a, uint32_t b) { + uint64_t p = a; + p *= b; + p /= VOLUME_NORM; + + return (uint32_t) p; +} |