9f7e8b6b2a09a1d6d9a5de7bafb2c2028fd8e850
[nihav.git] / nihav-llaudio / src / codecs / apepred.rs
1 const HISTORY_SIZE: usize = 512;
2
3 fn val2sign(val: i32) -> i32 {
4 if val > 0 {
5 -1
6 } else if val < 0 {
7 1
8 } else {
9 0
10 }
11 }
12
13 pub struct OldFilt {
14 version: u16,
15 compression: u16,
16 }
17
18 pub struct NewFilt {
19 version: u16,
20 filters: [NFilterContext; 3],
21 lfilt: LastFilterContext,
22 rfilt: LastFilterContext,
23 }
24
25 #[allow(clippy::large_enum_variant)]
26 pub enum FilterMode {
27 Old(OldFilt),
28 New(NewFilt),
29 None,
30 }
31
32 impl FilterMode {
33 pub fn new(version: u16, compression: u16) -> Self {
34 if version < 3930 {
35 FilterMode::Old(OldFilt::new(version, compression))
36 } else {
37 FilterMode::New(NewFilt::new(version, compression))
38 }
39 }
40 pub fn filter_mono(&mut self, l: &mut [i32]) {
41 match *self {
42 FilterMode::Old(ref mut ofilt) => ofilt.filter(l),
43 FilterMode::New(ref mut nfilt) => nfilt.filter_mono(l),
44 FilterMode::None => unreachable!(),
45 };
46 }
47 pub fn filter_stereo(&mut self, l: &mut [i32], r: &mut [i32]) {
48 match *self {
49 FilterMode::Old(ref mut ofilt) => {
50 ofilt.filter(l);
51 ofilt.filter(r);
52 for (l, r) in l.iter_mut().zip(r.iter_mut()) {
53 let new_l = *l - *r / 2;
54 let new_r = *r + new_l;
55 *l = new_l;
56 *r = new_r;
57 }
58 },
59 FilterMode::New(ref mut nfilt) => {
60 nfilt.filter_stereo(l, r);
61 for (l, r) in l.iter_mut().zip(r.iter_mut()) {
62 let new_l = *r - *l / 2;
63 let new_r = *l + new_l;
64 *l = new_l;
65 *r = new_r;
66 }
67 },
68 FilterMode::None => unreachable!(),
69 };
70 }
71 }
72
73 const NEW_FILTER_PARAMS: [[(u8, u8); 3]; 5] = [
74 [ (0, 0), ( 0, 0), ( 0, 0) ],
75 [ (1, 11), ( 0, 0), ( 0, 0) ],
76 [ (4, 11), ( 0, 0), ( 0, 0) ],
77 [ (2, 10), (16, 13), ( 0, 0) ],
78 [ (1, 11), (16, 13), (80, 15) ],
79 ];
80
81 #[derive(Clone,Default)]
82 struct NFilterContext {
83 buf: Vec<i32>,
84 coeffs: Vec<i32>,
85 order: usize,
86 bits: u8,
87 avg: i32,
88 new: bool,
89 }
90
91 fn adapt_loop(filt: &mut [i32], coeffs: &[i32], adapt: &[i32], val: i32) -> i32 {
92 let mut sum = 0i32;
93 for (coef, (res, adapt)) in filt.iter_mut().zip(coeffs.iter().zip(adapt.iter())) {
94 sum += *coef * *res;
95 if val < 0 {
96 *coef += *adapt;
97 } else if val > 0 {
98 *coef -= *adapt;
99 }
100 *coef = *coef << 16 >> 16;
101 }
102 sum
103 }
104
105 impl NFilterContext {
106 fn new(ord16: u8, bits: u8, new: bool) -> Self {
107 let order = ord16 as usize * 16;
108 Self {
109 buf: if order > 0 { vec![0; order * 2 + HISTORY_SIZE] } else { Vec::new() },
110 coeffs: vec![0; order],
111 order,
112 bits,
113 avg: 0,
114 new,
115 }
116 }
117 fn reset(&mut self) {
118 for el in self.buf[..self.order * 2].iter_mut() { *el = 0; }
119 for el in self.coeffs.iter_mut() { *el = 0; }
120 self.avg = 0;
121 }
122 fn apply(&mut self, dst: &mut [i32]) {
123 if self.order == 0 { return; }
124 let mut adapt_pos = self.order;
125 let mut delay_pos = self.order * 2;
126 for el in dst.iter_mut() {
127 let sum = adapt_loop(&mut self.coeffs,
128 &self.buf[delay_pos - self.order..],
129 &self.buf[adapt_pos - self.order..], *el);
130 let pred = (sum + (1 << (self.bits - 1))) >> self.bits;
131 let val = *el + pred;
132 *el = val;
133 self.buf[delay_pos] = val.min(32767).max(-32768);
134 if self.new {
135 let aval = val.abs();
136 let sign = val2sign(val);
137 self.buf[adapt_pos] = if aval == 0 {
138 0
139 } else if aval <= self.avg * 4 / 3 {
140 sign * 8
141 } else if aval <= self.avg * 3 {
142 sign * 16
143 } else {
144 sign * 32
145 };
146 self.avg += (aval - self.avg) / 16;
147 self.buf[adapt_pos - 1] >>= 1;
148 self.buf[adapt_pos - 2] >>= 1;
149 self.buf[adapt_pos - 8] >>= 1;
150 } else {
151 self.buf[adapt_pos] = 4 * val2sign(val);
152 self.buf[adapt_pos - 4] >>= 1;
153 self.buf[adapt_pos - 8] >>= 1;
154 }
155 delay_pos += 1;
156 adapt_pos += 1;
157 if delay_pos == HISTORY_SIZE + self.order * 2 {
158 delay_pos = self.order * 2;
159 adapt_pos = self.order;
160 for i in 0..self.order * 2 {
161 self.buf[i] = self.buf[HISTORY_SIZE + i];
162 }
163 }
164 }
165 }
166 }
167
168 #[derive(Clone,Copy,Default)]
169 struct LastFilterContext {
170 last_a: i32,
171 filter_a: i32,
172 filter_b: i32,
173 coeffs_a: [i32; 4],
174 coeffs_b: [i32; 5],
175 delay_a: [i32; 4],
176 adapt_a: [i32; 4],
177 delay_b: [i32; 5],
178 adapt_b: [i32; 5],
179 }
180
181 impl LastFilterContext {
182 fn init(&mut self) {
183 const COEFFS_A_NEW: [i32; 4] = [360, 317, -109, 98];
184
185 self.filter_a = 0;
186 self.filter_b = 0;
187 self.coeffs_a = COEFFS_A_NEW;
188 self.coeffs_b = [0; 5];
189 self.last_a = 0;
190 self.delay_a = [0; 4];
191 self.adapt_a = [0; 4];
192 self.delay_b = [0; 5];
193 self.adapt_b = [0; 5];
194 }
195 fn predict_a(&mut self) -> i32 {
196 for i in (0..3).rev() {
197 self.delay_a[i + 1] = self.delay_a[i];
198 self.adapt_a[i + 1] = self.adapt_a[i];
199 }
200 self.delay_a[0] = self.last_a;
201 self.delay_a[1] = self.last_a - self.delay_a[1];
202 self.adapt_a[0] = val2sign(self.delay_a[0]);
203 self.adapt_a[1] = val2sign(self.delay_a[1]);
204
205 self.delay_a[0] * self.coeffs_a[0] +
206 self.delay_a[1] * self.coeffs_a[1] +
207 self.delay_a[2] * self.coeffs_a[2] +
208 self.delay_a[3] * self.coeffs_a[3]
209 }
210 fn predict_b(&mut self, other_a: i32) -> i32 {
211 for i in (0..4).rev() {
212 self.delay_b[i + 1] = self.delay_b[i];
213 self.adapt_b[i + 1] = self.adapt_b[i];
214 }
215 self.delay_b[0] = other_a - ((self.filter_b * 31) >> 5);
216 self.delay_b[1] = self.delay_b[0] - self.delay_b[1];
217 self.adapt_b[0] = val2sign(self.delay_b[0]);
218 self.adapt_b[1] = val2sign(self.delay_b[1]);
219
220 self.filter_b = other_a;
221
222 (self.delay_b[0] * self.coeffs_b[0] +
223 self.delay_b[1] * self.coeffs_b[1] +
224 self.delay_b[2] * self.coeffs_b[2] +
225 self.delay_b[3] * self.coeffs_b[3] +
226 self.delay_b[4] * self.coeffs_b[4]) >> 1
227 }
228 fn update_a(&mut self, pred: i32, diff: i32) -> i32 {
229 self.last_a = diff + (pred >> 10);
230 let sign = val2sign(diff);
231 for i in 0..4 {
232 self.coeffs_a[i] += self.adapt_a[i] * sign;
233 }
234 self.filter_a = self.last_a + ((self.filter_a * 31) >> 5);
235
236 self.filter_a
237 }
238 fn update_b(&mut self, diff: i32) {
239 let sign = val2sign(diff);
240 for i in 0..5 {
241 self.coeffs_b[i] += self.adapt_b[i] * sign;
242 }
243 }
244 fn predict_3930(&mut self, diff: i32) -> i32 {
245 for i in (0..3).rev() {
246 self.delay_a[i + 1] = self.delay_a[i];
247 }
248 self.delay_a[0] = self.last_a;
249 let d0 = self.delay_a[0];
250 let d1 = self.delay_a[0] - self.delay_a[1];
251 let d2 = self.delay_a[1] - self.delay_a[2];
252 let d3 = self.delay_a[2] - self.delay_a[3];
253
254 let pred = (self.coeffs_a[0] * d0 +
255 self.coeffs_a[1] * d1 +
256 self.coeffs_a[2] * d2 +
257 self.coeffs_a[3] * d3) >> 9;
258 self.last_a = diff + pred;
259 self.filter_a = self.last_a + ((self.filter_a * 31) >> 5);
260
261 let sign = val2sign(diff);
262 self.coeffs_a[0] += if d0 < 0 { sign } else { -sign };
263 self.coeffs_a[1] += if d1 < 0 { sign } else { -sign };
264 self.coeffs_a[2] += if d2 < 0 { sign } else { -sign };
265 self.coeffs_a[3] += if d3 < 0 { sign } else { -sign };
266
267 self.filter_a
268 }
269 }
270
271 impl NewFilt {
272 fn new(version: u16, compression: u16) -> Self {
273 let cidx = (compression / 1000) as usize - 1;
274 let mut obj = Self {
275 version,
276 filters: [NFilterContext::default(), NFilterContext::default(), NFilterContext::default()],
277 lfilt: LastFilterContext::default(),
278 rfilt: LastFilterContext::default(),
279 };
280 obj.version = version;
281 let new = version >= 3980;
282 for i in 0..3 {
283 let (ord16, bits) = NEW_FILTER_PARAMS[cidx][i];
284 obj.filters[i] = NFilterContext::new(ord16, bits, new);
285 }
286 obj
287 }
288 fn filter_mono(&mut self, dst: &mut [i32]) {
289 for filt in self.filters.iter_mut() {
290 filt.reset();
291 filt.apply(dst);
292 }
293 self.lfilt.init();
294 if self.version >= 3950 {
295 for el in dst.iter_mut() {
296 let pred = self.lfilt.predict_a();
297 *el = self.lfilt.update_a(pred, *el);
298 }
299 } else {
300 for el in dst.iter_mut() {
301 *el = self.lfilt.predict_3930(*el);
302 }
303 }
304 }
305 fn filter_stereo(&mut self, l: &mut [i32], r: &mut [i32]) {
306 for filt in self.filters.iter_mut() {
307 filt.reset();
308 filt.apply(l);
309 filt.reset();
310 filt.apply(r);
311 }
312 self.lfilt.init();
313 self.rfilt.init();
314 if self.version >= 3950 {
315 for (l, r) in l.iter_mut().zip(r.iter_mut()) {
316 let mut pred = self.lfilt.predict_a();
317 pred += self.lfilt.predict_b(self.rfilt.filter_a);
318 let new_l = self.lfilt.update_a(pred, *l);
319 self.lfilt.update_b(*l);
320 *l = new_l;
321
322 let mut pred = self.rfilt.predict_a();
323 pred += self.rfilt.predict_b(self.lfilt.filter_a);
324 let new_r = self.rfilt.update_a(pred, *r);
325 self.rfilt.update_b(*r);
326 *r = new_r;
327 }
328 } else {
329 for (l, r) in l.iter_mut().zip(r.iter_mut()) {
330 let new_l = self.lfilt.predict_3930(*r);
331 let new_r = self.rfilt.predict_3930(*l);
332 *l = new_l;
333 *r = new_r;
334 }
335 }
336 }
337 }
338
339 impl OldFilt {
340 fn new(version: u16, compression: u16) -> Self {
341 Self {
342 version, compression
343 }
344 }
345 fn filter(&mut self, dst: &mut [i32]) {
346 match self.compression {
347 1000 => {
348 Self::filter_fast(dst);
349 },
350 2000 => {
351 Self::filter_normal(dst, 4, 10);
352 },
353 3000 => {
354 Self::filter_high(dst, 16, 9);
355 Self::filter_normal(dst, 16, 10);
356 },
357 4000 => {
358 if self.version < 3830 {
359 Self::filter_high(dst, 128, 11);
360 Self::filter_normal(dst, 128, 10);
361 } else {
362 Self::filter_extra_high(dst);
363 Self::filter_high(dst, 256, 12);
364 Self::filter_normal(dst, 256, 11);
365 }
366 },
367 _ => unreachable!(),
368 };
369 }
370 fn filter_fast(dst: &mut [i32]) {
371 const COEFF_A_FAST: i32 = 375;
372
373 if dst.len() <= 3 {
374 return;
375 }
376 let mut delay = [dst[1], dst[0]];
377 let mut last = dst[2];
378 let mut filter = dst[2];
379 let mut weight = COEFF_A_FAST;
380 for el in dst[3..].iter_mut() {
381 delay[1] = delay[0];
382 delay[0] = last;
383 let pred = delay[0] * 2 - delay[1];
384 last = *el + ((pred * weight) >> 9);
385 if (*el ^ pred) > 0 {
386 weight += 1;
387 } else {
388 weight -= 1;
389 }
390 filter += last;
391 *el = filter;
392 }
393 }
394 fn filter_normal(dst: &mut [i32], start: usize, shift: u8) {
395 const COEFFS_A_NORMAL: [i32; 3] = [64, 115, 64];
396 const COEFFS_B_NORMAL: [i32; 2] = [740, 0];
397
398 let mut last = 0;
399 let mut coeffs_a = COEFFS_A_NORMAL;
400 let mut coeffs_b = COEFFS_B_NORMAL;
401 let mut filter_a = 0;
402 let mut filter_b = 0;
403 let mut delay_a = [0; 3];
404 let mut delay_b = [0; 2];
405
406 for (i, el) in dst.iter_mut().enumerate() {
407 delay_a[2] = delay_a[1]; delay_a[1] = delay_a[0]; delay_a[0] = last;
408 delay_b[1] = delay_b[0]; delay_b[0] = filter_b;
409 if i < start {
410 let val = *el + filter_a;
411 last = *el;
412 filter_b = *el;
413 filter_a = val;
414 *el = val;
415 continue;
416 }
417 let a0 = delay_a[0] + (delay_a[2] - delay_a[1]) * 8;
418 let a1 = (delay_a[0] - delay_a[1]) * 2;
419 let a2 = delay_a[0];
420 let b0 = delay_b[0] * 2 - delay_b[1];
421 let b1 = delay_b[0];
422
423 let pred_a = a0 * coeffs_a[0] + a1 * coeffs_a[1] + a2 * coeffs_a[2];
424 let pred_b = b0 * coeffs_b[0] - b1 * coeffs_b[1];
425
426 let sign = val2sign(*el);
427 coeffs_a[0] += (((a0 >> 30) & 2) - 1) * sign;
428 coeffs_a[1] += (((a1 >> 28) & 8) - 4) * sign;
429 coeffs_a[2] += (((a2 >> 28) & 8) - 4) * sign;
430 last = *el + (pred_a >> 11);
431
432 let sign = val2sign(last);
433 coeffs_b[0] += (((b0 >> 29) & 4) - 2) * sign;
434 coeffs_b[1] -= (((b1 >> 30) & 2) - 1) * sign;
435
436 filter_b = last + (pred_b >> shift);
437 filter_a = filter_b + ((filter_a * 31) >> 5);
438
439 *el = filter_a;
440 }
441 }
442 fn filter_high(dst: &mut [i32], order: usize, shift: u8) {
443 let mut coeffs = [0i32; 256];
444 let mut delay = [0i32; 256];
445 if dst.len() <= order {
446 return;
447 }
448 delay[..order].copy_from_slice(&dst[..order]);
449 for el in dst[order..].iter_mut() {
450 let sign = val2sign(*el);
451 let mut sum = 0;
452 for i in 0..order {
453 sum += delay[i] * coeffs[i];
454 coeffs[i] -= (((delay[i] >> 30) & 2) - 1) * sign;
455 }
456 *el -= sum >> shift;
457 for i in 0..order-1 {
458 delay[i] = delay[i + 1];
459 }
460 delay[order - 1] = *el;
461 }
462 }
463 fn filter_extra_high(dst: &mut [i32]) {
464 let mut coeffs = [0i32; 8];
465 let mut delay = [0i32; 8];
466 for el in dst[256..].iter_mut() {
467 let sign = val2sign(*el);
468 let mut sum = 0;
469 for i in 0..8 {
470 sum += delay[i] * coeffs[i];
471 coeffs[i] -= (((delay[i] >> 30) & 2) - 1) * sign;
472 }
473 for i in (0..7).rev() {
474 delay[i + 1] = delay[i];
475 }
476 delay[0] = *el;
477 *el -= sum >> 9;
478 }
479 }
480 }