fuchsia_audio_device/
types.rs
1use fidl_fuchsia_hardware_audio::{PcmFormat, SampleFormat};
6
7use std::result;
8use thiserror::Error;
9
10pub type Result<T> = result::Result<T, Error>;
12
13#[derive(Error, Debug)]
15pub enum Error {
16 #[error("Value was out of range")]
18 OutOfRange,
19
20 #[error("Invalid Header for a message")]
22 InvalidHeader,
23
24 #[error("Encoding error")]
26 Encoding,
27
28 #[error("Encountered an IO error reading from the channel: {}", _0)]
30 PeerRead(zx::Status),
31
32 #[error("Encountered an IO error writing to the channel: {}", _0)]
34 PeerWrite(zx::Status),
35
36 #[error("Encountered an IO error: {}", _0)]
38 IOError(zx::Status),
39
40 #[error("Encountered an error on a RequestStream: {}", _0)]
42 RequestStreamError(#[from] fidl::Error),
43
44 #[error("Peer performed an invalid action: {}", _0)]
46 PeerError(String),
47
48 #[error("Tried to do an action in an invalid state")]
50 InvalidState,
51
52 #[error("No channel found for reply")]
54 NoChannel,
55
56 #[error("Message has not been implemented yet")]
58 UnimplementedMessage,
59
60 #[error("Invalid argument")]
62 InvalidArgs,
63
64 #[doc(hidden)]
65 #[error("__Nonexhaustive error should never be created.")]
66 __Nonexhaustive,
67}
68
69#[derive(Debug, PartialEq, Clone)]
70pub enum AudioSampleFormat {
71 Eight { unsigned: bool },
72 Sixteen { unsigned: bool, invert_endian: bool },
73 TwentyFourPacked { unsigned: bool, invert_endian: bool },
74 TwentyIn32 { unsigned: bool, invert_endian: bool },
75 TwentyFourIn32 { unsigned: bool, invert_endian: bool },
76 ThirtyTwo { unsigned: bool, invert_endian: bool },
77 Float { invert_endian: bool },
78}
79
80impl AudioSampleFormat {
81 fn is_unsigned(&self) -> bool {
82 use AudioSampleFormat::*;
83 match self {
84 Eight { unsigned }
85 | Sixteen { unsigned, .. }
86 | TwentyFourPacked { unsigned, .. }
87 | TwentyIn32 { unsigned, .. }
88 | TwentyFourIn32 { unsigned, .. }
89 | ThirtyTwo { unsigned, .. } => *unsigned,
90 Float { .. } => false,
91 }
92 }
93}
94
95impl From<PcmFormat> for AudioSampleFormat {
97 fn from(v: PcmFormat) -> Self {
98 if let SampleFormat::PcmFloat = v.sample_format {
99 if v.bytes_per_sample == 32 && v.valid_bits_per_sample == 32 {
100 AudioSampleFormat::Float { invert_endian: false }
101 } else {
102 panic!("audio sample format not supported");
103 }
104 } else {
105 let is_unsigned = v.sample_format == SampleFormat::PcmUnsigned;
106 match v.bytes_per_sample {
107 1u8 => {
108 assert_eq!(v.valid_bits_per_sample, 8u8);
109 AudioSampleFormat::Eight { unsigned: is_unsigned }
110 }
111 2u8 => {
112 assert_eq!(v.valid_bits_per_sample, 16u8);
113 AudioSampleFormat::Sixteen { unsigned: is_unsigned, invert_endian: false }
114 }
115 3u8 => {
116 assert_eq!(v.valid_bits_per_sample, 24u8);
117 AudioSampleFormat::TwentyFourPacked {
118 unsigned: is_unsigned,
119 invert_endian: false,
120 }
121 }
122 4u8 => match v.valid_bits_per_sample {
123 20u8 => AudioSampleFormat::TwentyIn32 {
124 unsigned: is_unsigned,
125 invert_endian: false,
126 },
127 24u8 => AudioSampleFormat::TwentyFourIn32 {
128 unsigned: is_unsigned,
129 invert_endian: false,
130 },
131 32u8 => {
132 AudioSampleFormat::ThirtyTwo { unsigned: is_unsigned, invert_endian: false }
133 }
134 _ => panic!(
135 "audio valid bits per sample {:?} not supported",
136 v.valid_bits_per_sample
137 ),
138 },
139 _ => panic!("audio bytes per samples {:?} not supported", v.bytes_per_sample),
140 }
141 }
142 }
143}
144
145impl AudioSampleFormat {
146 pub fn compute_frame_size(&self, channels: usize) -> Result<usize> {
150 let bytes_per_channel = match self {
151 AudioSampleFormat::Eight { .. } => 1,
152 AudioSampleFormat::Sixteen { .. } => 2,
153 AudioSampleFormat::TwentyFourPacked { .. } => 3,
154 AudioSampleFormat::TwentyIn32 { .. }
155 | AudioSampleFormat::TwentyFourIn32 { .. }
156 | AudioSampleFormat::ThirtyTwo { .. }
157 | AudioSampleFormat::Float { .. } => 4,
158 };
159 Ok(channels * bytes_per_channel)
160 }
161}
162
163impl std::fmt::Display for AudioSampleFormat {
164 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
165 if self.is_unsigned() {
166 f.write_str("u")?;
167 } else {
168 f.write_str("i")?;
169 }
170 use AudioSampleFormat::*;
171 match self {
172 Eight { .. } => f.write_str("8"),
173 Sixteen { .. } => f.write_str("16"),
174 TwentyFourPacked { .. } => f.write_str("24p"),
175 TwentyIn32 { .. } => f.write_str("20(32)"),
176 TwentyFourIn32 { .. } => f.write_str("24(32)"),
177 ThirtyTwo { .. } => f.write_str("32"),
178 Float { .. } => f.write_str("float"),
179 }
180 }
181}