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/g_adapt.c
35 Functions:
36
37 Date: 02/04/2002
38
39 ------------------------------------------------------------------------------
40 REVISION HISTORY
41
42 Description: Updated template used to PV coding template.
43 Changed to accept the pOverflow flag for EPOC compatibility.
44
45 Description: Replaced OSCL mem type functions and eliminated include
46 files that now are chosen by OSCL definitions
47
48 Description: Replaced "int" and/or "char" with OSCL defined types.
49
50 Description:
51
52 ------------------------------------------------------------------------------
53 MODULE DESCRIPTION
54
55
56 ------------------------------------------------------------------------------
57 */
58
59 /*----------------------------------------------------------------------------
60 ; INCLUDES
61 ----------------------------------------------------------------------------*/
62 #include <stdlib.h>
63
64 #include "g_adapt.h"
65 #include "typedef.h"
66 #include "basic_op.h"
67 #include "oper_32b.h"
68 #include "cnst.h"
69 #include "gmed_n.h"
70
71 /*----------------------------------------------------------------------------
72 ; MACROS
73 ; Define module specific macros here
74 ----------------------------------------------------------------------------*/
75
76 /*----------------------------------------------------------------------------
77 ; DEFINES
78 ; Include all pre-processor statements here. Include conditional
79 ; compile variables also.
80 ----------------------------------------------------------------------------*/
81 #define LTP_GAIN_THR1 2721 /* 2721 Q13 = 0.3322 ~= 1.0 / (10*log10(2)) */
82 #define LTP_GAIN_THR2 5443 /* 5443 Q13 = 0.6644 ~= 2.0 / (10*log10(2)) */
83
84 /*----------------------------------------------------------------------------
85 ; LOCAL FUNCTION DEFINITIONS
86 ; Function Prototype declaration
87 ----------------------------------------------------------------------------*/
88
89 /*----------------------------------------------------------------------------
90 ; LOCAL VARIABLE DEFINITIONS
91 ; Variable declaration - defined here and used outside this module
92 ----------------------------------------------------------------------------*/
93
94
95 /*
96 ------------------------------------------------------------------------------
97 FUNCTION NAME: gain_adapt_init
98 ------------------------------------------------------------------------------
99 INPUT AND OUTPUT DEFINITIONS
100
101 Inputs:
102 st -- double pointer to GainAdaptState
103
104 Outputs:
105 st -- double ponter to GainAdaptState
106
107 Returns:
108 -1 if an error occurs during memory initialization
109 0 if OK
110
111 Global Variables Used:
112 None
113
114 Local Variables Needed:
115 None
116
117 ------------------------------------------------------------------------------
118 FUNCTION DESCRIPTION
119
120 Allocates state memory and initializes state memory
121
122 ------------------------------------------------------------------------------
123 REQUIREMENTS
124
125 None
126
127 ------------------------------------------------------------------------------
128 REFERENCES
129
130 g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
131
132 ------------------------------------------------------------------------------
133 PSEUDO-CODE
134
135
136 ------------------------------------------------------------------------------
137 RESOURCES USED [optional]
138
139 When the code is written for a specific target processor the
140 the resources used should be documented below.
141
142 HEAP MEMORY USED: x bytes
143
144 STACK MEMORY USED: x bytes
145
146 CLOCK CYCLES: (cycle count equation for this function) + (variable
147 used to represent cycle count for each subroutine
148 called)
149 where: (cycle count variable) = cycle count for [subroutine
150 name]
151
152 ------------------------------------------------------------------------------
153 CAUTION [optional]
154 [State any special notes, constraints or cautions for users of this function]
155
156 ------------------------------------------------------------------------------
157 */
158
gain_adapt_init(GainAdaptState ** st)159 Word16 gain_adapt_init(GainAdaptState **st)
160 {
161 GainAdaptState* s;
162
163 if (st == (GainAdaptState **) NULL)
164 {
165 /* fprintf(stderr, "gain_adapt_init: invalid parameter\n"); */
166 return -1;
167 }
168 *st = NULL;
169
170 /* allocate memory */
171 if ((s = (GainAdaptState *) malloc(sizeof(GainAdaptState))) == NULL)
172 {
173 /* fprintf(stderr, "gain_adapt_init: can't malloc state structure\n"); */
174 return -1;
175 }
176 gain_adapt_reset(s);
177 *st = s;
178
179 return 0;
180 }
181
182 /*
183 ------------------------------------------------------------------------------
184 FUNCTION NAME: gain_adapt_reset
185 ------------------------------------------------------------------------------
186 INPUT AND OUTPUT DEFINITIONS
187
188 Inputs:
189 st -- double pointer to GainAdaptState
190
191 Outputs:
192 st -- double ponter to GainAdaptState
193
194 Returns:
195 -1 if an error occurs
196 0 if OK
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 REQUIREMENTS
210
211 None
212
213 ------------------------------------------------------------------------------
214 REFERENCES
215
216 g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
217
218 ------------------------------------------------------------------------------
219 PSEUDO-CODE
220
221
222 ------------------------------------------------------------------------------
223 RESOURCES USED [optional]
224
225 When the code is written for a specific target processor the
226 the resources used should be documented below.
227
228 HEAP MEMORY USED: x bytes
229
230 STACK MEMORY USED: x bytes
231
232 CLOCK CYCLES: (cycle count equation for this function) + (variable
233 used to represent cycle count for each subroutine
234 called)
235 where: (cycle count variable) = cycle count for [subroutine
236 name]
237
238 ------------------------------------------------------------------------------
239 CAUTION [optional]
240 [State any special notes, constraints or cautions for users of this function]
241
242 ------------------------------------------------------------------------------
243 */
244
gain_adapt_reset(GainAdaptState * st)245 Word16 gain_adapt_reset(GainAdaptState *st)
246 {
247 Word16 i;
248
249 if (st == (GainAdaptState *) NULL)
250 {
251 /* fprintf(stderr, "gain_adapt_reset: invalid parameter\n"); */
252 return -1;
253 }
254
255 st->onset = 0;
256 st->prev_alpha = 0;
257 st->prev_gc = 0;
258
259 for (i = 0; i < LTPG_MEM_SIZE; i++)
260 {
261 st->ltpg_mem[i] = 0;
262 }
263
264 return 0;
265 }
266
267
268 /*
269 ------------------------------------------------------------------------------
270 FUNCTION NAME: gain_adapt_exit
271 ------------------------------------------------------------------------------
272 INPUT AND OUTPUT DEFINITIONS
273
274 Inputs:
275 st -- double pointer to GainAdaptState
276
277 Outputs:
278 None
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 REQUIREMENTS
295
296 None
297
298 ------------------------------------------------------------------------------
299 REFERENCES
300
301 g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
302
303 ------------------------------------------------------------------------------
304 PSEUDO-CODE
305
306
307 ------------------------------------------------------------------------------
308 RESOURCES USED [optional]
309
310 When the code is written for a specific target processor the
311 the resources used should be documented below.
312
313 HEAP MEMORY USED: x bytes
314
315 STACK MEMORY USED: x bytes
316
317 CLOCK CYCLES: (cycle count equation for this function) + (variable
318 used to represent cycle count for each subroutine
319 called)
320 where: (cycle count variable) = cycle count for [subroutine
321 name]
322
323 ------------------------------------------------------------------------------
324 CAUTION [optional]
325 [State any special notes, constraints or cautions for users of this function]
326
327 ------------------------------------------------------------------------------
328 */
329
gain_adapt_exit(GainAdaptState ** st)330 void gain_adapt_exit(GainAdaptState **st)
331 {
332 if (st == NULL || *st == NULL)
333 return;
334
335 /* deallocate memory */
336 free(*st);
337 *st = NULL;
338
339 return;
340 }
341
342 /*
343 ------------------------------------------------------------------------------
344 FUNCTION NAME: gain_adapt
345 ------------------------------------------------------------------------------
346 INPUT AND OUTPUT DEFINITIONS
347
348 Inputs:
349 st -- double pointer to GainAdaptState
350 ltpg -- Word16 -- ltp coding gain (log2()), Q13
351 gain_cod -- Word16 -- code gain, Q1
352
353 Outputs:
354 alpha -- Pointer to Word16 -- gain adaptation factor, Q15
355 pOverflow -- Pointer to Flag -- overflow indicator
356
357 Returns:
358 None
359
360 Global Variables Used:
361 None
362
363 Local Variables Needed:
364 None
365
366 ------------------------------------------------------------------------------
367 FUNCTION DESCRIPTION
368
369 Purpose: calculate pitch/codebook gain adaptation factor alpha
370 (and update the adaptor state)
371
372 ------------------------------------------------------------------------------
373 REQUIREMENTS
374
375 None
376
377 ------------------------------------------------------------------------------
378 REFERENCES
379
380 g_adapt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
381
382 ------------------------------------------------------------------------------
383 PSEUDO-CODE
384
385
386 ------------------------------------------------------------------------------
387 RESOURCES USED [optional]
388
389 When the code is written for a specific target processor the
390 the resources used should be documented below.
391
392 HEAP MEMORY USED: x bytes
393
394 STACK MEMORY USED: x bytes
395
396 CLOCK CYCLES: (cycle count equation for this function) + (variable
397 used to represent cycle count for each subroutine
398 called)
399 where: (cycle count variable) = cycle count for [subroutine
400 name]
401
402 ------------------------------------------------------------------------------
403 CAUTION [optional]
404 [State any special notes, constraints or cautions for users of this function]
405
406 ------------------------------------------------------------------------------
407 */
408
gain_adapt(GainAdaptState * st,Word16 ltpg,Word16 gain_cod,Word16 * alpha,Flag * pOverflow)409 void gain_adapt(
410 GainAdaptState *st, /* i : state struct */
411 Word16 ltpg, /* i : ltp coding gain (log2()), Q13 */
412 Word16 gain_cod, /* i : code gain, Q1 */
413 Word16 *alpha, /* o : gain adaptation factor, Q15 */
414 Flag *pOverflow
415 )
416 {
417 Word16 adapt; /* adaptdation status; 0, 1, or 2 */
418 Word16 result; /* alpha factor, Q13 */
419 Word16 filt; /* median-filtered LTP coding gain, Q13 */
420 Word16 tmp;
421 Word16 i;
422
423 /* basic adaptation */
424 if (ltpg <= LTP_GAIN_THR1)
425 {
426 adapt = 0;
427 }
428 else
429 {
430 if (ltpg <= LTP_GAIN_THR2)
431 {
432 adapt = 1;
433 }
434 else
435 {
436 adapt = 2;
437 }
438 }
439
440 /*
441 * // onset indicator
442 * if ((cbGain > onFact * cbGainMem[0]) && (cbGain > 100.0))
443 * onset = 8;
444 * else
445 * if (onset)
446 * onset--;
447 */
448 /* tmp = cbGain / onFact; onFact = 2.0; 200 Q1 = 100.0 */
449 tmp = shr_r(gain_cod, 1, pOverflow);
450
451 if ((tmp > st->prev_gc) && (gain_cod > 200))
452 {
453 st->onset = 8;
454 }
455 else
456 {
457 if (st->onset != 0)
458 {
459 st->onset = sub(st->onset, 1, pOverflow);
460 }
461 }
462
463 /*
464 * // if onset, increase adaptor state
465 * if (onset && (gainAdapt < 2)) gainAdapt++;
466 */
467 if ((st->onset != 0) && (adapt < 2))
468 {
469 adapt = add(adapt, 1, pOverflow);
470 }
471
472 st->ltpg_mem[0] = ltpg;
473 filt = gmed_n(st->ltpg_mem, 5); /* function result */
474
475 if (adapt == 0)
476 {
477 if (filt > 5443) /* 5443 Q13 = 0.66443... */
478 {
479 result = 0;
480 }
481 else
482 {
483 if (filt < 0)
484 {
485 result = 16384; /* 16384 Q15 = 0.5 */
486 }
487 else
488 { /* result = 0.5 - 0.75257499*filt */
489 /* result (Q15) = 16384 - 24660 * (filt << 2) */
490 filt = shl(filt, 2, pOverflow); /* Q15 */
491 result = mult(24660, filt, pOverflow);
492 result = sub(16384, result, pOverflow);
493 }
494 }
495 }
496 else
497 {
498 result = 0;
499 }
500 /*
501 * if (prevAlpha == 0.0) result = 0.5 * (result + prevAlpha);
502 */
503 if (st->prev_alpha == 0)
504 {
505 result = shr(result, 1, pOverflow);
506 }
507
508 /* store the result */
509 *alpha = result;
510
511 /* update adapter state memory */
512 st->prev_alpha = result;
513 st->prev_gc = gain_cod;
514
515 for (i = LTPG_MEM_SIZE - 1; i > 0; i--)
516 {
517 st->ltpg_mem[i] = st->ltpg_mem[i-1];
518 }
519 /* mem[0] is just present for convenience in calling the gmed_n[5]
520 * function above. The memory depth is really LTPG_MEM_SIZE-1.
521 */
522 }
523