Initialize Tizen 2.3
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / enc / src / gain_q.cpp
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20
21     3GPP TS 26.073
22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23     Available from http://www.3gpp.org
24
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34  Filename: gain_q.cpp
35
36 ------------------------------------------------------------------------------
37  MODULE DESCRIPTION
38
39     Quantazation of gains
40 ------------------------------------------------------------------------------
41 */
42
43 /*----------------------------------------------------------------------------
44 ; INCLUDES
45 ----------------------------------------------------------------------------*/
46 #include "gain_q.h"
47 #include "typedef.h"
48 #include "basic_op.h"
49 #include "qua_gain.h"
50 #include "cnst.h"
51 #include "mode.h"
52 #include "g_code.h"
53 #include "q_gain_c.h"
54 #include "calc_en.h"
55 #include "qgain795.h"
56 #include "qgain475.h"
57 #include "set_zero.h"
58 #include "oscl_mem.h"
59
60
61 /*----------------------------------------------------------------------------
62 ; MACROS
63 ; Define module specific macros here
64 ----------------------------------------------------------------------------*/
65
66 /*----------------------------------------------------------------------------
67 ; DEFINES
68 ; Include all pre-processor statements here. Include conditional
69 ; compile variables also.
70 ----------------------------------------------------------------------------*/
71 #define NPRED 4  /* number of prediction taps */
72
73 /*----------------------------------------------------------------------------
74 ; LOCAL FUNCTION DEFINITIONS
75 ; Function Prototype declaration
76 ----------------------------------------------------------------------------*/
77
78 /*----------------------------------------------------------------------------
79 ; LOCAL VARIABLE DEFINITIONS
80 ; Variable declaration - defined here and used outside this module
81 ----------------------------------------------------------------------------*/
82
83 /*
84 ------------------------------------------------------------------------------
85  FUNCTION NAME: gainQuant_init
86 ------------------------------------------------------------------------------
87  INPUT AND OUTPUT DEFINITIONS
88
89  Inputs:
90     st -- double pointer to gainQuantState
91
92  Outputs:
93     st -- double ponter to gainQuantState
94
95  Returns:
96     -1 if an error occurs during memory initialization
97      0 if OK
98
99  Global Variables Used:
100     None
101
102  Local Variables Needed:
103     None
104
105 ------------------------------------------------------------------------------
106  FUNCTION DESCRIPTION
107
108     Allocates state memory and initializes state memory
109
110 ------------------------------------------------------------------------------
111  REQUIREMENTS
112
113  None
114
115 ------------------------------------------------------------------------------
116  REFERENCES
117
118  gain_q.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
119
120 ------------------------------------------------------------------------------
121  PSEUDO-CODE
122
123
124 ------------------------------------------------------------------------------
125  CAUTION [optional]
126  [State any special notes, constraints or cautions for users of this function]
127
128 ------------------------------------------------------------------------------
129 */
130
131 Word16 gainQuant_init(gainQuantState **state)
132 {
133     gainQuantState* s;
134
135     if (state == (gainQuantState **) NULL)
136     {
137         /* fprintf(stderr, "gainQuant_init: invalid parameter\n"); */
138         return -1;
139     }
140     *state = NULL;
141
142     /* allocate memory */
143     if ((s = (gainQuantState *) oscl_malloc(sizeof(gainQuantState))) == NULL)
144     {
145         /* fprintf(stderr, "gainQuant_init: can not malloc state structure\n"); */
146         return -1;
147     }
148
149     s->gain_idx_ptr = NULL;
150
151     s->adaptSt = NULL;
152
153     /* Init sub states */
154     if (gc_pred_reset(&s->gc_predSt)
155             || gc_pred_reset(&s->gc_predUnqSt)
156             || gain_adapt_init(&s->adaptSt))
157     {
158         gainQuant_exit(&s);
159         return -1;
160     }
161
162     gainQuant_reset(s);
163     *state = s;
164
165     return 0;
166 }
167
168 /*
169 ------------------------------------------------------------------------------
170  FUNCTION NAME: gainQuant_reset
171 ------------------------------------------------------------------------------
172  INPUT AND OUTPUT DEFINITIONS
173
174  Inputs:
175     st -- double pointer to gainQuantState
176
177  Outputs:
178     st -- double ponter to gainQuantState
179
180  Returns:
181     -1 if an error occurs
182      0 if OK
183
184  Global Variables Used:
185     None
186
187  Local Variables Needed:
188     None
189
190 ------------------------------------------------------------------------------
191  FUNCTION DESCRIPTION
192
193     Initializes state memory to zero
194 ------------------------------------------------------------------------------
195  REQUIREMENTS
196
197  None
198
199 ------------------------------------------------------------------------------
200  REFERENCES
201
202  gain_q.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
203
204 ------------------------------------------------------------------------------
205  PSEUDO-CODE
206
207
208 ------------------------------------------------------------------------------
209  CAUTION [optional]
210  [State any special notes, constraints or cautions for users of this function]
211
212 ------------------------------------------------------------------------------
213 */
214
215 Word16 gainQuant_reset(gainQuantState *state)
216 {
217
218     if (state == (gainQuantState *) NULL)
219     {
220         /* fprintf(stderr, "gainQuant_reset: invalid parameter\n"); */
221         return -1;
222     }
223
224     state->sf0_exp_gcode0 = 0;
225     state->sf0_frac_gcode0 = 0;
226     state->sf0_exp_target_en = 0;
227     state->sf0_frac_target_en = 0;
228
229
230     oscl_memset((void *)state->sf0_exp_coeff,  0, 5*sizeof(*state->sf0_exp_coeff));
231     oscl_memset((void *)state->sf0_frac_coeff, 0, 5*sizeof(*state->sf0_frac_coeff));
232
233     state->gain_idx_ptr = NULL;
234
235     gc_pred_reset(&(state->gc_predSt));
236     gc_pred_reset(&(state->gc_predUnqSt));
237     gain_adapt_reset(state->adaptSt);
238
239     return 0;
240 }
241
242 /*
243 ------------------------------------------------------------------------------
244  FUNCTION NAME: gainQuant_exit
245 ------------------------------------------------------------------------------
246  INPUT AND OUTPUT DEFINITIONS
247
248  Inputs:
249     st -- double pointer to gainQuantState
250
251  Outputs:
252     None
253
254  Returns:
255     None
256
257  Global Variables Used:
258     None
259
260  Local Variables Needed:
261     None
262
263 ------------------------------------------------------------------------------
264  FUNCTION DESCRIPTION
265
266     The memory used for state memory is freed
267 ------------------------------------------------------------------------------
268  REQUIREMENTS
269
270  None
271
272 ------------------------------------------------------------------------------
273  REFERENCES
274
275  gain_q.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
276
277 ------------------------------------------------------------------------------
278  PSEUDO-CODE
279
280
281 ------------------------------------------------------------------------------
282  CAUTION [optional]
283  [State any special notes, constraints or cautions for users of this function]
284
285 ------------------------------------------------------------------------------
286 */
287
288 void gainQuant_exit(gainQuantState **state)
289 {
290     if (state == NULL || *state == NULL)
291         return;
292
293     gain_adapt_exit(&(*state)->adaptSt);
294
295     /* deallocate memory */
296     oscl_free(*state);
297     *state = NULL;
298
299     return;
300 }
301
302
303
304 /*
305 ------------------------------------------------------------------------------
306  FUNCTION NAME: gainQuant
307 ------------------------------------------------------------------------------
308  INPUT AND OUTPUT DEFINITIONS
309
310  Inputs:
311     st   -- pointer to gainQuantState
312     mode -- enum Mode -- coder mode
313     res  -- Word16 array -- LP residual,                 Q0
314     exc  -- Word16 array -- LTP excitation (unfiltered), Q0
315     code -- Word16 array -- CB innovation (unfiltered),  Q13
316                             (unsharpened for MR475)
317     xn  -- Word16 array -- Target vector.
318     xn2 -- Word16 array -- Target vector.
319     y1  -- Word16 array -- Adaptive codebook.
320     Y2  -- Word16 array -- Filtered innovative vector.
321     g_coeff -- Word16 array -- Correlations <xn y1> <y1 y1>
322                                Compute in G_pitch().
323
324     even_subframe -- Word16 -- even subframe indicator flag
325     gp_limit -- Word16 -- pitch gain limit
326     gain_pit -- Word16 Pointer -- Pitch gain.
327
328  Outputs:
329     st -- pointer to gainQuantState
330     sf0_gain_pit -- Word16 Pointer -- Pitch gain sf 0.   MR475
331     sf0_gain_cod -- Word16 Pointer -- Code gain sf 0.    MR475
332     gain_pit -- Word16 Pointer -- Pitch gain.
333     gain_cod -- Word16 Pointer -- Code gain.
334                                   MR475: gain_* unquantized in even
335                                   subframes, quantized otherwise
336
337     anap -- Word16 Double Pointer -- Index of quantization
338
339     pOverflow -- Flag Pointer -- overflow indicator
340
341  Returns:
342     Zero
343
344  Global Variables Used:
345     None
346
347  Local Variables Needed:
348     None
349
350 ------------------------------------------------------------------------------
351  FUNCTION DESCRIPTION
352
353     Quantazation of gains
354
355 ------------------------------------------------------------------------------
356  REQUIREMENTS
357
358  None
359
360 ------------------------------------------------------------------------------
361  REFERENCES
362
363  gain_q.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
364
365 ------------------------------------------------------------------------------
366  PSEUDO-CODE
367
368
369 ------------------------------------------------------------------------------
370  CAUTION [optional]
371  [State any special notes, constraints or cautions for users of this function]
372
373 ------------------------------------------------------------------------------
374 */
375
376
377
378 void gainQuant(
379     gainQuantState *st,   /* i/o : State struct                      */
380     enum Mode mode,       /* i   : coder mode                        */
381     Word16 res[],         /* i   : LP residual,                 Q0   */
382     Word16 exc[],         /* i   : LTP excitation (unfiltered), Q0   */
383     Word16 code[],        /* i   : CB innovation (unfiltered),  Q13  */
384     /*       (unsharpened for MR475)           */
385     Word16 xn[],          /* i   : Target vector.                    */
386     Word16 xn2[],         /* i   : Target vector.                    */
387     Word16 y1[],          /* i   : Adaptive codebook.                */
388     Word16 Y2[],          /* i   : Filtered innovative vector.       */
389     Word16 g_coeff[],     /* i   : Correlations <xn y1> <y1 y1>      */
390     /*       Compute in G_pitch().             */
391     Word16 even_subframe, /* i   : even subframe indicator flag      */
392     Word16 gp_limit,      /* i   : pitch gain limit                  */
393     Word16 *sf0_gain_pit, /* o   : Pitch gain sf 0.   MR475          */
394     Word16 *sf0_gain_cod, /* o   : Code gain sf 0.    MR475          */
395     Word16 *gain_pit,     /* i/o : Pitch gain.                       */
396     Word16 *gain_cod,     /* o   : Code gain.                        */
397     /*       MR475: gain_* unquantized in even */
398     /*       subframes, quantized otherwise    */
399     Word16 **anap,        /* o   : Index of quantization             */
400     CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of tbl ptrs */
401     Flag   *pOverflow     /* o   : overflow indicator                */
402 )
403 {
404     Word16 exp_gcode0;
405     Word16 frac_gcode0;
406     Word16 qua_ener_MR122;
407     Word16 qua_ener;
408     Word16 frac_coeff[5];
409     Word16 exp_coeff[5];
410     Word16 exp_en;
411     Word16 frac_en;
412     Word16 cod_gain_exp;
413     Word16 cod_gain_frac;
414     Word16 temp;
415
416     if (mode == MR475)
417     {
418         if (even_subframe != 0)
419         {
420             /* save position in output parameter stream and current
421                state of codebook gain predictor */
422             st->gain_idx_ptr = (*anap)++;
423
424 //            gc_pred_copy(&(st->gc_predSt), &(st->gc_predUnqSt));
425
426             oscl_memcpy(st->gc_predUnqSt.past_qua_en,
427                         st->gc_predSt.past_qua_en,
428                         NPRED*sizeof(Word16));
429             oscl_memcpy(st->gc_predUnqSt.past_qua_en_MR122,
430                         st->gc_predSt.past_qua_en_MR122,
431                         NPRED*sizeof(Word16));
432
433
434             /* predict codebook gain (using "unquantized" predictor)*/
435             /* (note that code[] is unsharpened in MR475)           */
436             gc_pred(
437                 &(st->gc_predUnqSt),
438                 mode,
439                 code,
440                 &st->sf0_exp_gcode0,
441                 &st->sf0_frac_gcode0,
442                 &exp_en,
443                 &frac_en,
444                 pOverflow);
445
446             /* calculate energy coefficients for quantization
447                and store them in state structure (will be used
448                in next subframe when real quantizer is run) */
449             calc_filt_energies(
450                 mode,
451                 xn,
452                 xn2,
453                 y1,
454                 Y2,
455                 g_coeff,
456                 st->sf0_frac_coeff,
457                 st->sf0_exp_coeff,
458                 &cod_gain_frac,
459                 &cod_gain_exp,
460                 pOverflow);
461
462             /* store optimum codebook gain (Q1) */
463             temp = cod_gain_exp + 1;
464
465             *gain_cod =
466                 shl(
467                     cod_gain_frac,
468                     temp,
469                     pOverflow);
470
471             calc_target_energy(
472                 xn,
473                 &st->sf0_exp_target_en,
474                 &st->sf0_frac_target_en,
475                 pOverflow);
476
477             /* calculate optimum codebook gain and update
478                "unquantized" predictor                    */
479             MR475_update_unq_pred(
480                 &(st->gc_predUnqSt),
481                 st->sf0_exp_gcode0,
482                 st->sf0_frac_gcode0,
483                 cod_gain_exp,
484                 cod_gain_frac,
485                 pOverflow);
486
487             /* the real quantizer is not run here... */
488         }
489         else
490         {
491             /* predict codebook gain (using "unquantized" predictor) */
492             /* (note that code[] is unsharpened in MR475)            */
493             gc_pred(
494                 &(st->gc_predUnqSt),
495                 mode,
496                 code,
497                 &exp_gcode0,
498                 &frac_gcode0,
499                 &exp_en,
500                 &frac_en,
501                 pOverflow);
502
503             /* calculate energy coefficients for quantization */
504             calc_filt_energies(
505                 mode,
506                 xn,
507                 xn2,
508                 y1,
509                 Y2,
510                 g_coeff,
511                 frac_coeff,
512                 exp_coeff,
513                 &cod_gain_frac,
514                 &cod_gain_exp,
515                 pOverflow);
516
517             calc_target_energy(
518                 xn,
519                 &exp_en,
520                 &frac_en,
521                 pOverflow);
522
523             /* run real (4-dim) quantizer and update real gain predictor */
524             *st->gain_idx_ptr =
525                 MR475_gain_quant(
526                     &(st->gc_predSt),
527                     st->sf0_exp_gcode0,
528                     st->sf0_frac_gcode0,
529                     st->sf0_exp_coeff,
530                     st->sf0_frac_coeff,
531                     st->sf0_exp_target_en,
532                     st->sf0_frac_target_en,
533                     code,
534                     exp_gcode0,
535                     frac_gcode0,
536                     exp_coeff,
537                     frac_coeff,
538                     exp_en,
539                     frac_en,
540                     gp_limit,
541                     sf0_gain_pit,
542                     sf0_gain_cod,
543                     gain_pit,
544                     gain_cod,
545                     pOverflow);
546         }
547     }
548     else
549     {
550         /*-------------------------------------------------------------------*
551          *  predict codebook gain and quantize                               *
552          *  (also compute normalized CB innovation energy for MR795)         *
553          *-------------------------------------------------------------------*/
554         gc_pred(
555             &(st->gc_predSt),
556             mode,
557             code,
558             &exp_gcode0,
559             &frac_gcode0,
560             &exp_en,
561             &frac_en,
562             pOverflow);
563
564         if (mode == MR122)
565         {
566             *gain_cod =
567                 G_code(
568                     xn2,
569                     Y2,
570                     pOverflow);
571
572             *(*anap)++ =
573                 q_gain_code(
574                     mode,
575                     exp_gcode0,
576                     frac_gcode0,
577                     gain_cod,
578                     &qua_ener_MR122,
579                     &qua_ener,
580                     common_amr_tbls->qua_gain_code_ptr,
581                     pOverflow);
582         }
583         else
584         {
585             /* calculate energy coefficients for quantization */
586             calc_filt_energies(
587                 mode,
588                 xn,
589                 xn2,
590                 y1,
591                 Y2,
592                 g_coeff,
593                 frac_coeff,
594                 exp_coeff,
595                 &cod_gain_frac,
596                 &cod_gain_exp,
597                 pOverflow);
598
599             if (mode == MR795)
600             {
601                 MR795_gain_quant(
602                     st->adaptSt,
603                     res,
604                     exc,
605                     code,
606                     frac_coeff,
607                     exp_coeff,
608                     exp_en,
609                     frac_en,
610                     exp_gcode0,
611                     frac_gcode0,
612                     L_SUBFR,
613                     cod_gain_frac,
614                     cod_gain_exp,
615                     gp_limit,
616                     gain_pit,
617                     gain_cod,
618                     &qua_ener_MR122,
619                     &qua_ener,
620                     anap,
621                     common_amr_tbls,
622                     pOverflow);
623             }
624             else
625             {
626                 *(*anap)++ =
627                     Qua_gain(
628                         mode,
629                         exp_gcode0,
630                         frac_gcode0,
631                         frac_coeff,
632                         exp_coeff,
633                         gp_limit,
634                         gain_pit,
635                         gain_cod,
636                         &qua_ener_MR122,
637                         &qua_ener,
638                         common_amr_tbls,
639                         pOverflow);
640             }
641         }
642
643         /*------------------------------------------------------------------*
644          *  update table of past quantized energies                         *
645          *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                         *
646          *  st->past_qua_en(Q10) = 20 * Log10(qua_gain_code) / constant     *
647          *                       = Log2(qua_gain_code)                      *
648          *                       = qua_ener                                 *
649          *                                           constant = 20*Log10(2) *
650          *------------------------------------------------------------------*/
651         gc_pred_update(
652             &(st->gc_predSt),
653             qua_ener_MR122,
654             qua_ener);
655     }
656
657     return;
658 }