summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/amrnb/common/src/gc_pred.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/amrnb/common/src/gc_pred.cpp')
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/gc_pred.cpp1046
1 files changed, 0 insertions, 1046 deletions
diff --git a/media/libstagefright/codecs/amrnb/common/src/gc_pred.cpp b/media/libstagefright/codecs/amrnb/common/src/gc_pred.cpp
deleted file mode 100644
index 3650f3c..0000000
--- a/media/libstagefright/codecs/amrnb/common/src/gc_pred.cpp
+++ /dev/null
@@ -1,1046 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
- 3GPP TS 26.073
- ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
- Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/*
-
- Pathname: ./audio/gsm-amr/c/src/gc_pred.c
- Functions:
- gc_pred_reset
- gc_pred
- gc_pred_update
- gc_pred_average_limited
-
-------------------------------------------------------------------------------
- MODULE DESCRIPTION
-
- This file contains the functions that perform codebook gain MA prediction.
-
-------------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "gc_pred.h"
-#include "basicop_malloc.h"
-#include "basic_op.h"
-#include "cnst.h"
-#include "log2.h"
-
-/*----------------------------------------------------------------------------
-; MACROS
-; Define module specific macros here
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; DEFINES
-; Include all pre-processor statements here. Include conditional
-; compile variables also.
-----------------------------------------------------------------------------*/
-#define NPRED 4 /* number of prediction taps */
-
-/* average innovation energy. */
-/* MEAN_ENER = 36.0/constant, constant = 20*Log10(2) */
-#define MEAN_ENER_MR122 783741L /* 36/(20*log10(2)) (Q17) */
-
-/* minimum quantized energy: -14 dB */
-#define MIN_ENERGY -14336 /* 14 Q10 */
-#define MIN_ENERGY_MR122 -2381 /* 14 / (20*log10(2)) Q10 */
-
-/*----------------------------------------------------------------------------
-; LOCAL FUNCTION DEFINITIONS
-; Function Prototype declaration
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; LOCAL VARIABLE DEFINITIONS
-; Variable declaration - defined here and used outside this module
-----------------------------------------------------------------------------*/
-
-/* MA prediction coefficients (Q13) */
-static const Word16 pred[NPRED] = {5571, 4751, 2785, 1556};
-
-/* MA prediction coefficients (Q6) */
-static const Word16 pred_MR122[NPRED] = {44, 37, 22, 12};
-
-/*
-------------------------------------------------------------------------------
- FUNCTION NAME: gc_pred_reset
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
- state = pointer to a structure of type gc_predState
-
- Outputs:
- past_qua_en field in the structure pointed to by state is initialized
- to MIN_ENERGY
- past_qua_en_MR122 field in the structure pointed to by state is
- initialized to MIN_ENERGY_MR122
-
- Returns:
- return_value = 0, if reset was successful; -1, otherwise (int)
-
- Global Variables Used:
- None
-
- Local Variables Needed:
- None
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- This function initializes the state memory used by gc_pred to zero.
-
-------------------------------------------------------------------------------
- REQUIREMENTS
-
- None
-
-------------------------------------------------------------------------------
- REFERENCES
-
- gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
-
-------------------------------------------------------------------------------
- PSEUDO-CODE
-
-int gc_pred_reset (gc_predState *state)
-{
- Word16 i;
-
- if (state == (gc_predState *) NULL){
- fprintf(stderr, "gc_pred_reset: invalid parameter\n");
- return -1;
- }
-
- for(i = 0; i < NPRED; i++)
- {
- state->past_qua_en[i] = MIN_ENERGY;
- state->past_qua_en_MR122[i] = MIN_ENERGY_MR122;
- }
- return 0;
-}
-
-------------------------------------------------------------------------------
- RESOURCES USED [optional]
-
- When the code is written for a specific target processor the
- the resources used should be documented below.
-
- HEAP MEMORY USED: x bytes
-
- STACK MEMORY USED: x bytes
-
- CLOCK CYCLES: (cycle count equation for this function) + (variable
- used to represent cycle count for each subroutine
- called)
- where: (cycle count variable) = cycle count for [subroutine
- name]
-
-------------------------------------------------------------------------------
- CAUTION [optional]
- [State any special notes, constraints or cautions for users of this function]
-
-------------------------------------------------------------------------------
-*/
-
-Word16 gc_pred_reset(gc_predState *state)
-{
- Word16 i;
-
- if (state == (gc_predState *) NULL)
- {
- /* fprintf(stderr, "gc_pred_reset: invalid parameter\n"); */
- return -1;
- }
-
- for (i = 0; i < NPRED; i++)
- {
- state->past_qua_en[i] = MIN_ENERGY;
- state->past_qua_en_MR122[i] = MIN_ENERGY_MR122;
- }
-
- return(0);
-}
-
-/****************************************************************************/
-
-/*
-------------------------------------------------------------------------------
- FUNCTION NAME: gc_pred
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
- st = pointer to a structure of type gc_predState
- mode = AMR mode (enum Mode)
- code = pointer to the innovative codebook vector; Q12 in MR122 mode,
- otherwise, Q13 (Word16)
- exp_gcode0 = pointer to the exponent part of predicted gain factor
- (Q0) (Word16)
- frac_gcode0 = pointer to the fractional part of predicted gain factor
- (Q15) (Word16)
- exp_en = pointer to the exponent part of the innovation energy; this
- is calculated for MR795 mode, Q0 (Word16)
- frac_en = pointer to the fractional part of the innovation energy;
- this is calculated for MR795 mode, Q15 (Word16)
- pOverflow = pointer to overflow (Flag)
-
- Outputs:
- store pointed to by exp_gcode0 contains the exponent part of the
- recently calculated predicted gain factor
- store pointed to by frac_gcode0 contains the fractional part of the
- recently calculated predicted gain factor
- store pointed to by exp_en contains the exponent part of the
- recently calculated innovation energy
- store pointed to by frac_en contains the fractional part of the
- recently calculated innovation energy
- pOverflow = 1 if the math functions called by gc_pred
- results in overflow else zero.
-
- Returns:
- None
-
- Global Variables Used:
- None
-
- Local Variables Needed:
- pred = table of MA prediction coefficients (Q13) (Word16)
- pred_MR122 = table of MA prediction coefficients (Q6) (Word16)
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- This function performs the MA prediction of the innovation energy (in
- dB/(20*log10(2))), with the mean removed.
-
-------------------------------------------------------------------------------
- REQUIREMENTS
-
- None
-
-------------------------------------------------------------------------------
- REFERENCES
-
- gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
-
-------------------------------------------------------------------------------
- PSEUDO-CODE
-
-The original etsi reference code uses a global flag Overflow. However, in the
-actual implementation a pointer to a the overflow flag is passed in.
-
-void
-gc_pred(
- gc_predState *st, // i/o: State struct
- enum Mode mode, // i : AMR mode
- Word16 *code, // i : innovative codebook vector (L_SUBFR)
- // MR122: Q12, other modes: Q13
- Word16 *exp_gcode0, // o : exponent of predicted gain factor, Q0
- Word16 *frac_gcode0,// o : fraction of predicted gain factor Q15
- Word16 *exp_en, // o : exponent of innovation energy, Q0
- // (only calculated for MR795)
- Word16 *frac_en // o : fraction of innovation energy, Q15
- // (only calculated for MR795)
-)
-{
- Word16 i;
- Word32 ener_code;
- Word16 exp, frac;
-
- *-------------------------------------------------------------------*
- * energy of code: *
- * ~~~~~~~~~~~~~~~ *
- * ener_code = sum(code[i]^2) *
- *-------------------------------------------------------------------*
- ener_code = L_mac((Word32) 0, code[0], code[0]);
- // MR122: Q12*Q12 -> Q25
- // others: Q13*Q13 -> Q27
- for (i = 1; i < L_SUBFR; i++)
- ener_code = L_mac(ener_code, code[i], code[i]);
-
- if (sub (mode, MR122) == 0)
- {
- Word32 ener;
-
- // ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20
- ener_code = L_mult (pv_round (ener_code), 26214); // Q9 * Q20 -> Q30
-
- *-------------------------------------------------------------------*
- * energy of code: *
- * ~~~~~~~~~~~~~~~ *
- * ener_code(Q17) = 10 * Log10(energy) / constant *
- * = 1/2 * Log2(energy) *
- * constant = 20*Log10(2) *
- *-------------------------------------------------------------------*
- // ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30
- Log2(ener_code, &exp, &frac);
- ener_code = L_Comp (sub (exp, 30), frac); // Q16 for log()
- // ->Q17 for 1/2 log()
-
- *-------------------------------------------------------------------*
- * predicted energy: *
- * ~~~~~~~~~~~~~~~~~ *
- * ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant *
- * = MEAN_ENER + sum(pred[i]*past_qua_en[i]) *
- * constant = 20*Log10(2) *
- *-------------------------------------------------------------------*
-
- ener = MEAN_ENER_MR122; // Q24 (Q17)
- for (i = 0; i < NPRED; i++)
- {
- ener = L_mac (ener, st->past_qua_en_MR122[i], pred_MR122[i]);
- // Q10 * Q13 -> Q24
- // Q10 * Q6 -> Q17
- }
-
- *-------------------------------------------------------------------*
- * predicted codebook gain *
- * ~~~~~~~~~~~~~~~~~~~~~~~ *
- * gc0 = Pow10( (ener*constant - ener_code*constant) / 20 ) *
- * = Pow2(ener-ener_code) *
- * = Pow2(int(d)+frac(d)) *
- * *
- * (store exp and frac for pow2()) *
- *-------------------------------------------------------------------*
-
- ener = L_shr (L_sub (ener, ener_code), 1); // Q16
- L_Extract(ener, exp_gcode0, frac_gcode0);
- }
- else // all modes except 12.2
- {
- Word32 L_tmp;
- Word16 exp_code, gcode0;
-
- *-----------------------------------------------------------------*
- * Compute: means_ener - 10log10(ener_code/ L_sufr) *
- *-----------------------------------------------------------------*
-
- exp_code = norm_l (ener_code);
- ener_code = L_shl (ener_code, exp_code);
-
- // Log2 = log2 + 27
- Log2_norm (ener_code, exp_code, &exp, &frac);
-
- // fact = 10/log2(10) = 3.01 = 24660 Q13
- L_tmp = Mpy_32_16(exp, frac, -24660); // Q0.Q15 * Q13 -> Q14
-
- * L_tmp = means_ener - 10log10(ener_code/L_SUBFR)
- * = means_ener - 10log10(ener_code) + 10log10(L_SUBFR)
- * = K - fact * Log2(ener_code)
- * = K - fact * log2(ener_code) - fact*27
- *
- * ==> K = means_ener + fact*27 + 10log10(L_SUBFR)
- *
- * means_ener = 33 = 540672 Q14 (MR475, MR515, MR59)
- * means_ener = 28.75 = 471040 Q14 (MR67)
- * means_ener = 30 = 491520 Q14 (MR74)
- * means_ener = 36 = 589824 Q14 (MR795)
- * means_ener = 33 = 540672 Q14 (MR102)
- * 10log10(L_SUBFR) = 16.02 = 262481.51 Q14
- * fact * 27 = 1331640 Q14
- * -----------------------------------------
- * (MR475, MR515, MR59) K = 2134793.51 Q14 ~= 16678 * 64 * 2
- * (MR67) K = 2065161.51 Q14 ~= 32268 * 32 * 2
- * (MR74) K = 2085641.51 Q14 ~= 32588 * 32 * 2
- * (MR795) K = 2183945.51 Q14 ~= 17062 * 64 * 2
- * (MR102) K = 2134793.51 Q14 ~= 16678 * 64 * 2
-
-
- if (sub (mode, MR102) == 0)
- {
- // mean = 33 dB
- L_tmp = L_mac(L_tmp, 16678, 64); // Q14
- }
- else if (sub (mode, MR795) == 0)
- {
- // ener_code = <xn xn> * 2^27*2^exp_code
- // frac_en = ener_code / 2^16
- // = <xn xn> * 2^11*2^exp_code
- // <xn xn> = <xn xn>*2^11*2^exp * 2^exp_en
- // := frac_en * 2^exp_en
-
- // ==> exp_en = -11-exp_code;
-
- *frac_en = extract_h (ener_code);
- *exp_en = sub (-11, exp_code);
-
- // mean = 36 dB
- L_tmp = L_mac(L_tmp, 17062, 64); // Q14
- }
- else if (sub (mode, MR74) == 0)
- {
- // mean = 30 dB
- L_tmp = L_mac(L_tmp, 32588, 32); // Q14
- }
- else if (sub (mode, MR67) == 0)
- {
- // mean = 28.75 dB
- L_tmp = L_mac(L_tmp, 32268, 32); // Q14
- }
- else // MR59, MR515, MR475
- {
- // mean = 33 dB
- L_tmp = L_mac(L_tmp, 16678, 64); // Q14
- }
-
- *-----------------------------------------------------------------*
- * Compute gcode0. *
- * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener *
- *-----------------------------------------------------------------*
-
- L_tmp = L_shl(L_tmp, 10); // Q24
- for (i = 0; i < 4; i++)
- L_tmp = L_mac(L_tmp, pred[i], st->past_qua_en[i]);
- // Q13 * Q10 -> Q24
-
- gcode0 = extract_h(L_tmp); // Q8
-
- *-----------------------------------------------------------------*
- * gcode0 = pow(10.0, gcode0/20) *
- * = pow(2, 3.3219*gcode0/20) *
- * = pow(2, 0.166*gcode0) *
- *-----------------------------------------------------------------*
-
- // 5439 Q15 = 0.165985
- // (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15)
- if (sub (mode, MR74) == 0) // For IS641 bitexactness
- L_tmp = L_mult(gcode0, 5439); // Q8 * Q15 -> Q24
- else
- L_tmp = L_mult(gcode0, 5443); // Q8 * Q15 -> Q24
-
- L_tmp = L_shr(L_tmp, 8); // -> Q16
- L_Extract(L_tmp, exp_gcode0, frac_gcode0); // -> Q0.Q15
- }
-}
-
-------------------------------------------------------------------------------
- RESOURCES USED [optional]
-
- When the code is written for a specific target processor the
- the resources used should be documented below.
-
- HEAP MEMORY USED: x bytes
-
- STACK MEMORY USED: x bytes
-
- CLOCK CYCLES: (cycle count equation for this function) + (variable
- used to represent cycle count for each subroutine
- called)
- where: (cycle count variable) = cycle count for [subroutine
- name]
-
-------------------------------------------------------------------------------
- CAUTION [optional]
- [State any special notes, constraints or cautions for users of this function]
-
-------------------------------------------------------------------------------
-*/
-
-void gc_pred(
- gc_predState *st, /* i/o: State struct */
- enum Mode mode, /* i : AMR mode */
- Word16 *code, /* i : innovative codebook vector (L_SUBFR) */
- /* MR122: Q12, other modes: Q13 */
- Word16 *exp_gcode0, /* o : exponent of predicted gain factor, Q0 */
- Word16 *frac_gcode0,/* o : fraction of predicted gain factor Q15 */
- Word16 *exp_en, /* o : exponent of innovation energy, Q0 */
- /* (only calculated for MR795) */
- Word16 *frac_en, /* o : fraction of innovation energy, Q15 */
- /* (only calculated for MR795) */
- Flag *pOverflow
-)
-{
- register Word16 i;
- register Word32 L_temp1, L_temp2;
- register Word32 L_tmp;
- Word32 ener_code;
- Word32 ener;
- Word16 exp, frac;
- Word16 exp_code, gcode0;
- Word16 tmp;
- Word16 *p_code = &code[0];
-
- /*-------------------------------------------------------------------*
- * energy of code: *
- * ~~~~~~~~~~~~~~~ *
- * ener_code = sum(code[i]^2) *
- *-------------------------------------------------------------------*/
- ener_code = 0;
-
- /* MR122: Q12*Q12 -> Q25 */
- /* others: Q13*Q13 -> Q27 */
-
- for (i = L_SUBFR >> 2; i != 0; i--)
- {
- tmp = *(p_code++);
- ener_code += ((Word32) tmp * tmp) >> 3;
- tmp = *(p_code++);
- ener_code += ((Word32) tmp * tmp) >> 3;
- tmp = *(p_code++);
- ener_code += ((Word32) tmp * tmp) >> 3;
- tmp = *(p_code++);
- ener_code += ((Word32) tmp * tmp) >> 3;
- }
-
- ener_code <<= 4;
-
- if (ener_code < 0) /* Check for saturation */
- {
- ener_code = MAX_32;
- }
-
- if (mode == MR122)
- {
- /* ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20 */
- /* Q9 * Q20 -> Q30 */
-
- ener_code = ((Word32)(pv_round(ener_code, pOverflow) * 26214)) << 1;
-
- /*-------------------------------------------------------------*
- * energy of code: *
- * ~~~~~~~~~~~~~~~ *
- * ener_code(Q17) = 10 * Log10(energy) / constant *
- * = 1/2 * Log2(energy) *
- * constant = 20*Log10(2) *
- *-------------------------------------------------------------*/
- /* ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30 */
- Log2(ener_code, &exp, &frac, pOverflow);
-
- /* Q16 for log() */
- /* ->Q17 for 1/2 log()*/
-
- L_temp1 = (Word32)(exp - 30) << 16;
- ener_code = L_temp1 + ((Word32)frac << 1);
-
- /*-------------------------------------------------------------*
- * predicted energy: *
- * ~~~~~~~~~~~~~~~~~ *
- * ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant *
- * = MEAN_ENER + sum(pred[i]*past_qua_en[i]) *
- * constant = 20*Log10(2) *
- *-------------------------------------------------------------*/
-
- ener = MEAN_ENER_MR122; /* Q24 (Q17) */
- for (i = 0; i < NPRED; i++)
- {
- L_temp1 = (((Word32) st->past_qua_en_MR122[i]) *
- pred_MR122[i]) << 1;
- ener = L_add(ener, L_temp1, pOverflow);
-
- /* Q10 * Q13 -> Q24 */
- /* Q10 * Q6 -> Q17 */
- }
-
- /*---------------------------------------------------------------*
- * predicted codebook gain *
- * ~~~~~~~~~~~~~~~~~~~~~~~ *
- * gc0 = Pow10( (ener*constant - ener_code*constant) / 20 ) *
- * = Pow2(ener-ener_code) *
- * = Pow2(int(d)+frac(d)) *
- * *
- * (store exp and frac for pow2()) *
- *---------------------------------------------------------------*/
- /* Q16 */
-
- L_temp1 = L_sub(ener, ener_code, pOverflow);
-
-
- *exp_gcode0 = (Word16)(L_temp1 >> 17);
-
- L_temp2 = (Word32) * exp_gcode0 << 15;
- L_temp1 >>= 2;
-
- *frac_gcode0 = (Word16)(L_temp1 - L_temp2);
-
- }
- else /* all modes except 12.2 */
- {
- /*-----------------------------------------------------------------*
- * Compute: means_ener - 10log10(ener_code/ L_sufr) *
- *-----------------------------------------------------------------*/
-
- exp_code = norm_l(ener_code);
- ener_code = L_shl(ener_code, exp_code, pOverflow);
-
- /* Log2 = log2 + 27 */
- Log2_norm(ener_code, exp_code, &exp, &frac);
-
- /* fact = 10/log2(10) = 3.01 = 24660 Q13 */
- /* Q0.Q15 * Q13 -> Q14 */
-
- L_temp2 = (((Word32) exp) * -24660) << 1;
- L_tmp = (((Word32) frac) * -24660) >> 15;
-
- /* Sign-extend resulting product */
- if (L_tmp & (Word32) 0x00010000L)
- {
- L_tmp = L_tmp | (Word32) 0xffff0000L;
- }
-
- L_tmp = L_tmp << 1;
- L_tmp = L_add(L_tmp, L_temp2, pOverflow);
-
-
- /* L_tmp = means_ener - 10log10(ener_code/L_SUBFR)
- * = means_ener - 10log10(ener_code) + 10log10(L_SUBFR)
- * = K - fact * Log2(ener_code)
- * = K - fact * log2(ener_code) - fact*27
- *
- * ==> K = means_ener + fact*27 + 10log10(L_SUBFR)
- *
- * means_ener = 33 = 540672 Q14 (MR475, MR515, MR59)
- * means_ener = 28.75 = 471040 Q14 (MR67)
- * means_ener = 30 = 491520 Q14 (MR74)
- * means_ener = 36 = 589824 Q14 (MR795)
- * means_ener = 33 = 540672 Q14 (MR102)
- * 10log10(L_SUBFR) = 16.02 = 262481.51 Q14
- * fact * 27 = 1331640 Q14
- * -----------------------------------------
- * (MR475, MR515, MR59) K = 2134793.51 Q14 ~= 16678 * 64 * 2
- * (MR67) K = 2065161.51 Q14 ~= 32268 * 32 * 2
- * (MR74) K = 2085641.51 Q14 ~= 32588 * 32 * 2
- * (MR795) K = 2183945.51 Q14 ~= 17062 * 64 * 2
- * (MR102) K = 2134793.51 Q14 ~= 16678 * 64 * 2
- */
-
- if (mode == MR102)
- {
- /* mean = 33 dB */
- L_temp2 = (Word32) 16678 << 7;
- L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */
- }
- else if (mode == MR795)
- {
- /* ener_code = <xn xn> * 2^27*2^exp_code
- frac_en = ener_code / 2^16
- = <xn xn> * 2^11*2^exp_code
- <xn xn> = <xn xn>*2^11*2^exp * 2^exp_en
- : = frac_en * 2^exp_en
- ==> exp_en = -11-exp_code; */
- *frac_en = (Word16)(ener_code >> 16);
- *exp_en = sub(-11, exp_code, pOverflow);
-
- /* mean = 36 dB */
- L_temp2 = (Word32) 17062 << 7;
- L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */
- }
- else if (mode == MR74)
- {
- /* mean = 30 dB */
- L_temp2 = (Word32) 32588 << 6;
- L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */
- }
- else if (mode == MR67)
- {
- /* mean = 28.75 dB */
- L_temp2 = (Word32) 32268 << 6;
- L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */
- }
- else /* MR59, MR515, MR475 */
- {
- /* mean = 33 dB */
- L_temp2 = (Word32) 16678 << 7;
- L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */
- }
-
- /*-------------------------------------------------------------*
- * Compute gcode0. *
- * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener *
- *--------------------------------------------------------------*/
- /* Q24 */
- if (L_tmp > (Word32) 0X001fffffL)
- {
- *pOverflow = 1;
- L_tmp = MAX_32;
- }
- else if (L_tmp < (Word32) 0xffe00000L)
- {
- *pOverflow = 1;
- L_tmp = MIN_32;
- }
- else
- {
- L_tmp = L_tmp << 10;
- }
-
- for (i = 0; i < 4; i++)
- {
- L_temp2 = ((((Word32) pred[i]) * st->past_qua_en[i]) << 1);
- L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q13 * Q10 -> Q24 */
- }
-
- gcode0 = (Word16)(L_tmp >> 16); /* Q8 */
-
- /*-----------------------------------------------------------*
- * gcode0 = pow(10.0, gcode0/20) *
- * = pow(2, 3.3219*gcode0/20) *
- * = pow(2, 0.166*gcode0) *
- *-----------------------------------------------------------*/
-
- /* 5439 Q15 = 0.165985 */
- /* (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15) */
-
- if (mode == MR74) /* For IS641 bitexactness */
- {
- L_tmp = (((Word32) gcode0) * 5439) << 1; /* Q8 * Q15 -> Q24 */
- }
- else
- {
- L_tmp = (((Word32) gcode0) * 5443) << 1; /* Q8 * Q15 -> Q24 */
- }
-
- if (L_tmp < 0)
- {
- L_tmp = ~((~L_tmp) >> 8);
- }
- else
- {
- L_tmp = L_tmp >> 8; /* -> Q16 */
- }
-
- *exp_gcode0 = (Word16)(L_tmp >> 16);
- if (L_tmp < 0)
- {
- L_temp1 = ~((~L_tmp) >> 1);
- }
- else
- {
- L_temp1 = L_tmp >> 1;
- }
- L_temp2 = (Word32) * exp_gcode0 << 15;
- *frac_gcode0 = (Word16)(L_sub(L_temp1, L_temp2, pOverflow));
- /* -> Q0.Q15 */
- }
-
- return;
-}
-
-/****************************************************************************/
-
-/*
-------------------------------------------------------------------------------
- FUNCTION NAME: gc_pred_update
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
- st = pointer to a structure of type gc_predState
- qua_ener_MR122 = quantized energy for update (Q10); calculated as
- (log2(qua_err)) (Word16)
- qua_ener = quantized energy for update (Q10); calculated as
- (20*log10(qua_err)) (Word16)
-
- Outputs:
- structure pointed to by st contains the calculated quantized energy
- for update
-
- Returns:
- None
-
- Global Variables Used:
- None
-
- Local Variables Needed:
- None
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- This function updates the MA predictor with the last quantized energy.
-
-------------------------------------------------------------------------------
- REQUIREMENTS
-
- None
-
-------------------------------------------------------------------------------
- REFERENCES
-
- gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
-
-------------------------------------------------------------------------------
- PSEUDO-CODE
-
-void gc_pred_update(
- gc_predState *st, // i/o: State struct
- Word16 qua_ener_MR122, // i : quantized energy for update, Q10
- // (log2(qua_err))
- Word16 qua_ener // i : quantized energy for update, Q10
- // (20*log10(qua_err))
-)
-{
- Word16 i;
-
- for (i = 3; i > 0; i--)
- {
- st->past_qua_en[i] = st->past_qua_en[i - 1];
- st->past_qua_en_MR122[i] = st->past_qua_en_MR122[i - 1];
- }
-
- st->past_qua_en_MR122[0] = qua_ener_MR122; // log2 (qua_err), Q10
-
- st->past_qua_en[0] = qua_ener; // 20*log10(qua_err), Q10
-
-}
-
-------------------------------------------------------------------------------
- RESOURCES USED [optional]
-
- When the code is written for a specific target processor the
- the resources used should be documented below.
-
- HEAP MEMORY USED: x bytes
-
- STACK MEMORY USED: x bytes
-
- CLOCK CYCLES: (cycle count equation for this function) + (variable
- used to represent cycle count for each subroutine
- called)
- where: (cycle count variable) = cycle count for [subroutine
- name]
-
-------------------------------------------------------------------------------
- CAUTION [optional]
- [State any special notes, constraints or cautions for users of this function]
-
-------------------------------------------------------------------------------
-*/
-
-void gc_pred_update(
- gc_predState *st, /* i/o: State struct */
- Word16 qua_ener_MR122, /* i : quantized energy for update, Q10 */
- /* (log2(qua_err)) */
- Word16 qua_ener /* i : quantized energy for update, Q10 */
- /* (20*log10(qua_err)) */
-)
-{
- st->past_qua_en[3] = st->past_qua_en[2];
- st->past_qua_en_MR122[3] = st->past_qua_en_MR122[2];
-
- st->past_qua_en[2] = st->past_qua_en[1];
- st->past_qua_en_MR122[2] = st->past_qua_en_MR122[1];
-
- st->past_qua_en[1] = st->past_qua_en[0];
- st->past_qua_en_MR122[1] = st->past_qua_en_MR122[0];
-
- st->past_qua_en_MR122[0] = qua_ener_MR122; /* log2 (qua_err), Q10 */
-
- st->past_qua_en[0] = qua_ener; /* 20*log10(qua_err), Q10 */
-
- return;
-}
-
-/****************************************************************************/
-
-/*
-------------------------------------------------------------------------------
- FUNCTION NAME: gc_pred_average_limited
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
- st = pointer to a structure of type gc_predState
- ener_avg_MR122 = pointer to the averaged quantized energy (Q10);
- calculated as (log2(qua_err)) (Word16)
- ener_avg = pointer to the averaged quantized energy (Q10); calculated
- as (20*log10(qua_err)) (Word16)
- pOverflow = pointer to overflow (Flag)
-
- Outputs:
- store pointed to by ener_avg_MR122 contains the new averaged quantized
- energy
- store pointed to by ener_avg contains the new averaged quantized
- energy
- pOverflow = 1 if the math functions called by gc_pred_average_limited
- results in overflow else zero.
-
- Returns:
- None
-
- Global Variables Used:
- None
-
- Local Variables Needed:
- None
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- This function calculates the average of MA predictor state values (with a
- lower limit) used in error concealment.
-
-------------------------------------------------------------------------------
- REQUIREMENTS
-
- None
-
-------------------------------------------------------------------------------
- REFERENCES
-
- gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
-
-------------------------------------------------------------------------------
- PSEUDO-CODE
-
-The original etsi reference code uses a global flag Overflow. However, in the
-actual implementation a pointer to a the overflow flag is passed in.
-
-void gc_pred_average_limited(
- gc_predState *st, // i: State struct
- Word16 *ener_avg_MR122, // o: everaged quantized energy, Q10
- // (log2(qua_err))
- Word16 *ener_avg // o: averaged quantized energy, Q10
- // (20*log10(qua_err))
-)
-{
- Word16 av_pred_en;
- Word16 i;
-
- // do average in MR122 mode (log2() domain)
- av_pred_en = 0;
- for (i = 0; i < NPRED; i++)
- {
- av_pred_en = add (av_pred_en, st->past_qua_en_MR122[i]);
- }
-
- // av_pred_en = 0.25*av_pred_en
- av_pred_en = mult (av_pred_en, 8192);
-
- // if (av_pred_en < -14/(20Log10(2))) av_pred_en = ..
-
- if (sub (av_pred_en, MIN_ENERGY_MR122) < 0)
- {
- av_pred_en = MIN_ENERGY_MR122;
- }
- *ener_avg_MR122 = av_pred_en;
-
- // do average for other modes (20*log10() domain)
- av_pred_en = 0;
- for (i = 0; i < NPRED; i++)
- {
- av_pred_en = add (av_pred_en, st->past_qua_en[i]);
- }
-
- // av_pred_en = 0.25*av_pred_en
- av_pred_en = mult (av_pred_en, 8192);
-
- // if (av_pred_en < -14) av_pred_en = ..
-
- if (sub (av_pred_en, MIN_ENERGY) < 0)
- {
- av_pred_en = MIN_ENERGY;
- }
- *ener_avg = av_pred_en;
-}
-
-------------------------------------------------------------------------------
- RESOURCES USED [optional]
-
- When the code is written for a specific target processor the
- the resources used should be documented below.
-
- HEAP MEMORY USED: x bytes
-
- STACK MEMORY USED: x bytes
-
- CLOCK CYCLES: (cycle count equation for this function) + (variable
- used to represent cycle count for each subroutine
- called)
- where: (cycle count variable) = cycle count for [subroutine
- name]
-
-------------------------------------------------------------------------------
- CAUTION [optional]
- [State any special notes, constraints or cautions for users of this function]
-
-------------------------------------------------------------------------------
-*/
-
-void gc_pred_average_limited(
- gc_predState *st, /* i: State struct */
- Word16 *ener_avg_MR122, /* o: everaged quantized energy, Q10 */
- /* (log2(qua_err)) */
- Word16 *ener_avg, /* o: averaged quantized energy, Q10 */
- /* (20*log10(qua_err)) */
- Flag *pOverflow
-)
-{
- Word16 av_pred_en;
- register Word16 i;
-
- /* do average in MR122 mode (log2() domain) */
- av_pred_en = 0;
- for (i = 0; i < NPRED; i++)
- {
- av_pred_en =
- add(av_pred_en, st->past_qua_en_MR122[i], pOverflow);
- }
-
- /* av_pred_en = 0.25*av_pred_en (with sign-extension)*/
- if (av_pred_en < 0)
- {
- av_pred_en = (av_pred_en >> 2) | 0xc000;
- }
- else
- {
- av_pred_en >>= 2;
- }
-
- /* if (av_pred_en < -14/(20Log10(2))) av_pred_en = .. */
- if (av_pred_en < MIN_ENERGY_MR122)
- {
- av_pred_en = MIN_ENERGY_MR122;
- }
- *ener_avg_MR122 = av_pred_en;
-
- /* do average for other modes (20*log10() domain) */
- av_pred_en = 0;
- for (i = 0; i < NPRED; i++)
- {
- av_pred_en = add(av_pred_en, st->past_qua_en[i], pOverflow);
- }
-
- /* av_pred_en = 0.25*av_pred_en (with sign-extension)*/
- if (av_pred_en < 0)
- {
- av_pred_en = (av_pred_en >> 2) | 0xc000;
- }
- else
- {
- av_pred_en >>= 2;
- }
-
- /* if (av_pred_en < -14) av_pred_en = .. */
- if (av_pred_en < MIN_ENERGY)
- {
- av_pred_en = MIN_ENERGY;
- }
- *ener_avg = av_pred_en;
-}