Hi, I fixed bug: #874 pulseaudio breaks per-channel volume config when restoring volume from 0%. I created arrayto record balance. When the volume change to 0%, I can use last balance to calculate new volume. Here is the patch: Signed-off-by: Chen Rui <rui.chen at tieto.com> --- src/pulse/volume.c | 23 +++++++++++++++++++++-- src/pulsecore/sink.c | 21 ++++++++++++++++++++- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/pulse/volume.c b/src/pulse/volume.c index f74d720..a51af0b 100644 --- a/src/pulse/volume.c +++ b/src/pulse/volume.c @@ -683,6 +683,8 @@ pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, flo pa_cvolume* pa_cvolume_scale(pa_cvolume *v, pa_volume_t max) { unsigned c; + static float balance[PA_CHANNELS_MAX/2] = {0}; + pa_volume_t left, right; pa_volume_t t = 0; pa_assert(v); @@ -692,8 +694,25 @@ pa_cvolume* pa_cvolume_scale(pa_cvolume *v, pa_volume_t max) { t = pa_cvolume_max(v); - if (t <= PA_VOLUME_MUTED) - return pa_cvolume_set(v, v->channels, max); + for (c = 0; c < v->channels/2; c++){ + left = v->values[2*c]; + right = v->values[2*c+1]; + if (left < right) + balance[c] = (1 - (float)left/right); + else if(left > right) + balance[c] = (-1 + (float)right/left); + } + + if (t <= PA_VOLUME_MUTED){ + pa_cvolume_set(v, v->channels, max); + for (c = 0; c < v->channels/2; c++){ + if(balance[c] > 0) + v->values[2*c] = v->values[2*c] * (1 - balance[c]); + else if(balance[c] < 0) + v->values[2*c+1] = v->values[2*c+1] * (1 + balance[c]); + } + return v; + } for (c = 0; c < v->channels; c++) v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) max) / (uint64_t) t); diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 7b4e626..e7076ad 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -1454,8 +1454,27 @@ void pa_sink_set_volume( if (volume) { - if (pa_cvolume_compatible(volume, &s->sample_spec)) + if (pa_cvolume_compatible(volume, &s->sample_spec)){ + pa_cvolume *tmp_volume = volume; + unsigned c; + static float balance[PA_CHANNELS_MAX/2]; + for (c = 0; c < volume->channels/2; c++){ + pa_volume_t left, right; + left = tmp_volume->values[2*c]; + right = tmp_volume->values[2*c+1]; + if (left < right) + balance[c] = (1 - (float)left/right); + else if(left > right) + balance[c] = (-1 + (float)right/left); + if(left == right && left == 0){ + if(balance[c] > 0) + tmp_volume->values[2*c] = tmp_volume->values[2*c] * (1 - balance[c]); + else if(balance < 0) + tmp_volume->values[2*c+1] = tmp_volume->values[2*c+1] * (1 + balance[c]); + } + } s->reference_volume = *volume; + } else pa_cvolume_scale(&s->reference_volume, pa_cvolume_max(volume));