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