Initialize Tizen 2.3
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / enc / src / pre_proc.cpp
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  Filename: pre_proc.cpp
35  Funtions: Pre_Process_init
36            Pre_Process_reset
37            Pre_Process_exit
38            Pre_Process
39
40 ------------------------------------------------------------------------------
41  MODULE DESCRIPTION
42
43  These modules handle the preprocessing of input speech.
44
45 ------------------------------------------------------------------------------
46 */
47
48
49 /*----------------------------------------------------------------------------
50 ; INCLUDES
51 ----------------------------------------------------------------------------*/
52 #include "pre_proc.h"
53 #include "typedef.h"
54 #include "oscl_mem.h"
55
56 /*----------------------------------------------------------------------------
57 ; MACROS
58 ; Define module specific macros here
59 ----------------------------------------------------------------------------*/
60
61
62 /*----------------------------------------------------------------------------
63 ; DEFINES
64 ; Include all pre-processor statements here. Include conditional
65 ; compile variables also.
66 ----------------------------------------------------------------------------*/
67
68
69 /*----------------------------------------------------------------------------
70 ; LOCAL FUNCTION DEFINITIONS
71 ; Function Prototype declaration
72 ----------------------------------------------------------------------------*/
73
74 /*----------------------------------------------------------------------------
75 ; LOCAL VARIABLE DEFINITIONS
76 ; Variable declaration - defined here and used outside this module
77 ----------------------------------------------------------------------------*/
78
79
80
81
82 /*
83 ------------------------------------------------------------------------------
84  FUNCTION NAME: Pre_Process_init
85 ------------------------------------------------------------------------------
86  INPUT AND OUTPUT DEFINITIONS
87
88  Inputs:
89     state = pointer to an array of pointer to structures of type
90         Pre_ProcessState
91
92  Outputs:
93     Structure pointed to by the pointer pointed to by state is
94       initialized to its reset value
95     state points to the allocated memory
96
97  Returns:
98     return_value = 0 if memory was successfully initialized,
99                    otherwise returns -1.
100
101  Global Variables Used:
102     None.
103
104  Local Variables Needed:
105     None.
106
107 ------------------------------------------------------------------------------
108  FUNCTION DESCRIPTION
109
110  Allocates state memory and initializes state memory.
111
112 ------------------------------------------------------------------------------
113  REQUIREMENTS
114
115  None.
116
117 ------------------------------------------------------------------------------
118  REFERENCES
119
120  pre_proc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
121
122 ------------------------------------------------------------------------------
123  PSEUDO-CODE
124
125 int Pre_Process_init (Pre_ProcessState **state)
126 {
127   Pre_ProcessState* s;
128
129   if (state == (Pre_ProcessState **) NULL){
130       fprintf(stderr, "Pre_Process_init: invalid parameter\n");
131       return -1;
132   }
133   *state = NULL;
134
135   // allocate memory
136   if ((s= (Pre_ProcessState *) malloc(sizeof(Pre_ProcessState))) == NULL){
137       fprintf(stderr, "Pre_Process_init: can not malloc state structure\n");
138       return -1;
139   }
140
141   Pre_Process_reset(s);
142   *state = s;
143
144   return 0;
145 }
146
147 ------------------------------------------------------------------------------
148  CAUTION [optional]
149  [State any special notes, constraints or cautions for users of this function]
150
151 ------------------------------------------------------------------------------
152 */
153
154 Word16 Pre_Process_init(Pre_ProcessState **state)
155 {
156     Pre_ProcessState* s;
157
158     if (state == (Pre_ProcessState **) NULL)
159     {
160         /*  fprintf(stderr, "Pre_Process_init: invalid parameter\n");  */
161         return(-1);
162     }
163     *state = NULL;
164
165     /* allocate memory */
166     if ((s = (Pre_ProcessState *) oscl_malloc(sizeof(Pre_ProcessState))) == NULL)
167     {
168         /*  fprintf(stderr, "Pre_Process_init:
169             can not malloc state structure\n");  */
170         return(-1);
171     }
172
173     Pre_Process_reset(s);
174     *state = s;
175
176     return(0);
177 }
178
179 /****************************************************************************/
180
181
182 /*
183 ------------------------------------------------------------------------------
184  FUNCTION NAME: Pre_Process_reset
185 ------------------------------------------------------------------------------
186  INPUT AND OUTPUT DEFINITIONS
187
188  Inputs:
189     state = pointer to structure of type Pre_ProcessState
190
191  Outputs:
192     Structure pointed to by state is initialized to zero.
193
194  Returns:
195     return_value = 0 if memory was successfully reset,
196                    otherwise returns -1.
197
198  Global Variables Used:
199     None.
200
201  Local Variables Needed:
202     None.
203
204 ------------------------------------------------------------------------------
205  FUNCTION DESCRIPTION
206
207  Initializes state memory to zero.
208
209 ------------------------------------------------------------------------------
210  REQUIREMENTS
211
212  None.
213
214 ------------------------------------------------------------------------------
215  REFERENCES
216
217  pre_proc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
218
219 ------------------------------------------------------------------------------
220  PSEUDO-CODE
221
222 int Pre_Process_reset (Pre_ProcessState *state)
223 {
224   if (state == (Pre_ProcessState *) NULL){
225       fprintf(stderr, "Pre_Process_reset: invalid parameter\n");
226       return -1;
227   }
228
229   state->y2_hi = 0;
230   state->y2_lo = 0;
231   state->y1_hi = 0;
232   state->y1_lo = 0;
233   state->x0 = 0;
234   state->x1 = 0;
235
236   return 0;
237 }
238
239 ------------------------------------------------------------------------------
240  CAUTION [optional]
241  [State any special notes, constraints or cautions for users of this function]
242
243 ------------------------------------------------------------------------------
244 */
245
246 Word16 Pre_Process_reset(Pre_ProcessState *state)
247 {
248     if (state == (Pre_ProcessState *) NULL)
249     {
250         /*  fprintf(stderr, "Pre_Process_reset: invalid parameter\n");  */
251         return(-1);
252     }
253
254     state->y2_hi = 0;
255     state->y2_lo = 0;
256     state->y1_hi = 0;
257     state->y1_lo = 0;
258     state->x0 = 0;
259     state->x1 = 0;
260
261     return(0);
262 }
263
264 /****************************************************************************/
265
266
267 /*
268 ------------------------------------------------------------------------------
269  FUNCTION NAME: Pre_Process_exit
270 ------------------------------------------------------------------------------
271  INPUT AND OUTPUT DEFINITIONS
272
273  Inputs:
274     state = a pointer to an array of pointers to structures of
275         type Pre_ProcessState
276
277  Outputs:
278     state points to a NULL address
279
280  Returns:
281     None.
282
283  Global Variables Used:
284     None.
285
286  Local Variables Needed:
287     None.
288
289 ------------------------------------------------------------------------------
290  FUNCTION DESCRIPTION
291
292  The memory used for state memory is freed.
293
294 ------------------------------------------------------------------------------
295  REQUIREMENTS
296
297  None.
298
299 ------------------------------------------------------------------------------
300  REFERENCES
301
302  pre_proc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
303
304 ------------------------------------------------------------------------------
305  PSEUDO-CODE
306
307 void Pre_Process_exit (Pre_ProcessState **state)
308 {
309   if (state == NULL || *state == NULL)
310       return;
311
312   // deallocate memory
313   free(*state);
314   *state = NULL;
315
316   return;
317 }
318
319 ------------------------------------------------------------------------------
320  CAUTION [optional]
321  [State any special notes, constraints or cautions for users of this function]
322
323 ------------------------------------------------------------------------------
324 */
325
326 void Pre_Process_exit(Pre_ProcessState **state)
327 {
328     if (state == NULL || *state == NULL)
329     {
330         return;
331     }
332
333     /* deallocate memory */
334     oscl_free(*state);
335     *state = NULL;
336
337     return;
338 }
339
340 /****************************************************************************/
341
342 /*
343 ------------------------------------------------------------------------------
344  FUNCTION NAME: Pre_Process
345 ------------------------------------------------------------------------------
346  INPUT AND OUTPUT DEFINITIONS
347
348  Inputs:
349     st = a pointer to a structure of type Pre_ProcessState
350     signal = input/output signal (Word16)
351     lg = length of signal (Word16)
352
353  Outputs:
354     st points to the updated structure
355
356  Returns:
357     return_value = 0 (int)
358
359  Global Variables Used:
360     a = points to a buffer of filter coefficients
361     b = points to a buffer of filter coefficients
362
363  Local Variables Needed:
364     None.
365
366 ------------------------------------------------------------------------------
367  FUNCTION DESCRIPTION
368
369  This module performs the preprocessing of the input speech.
370  The signal is passed through a 2nd order high pass filtering with cut off
371  frequency at 80 Hz. The input is divided by two in the filtering process.
372
373     y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b[2]*x[i-2]/2
374                      + a[1]*y[i-1] + a[2]*y[i-2];
375
376 ------------------------------------------------------------------------------
377  REQUIREMENTS
378
379  None.
380
381 ------------------------------------------------------------------------------
382  REFERENCES
383
384  pre_proc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
385
386 ------------------------------------------------------------------------------
387  PSEUDO-CODE
388
389 int Pre_Process (
390     Pre_ProcessState *st,
391     Word16 signal[], // input/output signal
392     Word16 lg)       // lenght of signal
393 {
394     Word16 i, x2;
395     Word32 L_tmp;
396
397     for (i = 0; i < lg; i++)
398     {
399         x2 = st->x1;
400         st->x1 = st->x0;
401         st->x0 = signal[i];
402
403         //  y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b140[2]*x[i-2]/2
404         //                     + a[1]*y[i-1] + a[2] * y[i-2];
405
406         L_tmp = Mpy_32_16 (st->y1_hi, st->y1_lo, a[1]);
407         L_tmp = L_add (L_tmp, Mpy_32_16 (st->y2_hi, st->y2_lo, a[2]));
408         L_tmp = L_mac (L_tmp, st->x0, b[0]);
409         L_tmp = L_mac (L_tmp, st->x1, b[1]);
410         L_tmp = L_mac (L_tmp, x2, b[2]);
411         L_tmp = L_shl (L_tmp, 3);
412         signal[i] = pv_round (L_tmp);
413
414         st->y2_hi = st->y1_hi;
415         st->y2_lo = st->y1_lo;
416         L_Extract (L_tmp, &st->y1_hi, &st->y1_lo);
417     }
418     return 0;
419 }
420
421 ------------------------------------------------------------------------------
422  CAUTION [optional]
423  [State any special notes, constraints or cautions for users of this function]
424
425 ------------------------------------------------------------------------------
426 */
427 /*
428     filter coefficients (fc = 80 Hz, coeff. b[] is divided by 2)
429     const Word16 b[3] = {1899, -3798, 1899};
430     const Word16 a[3] = {4096, 7807, -3733};
431
432 */
433
434 void Pre_Process(
435     Pre_ProcessState *st,
436     Word16 signal[], /* input/output signal */
437     Word16 lg)       /* length of signal    */
438 {
439     register Word16 i;
440     Word16 x_n_2;
441     Word16 x_n_1;
442     Word32 L_tmp;
443     Word16 *p_signal = signal;
444
445     x_n_2 = st->x1;
446     x_n_1 = st->x0;
447
448     for (i = lg; i != 0; i--)
449     {
450
451
452         /*  y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b140[2]*x[i-2]/2  */
453         /*                     + a[1]*y[i-1] + a[2] * y[i-2];      */
454
455         L_tmp     = ((Word32) st->y1_hi) * 7807;
456         L_tmp    += (Word32)(((Word32) st->y1_lo * 7807) >> 15);
457
458         L_tmp    += ((Word32) st->y2_hi) * (-3733);
459         st->y2_hi =  st->y1_hi;
460         L_tmp    += (Word32)(((Word32) st->y2_lo * (-3733)) >> 15);
461         st->y2_lo =  st->y1_lo;
462
463         L_tmp    += ((Word32) x_n_2) * 1899;
464         x_n_2     =  x_n_1;
465         L_tmp    += ((Word32) x_n_1) * (-3798);
466         x_n_1     = *(p_signal);
467         L_tmp    += ((Word32) x_n_1) * 1899;
468
469
470         *(p_signal++) = (Word16)((L_tmp + 0x0000800L) >> 12);
471
472         st->y1_hi = (Word16)(L_tmp >> 12);
473         st->y1_lo = (Word16)((L_tmp << 3) - ((Word32)(st->y1_hi) << 15));
474
475     }
476
477     st->x1 = x_n_2;
478     st->x0 = x_n_1;
479
480     return;
481 }
482
483