1#![allow(clippy::needless_range_loop)]
2
3mod aht;
4mod aht_tables;
5mod bits;
6mod block;
7mod eac3;
8mod header;
9mod imdct;
10mod tables;
11
12pub use header::frame_len;
13
14use bits::Bits;
15use block::{CHANNELS, LFE, State};
16use header::{Header, Kind};
17use imdct::Imdct;
18
19use crate::media::{AudioBuffer, Error, Packet, Result};
20
21const K: f32 = std::f32::consts::FRAC_1_SQRT_2;
22const MAX_SAMPLES: usize = 1536;
23
24const SL: usize = 6;
25const SR: usize = 7;
26const BL: usize = 4;
27const BR: usize = 5;
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq)]
30pub struct Info {
31 pub rate: u32,
32 pub channels: u16,
33 pub eac3: bool,
34}
35
36pub fn info(frame: &[u8]) -> Result<Info> {
37 let h = header::parse(frame)?;
38 Ok(Info {
39 rate: h.rate,
40 channels: h.nchans() as u16,
41 eac3: h.eac3,
42 })
43}
44
45pub fn layout(channels: u16) -> u16 {
46 match channels {
47 0 | 1 => 1,
48 2 => 2,
49 3..=6 => 6,
50 _ => 8,
51 }
52}
53
54fn locations(acmod: u8, lfeon: bool) -> ([u8; 6], usize) {
55 let (front, n): ([u8; 5], usize) = match acmod {
56 0 | 2 => ([0, 2, 0, 0, 0], 2),
57 1 => ([1, 0, 0, 0, 0], 1),
58 3 => ([0, 1, 2, 0, 0], 3),
59 4 => ([0, 2, 16, 0, 0], 3),
60 5 => ([0, 1, 2, 16, 0], 4),
61 6 => ([0, 2, 3, 4, 0], 4),
62 _ => ([0, 1, 2, 3, 4], 5),
63 };
64 let mut out = [0u8; 6];
65 out[..5].copy_from_slice(&front);
66 if lfeon {
67 out[n] = 15;
68 }
69 (out, n + lfeon as usize)
70}
71
72fn chanmap_locations(map: u16, n: usize) -> Option<[u8; 16]> {
73 let mut out = [0u8; 16];
74 let mut k = 0;
75 for bit in 0..16u8 {
76 if map & (0x8000 >> bit) == 0 {
77 continue;
78 }
79 let pair = matches!(bit, 5 | 6 | 9 | 10 | 11 | 13);
80 for side in 0..1 + pair as u8 {
81 if k >= 16 {
82 return None;
83 }
84 out[k] = bit | (side << 5);
85 k += 1;
86 }
87 }
88 (k == n).then_some(out)
89}
90
91fn slots(loc: u8) -> &'static [(usize, f32)] {
92 let right = loc & 0x20 != 0;
93 match (loc & 0x1F, right) {
94 (0, _) => &[(0, 1.0)],
95 (1, _) => &[(2, 1.0)],
96 (2, _) => &[(1, 1.0)],
97 (3, _) => &[(SL, 1.0)],
98 (4, _) => &[(SR, 1.0)],
99 (5, false) => &[(0, K), (2, K)],
100 (5, true) => &[(1, K), (2, K)],
101 (6, false) => &[(BL, 1.0)],
102 (6, true) => &[(BR, 1.0)],
103 (7, _) => &[(BL, K), (BR, K)],
104 (8, _) => &[(SL, 0.5), (SR, 0.5)],
105 (9, false) => &[(SL, 1.0)],
106 (9, true) => &[(SR, 1.0)],
107 (10, false) => &[(0, 1.0)],
108 (10, true) => &[(1, 1.0)],
109 (11, false) => &[(0, K)],
110 (11, true) => &[(1, K)],
111 (12, _) => &[(2, K)],
112 (13, false) => &[(SL, K)],
113 (13, true) => &[(SR, K)],
114 (16, _) => &[(SL, K), (SR, K)],
115 _ => &[(3, 1.0)],
116 }
117}
118
119struct Sub {
120 state: State,
121 pcm: Box<[[f32; MAX_SAMPLES]; CHANNELS]>,
122 order: [usize; 6],
123 locs: [u8; 16],
124 n: usize,
125 samples: usize,
126 live: bool,
127}
128
129impl Sub {
130 fn new() -> Sub {
131 Sub {
132 state: State::new(),
133 pcm: Box::new([[0.0; MAX_SAMPLES]; CHANNELS]),
134 order: [0; 6],
135 locs: [0; 16],
136 n: 0,
137 samples: 0,
138 live: false,
139 }
140 }
141}
142
143pub struct Decoder {
144 rate: u32,
145 channels: u16,
146 imdct: Imdct,
147 subs: Vec<Sub>,
148 time: Box<[[[f32; 512]; CHANNELS]; 6]>,
149 slots: Box<[[f32; MAX_SAMPLES]; 8]>,
150 nodither: bool,
151}
152
153impl Decoder {
154 pub fn new(rate: u32, channels: u16) -> Decoder {
155 Decoder {
156 rate,
157 channels: layout(channels),
158 imdct: Imdct::new(),
159 subs: Vec::new(),
160 time: Box::new([[[0.0; 512]; CHANNELS]; 6]),
161 slots: Box::new([[0.0; MAX_SAMPLES]; 8]),
162 nodither: false,
163 }
164 }
165
166 pub fn rate(&self) -> u32 {
167 self.rate
168 }
169
170 pub fn channels(&self) -> u16 {
171 self.channels
172 }
173
174 pub fn reset(&mut self) {
175 self.subs.clear();
176 }
177
178 #[cfg(test)]
179 pub(crate) fn without_dither(mut self) -> Decoder {
180 self.nodither = true;
181 self
182 }
183
184 #[cfg(test)]
185 pub(crate) fn holes(&mut self) -> Vec<usize> {
186 self.subs
187 .first_mut()
188 .map(|s| std::mem::take(&mut s.state.holes))
189 .unwrap_or_default()
190 }
191
192 #[cfg(test)]
193 pub(crate) fn marks(&mut self) -> Vec<usize> {
194 self.subs
195 .first_mut()
196 .map(|s| std::mem::take(&mut s.state.marks))
197 .unwrap_or_default()
198 }
199
200 pub fn decode(&mut self, packet: &Packet) -> Result<AudioBuffer> {
201 self.decode_frame(&packet.data)
202 }
203
204 pub fn decode_frame(&mut self, data: &[u8]) -> Result<AudioBuffer> {
205 let mut out = AudioBuffer::new(self.rate, self.channels);
206 self.decode_into(data, &mut out.samples)?;
207 Ok(out)
208 }
209
210 pub fn decode_into(&mut self, data: &[u8], out: &mut Vec<f32>) -> Result<()> {
211 out.clear();
212 let mut pos = 0;
213 let mut open = false;
214 while data.len() - pos >= 6 {
215 let rest = &data[pos..];
216 let h = header::parse(rest)?;
217 let frame = rest.get(..h.bytes).ok_or_else(|| {
218 Error::Invalid(format!(
219 "AC-3 frame of {} bytes in {} remaining",
220 h.bytes,
221 rest.len()
222 ))
223 })?;
224 pos += h.bytes;
225 let slot = match (h.kind, h.substream) {
226 (Kind::Independent | Kind::Convert, 0) => 0,
227 (Kind::Dependent, k) if open => 1 + k as usize,
228 _ => continue,
229 };
230 if slot == 0 {
231 if open {
232 self.render(out);
233 }
234 for s in self.subs.iter_mut() {
235 s.live = false;
236 }
237 self.rate = h.rate;
238 open = true;
239 }
240 while self.subs.len() <= slot {
241 self.subs.push(Sub::new());
242 }
243 if let Err(e) = self.substream(slot, &h, frame) {
244 self.subs[slot] = Sub::new();
245 return Err(e);
246 }
247 }
248 if !open {
249 return Err(Error::Invalid(
250 "AC-3 packet without an independent frame".into(),
251 ));
252 }
253 self.render(out);
254 Ok(())
255 }
256
257 fn substream(&mut self, slot: usize, h: &Header, frame: &[u8]) -> Result<()> {
258 let samples = h.blocks * 256;
259 if slot > 0 && self.subs[0].samples != samples {
260 return Err(Error::Invalid(
261 "E-AC-3 dependent frame with a different block count".into(),
262 ));
263 }
264 let sub = &mut self.subs[slot];
265 sub.state.nodither = self.nodither;
266 let mut b = Bits::new(frame);
267 b.skip(h.bits)?;
268 if h.eac3 {
269 eac3::decode(&mut sub.state, &mut b, h)?;
270 } else {
271 for blk in 0..6 {
272 sub.state.blk = blk;
273 block::read_block_ac3(&mut sub.state, &mut b, h, blk)?;
274 block::dsp(&mut sub.state, h.nfchans, h.acmod);
275 sub.state.mark(h.nfchans, h.lfeon);
276 }
277 }
278 let chans: Vec<usize> = (0..h.nfchans).chain(h.lfeon.then_some(LFE)).collect();
279 let mut spec = Vec::with_capacity(36);
280 let mut short = Vec::with_capacity(36);
281 let mut time = Vec::with_capacity(36);
282 for (blk, t) in self.time.iter_mut().enumerate().take(h.blocks) {
283 for (ch, t) in t.iter_mut().enumerate() {
284 if chans.contains(&ch) {
285 spec.push(&sub.state.spec[blk][ch]);
286 short.push(sub.state.short[blk][ch]);
287 time.push(t);
288 }
289 }
290 }
291 self.imdct.run(&spec, &short, &mut time);
292 for &ch in &chans {
293 for blk in 0..h.blocks {
294 let c = &mut sub.state.ch[ch];
295 self.imdct.overlap(
296 &self.time[blk][ch],
297 &mut c.delay,
298 sub.state.gain[blk][ch],
299 &mut sub.pcm[ch][blk * 256..blk * 256 + 256],
300 );
301 }
302 }
303 let (locs, n) = locations(h.acmod, h.lfeon);
304 sub.order = std::array::from_fn(|i| chans.get(i).copied().unwrap_or(0));
305 sub.n = n;
306 sub.locs = [0; 16];
307 match h.chanmap.filter(|_| slot > 0) {
308 Some(map) => {
309 sub.locs = chanmap_locations(map, n).ok_or_else(|| {
310 Error::Invalid("E-AC-3 channel map does not match its channels".into())
311 })?;
312 }
313 None => sub.locs[..6].copy_from_slice(&locs),
314 }
315 sub.samples = samples;
316 sub.live = true;
317 Ok(())
318 }
319
320 fn render(&mut self, out: &mut Vec<f32>) {
321 let Some(main) = self.subs.first() else {
322 return;
323 };
324 let samples = main.samples;
325 let mut sources: Vec<(u8, usize, usize)> = (0..main.n)
326 .map(|i| (main.locs[i], 0, main.order[i]))
327 .collect();
328 for (k, sub) in self.subs.iter().enumerate().skip(1) {
329 if !sub.live || sub.samples != samples {
330 continue;
331 }
332 for i in 0..sub.n.min(6) {
333 let src = (sub.locs[i], k, sub.order[i]);
334 match sources.iter_mut().find(|s| s.0 == src.0) {
335 Some(s) => *s = src,
336 None => sources.push(src),
337 }
338 }
339 }
340 let only_center = sources.iter().all(|s| s.0 == 1 || s.0 == 15);
341 for s in self.slots.iter_mut() {
342 s[..samples].fill(0.0);
343 }
344 for &(loc, k, ch) in &sources {
345 let pcm = &self.subs[k].pcm[ch];
346 for &(slot, g) in slots(loc) {
347 for (o, &v) in self.slots[slot][..samples].iter_mut().zip(&pcm[..samples]) {
348 *o += v * g;
349 }
350 }
351 }
352 let s = &self.slots;
353 let n = self.channels as usize;
354 let base = out.len();
355 out.resize(base + samples * n, 0.0);
356 let dst = &mut out[base..];
357 match n {
358 8 => {
359 for (i, f) in dst.chunks_exact_mut(8).enumerate() {
360 for (c, v) in f.iter_mut().enumerate() {
361 *v = s[c][i];
362 }
363 }
364 }
365 6 => {
366 for (i, f) in dst.chunks_exact_mut(6).enumerate() {
367 f[0] = s[0][i];
368 f[1] = s[1][i];
369 f[2] = s[2][i];
370 f[3] = s[3][i];
371 f[4] = s[SL][i] + K * s[BL][i];
372 f[5] = s[SR][i] + K * s[BR][i];
373 }
374 }
375 _ if only_center => {
376 for (i, f) in dst.chunks_exact_mut(n).enumerate() {
377 f.fill(s[2][i]);
378 }
379 }
380 2 => {
381 for (i, f) in dst.chunks_exact_mut(2).enumerate() {
382 let c = K * s[2][i];
383 f[0] = s[0][i] + c + K * (s[SL][i] + s[BL][i]);
384 f[1] = s[1][i] + c + K * (s[SR][i] + s[BR][i]);
385 }
386 }
387 _ => {
388 for (i, v) in dst.iter_mut().enumerate() {
389 let c = K * s[2][i];
390 let l = s[0][i] + c + K * (s[SL][i] + s[BL][i]);
391 let r = s[1][i] + c + K * (s[SR][i] + s[BR][i]);
392 *v = 0.5 * (l + r);
393 }
394 }
395 }
396 }
397}
398
399#[cfg(test)]
400mod tests;