• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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