1use std::io;
2
3use byteorder::ReadBytesExt;
4use bytes::Bytes;
5use nutype_enum::nutype_enum;
6use scuffle_bytes_util::BytesCursorExt;
7
8use super::aac::{AacPacket, AacPacketType};
9
10#[derive(Debug, Clone, PartialEq)]
18pub struct AudioData {
19 pub sound_rate: SoundRate,
21 pub sound_size: SoundSize,
23 pub sound_type: SoundType,
25 pub body: AudioDataBody,
27}
28
29impl AudioData {
30 pub fn demux(reader: &mut io::Cursor<Bytes>) -> io::Result<Self> {
31 let byte = reader.read_u8()?;
32 let sound_format = SoundFormat::from(byte >> 4);
34 let sound_rate = SoundRate::from((byte >> 2) & 0b11);
36 let sound_size = SoundSize::from((byte >> 1) & 0b1);
38 let sound_type = SoundType::from(byte & 0b1);
40
41 let body = AudioDataBody::demux(sound_format, reader)?;
43
44 Ok(AudioData {
45 sound_rate,
46 sound_size,
47 sound_type,
48 body,
49 })
50 }
51}
52
53nutype_enum! {
54 pub enum SoundFormat(u8) {
62 LinearPcmPlatformEndian = 0,
64 Adpcm = 1,
66 Mp3 = 2,
68 LinearPcmLittleEndian = 3,
70 Nellymoser16KhzMono = 4,
72 Nellymoser8KhzMono = 5,
74 Nellymoser = 6,
76 G711ALaw = 7,
78 G711MuLaw = 8,
80 Aac = 10,
82 Speex = 11,
84 Mp38Khz = 14,
86 DeviceSpecificSound = 15,
88 }
89}
90
91#[derive(Debug, Clone, PartialEq)]
99pub enum AudioDataBody {
100 Aac(AacPacket),
102 Unknown { sound_format: SoundFormat, data: Bytes },
104}
105
106impl AudioDataBody {
107 pub fn demux(sound_format: SoundFormat, reader: &mut io::Cursor<Bytes>) -> io::Result<Self> {
111 match sound_format {
112 SoundFormat::Aac => {
113 let aac_packet_type = AacPacketType::from(reader.read_u8()?);
116 Ok(Self::Aac(AacPacket::new(aac_packet_type, reader.extract_remaining())))
117 }
118 _ => Ok(Self::Unknown {
119 sound_format,
120 data: reader.extract_remaining(),
121 }),
122 }
123 }
124}
125
126nutype_enum! {
127 pub enum SoundRate(u8) {
135 Hz5500 = 0,
137 Hz11000 = 1,
139 Hz22000 = 2,
141 Hz44000 = 3,
143 }
144}
145
146nutype_enum! {
147 pub enum SoundSize(u8) {
155 Bit8 = 0,
157 Bit16 = 1,
159 }
160}
161
162nutype_enum! {
163 pub enum SoundType(u8) {
171 Mono = 0,
173 Stereo = 1,
175 }
176}
177
178#[cfg(test)]
179#[cfg_attr(all(test, coverage_nightly), coverage(off))]
180mod tests {
181 use super::*;
182
183 #[test]
184 fn test_sound_format() {
185 let cases = [
186 (
187 0x00,
188 SoundFormat::LinearPcmPlatformEndian,
189 "SoundFormat::LinearPcmPlatformEndian",
190 ),
191 (0x01, SoundFormat::Adpcm, "SoundFormat::Adpcm"),
192 (0x02, SoundFormat::Mp3, "SoundFormat::Mp3"),
193 (0x03, SoundFormat::LinearPcmLittleEndian, "SoundFormat::LinearPcmLittleEndian"),
194 (0x04, SoundFormat::Nellymoser16KhzMono, "SoundFormat::Nellymoser16KhzMono"),
195 (0x05, SoundFormat::Nellymoser8KhzMono, "SoundFormat::Nellymoser8KhzMono"),
196 (0x06, SoundFormat::Nellymoser, "SoundFormat::Nellymoser"),
197 (0x07, SoundFormat::G711ALaw, "SoundFormat::G711ALaw"),
198 (0x08, SoundFormat::G711MuLaw, "SoundFormat::G711MuLaw"),
199 (0x0A, SoundFormat::Aac, "SoundFormat::Aac"),
200 (0x0B, SoundFormat::Speex, "SoundFormat::Speex"),
201 (0x0E, SoundFormat::Mp38Khz, "SoundFormat::Mp38Khz"),
202 (0x0F, SoundFormat::DeviceSpecificSound, "SoundFormat::DeviceSpecificSound"),
203 ];
204
205 for (value, expected, name) in cases {
206 let sound_format = SoundFormat::from(value);
207 assert_eq!(sound_format, expected);
208 assert_eq!(format!("{:?}", sound_format), name);
209 }
210 }
211
212 #[test]
213 fn test_sound_rate() {
214 let cases = [
215 (0x00, SoundRate::Hz5500, "SoundRate::Hz5500"),
216 (0x01, SoundRate::Hz11000, "SoundRate::Hz11000"),
217 (0x02, SoundRate::Hz22000, "SoundRate::Hz22000"),
218 (0x03, SoundRate::Hz44000, "SoundRate::Hz44000"),
219 ];
220
221 for (value, expected, name) in cases {
222 let sound_rate = SoundRate::from(value);
223 assert_eq!(sound_rate, expected);
224 assert_eq!(format!("{:?}", sound_rate), name);
225 }
226 }
227
228 #[test]
229 fn test_sound_size() {
230 let cases = [
231 (0x00, SoundSize::Bit8, "SoundSize::Bit8"),
232 (0x01, SoundSize::Bit16, "SoundSize::Bit16"),
233 ];
234
235 for (value, expected, name) in cases {
236 let sound_size = SoundSize::from(value);
237 assert_eq!(sound_size, expected);
238 assert_eq!(format!("{:?}", sound_size), name);
239 }
240 }
241
242 #[test]
243 fn test_sound_type() {
244 let cases = [
245 (0x00, SoundType::Mono, "SoundType::Mono"),
246 (0x01, SoundType::Stereo, "SoundType::Stereo"),
247 ];
248
249 for (value, expected, name) in cases {
250 let sound_type = SoundType::from(value);
251 assert_eq!(sound_type, expected);
252 assert_eq!(format!("{:?}", sound_type), name);
253 }
254 }
255
256 #[test]
257 fn test_audio_data_demux() {
258 let mut reader = io::Cursor::new(Bytes::from(vec![0b10101101, 0b00000000, 1, 2, 3]));
259
260 let audio_data = AudioData::demux(&mut reader).unwrap();
261 assert_eq!(audio_data.sound_rate, SoundRate::Hz44000);
262 assert_eq!(audio_data.sound_size, SoundSize::Bit8);
263 assert_eq!(audio_data.sound_type, SoundType::Stereo);
264 assert_eq!(
265 audio_data.body,
266 AudioDataBody::Aac(AacPacket::SequenceHeader(Bytes::from(vec![1, 2, 3])))
267 );
268
269 let mut reader = io::Cursor::new(Bytes::from(vec![0b10101101, 0b00100000, 1, 2, 3]));
270
271 let audio_data = AudioData::demux(&mut reader).unwrap();
272 assert_eq!(audio_data.sound_rate, SoundRate::Hz44000);
273 assert_eq!(audio_data.sound_size, SoundSize::Bit8);
274 assert_eq!(audio_data.sound_type, SoundType::Stereo);
275 assert_eq!(
276 audio_data.body,
277 AudioDataBody::Aac(AacPacket::Unknown {
278 aac_packet_type: AacPacketType(0b00100000),
279 data: Bytes::from(vec![1, 2, 3])
280 })
281 );
282
283 let mut reader = io::Cursor::new(Bytes::from(vec![0b10001101, 0b00000000, 1, 2, 3]));
284
285 let audio_data = AudioData::demux(&mut reader).unwrap();
286 assert_eq!(
287 audio_data.body,
288 AudioDataBody::Unknown {
289 sound_format: SoundFormat(8),
290 data: Bytes::from(vec![0, 1, 2, 3])
291 }
292 );
293 }
294}