comparison src/post_pro.c @ 5:799b56cbccb6

EFR2 decoder: add post-processing step from AMR
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 03 Apr 2024 06:09:10 +0000
parents
children
comparison
equal deleted inserted replaced
4:5d7a6bc6960f 5:799b56cbccb6
1 /*
2 ********************************************************************************
3 *
4 * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
5 * R99 Version 3.3.0
6 * REL-4 Version 4.1.0
7 *
8 ********************************************************************************
9 *
10 * File : post_pro.c
11 * Purpose : Postprocessing of output speech.
12 *
13 * - 2nd order high pass filtering with cut
14 * off frequency at 60 Hz.
15 * - Multiplication of output by two.
16 *
17 ********************************************************************************
18 */
19
20
21 /*
22 ********************************************************************************
23 * MODULE INCLUDE FILE AND VERSION ID
24 ********************************************************************************
25 */
26 #if 0
27 #include "post_pro.h"
28 const char post_pro_id[] = "@(#)$Id $" post_pro_h;
29 #endif
30
31 /*
32 ********************************************************************************
33 * INCLUDE FILES
34 ********************************************************************************
35 */
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include "typedef.h"
39 #include "basic_op.h"
40 #include "oper_32b.h"
41 #include "count.h"
42 #include "post_pro.h"
43
44 /*
45 ********************************************************************************
46 * LOCAL VARIABLES AND TABLES
47 ********************************************************************************
48 */
49 /* filter coefficients (fc = 60 Hz) */
50 static const Word16 b[3] = {7699, -15398, 7699};
51 static const Word16 a[3] = {8192, 15836, -7667};
52
53 typedef struct {
54 Word16 y2_hi;
55 Word16 y2_lo;
56 Word16 y1_hi;
57 Word16 y1_lo;
58 Word16 x0;
59 Word16 x1;
60 } Post_ProcessState;
61
62 static Post_ProcessState ppstate;
63
64 /*
65 ********************************************************************************
66 * PUBLIC PROGRAM CODE
67 ********************************************************************************
68 */
69
70 /*************************************************************************
71 *
72 * Function: Post_Process_reset
73 * Purpose: Initializes state memory to zero
74 *
75 **************************************************************************
76 */
77 void AMR_postproc_reset (void)
78 {
79 Post_ProcessState *state = &ppstate;
80
81 state->y2_hi = 0;
82 state->y2_lo = 0;
83 state->y1_hi = 0;
84 state->y1_lo = 0;
85 state->x0 = 0;
86 state->x1 = 0;
87 }
88
89 /*************************************************************************
90 *
91 * FUNCTION: Post_Process()
92 *
93 * PURPOSE: Postprocessing of input speech.
94 *
95 * DESCRIPTION:
96 * - 2nd order high pass filtering with cut off frequency at 60 Hz.
97 * - Multiplication of output by two.
98 *
99 * Algorithm:
100 *
101 * y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b[2]*x[i-2]*2
102 * + a[1]*y[i-1] + a[2]*y[i-2];
103 *
104 *
105 *************************************************************************/
106 void Post_Process (
107 Word16 signal[], /* i/o : signal */
108 Word16 lg /* i : length of signal */
109 )
110 {
111 Post_ProcessState *st = &ppstate;
112 Word16 i, x2;
113 Word32 L_tmp;
114
115 test (); test ();
116 for (i = 0; i < lg; i++)
117 {
118 x2 = st->x1; move16 ();
119 st->x1 = st->x0; move16 ();
120 st->x0 = signal[i]; move16 ();
121
122 /* y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b140[2]*x[i-2]/2 */
123 /* + a[1]*y[i-1] + a[2] * y[i-2]; */
124
125 L_tmp = Mpy_32_16 (st->y1_hi, st->y1_lo, a[1]);
126 L_tmp = L_add (L_tmp, Mpy_32_16 (st->y2_hi, st->y2_lo, a[2]));
127 L_tmp = L_mac (L_tmp, st->x0, b[0]);
128 L_tmp = L_mac (L_tmp, st->x1, b[1]);
129 L_tmp = L_mac (L_tmp, x2, b[2]);
130 L_tmp = L_shl (L_tmp, 2);
131
132 /* Multiplication by two of output speech with saturation. */
133 signal[i] = round(L_shl(L_tmp, 1)); move16 ();
134
135 st->y2_hi = st->y1_hi; move16 ();
136 st->y2_lo = st->y1_lo; move16 ();
137 L_Extract (L_tmp, &st->y1_hi, &st->y1_lo);
138 }
139 }