1use std::{
2 iter, mem,
3 num::{NonZeroU32, NonZeroU8},
4};
5
6use strum::EnumCount;
7
8pub use super::channel_layout::*;
9use crate::{
10 align_to,
11 audio::AudioFrame,
12 error::Error,
13 frame::{Frame, PlaneDescriptor, PlaneVec},
14 invalid_param_error, time, FrameDescriptor, FrameDescriptorSpec, MediaType, Result,
15};
16
17pub const SAMPLE_RATE_TELEPHONE: u32 = 8000;
18pub const SAMPLE_RATE_VOIP: u32 = 16000;
19pub const SAMPLE_RATE_CD: u32 = 44100;
20pub const SAMPLE_RATE_DVD: u32 = 48000;
21pub const SAMPLE_RATE_HIGH: u32 = 96000;
22pub const SAMPLE_RATE_ULTRA_HIGH: u32 = 192000;
23
24#[derive(Clone, Copy, Debug, EnumCount, Eq, PartialEq)]
25pub enum SampleFormat {
26 U8 = 0, S16, S32, S64, F32, F64, U8P, S16P, S32P, S64P, F32P, F64P, }
39
40impl From<SampleFormat> for usize {
41 fn from(value: SampleFormat) -> Self {
42 value as usize
43 }
44}
45
46impl TryFrom<usize> for SampleFormat {
47 type Error = Error;
48
49 fn try_from(value: usize) -> Result<Self> {
50 if value < SampleFormat::COUNT {
51 Ok(unsafe { mem::transmute::<u8, SampleFormat>(value as u8) })
52 } else {
53 Err(invalid_param_error!(value))
54 }
55 }
56}
57
58struct SampleFormatDescriptor {
59 pub bits: u8,
60 pub planar: bool,
61}
62
63static SAMPLE_FORMAT_DESC: [SampleFormatDescriptor; SampleFormat::COUNT] = [
64 SampleFormatDescriptor {
66 bits: 8,
67 planar: false,
68 },
69 SampleFormatDescriptor {
71 bits: 16,
72 planar: false,
73 },
74 SampleFormatDescriptor {
76 bits: 32,
77 planar: false,
78 },
79 SampleFormatDescriptor {
81 bits: 64,
82 planar: false,
83 },
84 SampleFormatDescriptor {
86 bits: 32,
87 planar: false,
88 },
89 SampleFormatDescriptor {
91 bits: 64,
92 planar: false,
93 },
94 SampleFormatDescriptor {
96 bits: 8,
97 planar: true,
98 },
99 SampleFormatDescriptor {
101 bits: 16,
102 planar: true,
103 },
104 SampleFormatDescriptor {
106 bits: 32,
107 planar: true,
108 },
109 SampleFormatDescriptor {
111 bits: 64,
112 planar: true,
113 },
114 SampleFormatDescriptor {
116 bits: 32,
117 planar: true,
118 },
119 SampleFormatDescriptor {
121 bits: 64,
122 planar: true,
123 },
124];
125
126impl SampleFormat {
127 pub fn bits(&self) -> u8 {
128 SAMPLE_FORMAT_DESC[*self as usize].bits
129 }
130
131 pub fn bytes(&self) -> u8 {
132 self.bits() >> 3
133 }
134
135 pub fn is_planar(&self) -> bool {
136 SAMPLE_FORMAT_DESC[*self as usize].planar
137 }
138
139 pub fn is_packed(&self) -> bool {
140 !SAMPLE_FORMAT_DESC[*self as usize].planar
141 }
142
143 pub fn planar_sample_format(&self) -> SampleFormat {
144 match *self {
145 SampleFormat::U8 | SampleFormat::U8P => SampleFormat::U8P,
146 SampleFormat::S16 | SampleFormat::S16P => SampleFormat::S16P,
147 SampleFormat::S32 | SampleFormat::S32P => SampleFormat::S32P,
148 SampleFormat::S64 | SampleFormat::S64P => SampleFormat::S64P,
149 SampleFormat::F32 | SampleFormat::F32P => SampleFormat::F32P,
150 SampleFormat::F64 | SampleFormat::F64P => SampleFormat::F64P,
151 }
152 }
153
154 pub fn packed_sample_format(&self) -> SampleFormat {
155 match *self {
156 SampleFormat::U8 | SampleFormat::U8P => SampleFormat::U8,
157 SampleFormat::S16 | SampleFormat::S16P => SampleFormat::S16,
158 SampleFormat::S32 | SampleFormat::S32P => SampleFormat::S32,
159 SampleFormat::S64 | SampleFormat::S64P => SampleFormat::S64,
160 SampleFormat::F32 | SampleFormat::F32P => SampleFormat::F32,
161 SampleFormat::F64 | SampleFormat::F64P => SampleFormat::F64,
162 }
163 }
164
165 pub(crate) fn calc_plane_size(&self, channels: u8, samples: u32) -> usize {
166 if self.is_planar() {
167 self.bytes() as usize * samples as usize
168 } else {
169 self.bytes() as usize * samples as usize * channels as usize
170 }
171 }
172
173 pub(crate) fn calc_data_size(&self, channels: u8, samples: u32, alignment: u32) -> (usize, PlaneVec<PlaneDescriptor>) {
174 let mut planes = PlaneVec::new();
175 let used_bytes = self.calc_plane_size(channels, samples);
176 let allocated_size = align_to(used_bytes, alignment as usize);
177
178 let size = if self.is_planar() {
179 planes.extend(iter::repeat_n(PlaneDescriptor::Audio(allocated_size, used_bytes), channels as usize));
180 allocated_size * channels as usize
181 } else {
182 planes.push(PlaneDescriptor::Audio(allocated_size, used_bytes));
183 allocated_size
184 };
185
186 (size, planes)
187 }
188}
189
190#[derive(Clone, Debug, Eq, PartialEq)]
191pub struct AudioFrameDescriptor {
192 pub format: SampleFormat,
193 pub samples: NonZeroU32,
194 pub sample_rate: NonZeroU32,
195 pub channel_layout: ChannelLayout,
196}
197
198impl AudioFrameDescriptor {
199 pub fn new(format: SampleFormat, channels: NonZeroU8, samples: NonZeroU32, sample_rate: NonZeroU32) -> Self {
200 Self {
201 format,
202 samples,
203 sample_rate,
204 channel_layout: ChannelLayout::default_from_channels(channels.get()).unwrap_or_default(),
205 }
206 }
207
208 pub fn try_new(format: SampleFormat, channels: u8, samples: u32, sample_rate: u32) -> Result<Self> {
209 let channels = NonZeroU8::new(channels).ok_or_else(|| invalid_param_error!(channels))?;
210 let samples = NonZeroU32::new(samples).ok_or_else(|| invalid_param_error!(samples))?;
211 let sample_rate = NonZeroU32::new(sample_rate).ok_or_else(|| invalid_param_error!(sample_rate))?;
212
213 Ok(Self::new(format, channels, samples, sample_rate))
214 }
215
216 pub fn from_channel_layout(format: SampleFormat, samples: NonZeroU32, sample_rate: NonZeroU32, channel_layout: ChannelLayout) -> Self {
217 Self {
218 format,
219 samples,
220 sample_rate,
221 channel_layout,
222 }
223 }
224
225 pub fn try_from_channel_layout(format: SampleFormat, samples: u32, sample_rate: u32, channel_layout: ChannelLayout) -> Result<Self> {
226 let samples = NonZeroU32::new(samples).ok_or_else(|| invalid_param_error!(samples))?;
227 let sample_rate = NonZeroU32::new(sample_rate).ok_or_else(|| invalid_param_error!(sample_rate))?;
228
229 Ok(Self::from_channel_layout(format, samples, sample_rate, channel_layout))
230 }
231
232 pub fn channels(&self) -> NonZeroU8 {
233 self.channel_layout.channels
234 }
235
236 pub fn duration_equal(&self, other: &AudioFrameDescriptor) -> bool {
237 let duration1 = self.samples.get() as u64 * time::MSEC_PER_SEC / self.sample_rate.get() as u64;
238 let duration2 = other.samples.get() as u64 * time::MSEC_PER_SEC / other.sample_rate.get() as u64;
239 duration1 == duration2
240 }
241}
242
243impl From<AudioFrameDescriptor> for FrameDescriptor {
244 fn from(desc: AudioFrameDescriptor) -> Self {
245 FrameDescriptor::Audio(desc)
246 }
247}
248
249impl TryFrom<FrameDescriptor> for AudioFrameDescriptor {
250 type Error = Error;
251
252 fn try_from(value: FrameDescriptor) -> Result<Self> {
253 match value {
254 FrameDescriptor::Audio(desc) => Ok(desc),
255 _ => Err(invalid_param_error!(value)),
256 }
257 }
258}
259
260impl FrameDescriptorSpec for AudioFrameDescriptor {
261 fn media_type(&self) -> crate::MediaType {
262 MediaType::Audio
263 }
264
265 fn create_frame(&self) -> Result<Frame<'static, Self>> {
266 AudioFrame::new_with_descriptor(self.clone())
267 }
268
269 fn as_audio(&self) -> Option<&AudioFrameDescriptor> {
270 Some(self)
271 }
272}