1use std::{
2 iter,
3 num::{NonZeroU32, NonZeroU8},
4};
5
6use crate::{
7 base::time,
8 media_frame::{MemoryPlanes, PlaneInformation},
9};
10
11pub const SAMPLE_RATE_TELEPHONE: u32 = 8000;
12pub const SAMPLE_RATE_VOIP: u32 = 16000;
13pub const SAMPLE_RATE_CD: u32 = 44100;
14pub const SAMPLE_RATE_DVD: u32 = 48000;
15pub const SAMPLE_RATE_HIGH: u32 = 96000;
16pub const SAMPLE_RATE_ULTRA_HIGH: u32 = 192000;
17
18#[derive(Clone, Copy, Debug, PartialEq)]
19pub enum AudioFormat {
20 U8 = 0, S16, S32, F32, F64, U8P, S16P, S32P, F32P, F64P, MAX,
31}
32
33#[derive(Clone, Debug, PartialEq)]
34pub struct AudioFrameDescription {
35 pub format: AudioFormat,
36 pub channels: NonZeroU8,
37 pub samples: NonZeroU32,
38 pub sample_rate: NonZeroU32,
39}
40
41impl AudioFrameDescription {
42 pub fn new(format: AudioFormat, channels: NonZeroU8, samples: NonZeroU32, sample_rate: NonZeroU32) -> Self {
43 Self {
44 format,
45 channels,
46 samples,
47 sample_rate,
48 }
49 }
50
51 pub fn duration_equal(&self, other: &AudioFrameDescription) -> bool {
52 let duration1 = self.samples.get() as u64 * time::MSEC_PER_SEC / self.sample_rate.get() as u64;
53 let duration2 = other.samples.get() as u64 * time::MSEC_PER_SEC / other.sample_rate.get() as u64;
54 duration1 == duration2
55 }
56}
57
58struct AudioFormatInfo {
59 pub bits: u8,
60 pub is_planar: bool,
61}
62
63static AUDIO_FORMAT_INFO: [AudioFormatInfo; AudioFormat::MAX as usize] = [
64 AudioFormatInfo {
66 bits: 8,
67 is_planar: false,
68 },
69 AudioFormatInfo {
71 bits: 16,
72 is_planar: false,
73 },
74 AudioFormatInfo {
76 bits: 32,
77 is_planar: false,
78 },
79 AudioFormatInfo {
81 bits: 32,
82 is_planar: false,
83 },
84 AudioFormatInfo {
86 bits: 64,
87 is_planar: false,
88 },
89 AudioFormatInfo {
91 bits: 8,
92 is_planar: true,
93 },
94 AudioFormatInfo {
96 bits: 16,
97 is_planar: true,
98 },
99 AudioFormatInfo {
101 bits: 32,
102 is_planar: true,
103 },
104 AudioFormatInfo {
106 bits: 32,
107 is_planar: true,
108 },
109 AudioFormatInfo {
111 bits: 64,
112 is_planar: true,
113 },
114];
115
116impl AudioFormat {
117 pub fn bits(&self) -> u8 {
118 AUDIO_FORMAT_INFO[*self as usize].bits
119 }
120
121 pub fn bytes(&self) -> u8 {
122 self.bits() >> 3
123 }
124
125 pub fn data_calc(&self, channels: u8, samples: u32) -> (u32, MemoryPlanes) {
126 let mut size = 0;
127 let mut planes = MemoryPlanes::new();
128 let stride = self.stride(channels, samples);
129
130 if self.is_planar() {
131 planes.extend(iter::repeat(PlaneInformation::Audio(stride)).take(channels as usize));
132 size += stride * channels as u32;
133 } else {
134 planes.push(PlaneInformation::Audio(stride));
135 size = stride;
136 }
137
138 (size, planes)
139 }
140
141 pub fn is_planar(&self) -> bool {
142 AUDIO_FORMAT_INFO[*self as usize].is_planar
143 }
144
145 pub fn stride(&self, channels: u8, samples: u32) -> u32 {
146 if self.is_planar() {
147 self.bytes() as u32 * samples
148 } else {
149 self.bytes() as u32 * channels as u32 * samples
150 }
151 }
152}