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 Pathname: ./audio/gsm-amr/c/src/gc_pred.c
32 Functions:
33 gc_pred_reset
34 gc_pred
35 gc_pred_update
36 gc_pred_average_limited
37
38 ------------------------------------------------------------------------------
39 MODULE DESCRIPTION
40
41 This file contains the functions that perform codebook gain MA prediction.
42
43 ------------------------------------------------------------------------------
44 */
45
46 /*----------------------------------------------------------------------------
47 ; INCLUDES
48 ----------------------------------------------------------------------------*/
49 #include "gc_pred.h"
50 #include "basicop_malloc.h"
51 #include "basic_op.h"
52 #include "cnst.h"
53 #include "log2.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 NPRED 4 /* number of prediction taps */
66
67 /* average innovation energy. */
68 /* MEAN_ENER = 36.0/constant, constant = 20*Log10(2) */
69 #define MEAN_ENER_MR122 783741L /* 36/(20*log10(2)) (Q17) */
70
71 /* minimum quantized energy: -14 dB */
72 #define MIN_ENERGY (-14336) /* 14 Q10 */
73 #define MIN_ENERGY_MR122 (-2381) /* 14 / (20*log10(2)) Q10 */
74
75 /*----------------------------------------------------------------------------
76 ; LOCAL FUNCTION DEFINITIONS
77 ; Function Prototype declaration
78 ----------------------------------------------------------------------------*/
79
80 /*----------------------------------------------------------------------------
81 ; LOCAL VARIABLE DEFINITIONS
82 ; Variable declaration - defined here and used outside this module
83 ----------------------------------------------------------------------------*/
84
85 /* MA prediction coefficients (Q13) */
86 static const Word16 pred[NPRED] = {5571, 4751, 2785, 1556};
87
88 /* MA prediction coefficients (Q6) */
89 static const Word16 pred_MR122[NPRED] = {44, 37, 22, 12};
90
91 /*
92 ------------------------------------------------------------------------------
93 FUNCTION NAME: gc_pred_reset
94 ------------------------------------------------------------------------------
95 INPUT AND OUTPUT DEFINITIONS
96
97 Inputs:
98 state = pointer to a structure of type gc_predState
99
100 Outputs:
101 past_qua_en field in the structure pointed to by state is initialized
102 to MIN_ENERGY
103 past_qua_en_MR122 field in the structure pointed to by state is
104 initialized to MIN_ENERGY_MR122
105
106 Returns:
107 return_value = 0, if reset was successful; -1, otherwise (int)
108
109 Global Variables Used:
110 None
111
112 Local Variables Needed:
113 None
114
115 ------------------------------------------------------------------------------
116 FUNCTION DESCRIPTION
117
118 This function initializes the state memory used by gc_pred to zero.
119
120 ------------------------------------------------------------------------------
121 REQUIREMENTS
122
123 None
124
125 ------------------------------------------------------------------------------
126 REFERENCES
127
128 gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
129
130 ------------------------------------------------------------------------------
131 PSEUDO-CODE
132
133 int gc_pred_reset (gc_predState *state)
134 {
135 Word16 i;
136
137 if (state == (gc_predState *) NULL){
138 fprintf(stderr, "gc_pred_reset: invalid parameter\n");
139 return -1;
140 }
141
142 for(i = 0; i < NPRED; i++)
143 {
144 state->past_qua_en[i] = MIN_ENERGY;
145 state->past_qua_en_MR122[i] = MIN_ENERGY_MR122;
146 }
147 return 0;
148 }
149
150 ------------------------------------------------------------------------------
151 RESOURCES USED [optional]
152
153 When the code is written for a specific target processor the
154 the resources used should be documented below.
155
156 HEAP MEMORY USED: x bytes
157
158 STACK MEMORY USED: x bytes
159
160 CLOCK CYCLES: (cycle count equation for this function) + (variable
161 used to represent cycle count for each subroutine
162 called)
163 where: (cycle count variable) = cycle count for [subroutine
164 name]
165
166 ------------------------------------------------------------------------------
167 CAUTION [optional]
168 [State any special notes, constraints or cautions for users of this function]
169
170 ------------------------------------------------------------------------------
171 */
172
gc_pred_reset(gc_predState * state)173 Word16 gc_pred_reset(gc_predState *state)
174 {
175 Word16 i;
176
177 if (state == (gc_predState *) NULL)
178 {
179 /* fprintf(stderr, "gc_pred_reset: invalid parameter\n"); */
180 return -1;
181 }
182
183 for (i = 0; i < NPRED; i++)
184 {
185 state->past_qua_en[i] = MIN_ENERGY;
186 state->past_qua_en_MR122[i] = MIN_ENERGY_MR122;
187 }
188
189 return(0);
190 }
191
192 /****************************************************************************/
193
194 /*
195 ------------------------------------------------------------------------------
196 FUNCTION NAME: gc_pred
197 ------------------------------------------------------------------------------
198 INPUT AND OUTPUT DEFINITIONS
199
200 Inputs:
201 st = pointer to a structure of type gc_predState
202 mode = AMR mode (enum Mode)
203 code = pointer to the innovative codebook vector; Q12 in MR122 mode,
204 otherwise, Q13 (Word16)
205 exp_gcode0 = pointer to the exponent part of predicted gain factor
206 (Q0) (Word16)
207 frac_gcode0 = pointer to the fractional part of predicted gain factor
208 (Q15) (Word16)
209 exp_en = pointer to the exponent part of the innovation energy; this
210 is calculated for MR795 mode, Q0 (Word16)
211 frac_en = pointer to the fractional part of the innovation energy;
212 this is calculated for MR795 mode, Q15 (Word16)
213 pOverflow = pointer to overflow (Flag)
214
215 Outputs:
216 store pointed to by exp_gcode0 contains the exponent part of the
217 recently calculated predicted gain factor
218 store pointed to by frac_gcode0 contains the fractional part of the
219 recently calculated predicted gain factor
220 store pointed to by exp_en contains the exponent part of the
221 recently calculated innovation energy
222 store pointed to by frac_en contains the fractional part of the
223 recently calculated innovation energy
224 pOverflow = 1 if the math functions called by gc_pred
225 results in overflow else zero.
226
227 Returns:
228 None
229
230 Global Variables Used:
231 None
232
233 Local Variables Needed:
234 pred = table of MA prediction coefficients (Q13) (Word16)
235 pred_MR122 = table of MA prediction coefficients (Q6) (Word16)
236
237 ------------------------------------------------------------------------------
238 FUNCTION DESCRIPTION
239
240 This function performs the MA prediction of the innovation energy (in
241 dB/(20*log10(2))), with the mean removed.
242
243 ------------------------------------------------------------------------------
244 REQUIREMENTS
245
246 None
247
248 ------------------------------------------------------------------------------
249 REFERENCES
250
251 gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
252
253 ------------------------------------------------------------------------------
254 PSEUDO-CODE
255
256 The original etsi reference code uses a global flag Overflow. However, in the
257 actual implementation a pointer to a the overflow flag is passed in.
258
259 void
260 gc_pred(
261 gc_predState *st, // i/o: State struct
262 enum Mode mode, // i : AMR mode
263 Word16 *code, // i : innovative codebook vector (L_SUBFR)
264 // MR122: Q12, other modes: Q13
265 Word16 *exp_gcode0, // o : exponent of predicted gain factor, Q0
266 Word16 *frac_gcode0,// o : fraction of predicted gain factor Q15
267 Word16 *exp_en, // o : exponent of innovation energy, Q0
268 // (only calculated for MR795)
269 Word16 *frac_en // o : fraction of innovation energy, Q15
270 // (only calculated for MR795)
271 )
272 {
273 Word16 i;
274 Word32 ener_code;
275 Word16 exp, frac;
276
277 *-------------------------------------------------------------------*
278 * energy of code: *
279 * ~~~~~~~~~~~~~~~ *
280 * ener_code = sum(code[i]^2) *
281 *-------------------------------------------------------------------*
282 ener_code = L_mac((Word32) 0, code[0], code[0]);
283 // MR122: Q12*Q12 -> Q25
284 // others: Q13*Q13 -> Q27
285 for (i = 1; i < L_SUBFR; i++)
286 ener_code = L_mac(ener_code, code[i], code[i]);
287
288 if (sub (mode, MR122) == 0)
289 {
290 Word32 ener;
291
292 // ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20
293 ener_code = L_mult (pv_round (ener_code), 26214); // Q9 * Q20 -> Q30
294
295 *-------------------------------------------------------------------*
296 * energy of code: *
297 * ~~~~~~~~~~~~~~~ *
298 * ener_code(Q17) = 10 * Log10(energy) / constant *
299 * = 1/2 * Log2(energy) *
300 * constant = 20*Log10(2) *
301 *-------------------------------------------------------------------*
302 // ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30
303 Log2(ener_code, &exp, &frac);
304 ener_code = L_Comp (sub (exp, 30), frac); // Q16 for log()
305 // ->Q17 for 1/2 log()
306
307 *-------------------------------------------------------------------*
308 * predicted energy: *
309 * ~~~~~~~~~~~~~~~~~ *
310 * ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant *
311 * = MEAN_ENER + sum(pred[i]*past_qua_en[i]) *
312 * constant = 20*Log10(2) *
313 *-------------------------------------------------------------------*
314
315 ener = MEAN_ENER_MR122; // Q24 (Q17)
316 for (i = 0; i < NPRED; i++)
317 {
318 ener = L_mac (ener, st->past_qua_en_MR122[i], pred_MR122[i]);
319 // Q10 * Q13 -> Q24
320 // Q10 * Q6 -> Q17
321 }
322
323 *-------------------------------------------------------------------*
324 * predicted codebook gain *
325 * ~~~~~~~~~~~~~~~~~~~~~~~ *
326 * gc0 = Pow10( (ener*constant - ener_code*constant) / 20 ) *
327 * = Pow2(ener-ener_code) *
328 * = Pow2(int(d)+frac(d)) *
329 * *
330 * (store exp and frac for pow2()) *
331 *-------------------------------------------------------------------*
332
333 ener = L_shr (L_sub (ener, ener_code), 1); // Q16
334 L_Extract(ener, exp_gcode0, frac_gcode0);
335 }
336 else // all modes except 12.2
337 {
338 Word32 L_tmp;
339 Word16 exp_code, gcode0;
340
341 *-----------------------------------------------------------------*
342 * Compute: means_ener - 10log10(ener_code/ L_sufr) *
343 *-----------------------------------------------------------------*
344
345 exp_code = norm_l (ener_code);
346 ener_code = L_shl (ener_code, exp_code);
347
348 // Log2 = log2 + 27
349 Log2_norm (ener_code, exp_code, &exp, &frac);
350
351 // fact = 10/log2(10) = 3.01 = 24660 Q13
352 L_tmp = Mpy_32_16(exp, frac, -24660); // Q0.Q15 * Q13 -> Q14
353
354 * L_tmp = means_ener - 10log10(ener_code/L_SUBFR)
355 * = means_ener - 10log10(ener_code) + 10log10(L_SUBFR)
356 * = K - fact * Log2(ener_code)
357 * = K - fact * log2(ener_code) - fact*27
358 *
359 * ==> K = means_ener + fact*27 + 10log10(L_SUBFR)
360 *
361 * means_ener = 33 = 540672 Q14 (MR475, MR515, MR59)
362 * means_ener = 28.75 = 471040 Q14 (MR67)
363 * means_ener = 30 = 491520 Q14 (MR74)
364 * means_ener = 36 = 589824 Q14 (MR795)
365 * means_ener = 33 = 540672 Q14 (MR102)
366 * 10log10(L_SUBFR) = 16.02 = 262481.51 Q14
367 * fact * 27 = 1331640 Q14
368 * -----------------------------------------
369 * (MR475, MR515, MR59) K = 2134793.51 Q14 ~= 16678 * 64 * 2
370 * (MR67) K = 2065161.51 Q14 ~= 32268 * 32 * 2
371 * (MR74) K = 2085641.51 Q14 ~= 32588 * 32 * 2
372 * (MR795) K = 2183945.51 Q14 ~= 17062 * 64 * 2
373 * (MR102) K = 2134793.51 Q14 ~= 16678 * 64 * 2
374
375
376 if (sub (mode, MR102) == 0)
377 {
378 // mean = 33 dB
379 L_tmp = L_mac(L_tmp, 16678, 64); // Q14
380 }
381 else if (sub (mode, MR795) == 0)
382 {
383 // ener_code = <xn xn> * 2^27*2^exp_code
384 // frac_en = ener_code / 2^16
385 // = <xn xn> * 2^11*2^exp_code
386 // <xn xn> = <xn xn>*2^11*2^exp * 2^exp_en
387 // := frac_en * 2^exp_en
388
389 // ==> exp_en = -11-exp_code;
390
391 *frac_en = extract_h (ener_code);
392 *exp_en = sub (-11, exp_code);
393
394 // mean = 36 dB
395 L_tmp = L_mac(L_tmp, 17062, 64); // Q14
396 }
397 else if (sub (mode, MR74) == 0)
398 {
399 // mean = 30 dB
400 L_tmp = L_mac(L_tmp, 32588, 32); // Q14
401 }
402 else if (sub (mode, MR67) == 0)
403 {
404 // mean = 28.75 dB
405 L_tmp = L_mac(L_tmp, 32268, 32); // Q14
406 }
407 else // MR59, MR515, MR475
408 {
409 // mean = 33 dB
410 L_tmp = L_mac(L_tmp, 16678, 64); // Q14
411 }
412
413 *-----------------------------------------------------------------*
414 * Compute gcode0. *
415 * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener *
416 *-----------------------------------------------------------------*
417
418 L_tmp = L_shl(L_tmp, 10); // Q24
419 for (i = 0; i < 4; i++)
420 L_tmp = L_mac(L_tmp, pred[i], st->past_qua_en[i]);
421 // Q13 * Q10 -> Q24
422
423 gcode0 = extract_h(L_tmp); // Q8
424
425 *-----------------------------------------------------------------*
426 * gcode0 = pow(10.0, gcode0/20) *
427 * = pow(2, 3.3219*gcode0/20) *
428 * = pow(2, 0.166*gcode0) *
429 *-----------------------------------------------------------------*
430
431 // 5439 Q15 = 0.165985
432 // (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15)
433 if (sub (mode, MR74) == 0) // For IS641 bitexactness
434 L_tmp = L_mult(gcode0, 5439); // Q8 * Q15 -> Q24
435 else
436 L_tmp = L_mult(gcode0, 5443); // Q8 * Q15 -> Q24
437
438 L_tmp = L_shr(L_tmp, 8); // -> Q16
439 L_Extract(L_tmp, exp_gcode0, frac_gcode0); // -> Q0.Q15
440 }
441 }
442
443 ------------------------------------------------------------------------------
444 RESOURCES USED [optional]
445
446 When the code is written for a specific target processor the
447 the resources used should be documented below.
448
449 HEAP MEMORY USED: x bytes
450
451 STACK MEMORY USED: x bytes
452
453 CLOCK CYCLES: (cycle count equation for this function) + (variable
454 used to represent cycle count for each subroutine
455 called)
456 where: (cycle count variable) = cycle count for [subroutine
457 name]
458
459 ------------------------------------------------------------------------------
460 CAUTION [optional]
461 [State any special notes, constraints or cautions for users of this function]
462
463 ------------------------------------------------------------------------------
464 */
465
gc_pred(gc_predState * st,enum Mode mode,Word16 * code,Word16 * exp_gcode0,Word16 * frac_gcode0,Word16 * exp_en,Word16 * frac_en,Flag * pOverflow)466 void gc_pred(
467 gc_predState *st, /* i/o: State struct */
468 enum Mode mode, /* i : AMR mode */
469 Word16 *code, /* i : innovative codebook vector (L_SUBFR) */
470 /* MR122: Q12, other modes: Q13 */
471 Word16 *exp_gcode0, /* o : exponent of predicted gain factor, Q0 */
472 Word16 *frac_gcode0,/* o : fraction of predicted gain factor Q15 */
473 Word16 *exp_en, /* o : exponent of innovation energy, Q0 */
474 /* (only calculated for MR795) */
475 Word16 *frac_en, /* o : fraction of innovation energy, Q15 */
476 /* (only calculated for MR795) */
477 Flag *pOverflow
478 )
479 {
480 Word16 i;
481 Word32 L_temp1, L_temp2;
482 Word32 L_tmp;
483 Word32 ener_code;
484 Word32 ener;
485 Word16 exp, frac;
486 Word16 exp_code, gcode0;
487 Word16 tmp;
488 Word16 *p_code = &code[0];
489
490 /*-------------------------------------------------------------------*
491 * energy of code: *
492 * ~~~~~~~~~~~~~~~ *
493 * ener_code = sum(code[i]^2) *
494 *-------------------------------------------------------------------*/
495 ener_code = 0;
496
497 /* MR122: Q12*Q12 -> Q25 */
498 /* others: Q13*Q13 -> Q27 */
499
500 for (i = L_SUBFR >> 2; i != 0; i--)
501 {
502 tmp = *(p_code++);
503 ener_code += ((Word32) tmp * tmp) >> 3;
504 tmp = *(p_code++);
505 ener_code += ((Word32) tmp * tmp) >> 3;
506 tmp = *(p_code++);
507 ener_code += ((Word32) tmp * tmp) >> 3;
508 tmp = *(p_code++);
509 ener_code += ((Word32) tmp * tmp) >> 3;
510 }
511
512 ener_code <<= 4;
513
514 if (ener_code < 0) /* Check for saturation */
515 {
516 ener_code = MAX_32;
517 }
518
519 if (mode == MR122)
520 {
521 /* ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20 */
522 /* Q9 * Q20 -> Q30 */
523
524 ener_code = ((Word32)(pv_round(ener_code, pOverflow) * 26214)) << 1;
525
526 /*-------------------------------------------------------------*
527 * energy of code: *
528 * ~~~~~~~~~~~~~~~ *
529 * ener_code(Q17) = 10 * Log10(energy) / constant *
530 * = 1/2 * Log2(energy) *
531 * constant = 20*Log10(2) *
532 *-------------------------------------------------------------*/
533 /* ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30 */
534 Log2(ener_code, &exp, &frac, pOverflow);
535
536 /* Q16 for log() */
537 /* ->Q17 for 1/2 log()*/
538
539 L_temp1 = (Word32)(exp - 30) << 16;
540 ener_code = L_temp1 + ((Word32)frac << 1);
541
542 /*-------------------------------------------------------------*
543 * predicted energy: *
544 * ~~~~~~~~~~~~~~~~~ *
545 * ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant *
546 * = MEAN_ENER + sum(pred[i]*past_qua_en[i]) *
547 * constant = 20*Log10(2) *
548 *-------------------------------------------------------------*/
549
550 ener = MEAN_ENER_MR122; /* Q24 (Q17) */
551 for (i = 0; i < NPRED; i++)
552 {
553 L_temp1 = (((Word32) st->past_qua_en_MR122[i]) *
554 pred_MR122[i]) << 1;
555 ener = L_add(ener, L_temp1, pOverflow);
556
557 /* Q10 * Q13 -> Q24 */
558 /* Q10 * Q6 -> Q17 */
559 }
560
561 /*---------------------------------------------------------------*
562 * predicted codebook gain *
563 * ~~~~~~~~~~~~~~~~~~~~~~~ *
564 * gc0 = Pow10( (ener*constant - ener_code*constant) / 20 ) *
565 * = Pow2(ener-ener_code) *
566 * = Pow2(int(d)+frac(d)) *
567 * *
568 * (store exp and frac for pow2()) *
569 *---------------------------------------------------------------*/
570 /* Q16 */
571
572 L_temp1 = L_sub(ener, ener_code, pOverflow);
573
574
575 *exp_gcode0 = (Word16)(L_temp1 >> 17);
576
577 L_temp2 = (Word32) * exp_gcode0 << 15;
578 L_temp1 >>= 2;
579
580 *frac_gcode0 = (Word16)(L_temp1 - L_temp2);
581
582 }
583 else /* all modes except 12.2 */
584 {
585 /*-----------------------------------------------------------------*
586 * Compute: means_ener - 10log10(ener_code/ L_sufr) *
587 *-----------------------------------------------------------------*/
588
589 exp_code = norm_l(ener_code);
590 ener_code = L_shl(ener_code, exp_code, pOverflow);
591
592 /* Log2 = log2 + 27 */
593 Log2_norm(ener_code, exp_code, &exp, &frac);
594
595 /* fact = 10/log2(10) = 3.01 = 24660 Q13 */
596 /* Q0.Q15 * Q13 -> Q14 */
597
598 L_temp2 = (((Word32) exp) * -24660) << 1;
599 L_tmp = (((Word32) frac) * -24660) >> 15;
600
601 /* Sign-extend resulting product */
602 if (L_tmp & (Word32) 0x00010000L)
603 {
604 L_tmp = L_tmp | (Word32) 0xffff0000L;
605 }
606
607 L_tmp = L_tmp << 1;
608 L_tmp = L_add(L_tmp, L_temp2, pOverflow);
609
610
611 /* L_tmp = means_ener - 10log10(ener_code/L_SUBFR)
612 * = means_ener - 10log10(ener_code) + 10log10(L_SUBFR)
613 * = K - fact * Log2(ener_code)
614 * = K - fact * log2(ener_code) - fact*27
615 *
616 * ==> K = means_ener + fact*27 + 10log10(L_SUBFR)
617 *
618 * means_ener = 33 = 540672 Q14 (MR475, MR515, MR59)
619 * means_ener = 28.75 = 471040 Q14 (MR67)
620 * means_ener = 30 = 491520 Q14 (MR74)
621 * means_ener = 36 = 589824 Q14 (MR795)
622 * means_ener = 33 = 540672 Q14 (MR102)
623 * 10log10(L_SUBFR) = 16.02 = 262481.51 Q14
624 * fact * 27 = 1331640 Q14
625 * -----------------------------------------
626 * (MR475, MR515, MR59) K = 2134793.51 Q14 ~= 16678 * 64 * 2
627 * (MR67) K = 2065161.51 Q14 ~= 32268 * 32 * 2
628 * (MR74) K = 2085641.51 Q14 ~= 32588 * 32 * 2
629 * (MR795) K = 2183945.51 Q14 ~= 17062 * 64 * 2
630 * (MR102) K = 2134793.51 Q14 ~= 16678 * 64 * 2
631 */
632
633 if (mode == MR102)
634 {
635 /* mean = 33 dB */
636 L_temp2 = (Word32) 16678 << 7;
637 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */
638 }
639 else if (mode == MR795)
640 {
641 /* ener_code = <xn xn> * 2^27*2^exp_code
642 frac_en = ener_code / 2^16
643 = <xn xn> * 2^11*2^exp_code
644 <xn xn> = <xn xn>*2^11*2^exp * 2^exp_en
645 : = frac_en * 2^exp_en
646 ==> exp_en = -11-exp_code; */
647 *frac_en = (Word16)(ener_code >> 16);
648 *exp_en = sub(-11, exp_code, pOverflow);
649
650 /* mean = 36 dB */
651 L_temp2 = (Word32) 17062 << 7;
652 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */
653 }
654 else if (mode == MR74)
655 {
656 /* mean = 30 dB */
657 L_temp2 = (Word32) 32588 << 6;
658 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */
659 }
660 else if (mode == MR67)
661 {
662 /* mean = 28.75 dB */
663 L_temp2 = (Word32) 32268 << 6;
664 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */
665 }
666 else /* MR59, MR515, MR475 */
667 {
668 /* mean = 33 dB */
669 L_temp2 = (Word32) 16678 << 7;
670 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */
671 }
672
673 /*-------------------------------------------------------------*
674 * Compute gcode0. *
675 * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener *
676 *--------------------------------------------------------------*/
677 /* Q24 */
678 if (L_tmp > (Word32) 0X001fffffL)
679 {
680 *pOverflow = 1;
681 L_tmp = MAX_32;
682 }
683 else if (L_tmp < (Word32) 0xffe00000L)
684 {
685 *pOverflow = 1;
686 L_tmp = MIN_32;
687 }
688 else
689 {
690 L_tmp = L_tmp << 10;
691 }
692
693 for (i = 0; i < 4; i++)
694 {
695 L_temp2 = ((((Word32) pred[i]) * st->past_qua_en[i]) << 1);
696 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q13 * Q10 -> Q24 */
697 }
698
699 gcode0 = (Word16)(L_tmp >> 16); /* Q8 */
700
701 /*-----------------------------------------------------------*
702 * gcode0 = pow(10.0, gcode0/20) *
703 * = pow(2, 3.3219*gcode0/20) *
704 * = pow(2, 0.166*gcode0) *
705 *-----------------------------------------------------------*/
706
707 /* 5439 Q15 = 0.165985 */
708 /* (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15) */
709
710 if (mode == MR74) /* For IS641 bitexactness */
711 {
712 L_tmp = (((Word32) gcode0) * 5439) << 1; /* Q8 * Q15 -> Q24 */
713 }
714 else
715 {
716 L_tmp = (((Word32) gcode0) * 5443) << 1; /* Q8 * Q15 -> Q24 */
717 }
718
719 if (L_tmp < 0)
720 {
721 L_tmp = ~((~L_tmp) >> 8);
722 }
723 else
724 {
725 L_tmp = L_tmp >> 8; /* -> Q16 */
726 }
727
728 *exp_gcode0 = (Word16)(L_tmp >> 16);
729 if (L_tmp < 0)
730 {
731 L_temp1 = ~((~L_tmp) >> 1);
732 }
733 else
734 {
735 L_temp1 = L_tmp >> 1;
736 }
737 L_temp2 = (Word32) * exp_gcode0 << 15;
738 *frac_gcode0 = (Word16)(L_sub(L_temp1, L_temp2, pOverflow));
739 /* -> Q0.Q15 */
740 }
741
742 return;
743 }
744
745 /****************************************************************************/
746
747 /*
748 ------------------------------------------------------------------------------
749 FUNCTION NAME: gc_pred_update
750 ------------------------------------------------------------------------------
751 INPUT AND OUTPUT DEFINITIONS
752
753 Inputs:
754 st = pointer to a structure of type gc_predState
755 qua_ener_MR122 = quantized energy for update (Q10); calculated as
756 (log2(qua_err)) (Word16)
757 qua_ener = quantized energy for update (Q10); calculated as
758 (20*log10(qua_err)) (Word16)
759
760 Outputs:
761 structure pointed to by st contains the calculated quantized energy
762 for update
763
764 Returns:
765 None
766
767 Global Variables Used:
768 None
769
770 Local Variables Needed:
771 None
772
773 ------------------------------------------------------------------------------
774 FUNCTION DESCRIPTION
775
776 This function updates the MA predictor with the last quantized energy.
777
778 ------------------------------------------------------------------------------
779 REQUIREMENTS
780
781 None
782
783 ------------------------------------------------------------------------------
784 REFERENCES
785
786 gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
787
788 ------------------------------------------------------------------------------
789 PSEUDO-CODE
790
791 void gc_pred_update(
792 gc_predState *st, // i/o: State struct
793 Word16 qua_ener_MR122, // i : quantized energy for update, Q10
794 // (log2(qua_err))
795 Word16 qua_ener // i : quantized energy for update, Q10
796 // (20*log10(qua_err))
797 )
798 {
799 Word16 i;
800
801 for (i = 3; i > 0; i--)
802 {
803 st->past_qua_en[i] = st->past_qua_en[i - 1];
804 st->past_qua_en_MR122[i] = st->past_qua_en_MR122[i - 1];
805 }
806
807 st->past_qua_en_MR122[0] = qua_ener_MR122; // log2 (qua_err), Q10
808
809 st->past_qua_en[0] = qua_ener; // 20*log10(qua_err), Q10
810
811 }
812
813 ------------------------------------------------------------------------------
814 RESOURCES USED [optional]
815
816 When the code is written for a specific target processor the
817 the resources used should be documented below.
818
819 HEAP MEMORY USED: x bytes
820
821 STACK MEMORY USED: x bytes
822
823 CLOCK CYCLES: (cycle count equation for this function) + (variable
824 used to represent cycle count for each subroutine
825 called)
826 where: (cycle count variable) = cycle count for [subroutine
827 name]
828
829 ------------------------------------------------------------------------------
830 CAUTION [optional]
831 [State any special notes, constraints or cautions for users of this function]
832
833 ------------------------------------------------------------------------------
834 */
835
gc_pred_update(gc_predState * st,Word16 qua_ener_MR122,Word16 qua_ener)836 void gc_pred_update(
837 gc_predState *st, /* i/o: State struct */
838 Word16 qua_ener_MR122, /* i : quantized energy for update, Q10 */
839 /* (log2(qua_err)) */
840 Word16 qua_ener /* i : quantized energy for update, Q10 */
841 /* (20*log10(qua_err)) */
842 )
843 {
844 st->past_qua_en[3] = st->past_qua_en[2];
845 st->past_qua_en_MR122[3] = st->past_qua_en_MR122[2];
846
847 st->past_qua_en[2] = st->past_qua_en[1];
848 st->past_qua_en_MR122[2] = st->past_qua_en_MR122[1];
849
850 st->past_qua_en[1] = st->past_qua_en[0];
851 st->past_qua_en_MR122[1] = st->past_qua_en_MR122[0];
852
853 st->past_qua_en_MR122[0] = qua_ener_MR122; /* log2 (qua_err), Q10 */
854
855 st->past_qua_en[0] = qua_ener; /* 20*log10(qua_err), Q10 */
856
857 return;
858 }
859
860 /****************************************************************************/
861
862 /*
863 ------------------------------------------------------------------------------
864 FUNCTION NAME: gc_pred_average_limited
865 ------------------------------------------------------------------------------
866 INPUT AND OUTPUT DEFINITIONS
867
868 Inputs:
869 st = pointer to a structure of type gc_predState
870 ener_avg_MR122 = pointer to the averaged quantized energy (Q10);
871 calculated as (log2(qua_err)) (Word16)
872 ener_avg = pointer to the averaged quantized energy (Q10); calculated
873 as (20*log10(qua_err)) (Word16)
874 pOverflow = pointer to overflow (Flag)
875
876 Outputs:
877 store pointed to by ener_avg_MR122 contains the new averaged quantized
878 energy
879 store pointed to by ener_avg contains the new averaged quantized
880 energy
881 pOverflow = 1 if the math functions called by gc_pred_average_limited
882 results in overflow else zero.
883
884 Returns:
885 None
886
887 Global Variables Used:
888 None
889
890 Local Variables Needed:
891 None
892
893 ------------------------------------------------------------------------------
894 FUNCTION DESCRIPTION
895
896 This function calculates the average of MA predictor state values (with a
897 lower limit) used in error concealment.
898
899 ------------------------------------------------------------------------------
900 REQUIREMENTS
901
902 None
903
904 ------------------------------------------------------------------------------
905 REFERENCES
906
907 gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
908
909 ------------------------------------------------------------------------------
910 PSEUDO-CODE
911
912 The original etsi reference code uses a global flag Overflow. However, in the
913 actual implementation a pointer to a the overflow flag is passed in.
914
915 void gc_pred_average_limited(
916 gc_predState *st, // i: State struct
917 Word16 *ener_avg_MR122, // o: everaged quantized energy, Q10
918 // (log2(qua_err))
919 Word16 *ener_avg // o: averaged quantized energy, Q10
920 // (20*log10(qua_err))
921 )
922 {
923 Word16 av_pred_en;
924 Word16 i;
925
926 // do average in MR122 mode (log2() domain)
927 av_pred_en = 0;
928 for (i = 0; i < NPRED; i++)
929 {
930 av_pred_en = add (av_pred_en, st->past_qua_en_MR122[i]);
931 }
932
933 // av_pred_en = 0.25*av_pred_en
934 av_pred_en = mult (av_pred_en, 8192);
935
936 // if (av_pred_en < -14/(20Log10(2))) av_pred_en = ..
937
938 if (sub (av_pred_en, MIN_ENERGY_MR122) < 0)
939 {
940 av_pred_en = MIN_ENERGY_MR122;
941 }
942 *ener_avg_MR122 = av_pred_en;
943
944 // do average for other modes (20*log10() domain)
945 av_pred_en = 0;
946 for (i = 0; i < NPRED; i++)
947 {
948 av_pred_en = add (av_pred_en, st->past_qua_en[i]);
949 }
950
951 // av_pred_en = 0.25*av_pred_en
952 av_pred_en = mult (av_pred_en, 8192);
953
954 // if (av_pred_en < -14) av_pred_en = ..
955
956 if (sub (av_pred_en, MIN_ENERGY) < 0)
957 {
958 av_pred_en = MIN_ENERGY;
959 }
960 *ener_avg = av_pred_en;
961 }
962
963 ------------------------------------------------------------------------------
964 RESOURCES USED [optional]
965
966 When the code is written for a specific target processor the
967 the resources used should be documented below.
968
969 HEAP MEMORY USED: x bytes
970
971 STACK MEMORY USED: x bytes
972
973 CLOCK CYCLES: (cycle count equation for this function) + (variable
974 used to represent cycle count for each subroutine
975 called)
976 where: (cycle count variable) = cycle count for [subroutine
977 name]
978
979 ------------------------------------------------------------------------------
980 CAUTION [optional]
981 [State any special notes, constraints or cautions for users of this function]
982
983 ------------------------------------------------------------------------------
984 */
985
gc_pred_average_limited(gc_predState * st,Word16 * ener_avg_MR122,Word16 * ener_avg,Flag * pOverflow)986 void gc_pred_average_limited(
987 gc_predState *st, /* i: State struct */
988 Word16 *ener_avg_MR122, /* o: everaged quantized energy, Q10 */
989 /* (log2(qua_err)) */
990 Word16 *ener_avg, /* o: averaged quantized energy, Q10 */
991 /* (20*log10(qua_err)) */
992 Flag *pOverflow
993 )
994 {
995 Word16 av_pred_en;
996 Word16 i;
997
998 /* do average in MR122 mode (log2() domain) */
999 av_pred_en = 0;
1000 for (i = 0; i < NPRED; i++)
1001 {
1002 av_pred_en =
1003 add(av_pred_en, st->past_qua_en_MR122[i], pOverflow);
1004 }
1005
1006 /* av_pred_en = 0.25*av_pred_en (with sign-extension)*/
1007 if (av_pred_en < 0)
1008 {
1009 av_pred_en = (av_pred_en >> 2) | 0xc000;
1010 }
1011 else
1012 {
1013 av_pred_en >>= 2;
1014 }
1015
1016 /* if (av_pred_en < -14/(20Log10(2))) av_pred_en = .. */
1017 if (av_pred_en < MIN_ENERGY_MR122)
1018 {
1019 av_pred_en = MIN_ENERGY_MR122;
1020 }
1021 *ener_avg_MR122 = av_pred_en;
1022
1023 /* do average for other modes (20*log10() domain) */
1024 av_pred_en = 0;
1025 for (i = 0; i < NPRED; i++)
1026 {
1027 av_pred_en = add(av_pred_en, st->past_qua_en[i], pOverflow);
1028 }
1029
1030 /* av_pred_en = 0.25*av_pred_en (with sign-extension)*/
1031 if (av_pred_en < 0)
1032 {
1033 av_pred_en = (av_pred_en >> 2) | 0xc000;
1034 }
1035 else
1036 {
1037 av_pred_en >>= 2;
1038 }
1039
1040 /* if (av_pred_en < -14) av_pred_en = .. */
1041 if (av_pred_en < MIN_ENERGY)
1042 {
1043 av_pred_en = MIN_ENERGY;
1044 }
1045 *ener_avg = av_pred_en;
1046 }
1047