[pulseaudio-discuss] [RFC PATCH] softvolume: implement fast volume translation
Wang Xingchao
xingchao.wang at intel.com
Tue Oct 18 14:09:28 PDT 2011
if all channels have same volume setting, use fast way to
do volume change. this patch intended to work for two formats:
s16ne/s16re.
Signed-off-by: Wang Xingchao <xingchao.wang at intel.com>
---
src/pulsecore/svolume_c.c | 70 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 70 insertions(+), 0 deletions(-)
diff --git a/src/pulsecore/svolume_c.c b/src/pulsecore/svolume_c.c
index 272e7a7..7919faa 100644
--- a/src/pulsecore/svolume_c.c
+++ b/src/pulsecore/svolume_c.c
@@ -90,9 +90,43 @@ static void pa_volume_ulaw_c(uint8_t *samples, int32_t *volumes, unsigned channe
static void pa_volume_s16ne_c(int16_t *samples, int32_t *volumes, unsigned channels, unsigned length) {
unsigned channel;
+ int32_t same_vol = volumes[0];
+ unsigned fast_vol;
length /= sizeof(int16_t);
+ for (channel = 0; channel < channels; channel++) {
+ if (volumes[channel] != same_vol)
+ break;
+ }
+
+ fast_vol = channel < channels? 0 : 1;
+
+ if (fast_vol) {
+ int32_t t, hi, lo;
+ int32_t ht, lt;
+
+ hi = same_vol >> 16;
+ lo = same_vol & 0xffff;
+ while (length) {
+ t = *((int32_t *)samples);
+ ht = t >> 16;
+ lt = t & 0xffff;
+
+ ht = ((ht * lo) >> 16) + (ht * hi);
+ ht = PA_CLAMP_UNLIKELY(ht, -0x8000, 0x7FFF);
+
+ lt = ((lt * lo) >> 16) + (lt * hi);
+ lt = PA_CLAMP_UNLIKELY(lt, -0x8000, 0x7FFF);
+
+ *((int32_t *)samples) = ht<<16|lt;
+
+ samples += 2;
+ length -= 2;
+ }
+
+ return;
+ }
for (channel = 0; length; length--) {
int32_t t, hi, lo;
@@ -117,9 +151,45 @@ static void pa_volume_s16ne_c(int16_t *samples, int32_t *volumes, unsigned chann
static void pa_volume_s16re_c(int16_t *samples, int32_t *volumes, unsigned channels, unsigned length) {
unsigned channel;
+ int32_t same_vol = volumes[0];
+ unsigned fast_vol;
length /= sizeof(int16_t);
+ for (channel = 0; channel < channels; channel++) {
+ if (volumes[channel] != same_vol)
+ break;
+ }
+
+ fast_vol = channel < channels? 0 : 1;
+
+ if (fast_vol) {
+ int32_t t, hi, lo;
+ int32_t ht, lt;
+
+ hi = same_vol >> 16;
+ lo = same_vol & 0xffff;
+
+ while (length) {
+ t = *((int32_t *)samples);
+ ht = (int32_t)PA_INT16_SWAP((int16_t)(t >> 16));
+ lt = (int32_t)PA_INT16_SWAP((int16_t)(t & 0xffff));
+
+ ht = ((ht * lo) >> 16) + (ht * hi);
+ ht = PA_CLAMP_UNLIKELY(ht, -0x8000, 0x7FFF);
+
+ lt = ((lt * lo) >> 16) + (lt * hi);
+ lt = PA_CLAMP_UNLIKELY(lt, -0x8000, 0x7FFF);
+
+ *((int32_t *)samples) = PA_INT16_SWAP((int16_t) ht<<16)|PA_INT16_SWAP((int16_t) lt);
+
+ samples += 2;
+ length -= 2;
+ }
+
+ return;
+ }
+
for (channel = 0; length; length--) {
int32_t t, hi, lo;
--
1.7.1
More information about the pulseaudio-discuss
mailing list