⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dec_gain2_amr_wb.cpp

📁 实现3GPP的GSM中AMR语音的CODECS。
💻 CPP
字号:
/* ------------------------------------------------------------------ * Copyright (C) 2008 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.173    ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec    Available from http://www.3gpp.org(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)Permission to distribute, modify and use this file under the standard licenseterms listed above has been obtained from the copyright holder.****************************************************************************************//*------------------------------------------------------------------------------ Filename: dec_gain2_amr_wb.cpp     Date: 05/08/2004------------------------------------------------------------------------------ REVISION HISTORY Description:------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS     int16 index,                 (i)     : index of quantization.     int16 nbits,                 (i)     : number of bits (6 or 7)     int16 code[],                (i) Q9  : Innovative vector.     int16 L_subfr,               (i)     : Subframe lenght.     int16 * gain_pit,            (o) Q14 : Pitch gain.     int32 * gain_cod,            (o) Q16 : Code gain.     int16 bfi,                   (i)     : bad frame indicator     int16 prev_bfi,              (i)     : Previous BF indicator     int16 state,                 (i)     : State of BFH     int16 unusable_frame,        (i)     : UF indicator     int16 vad_hist,              (i)     : number of non-speech frames     int16 * mem                  (i/o)   : static memory (4 words)------------------------------------------------------------------------------ FUNCTION DESCRIPTION    Decode the pitch and codebook gains------------------------------------------------------------------------------ REQUIREMENTS------------------------------------------------------------------------------ REFERENCES------------------------------------------------------------------------------ PSEUDO-CODE------------------------------------------------------------------------------*//*----------------------------------------------------------------------------; INCLUDES----------------------------------------------------------------------------*/#include "pv_amr_wb_type_defs.h"#include "pvamrwbdecoder_basic_op.h"#include "pvamrwb_math_op.h"#include "pvamrwbdecoder_cnst.h"#include "pvamrwbdecoder_acelp.h"#include "qisf_ns.h"/*----------------------------------------------------------------------------; MACROS; Define module specific macros here----------------------------------------------------------------------------*//*----------------------------------------------------------------------------; DEFINES; Include all pre-processor statements here. Include conditional; compile variables also.----------------------------------------------------------------------------*/#define MEAN_ENER    30#define PRED_ORDER   4#define L_LTPHIST 5/*----------------------------------------------------------------------------; LOCAL FUNCTION DEFINITIONS; Function Prototype declaration----------------------------------------------------------------------------*//*----------------------------------------------------------------------------; LOCAL STORE/BUFFER/POINTER DEFINITIONS; Variable declaration - defined here and used outside this module----------------------------------------------------------------------------*/const int16 pdown_unusable[7] = {32767, 31130, 29491, 24576, 7537, 1638, 328};const int16 cdown_unusable[7] = {32767, 16384, 8192, 8192, 8192, 4915, 3277};const int16 pdown_usable[7] = {32767, 32113, 31457, 24576, 7537, 1638, 328};const int16 cdown_usable[7] = {32767, 32113, 32113, 32113, 32113, 32113, 22938};/* MA prediction coeff ={0.5, 0.4, 0.3, 0.2} in Q13 */const int16 pred[PRED_ORDER] = {4096, 3277, 2458, 1638};/*----------------------------------------------------------------------------; EXTERNAL FUNCTION REFERENCES; Declare functions defined elsewhere and referenced in this module----------------------------------------------------------------------------*//*----------------------------------------------------------------------------; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES; Declare variables used in this module but defined elsewhere----------------------------------------------------------------------------*//*----------------------------------------------------------------------------; FUNCTION CODE----------------------------------------------------------------------------*//* output  :static memory (4 words)      */void dec_gain2_amr_wb_init(int16 * mem){    /* 4nd order quantizer energy predictor (init to -14.0 in Q10) */    mem[0] = -14336;                          /* past_qua_en[0] */    mem[1] = -14336;                          /* past_qua_en[1] */    mem[2] = -14336;                          /* past_qua_en[2] */    mem[3] = -14336;                          /* past_qua_en[3] */    /* 4  *past_gain_pit  */    /* 5  *past_gain_code  */    /* 6  *prev_gc  */    /* next 5  pbuf[]  */    /* next 5  gbuf[]  */    /* next 5  pbuf2[]  */    pv_memset((void *)&mem[4], 0, 18*sizeof(*mem));    mem[22] = 21845;}/*----------------------------------------------------------------------------; FUNCTION CODE----------------------------------------------------------------------------*/void dec_gain2_amr_wb(    int16 index,               /* (i)     : index of quantization.      */    int16 nbits,               /* (i)     : number of bits (6 or 7)     */    int16 code[],              /* (i) Q9  : Innovative vector.          */    int16 L_subfr,             /* (i)     : Subframe lenght.            */    int16 * gain_pit,          /* (o) Q14 : Pitch gain.                 */    int32 * gain_cod,          /* (o) Q16 : Code gain.                  */    int16 bfi,                 /* (i)     : bad frame indicator         */    int16 prev_bfi,            /* (i)     : Previous BF indicator       */    int16 state,               /* (i)     : State of BFH                */    int16 unusable_frame,      /* (i)     : UF indicator                */    int16 vad_hist,            /* (i)     : number of non-speech frames */    int16 * mem                /* (i/o)   : static memory (4 words)     */){    const int16 *p;    int16 *past_gain_pit, *past_gain_code, *past_qua_en, *gbuf, *pbuf, *prev_gc;    int16 *pbuf2;    int16 i, tmp, exp, frac, gcode0, exp_gcode0, qua_ener, gcode_inov;    int16 tmp1, g_code;    int16 tmp2;    int32 L_tmp;    past_qua_en = mem;    past_gain_pit = mem + 4;    past_gain_code = mem + 5;    prev_gc = mem + 6;    pbuf = mem + 7;    gbuf = mem + 12;    pbuf2 = mem + 17;    /*     *  Find energy of code and compute:     *     *    L_tmp = 1.0 / sqrt(energy of code/ L_subfr)     */    L_tmp = Dot_product12(code, code, L_subfr, &exp);    exp -= 24;                /* exp: -18 (code in Q9), -6 (/L_subfr) */    one_ov_sqrt_norm(&L_tmp, &exp);    gcode_inov = extract_h(shl_int32(L_tmp, exp - 3));  /* g_code_inov in Q12 */    /*     * Case of erasure.     */    if (bfi != 0)    {        tmp = median5(&pbuf[2]);        *past_gain_pit = tmp;        if (*past_gain_pit > 15565)        {            *past_gain_pit = 15565;        /* 0.95 in Q14 */        }        if (unusable_frame != 0)        {            *gain_pit = mult_int16(pdown_unusable[state], *past_gain_pit);        }        else        {            *gain_pit = mult_int16(pdown_usable[state], *past_gain_pit);        }        tmp = median5(&gbuf[2]);        if (vad_hist > 2)        {            *past_gain_code = tmp;        }        else        {            if (unusable_frame != 0)            {                *past_gain_code = mult_int16(cdown_unusable[state], tmp);            }            else            {                *past_gain_code = mult_int16(cdown_usable[state], tmp);            }        }        /* update table of past quantized energies */        tmp  = past_qua_en[3];        tmp1 = past_qua_en[2];        L_tmp  = tmp;        L_tmp += tmp1;        past_qua_en[3] = tmp;        tmp  = past_qua_en[1];        tmp1 = past_qua_en[0];        L_tmp += tmp;        L_tmp += tmp1;        past_qua_en[2] = tmp;        qua_ener = (int16)(L_tmp >> 3);        past_qua_en[1] = tmp1;        qua_ener -= 3072;    /* -3 in Q10 */        if (qua_ener < -14336)        {            qua_ener = -14336;                /* -14 in Q10 */        }        past_qua_en[0] = qua_ener;        for (i = 1; i < 5; i++)        {            gbuf[i - 1] = gbuf[i];            pbuf[i - 1] = pbuf[i];        }        gbuf[4] = *past_gain_code;        pbuf[4] = *past_gain_pit;        /* adjust gain according to energy of code */        /* past_gain_code(Q3) * gcode_inov(Q12) => Q16 */        *gain_cod = mul_16by16_to_int32(*past_gain_code, gcode_inov);        return;    }    /*     * Compute gcode0     *  = Sum(i=0,1) pred[i]*past_qua_en[i] + mean_ener - ener_code     */    L_tmp = L_deposit_h(MEAN_ENER);        /* MEAN_ENER in Q16 */    L_tmp = shl_int32(L_tmp, 8);               /* From Q16 to Q24 */    L_tmp = mac_16by16_to_int32(L_tmp, pred[0], past_qua_en[0]);      /* Q13*Q10 -> Q24 */    L_tmp = mac_16by16_to_int32(L_tmp, pred[1], past_qua_en[1]);      /* Q13*Q10 -> Q24 */    L_tmp = mac_16by16_to_int32(L_tmp, pred[2], past_qua_en[2]);      /* Q13*Q10 -> Q24 */    L_tmp = mac_16by16_to_int32(L_tmp, pred[3], past_qua_en[3]);      /* Q13*Q10 -> Q24 */    gcode0 = extract_h(L_tmp);             /* From Q24 to Q8  */    /*     * gcode0 = pow(10.0, gcode0/20)     *        = pow(2, 3.321928*gcode0/20)     *        = pow(2, 0.166096*gcode0)     */    L_tmp = ((int32)gcode0 * 5443) >> 7;      /* *0.166096 in Q15 -> Q24     */    int32_to_dpf(L_tmp, &exp_gcode0, &frac);  /* Extract exponant of gcode0  */    gcode0 = (int16)(power_of_2(14, frac));    /* Put 14 as exponant so that  */    /* output of Pow2() will be:   */    /* 16384 < Pow2() <= 32767     */    exp_gcode0 -= 14;    /* Read the quantized gains */    if (nbits == 6)    {        p = &t_qua_gain6b[index<<1];    }    else    {        p = &t_qua_gain7b[index<<1];    }    *gain_pit = *p++;                         /* selected pitch gain in Q14 */    g_code = *p++;                            /* selected code gain in Q11  */    L_tmp = mul_16by16_to_int32(g_code, gcode0);        /* Q11*Q0 -> Q12 */    L_tmp = shl_int32(L_tmp, exp_gcode0 + 4);   /* Q12 -> Q16 */    *gain_cod = L_tmp;                        /* gain of code in Q16 */    if (prev_bfi == 1)    {        L_tmp = mul_16by16_to_int32(*prev_gc, 5120);    /* prev_gc(Q3) * 1.25(Q12) = Q16 */        /* if((*gain_cod > ((*prev_gc) * 1.25)) && (*gain_cod > 100.0)) */        if ((*gain_cod > L_tmp) && (*gain_cod > 6553600))        {            *gain_cod = L_tmp;        }    }    /* keep past gain code in Q3 for frame erasure (can saturate) */    *past_gain_code = amr_wb_round(shl_int32(*gain_cod, 3));    *past_gain_pit = *gain_pit;    *prev_gc = *past_gain_code;    tmp  = gbuf[1];    tmp1 = pbuf[1];    tmp2 = pbuf2[1];    for (i = 1; i < 5; i++)    {        gbuf[i - 1]  = tmp;        pbuf[i - 1]  = tmp1;        pbuf2[i - 1] = tmp2;        tmp  = gbuf[i];        tmp1 = pbuf[i];        tmp2 = pbuf2[i];    }    gbuf[4] = *past_gain_code;    pbuf[4] = *past_gain_pit;    pbuf2[4] = *past_gain_pit;    /* adjust gain according to energy of code */    int32_to_dpf(*gain_cod, &exp, &frac);    L_tmp = mul_32by16(exp, frac, gcode_inov);    *gain_cod = shl_int32(L_tmp, 3);              /* gcode_inov in Q12 */    past_qua_en[3] = past_qua_en[2];    past_qua_en[2] = past_qua_en[1];    past_qua_en[1] = past_qua_en[0];    /*     * qua_ener = 20*log10(g_code)     *          = 6.0206*log2(g_code)     *          = 6.0206*(log2(g_codeQ11) - 11)     */    L_tmp = (int32)g_code;    amrwb_log_2(L_tmp, &exp, &frac);    exp -= 11;    L_tmp = mul_32by16(exp, frac, 24660);   /* x 6.0206 in Q12 */    /* update table of past quantized energies */    past_qua_en[0] = (int16)(L_tmp >> 3); /* result in Q10 */    return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -