1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 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 Pathname: ./audio/gsm-amr/c/src/post_pro.c
35 Functions:
36 Post_Process_reset
37 Post_Process
38
39 Date: 04/03/2000
40
41 ------------------------------------------------------------------------------
42 REVISION HISTORY
43
44 Description: Updated template used to PV coding template. First attempt at
45 optimizing C code.
46
47 Description: Deleted variables listed in the Local Stores Needed/Modified
48 sections. Optimized the "else" portion of the first "if"
49 statement in Post_Process function.
50
51 Description: Made grouping more explicit in the calculation of
52 signal[i] << 1 in the Post_Process function.
53
54 Description: Added setting of Overflow flag in inlined code.
55
56 Description: Synchronized file with UMTS version 3.2.0. Updated coding
57 template. Removed unnecessary include files.
58
59 Description: Replaced basic_op.h with the header file of the math functions
60 used in the file.
61
62 Description: Made the following changes per comments from Phase 2/3 review:
63 1. Updated copyright year.
64 2. Fixed typecasting issue with TI C compiler.
65 3. Used short-hand notation for math operations, e.g., "+=",
66 in the code.
67
68 Description: Removed the functions post_pro_init and post_pro_exit.
69 The post_pro related structure is no longer dynamically allocated.
70
71 Description: Added pOverflow as a passed in variable as per changes needed
72 for the EPOC release.
73
74 Description: Optimized file to reduce clock cycle usage. Updated copyright
75 year and removed unused files in Include section.
76
77 Description: Replaced OSCL mem type functions and eliminated include
78 files that now are chosen by OSCL definitions
79
80 Description: Replaced "int" and/or "char" with OSCL defined types.
81
82 Description: Changed round function name to pv_round to avoid conflict with
83 round function in C standard library.
84
85 Description:
86
87 ------------------------------------------------------------------------------
88 MODULE DESCRIPTION
89
90 This file contains the function that performs post-processing on the output
91 speech. Post-processing include filtering the output speech through a second
92 order high pass filter with cutoff frequency of 60 Hz, and up-scaling the
93 output speech by a factor of 2. In addition to the post-processing function
94 itself, a post-processing initialization function, post-processing reset
95 function, and post-processing exit function are also included in this file.
96
97 ------------------------------------------------------------------------------
98 */
99
100
101 /*----------------------------------------------------------------------------
102 ; INCLUDES
103 ----------------------------------------------------------------------------*/
104 #include "post_pro.h"
105 #include "typedef.h"
106 #include "basic_op.h"
107
108 /*----------------------------------------------------------------------------
109 ; MACROS
110 ; Define module specific macros here
111 ----------------------------------------------------------------------------*/
112
113
114 /*----------------------------------------------------------------------------
115 ; DEFINES
116 ; Include all pre-processor statements here. Include conditional
117 ; compile variables also.
118 ----------------------------------------------------------------------------*/
119
120 /*----------------------------------------------------------------------------
121 ; LOCAL FUNCTION DEFINITIONS
122 ; Function Prototype declaration
123 ----------------------------------------------------------------------------*/
124
125 /*----------------------------------------------------------------------------
126 ; LOCAL VARIABLE DEFINITIONS
127 ; Variable declaration - defined here and used outside this module
128 ----------------------------------------------------------------------------*/
129
130 /* filter coefficients (fc = 60 Hz) */
131 static const Word16 b[3] = {7699, -15398, 7699};
132 static const Word16 a[3] = {8192, 15836, -7667};
133
134 /*
135 ------------------------------------------------------------------------------
136 FUNCTION NAME: Post_Process_reset
137 ------------------------------------------------------------------------------
138 INPUT AND OUTPUT DEFINITIONS
139
140 Inputs:
141 state = pointer to a structure of type Post_ProcessState
142
143 Outputs:
144 structure pointed to by state will have all its fields initialized
145 to zero
146
147 Returns:
148 return_value = 0, if reset was successful; -1, otherwise (int)
149
150 Global Variables Used:
151 None
152
153 Local Variables Needed:
154 None
155
156 ------------------------------------------------------------------------------
157 FUNCTION DESCRIPTION
158
159 This function initializes state memory to zero.
160
161 ------------------------------------------------------------------------------
162 REQUIREMENTS
163
164 None
165
166 ------------------------------------------------------------------------------
167 REFERENCES
168
169 post_pro.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
170
171 ------------------------------------------------------------------------------
172 PSEUDO-CODE
173
174 int Post_Process_reset (Post_ProcessState *state)
175 {
176 if (state == (Post_ProcessState *) NULL){
177 fprint(stderr, "Post_Process_reset: invalid parameter\n");
178 return -1;
179 }
180
181 state->y2_hi = 0;
182 state->y2_lo = 0;
183 state->y1_hi = 0;
184 state->y1_lo = 0;
185 state->x0 = 0;
186 state->x1 = 0;
187
188 return 0;
189 }
190 ------------------------------------------------------------------------------
191 RESOURCES USED [optional]
192
193 When the code is written for a specific target processor the
194 the resources used should be documented below.
195
196 HEAP MEMORY USED: x bytes
197
198 STACK MEMORY USED: x bytes
199
200 CLOCK CYCLES: (cycle count equation for this function) + (variable
201 used to represent cycle count for each subroutine
202 called)
203 where: (cycle count variable) = cycle count for [subroutine
204 name]
205
206 ------------------------------------------------------------------------------
207 CAUTION [optional]
208 [State any special notes, constraints or cautions for users of this function]
209
210 ------------------------------------------------------------------------------
211 */
212
Post_Process_reset(Post_ProcessState * state)213 Word16 Post_Process_reset(Post_ProcessState *state)
214 {
215 if (state == (Post_ProcessState *) NULL)
216 {
217 /* fprint(stderr, "Post_Process_reset: invalid parameter\n"); */
218 return(-1);
219 }
220
221 state->y2_hi = 0;
222 state->y2_lo = 0;
223 state->y1_hi = 0;
224 state->y1_lo = 0;
225 state->x0 = 0;
226 state->x1 = 0;
227
228 return(0);
229 }
230
231 /****************************************************************************/
232
233 /*
234 ------------------------------------------------------------------------------
235 FUNCTION NAME: Post_Process
236 ------------------------------------------------------------------------------
237 INPUT AND OUTPUT DEFINITIONS
238
239 Inputs:
240 st = pointer to a structure of type Post_ProcessState
241 signal = buffer containing the input signal (Word16)
242 lg = length of the input signal (Word16)
243 pOverflow = pointer to overflow indicator of type Flag
244
245 Outputs:
246 structure pointed to by st contains new filter input and output values
247 signal buffer contains the HP filtered and up-scaled input signal
248 pOverflow points to 1 if overflow occurs in the math functions called
249 else it points to 0.
250
251 Returns:
252 return_value = 0 (int)
253
254 Global Variables Used:
255 a = buffer containing filter coefficients
256 b = buffer containing filter coefficients
257
258 Local Variables Needed:
259 None
260
261 ------------------------------------------------------------------------------
262 FUNCTION DESCRIPTION
263
264 This function performs post-processing on the output speech signal. First,
265 the output speech goes through a second order high pass filter with a
266 cutoff frequency of 60 Hz. Then, the filtered output speech is multiplied
267 by a factor of 2. The algorithm implemented follows the following difference
268 equation:
269
270 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];
271
272 ------------------------------------------------------------------------------
273 REQUIREMENTS
274
275 None
276
277 ------------------------------------------------------------------------------
278 REFERENCES
279
280 post_pro.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
281
282 ------------------------------------------------------------------------------
283 PSEUDO-CODE
284
285 int Post_Process (
286 Post_ProcessState *st, //i/o : post process state
287 Word16 signal[], //i/o : signal
288 Word16 lg //i : length of signal
289 )
290 {
291 Word16 i, x2;
292 Word32 L_tmp;
293
294 for (i = 0; i < lg; i++)
295 {
296 x2 = st->x1;
297 st->x1 = st->x0;
298 st->x0 = signal[i];
299
300 // y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b140[2]*x[i-2]/2
301 // + a[1]*y[i-1] + a[2] * y[i-2];
302
303 L_tmp = Mpy_32_16 (st->y1_hi, st->y1_lo, a[1]);
304 L_tmp = L_add (L_tmp, Mpy_32_16 (st->y2_hi, st->y2_lo, a[2]));
305 L_tmp = L_mac (L_tmp, st->x0, b[0]);
306 L_tmp = L_mac (L_tmp, st->x1, b[1]);
307 L_tmp = L_mac (L_tmp, x2, b[2]);
308 L_tmp = L_shl (L_tmp, 2);
309
310 //Multiplication by two of output speech with saturation.
311 signal[i] = pv_round(L_shl(L_tmp, 1));
312
313 st->y2_hi = st->y1_hi;
314 st->y2_lo = st->y1_lo;
315 L_Extract (L_tmp, &st->y1_hi, &st->y1_lo);
316 }
317
318 return 0;
319 }
320
321 ------------------------------------------------------------------------------
322 RESOURCES USED [optional]
323
324 When the code is written for a specific target processor the
325 the resources used should be documented below.
326
327 HEAP MEMORY USED: x bytes
328
329 STACK MEMORY USED: x bytes
330
331 CLOCK CYCLES: (cycle count equation for this function) + (variable
332 used to represent cycle count for each subroutine
333 called)
334 where: (cycle count variable) = cycle count for [subroutine
335 name]
336
337 ------------------------------------------------------------------------------
338 CAUTION [optional]
339 [State any special notes, constraints or cautions for users of this function]
340
341 ------------------------------------------------------------------------------
342 */
343
Post_Process(Post_ProcessState * st,Word16 signal[],Word16 lg,Flag * pOverflow)344 void Post_Process(
345 Post_ProcessState *st, /* i/o : post process state */
346 Word16 signal[], /* i/o : signal */
347 Word16 lg, /* i : length of signal */
348 Flag *pOverflow
349 )
350 {
351 Word16 i, x2;
352 Word32 L_tmp;
353
354 Word16 *p_signal;
355 Word16 c_a1 = a[1];
356 Word16 c_a2 = a[2];
357 Word16 c_b0 = b[0];
358 Word16 c_b1 = b[1];
359 Word16 c_b2 = b[2];
360
361 p_signal = &signal[0];
362
363 for (i = 0; i < lg; i++)
364 {
365 x2 = st->x1;
366 st->x1 = st->x0;
367 st->x0 = *(p_signal);
368
369 /* y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b140[2]*x[i-2]/2 */
370 /* + a[1]*y[i-1] + a[2] * y[i-2]; */
371
372 L_tmp = ((Word32) st->y1_hi) * c_a1;
373 L_tmp += (((Word32) st->y1_lo) * c_a1) >> 15;
374 L_tmp += ((Word32) st->y2_hi) * c_a2;
375 L_tmp += (((Word32) st->y2_lo) * c_a2) >> 15;
376 L_tmp += ((Word32) st->x0) * c_b0;
377 L_tmp += ((Word32) st->x1) * c_b1;
378 L_tmp += ((Word32) x2) * c_b2;
379 L_tmp = L_shl(L_tmp, 3, pOverflow);
380
381
382 /* Multiplication by two of output speech with saturation. */
383
384 *(p_signal++) = pv_round(L_shl(L_tmp, 1, pOverflow), pOverflow);
385
386 st->y2_hi = st->y1_hi;
387 st->y2_lo = st->y1_lo;
388
389 st->y1_hi = (Word16)(L_tmp >> 16);
390 st->y1_lo = (Word16)((L_tmp >> 1) - ((Word32) st->y1_hi << 15));
391
392 }
393
394 return;
395 }
396