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/gain_q.c
35 Functions:
36
37 Date: 02/05/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: Removed everything associated with gc_pred_init
46 and gc_pred_exit. gc_pred_exit was simply removed -- gc_pred_init
47 was replaced with calls to gc_pred_reset. This is because the gc_pred
48 related structures are no longer dynamically allocated via malloc.
49
50 Description: For gainQuant()
51 1. Replaced gc_pred_copy() with memcpy.
52 2. Eliminated unused include file gc_pred.h.
53
54 Description: Replaced OSCL mem type functions and eliminated include
55 files that now are chosen by OSCL definitions
56
57 Description: Replaced "int" and/or "char" with OSCL defined types.
58
59 Description:
60
61 ------------------------------------------------------------------------------
62 MODULE DESCRIPTION
63
64 Quantazation of gains
65 ------------------------------------------------------------------------------
66 */
67
68 /*----------------------------------------------------------------------------
69 ; INCLUDES
70 ----------------------------------------------------------------------------*/
71 #include <stdlib.h>
72 #include <string.h>
73
74 #include "gain_q.h"
75 #include "typedef.h"
76 #include "basic_op.h"
77 #include "qua_gain.h"
78 #include "cnst.h"
79 #include "mode.h"
80 #include "g_code.h"
81 #include "q_gain_c.h"
82 #include "calc_en.h"
83 #include "qgain795.h"
84 #include "qgain475.h"
85 #include "set_zero.h"
86
87
88 /*----------------------------------------------------------------------------
89 ; MACROS
90 ; Define module specific macros here
91 ----------------------------------------------------------------------------*/
92
93 /*----------------------------------------------------------------------------
94 ; DEFINES
95 ; Include all pre-processor statements here. Include conditional
96 ; compile variables also.
97 ----------------------------------------------------------------------------*/
98 #define NPRED 4 /* number of prediction taps */
99
100 /*----------------------------------------------------------------------------
101 ; LOCAL FUNCTION DEFINITIONS
102 ; Function Prototype declaration
103 ----------------------------------------------------------------------------*/
104
105 /*----------------------------------------------------------------------------
106 ; LOCAL VARIABLE DEFINITIONS
107 ; Variable declaration - defined here and used outside this module
108 ----------------------------------------------------------------------------*/
109
110 /*
111 ------------------------------------------------------------------------------
112 FUNCTION NAME: gainQuant_init
113 ------------------------------------------------------------------------------
114 INPUT AND OUTPUT DEFINITIONS
115
116 Inputs:
117 st -- double pointer to gainQuantState
118
119 Outputs:
120 st -- double ponter to gainQuantState
121
122 Returns:
123 -1 if an error occurs during memory initialization
124 0 if OK
125
126 Global Variables Used:
127 None
128
129 Local Variables Needed:
130 None
131
132 ------------------------------------------------------------------------------
133 FUNCTION DESCRIPTION
134
135 Allocates state memory and initializes state memory
136
137 ------------------------------------------------------------------------------
138 REQUIREMENTS
139
140 None
141
142 ------------------------------------------------------------------------------
143 REFERENCES
144
145 gain_q.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
146
147 ------------------------------------------------------------------------------
148 PSEUDO-CODE
149
150
151 ------------------------------------------------------------------------------
152 RESOURCES USED [optional]
153
154 When the code is written for a specific target processor the
155 the resources used should be documented below.
156
157 HEAP MEMORY USED: x bytes
158
159 STACK MEMORY USED: x bytes
160
161 CLOCK CYCLES: (cycle count equation for this function) + (variable
162 used to represent cycle count for each subroutine
163 called)
164 where: (cycle count variable) = cycle count for [subroutine
165 name]
166
167 ------------------------------------------------------------------------------
168 CAUTION [optional]
169 [State any special notes, constraints or cautions for users of this function]
170
171 ------------------------------------------------------------------------------
172 */
173
gainQuant_init(gainQuantState ** state)174 Word16 gainQuant_init(gainQuantState **state)
175 {
176 gainQuantState* s;
177
178 if (state == (gainQuantState **) NULL)
179 {
180 /* fprintf(stderr, "gainQuant_init: invalid parameter\n"); */
181 return -1;
182 }
183 *state = NULL;
184
185 /* allocate memory */
186 if ((s = (gainQuantState *) malloc(sizeof(gainQuantState))) == NULL)
187 {
188 /* fprintf(stderr, "gainQuant_init: can not malloc state structure\n"); */
189 return -1;
190 }
191
192 s->gain_idx_ptr = NULL;
193
194 s->adaptSt = NULL;
195
196 /* Init sub states */
197 if (gc_pred_reset(&s->gc_predSt)
198 || gc_pred_reset(&s->gc_predUnqSt)
199 || gain_adapt_init(&s->adaptSt))
200 {
201 gainQuant_exit(&s);
202 return -1;
203 }
204
205 gainQuant_reset(s);
206 *state = s;
207
208 return 0;
209 }
210
211 /*
212 ------------------------------------------------------------------------------
213 FUNCTION NAME: gainQuant_reset
214 ------------------------------------------------------------------------------
215 INPUT AND OUTPUT DEFINITIONS
216
217 Inputs:
218 st -- double pointer to gainQuantState
219
220 Outputs:
221 st -- double ponter to gainQuantState
222
223 Returns:
224 -1 if an error occurs
225 0 if OK
226
227 Global Variables Used:
228 None
229
230 Local Variables Needed:
231 None
232
233 ------------------------------------------------------------------------------
234 FUNCTION DESCRIPTION
235
236 Initializes state memory to zero
237 ------------------------------------------------------------------------------
238 REQUIREMENTS
239
240 None
241
242 ------------------------------------------------------------------------------
243 REFERENCES
244
245 gain_q.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
246
247 ------------------------------------------------------------------------------
248 PSEUDO-CODE
249
250
251 ------------------------------------------------------------------------------
252 RESOURCES USED [optional]
253
254 When the code is written for a specific target processor the
255 the resources used should be documented below.
256
257 HEAP MEMORY USED: x bytes
258
259 STACK MEMORY USED: x bytes
260
261 CLOCK CYCLES: (cycle count equation for this function) + (variable
262 used to represent cycle count for each subroutine
263 called)
264 where: (cycle count variable) = cycle count for [subroutine
265 name]
266
267 ------------------------------------------------------------------------------
268 CAUTION [optional]
269 [State any special notes, constraints or cautions for users of this function]
270
271 ------------------------------------------------------------------------------
272 */
273
gainQuant_reset(gainQuantState * state)274 Word16 gainQuant_reset(gainQuantState *state)
275 {
276
277 if (state == (gainQuantState *) NULL)
278 {
279 /* fprintf(stderr, "gainQuant_reset: invalid parameter\n"); */
280 return -1;
281 }
282
283 state->sf0_exp_gcode0 = 0;
284 state->sf0_frac_gcode0 = 0;
285 state->sf0_exp_target_en = 0;
286 state->sf0_frac_target_en = 0;
287
288 Set_zero(state->sf0_exp_coeff, 5);
289 Set_zero(state->sf0_frac_coeff, 5);
290 state->gain_idx_ptr = NULL;
291
292 gc_pred_reset(&(state->gc_predSt));
293 gc_pred_reset(&(state->gc_predUnqSt));
294 gain_adapt_reset(state->adaptSt);
295
296 return 0;
297 }
298
299 /*
300 ------------------------------------------------------------------------------
301 FUNCTION NAME: gainQuant_exit
302 ------------------------------------------------------------------------------
303 INPUT AND OUTPUT DEFINITIONS
304
305 Inputs:
306 st -- double pointer to gainQuantState
307
308 Outputs:
309 None
310
311 Returns:
312 None
313
314 Global Variables Used:
315 None
316
317 Local Variables Needed:
318 None
319
320 ------------------------------------------------------------------------------
321 FUNCTION DESCRIPTION
322
323 The memory used for state memory is freed
324 ------------------------------------------------------------------------------
325 REQUIREMENTS
326
327 None
328
329 ------------------------------------------------------------------------------
330 REFERENCES
331
332 gain_q.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
333
334 ------------------------------------------------------------------------------
335 PSEUDO-CODE
336
337
338 ------------------------------------------------------------------------------
339 RESOURCES USED [optional]
340
341 When the code is written for a specific target processor the
342 the resources used should be documented below.
343
344 HEAP MEMORY USED: x bytes
345
346 STACK MEMORY USED: x bytes
347
348 CLOCK CYCLES: (cycle count equation for this function) + (variable
349 used to represent cycle count for each subroutine
350 called)
351 where: (cycle count variable) = cycle count for [subroutine
352 name]
353
354 ------------------------------------------------------------------------------
355 CAUTION [optional]
356 [State any special notes, constraints or cautions for users of this function]
357
358 ------------------------------------------------------------------------------
359 */
360
gainQuant_exit(gainQuantState ** state)361 void gainQuant_exit(gainQuantState **state)
362 {
363 if (state == NULL || *state == NULL)
364 return;
365
366 gain_adapt_exit(&(*state)->adaptSt);
367
368 /* deallocate memory */
369 free(*state);
370 *state = NULL;
371
372 return;
373 }
374
375
376
377 /*
378 ------------------------------------------------------------------------------
379 FUNCTION NAME: gainQuant
380 ------------------------------------------------------------------------------
381 INPUT AND OUTPUT DEFINITIONS
382
383 Inputs:
384 st -- pointer to gainQuantState
385 mode -- enum Mode -- coder mode
386 res -- Word16 array -- LP residual, Q0
387 exc -- Word16 array -- LTP excitation (unfiltered), Q0
388 code -- Word16 array -- CB innovation (unfiltered), Q13
389 (unsharpened for MR475)
390 xn -- Word16 array -- Target vector.
391 xn2 -- Word16 array -- Target vector.
392 y1 -- Word16 array -- Adaptive codebook.
393 Y2 -- Word16 array -- Filtered innovative vector.
394 g_coeff -- Word16 array -- Correlations <xn y1> <y1 y1>
395 Compute in G_pitch().
396
397 even_subframe -- Word16 -- even subframe indicator flag
398 gp_limit -- Word16 -- pitch gain limit
399 gain_pit -- Word16 Pointer -- Pitch gain.
400
401 Outputs:
402 st -- pointer to gainQuantState
403 sf0_gain_pit -- Word16 Pointer -- Pitch gain sf 0. MR475
404 sf0_gain_cod -- Word16 Pointer -- Code gain sf 0. MR475
405 gain_pit -- Word16 Pointer -- Pitch gain.
406 gain_cod -- Word16 Pointer -- Code gain.
407 MR475: gain_* unquantized in even
408 subframes, quantized otherwise
409
410 anap -- Word16 Double Pointer -- Index of quantization
411
412 pOverflow -- Flag Pointer -- overflow indicator
413
414 Returns:
415 Zero
416
417 Global Variables Used:
418 None
419
420 Local Variables Needed:
421 None
422
423 ------------------------------------------------------------------------------
424 FUNCTION DESCRIPTION
425
426 Quantazation of gains
427
428 ------------------------------------------------------------------------------
429 REQUIREMENTS
430
431 None
432
433 ------------------------------------------------------------------------------
434 REFERENCES
435
436 gain_q.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
437
438 ------------------------------------------------------------------------------
439 PSEUDO-CODE
440
441
442 ------------------------------------------------------------------------------
443 RESOURCES USED [optional]
444
445 When the code is written for a specific target processor the
446 the resources used should be documented below.
447
448 HEAP MEMORY USED: x bytes
449
450 STACK MEMORY USED: x bytes
451
452 CLOCK CYCLES: (cycle count equation for this function) + (variable
453 used to represent cycle count for each subroutine
454 called)
455 where: (cycle count variable) = cycle count for [subroutine
456 name]
457
458 ------------------------------------------------------------------------------
459 CAUTION [optional]
460 [State any special notes, constraints or cautions for users of this function]
461
462 ------------------------------------------------------------------------------
463 */
464
465
466
gainQuant(gainQuantState * st,enum Mode mode,Word16 res[],Word16 exc[],Word16 code[],Word16 xn[],Word16 xn2[],Word16 y1[],Word16 Y2[],Word16 g_coeff[],Word16 even_subframe,Word16 gp_limit,Word16 * sf0_gain_pit,Word16 * sf0_gain_cod,Word16 * gain_pit,Word16 * gain_cod,Word16 ** anap,Flag * pOverflow)467 void gainQuant(
468 gainQuantState *st, /* i/o : State struct */
469 enum Mode mode, /* i : coder mode */
470 Word16 res[], /* i : LP residual, Q0 */
471 Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */
472 Word16 code[], /* i : CB innovation (unfiltered), Q13 */
473 /* (unsharpened for MR475) */
474 Word16 xn[], /* i : Target vector. */
475 Word16 xn2[], /* i : Target vector. */
476 Word16 y1[], /* i : Adaptive codebook. */
477 Word16 Y2[], /* i : Filtered innovative vector. */
478 Word16 g_coeff[], /* i : Correlations <xn y1> <y1 y1> */
479 /* Compute in G_pitch(). */
480 Word16 even_subframe, /* i : even subframe indicator flag */
481 Word16 gp_limit, /* i : pitch gain limit */
482 Word16 *sf0_gain_pit, /* o : Pitch gain sf 0. MR475 */
483 Word16 *sf0_gain_cod, /* o : Code gain sf 0. MR475 */
484 Word16 *gain_pit, /* i/o : Pitch gain. */
485 Word16 *gain_cod, /* o : Code gain. */
486 /* MR475: gain_* unquantized in even */
487 /* subframes, quantized otherwise */
488 Word16 **anap, /* o : Index of quantization */
489 Flag *pOverflow /* o : overflow indicator */
490 )
491 {
492 Word16 exp_gcode0;
493 Word16 frac_gcode0;
494 Word16 qua_ener_MR122;
495 Word16 qua_ener;
496 Word16 frac_coeff[5];
497 Word16 exp_coeff[5];
498 Word16 exp_en;
499 Word16 frac_en;
500 Word16 cod_gain_exp;
501 Word16 cod_gain_frac;
502 Word16 temp;
503
504 if (mode == MR475)
505 {
506 if (even_subframe != 0)
507 {
508 /* save position in output parameter stream and current
509 state of codebook gain predictor */
510 st->gain_idx_ptr = (*anap)++;
511
512 // gc_pred_copy(&(st->gc_predSt), &(st->gc_predUnqSt));
513
514 memcpy(st->gc_predUnqSt.past_qua_en,
515 st->gc_predSt.past_qua_en,
516 NPRED*sizeof(Word16));
517 memcpy(st->gc_predUnqSt.past_qua_en_MR122,
518 st->gc_predSt.past_qua_en_MR122,
519 NPRED*sizeof(Word16));
520
521
522 /* predict codebook gain (using "unquantized" predictor)*/
523 /* (note that code[] is unsharpened in MR475) */
524 gc_pred(
525 &(st->gc_predUnqSt),
526 mode,
527 code,
528 &st->sf0_exp_gcode0,
529 &st->sf0_frac_gcode0,
530 &exp_en,
531 &frac_en,
532 pOverflow);
533
534 /* calculate energy coefficients for quantization
535 and store them in state structure (will be used
536 in next subframe when real quantizer is run) */
537 calc_filt_energies(
538 mode,
539 xn,
540 xn2,
541 y1,
542 Y2,
543 g_coeff,
544 st->sf0_frac_coeff,
545 st->sf0_exp_coeff,
546 &cod_gain_frac,
547 &cod_gain_exp,
548 pOverflow);
549
550 /* store optimum codebook gain (Q1) */
551 temp =
552 add(
553 cod_gain_exp,
554 1,
555 pOverflow);
556
557 *gain_cod =
558 shl(
559 cod_gain_frac,
560 temp,
561 pOverflow);
562
563 calc_target_energy(
564 xn,
565 &st->sf0_exp_target_en,
566 &st->sf0_frac_target_en,
567 pOverflow);
568
569 /* calculate optimum codebook gain and update
570 "unquantized" predictor */
571 MR475_update_unq_pred(
572 &(st->gc_predUnqSt),
573 st->sf0_exp_gcode0,
574 st->sf0_frac_gcode0,
575 cod_gain_exp,
576 cod_gain_frac,
577 pOverflow);
578
579 /* the real quantizer is not run here... */
580 }
581 else
582 {
583 /* predict codebook gain (using "unquantized" predictor) */
584 /* (note that code[] is unsharpened in MR475) */
585 gc_pred(
586 &(st->gc_predUnqSt),
587 mode,
588 code,
589 &exp_gcode0,
590 &frac_gcode0,
591 &exp_en,
592 &frac_en,
593 pOverflow);
594
595 /* calculate energy coefficients for quantization */
596 calc_filt_energies(
597 mode,
598 xn,
599 xn2,
600 y1,
601 Y2,
602 g_coeff,
603 frac_coeff,
604 exp_coeff,
605 &cod_gain_frac,
606 &cod_gain_exp,
607 pOverflow);
608
609 calc_target_energy(
610 xn,
611 &exp_en,
612 &frac_en,
613 pOverflow);
614
615 /* run real (4-dim) quantizer and update real gain predictor */
616 *st->gain_idx_ptr =
617 MR475_gain_quant(
618 &(st->gc_predSt),
619 st->sf0_exp_gcode0,
620 st->sf0_frac_gcode0,
621 st->sf0_exp_coeff,
622 st->sf0_frac_coeff,
623 st->sf0_exp_target_en,
624 st->sf0_frac_target_en,
625 code,
626 exp_gcode0,
627 frac_gcode0,
628 exp_coeff,
629 frac_coeff,
630 exp_en,
631 frac_en,
632 gp_limit,
633 sf0_gain_pit,
634 sf0_gain_cod,
635 gain_pit,
636 gain_cod,
637 pOverflow);
638 }
639 }
640 else
641 {
642 /*-------------------------------------------------------------------*
643 * predict codebook gain and quantize *
644 * (also compute normalized CB innovation energy for MR795) *
645 *-------------------------------------------------------------------*/
646 gc_pred(
647 &(st->gc_predSt),
648 mode,
649 code,
650 &exp_gcode0,
651 &frac_gcode0,
652 &exp_en,
653 &frac_en,
654 pOverflow);
655
656 if (mode == MR122)
657 {
658 *gain_cod =
659 G_code(
660 xn2,
661 Y2,
662 pOverflow);
663
664 *(*anap)++ =
665 q_gain_code(
666 mode,
667 exp_gcode0,
668 frac_gcode0,
669 gain_cod,
670 &qua_ener_MR122,
671 &qua_ener,
672 pOverflow);
673 }
674 else
675 {
676 /* calculate energy coefficients for quantization */
677 calc_filt_energies(
678 mode,
679 xn,
680 xn2,
681 y1,
682 Y2,
683 g_coeff,
684 frac_coeff,
685 exp_coeff,
686 &cod_gain_frac,
687 &cod_gain_exp,
688 pOverflow);
689
690 if (mode == MR795)
691 {
692 MR795_gain_quant(
693 st->adaptSt,
694 res,
695 exc,
696 code,
697 frac_coeff,
698 exp_coeff,
699 exp_en,
700 frac_en,
701 exp_gcode0,
702 frac_gcode0,
703 L_SUBFR,
704 cod_gain_frac,
705 cod_gain_exp,
706 gp_limit,
707 gain_pit,
708 gain_cod,
709 &qua_ener_MR122,
710 &qua_ener,
711 anap,
712 pOverflow);
713 }
714 else
715 {
716 *(*anap)++ =
717 Qua_gain(
718 mode,
719 exp_gcode0,
720 frac_gcode0,
721 frac_coeff,
722 exp_coeff,
723 gp_limit,
724 gain_pit,
725 gain_cod,
726 &qua_ener_MR122,
727 &qua_ener,
728 pOverflow);
729 }
730 }
731
732 /*------------------------------------------------------------------*
733 * update table of past quantized energies *
734 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
735 * st->past_qua_en(Q10) = 20 * Log10(qua_gain_code) / constant *
736 * = Log2(qua_gain_code) *
737 * = qua_ener *
738 * constant = 20*Log10(2) *
739 *------------------------------------------------------------------*/
740 gc_pred_update(
741 &(st->gc_predSt),
742 qua_ener_MR122,
743 qua_ener);
744 }
745
746 return;
747 }
748