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/pre_proc.c
35  Funtions: Pre_Process_init
36            Pre_Process_reset
37            Pre_Process_exit
38            Pre_Process
39 
40      Date: 05/17/2000
41 
42 ------------------------------------------------------------------------------
43  REVISION HISTORY
44 
45  Description: Put the file into our template structure.
46 
47  Description: First pass optimization.
48 
49  Description: Made changes based on comments from review meeting.
50 
51  Description: Synchronized file with UMTS version 3.2.0. Updated coding
52               template. Removed unnecessary include files.
53 
54  Description: Removed basic_op.h from the Include section. It is not used.
55 
56  Description: Made the following changes per comments from Phase 2/3 review:
57               1. Fixed typecasting issue with TI C compiler.
58               2. Modified FOR loop to count down.
59               3. Cosmetic changes to the code to make address post-increment
60                  clearer.
61               4. Removed unnecessary typecasting in the multiply-accumulate
62                  portion of FOR loop body.
63               5. Removed "static" in table definitions.
64               6. Updated copyright year.
65 
66  Description:  For Pre_Process()
67               1. Replaced variables (containing filter coefficients) with
68                  constants, to avoid extra register swaping.
69               2. Changed to decrement loop
70 
71  Description:  Replaced OSCL mem type functions and eliminated include
72                files that now are chosen by OSCL definitions
73 
74  Description:  Replaced "int" and/or "char" with OSCL defined types.
75 
76  Description: Changed round function name to pv_round to avoid conflict with
77               round function in C standard library.
78 
79  Description:
80 
81 ------------------------------------------------------------------------------
82  MODULE DESCRIPTION
83 
84  These modules handle the preprocessing of input speech.
85 
86 ------------------------------------------------------------------------------
87 */
88 
89 
90 /*----------------------------------------------------------------------------
91 ; INCLUDES
92 ----------------------------------------------------------------------------*/
93 #include <stdlib.h>
94 
95 #include "pre_proc.h"
96 #include "typedef.h"
97 
98 /*----------------------------------------------------------------------------
99 ; MACROS
100 ; Define module specific macros here
101 ----------------------------------------------------------------------------*/
102 
103 
104 /*----------------------------------------------------------------------------
105 ; DEFINES
106 ; Include all pre-processor statements here. Include conditional
107 ; compile variables also.
108 ----------------------------------------------------------------------------*/
109 
110 
111 /*----------------------------------------------------------------------------
112 ; LOCAL FUNCTION DEFINITIONS
113 ; Function Prototype declaration
114 ----------------------------------------------------------------------------*/
115 
116 /*----------------------------------------------------------------------------
117 ; LOCAL VARIABLE DEFINITIONS
118 ; Variable declaration - defined here and used outside this module
119 ----------------------------------------------------------------------------*/
120 
121 
122 
123 
124 /*
125 ------------------------------------------------------------------------------
126  FUNCTION NAME: Pre_Process_init
127 ------------------------------------------------------------------------------
128  INPUT AND OUTPUT DEFINITIONS
129 
130  Inputs:
131     state = pointer to an array of pointer to structures of type
132         Pre_ProcessState
133 
134  Outputs:
135     Structure pointed to by the pointer pointed to by state is
136       initialized to its reset value
137     state points to the allocated memory
138 
139  Returns:
140     return_value = 0 if memory was successfully initialized,
141                    otherwise returns -1.
142 
143  Global Variables Used:
144     None.
145 
146  Local Variables Needed:
147     None.
148 
149 ------------------------------------------------------------------------------
150  FUNCTION DESCRIPTION
151 
152  Allocates state memory and initializes state memory.
153 
154 ------------------------------------------------------------------------------
155  REQUIREMENTS
156 
157  None.
158 
159 ------------------------------------------------------------------------------
160  REFERENCES
161 
162  pre_proc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
163 
164 ------------------------------------------------------------------------------
165  PSEUDO-CODE
166 
167 int Pre_Process_init (Pre_ProcessState **state)
168 {
169   Pre_ProcessState* s;
170 
171   if (state == (Pre_ProcessState **) NULL){
172       fprintf(stderr, "Pre_Process_init: invalid parameter\n");
173       return -1;
174   }
175   *state = NULL;
176 
177   // allocate memory
178   if ((s= (Pre_ProcessState *) malloc(sizeof(Pre_ProcessState))) == NULL){
179       fprintf(stderr, "Pre_Process_init: can not malloc state structure\n");
180       return -1;
181   }
182 
183   Pre_Process_reset(s);
184   *state = s;
185 
186   return 0;
187 }
188 
189 ------------------------------------------------------------------------------
190  RESOURCES USED [optional]
191 
192  When the code is written for a specific target processor the
193  the resources used should be documented below.
194 
195  HEAP MEMORY USED: x bytes
196 
197  STACK MEMORY USED: x bytes
198 
199  CLOCK CYCLES: (cycle count equation for this function) + (variable
200                 used to represent cycle count for each subroutine
201                 called)
202      where: (cycle count variable) = cycle count for [subroutine
203                                      name]
204 
205 ------------------------------------------------------------------------------
206  CAUTION [optional]
207  [State any special notes, constraints or cautions for users of this function]
208 
209 ------------------------------------------------------------------------------
210 */
211 
Pre_Process_init(Pre_ProcessState ** state)212 Word16 Pre_Process_init(Pre_ProcessState **state)
213 {
214     Pre_ProcessState* s;
215 
216     if (state == (Pre_ProcessState **) NULL)
217     {
218         /*  fprintf(stderr, "Pre_Process_init: invalid parameter\n");  */
219         return(-1);
220     }
221     *state = NULL;
222 
223     /* allocate memory */
224     if ((s = (Pre_ProcessState *) malloc(sizeof(Pre_ProcessState))) == NULL)
225     {
226         /*  fprintf(stderr, "Pre_Process_init:
227             can not malloc state structure\n");  */
228         return(-1);
229     }
230 
231     Pre_Process_reset(s);
232     *state = s;
233 
234     return(0);
235 }
236 
237 /****************************************************************************/
238 
239 
240 /*
241 ------------------------------------------------------------------------------
242  FUNCTION NAME: Pre_Process_reset
243 ------------------------------------------------------------------------------
244  INPUT AND OUTPUT DEFINITIONS
245 
246  Inputs:
247     state = pointer to structure of type Pre_ProcessState
248 
249  Outputs:
250     Structure pointed to by state is initialized to zero.
251 
252  Returns:
253     return_value = 0 if memory was successfully reset,
254                    otherwise returns -1.
255 
256  Global Variables Used:
257     None.
258 
259  Local Variables Needed:
260     None.
261 
262 ------------------------------------------------------------------------------
263  FUNCTION DESCRIPTION
264 
265  Initializes state memory to zero.
266 
267 ------------------------------------------------------------------------------
268  REQUIREMENTS
269 
270  None.
271 
272 ------------------------------------------------------------------------------
273  REFERENCES
274 
275  pre_proc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
276 
277 ------------------------------------------------------------------------------
278  PSEUDO-CODE
279 
280 int Pre_Process_reset (Pre_ProcessState *state)
281 {
282   if (state == (Pre_ProcessState *) NULL){
283       fprintf(stderr, "Pre_Process_reset: invalid parameter\n");
284       return -1;
285   }
286 
287   state->y2_hi = 0;
288   state->y2_lo = 0;
289   state->y1_hi = 0;
290   state->y1_lo = 0;
291   state->x0 = 0;
292   state->x1 = 0;
293 
294   return 0;
295 }
296 
297 ------------------------------------------------------------------------------
298  RESOURCES USED [optional]
299 
300  When the code is written for a specific target processor the
301  the resources used should be documented below.
302 
303  HEAP MEMORY USED: x bytes
304 
305  STACK MEMORY USED: x bytes
306 
307  CLOCK CYCLES: (cycle count equation for this function) + (variable
308                 used to represent cycle count for each subroutine
309                 called)
310      where: (cycle count variable) = cycle count for [subroutine
311                                      name]
312 
313 ------------------------------------------------------------------------------
314  CAUTION [optional]
315  [State any special notes, constraints or cautions for users of this function]
316 
317 ------------------------------------------------------------------------------
318 */
319 
Pre_Process_reset(Pre_ProcessState * state)320 Word16 Pre_Process_reset(Pre_ProcessState *state)
321 {
322     if (state == (Pre_ProcessState *) NULL)
323     {
324         /*  fprintf(stderr, "Pre_Process_reset: invalid parameter\n");  */
325         return(-1);
326     }
327 
328     state->y2_hi = 0;
329     state->y2_lo = 0;
330     state->y1_hi = 0;
331     state->y1_lo = 0;
332     state->x0 = 0;
333     state->x1 = 0;
334 
335     return(0);
336 }
337 
338 /****************************************************************************/
339 
340 
341 /*
342 ------------------------------------------------------------------------------
343  FUNCTION NAME: Pre_Process_exit
344 ------------------------------------------------------------------------------
345  INPUT AND OUTPUT DEFINITIONS
346 
347  Inputs:
348     state = a pointer to an array of pointers to structures of
349         type Pre_ProcessState
350 
351  Outputs:
352     state points to a NULL address
353 
354  Returns:
355     None.
356 
357  Global Variables Used:
358     None.
359 
360  Local Variables Needed:
361     None.
362 
363 ------------------------------------------------------------------------------
364  FUNCTION DESCRIPTION
365 
366  The memory used for state memory is freed.
367 
368 ------------------------------------------------------------------------------
369  REQUIREMENTS
370 
371  None.
372 
373 ------------------------------------------------------------------------------
374  REFERENCES
375 
376  pre_proc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
377 
378 ------------------------------------------------------------------------------
379  PSEUDO-CODE
380 
381 void Pre_Process_exit (Pre_ProcessState **state)
382 {
383   if (state == NULL || *state == NULL)
384       return;
385 
386   // deallocate memory
387   free(*state);
388   *state = NULL;
389 
390   return;
391 }
392 
393 ------------------------------------------------------------------------------
394  RESOURCES USED [optional]
395 
396  When the code is written for a specific target processor the
397  the resources used should be documented below.
398 
399  HEAP MEMORY USED: x bytes
400 
401  STACK MEMORY USED: x bytes
402 
403  CLOCK CYCLES: (cycle count equation for this function) + (variable
404                 used to represent cycle count for each subroutine
405                 called)
406      where: (cycle count variable) = cycle count for [subroutine
407                                      name]
408 
409 ------------------------------------------------------------------------------
410  CAUTION [optional]
411  [State any special notes, constraints or cautions for users of this function]
412 
413 ------------------------------------------------------------------------------
414 */
415 
Pre_Process_exit(Pre_ProcessState ** state)416 void Pre_Process_exit(Pre_ProcessState **state)
417 {
418     if (state == NULL || *state == NULL)
419     {
420         return;
421     }
422 
423     /* deallocate memory */
424     free(*state);
425     *state = NULL;
426 
427     return;
428 }
429 
430 /****************************************************************************/
431 
432 /*
433 ------------------------------------------------------------------------------
434  FUNCTION NAME: Pre_Process
435 ------------------------------------------------------------------------------
436  INPUT AND OUTPUT DEFINITIONS
437 
438  Inputs:
439     st = a pointer to a structure of type Pre_ProcessState
440     signal = input/output signal (Word16)
441     lg = length of signal (Word16)
442 
443  Outputs:
444     st points to the updated structure
445 
446  Returns:
447     return_value = 0 (int)
448 
449  Global Variables Used:
450     a = points to a buffer of filter coefficients
451     b = points to a buffer of filter coefficients
452 
453  Local Variables Needed:
454     None.
455 
456 ------------------------------------------------------------------------------
457  FUNCTION DESCRIPTION
458 
459  This module performs the preprocessing of the input speech.
460  The signal is passed through a 2nd order high pass filtering with cut off
461  frequency at 80 Hz. The input is divided by two in the filtering process.
462 
463     y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b[2]*x[i-2]/2
464                      + a[1]*y[i-1] + a[2]*y[i-2];
465 
466 ------------------------------------------------------------------------------
467  REQUIREMENTS
468 
469  None.
470 
471 ------------------------------------------------------------------------------
472  REFERENCES
473 
474  pre_proc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
475 
476 ------------------------------------------------------------------------------
477  PSEUDO-CODE
478 
479 int Pre_Process (
480     Pre_ProcessState *st,
481     Word16 signal[], // input/output signal
482     Word16 lg)       // lenght of signal
483 {
484     Word16 i, x2;
485     Word32 L_tmp;
486 
487     for (i = 0; i < lg; i++)
488     {
489         x2 = st->x1;
490         st->x1 = st->x0;
491         st->x0 = signal[i];
492 
493         //  y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b140[2]*x[i-2]/2
494         //                     + a[1]*y[i-1] + a[2] * y[i-2];
495 
496         L_tmp = Mpy_32_16 (st->y1_hi, st->y1_lo, a[1]);
497         L_tmp = L_add (L_tmp, Mpy_32_16 (st->y2_hi, st->y2_lo, a[2]));
498         L_tmp = L_mac (L_tmp, st->x0, b[0]);
499         L_tmp = L_mac (L_tmp, st->x1, b[1]);
500         L_tmp = L_mac (L_tmp, x2, b[2]);
501         L_tmp = L_shl (L_tmp, 3);
502         signal[i] = pv_round (L_tmp);
503 
504         st->y2_hi = st->y1_hi;
505         st->y2_lo = st->y1_lo;
506         L_Extract (L_tmp, &st->y1_hi, &st->y1_lo);
507     }
508     return 0;
509 }
510 
511 ------------------------------------------------------------------------------
512  RESOURCES USED [optional]
513 
514  When the code is written for a specific target processor the
515  the resources used should be documented below.
516 
517  HEAP MEMORY USED: x bytes
518 
519  STACK MEMORY USED: x bytes
520 
521  CLOCK CYCLES: (cycle count equation for this function) + (variable
522                 used to represent cycle count for each subroutine
523                 called)
524      where: (cycle count variable) = cycle count for [subroutine
525                                      name]
526 
527 ------------------------------------------------------------------------------
528  CAUTION [optional]
529  [State any special notes, constraints or cautions for users of this function]
530 
531 ------------------------------------------------------------------------------
532 */
533 /*
534     filter coefficients (fc = 80 Hz, coeff. b[] is divided by 2)
535     const Word16 b[3] = {1899, -3798, 1899};
536     const Word16 a[3] = {4096, 7807, -3733};
537 
538 */
539 
Pre_Process(Pre_ProcessState * st,Word16 signal[],Word16 lg)540 void Pre_Process(
541     Pre_ProcessState *st,
542     Word16 signal[], /* input/output signal */
543     Word16 lg)       /* length of signal    */
544 {
545     Word16 i;
546     Word16 x_n_2;
547     Word16 x_n_1;
548     Word32 L_tmp;
549     Word16 *p_signal = signal;
550 
551     x_n_2 = st->x1;
552     x_n_1 = st->x0;
553 
554     for (i = lg; i != 0; i--)
555     {
556 
557 
558         /*  y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b140[2]*x[i-2]/2  */
559         /*                     + a[1]*y[i-1] + a[2] * y[i-2];      */
560 
561         L_tmp     = ((Word32) st->y1_hi) * 7807;
562         L_tmp    += (Word32)(((Word32) st->y1_lo * 7807) >> 15);
563 
564         L_tmp    += ((Word32) st->y2_hi) * (-3733);
565         st->y2_hi =  st->y1_hi;
566         L_tmp    += (Word32)(((Word32) st->y2_lo * (-3733)) >> 15);
567         st->y2_lo =  st->y1_lo;
568 
569         L_tmp    += ((Word32) x_n_2) * 1899;
570         x_n_2     =  x_n_1;
571         L_tmp    += ((Word32) x_n_1) * (-3798);
572         x_n_1     = *(p_signal);
573         L_tmp    += ((Word32) x_n_1) * 1899;
574 
575 
576         *(p_signal++) = (Word16)((L_tmp + 0x0000800L) >> 12);
577 
578         st->y1_hi = (Word16)(L_tmp >> 12);
579         st->y1_lo = (Word16)((L_tmp << 3) - ((Word32)(st->y1_hi) << 15));
580 
581     }
582 
583     st->x1 = x_n_2;
584     st->x0 = x_n_1;
585 
586     return;
587 }
588 
589 
590