coreaudio/audio_unit/
sample_format.rs1use super::audio_format::{self, LinearPcmFlags};
2
3#[derive(Copy, Clone, Debug, PartialEq, Eq)]
5pub enum SampleFormat {
6 F32,
8 I32,
10 I24,
12 I16,
14 I8,
16}
17
18impl SampleFormat {
19 pub fn does_match_flags(&self, flags: audio_format::LinearPcmFlags) -> bool {
21 let is_float = flags.contains(LinearPcmFlags::IS_FLOAT);
22 let is_signed_integer = flags.contains(LinearPcmFlags::IS_SIGNED_INTEGER);
23 let is_packed = flags.contains(LinearPcmFlags::IS_PACKED);
24 match *self {
25 SampleFormat::F32 => is_float && !is_signed_integer && is_packed,
26 SampleFormat::I32 | SampleFormat::I16 | SampleFormat::I8 => {
27 is_signed_integer && !is_float && is_packed
28 }
29 SampleFormat::I24 => is_signed_integer && !is_float,
30 }
31 }
32
33 pub fn from_flags_and_bits_per_sample(
35 flags: audio_format::LinearPcmFlags,
36 bits_per_sample: u32,
37 ) -> Option<Self> {
38 let packed = flags.contains(LinearPcmFlags::IS_PACKED);
39 let sample_format = if flags.contains(LinearPcmFlags::IS_FLOAT) {
40 match (bits_per_sample, packed) {
41 (32, true) => SampleFormat::F32,
42 _ => return None,
43 }
44 } else if flags.contains(LinearPcmFlags::IS_SIGNED_INTEGER) {
45 match (bits_per_sample, packed) {
46 (8, true) => SampleFormat::I8,
47 (16, true) => SampleFormat::I16,
48 (24, _) => SampleFormat::I24,
49 (32, true) => SampleFormat::I32,
50 _ => return None,
51 }
52 } else {
53 return None;
55 };
56 Some(sample_format)
57 }
58
59 pub fn size_in_bytes(&self) -> usize {
61 use std::mem::size_of;
62 match *self {
63 SampleFormat::F32 => size_of::<f32>(),
64 SampleFormat::I32 => size_of::<i32>(),
65 SampleFormat::I24 => 3 * size_of::<u8>(),
66 SampleFormat::I16 => size_of::<i16>(),
67 SampleFormat::I8 => size_of::<i8>(),
68 }
69 }
70
71 pub fn size_in_bits(&self) -> u32 {
73 match *self {
74 SampleFormat::F32 => 32,
75 SampleFormat::I32 => 32,
76 SampleFormat::I24 => 24,
77 SampleFormat::I16 => 16,
78 SampleFormat::I8 => 8,
79 }
80 }
81}
82
83pub trait Sample {
85 fn sample_format() -> SampleFormat;
87}
88
89macro_rules! impl_sample {
92 ($($T:ident $format:ident),* $(,)*) => {
93 $(
94 impl Sample for $T {
95 fn sample_format() -> SampleFormat {
96 SampleFormat::$format
97 }
98 }
99 )*
100 }
101}
102
103impl_sample!(f32 F32, i32 I32, i16 I16, i8 I8);