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 handing channel mapping.
15 
16 use std::os::raw::c_char;
17 use num_derive::{FromPrimitive, ToPrimitive};
18 use crate::sample::pa_sample_spec;
19 
20 pub type pa_channel_position_mask_t = u64;
21 
22 #[inline(always)]
pa_channel_position_mask(pos: pa_channel_position_t) -> pa_channel_position_mask_t23 pub const fn pa_channel_position_mask(pos: pa_channel_position_t) -> pa_channel_position_mask_t {
24     1u64 << (pos as pa_channel_position_mask_t)
25 }
26 
27 #[repr(C)]
28 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
29 #[derive(FromPrimitive, ToPrimitive)]
30 pub enum pa_channel_position_t {
31     Invalid = -1,
32     Mono = 0,
33 
34     FrontLeft,
35     FrontRight,
36     FrontCenter,
37 
38     RearCenter,
39     RearLeft,
40     RearRight,
41 
42     Lfe,
43 
44     FrontLeftOfCenter,
45     FrontRightOfCenter,
46 
47     SideLeft,
48     SideRight,
49 
50     Aux0,
51     Aux1,
52     Aux2,
53     Aux3,
54     Aux4,
55     Aux5,
56     Aux6,
57     Aux7,
58     Aux8,
59     Aux9,
60     Aux10,
61     Aux11,
62     Aux12,
63     Aux13,
64     Aux14,
65     Aux15,
66     Aux16,
67     Aux17,
68     Aux18,
69     Aux19,
70     Aux20,
71     Aux21,
72     Aux22,
73     Aux23,
74     Aux24,
75     Aux25,
76     Aux26,
77     Aux27,
78     Aux28,
79     Aux29,
80     Aux30,
81     Aux31,
82 
83     TopCenter,
84 
85     TopFrontLeft,
86     TopFrontRight,
87     TopFrontCenter,
88 
89     TopRearLeft,
90     TopRearRight,
91     TopRearCenter,
92 }
93 
94 pub const PA_CHANNEL_POSITION_MAX: usize = 51;
95 
96 pub const PA_CHANNEL_POSITION_INVALID:               pa_channel_position_t = pa_channel_position_t::Invalid;
97 pub const PA_CHANNEL_POSITION_MONO:                  pa_channel_position_t = pa_channel_position_t::Mono;
98 pub const PA_CHANNEL_POSITION_LEFT:                  pa_channel_position_t = pa_channel_position_t::FrontLeft;
99 pub const PA_CHANNEL_POSITION_RIGHT:                 pa_channel_position_t = pa_channel_position_t::FrontRight;
100 pub const PA_CHANNEL_POSITION_CENTER:                pa_channel_position_t = pa_channel_position_t::FrontCenter;
101 pub const PA_CHANNEL_POSITION_FRONT_LEFT:            pa_channel_position_t = pa_channel_position_t::FrontLeft;
102 pub const PA_CHANNEL_POSITION_FRONT_RIGHT:           pa_channel_position_t = pa_channel_position_t::FrontRight;
103 pub const PA_CHANNEL_POSITION_FRONT_CENTER:          pa_channel_position_t = pa_channel_position_t::FrontCenter;
104 pub const PA_CHANNEL_POSITION_REAR_CENTER:           pa_channel_position_t = pa_channel_position_t::RearCenter;
105 pub const PA_CHANNEL_POSITION_REAR_LEFT:             pa_channel_position_t = pa_channel_position_t::RearLeft;
106 pub const PA_CHANNEL_POSITION_REAR_RIGHT:            pa_channel_position_t = pa_channel_position_t::RearRight;
107 pub const PA_CHANNEL_POSITION_LFE:                   pa_channel_position_t = pa_channel_position_t::Lfe;
108 pub const PA_CHANNEL_POSITION_SUBWOOFER:             pa_channel_position_t = pa_channel_position_t::Lfe;
109 pub const PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER:  pa_channel_position_t = pa_channel_position_t::FrontLeftOfCenter;
110 pub const PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER: pa_channel_position_t = pa_channel_position_t::FrontRightOfCenter;
111 pub const PA_CHANNEL_POSITION_SIDE_LEFT:             pa_channel_position_t = pa_channel_position_t::SideLeft;
112 pub const PA_CHANNEL_POSITION_SIDE_RIGHT:            pa_channel_position_t = pa_channel_position_t::SideRight;
113 pub const PA_CHANNEL_POSITION_AUX0:                  pa_channel_position_t = pa_channel_position_t::Aux0;
114 pub const PA_CHANNEL_POSITION_AUX1:                  pa_channel_position_t = pa_channel_position_t::Aux1;
115 pub const PA_CHANNEL_POSITION_AUX2:                  pa_channel_position_t = pa_channel_position_t::Aux2;
116 pub const PA_CHANNEL_POSITION_AUX3:                  pa_channel_position_t = pa_channel_position_t::Aux3;
117 pub const PA_CHANNEL_POSITION_AUX4:                  pa_channel_position_t = pa_channel_position_t::Aux4;
118 pub const PA_CHANNEL_POSITION_AUX5:                  pa_channel_position_t = pa_channel_position_t::Aux5;
119 pub const PA_CHANNEL_POSITION_AUX6:                  pa_channel_position_t = pa_channel_position_t::Aux6;
120 pub const PA_CHANNEL_POSITION_AUX7:                  pa_channel_position_t = pa_channel_position_t::Aux7;
121 pub const PA_CHANNEL_POSITION_AUX8:                  pa_channel_position_t = pa_channel_position_t::Aux8;
122 pub const PA_CHANNEL_POSITION_AUX9:                  pa_channel_position_t = pa_channel_position_t::Aux9;
123 pub const PA_CHANNEL_POSITION_AUX10:                 pa_channel_position_t = pa_channel_position_t::Aux10;
124 pub const PA_CHANNEL_POSITION_AUX11:                 pa_channel_position_t = pa_channel_position_t::Aux11;
125 pub const PA_CHANNEL_POSITION_AUX12:                 pa_channel_position_t = pa_channel_position_t::Aux12;
126 pub const PA_CHANNEL_POSITION_AUX13:                 pa_channel_position_t = pa_channel_position_t::Aux13;
127 pub const PA_CHANNEL_POSITION_AUX14:                 pa_channel_position_t = pa_channel_position_t::Aux14;
128 pub const PA_CHANNEL_POSITION_AUX15:                 pa_channel_position_t = pa_channel_position_t::Aux15;
129 pub const PA_CHANNEL_POSITION_AUX16:                 pa_channel_position_t = pa_channel_position_t::Aux16;
130 pub const PA_CHANNEL_POSITION_AUX17:                 pa_channel_position_t = pa_channel_position_t::Aux17;
131 pub const PA_CHANNEL_POSITION_AUX18:                 pa_channel_position_t = pa_channel_position_t::Aux18;
132 pub const PA_CHANNEL_POSITION_AUX19:                 pa_channel_position_t = pa_channel_position_t::Aux19;
133 pub const PA_CHANNEL_POSITION_AUX20:                 pa_channel_position_t = pa_channel_position_t::Aux20;
134 pub const PA_CHANNEL_POSITION_AUX21:                 pa_channel_position_t = pa_channel_position_t::Aux21;
135 pub const PA_CHANNEL_POSITION_AUX22:                 pa_channel_position_t = pa_channel_position_t::Aux22;
136 pub const PA_CHANNEL_POSITION_AUX23:                 pa_channel_position_t = pa_channel_position_t::Aux23;
137 pub const PA_CHANNEL_POSITION_AUX24:                 pa_channel_position_t = pa_channel_position_t::Aux24;
138 pub const PA_CHANNEL_POSITION_AUX25:                 pa_channel_position_t = pa_channel_position_t::Aux25;
139 pub const PA_CHANNEL_POSITION_AUX26:                 pa_channel_position_t = pa_channel_position_t::Aux26;
140 pub const PA_CHANNEL_POSITION_AUX27:                 pa_channel_position_t = pa_channel_position_t::Aux27;
141 pub const PA_CHANNEL_POSITION_AUX28:                 pa_channel_position_t = pa_channel_position_t::Aux28;
142 pub const PA_CHANNEL_POSITION_AUX29:                 pa_channel_position_t = pa_channel_position_t::Aux29;
143 pub const PA_CHANNEL_POSITION_AUX30:                 pa_channel_position_t = pa_channel_position_t::Aux30;
144 pub const PA_CHANNEL_POSITION_AUX31:                 pa_channel_position_t = pa_channel_position_t::Aux31;
145 pub const PA_CHANNEL_POSITION_TOP_CENTER:            pa_channel_position_t = pa_channel_position_t::TopCenter;
146 pub const PA_CHANNEL_POSITION_TOP_FRONT_LEFT:        pa_channel_position_t = pa_channel_position_t::TopFrontLeft;
147 pub const PA_CHANNEL_POSITION_TOP_FRONT_RIGHT:       pa_channel_position_t = pa_channel_position_t::TopFrontRight;
148 pub const PA_CHANNEL_POSITION_TOP_FRONT_CENTER:      pa_channel_position_t = pa_channel_position_t::TopFrontCenter;
149 pub const PA_CHANNEL_POSITION_TOP_REAR_LEFT:         pa_channel_position_t = pa_channel_position_t::TopRearLeft;
150 pub const PA_CHANNEL_POSITION_TOP_REAR_RIGHT:        pa_channel_position_t = pa_channel_position_t::TopRearRight;
151 pub const PA_CHANNEL_POSITION_TOP_REAR_CENTER:       pa_channel_position_t = pa_channel_position_t::TopRearCenter;
152 
153 impl Default for pa_channel_position_t {
default() -> Self154     fn default() -> Self {
155         pa_channel_position_t::Invalid
156     }
157 }
158 
159 /// Channel map definition standards.
160 ///
161 /// Used in having a channel map automatically setup per number of channels and a specific standard.
162 #[repr(C)]
163 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
164 #[derive(FromPrimitive, ToPrimitive)]
165 pub enum pa_channel_map_def_t {
166     /// The mapping from RFC3551, which is based on AIFF-C.
167     AIFF,
168     /// The default mapping used by ALSA. This mapping is probably not too useful since ALSA’s
169     /// default channel mapping depends on the device string used.
170     ALSA,
171     /// Only aux channels.
172     Aux,
173     /// Microsoft’s WAVEFORMATEXTENSIBLE mapping. This mapping works as if all LSBs of dwChannelMask
174     /// are set.
175     WAVEEx,
176     /// The default channel mapping used by OSS as defined in the OSS 4.0 API specs. This mapping is
177     /// probably not too useful since the OSS API has changed in this respect and no longer knows a
178     /// default channel mapping based on the number of channels.
179     OSS,
180 }
181 
182 pub const PA_CHANNEL_MAP_DEF_MAX: usize = 5;
183 
184 pub const PA_CHANNEL_MAP_AIFF:    pa_channel_map_def_t = pa_channel_map_def_t::AIFF;
185 pub const PA_CHANNEL_MAP_ALSA:    pa_channel_map_def_t = pa_channel_map_def_t::ALSA;
186 pub const PA_CHANNEL_MAP_AUX:     pa_channel_map_def_t = pa_channel_map_def_t::Aux;
187 pub const PA_CHANNEL_MAP_WAVEEX:  pa_channel_map_def_t = pa_channel_map_def_t::WAVEEx;
188 pub const PA_CHANNEL_MAP_OSS:     pa_channel_map_def_t = pa_channel_map_def_t::OSS;
189 pub const PA_CHANNEL_MAP_DEFAULT: pa_channel_map_def_t = pa_channel_map_def_t::AIFF;
190 
191 impl Default for pa_channel_map_def_t {
default() -> Self192     fn default() -> Self {
193         PA_CHANNEL_MAP_DEFAULT
194     }
195 }
196 
197 #[repr(C)]
198 #[derive(Default, Debug, Copy, Clone)]
199 pub struct pa_channel_map {
200     pub channels: u8,
201     pub map: [pa_channel_position_t; crate::sample::PA_CHANNELS_MAX as usize],
202 }
203 
204 pub const PA_CHANNEL_MAP_SNPRINT_MAX: usize = 336;
205 
206 #[rustfmt::skip]
207 #[link(name = "pulse")]
208 extern "C" {
pa_channel_map_init(m: *mut pa_channel_map) -> *mut pa_channel_map209     pub fn pa_channel_map_init(m: *mut pa_channel_map) -> *mut pa_channel_map;
pa_channel_map_init_mono(m: *mut pa_channel_map) -> *mut pa_channel_map210     pub fn pa_channel_map_init_mono(m: *mut pa_channel_map) -> *mut pa_channel_map;
pa_channel_map_init_stereo(m: *mut pa_channel_map) -> *mut pa_channel_map211     pub fn pa_channel_map_init_stereo(m: *mut pa_channel_map) -> *mut pa_channel_map;
pa_channel_map_init_auto(m: *mut pa_channel_map, channels: u32, def: pa_channel_map_def_t) -> *mut pa_channel_map212     pub fn pa_channel_map_init_auto(m: *mut pa_channel_map, channels: u32, def: pa_channel_map_def_t) -> *mut pa_channel_map;
pa_channel_map_init_extend(m: *mut pa_channel_map, channels: u32, def: pa_channel_map_def_t) -> *mut pa_channel_map213     pub fn pa_channel_map_init_extend(m: *mut pa_channel_map, channels: u32, def: pa_channel_map_def_t) -> *mut pa_channel_map;
pa_channel_position_to_string(pos: pa_channel_position_t) -> *const c_char214     pub fn pa_channel_position_to_string(pos: pa_channel_position_t) -> *const c_char;
pa_channel_position_from_string(s: *const c_char) -> pa_channel_position_t215     pub fn pa_channel_position_from_string(s: *const c_char) -> pa_channel_position_t;
pa_channel_position_to_pretty_string(pos: pa_channel_position_t) -> *const c_char216     pub fn pa_channel_position_to_pretty_string(pos: pa_channel_position_t) -> *const c_char;
pa_channel_map_snprint(s: *mut c_char, l: usize, map: *const pa_channel_map) -> *mut c_char217     pub fn pa_channel_map_snprint(s: *mut c_char, l: usize, map: *const pa_channel_map) -> *mut c_char;
pa_channel_map_parse(map: *mut pa_channel_map, s: *const c_char) -> *mut pa_channel_map218     pub fn pa_channel_map_parse(map: *mut pa_channel_map, s: *const c_char) -> *mut pa_channel_map;
pa_channel_map_equal(a: *const pa_channel_map, b: *const pa_channel_map) -> i32219     pub fn pa_channel_map_equal(a: *const pa_channel_map, b: *const pa_channel_map) -> i32;
pa_channel_map_valid(map: *const pa_channel_map) -> i32220     pub fn pa_channel_map_valid(map: *const pa_channel_map) -> i32;
pa_channel_map_compatible(map: *const pa_channel_map, ss: *const pa_sample_spec) -> i32221     pub fn pa_channel_map_compatible(map: *const pa_channel_map, ss: *const pa_sample_spec) -> i32;
pa_channel_map_superset(a: *const pa_channel_map, b: *const pa_channel_map) -> i32222     pub fn pa_channel_map_superset(a: *const pa_channel_map, b: *const pa_channel_map) -> i32;
pa_channel_map_can_balance(map: *const pa_channel_map) -> i32223     pub fn pa_channel_map_can_balance(map: *const pa_channel_map) -> i32;
pa_channel_map_can_fade(map: *const pa_channel_map) -> i32224     pub fn pa_channel_map_can_fade(map: *const pa_channel_map) -> i32;
225     #[cfg(any(doc, feature = "pa_v8"))]
226     #[cfg_attr(docsrs, doc(cfg(feature = "pa_v8")))]
pa_channel_map_can_lfe_balance(map: *const pa_channel_map) -> i32227     pub fn pa_channel_map_can_lfe_balance(map: *const pa_channel_map) -> i32;
pa_channel_map_to_name(map: *const pa_channel_map) -> *const c_char228     pub fn pa_channel_map_to_name(map: *const pa_channel_map) -> *const c_char;
pa_channel_map_to_pretty_name(map: *const pa_channel_map) -> *const c_char229     pub fn pa_channel_map_to_pretty_name(map: *const pa_channel_map) -> *const c_char;
pa_channel_map_has_position(map: *const pa_channel_map, p: pa_channel_position_t) -> i32230     pub fn pa_channel_map_has_position(map: *const pa_channel_map, p: pa_channel_position_t) -> i32;
pa_channel_map_mask(map: *const pa_channel_map) -> pa_channel_position_mask_t231     pub fn pa_channel_map_mask(map: *const pa_channel_map) -> pa_channel_position_mask_t;
232 }
233