1use std::{
2 iter,
3 num::{NonZeroU32, NonZeroU8},
4 sync::LazyLock,
5};
6
7use bitflags::bitflags;
8use smallvec::SmallVec;
9
10use crate::{
11 error::Error,
12 frame::{PlaneInformation, PlaneInformationVec},
13 invalid_param_error,
14 media::FrameDescriptor,
15 time, Result,
16};
17
18pub const SAMPLE_RATE_TELEPHONE: u32 = 8000;
19pub const SAMPLE_RATE_VOIP: u32 = 16000;
20pub const SAMPLE_RATE_CD: u32 = 44100;
21pub const SAMPLE_RATE_DVD: u32 = 48000;
22pub const SAMPLE_RATE_HIGH: u32 = 96000;
23pub const SAMPLE_RATE_ULTRA_HIGH: u32 = 192000;
24
25#[derive(Clone, Copy, Debug, Eq, PartialEq)]
26pub enum SampleFormat {
27 U8 = 0, S16, S32, F32, F64, U8P, S16P, S32P, F32P, F64P, MAX,
38}
39
40#[derive(Clone, Copy, Debug, Eq, PartialEq)]
41pub enum ChannelFormat {
42 FrontLeft,
43 FrontRight,
44 FrontCenter,
45 LowFrequency,
46 BackLeft,
47 BackRight,
48 FrontLeftOfCenter,
49 FrontRightOfCenter,
50 BackCenter,
51 SideLeft,
52 SideRight,
53 TopCenter,
54 TopFrontLeft,
55 TopFrontCenter,
56 TopFrontRight,
57 TopBackLeft,
58 TopBackCenter,
59 TopBackRight,
60}
61
62macro_rules! chn_fmt_masks {
63 ($($mask:ident)|+) => {
64 0 $(| ChannelFormatMasks::$mask.bits())+
65 };
66 ($mask:ident) => {
67 ChannelFormatMasks::$mask.bits()
68 };
69}
70
71bitflags! {
72 #[repr(transparent)]
73 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
74 pub struct ChannelFormatMasks: u32 {
75 const FrontLeft = 1u32 << ChannelFormat::FrontLeft as u32;
76 const FrontRight = 1u32 << ChannelFormat::FrontRight as u32;
77 const FrontCenter = 1u32 << ChannelFormat::FrontCenter as u32;
78 const LowFrequency = 1u32 << ChannelFormat::LowFrequency as u32;
79 const BackLeft = 1u32 << ChannelFormat::BackLeft as u32;
80 const BackRight = 1u32 << ChannelFormat::BackRight as u32;
81 const FrontLeftOfCenter = 1u32 << ChannelFormat::FrontLeftOfCenter as u32;
82 const FrontRightOfCenter = 1u32 << ChannelFormat::FrontRightOfCenter as u32;
83 const BackCenter = 1u32 << ChannelFormat::BackCenter as u32;
84 const SideLeft = 1u32 << ChannelFormat::SideLeft as u32;
85 const SideRight = 1u32 << ChannelFormat::SideRight as u32;
86 const TopCenter = 1u32 << ChannelFormat::TopCenter as u32;
87 const TopFrontLeft = 1u32 << ChannelFormat::TopFrontLeft as u32;
88 const TopFrontCenter = 1u32 << ChannelFormat::TopFrontCenter as u32;
89 const TopFrontRight = 1u32 << ChannelFormat::TopFrontRight as u32;
90 const TopBackLeft = 1u32 << ChannelFormat::TopBackLeft as u32;
91 const TopBackCenter = 1u32 << ChannelFormat::TopBackCenter as u32;
92 const TopBackRight = 1u32 << ChannelFormat::TopBackRight as u32;
93
94 const Mono = chn_fmt_masks!(FrontCenter);
95 const Stereo = chn_fmt_masks!(FrontLeft | FrontRight);
96 const Surround_2_1 = chn_fmt_masks!(Stereo | LowFrequency);
97 const Surround = chn_fmt_masks!(Stereo | FrontCenter);
98 const Surround_3_0 = chn_fmt_masks!(Surround);
99 const Surround_3_0_FRONT = chn_fmt_masks!(Surround);
100 const Surround_3_0_BACK = chn_fmt_masks!(Stereo | BackCenter);
101 const Surround_3_1 = chn_fmt_masks!(Surround_3_0 | LowFrequency);
102 const Surround_3_1_2 = chn_fmt_masks!(Surround_3_1 | TopFrontLeft | TopFrontRight);
103 const Surround_4_0 = chn_fmt_masks!(Surround_3_0 | BackCenter);
104 const Surround_4_1 = chn_fmt_masks!(Surround_4_0 | LowFrequency);
105 const Surround_2_2 = chn_fmt_masks!(Stereo | SideLeft | SideRight);
106 const Quad = chn_fmt_masks!(Stereo | BackLeft | BackRight);
107 const Surround_5_0 = chn_fmt_masks!(Surround_3_0 | SideLeft | SideRight);
108 const Surround_5_1 = chn_fmt_masks!(Surround_5_0 | LowFrequency);
109 const Surround_5_0_BACK = chn_fmt_masks!(Surround_3_0 | BackLeft | BackRight);
110 const Surround_5_1_BACK = chn_fmt_masks!(Surround_5_0_BACK | LowFrequency);
111 const Surround_6_0 = chn_fmt_masks!(Surround_5_0 | BackCenter);
112 const Hexagonal = chn_fmt_masks!(Surround_5_0_BACK | BackCenter);
113 const Surround_6_1 = chn_fmt_masks!(Surround_6_0 | LowFrequency);
114 const Surround_6_0_FRONT = chn_fmt_masks!(Surround_2_2 | FrontLeftOfCenter | FrontRightOfCenter);
115 const Surround_6_1_FRONT = chn_fmt_masks!(Surround_6_0_FRONT | LowFrequency);
116 const Surround_6_1_BACK = chn_fmt_masks!(Surround_5_1_BACK | BackCenter);
117 const Surround_7_0 = chn_fmt_masks!(Surround_5_0 | BackLeft | BackRight);
118 const Surround_7_1 = chn_fmt_masks!(Surround_7_0 | LowFrequency);
119 const Surround_7_0_FRONT = chn_fmt_masks!(Surround_5_0 | FrontLeftOfCenter | FrontRightOfCenter);
120 const Surround_7_1_WIDE = chn_fmt_masks!(Surround_5_1 | FrontLeftOfCenter | FrontRightOfCenter);
121 const Surround_7_1_WIDE_BACK = chn_fmt_masks!(Surround_5_1_BACK | FrontLeftOfCenter | FrontRightOfCenter);
122 const Surround_5_1_2 = chn_fmt_masks!(Surround_5_1 | TopFrontLeft | TopFrontRight);
123 const Surround_5_1_2_BACK = chn_fmt_masks!(Surround_5_1_BACK | TopFrontLeft | TopFrontRight);
124 const Octagonal = chn_fmt_masks!(Surround_5_0 | BackLeft | BackCenter | BackRight);
125 const Cube = chn_fmt_masks!(Quad | TopFrontLeft | TopFrontRight | TopBackLeft | TopBackRight);
126 const Surround_5_1_4_BACK = chn_fmt_masks!(Surround_5_1_2 | TopBackLeft | TopBackRight);
127 const Surround_7_1_2 = chn_fmt_masks!(Surround_7_1 | TopFrontLeft | TopFrontRight);
128 const Surround_7_1_4_BACK = chn_fmt_masks!(Surround_7_1_2 | TopBackLeft | TopBackRight);
129 const Surround_9_1_4_BACK = chn_fmt_masks!(Surround_7_1_4_BACK | FrontLeftOfCenter | FrontRightOfCenter);
130 }
131}
132
133#[derive(Clone, Copy, Debug, Eq, PartialEq)]
134pub enum ChannelOrder {
135 Unspecified,
136 Native,
137 Custom,
138 MAX,
139}
140
141const DEFAULT_MAX_CHANNELS: usize = 16;
142
143#[derive(Clone, Debug, Eq, PartialEq)]
144pub enum ChannelLayoutSpec {
145 Mask(ChannelFormatMasks),
146 Map(Option<SmallVec<[ChannelFormat; DEFAULT_MAX_CHANNELS]>>),
147}
148
149#[derive(Clone, Debug, Eq, PartialEq)]
150pub struct ChannelLayout {
151 pub order: ChannelOrder,
152 pub channels: NonZeroU8,
153 pub spec: ChannelLayoutSpec,
154}
155
156#[derive(Clone, Debug, Eq, PartialEq)]
157pub struct AudioFrameDescriptor {
158 pub format: SampleFormat,
159 pub samples: NonZeroU32,
160 pub sample_rate: NonZeroU32,
161 pub channel_layout: ChannelLayout,
162}
163
164struct ChannelLayoutMap {
165 map: Vec<Option<Vec<ChannelLayout>>>,
166}
167
168macro_rules! define_channel_layout_map {
169 ( $($channel_count:literal => [$($mask:ident),*]),* $(,)? ) => {
170 static CHANNEL_LAYOUT_MAP: LazyLock<ChannelLayoutMap> = LazyLock::new(|| {
171 let mut map = vec![None; DEFAULT_MAX_CHANNELS];
172 $(
173 let channels = NonZeroU8::new($channel_count).unwrap();
174 map[($channel_count - 1) as usize] = Some(vec![
175 $(
176 ChannelLayout {
177 order: ChannelOrder::Native,
178 channels,
179 spec: ChannelLayoutSpec::Mask(ChannelFormatMasks::$mask),
180 }
181 ),*
182 ]);
183 )*
184 ChannelLayoutMap { map }
185 });
186 };
187}
188
189define_channel_layout_map! {
190 1 => [Mono],
191 2 => [Stereo],
192 3 => [Surround_2_1, Surround_3_0, Surround_3_0_BACK],
193 4 => [Surround_3_1, Surround_4_0, Surround_2_2, Quad],
194 5 => [Surround_4_1, Surround_5_0, Surround_5_0_BACK],
195 6 => [Surround_5_1, Surround_5_1_BACK, Surround_6_0, Surround_6_0_FRONT, Surround_3_1_2, Hexagonal],
196 7 => [Surround_6_1, Surround_6_1_FRONT, Surround_6_1_BACK, Surround_7_0, Surround_7_0_FRONT],
197 8 => [Surround_7_1, Surround_7_1_WIDE, Surround_7_1_WIDE_BACK, Surround_5_1_2, Surround_5_1_2_BACK, Octagonal, Cube],
198 10 => [Surround_5_1_4_BACK, Surround_7_1_2],
199 12 => [Surround_7_1_4_BACK],
200 14 => [Surround_9_1_4_BACK],
201}
202
203struct SampleFormatDescriptor {
204 pub bits: u8,
205 pub is_planar: bool,
206}
207
208static SAMPLE_FORMAT_DESC: [SampleFormatDescriptor; SampleFormat::MAX as usize] = [
209 SampleFormatDescriptor {
211 bits: 8,
212 is_planar: false,
213 },
214 SampleFormatDescriptor {
216 bits: 16,
217 is_planar: false,
218 },
219 SampleFormatDescriptor {
221 bits: 32,
222 is_planar: false,
223 },
224 SampleFormatDescriptor {
226 bits: 32,
227 is_planar: false,
228 },
229 SampleFormatDescriptor {
231 bits: 64,
232 is_planar: false,
233 },
234 SampleFormatDescriptor {
236 bits: 8,
237 is_planar: true,
238 },
239 SampleFormatDescriptor {
241 bits: 16,
242 is_planar: true,
243 },
244 SampleFormatDescriptor {
246 bits: 32,
247 is_planar: true,
248 },
249 SampleFormatDescriptor {
251 bits: 32,
252 is_planar: true,
253 },
254 SampleFormatDescriptor {
256 bits: 64,
257 is_planar: true,
258 },
259];
260
261impl SampleFormat {
262 pub fn bits(&self) -> u8 {
263 SAMPLE_FORMAT_DESC[*self as usize].bits
264 }
265
266 pub fn bytes(&self) -> u8 {
267 self.bits() >> 3
268 }
269
270 pub fn is_planar(&self) -> bool {
271 SAMPLE_FORMAT_DESC[*self as usize].is_planar
272 }
273
274 pub fn stride(&self, channels: u8, samples: u32) -> usize {
275 if self.is_planar() {
276 self.bytes() as usize * samples as usize
277 } else {
278 self.bytes() as usize * channels as usize * samples as usize
279 }
280 }
281
282 pub(crate) fn calc_data(&self, channels: u8, samples: u32) -> (usize, PlaneInformationVec) {
283 let mut size = 0;
284 let mut planes = PlaneInformationVec::new();
285 let stride = self.stride(channels, samples);
286
287 if self.is_planar() {
288 planes.extend(iter::repeat_n(PlaneInformation::Audio(stride, stride), channels as usize));
289 size += stride * channels as usize;
290 } else {
291 planes.push(PlaneInformation::Audio(stride, stride));
292 size = stride;
293 }
294
295 (size, planes)
296 }
297
298 pub(crate) fn calc_actual_bytes(&self, channels: u8, samples: u32) -> usize {
299 let bytes = self.stride(channels, samples);
300 if self.is_planar() {
301 bytes * channels as usize
302 } else {
303 bytes
304 }
305 }
306}
307
308impl From<ChannelFormat> for u32 {
309 fn from(format: ChannelFormat) -> Self {
310 format as u32
311 }
312}
313
314impl From<ChannelFormat> for ChannelFormatMasks {
315 fn from(format: ChannelFormat) -> Self {
316 ChannelFormatMasks::from_bits_truncate(1u32 << format as u32)
317 }
318}
319
320impl Default for ChannelLayout {
321 fn default() -> Self {
322 Self {
323 order: ChannelOrder::Unspecified,
324 channels: NonZeroU8::new(1).unwrap(),
325 spec: ChannelLayoutSpec::Mask(ChannelFormatMasks::from_bits_truncate(0)),
326 }
327 }
328}
329
330impl TryFrom<ChannelFormatMasks> for ChannelLayout {
331 type Error = Error;
332
333 fn try_from(mask: ChannelFormatMasks) -> std::result::Result<Self, Self::Error> {
334 Self::from_mask(mask)
335 }
336}
337
338impl TryFrom<u8> for ChannelLayout {
339 type Error = Error;
340
341 fn try_from(channels: u8) -> std::result::Result<Self, Self::Error> {
342 Self::default_from_channels(channels)
343 }
344}
345
346impl ChannelLayout {
347 pub fn from_mask(mask: ChannelFormatMasks) -> Result<Self> {
348 let channels = mask.bits().count_ones() as u8;
349 let spec = ChannelLayoutSpec::Mask(mask);
350
351 NonZeroU8::new(channels)
352 .map(|channels| Self {
353 order: ChannelOrder::Native,
354 channels,
355 spec,
356 })
357 .ok_or_else(|| invalid_param_error!("channel mask is empty"))
358 }
359
360 pub fn default_from_channels(channels: u8) -> Result<Self> {
361 let channels = NonZeroU8::new(channels).ok_or(invalid_param_error!(channels))?;
362
363 Ok(CHANNEL_LAYOUT_MAP
364 .map
365 .get((channels.get() - 1) as usize)
366 .and_then(|opt| opt.as_ref())
367 .and_then(|layouts| layouts.first())
368 .cloned()
369 .unwrap_or(Self {
370 order: ChannelOrder::Unspecified,
371 channels,
372 spec: ChannelLayoutSpec::Mask(ChannelFormatMasks::from_bits_truncate(0)),
373 }))
374 }
375}
376
377impl AudioFrameDescriptor {
378 pub fn new(format: SampleFormat, channels: NonZeroU8, samples: NonZeroU32, sample_rate: NonZeroU32) -> Self {
379 Self {
380 format,
381 samples,
382 sample_rate,
383 channel_layout: ChannelLayout::default_from_channels(channels.get()).unwrap_or_default(),
384 }
385 }
386
387 pub fn try_new(format: SampleFormat, channels: u8, samples: u32, sample_rate: u32) -> Result<Self> {
388 let channels = NonZeroU8::new(channels).ok_or(invalid_param_error!(channels))?;
389 let samples = NonZeroU32::new(samples).ok_or(invalid_param_error!(samples))?;
390 let sample_rate = NonZeroU32::new(sample_rate).ok_or(invalid_param_error!(sample_rate))?;
391
392 Ok(Self::new(format, channels, samples, sample_rate))
393 }
394
395 pub fn from_channel_layout(format: SampleFormat, samples: NonZeroU32, sample_rate: NonZeroU32, channel_layout: ChannelLayout) -> Self {
396 Self {
397 format,
398 samples,
399 sample_rate,
400 channel_layout,
401 }
402 }
403
404 pub fn try_from_channel_layout(format: SampleFormat, samples: u32, sample_rate: u32, channel_layout: ChannelLayout) -> Result<Self> {
405 let samples = NonZeroU32::new(samples).ok_or(invalid_param_error!(samples))?;
406 let sample_rate = NonZeroU32::new(sample_rate).ok_or(invalid_param_error!(sample_rate))?;
407
408 Ok(Self::from_channel_layout(format, samples, sample_rate, channel_layout))
409 }
410
411 pub fn channels(&self) -> NonZeroU8 {
412 self.channel_layout.channels
413 }
414
415 pub fn duration_equal(&self, other: &AudioFrameDescriptor) -> bool {
416 let duration1 = self.samples.get() as u64 * time::MSEC_PER_SEC / self.sample_rate.get() as u64;
417 let duration2 = other.samples.get() as u64 * time::MSEC_PER_SEC / other.sample_rate.get() as u64;
418 duration1 == duration2
419 }
420}
421
422impl From<AudioFrameDescriptor> for FrameDescriptor {
423 fn from(desc: AudioFrameDescriptor) -> Self {
424 FrameDescriptor::Audio(desc)
425 }
426}