scuffle_flv/audio/header/
legacy.rs1use std::io;
4
5use byteorder::ReadBytesExt;
6use bytes::Bytes;
7use nutype_enum::nutype_enum;
8
9use crate::error::FlvError;
10
11nutype_enum! {
12 pub enum SoundFormat(u8) {
19 LinearPcmPlatformEndian = 0,
21 Adpcm = 1,
23 Mp3 = 2,
25 LinearPcmLittleEndian = 3,
27 Nellymoser16KhzMono = 4,
29 Nellymoser8KhzMono = 5,
31 Nellymoser = 6,
33 G711ALaw = 7,
35 G711MuLaw = 8,
37 ExHeader = 9,
41 Aac = 10,
43 Speex = 11,
45 Mp38Khz = 14,
47 DeviceSpecificSound = 15,
49 }
50}
51
52nutype_enum! {
53 pub enum SoundRate(u8) {
60 Hz5500 = 0,
62 Hz11000 = 1,
64 Hz22000 = 2,
66 Hz44000 = 3,
68 }
69}
70
71nutype_enum! {
72 pub enum SoundSize(u8) {
81 Bit8 = 0,
83 Bit16 = 1,
85 }
86}
87
88nutype_enum! {
89 pub enum SoundType(u8) {
96 Mono = 0,
98 Stereo = 1,
100 }
101}
102
103#[derive(Debug, Clone, PartialEq)]
108pub struct LegacyAudioTagHeader {
109 pub sound_format: SoundFormat,
111 pub sound_rate: SoundRate,
113 pub sound_size: SoundSize,
115 pub sound_type: SoundType,
117}
118
119impl LegacyAudioTagHeader {
120 #[allow(clippy::unusual_byte_groupings)]
122 pub fn demux(reader: &mut io::Cursor<Bytes>) -> Result<Self, FlvError> {
123 let byte = reader.read_u8()?;
124
125 let sound_format = SoundFormat::from(byte >> 4); let sound_rate = SoundRate::from((byte & 0b0000_11_0_0) >> 2);
129 let sound_size = SoundSize::from((byte & 0b0000_00_1_0) >> 1);
131 let sound_type = SoundType::from(byte & 0b0000_00_0_1);
133
134 Ok(Self {
135 sound_format,
136 sound_rate,
137 sound_size,
138 sound_type,
139 })
140 }
141}
142
143#[cfg(test)]
144#[cfg_attr(all(test, coverage_nightly), coverage(off))]
145mod tests {
146 use super::*;
147
148 #[test]
149 fn test_sound_format() {
150 let cases = [
151 (
152 0x00,
153 SoundFormat::LinearPcmPlatformEndian,
154 "SoundFormat::LinearPcmPlatformEndian",
155 ),
156 (0x01, SoundFormat::Adpcm, "SoundFormat::Adpcm"),
157 (0x02, SoundFormat::Mp3, "SoundFormat::Mp3"),
158 (0x03, SoundFormat::LinearPcmLittleEndian, "SoundFormat::LinearPcmLittleEndian"),
159 (0x04, SoundFormat::Nellymoser16KhzMono, "SoundFormat::Nellymoser16KhzMono"),
160 (0x05, SoundFormat::Nellymoser8KhzMono, "SoundFormat::Nellymoser8KhzMono"),
161 (0x06, SoundFormat::Nellymoser, "SoundFormat::Nellymoser"),
162 (0x07, SoundFormat::G711ALaw, "SoundFormat::G711ALaw"),
163 (0x08, SoundFormat::G711MuLaw, "SoundFormat::G711MuLaw"),
164 (0x0A, SoundFormat::Aac, "SoundFormat::Aac"),
165 (0x0B, SoundFormat::Speex, "SoundFormat::Speex"),
166 (0x0E, SoundFormat::Mp38Khz, "SoundFormat::Mp38Khz"),
167 (0x0F, SoundFormat::DeviceSpecificSound, "SoundFormat::DeviceSpecificSound"),
168 ];
169
170 for (value, expected, name) in cases {
171 let sound_format = SoundFormat::from(value);
172 assert_eq!(sound_format, expected);
173 assert_eq!(format!("{sound_format:?}"), name);
174 }
175 }
176
177 #[test]
178 fn test_sound_rate() {
179 let cases = [
180 (0x00, SoundRate::Hz5500, "SoundRate::Hz5500"),
181 (0x01, SoundRate::Hz11000, "SoundRate::Hz11000"),
182 (0x02, SoundRate::Hz22000, "SoundRate::Hz22000"),
183 (0x03, SoundRate::Hz44000, "SoundRate::Hz44000"),
184 ];
185
186 for (value, expected, name) in cases {
187 let sound_rate = SoundRate::from(value);
188 assert_eq!(sound_rate, expected);
189 assert_eq!(format!("{sound_rate:?}"), name);
190 }
191 }
192
193 #[test]
194 fn test_sound_size() {
195 let cases = [
196 (0x00, SoundSize::Bit8, "SoundSize::Bit8"),
197 (0x01, SoundSize::Bit16, "SoundSize::Bit16"),
198 ];
199
200 for (value, expected, name) in cases {
201 let sound_size = SoundSize::from(value);
202 assert_eq!(sound_size, expected);
203 assert_eq!(format!("{sound_size:?}"), name);
204 }
205 }
206
207 #[test]
208 fn test_sound_type() {
209 let cases = [
210 (0x00, SoundType::Mono, "SoundType::Mono"),
211 (0x01, SoundType::Stereo, "SoundType::Stereo"),
212 ];
213
214 for (value, expected, name) in cases {
215 let sound_type = SoundType::from(value);
216 assert_eq!(sound_type, expected);
217 assert_eq!(format!("{sound_type:?}"), name);
218 }
219 }
220}