1use std::convert::TryFrom;
11use std::fmt;
12
13#[derive(PartialEq, Debug)]
15pub enum AudioObjectTypeError {
16 EscapeValue,
19 TooLarge(u8),
21}
22
23#[derive(PartialEq, Debug)]
25pub enum SamplingFrequencyIndexError {
26 EscapeValue,
29 TooLarge(u8),
31}
32
33#[derive(PartialEq, Debug)]
35pub struct ChannelConfigurationError(
36 pub u8,
38);
39
40#[derive(Eq, PartialEq, Copy, Clone)]
73pub struct AudioObjectType(u8);
74
75pub const AOT_ESCAPE_VALUE: u8 = 0b_11111;
78
79impl AudioObjectType {
80 const MAX: u8 = 95;
82
83 pub const fn new(value: u8) -> Self {
88 assert!(value != AOT_ESCAPE_VALUE, "AudioObjectType: 31 is the escape value, not an audio object type");
89 assert!(value <= Self::MAX, "AudioObjectType: value must be 0..=95");
90 Self(value)
91 }
92}
93
94impl From<AudioObjectType> for u8 {
95 fn from(v: AudioObjectType) -> Self {
96 v.0
97 }
98}
99impl TryFrom<u8> for AudioObjectType {
100 type Error = AudioObjectTypeError;
101
102 fn try_from(value: u8) -> Result<Self, Self::Error> {
103 match value {
104 AOT_ESCAPE_VALUE => Err(AudioObjectTypeError::EscapeValue),
105 0..=Self::MAX => Ok(AudioObjectType(value)),
106 _ => Err(AudioObjectTypeError::TooLarge(value)),
107 }
108 }
109}
110
111macro_rules! implement_aot {
112 (
113 $( $tag:literal $id:ident $desc:literal ),* ,
114 ) => {
115
116 impl AudioObjectType {
117 $(
118 #[doc=$desc]
119 pub const $id: AudioObjectType = AudioObjectType($tag);
120 )*
121 }
122
123 impl fmt::Debug for AudioObjectType {
124 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125 match self.0 {
126 $(
127 $tag => write!(f, "{}({})", stringify!($id), $tag)
128 ),* ,
129 _ => write!(f, "RESERVED({})", self.0),
130 }
131 }
132 }
133 }
134}
135
136implement_aot! {
137 0 NULL "Null",
138 1 AAC_MAIN "AAC main",
139 3 AAC_SSR "AAC SSR",
140 4 AAC_LTP "AAC LTP",
141 7 TWIN_VQ "TwinVQ",
142 8 CELP "CELP",
143 9 HVXC "HVXC",
144 5 SBR "SBR",
145 6 AAC_SCALABLE "AAC Scalable",
146 2 AAC_LC "AAC LC",
147 12 TTSI "TTSI",
148 13 MAIN_SYNTHETIC "Main synthetic",
149 14 WAVETABLE_SYNTHESIS "Wavetable synthesis",
150 15 GENERAL_MIDI "General MIDI",
151 16 ALGORITHMIC_SYNTHESIS_AND_AUDIO_FX "Algorithmic Synthesis and Audio FX",
152 17 ER_AAC_LC "ER AAC LC",
153 19 ER_AAC_LTP "ER AAC LTP",
154 20 ER_AAC_SCALABLE "ER AAC Scalable",
155 21 ER_TWIN_VQ "ER TwinVQ",
156 22 ER_BSAC "ER BSAC",
157 23 ER_AAC_LD "ER AAC LD",
158 24 ER_CELP "ER CELP",
159 25 ER_HVXC "ER HVXC",
160 26 ER_HILN "ER HILN",
161 27 ER_PARAMETRIC "ER Parametric",
162 28 SSC "SSC",
163 29 PS "PS",
164 30 MPEG_SURROUND "MPEG Surround",
165 32 LAYER1 "Layer-1",
167 33 LAYER2 "Layer-2",
168 34 LAYER3 "Layer-3",
169 35 DST "DST",
170 36 ALS "ALS",
171 37 SLS "SLS",
172 38 SLS_NON_CORE "SLS non-core",
173 39 ER_AAC_ELD "ER AAC ELD",
174 40 SMR_SIMPLE "SMR Simple",
175 41 SMR_MAIN "SMR Main",
176 42 USAC "Unified Speech and Audio Coding",
177 43 SAOC "Spatial Audio Object Coding",
178 44 LD_MPEG_SURROUND "Low Delay MPEG Surround",
179 45 SAOC_DE "Spatial Audio Object Coding Dialogue Enhancement",
180 46 AUDIO_SYNC "Audio synchronization tool",
181}
182
183#[derive(PartialEq, Eq, Clone, Copy)]
193pub struct SamplingFrequencyIndex(u8);
194
195impl SamplingFrequencyIndex {
196 const MAX: u8 = 0xe;
198
199 pub const FREQ_96000: Self = Self(0x0);
201 pub const FREQ_88200: Self = Self(0x1);
203 pub const FREQ_64000: Self = Self(0x2);
205 pub const FREQ_48000: Self = Self(0x3);
207 pub const FREQ_44100: Self = Self(0x4);
209 pub const FREQ_32000: Self = Self(0x5);
211 pub const FREQ_24000: Self = Self(0x6);
213 pub const FREQ_22050: Self = Self(0x7);
215 pub const FREQ_16000: Self = Self(0x8);
217 pub const FREQ_12000: Self = Self(0x9);
219 pub const FREQ_11025: Self = Self(0xa);
221 pub const FREQ_8000: Self = Self(0xb);
223 pub const FREQ_7350: Self = Self(0xc);
225
226 pub const fn new(value: u8) -> Self {
231 assert!(value <= Self::MAX, "SamplingFrequencyIndex: value must be 0x0..=0xe");
232 Self(value)
233 }
234
235 pub fn freq(&self) -> Option<u32> {
238 match self.0 {
239 0x0 => Some(96000),
240 0x1 => Some(88200),
241 0x2 => Some(64000),
242 0x3 => Some(48000),
243 0x4 => Some(44100),
244 0x5 => Some(32000),
245 0x6 => Some(24000),
246 0x7 => Some(22050),
247 0x8 => Some(16000),
248 0x9 => Some(12000),
249 0xa => Some(11025),
250 0xb => Some(8000),
251 0xc => Some(7350),
252 _ => None,
253 }
254 }
255}
256
257impl fmt::Debug for SamplingFrequencyIndex {
258 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
259 match self.0 {
260 0x0 => write!(f, "FREQ_96000(0)"),
261 0x1 => write!(f, "FREQ_88200(1)"),
262 0x2 => write!(f, "FREQ_64000(2)"),
263 0x3 => write!(f, "FREQ_48000(3)"),
264 0x4 => write!(f, "FREQ_44100(4)"),
265 0x5 => write!(f, "FREQ_32000(5)"),
266 0x6 => write!(f, "FREQ_24000(6)"),
267 0x7 => write!(f, "FREQ_22050(7)"),
268 0x8 => write!(f, "FREQ_16000(8)"),
269 0x9 => write!(f, "FREQ_12000(9)"),
270 0xa => write!(f, "FREQ_11025(10)"),
271 0xb => write!(f, "FREQ_8000(11)"),
272 0xc => write!(f, "FREQ_7350(12)"),
273 _ => write!(f, "RESERVED({})", self.0),
274 }
275 }
276}
277
278impl From<SamplingFrequencyIndex> for u8 {
279 fn from(v: SamplingFrequencyIndex) -> Self {
280 v.0
281 }
282}
283impl TryFrom<u8> for SamplingFrequencyIndex {
284 type Error = SamplingFrequencyIndexError;
285
286 fn try_from(value: u8) -> Result<Self, Self::Error> {
287 match value {
288 0..=Self::MAX => Ok(SamplingFrequencyIndex(value)),
289 0xf => Err(SamplingFrequencyIndexError::EscapeValue),
290 _ => Err(SamplingFrequencyIndexError::TooLarge(value)),
291 }
292 }
293}
294
295#[derive(PartialEq, Eq, Clone, Copy)]
304pub struct ChannelConfiguration(u8);
305
306impl ChannelConfiguration {
307 const MAX: u8 = 0xf;
309
310 pub const OBJECT_TYPE_SPECIFIC_CONFIG: Self = Self(0x0);
312 pub const MONO: Self = Self(0x1);
314 pub const STEREO: Self = Self(0x2);
316 pub const THREE: Self = Self(0x3);
318 pub const FOUR: Self = Self(0x4);
320 pub const FIVE: Self = Self(0x5);
322 pub const FIVE_ONE: Self = Self(0x6);
324 pub const SEVEN_ONE: Self = Self(0x7);
326
327 pub const fn new(value: u8) -> Self {
332 assert!(value <= Self::MAX, "ChannelConfiguration: expected a 4 bit value");
333 Self(value)
334 }
335}
336
337impl fmt::Debug for ChannelConfiguration {
338 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
339 match self.0 {
340 0 => write!(f, "OBJECT_TYPE_SPECIFIC_CONFIG(0)"),
341 1 => write!(f, "MONO(1)"),
342 2 => write!(f, "STEREO(2)"),
343 3 => write!(f, "THREE(3)"),
344 4 => write!(f, "FOUR(4)"),
345 5 => write!(f, "FIVE(5)"),
346 6 => write!(f, "FIVE_ONE(6)"),
347 7 => write!(f, "SEVEN_ONE(7)"),
348 _ => write!(f, "RESERVED({})", self.0),
349 }
350 }
351}
352
353impl From<ChannelConfiguration> for u8 {
354 fn from(v: ChannelConfiguration) -> Self {
355 v.0
356 }
357}
358impl TryFrom<u8> for ChannelConfiguration {
359 type Error = ChannelConfigurationError;
360
361 fn try_from(value: u8) -> Result<Self, Self::Error> {
362 match value {
363 0..=Self::MAX => Ok(ChannelConfiguration(value)),
364 _ => Err(ChannelConfigurationError(value)),
365 }
366 }
367}
368
369#[cfg(test)]
370mod tests {
371 use super::*;
372 use std::convert::TryFrom;
373
374 #[test]
375 fn aot_escape_value() {
376 assert_eq!(
377 Err(AudioObjectTypeError::EscapeValue),
378 AudioObjectType::try_from(AOT_ESCAPE_VALUE)
379 );
380 }
381
382 #[test]
383 fn aot_too_large() {
384 assert_eq!(
385 Err(AudioObjectTypeError::TooLarge(96)),
386 AudioObjectType::try_from(96)
387 );
388 }
389
390 #[test]
391 fn aot_valid() {
392 assert_eq!(AudioObjectType::AAC_LC, AudioObjectType::try_from(2).unwrap());
393 assert_eq!(2u8, AudioObjectType::AAC_LC.into());
394 }
395
396 #[test]
397 fn sampling_frequency_known_indices() {
398 assert_eq!(SamplingFrequencyIndex::FREQ_96000.freq(), Some(96000));
399 assert_eq!(SamplingFrequencyIndex::FREQ_88200.freq(), Some(88200));
400 assert_eq!(SamplingFrequencyIndex::FREQ_64000.freq(), Some(64000));
401 assert_eq!(SamplingFrequencyIndex::FREQ_48000.freq(), Some(48000));
402 assert_eq!(SamplingFrequencyIndex::FREQ_44100.freq(), Some(44100));
403 assert_eq!(SamplingFrequencyIndex::FREQ_32000.freq(), Some(32000));
404 assert_eq!(SamplingFrequencyIndex::FREQ_24000.freq(), Some(24000));
405 assert_eq!(SamplingFrequencyIndex::FREQ_22050.freq(), Some(22050));
406 assert_eq!(SamplingFrequencyIndex::FREQ_16000.freq(), Some(16000));
407 assert_eq!(SamplingFrequencyIndex::FREQ_12000.freq(), Some(12000));
408 assert_eq!(SamplingFrequencyIndex::FREQ_11025.freq(), Some(11025));
409 assert_eq!(SamplingFrequencyIndex::FREQ_8000.freq(), Some(8000));
410 assert_eq!(SamplingFrequencyIndex::FREQ_7350.freq(), Some(7350));
411 }
412
413 #[test]
414 fn sampling_frequency_reserved_indices() {
415 assert_eq!(SamplingFrequencyIndex::new(0xd).freq(), None);
416 assert_eq!(SamplingFrequencyIndex::new(0xe).freq(), None);
417 }
418
419 #[test]
420 fn sampling_frequency_new_valid() {
421 assert_eq!(SamplingFrequencyIndex::new(0x3), SamplingFrequencyIndex::FREQ_48000);
422 }
423
424 #[test]
425 #[should_panic]
426 fn sampling_frequency_new_escape() {
427 SamplingFrequencyIndex::new(0xf);
428 }
429
430 #[test]
431 #[should_panic]
432 fn sampling_frequency_new_too_large() {
433 SamplingFrequencyIndex::new(0x10);
434 }
435
436 #[test]
437 fn channel_configuration_valid() {
438 assert_eq!(ChannelConfiguration::MONO, ChannelConfiguration::new(1));
439 assert_eq!(ChannelConfiguration::STEREO, ChannelConfiguration::new(2));
440 assert_eq!(ChannelConfiguration::FIVE_ONE, ChannelConfiguration::new(6));
441 assert_eq!(ChannelConfiguration::SEVEN_ONE, ChannelConfiguration::new(7));
442 }
443
444 #[test]
445 fn channel_configuration_reserved() {
446 let _ = ChannelConfiguration::new(0xf);
448 }
449
450 #[test]
451 #[should_panic]
452 fn channel_configuration_too_large() {
453 ChannelConfiguration::new(0x10);
454 }
455
456 #[test]
457 fn sampling_frequency_try_from_valid() {
458 assert_eq!(
459 SamplingFrequencyIndex::try_from(0x3),
460 Ok(SamplingFrequencyIndex::FREQ_48000),
461 );
462 assert_eq!(
463 u8::from(SamplingFrequencyIndex::try_from(0x3).unwrap()),
464 0x3,
465 );
466 }
467
468 #[test]
469 fn sampling_frequency_try_from_escape() {
470 assert_eq!(
471 SamplingFrequencyIndex::try_from(0xf),
472 Err(SamplingFrequencyIndexError::EscapeValue),
473 );
474 }
475
476 #[test]
477 fn sampling_frequency_try_from_too_large() {
478 assert_eq!(
479 SamplingFrequencyIndex::try_from(0x10),
480 Err(SamplingFrequencyIndexError::TooLarge(0x10)),
481 );
482 }
483
484 #[test]
485 fn channel_configuration_try_from_valid() {
486 assert_eq!(
487 ChannelConfiguration::try_from(2),
488 Ok(ChannelConfiguration::STEREO),
489 );
490 assert_eq!(
491 ChannelConfiguration::try_from(0xf),
492 Ok(ChannelConfiguration::new(0xf)),
493 );
494 }
495
496 #[test]
497 fn channel_configuration_try_from_too_large() {
498 assert_eq!(
499 ChannelConfiguration::try_from(0x10),
500 Err(ChannelConfigurationError(0x10)),
501 );
502 }
503}