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