Home | History | Annotate | Download | only in src
      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 
    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 
    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 
    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 
    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