g729_sys/g729/post_processing.rs
1use crate::g729::basic_operations::*;
2use crate::g729::ld8k::*;
3
4/*****************************************************************************/
5/* */
6/* Define filter coefficients */
7/* Coefficient are given by the filter transfert function : */
8/* */
9/* 0.46363718 - 0.92724705z(-1) + 0.46363718z(-2) */
10/* H(z) = −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− */
11/* 1 - 1.9059465z(-1) + 0.9114024z(-2) */
12/* */
13/* giving: */
14/* y[i] = B0*x[i] + B1*x[i-1] + B2*x[i-2] */
15/* + A1*y[i-1] + A2*y[i-2] */
16/* */
17/*****************************************************************************/
18
19/* coefficients are stored in Q1.13 */
20const A1: Word16 = 15836;
21const A2: Word16 = -7667;
22const B0: Word16 = 7699;
23const B1: Word16 = -15398;
24const B2: Word16 = 7699;
25
26/* Initialization of context values */
27pub fn init_post_processing(
28 output_y2: &mut Word32,
29 output_y1: &mut Word32,
30 input_x0: &mut Word16,
31 input_x1: &mut Word16,
32) {
33 *output_y2 = 0;
34 *output_y1 = 0;
35 *input_x0 = 0;
36 *input_x1 = 0;
37}
38
39/*****************************************************************************/
40/* postProcessing : high pass filtering and upscaling Spec 4.2.5 */
41/* Algorithm: */
42/* y[i] = BO*x[i] + B1*x[i-1] + B2*x[i-2] + A1*y[i-1] + A2*y[i-2] */
43/* parameters: */
44/* -(i/o) decoderChannelContext : the channel context data */
45/* -(i/o) signal : 40 values in Q0, reconstructed speech, output */
46/* replaces the input in buffer */
47/* */
48/*****************************************************************************/
49pub fn post_processing(
50 output_y2: &mut Word32,
51 output_y1: &mut Word32,
52 input_x0: &mut Word16,
53 input_x1: &mut Word16,
54 signal: &mut [Word16],
55) {
56 let mut input_x2: Word16;
57 let mut acc: Word32; /* in Q13 */
58
59 for i in 0..L_SUBFRAME {
60 input_x2 = *input_x1;
61 *input_x1 = *input_x0;
62 *input_x0 = signal[i];
63
64 /* compute with acc and coefficients in Q13 */
65 acc = mult16_32_q13(A1, *output_y1); /* Y1 in Q14.13 * A1 in Q1.13 -> acc in Q17.13*/
66 acc = mac16_32_q13(acc, A2, *output_y2); /* Y2 in Q14.13 * A2 in Q0.13 -> Q15.13 + acc in Q17.13 -> acc in Q18.12 */
67 /* 3*(Xi in Q15.0 * Bi in Q0.13)->Q17.13 + acc in Q18.13 -> acc in 19.13(Overflow??) */
68 acc = mac16_16(acc, *input_x0, B0);
69 acc = mac16_16(acc, *input_x1, B1);
70 acc = saturate(mac16_16(acc, input_x2, B2), MAX_INT29); /* saturate the acc to keep in Q15.13 */
71
72 signal[i] = saturate(pshr(acc, 12), MAX_INT16 as Word32) as Word16; /* acc in Q13 -> *2 and scale back to Q0 */
73 *output_y2 = *output_y1;
74 *output_y1 = acc;
75 }
76}