Initialize Tizen 2.3
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / dec / src / post_pro.cpp
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2010 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20
21     3GPP TS 26.073
22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23     Available from http://www.3gpp.org
24
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34  Filename: post_pro.cpp
35  Functions:
36            Post_Process_reset
37            Post_Process
38
39 ------------------------------------------------------------------------------
40  MODULE DESCRIPTION
41
42  This file contains the function that performs post-processing on the output
43  speech. Post-processing include filtering the output speech through a second
44  order high pass filter with cutoff frequency of 60 Hz, and up-scaling the
45  output speech by a factor of 2. In addition to the post-processing function
46  itself, a post-processing initialization function, post-processing reset
47  function, and post-processing exit function are also included in this file.
48
49 ------------------------------------------------------------------------------
50 */
51
52
53 /*----------------------------------------------------------------------------
54 ; INCLUDES
55 ----------------------------------------------------------------------------*/
56 #include "post_pro.h"
57 #include "typedef.h"
58 #include "basic_op.h"
59
60 /*----------------------------------------------------------------------------
61 ; MACROS
62 ; Define module specific macros here
63 ----------------------------------------------------------------------------*/
64
65
66 /*----------------------------------------------------------------------------
67 ; DEFINES
68 ; Include all pre-processor statements here. Include conditional
69 ; compile variables also.
70 ----------------------------------------------------------------------------*/
71
72 /*----------------------------------------------------------------------------
73 ; LOCAL FUNCTION DEFINITIONS
74 ; Function Prototype declaration
75 ----------------------------------------------------------------------------*/
76
77 /*----------------------------------------------------------------------------
78 ; LOCAL VARIABLE DEFINITIONS
79 ; Variable declaration - defined here and used outside this module
80 ----------------------------------------------------------------------------*/
81
82 /* filter coefficients (fc = 60 Hz) */
83 static const Word16 b[3] = {7699, -15398, 7699};
84 static const Word16 a[3] = {8192, 15836, -7667};
85
86 /*
87 ------------------------------------------------------------------------------
88  FUNCTION NAME: Post_Process_reset
89 ------------------------------------------------------------------------------
90  INPUT AND OUTPUT DEFINITIONS
91
92  Inputs:
93     state = pointer to a structure of type Post_ProcessState
94
95  Outputs:
96     structure pointed to by state will have all its fields initialized
97       to zero
98
99  Returns:
100     return_value = 0, if reset was successful; -1, otherwise (int)
101
102  Global Variables Used:
103     None
104
105  Local Variables Needed:
106     None
107
108 ------------------------------------------------------------------------------
109  FUNCTION DESCRIPTION
110
111  This function initializes state memory to zero.
112
113 ------------------------------------------------------------------------------
114  REQUIREMENTS
115
116  None
117
118 ------------------------------------------------------------------------------
119  REFERENCES
120
121  post_pro.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
122
123 ------------------------------------------------------------------------------
124  PSEUDO-CODE
125
126 int Post_Process_reset (Post_ProcessState *state)
127 {
128   if (state == (Post_ProcessState *) NULL){
129       fprint(stderr, "Post_Process_reset: invalid parameter\n");
130       return -1;
131   }
132
133   state->y2_hi = 0;
134   state->y2_lo = 0;
135   state->y1_hi = 0;
136   state->y1_lo = 0;
137   state->x0 = 0;
138   state->x1 = 0;
139
140   return 0;
141 }
142 ------------------------------------------------------------------------------
143  CAUTION [optional]
144  [State any special notes, constraints or cautions for users of this function]
145
146 ------------------------------------------------------------------------------
147 */
148
149 Word16 Post_Process_reset(Post_ProcessState *state)
150 {
151     if (state == (Post_ProcessState *) NULL)
152     {
153         /*  fprint(stderr, "Post_Process_reset: invalid parameter\n");  */
154         return(-1);
155     }
156
157     state->y2_hi = 0;
158     state->y2_lo = 0;
159     state->y1_hi = 0;
160     state->y1_lo = 0;
161     state->x0 = 0;
162     state->x1 = 0;
163
164     return(0);
165 }
166
167 /****************************************************************************/
168
169 /*
170 ------------------------------------------------------------------------------
171  FUNCTION NAME: Post_Process
172 ------------------------------------------------------------------------------
173  INPUT AND OUTPUT DEFINITIONS
174
175  Inputs:
176     st = pointer to a structure of type Post_ProcessState
177     signal = buffer containing the input signal (Word16)
178     lg = length of the input signal (Word16)
179     pOverflow = pointer to overflow indicator of type Flag
180
181  Outputs:
182     structure pointed to by st contains new filter input and output values
183     signal buffer contains the HP filtered and up-scaled input signal
184     pOverflow points to 1 if overflow occurs in the math functions called
185               else it points to 0.
186
187  Returns:
188     return_value = 0 (int)
189
190  Global Variables Used:
191     a = buffer containing filter coefficients
192     b = buffer containing filter coefficients
193
194  Local Variables Needed:
195     None
196
197 ------------------------------------------------------------------------------
198  FUNCTION DESCRIPTION
199
200  This function performs post-processing on the output speech signal. First,
201  the output speech goes through a second order high pass filter with a
202  cutoff frequency of 60 Hz. Then, the filtered output speech is multiplied
203  by a factor of 2. The algorithm implemented follows the following difference
204  equation:
205
206  y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b[2]*x[i-2]*2 + a[1]*y[i-1] + a[2]*y[i-2];
207
208 ------------------------------------------------------------------------------
209  REQUIREMENTS
210
211  None
212
213 ------------------------------------------------------------------------------
214  REFERENCES
215
216  post_pro.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
217
218 ------------------------------------------------------------------------------
219  PSEUDO-CODE
220
221 int Post_Process (
222     Post_ProcessState *st,  //i/o : post process state
223     Word16 signal[],        //i/o : signal
224     Word16 lg               //i   : length of signal
225     )
226 {
227     Word16 i, x2;
228     Word32 L_tmp;
229
230     for (i = 0; i < lg; i++)
231     {
232         x2 = st->x1;
233         st->x1 = st->x0;
234         st->x0 = signal[i];
235
236         // y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b140[2]*x[i-2]/2
237         //                    + a[1]*y[i-1] + a[2] * y[i-2];
238
239         L_tmp = Mpy_32_16 (st->y1_hi, st->y1_lo, a[1]);
240         L_tmp = L_add (L_tmp, Mpy_32_16 (st->y2_hi, st->y2_lo, a[2]));
241         L_tmp = L_mac (L_tmp, st->x0, b[0]);
242         L_tmp = L_mac (L_tmp, st->x1, b[1]);
243         L_tmp = L_mac (L_tmp, x2, b[2]);
244         L_tmp = L_shl (L_tmp, 2);
245
246         //Multiplication by two of output speech with saturation.
247         signal[i] = pv_round(L_shl(L_tmp, 1));
248
249         st->y2_hi = st->y1_hi;
250         st->y2_lo = st->y1_lo;
251         L_Extract (L_tmp, &st->y1_hi, &st->y1_lo);
252     }
253
254     return 0;
255 }
256
257 ------------------------------------------------------------------------------
258  CAUTION [optional]
259  [State any special notes, constraints or cautions for users of this function]
260
261 ------------------------------------------------------------------------------
262 */
263
264 void Post_Process(
265     Post_ProcessState *st,  /* i/o : post process state                   */
266     Word16 signal[],        /* i/o : signal                               */
267     Word16 lg,              /* i   : length of signal                     */
268     Flag   *pOverflow
269 )
270 {
271     Word16 i, x2;
272     Word32 L_tmp;
273
274     Word16 *p_signal;
275     Word16 c_a1 = a[1];
276     Word16 c_a2 = a[2];
277     Word16 c_b0 = b[0];
278     Word16 c_b1 = b[1];
279     Word16 c_b2 = b[2];
280
281     p_signal = &signal[0];
282
283     for (i = 0; i < lg; i++)
284     {
285         x2 = st->x1;
286         st->x1 = st->x0;
287         st->x0 = *(p_signal);
288
289         /*  y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b140[2]*x[i-2]/2  */
290         /*                     + a[1]*y[i-1] + a[2] * y[i-2];      */
291
292         L_tmp = ((Word32) st->y1_hi) * c_a1;
293         L_tmp += (((Word32) st->y1_lo) * c_a1) >> 15;
294         L_tmp += ((Word32) st->y2_hi) * c_a2;
295         L_tmp += (((Word32) st->y2_lo) * c_a2) >> 15;
296         L_tmp += ((Word32) st->x0) * c_b0;
297         L_tmp += ((Word32) st->x1) * c_b1;
298         L_tmp += ((Word32) x2) * c_b2;
299
300         L_tmp = L_shl(L_tmp, 3, pOverflow);
301
302
303         /* Multiplication by two of output speech with saturation. */
304
305         *(p_signal++) = pv_round(L_shl(L_tmp, 1, pOverflow), pOverflow);
306
307         st->y2_hi = st->y1_hi;
308         st->y2_lo = st->y1_lo;
309
310         st->y1_hi = (Word16)(L_tmp >> 16);
311         st->y1_lo = (Word16)((L_tmp >> 1) - ((Word32) st->y1_hi << 15));
312
313     }
314
315     return;
316 }