1 use super::audio_format::{self, LinearPcmFlags};
2 
3 
4 /// Dynamic representation of audio data sample format.
5 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
6 pub enum SampleFormat {
7     F32,
8     I32,
9     I16,
10     I8,
11 }
12 
13 impl SampleFormat {
14 
does_match_flags(&self, flags: audio_format::LinearPcmFlags) -> bool15     pub fn does_match_flags(&self, flags: audio_format::LinearPcmFlags) -> bool {
16         let is_float = flags.contains(LinearPcmFlags::IS_FLOAT);
17         let is_signed_integer = flags.contains(LinearPcmFlags::IS_SIGNED_INTEGER);
18         match *self {
19             SampleFormat::F32 => is_float && !is_signed_integer,
20             SampleFormat::I32 |
21             SampleFormat::I16 |
22             SampleFormat::I8 => is_signed_integer && !is_float,
23         }
24     }
25 
from_flags_and_bytes_per_frame(flags: audio_format::LinearPcmFlags, bytes_per_frame: u32) -> Option<Self>26     pub fn from_flags_and_bytes_per_frame(flags: audio_format::LinearPcmFlags,
27                                           bytes_per_frame: u32) -> Option<Self>
28     {
29         Some(if flags.contains(LinearPcmFlags::IS_FLOAT) {
30             SampleFormat::F32
31         } else {
32             // TODO: Check whether or not we need to consider unsigned ints and `IS_PACKED`.
33             match bytes_per_frame {
34                 1 => SampleFormat::I8,
35                 2 => SampleFormat::I16,
36                 4 => SampleFormat::I32,
37                 _ => return None,
38             }
39         })
40     }
41 
size_in_bytes(&self) -> usize42     pub fn size_in_bytes(&self) -> usize {
43         use std::mem::size_of;
44         match *self {
45             SampleFormat::F32 => size_of::<f32>(),
46             SampleFormat::I32 => size_of::<i32>(),
47             SampleFormat::I16 => size_of::<i16>(),
48             SampleFormat::I8 => size_of::<i8>(),
49         }
50     }
51 
52 }
53 
54 /// Audio data sample types.
55 pub trait Sample {
56     /// Dynamic representation of audio data sample format.
sample_format() -> SampleFormat57     fn sample_format() -> SampleFormat;
58 }
59 
60 /// Simplified implementation of the `Sample` trait for sample types.
61 macro_rules! impl_sample {
62     ($($T:ident $format:ident),* $(,)*) => {
63         $(
64             impl Sample for $T {
65                 fn sample_format() -> SampleFormat {
66                     SampleFormat::$format
67                 }
68             }
69         )*
70     }
71 }
72 
73 impl_sample!(f32 F32, i32 I32, i16 I16, i8 I8);
74