[pulseaudio-discuss] [PATCH v2 1/2] volume: Refactor get/set balance/fade

David Henningsson david.henningsson at canonical.com
Tue Oct 27 01:54:38 PDT 2015


get/set balance and fade use very similar code, so refactor out
common parts.

Signed-off-by: David Henningsson <david.henningsson at canonical.com>
---
 src/pulse/volume.c | 115 +++++++++++++++--------------------------------------
 1 file changed, 33 insertions(+), 82 deletions(-)

diff --git a/src/pulse/volume.c b/src/pulse/volume.c
index 69bef4f..b3addce 100644
--- a/src/pulse/volume.c
+++ b/src/pulse/volume.c
@@ -635,7 +635,12 @@ int pa_cvolume_compatible_with_channel_map(const pa_cvolume *v, const pa_channel
     return v->channels == cm->channels;
 }
 
-static void get_avg_lr(const pa_channel_map *map, const pa_cvolume *v, pa_volume_t *l, pa_volume_t *r) {
+/*
+ * Returns the average volume of l and r, where l and r are two disjoint sets of channels
+ * (e g left and right, or front and rear).
+ */
+static void get_avg(const pa_channel_map *map, const pa_cvolume *v, pa_volume_t *l, pa_volume_t *r,
+                    bool (*on_l)(pa_channel_position_t), bool (*on_r)(pa_channel_position_t)) {
     int c;
     pa_volume_t left = 0, right = 0;
     unsigned n_left = 0, n_right = 0;
@@ -647,10 +652,10 @@ static void get_avg_lr(const pa_channel_map *map, const pa_cvolume *v, pa_volume
     pa_assert(r);
 
     for (c = 0; c < map->channels; c++) {
-        if (on_left(map->map[c])) {
+        if (on_l(map->map[c])) {
             left += v->values[c];
             n_left++;
-        } else if (on_right(map->map[c])) {
+        } else if (on_r(map->map[c])) {
             right += v->values[c];
             n_right++;
         }
@@ -678,7 +683,7 @@ float pa_cvolume_get_balance(const pa_cvolume *v, const pa_channel_map *map) {
     if (!pa_channel_map_can_balance(map))
         return 0.0f;
 
-    get_avg_lr(map, v, &left, &right);
+    get_avg(map, v, &left, &right, on_left, on_right);
 
     if (left == right)
         return 0.0f;
@@ -698,21 +703,13 @@ float pa_cvolume_get_balance(const pa_cvolume *v, const pa_channel_map *map) {
         return 1.0f - ((float) left / (float) right);
 }
 
-pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, float new_balance) {
+static pa_cvolume* set_balance(pa_cvolume *v, const pa_channel_map *map, float new_balance,
+                               bool (*on_l)(pa_channel_position_t), bool (*on_r)(pa_channel_position_t)) {
+
     pa_volume_t left, nleft, right, nright, m;
     unsigned c;
 
-    pa_assert(map);
-    pa_assert(v);
-
-    pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), NULL);
-    pa_return_val_if_fail(new_balance >= -1.0f, NULL);
-    pa_return_val_if_fail(new_balance <= 1.0f, NULL);
-
-    if (!pa_channel_map_can_balance(map))
-        return v;
-
-    get_avg_lr(map, v, &left, &right);
+    get_avg(map, v, &left, &right, on_l, on_r);
 
     m = PA_MAX(left, right);
 
@@ -725,12 +722,12 @@ pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, flo
     }
 
     for (c = 0; c < map->channels; c++) {
-        if (on_left(map->map[c])) {
+        if (on_l(map->map[c])) {
             if (left == 0)
                 v->values[c] = nleft;
             else
                 v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) nleft) / (uint64_t) left);
-        } else if (on_right(map->map[c])) {
+        } else if (on_r(map->map[c])) {
             if (right == 0)
                 v->values[c] = nright;
             else
@@ -741,6 +738,21 @@ pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, flo
     return v;
 }
 
+
+pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, float new_balance) {
+    pa_assert(map);
+    pa_assert(v);
+
+    pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), NULL);
+    pa_return_val_if_fail(new_balance >= -1.0f, NULL);
+    pa_return_val_if_fail(new_balance <= 1.0f, NULL);
+
+    if (!pa_channel_map_can_balance(map))
+        return v;
+
+    return set_balance(v, map, new_balance, on_left, on_right);
+}
+
 pa_cvolume* pa_cvolume_scale(pa_cvolume *v, pa_volume_t max) {
     unsigned c;
     pa_volume_t t = 0;
@@ -785,40 +797,8 @@ pa_cvolume* pa_cvolume_scale_mask(pa_cvolume *v, pa_volume_t max, pa_channel_map
     return v;
 }
 
-static void get_avg_fr(const pa_channel_map *map, const pa_cvolume *v, pa_volume_t *f, pa_volume_t *r) {
-    int c;
-    pa_volume_t front = 0, rear = 0;
-    unsigned n_front = 0, n_rear = 0;
-
-    pa_assert(v);
-    pa_assert(map);
-    pa_assert(map->channels == v->channels);
-    pa_assert(f);
-    pa_assert(r);
-
-    for (c = 0; c < map->channels; c++) {
-        if (on_front(map->map[c])) {
-            front += v->values[c];
-            n_front++;
-        } else if (on_rear(map->map[c])) {
-            rear += v->values[c];
-            n_rear++;
-        }
-    }
-
-    if (n_front <= 0)
-        *f = PA_VOLUME_NORM;
-    else
-        *f = front / n_front;
-
-    if (n_rear <= 0)
-        *r = PA_VOLUME_NORM;
-    else
-        *r = rear / n_rear;
-}
-
 float pa_cvolume_get_fade(const pa_cvolume *v, const pa_channel_map *map) {
-    pa_volume_t front, rear;
+    pa_volume_t rear, front;
 
     pa_assert(v);
     pa_assert(map);
@@ -828,7 +808,7 @@ float pa_cvolume_get_fade(const pa_cvolume *v, const pa_channel_map *map) {
     if (!pa_channel_map_can_fade(map))
         return 0.0f;
 
-    get_avg_fr(map, v, &front, &rear);
+    get_avg(map, v, &rear, &front, on_rear, on_front);
 
     if (front == rear)
         return 0.0f;
@@ -840,9 +820,6 @@ float pa_cvolume_get_fade(const pa_cvolume *v, const pa_channel_map *map) {
 }
 
 pa_cvolume* pa_cvolume_set_fade(pa_cvolume *v, const pa_channel_map *map, float new_fade) {
-    pa_volume_t front, nfront, rear, nrear, m;
-    unsigned c;
-
     pa_assert(map);
     pa_assert(v);
 
@@ -853,33 +830,7 @@ pa_cvolume* pa_cvolume_set_fade(pa_cvolume *v, const pa_channel_map *map, float
     if (!pa_channel_map_can_fade(map))
         return v;
 
-    get_avg_fr(map, v, &front, &rear);
-
-    m = PA_MAX(front, rear);
-
-    if (new_fade <= 0) {
-        nfront = (new_fade + 1.0f) * m;
-        nrear = m;
-    } else {
-        nrear = (1.0f - new_fade) * m;
-        nfront = m;
-    }
-
-    for (c = 0; c < map->channels; c++) {
-        if (on_front(map->map[c])) {
-            if (front == 0)
-                v->values[c] = nfront;
-            else
-                v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) nfront) / (uint64_t) front);
-        } else if (on_rear(map->map[c])) {
-            if (rear == 0)
-                v->values[c] = nrear;
-            else
-                v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) nrear) / (uint64_t) rear);
-        }
-    }
-
-    return v;
+    return set_balance(v, map, new_fade, on_rear, on_front);
 }
 
 pa_cvolume* pa_cvolume_set_position(
-- 
1.9.1



More information about the pulseaudio-discuss mailing list