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