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/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
167int 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
212Word16 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
280int 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
320Word16 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
381void 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
416void 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
479int 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
540void 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