1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2010 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
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 ****************************************************************************************/
30 ------------------------------------------------------------------------------
34 Filename: post_pro.cpp
39 ------------------------------------------------------------------------------
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.
49 ------------------------------------------------------------------------------
53 /*----------------------------------------------------------------------------
55 ----------------------------------------------------------------------------*/
60 /*----------------------------------------------------------------------------
62 ; Define module specific macros here
63 ----------------------------------------------------------------------------*/
66 /*----------------------------------------------------------------------------
68 ; Include all pre-processor statements here. Include conditional
69 ; compile variables also.
70 ----------------------------------------------------------------------------*/
72 /*----------------------------------------------------------------------------
73 ; LOCAL FUNCTION DEFINITIONS
74 ; Function Prototype declaration
75 ----------------------------------------------------------------------------*/
77 /*----------------------------------------------------------------------------
78 ; LOCAL VARIABLE DEFINITIONS
79 ; Variable declaration - defined here and used outside this module
80 ----------------------------------------------------------------------------*/
82 /* filter coefficients (fc = 60 Hz) */
83 static const Word16 b[3] = {7699, -15398, 7699};
84 static const Word16 a[3] = {8192, 15836, -7667};
87 ------------------------------------------------------------------------------
88 FUNCTION NAME: Post_Process_reset
89 ------------------------------------------------------------------------------
90 INPUT AND OUTPUT DEFINITIONS
93 state = pointer to a structure of type Post_ProcessState
96 structure pointed to by state will have all its fields initialized
100 return_value = 0, if reset was successful; -1, otherwise (int)
102 Global Variables Used:
105 Local Variables Needed:
108 ------------------------------------------------------------------------------
111 This function initializes state memory to zero.
113 ------------------------------------------------------------------------------
118 ------------------------------------------------------------------------------
121 post_pro.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
123 ------------------------------------------------------------------------------
126 int Post_Process_reset (Post_ProcessState *state)
128 if (state == (Post_ProcessState *) NULL){
129 fprint(stderr, "Post_Process_reset: invalid parameter\n");
142 ------------------------------------------------------------------------------
144 [State any special notes, constraints or cautions for users of this function]
146 ------------------------------------------------------------------------------
149 Word16 Post_Process_reset(Post_ProcessState *state)
151 if (state == (Post_ProcessState *) NULL)
153 /* fprint(stderr, "Post_Process_reset: invalid parameter\n"); */
167 /****************************************************************************/
170 ------------------------------------------------------------------------------
171 FUNCTION NAME: Post_Process
172 ------------------------------------------------------------------------------
173 INPUT AND OUTPUT DEFINITIONS
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
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
188 return_value = 0 (int)
190 Global Variables Used:
191 a = buffer containing filter coefficients
192 b = buffer containing filter coefficients
194 Local Variables Needed:
197 ------------------------------------------------------------------------------
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
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];
208 ------------------------------------------------------------------------------
213 ------------------------------------------------------------------------------
216 post_pro.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
218 ------------------------------------------------------------------------------
222 Post_ProcessState *st, //i/o : post process state
223 Word16 signal[], //i/o : signal
224 Word16 lg //i : length of signal
230 for (i = 0; i < lg; i++)
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];
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);
246 //Multiplication by two of output speech with saturation.
247 signal[i] = pv_round(L_shl(L_tmp, 1));
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);
257 ------------------------------------------------------------------------------
259 [State any special notes, constraints or cautions for users of this function]
261 ------------------------------------------------------------------------------
265 Post_ProcessState *st, /* i/o : post process state */
266 Word16 signal[], /* i/o : signal */
267 Word16 lg, /* i : length of signal */
281 p_signal = &signal[0];
283 for (i = 0; i < lg; i++)
287 st->x0 = *(p_signal);
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]; */
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;
300 L_tmp = L_shl(L_tmp, 3, pOverflow);
303 /* Multiplication by two of output speech with saturation. */
305 *(p_signal++) = pv_round(L_shl(L_tmp, 1, pOverflow), pOverflow);
307 st->y2_hi = st->y1_hi;
308 st->y2_lo = st->y1_lo;
310 st->y1_hi = (Word16)(L_tmp >> 16);
311 st->y1_lo = (Word16)((L_tmp >> 1) - ((Word32) st->y1_hi << 15));