GNOME Bugzilla – Bug 680779
pulseaudio: Full volume may raise overall system volume when flat-volume is used
Last modified: 2015-09-09 10:31:28 UTC
Some applications (mostly those written before PulseAudio became common, or written on Ubuntu) ask playbin2 or similar elements to set the volume in 100% (or whatever their internal volume slider points to) and expect a sane result. Since the problem is common to many applications, I'd say it is a bug in either pulseaudio or gstreamer, in the sense that gstreamer's volume API is too easy to misuse when pulseaudio-with-flat-volumes is present. "Duplicates" or rather workarounds (some already fixed, some not, and some possibly broken with flat volumes disabled): https://bugzilla.gnome.org/show_bug.cgi?id=675217 (not fixed) https://bugs.launchpad.net/decibel-audio-player/+bug/511589 (claimed to be fixed, but really isn't) http://allievi.sssup.it/techblog/?p=768 (fixed) https://bugs.kde.org/show_bug.cgi?id=296589 (don't know) Pledges to remove flat volumes from pulseaudio or make them non-default: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=674935 http://pulseaudio.org/ticket/949 https://bugs.freedesktop.org/show_bug.cgi?id=46466 (in some sense) Easiest reproducer: gst-launch-0.10 playbin2 uri=file:///path/to/file.flac volume=1.0 Actual result: depends on the default sink. With alsasink, you get exactly the same behaviour as if there were no "volume=1.0" (i.e. no changes to the ALSA mixer - if it is set low, you get a quiet sound). With pulsesink, it depends on pulseaudio configuration. If flat volumes are enabled (i.e. the upstream default setting), this sets the maximum possible hardware volume, which is a different behaviour from all other sinks. If flat volumes are disabled (the default on Ubuntu), it behaves from the user viewpoint just like alsasink but does not need the internal software volume element. In other words, in all cases except "pulsesink with flat volumes", the volume on the playbin is relative to the system mixer setting. In the exceptional case (that is the default now in most Linux distributions) the volume is absolute (IOW, relative to the hardware maximum, disregarding the system mixer). And it is not possible to know if the absolute or relative volume mode is in use. Moreover, an application that wants to sound "slightly quieter than normal" should not care whether pulsesink is in use or whether flat volumes are enabled - so the abstraction provided by gstreamer's playbin2 is leaky and should be fixed. Expected result: consistent behaviour, non-leaky abstraction, relative-to-system-mixer volume scale in all cases, no surprise to users. BTW, 1) if pulseaudio folks remove flat volumes (or make them relative while keeping the alsa-mixer-adjusting logic) then this bug can be closed as invalid 2) pulseaudio folks recommend not exposing volume sliders in pulseaudio applications at all (see e.g. http://pulseaudio.org/ticket/949#comment:1, and IMHO this should apply to applications that use pulseaudio indirectly through gstreamer). So maybe it makes sense to fix this bug by removing all kinds of volume support from pulsesink, because this support is not supposed to be used.
This behavior still persists in GStreamer 1.x, I suspect there's not much chance of changing it at this point. However, it would be good for a 'best practice' for dealing with this issue to be added to the documentation, that way application developers don't inadvertently run into it.
There is already some documentation in PulseAudio, you may copy it or use as inspiration. I, as the author of this documentation, grant the permission to relicense this piece documentation if needed for the purposes of inclusion into GStreamer. http://cgit.freedesktop.org/pulseaudio/pulseaudio/commit/?id=3535fd7a076228fdeae3755cf8ac6fdcfa28741d OTOH I must state my own current opinion that some developers disagree with: PulseAudio bug. See also https://bugzilla.gnome.org/show_bug.cgi?id=675217 , https://bugs.webkit.org/show_bug.cgi?id=118974 , https://bugreports.qt.io/browse/QTBUG-34896
I would consider this as NOTABUG for GStreamer. The semantics are well defined in playbin: 100% (==1.0) means that the samples we send to the sink are not scaled, 0.5 means every sample is scaled by 0.5, 2.0 means it's scaled by 2.0. That is 100% is whatever the default of the sound system is, 0.5 is -6dB and 2.0 is +6dB. (dB = 20 * log_10(linear_scale)) It might be that pulsesink implements the GstStreamVolume interface wrong though, it should do exactly what I described above with PulseAudio API.
*** Bug 748577 has been marked as a duplicate of this bug. ***
I think it's a pulsesink thing too, note also that due to missing notify:: we endup not being able to workaround it it seems.
I agree that technically, this is NOTABUG for gstreamer. The thing that caught me was that our app has a volume slider, and didn't expect that the volume for the sink would change if my app didn't set it (because the sink volume was assumed to be local to the application). So user would set the volume to .5, and then the system audio would get set to .2 which changed the sink volume... well, when the volume got set inside my app to '1 step up', of course it set it to .6, which is of course very disconcerting. Documenting that this can happen sometime and that app authors need to expect it would be a very good idea, since it doesn't happen on all platforms. A note should be added to playbin/playsink AND autoaudiosink/pulsesink.
It is expected that applications use the stream volume as a stream volume, and it should not be necessary for them to be aware of the change to the system volume. Users should not be surprised by this either, since it is standard behaviour across all applications on their desktop. The exception to this is related to the comment Alexander makes. If your application allows programmatic access to the volume (such as JavaScript does in browser loading a web page <audio> or <video> elements), then there needs to be a way to not have flat volumes apply. This is something that we're still working on a reasonable solution for upstream. Either way, though, this is not a GStreamer bug, and I don't believe this needs to be documented in GStreamer.