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 <[email protected]>
---
 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

_______________________________________________
pulseaudio-discuss mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Reply via email to