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/****************************************************************************************
19Portions 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)
26Permission to distribute, modify and use this file under the standard license
27terms 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) */
131static const Word16 b[3] = {7699, -15398, 7699};
132static 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
174int 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
213Word16 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
285int 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
344void 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