volume: Refactor get/set balance/fade

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

Signed-off-by: David Henningsson <david.henningsson@canonical.com>
This commit is contained in:
David Henningsson 2015-10-27 09:54:38 +01:00 committed by Tanu Kaskinen
parent 69af1a713d
commit 387a244cd9

View file

@ -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(