* \section overv_sec Overview
*
* Sinks, sources, sink inputs and samples can all have their own volumes.
- * To deal with these, The PulseAudio libray contains a number of functions
+ * To deal with these, The PulseAudio library contains a number of functions
* that ease handling.
*
* The basic volume type in PulseAudio is the \ref pa_volume_t type. Most of
* \section conv_sec Convenience Functions
*
* To handle the pa_cvolume structure, the PulseAudio library provides a
- * number of convenienc functions:
+ * number of convenience functions:
*
* \li pa_cvolume_valid() - Tests if a pa_cvolume structure is valid.
* \li pa_cvolume_equal() - Tests if two pa_cvolume structures are identical.
* structure are muted.
* \li pa_cvolume_is_norm() - Tests if all channels of a pa_cvolume structure
* are at a normal volume.
- * \li pa_cvolume_set() - Set all channels of a pa_cvolume structure to a
- * certain volume.
- * \li pa_cvolume_reset() - Set all channels of a pa_cvolume structure to a
- * normal volume.
- * \li pa_cvolume_mute() - Set all channels of a pa_cvolume structure to a
- * muted volume.
+ * \li pa_cvolume_set() - Set the first n channels of a pa_cvolume structure to
+ * a certain volume.
+ * \li pa_cvolume_reset() - Set the first n channels of a pa_cvolume structure
+ * to a normal volume.
+ * \li pa_cvolume_mute() - Set the first n channels of a pa_cvolume structure
+ * to a muted volume.
* \li pa_cvolume_avg() - Return the average volume of all channels.
* \li pa_cvolume_snprint() - Pretty print a pa_cvolume structure.
*/
/** \file
- * Constants and routines for volume handling */
+ * Constants and routines for volume handling
+ *
+ * See also \subpage volume
+ */
PA_C_DECL_BEGIN
/** Normal volume (100%, 0 dB) */
#define PA_VOLUME_NORM ((pa_volume_t) 0x10000U)
-/** Muted volume (0%, -inf dB) */
+/** Muted (minimal valid) volume (0%, -inf dB) */
#define PA_VOLUME_MUTED ((pa_volume_t) 0U)
-/** Maximum volume we can store. \since 0.9.15 */
-#define PA_VOLUME_MAX ((pa_volume_t) UINT32_MAX)
+/** Maximum valid volume we can store. \since 0.9.15 */
+#define PA_VOLUME_MAX ((pa_volume_t) UINT32_MAX/2)
+
+/** Recommended maximum volume to show in user facing UIs.
+ * Note: UIs should deal gracefully with volumes greater than this value
+ * and not cause feedback loops etc. - i.e. if the volume is more than
+ * this, the UI should not limit it and push the limited value back to
+ * the server. \since 0.9.23 */
+#define PA_VOLUME_UI_MAX (pa_sw_volume_from_dB(+11.0))
+
+/** Special 'invalid' volume. \since 0.9.16 */
+#define PA_VOLUME_INVALID ((pa_volume_t) UINT32_MAX)
+
+/** Check if volume is valid. \since 1.0 */
+#define PA_VOLUME_IS_VALID(v) ((v) <= PA_VOLUME_MAX)
+
+/** Clamp volume to the permitted range. \since 1.0 */
+#define PA_CLAMP_VOLUME(v) (PA_CLAMP_UNLIKELY((v), PA_VOLUME_MUTED, PA_VOLUME_MAX))
/** A structure encapsulating a per-channel volume */
typedef struct pa_cvolume {
uint8_t channels; /**< Number of channels */
- pa_volume_t values[PA_CHANNELS_MAX]; /**< Per-channel volume */
+ pa_volume_t values[PA_CHANNELS_MAX]; /**< Per-channel volume */
} pa_cvolume;
/** Return non-zero when *a == *b */
* pa_cvolume_valid() will fail for it. \since 0.9.13 */
pa_cvolume* pa_cvolume_init(pa_cvolume *a);
-/** Set the volume of all channels to PA_VOLUME_NORM */
+/** Set the volume of the first n channels to PA_VOLUME_NORM */
#define pa_cvolume_reset(a, n) pa_cvolume_set((a), (n), PA_VOLUME_NORM)
-/** Set the volume of all channels to PA_VOLUME_MUTED */
+/** Set the volume of the first n channels to PA_VOLUME_MUTED */
#define pa_cvolume_mute(a, n) pa_cvolume_set((a), (n), PA_VOLUME_MUTED)
-/** Set the volume of all channels to the specified parameter */
+/** Set the volume of the specified number of channels to the volume v */
pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v);
/** Maximum length of the strings returned by
char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c);
/** Maximum length of the strings returned by
- * pa_cvolume_snprint_dB(). Please note that this value can change with
+ * pa_sw_cvolume_snprint_dB(). Please note that this value can change with
* any release without warning and without being considered API or ABI
* breakage. You should not use this definition anywhere where it
* might become part of an ABI. \since 0.9.13 */
/** Pretty print a volume structure but show dB values. \since 0.9.13 */
char *pa_sw_cvolume_snprint_dB(char *s, size_t l, const pa_cvolume *c);
+/** Maximum length of the strings returned by pa_cvolume_snprint_verbose().
+ * Please note that this value can change with any release without warning and
+ * without being considered API or ABI breakage. You should not use this
+ * definition anywhere where it might become part of an ABI. \since 5.0 */
+#define PA_CVOLUME_SNPRINT_VERBOSE_MAX 1984
+
+/** Pretty print a volume structure in a verbose way. The volume for each
+ * channel is printed in several formats: the raw pa_volume_t value,
+ * percentage, and if print_dB is non-zero, also the dB value. If map is not
+ * NULL, the channel names will be printed. \since 5.0 */
+char *pa_cvolume_snprint_verbose(char *s, size_t l, const pa_cvolume *c, const pa_channel_map *map, int print_dB);
+
/** Maximum length of the strings returned by
* pa_volume_snprint(). Please note that this value can change with
* any release without warning and without being considered API or ABI
char *pa_volume_snprint(char *s, size_t l, pa_volume_t v);
/** Maximum length of the strings returned by
- * pa_volume_snprint_dB(). Please note that this value can change with
+ * pa_sw_volume_snprint_dB(). Please note that this value can change with
* any release without warning and without being considered API or ABI
* breakage. You should not use this definition anywhere where it
* might become part of an ABI. \since 0.9.15 */
/** Pretty print a volume but show dB values. \since 0.9.15 */
char *pa_sw_volume_snprint_dB(char *s, size_t l, pa_volume_t v);
+/** Maximum length of the strings returned by pa_volume_snprint_verbose().
+ * Please note that this value can change with any release without warning and
+ * withou being considered API or ABI breakage. You should not use this
+ * definition anywhere where it might become part of an ABI. \since 5.0 */
+#define PA_VOLUME_SNPRINT_VERBOSE_MAX 35
+
+/** Pretty print a volume in a verbose way. The volume is printed in several
+ * formats: the raw pa_volume_t value, percentage, and if print_dB is non-zero,
+ * also the dB value. \since 5.0 */
+char *pa_volume_snprint_verbose(char *s, size_t l, pa_volume_t v, int print_dB);
+
/** Return the average volume of all channels */
pa_volume_t pa_cvolume_avg(const pa_cvolume *a) PA_GCC_PURE;
+/** Return the average volume of all channels that are included in the
+ * specified channel map with the specified channel position mask. If
+ * cm is NULL this call is identical to pa_cvolume_avg(). If no
+ * channel is selected the returned value will be
+ * PA_VOLUME_MUTED. \since 0.9.16 */
+pa_volume_t pa_cvolume_avg_mask(const pa_cvolume *a, const pa_channel_map *cm, pa_channel_position_mask_t mask) PA_GCC_PURE;
+
/** Return the maximum volume of all channels. \since 0.9.12 */
pa_volume_t pa_cvolume_max(const pa_cvolume *a) PA_GCC_PURE;
-/** Return TRUE when the passed cvolume structure is valid, FALSE otherwise */
+/** Return the maximum volume of all channels that are included in the
+ * specified channel map with the specified channel position mask. If
+ * cm is NULL this call is identical to pa_cvolume_max(). If no
+ * channel is selected the returned value will be PA_VOLUME_MUTED.
+ * \since 0.9.16 */
+pa_volume_t pa_cvolume_max_mask(const pa_cvolume *a, const pa_channel_map *cm, pa_channel_position_mask_t mask) PA_GCC_PURE;
+
+/** Return the minimum volume of all channels. \since 0.9.16 */
+pa_volume_t pa_cvolume_min(const pa_cvolume *a) PA_GCC_PURE;
+
+/** Return the minimum volume of all channels that are included in the
+ * specified channel map with the specified channel position mask. If
+ * cm is NULL this call is identical to pa_cvolume_min(). If no
+ * channel is selected the returned value will be PA_VOLUME_MUTED.
+ * \since 0.9.16 */
+pa_volume_t pa_cvolume_min_mask(const pa_cvolume *a, const pa_channel_map *cm, pa_channel_position_mask_t mask) PA_GCC_PURE;
+
+/** Return non-zero when the passed cvolume structure is valid */
int pa_cvolume_valid(const pa_cvolume *v) PA_GCC_PURE;
/** Return non-zero if the volume of all channels is equal to the specified value */
pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) PA_GCC_CONST;
/** Multiply two per-channel volumes and return the result in
- * *dest. This is only valid for software volumes! */
+ * *dest. This is only valid for software volumes! a, b and dest may
+ * point to the same structure. */
pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b);
+/** Multiply a per-channel volume with a scalar volume and return the
+ * result in *dest. This is only valid for software volumes! a
+ * and dest may point to the same structure. \since
+ * 0.9.16 */
+pa_cvolume *pa_sw_cvolume_multiply_scalar(pa_cvolume *dest, const pa_cvolume *a, pa_volume_t b);
+
/** Divide two volume specifications, return the result. This uses
* PA_VOLUME_NORM as neutral element of division. This is only valid
* for software volumes! If a division by zero is tried the result
* will be 0. \since 0.9.13 */
pa_volume_t pa_sw_volume_divide(pa_volume_t a, pa_volume_t b) PA_GCC_CONST;
-/** Multiply to per-channel volumes and return the result in
- * *dest. This is only valid for software volumes! \since 0.9.13 */
+/** Divide two per-channel volumes and return the result in
+ * *dest. This is only valid for software volumes! a, b
+ * and dest may point to the same structure. \since 0.9.13 */
pa_cvolume *pa_sw_cvolume_divide(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b);
-/** Convert a decibel value to a volume. This is only valid for software volumes! */
+/** Divide a per-channel volume by a scalar volume and return the
+ * result in *dest. This is only valid for software volumes! a
+ * and dest may point to the same structure. \since
+ * 0.9.16 */
+pa_cvolume *pa_sw_cvolume_divide_scalar(pa_cvolume *dest, const pa_cvolume *a, pa_volume_t b);
+
+/** Convert a decibel value to a volume (amplitude, not power). This is only valid for software volumes! */
pa_volume_t pa_sw_volume_from_dB(double f) PA_GCC_CONST;
-/** Convert a volume to a decibel value. This is only valid for software volumes! */
+/** Convert a volume to a decibel value (amplitude, not power). This is only valid for software volumes! */
double pa_sw_volume_to_dB(pa_volume_t v) PA_GCC_CONST;
-/** Convert a linear factor to a volume. This is only valid for software volumes! */
+/** Convert a linear factor to a volume. 0.0 and less is muted while
+ * 1.0 is PA_VOLUME_NORM. This is only valid for software volumes! */
pa_volume_t pa_sw_volume_from_linear(double v) PA_GCC_CONST;
/** Convert a volume to a linear factor. This is only valid for software volumes! */
#ifdef INFINITY
#define PA_DECIBEL_MININFTY ((double) -INFINITY)
#else
-/** This value is used as minus infinity when using pa_volume_{to,from}_dB(). */
+/** This floor value is used as minus infinity when using pa_sw_volume_to_dB() / pa_sw_volume_from_dB(). */
#define PA_DECIBEL_MININFTY ((double) -200.0)
#endif
* pa_channel_map_can_balance(). \since 0.9.15 */
pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, float new_balance);
-/** Calculate a 'fade' value (i.e. 'balance' between front and rear)
+/** Calculate a 'fade' value (i.e.\ 'balance' between front and rear)
* for the specified volume with the specified channel map. The return
* value will range from -1.0f (rear) to +1.0f (left). If no fade
* value is applicable to this channel map the return value will
* always be 0.0f. See pa_channel_map_can_fade(). \since 0.9.15 */
float pa_cvolume_get_fade(const pa_cvolume *v, const pa_channel_map *map) PA_GCC_PURE;
-/** Adjust the 'fade' value (i.e. 'balance' between front and rear)
+/** Adjust the 'fade' value (i.e.\ 'balance' between front and rear)
* for the specified volume with the specified channel map. v will be
* modified in place and returned. The balance is a value between
* -1.0f and +1.0f. This operation might not be reversible! Also,
* volumes are kept. \since 0.9.15 */
pa_cvolume* pa_cvolume_scale(pa_cvolume *v, pa_volume_t max);
+/** Scale the passed pa_cvolume structure so that the maximum volume
+ * of all channels selected via cm/mask equals max. This also modifies
+ * the volume of those channels that are unmasked. The proportions
+ * between the channel volumes are kept. \since 0.9.16 */
+pa_cvolume* pa_cvolume_scale_mask(pa_cvolume *v, pa_volume_t max, pa_channel_map *cm, pa_channel_position_mask_t mask);
+
/** Set the passed volume to all channels at the specified channel
* position. Will return the updated volume struct, or NULL if there
* is no channel at the position specified. You can check if a channel
* position. Will return 0 if there is no channel at the position
* specified. You can check if a channel map includes a specific
* position by calling pa_channel_map_has_position(). \since 0.9.16 */
-pa_volume_t pa_cvolume_get_position(pa_cvolume *cv, const pa_channel_map *map, pa_channel_position_t t);
+pa_volume_t pa_cvolume_get_position(pa_cvolume *cv, const pa_channel_map *map, pa_channel_position_t t) PA_GCC_PURE;
+
+/** This goes through all channels in a and b and sets the
+ * corresponding channel in dest to the greater volume of both. a, b
+ * and dest may point to the same structure. \since 0.9.16 */
+pa_cvolume* pa_cvolume_merge(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b);
+
+/** Increase the volume passed in by 'inc', but not exceeding 'limit'.
+ * The proportions between the channels are kept. \since 0.9.19 */
+pa_cvolume* pa_cvolume_inc_clamp(pa_cvolume *v, pa_volume_t inc, pa_volume_t limit);
+
+/** Increase the volume passed in by 'inc'. The proportions between
+ * the channels are kept. \since 0.9.16 */
+pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc);
+
+/** Decrease the volume passed in by 'dec'. The proportions between
+ * the channels are kept. \since 0.9.16 */
+pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec);
PA_C_DECL_END