libpulse_sys/
volume.rs

1// Copyright 2017 Lyndon Brown
2//
3// This file is part of the PulseAudio Rust language linking library.
4//
5// Licensed under the MIT license or the Apache license (version 2.0), at your option. You may not
6// copy, modify, or distribute this file except in compliance with said license. You can find copies
7// of these licenses either in the LICENSE-MIT and LICENSE-APACHE files, or alternatively at
8// <http://opensource.org/licenses/MIT> and <http://www.apache.org/licenses/LICENSE-2.0>
9// respectively.
10//
11// Portions of documentation are copied from the LGPL 2.1+ licensed PulseAudio C headers on a
12// fair-use basis, as discussed in the overall project readme (available in the git repository).
13
14//! Constants and routines for volume handling.
15
16use std::os::raw::c_char;
17use crate::channelmap::{pa_channel_map, pa_channel_position_mask_t, pa_channel_position_t};
18use crate::sample::pa_sample_spec;
19
20/// The basic volume type.
21pub type pa_volume_t = u32;
22
23/// Normal volume (100%, 0 dB).
24pub const PA_VOLUME_NORM: pa_volume_t = 0x10000;
25
26/// Muted (minimal valid) volume (0%, -inf dB).
27pub const PA_VOLUME_MUTED: pa_volume_t = 0;
28
29/// Maximum valid volume we can store.
30pub const PA_VOLUME_MAX: pa_volume_t = std::u32::MAX / 2;
31
32#[inline(always)]
33pub fn pa_volume_ui_max() -> pa_volume_t {
34    unsafe { pa_sw_volume_from_dB(11.0) }
35}
36
37/// Special ‘invalid’ volume.
38pub const PA_VOLUME_INVALID: pa_volume_t = std::u32::MAX;
39
40/// This floor value is used as minus infinity when using [`pa_sw_volume_to_dB()`] or
41/// [`pa_sw_volume_from_dB()`].
42pub const PA_DECIBEL_MININFTY: f64 = -std::f64::INFINITY;
43
44#[repr(C)]
45#[derive(Copy, Clone, Default)]
46pub struct pa_cvolume {
47    pub channels: u8,
48    pub values: [pa_volume_t; crate::sample::PA_CHANNELS_MAX as usize],
49}
50
51/// The maximum length of strings returned by [`pa_cvolume_snprint()`].
52///
53/// Please note that this value can change with any release without warning and without being
54/// considered API or ABI breakage. You should not use this definition anywhere where it might
55/// become part of an ABI.
56pub const PA_CVOLUME_SNPRINT_MAX: usize = 320;
57
58/// The maximum length of strings returned by [`pa_sw_cvolume_snprint_dB()`].
59///
60/// Please note that this value can change with any release without warning and without being
61/// considered API or ABI breakage. You should not use this definition anywhere where it might
62/// become part of an ABI.
63pub const PA_SW_CVOLUME_SNPRINT_DB_MAX: usize = 448;
64
65/// The maximum length of strings returned by [`pa_cvolume_snprint_verbose()`].
66///
67/// Please note that this value can change with any release without warning and without being
68/// considered API or ABI breakage. You should not use this definition anywhere where it might
69/// become part of an ABI.
70pub const PA_CVOLUME_SNPRINT_VERBOSE_MAX: usize = 1984;
71
72/// The maximum length of strings returned by [`pa_volume_snprint()`].
73///
74/// Please note that this value can change with any release without warning and without being
75/// considered API or ABI breakage. You should not use this definition anywhere where it might
76/// become part of an ABI.
77pub const PA_VOLUME_SNPRINT_MAX: usize = 10;
78
79/// The maximum length of strings returned by [`pa_sw_volume_snprint_dB()`].
80///
81/// Please note that this value can change with any release without warning and without being
82/// considered API or ABI breakage. You should not use this definition anywhere where it might
83/// become part of an ABI.
84pub const PA_SW_VOLUME_SNPRINT_DB_MAX: usize = 11;
85
86/// The maximum length of strings returned by [`pa_volume_snprint_verbose()`].
87///
88/// Please note that this value can change with any release without warning and without being
89/// considered API or ABI breakage. You should not use this definition anywhere where it might
90/// become part of an ABI.
91pub const PA_VOLUME_SNPRINT_VERBOSE_MAX: usize = 35;
92
93#[inline(always)]
94pub const fn pa_volume_is_valid(v: pa_volume_t) -> bool {
95    v <= PA_VOLUME_MAX
96}
97
98pub const fn pa_clamp_volume(v: pa_volume_t) -> pa_volume_t {
99    if v < PA_VOLUME_MUTED {
100        return PA_VOLUME_MUTED;
101    }
102    if v > PA_VOLUME_MAX {
103        return PA_VOLUME_MAX;
104    }
105    v
106}
107
108/// Sets the volume of the first n channels to [`PA_VOLUME_NORM`].
109#[inline(always)]
110pub unsafe fn pa_cvolume_reset(a: *mut pa_cvolume, n: u32) -> *mut pa_cvolume {
111    pa_cvolume_set(a, n, PA_VOLUME_NORM)
112}
113
114/// Sets the volume of the first n channels to [`PA_VOLUME_MUTED`].
115#[inline(always)]
116pub unsafe fn pa_cvolume_mute(a: *mut pa_cvolume, n: u32) -> *mut pa_cvolume {
117    pa_cvolume_set(a, n, PA_VOLUME_MUTED)
118}
119
120#[rustfmt::skip]
121#[link(name = "pulse")]
122extern "C" {
123    pub fn pa_cvolume_equal(a: *const pa_cvolume, b: *const pa_cvolume) -> i32;
124    pub fn pa_cvolume_init(a: *mut pa_cvolume) -> *mut pa_cvolume;
125    pub fn pa_cvolume_set(a: *mut pa_cvolume, channels: u32, v: pa_volume_t) -> *mut pa_cvolume;
126    pub fn pa_cvolume_snprint(s: *mut c_char, l: usize, c: *const pa_cvolume) -> *mut c_char;
127    pub fn pa_sw_cvolume_snprint_dB(s: *mut c_char, l: usize, c: *const pa_cvolume) -> *mut c_char;
128    pub fn pa_cvolume_snprint_verbose(s: *mut c_char, l: usize, c: *const pa_cvolume, map: *const pa_channel_map, print_dB: i32) -> *mut c_char;
129
130    pub fn pa_volume_snprint(s: *mut c_char, l: usize, v: pa_volume_t) -> *mut c_char;
131    pub fn pa_sw_volume_snprint_dB(s: *mut c_char, l: usize, v: pa_volume_t) -> *mut c_char;
132    pub fn pa_volume_snprint_verbose(s: *mut c_char, l: usize, v: pa_volume_t, print_dB: i32) -> *mut c_char;
133
134    pub fn pa_cvolume_avg(a: *const pa_cvolume) -> pa_volume_t;
135    pub fn pa_cvolume_avg_mask(a: *const pa_cvolume, cm: *const pa_channel_map, mask: pa_channel_position_mask_t) -> pa_volume_t;
136    pub fn pa_cvolume_max(a: *const pa_cvolume) -> pa_volume_t;
137    pub fn pa_cvolume_max_mask(a: *const pa_cvolume, cm: *const pa_channel_map, mask: pa_channel_position_mask_t) -> pa_volume_t;
138    pub fn pa_cvolume_min(a: *const pa_cvolume) -> pa_volume_t;
139    pub fn pa_cvolume_min_mask(a: *const pa_cvolume, cm: *const pa_channel_map, mask: pa_channel_position_mask_t) -> pa_volume_t;
140    pub fn pa_cvolume_valid(v: *const pa_cvolume) -> i32;
141    pub fn pa_cvolume_channels_equal_to(a: *const pa_cvolume, v: pa_volume_t) -> i32;
142
143    pub fn pa_sw_volume_multiply(a: pa_volume_t, b: pa_volume_t) -> pa_volume_t;
144    pub fn pa_sw_cvolume_multiply(dest: *mut pa_cvolume, a: *const pa_cvolume, b: *const pa_cvolume) -> *mut pa_cvolume;
145    pub fn pa_sw_cvolume_multiply_scalar(dest: *mut pa_cvolume, a: *const pa_cvolume, b: pa_volume_t) -> *mut pa_cvolume;
146    pub fn pa_sw_volume_divide(a: pa_volume_t, b: pa_volume_t) -> pa_volume_t;
147    pub fn pa_sw_cvolume_divide(dest: *mut pa_cvolume, a: *const pa_cvolume, b: *const pa_cvolume) -> *mut pa_cvolume;
148    pub fn pa_sw_cvolume_divide_scalar(dest: *mut pa_cvolume, a: *const pa_cvolume, b: pa_volume_t) -> *mut pa_cvolume;
149    pub fn pa_sw_volume_from_dB(f: f64) -> pa_volume_t;
150    pub fn pa_sw_volume_to_dB(v: pa_volume_t) -> f64;
151    pub fn pa_sw_volume_from_linear(v: f64) -> pa_volume_t;
152    pub fn pa_sw_volume_to_linear(v: pa_volume_t) -> f64;
153
154    pub fn pa_cvolume_remap(v: *mut pa_cvolume, from: *const pa_channel_map, to: *const pa_channel_map) -> *mut pa_cvolume;
155    pub fn pa_cvolume_compatible(v: *const pa_cvolume, ss: *const pa_sample_spec) -> i32;
156    pub fn pa_cvolume_compatible_with_channel_map(v: *const pa_cvolume, cm: *const pa_channel_map) -> i32;
157    pub fn pa_cvolume_get_balance(v: *const pa_cvolume, map: *const pa_channel_map) -> f32;
158    pub fn pa_cvolume_set_balance(v: *mut pa_cvolume, map: *const pa_channel_map, new_balance: f32) -> *mut pa_cvolume;
159    pub fn pa_cvolume_get_fade(v: *const pa_cvolume, map: *const pa_channel_map) -> f32;
160    pub fn pa_cvolume_set_fade(v: *mut pa_cvolume, map: *const pa_channel_map, new_fade: f32) -> *mut pa_cvolume;
161    #[cfg(any(doc, feature = "pa_v8"))]
162    #[cfg_attr(docsrs, doc(cfg(feature = "pa_v8")))]
163    pub fn pa_cvolume_get_lfe_balance(v: *const pa_cvolume, map: *const pa_channel_map) -> f32;
164    #[cfg(any(doc, feature = "pa_v8"))]
165    #[cfg_attr(docsrs, doc(cfg(feature = "pa_v8")))]
166    pub fn pa_cvolume_set_lfe_balance(v: *mut pa_cvolume, map: *const pa_channel_map, new_balance: f32) -> *mut pa_cvolume;
167    pub fn pa_cvolume_scale(v: *mut pa_cvolume, max: pa_volume_t) -> *mut pa_cvolume;
168    pub fn pa_cvolume_scale_mask(v: *mut pa_cvolume, max: pa_volume_t, cm: *const pa_channel_map, mask: pa_channel_position_mask_t) -> *mut pa_cvolume;
169    pub fn pa_cvolume_set_position(cv: *mut pa_cvolume, map: *const pa_channel_map, t: pa_channel_position_t, v: pa_volume_t) -> *mut pa_cvolume;
170    pub fn pa_cvolume_get_position(cv: *const pa_cvolume, map: *const pa_channel_map, t: pa_channel_position_t) -> pa_volume_t;
171    pub fn pa_cvolume_merge(dest: *mut pa_cvolume, a: *const pa_cvolume, b: *const pa_cvolume) -> *mut pa_cvolume;
172    pub fn pa_cvolume_inc_clamp(v: *mut pa_cvolume, inc: pa_volume_t, limit: pa_volume_t) -> *mut pa_cvolume;
173    pub fn pa_cvolume_inc(v: *mut pa_cvolume, inc: pa_volume_t) -> *mut pa_cvolume;
174    pub fn pa_cvolume_dec(v: *mut pa_cvolume, dec: pa_volume_t) -> *mut pa_cvolume;
175}