Initialize Tizen 2.3
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / enc / src / g_adapt.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: g_adapt.cpp
35  Functions:
36
37 ------------------------------------------------------------------------------
38  MODULE DESCRIPTION
39
40
41 ------------------------------------------------------------------------------
42 */
43
44 /*----------------------------------------------------------------------------
45 ; INCLUDES
46 ----------------------------------------------------------------------------*/
47 #include "g_adapt.h"
48 #include "typedef.h"
49 #include "basic_op.h"
50 #include "oper_32b.h"
51 #include "cnst.h"
52 #include "gmed_n.h"
53 #include "oscl_mem.h"
54
55 /*----------------------------------------------------------------------------
56 ; MACROS
57 ; Define module specific macros here
58 ----------------------------------------------------------------------------*/
59
60 /*----------------------------------------------------------------------------
61 ; DEFINES
62 ; Include all pre-processor statements here. Include conditional
63 ; compile variables also.
64 ----------------------------------------------------------------------------*/
65 #define LTP_GAIN_THR1 2721 /* 2721 Q13 = 0.3322 ~= 1.0 / (10*log10(2)) */
66 #define LTP_GAIN_THR2 5443 /* 5443 Q13 = 0.6644 ~= 2.0 / (10*log10(2)) */
67
68 /*----------------------------------------------------------------------------
69 ; LOCAL FUNCTION DEFINITIONS
70 ; Function Prototype declaration
71 ----------------------------------------------------------------------------*/
72
73 /*----------------------------------------------------------------------------
74 ; LOCAL VARIABLE DEFINITIONS
75 ; Variable declaration - defined here and used outside this module
76 ----------------------------------------------------------------------------*/
77
78
79 /*
80 ------------------------------------------------------------------------------
81  FUNCTION NAME: gain_adapt_init
82 ------------------------------------------------------------------------------
83  INPUT AND OUTPUT DEFINITIONS
84
85  Inputs:
86     st -- double pointer to GainAdaptState
87
88  Outputs:
89     st -- double ponter to GainAdaptState
90
91  Returns:
92     -1 if an error occurs during memory initialization
93      0 if OK
94
95  Global Variables Used:
96     None
97
98  Local Variables Needed:
99     None
100
101 ------------------------------------------------------------------------------
102  FUNCTION DESCRIPTION
103
104     Allocates state memory and initializes state memory
105
106 ------------------------------------------------------------------------------
107  REQUIREMENTS
108
109  None
110
111 ------------------------------------------------------------------------------
112  REFERENCES
113
114  g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
115
116 ------------------------------------------------------------------------------
117  PSEUDO-CODE
118
119
120 ------------------------------------------------------------------------------
121  CAUTION [optional]
122  [State any special notes, constraints or cautions for users of this function]
123
124 ------------------------------------------------------------------------------
125 */
126
127 Word16 gain_adapt_init(GainAdaptState **st)
128 {
129     GainAdaptState* s;
130
131     if (st == (GainAdaptState **) NULL)
132     {
133         /* fprintf(stderr, "gain_adapt_init: invalid parameter\n"); */
134         return -1;
135     }
136     *st = NULL;
137
138     /* allocate memory */
139     if ((s = (GainAdaptState *) oscl_malloc(sizeof(GainAdaptState))) == NULL)
140     {
141         /* fprintf(stderr, "gain_adapt_init: can't malloc state structure\n"); */
142         return -1;
143     }
144     gain_adapt_reset(s);
145     *st = s;
146
147     return 0;
148 }
149
150 /*
151 ------------------------------------------------------------------------------
152  FUNCTION NAME: gain_adapt_reset
153 ------------------------------------------------------------------------------
154  INPUT AND OUTPUT DEFINITIONS
155
156  Inputs:
157     st -- double pointer to GainAdaptState
158
159  Outputs:
160     st -- double ponter to GainAdaptState
161
162  Returns:
163     -1 if an error occurs
164      0 if OK
165
166  Global Variables Used:
167     None
168
169  Local Variables Needed:
170     None
171
172 ------------------------------------------------------------------------------
173  FUNCTION DESCRIPTION
174
175     Initializes state memory to zero
176 ------------------------------------------------------------------------------
177  REQUIREMENTS
178
179  None
180
181 ------------------------------------------------------------------------------
182  REFERENCES
183
184  g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
185
186 ------------------------------------------------------------------------------
187  PSEUDO-CODE
188
189
190 ------------------------------------------------------------------------------
191  CAUTION [optional]
192  [State any special notes, constraints or cautions for users of this function]
193
194 ------------------------------------------------------------------------------
195 */
196
197 Word16 gain_adapt_reset(GainAdaptState *st)
198 {
199     Word16 i;
200
201     if (st == (GainAdaptState *) NULL)
202     {
203         /* fprintf(stderr, "gain_adapt_reset: invalid parameter\n"); */
204         return -1;
205     }
206
207     st->onset = 0;
208     st->prev_alpha = 0;
209     st->prev_gc = 0;
210
211     for (i = 0; i < LTPG_MEM_SIZE; i++)
212     {
213         st->ltpg_mem[i] = 0;
214     }
215
216     return 0;
217 }
218
219
220 /*
221 ------------------------------------------------------------------------------
222  FUNCTION NAME: gain_adapt_exit
223 ------------------------------------------------------------------------------
224  INPUT AND OUTPUT DEFINITIONS
225
226  Inputs:
227     st -- double pointer to GainAdaptState
228
229  Outputs:
230     None
231
232  Returns:
233     None
234
235  Global Variables Used:
236     None
237
238  Local Variables Needed:
239     None
240
241 ------------------------------------------------------------------------------
242  FUNCTION DESCRIPTION
243
244     The memory used for state memory is freed
245 ------------------------------------------------------------------------------
246  REQUIREMENTS
247
248  None
249
250 ------------------------------------------------------------------------------
251  REFERENCES
252
253  g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
254
255 ------------------------------------------------------------------------------
256  PSEUDO-CODE
257
258
259 ------------------------------------------------------------------------------
260  CAUTION [optional]
261  [State any special notes, constraints or cautions for users of this function]
262
263 ------------------------------------------------------------------------------
264 */
265
266 void gain_adapt_exit(GainAdaptState **st)
267 {
268     if (st == NULL || *st == NULL)
269         return;
270
271     /* deallocate memory */
272     oscl_free(*st);
273     *st = NULL;
274
275     return;
276 }
277
278 /*
279 ------------------------------------------------------------------------------
280  FUNCTION NAME: gain_adapt
281 ------------------------------------------------------------------------------
282  INPUT AND OUTPUT DEFINITIONS
283
284  Inputs:
285     st -- double pointer to GainAdaptState
286     ltpg -- Word16 -- ltp coding gain (log2()), Q13
287     gain_cod -- Word16 -- code gain, Q1
288
289  Outputs:
290     alpha -- Pointer to Word16 --  gain adaptation factor,   Q15
291     pOverflow -- Pointer to Flag -- overflow indicator
292
293  Returns:
294     None
295
296  Global Variables Used:
297     None
298
299  Local Variables Needed:
300     None
301
302 ------------------------------------------------------------------------------
303  FUNCTION DESCRIPTION
304
305  Purpose:    calculate pitch/codebook gain adaptation factor alpha
306              (and update the adaptor state)
307
308 ------------------------------------------------------------------------------
309  REQUIREMENTS
310
311  None
312
313 ------------------------------------------------------------------------------
314  REFERENCES
315
316  g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
317
318 ------------------------------------------------------------------------------
319  PSEUDO-CODE
320
321
322 ------------------------------------------------------------------------------
323  CAUTION [optional]
324  [State any special notes, constraints or cautions for users of this function]
325
326 ------------------------------------------------------------------------------
327 */
328
329 void gain_adapt(
330     GainAdaptState *st,  /* i  : state struct                  */
331     Word16 ltpg,         /* i  : ltp coding gain (log2()), Q13 */
332     Word16 gain_cod,     /* i  : code gain,                Q1  */
333     Word16 *alpha,       /* o  : gain adaptation factor,   Q15 */
334     Flag   *pOverflow
335 )
336 {
337     Word16 adapt;      /* adaptdation status; 0, 1, or 2       */
338     Word16 result;     /* alpha factor, Q13                    */
339     Word16 filt;       /* median-filtered LTP coding gain, Q13 */
340     Word16 tmp;
341     Word16 i;
342
343     /* basic adaptation */
344     if (ltpg <= LTP_GAIN_THR1)
345     {
346         adapt = 0;
347     }
348     else
349     {
350         if (ltpg <= LTP_GAIN_THR2)
351         {
352             adapt = 1;
353         }
354         else
355         {
356             adapt = 2;
357         }
358     }
359
360     /*
361      * // onset indicator
362      * if ((cbGain > onFact * cbGainMem[0]) && (cbGain > 100.0))
363      *     onset = 8;
364      * else
365      *     if (onset)
366      *         onset--;
367      */
368     /* tmp = cbGain / onFact; onFact = 2.0; 200 Q1 = 100.0 */
369     tmp = shr_r(gain_cod, 1, pOverflow);
370
371     if ((tmp > st->prev_gc) && (gain_cod > 200))
372     {
373         st->onset = 8;
374     }
375     else
376     {
377         if (st->onset != 0)
378         {
379             st->onset--;
380         }
381     }
382
383     /*
384      *  // if onset, increase adaptor state
385      *  if (onset && (gainAdapt < 2)) gainAdapt++;
386      */
387     if ((st->onset != 0) && (adapt < 2))
388     {
389         adapt += 1;
390     }
391
392     st->ltpg_mem[0] = ltpg;
393     filt = gmed_n(st->ltpg_mem, 5);  /* function result */
394
395     if (adapt == 0)
396     {
397         if (filt > 5443) /* 5443 Q13 = 0.66443... */
398         {
399             result = 0;
400         }
401         else
402         {
403             if (filt < 0)
404             {
405                 result = 16384;  /* 16384 Q15 = 0.5 */
406             }
407             else
408             {   /* result       =   0.5 - 0.75257499*filt     */
409                 /* result (Q15) = 16384 - 24660 * (filt << 2) */
410                 filt = shl(filt, 2, pOverflow);  /* Q15 */
411                 result = mult(24660, filt, pOverflow);
412                 result = 16384 - result;
413             }
414         }
415     }
416     else
417     {
418         result = 0;
419     }
420     /*
421      *  if (prevAlpha == 0.0) result = 0.5 * (result + prevAlpha);
422      */
423     if (st->prev_alpha == 0)
424     {
425         result = shr(result, 1, pOverflow);
426     }
427
428     /* store the result */
429     *alpha = result;
430
431     /* update adapter state memory */
432     st->prev_alpha = result;
433     st->prev_gc = gain_cod;
434
435     for (i = LTPG_MEM_SIZE - 1; i > 0; i--)
436     {
437         st->ltpg_mem[i] = st->ltpg_mem[i-1];
438     }
439     /* mem[0] is just present for convenience in calling the gmed_n[5]
440      * function above. The memory depth is really LTPG_MEM_SIZE-1.
441      */
442 }