fuchsia_audio_device/
types.rs1use 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(Debug, PartialEq, Clone)]
15pub enum AudioStreamItem {
16 Data(Vec<u8>),
18 AudioDisabled,
20}
21
22impl From<Vec<u8>> for AudioStreamItem {
23 fn from(data: Vec<u8>) -> Self {
24 Self::Data(data)
25 }
26}
27
28#[derive(Error, Debug)]
30pub enum Error {
31 #[error("Value was out of range")]
33 OutOfRange,
34
35 #[error("Invalid Header for a message")]
37 InvalidHeader,
38
39 #[error("Encoding error")]
41 Encoding,
42
43 #[error("Encountered an IO error reading from the channel: {}", _0)]
45 PeerRead(zx::Status),
46
47 #[error("Encountered an IO error writing to the channel: {}", _0)]
49 PeerWrite(zx::Status),
50
51 #[error("Encountered an IO error: {}", _0)]
53 IOError(zx::Status),
54
55 #[error("Encountered an error on a RequestStream: {}", _0)]
57 RequestStreamError(#[from] fidl::Error),
58
59 #[error("Peer performed an invalid action: {}", _0)]
61 PeerError(String),
62
63 #[error("Tried to do an action in an invalid state")]
65 InvalidState,
66
67 #[error("Invalid argument")]
69 InvalidArgs,
70
71 #[doc(hidden)]
72 #[error("__Nonexhaustive error should never be created.")]
73 __Nonexhaustive,
74}
75
76impl From<Error> for zx::Status {
77 fn from(value: Error) -> Self {
78 match value {
79 Error::OutOfRange => zx::Status::OUT_OF_RANGE,
80 Error::PeerRead(s) | Error::PeerWrite(s) | Error::IOError(s) => s,
81 Error::RequestStreamError(_) => zx::Status::IO,
82 Error::InvalidState => zx::Status::BAD_STATE,
83 Error::InvalidArgs => zx::Status::INVALID_ARGS,
84 _ => zx::Status::INTERNAL,
85 }
86 }
87}
88
89#[derive(Debug, PartialEq, Clone)]
90pub enum AudioSampleFormat {
91 Eight { unsigned: bool },
92 Sixteen { unsigned: bool, invert_endian: bool },
93 TwentyFourPacked { unsigned: bool, invert_endian: bool },
94 TwentyIn32 { unsigned: bool, invert_endian: bool },
95 TwentyFourIn32 { unsigned: bool, invert_endian: bool },
96 ThirtyTwo { unsigned: bool, invert_endian: bool },
97 Float { invert_endian: bool },
98}
99
100impl AudioSampleFormat {
101 fn is_unsigned(&self) -> bool {
102 use AudioSampleFormat::*;
103 match self {
104 Eight { unsigned }
105 | Sixteen { unsigned, .. }
106 | TwentyFourPacked { unsigned, .. }
107 | TwentyIn32 { unsigned, .. }
108 | TwentyFourIn32 { unsigned, .. }
109 | ThirtyTwo { unsigned, .. } => *unsigned,
110 Float { .. } => false,
111 }
112 }
113}
114
115impl From<PcmFormat> for AudioSampleFormat {
117 fn from(v: PcmFormat) -> Self {
118 if let SampleFormat::PcmFloat = v.sample_format {
119 if v.bytes_per_sample == 32 && v.valid_bits_per_sample == 32 {
120 AudioSampleFormat::Float { invert_endian: false }
121 } else {
122 panic!("audio sample format not supported");
123 }
124 } else {
125 let is_unsigned = v.sample_format == SampleFormat::PcmUnsigned;
126 match v.bytes_per_sample {
127 1u8 => {
128 assert_eq!(v.valid_bits_per_sample, 8u8);
129 AudioSampleFormat::Eight { unsigned: is_unsigned }
130 }
131 2u8 => {
132 assert_eq!(v.valid_bits_per_sample, 16u8);
133 AudioSampleFormat::Sixteen { unsigned: is_unsigned, invert_endian: false }
134 }
135 3u8 => {
136 assert_eq!(v.valid_bits_per_sample, 24u8);
137 AudioSampleFormat::TwentyFourPacked {
138 unsigned: is_unsigned,
139 invert_endian: false,
140 }
141 }
142 4u8 => match v.valid_bits_per_sample {
143 20u8 => AudioSampleFormat::TwentyIn32 {
144 unsigned: is_unsigned,
145 invert_endian: false,
146 },
147 24u8 => AudioSampleFormat::TwentyFourIn32 {
148 unsigned: is_unsigned,
149 invert_endian: false,
150 },
151 32u8 => {
152 AudioSampleFormat::ThirtyTwo { unsigned: is_unsigned, invert_endian: false }
153 }
154 _ => panic!(
155 "audio valid bits per sample {:?} not supported",
156 v.valid_bits_per_sample
157 ),
158 },
159 _ => panic!("audio bytes per samples {:?} not supported", v.bytes_per_sample),
160 }
161 }
162 }
163}
164
165impl AudioSampleFormat {
166 pub fn compute_frame_size(&self, channels: usize) -> Result<usize> {
170 let bytes_per_channel = match self {
171 AudioSampleFormat::Eight { .. } => 1,
172 AudioSampleFormat::Sixteen { .. } => 2,
173 AudioSampleFormat::TwentyFourPacked { .. } => 3,
174 AudioSampleFormat::TwentyIn32 { .. }
175 | AudioSampleFormat::TwentyFourIn32 { .. }
176 | AudioSampleFormat::ThirtyTwo { .. }
177 | AudioSampleFormat::Float { .. } => 4,
178 };
179 Ok(channels * bytes_per_channel)
180 }
181}
182
183impl std::fmt::Display for AudioSampleFormat {
184 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
185 if self.is_unsigned() {
186 f.write_str("u")?;
187 } else {
188 f.write_str("i")?;
189 }
190 use AudioSampleFormat::*;
191 match self {
192 Eight { .. } => f.write_str("8"),
193 Sixteen { .. } => f.write_str("16"),
194 TwentyFourPacked { .. } => f.write_str("24p"),
195 TwentyIn32 { .. } => f.write_str("20(32)"),
196 TwentyFourIn32 { .. } => f.write_str("24(32)"),
197 ThirtyTwo { .. } => f.write_str("32"),
198 Float { .. } => f.write_str("float"),
199 }
200 }
201}