1use crate::media::Error;
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq)]
4pub enum Mode {
5 SilkOnly,
6 Hybrid,
7 CeltOnly,
8}
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
11pub enum Bandwidth {
12 Narrowband,
13 Mediumband,
14 Wideband,
15 SuperWideband,
16 Fullband,
17}
18
19impl Bandwidth {
20 pub fn celt_end_band(self) -> usize {
21 match self {
22 Bandwidth::Narrowband => 13,
23 Bandwidth::Mediumband | Bandwidth::Wideband => 17,
24 Bandwidth::SuperWideband => 19,
25 Bandwidth::Fullband => 21,
26 }
27 }
28}
29
30#[derive(Clone, Copy, Debug, PartialEq, Eq)]
31pub struct Toc {
32 pub config: u8,
33 pub mode: Mode,
34 pub bandwidth: Bandwidth,
35 pub stereo: bool,
36 pub code: u8,
37}
38
39impl Toc {
40 pub fn parse(b: u8) -> Toc {
41 let config = b >> 3;
42 let (mode, bandwidth) = match config {
43 0..=3 => (Mode::SilkOnly, Bandwidth::Narrowband),
44 4..=7 => (Mode::SilkOnly, Bandwidth::Mediumband),
45 8..=11 => (Mode::SilkOnly, Bandwidth::Wideband),
46 12..=13 => (Mode::Hybrid, Bandwidth::SuperWideband),
47 14..=15 => (Mode::Hybrid, Bandwidth::Fullband),
48 16..=19 => (Mode::CeltOnly, Bandwidth::Narrowband),
49 20..=23 => (Mode::CeltOnly, Bandwidth::Wideband),
50 24..=27 => (Mode::CeltOnly, Bandwidth::SuperWideband),
51 _ => (Mode::CeltOnly, Bandwidth::Fullband),
52 };
53 Toc {
54 config,
55 mode,
56 bandwidth,
57 stereo: b & 4 != 0,
58 code: b & 3,
59 }
60 }
61
62 pub fn frame_samples_48k(&self) -> usize {
63 self.frame_samples(48000)
64 }
65
66 pub fn frame_samples(&self, rate: u32) -> usize {
67 let rate = rate as usize;
68 let c = self.config as usize;
69 match self.mode {
70 Mode::CeltOnly => (rate << (c & 3)) / 400,
71 Mode::Hybrid => {
72 if c & 1 != 0 {
73 rate / 50
74 } else {
75 rate / 100
76 }
77 }
78 Mode::SilkOnly => match c & 3 {
79 3 => rate * 60 / 1000,
80 s => (rate << s) / 100,
81 },
82 }
83 }
84
85 pub fn channels(&self) -> usize {
86 if self.stereo { 2 } else { 1 }
87 }
88}
89
90#[derive(Clone, Debug)]
91pub struct Packet<'a> {
92 pub toc: Toc,
93 pub frames: Vec<&'a [u8]>,
94 pub padding: usize,
95}
96
97fn parse_size(data: &[u8]) -> Option<(usize, usize)> {
98 match data.first() {
99 None => None,
100 Some(&b) if b < 252 => Some((b as usize, 1)),
101 Some(&b) => data.get(1).map(|&b1| (4 * b1 as usize + b as usize, 2)),
102 }
103}
104
105impl<'a> Packet<'a> {
106 pub fn parse(data: &'a [u8]) -> Result<Packet<'a>, Error> {
107 Self::parse_impl(data, false).map(|(p, _)| p)
108 }
109
110 pub fn parse_self_delimited(data: &'a [u8]) -> Result<(Packet<'a>, usize), Error> {
111 Self::parse_impl(data, true)
112 }
113
114 fn parse_impl(data: &'a [u8], self_delimited: bool) -> Result<(Packet<'a>, usize), Error> {
115 let bad = || Error::Invalid("malformed packet framing".into());
116 if data.is_empty() {
117 return Err(Error::Invalid("empty packet".into()));
118 }
119 let toc = Toc::parse(data[0]);
120 let fs = toc.frame_samples_48k();
121 let mut pos = 1usize;
122 let mut len = data.len() as isize - 1;
123 let mut sizes: Vec<isize> = Vec::new();
124 let mut padding = 0usize;
125 let mut cbr = false;
126 let count;
127 let mut last_size = len;
128 let read_size = |pos: &mut usize, len: &mut isize| -> Result<isize, Error> {
129 let avail = &data[*pos..(*pos + (*len).max(0) as usize).min(data.len())];
130 let (s, n) = parse_size(avail).ok_or_else(bad)?;
131 *pos += n;
132 *len -= n as isize;
133 Ok(s as isize)
134 };
135 match toc.code {
136 0 => count = 1,
137 1 => {
138 count = 2;
139 cbr = true;
140 if !self_delimited {
141 if len & 1 != 0 {
142 return Err(bad());
143 }
144 last_size = len / 2;
145 sizes.push(last_size);
146 }
147 }
148 2 => {
149 count = 2;
150 let s0 = read_size(&mut pos, &mut len)?;
151 if s0 > len {
152 return Err(bad());
153 }
154 sizes.push(s0);
155 last_size = len - s0;
156 }
157 _ => {
158 if len < 1 {
159 return Err(bad());
160 }
161 let ch = data[pos];
162 pos += 1;
163 len -= 1;
164 count = (ch & 0x3F) as usize;
165 if count == 0 || fs * count > 5760 {
166 return Err(bad());
167 }
168 if ch & 0x40 != 0 {
169 loop {
170 if len <= 0 {
171 return Err(bad());
172 }
173 let b = data[pos];
174 pos += 1;
175 len -= 1;
176 let tmp = if b == 255 { 254 } else { b as isize };
177 len -= tmp;
178 padding += tmp as usize;
179 if b != 255 {
180 break;
181 }
182 }
183 }
184 if len < 0 {
185 return Err(bad());
186 }
187 cbr = ch & 0x80 == 0;
188 if !cbr {
189 last_size = len;
190 for _ in 0..count - 1 {
191 let before = len;
192 let s = read_size(&mut pos, &mut len)?;
193 if s > len {
194 return Err(bad());
195 }
196 sizes.push(s);
197 last_size -= (before - len) + s;
198 }
199 if last_size < 0 {
200 return Err(bad());
201 }
202 } else if !self_delimited {
203 last_size = len / count as isize;
204 if last_size * count as isize != len {
205 return Err(bad());
206 }
207 for _ in 0..count - 1 {
208 sizes.push(last_size);
209 }
210 }
211 }
212 }
213 if self_delimited {
214 let before = len;
215 let s = read_size(&mut pos, &mut len)?;
216 if s > len {
217 return Err(bad());
218 }
219 if cbr {
220 if s * count as isize > len {
221 return Err(bad());
222 }
223 sizes = vec![s; count - 1];
224 } else if (before - len) + s > last_size {
225 return Err(bad());
226 }
227 last_size = s;
228 }
229 if last_size > 1275 || sizes.iter().any(|&s| s > 1275) {
230 return Err(bad());
231 }
232 sizes.push(last_size);
233 let mut frames = Vec::with_capacity(count);
234 for &s in &sizes {
235 let s = s as usize;
236 if pos + s > data.len() {
237 return Err(bad());
238 }
239 frames.push(&data[pos..pos + s]);
240 pos += s;
241 }
242 let total = if self_delimited {
243 pos + padding
244 } else {
245 data.len()
246 };
247 if total > data.len() {
248 return Err(bad());
249 }
250 Ok((
251 Packet {
252 toc,
253 frames,
254 padding,
255 },
256 total,
257 ))
258 }
259}
260
261pub fn packet_samples_48k(data: &[u8]) -> Result<usize, Error> {
262 let p = Packet::parse(data)?;
263 Ok(p.toc.frame_samples_48k() * p.frames.len())
264}
265
266#[cfg(test)]
267mod tests {
268 use super::*;
269
270 #[test]
271 fn toc_configs() {
272 for cfg in 0u8..32 {
273 let t = Toc::parse(cfg << 3);
274 let ms10 = t.frame_samples(48000) * 10 / 48;
275 let expect = match cfg {
276 0..=11 => [100, 200, 400, 600][cfg as usize & 3],
277 12..=15 => [100, 200][cfg as usize & 1],
278 _ => [25, 50, 100, 200][cfg as usize & 3],
279 };
280 assert_eq!(ms10, expect, "config {cfg}");
281 }
282 assert!(Toc::parse(0x04).stereo);
283 }
284
285 #[test]
286 fn frame_codes() {
287 let p = Packet::parse(&[0x00, 1, 2, 3]).unwrap();
288 assert_eq!(p.frames, vec![&[1u8, 2, 3][..]]);
289 assert!(Packet::parse(&[0x01, 1, 2, 3]).is_err());
290 let p = Packet::parse(&[0x01, 1, 2, 3, 4]).unwrap();
291 assert_eq!(p.frames.len(), 2);
292 let p = Packet::parse(&[0x02, 1, 9, 8, 7]).unwrap();
293 assert_eq!(p.frames, vec![&[9u8][..], &[8u8, 7][..]]);
294 assert!(Packet::parse(&[0x02, 5, 1]).is_err());
295 let p = Packet::parse(&[0x03, 0x42, 3, 1, 2, 3, 4, 0, 0, 0]).unwrap();
296 assert_eq!(p.frames, vec![&[1u8, 2][..], &[3u8, 4][..]]);
297 assert_eq!(p.padding, 3);
298 let p = Packet::parse(&[0x03, 0x83, 1, 2, 10, 20, 21, 30]).unwrap();
299 assert_eq!(p.frames, vec![&[10u8][..], &[20u8, 21][..], &[30u8][..]]);
300 assert!(Packet::parse(&[0x03 | (3 << 3), 0x03, 0]).is_err());
301 assert!(Packet::parse(&[0x03, 0x00]).is_err());
302 assert!(Packet::parse(&[]).is_err());
303 }
304
305 #[test]
306 fn two_byte_sizes() {
307 let mut pkt = vec![0x02u8, 252, 1];
308 pkt.extend(std::iter::repeat_n(7u8, 256));
309 pkt.extend([1, 2]);
310 let p = Packet::parse(&pkt).unwrap();
311 assert_eq!(p.frames[0].len(), 256);
312 assert_eq!(p.frames[1], &[1, 2]);
313 }
314
315 #[test]
316 fn self_delimited() {
317 let (p, used) = Packet::parse_self_delimited(&[0x00, 2, 5, 6, 0xAA, 0xBB]).unwrap();
318 assert_eq!(p.frames, vec![&[5u8, 6][..]]);
319 assert_eq!(used, 4);
320 let (p, used) = Packet::parse_self_delimited(&[0x01, 1, 5, 6, 9]).unwrap();
321 assert_eq!(p.frames, vec![&[5u8][..], &[6u8][..]]);
322 assert_eq!(used, 4);
323 let (p, used) = Packet::parse_self_delimited(&[0x03, 0x82, 1, 2, 7, 8, 9, 0xFF]).unwrap();
324 assert_eq!(p.frames, vec![&[7u8][..], &[8u8, 9][..]]);
325 assert_eq!(used, 7);
326 }
327}