]> code.delx.au - pulseaudio/commitdiff
Documentation of known misuse of PulseAudio API
authorAlexander E. Patrakov <patrakov@gmail.com>
Mon, 21 Oct 2013 23:19:27 +0000 (00:19 +0100)
committerTanu Kaskinen <tanu.kaskinen@linux.intel.com>
Fri, 3 Jan 2014 10:53:07 +0000 (12:53 +0200)
Hello.

Over time, I became aware of several instances of tempting but
semantically incorrect usage of PulseAudio API (one from my own bad
proposal of "improving" Wine, one from Parole media player and one
from Webkit-GTK). I want to document these gotchas so that other
developers don't fall for that. See the attached patch.

I have checked that the rendered HTML is correct, but need someone to
confirm the factual accuracy of the proposed changes and, possibly, to
improve the wording.

--
Alexander E. Patrakov

src/pulse/introspect.h
src/pulse/stream.h
src/pulse/volume.h

index 023b4186a25f0278c598c70e4bc05872527dda12..e7224c6498d025eedd463ed31c79f8f65ee57c58 100644 (file)
  * \li Sink input - pa_context_kill_sink_input()
  * \li Source output - pa_context_kill_source_output()
  *
+ * It is strongly recommended that all volume changes are done as a direct
+ * result of user input. With automated requests, such as those resulting
+ * from misguided attempts of crossfading, PulseAudio can store the stream
+ * volume at an inappropriate moment and restore it later. Besides, such
+ * attempts lead to OSD popups in some desktop environments.
+ *
+ * As a special case of the general rule above, it is recommended that your
+ * application leaves the task of saving and restoring the volume of its
+ * streams to PulseAudio and does not attempt to do it by itself. PulseAudio
+ * really knows better about events such as stream moving or headphone
+ * plugging that would make the volume stored by the application inapplicable
+ * to the new configuration.
+ *
+ * Another important case where setting a sink input volume may be a bad idea
+ * is related to interpreters that interpret potentially untrusted scripts.
+ * PulseAudio relies on your application not making malicious requests (such
+ * as repeatedly setting the volume to 100%). Thus, script interpreters that
+ * represent a security boundary must sandbox volume-changing requests coming
+ * from their scripts. In the worst case, it may be necessary to apply the
+ * script-requested volume to the script-produced sounds by altering the
+ * samples in the script interpreter and not touching the sink or sink input
+ * volume as seen by PulseAudio.
+ *
+ * If an application changes any volume, it should also listen to changes of
+ * the same volume originating from outside the application (e.g., from the
+ * system mixer application) and update its user interface accordingly. Use
+ * \ref subscribe to get such notifications.
+ *
  * \subsection module_subsec Modules
  *
  * Server modules can be remotely loaded and unloaded using
index 9fab629e4d3710da986d3127dbef7c8bc0583eac..40cbe640d5e3a2e42c193bfb2e4feae46f142831 100644 (file)
  * pa_stream_set_state_callback(), and wait for the stream to enter an active
  * state.
  *
+ * Note: there is a user-controllable slider in mixer applications such as
+ * pavucontrol corresponding to each of the created streams. Multiple
+ * (especially identically named) volume sliders for the same application might
+ * confuse the user. Also, the server supports only a limited number of
+ * simultaneous streams. Because of this, it is not always appropriate to
+ * create multiple streams in one application that needs to output multiple
+ * sounds. The rough guideline is: if there is no use case that would require
+ * separate user-initiated volume changes for each stream, perform the mixing
+ * inside the application.
+ *
  * \subsection bufattr_subsec Buffer Attributes
  *
  * Playback and record streams always have a server-side buffer as
@@ -435,7 +445,9 @@ int pa_stream_is_corked(pa_stream *s);
  * an absolute device volume. Since 0.9.20 it is an absolute volume when
  * the sink is in flat volume mode, and relative otherwise, thus
  * making sure the volume passed here has always the same semantics as
- * the volume passed to pa_context_set_sink_input_volume(). */
+ * the volume passed to pa_context_set_sink_input_volume(). It is possible
+ * to figure out whether flat volume mode is in effect for a given sink
+ * by calling pa_context_get_sink_info_by_name(). */
 int pa_stream_connect_playback(
         pa_stream *s                  /**< The stream to connect to a sink */,
         const char *dev               /**< Name of the sink to connect to, or NULL for default */ ,
index ab6c59bac8286b2ed2cdfadf587db54b7c446f39..7806954e03f7a8b3f8dc086b7c82f3b9b903ede2 100644 (file)
  * Volumes commonly span between muted (0%), and normal (100%). It is possible
  * to set volumes to higher than 100%, but clipping might occur.
  *
+ * There is no single well-defined meaning attached to the 100% volume for a
+ * sink input. In fact, it depends on the server configuration. With flat
+ * volumes enabled (the default in most Linux distributions), it means the
+ * maximum volume that the sound hardware is capable of, which is usually so
+ * high that you absolutely must not set sink input volume to 100% unless the
+ * the user explicitly requests that (note that usually you shouldn't set the
+ * volume anyway if the user doesn't explicitly request it, instead, let
+ * PulseAudio decide the volume for the sink input). With flat volumes disabled
+ * (the default in Ubuntu), the sink input volume is relative to the sink
+ * volume, so 100% sink input volume means that the sink input is played at the
+ * current sink volume level. In this case 100% is often a good default volume
+ * for a sink input, although you still should let PulseAudio decide the
+ * default volume. It is possible to figure out whether flat volume mode is in
+ * effect for a given sink by calling pa_context_get_sink_info_by_name().
+ *
  * \section calc_sec Calculations
  *
  * The volumes in PulseAudio are logarithmic in nature and applications