From dbfbacc9571fade87855907b78c6ed5e27c910dd Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Mon, 23 Aug 2021 14:06:20 +0800 Subject: [PATCH] mixer-control: set max_volume to PA_VOLUME_NORM if no valid volume Reproducers: 1. After a fresh install of Ubuntu 20.04, open a gnome-terminal and press the Tab key, the system will output a bell notification sound. Open gnome-control-center and check the sound page, the output volume of 'System Sounds' is at 0, but the notification sound is still output at max volume. 2. After a fresh install of Ubuntu 20.04, open gnome-control-center directly, change to the sound page, the output volume of 'System Sounds' is at its max level. Click any 'Alert Sound' button at the bottom of the page, the sound is output at max volume but the UI slider for the output volume of 'System Sounds' changes to 0. The notification sound can however still could be heard at max volume. After a fresh install of the system, there is no saved entry for "sink-input-by-media-role:event" in PulseAudio's module-stream-restore, so libgvc will create a pa_ext_stream_restore_info in the _pa_ext_stream_restore_read_cb(). When a notification sound stream is sent to PA, PA will create an entry with name of "sink-input-by-media-role:event" and save it to the database, but volume_valid is false until gnome calls pa_ext_stream_restore_write(). So if users open the gnome-control-center before pa_ext_stream_restore_write() is called, although there is an entry named "sink-input-by-media-role:event" in the module-stream-restore, the volume is not valid in that entry, and calling pa_cvolume_max (&info->volume) will returns 0. In this case, libgvc reports the max_volume is 0, but in PulseAudio, the stream/sink-input volume is max (pa_sink_input_new() of the sink-input.c). Check if info->volume.channels is 0, which would mean the volume is not valid in the entry, and set max_volume to PA_VOLUME_NORM like _pa_ext_stream_restore_read_cb() does in this case. Below is the PA log about the stream entry without a valid volume: E: [pulseaudio] module-stream-restore.c: name=sink-input-by-media-role:event E: [pulseaudio] module-stream-restore.c: device=(null) no E: [pulseaudio] module-stream-restore.c: channel_map=(invalid) E: [pulseaudio] module-stream-restore.c: volume=(invalid) no E: [pulseaudio] module-stream-restore.c: mute=no no --- gvc-mixer-control.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gvc-mixer-control.c b/gvc-mixer-control.c index b603b77..2cc68ef 100644 --- a/gvc-mixer-control.c +++ b/gvc-mixer-control.c @@ -2871,7 +2871,13 @@ update_event_role_stream (GvcMixerControl *control, GUINT_TO_POINTER (control->priv->event_sink_input_id)); } - max_volume = pa_cvolume_max (&info->volume); + /* 0 channels here means there is no valid volume in + * pa_ext_stream_restore_info() and in the saved stream entry of + * module-stream-restore in PulseAudio. */ + if (info->volume.channels == 0) + max_volume = PA_VOLUME_NORM; + else + max_volume = pa_cvolume_max (&info->volume); gvc_mixer_stream_set_name (stream, _("System Sounds")); gvc_mixer_stream_set_icon_name (stream, "audio-x-generic");