?? sp_dec.c
字號:
/***************************************************************************
*
* File Name: sp_dec.c
*
* Purpose:
* Contains all functions for decoding speech. It does not
* include those routines needed to decode channel information.
*
* Since the GSM half-rate speech coder is an analysis-by-synthesis
* coder, many of the routines in this file are also called by the
* encoder. Functions are included for coded-parameter lookup,
* LPC filter coefficient interpolation, excitation vector lookup
* and construction, vector quantized gain lookup, and LPC synthesis
* filtering. In addition, some post-processing functions are
* included.
*
* Below is a listing of all the functions appearing in the file.
* The functions are arranged according to their purpose. Under
* each heading, the ordering is hierarchical.
*
* The entire speech decoder, under which all these routines fall,
* except were noted:
* speechDecoder()
*
* Spectral Smoothing of LPC:
* a_sst()
* aFlatRcDp()
* rcToCorrDpL()
* aToRc()
* rcToADp()
* VSELP codevector construction:
* b_con()
* v_con()
* LTP vector contruction:
* fp_ex()
* get_ipjj()
* lagDecode()
* LPC contruction
* getSfrmLpc()
* interpolateCheck()
* res_eng()
* lookupVq()
* Excitation scaling:
* rs_rr()
* g_corr1() (no scaling)
* rs_rrNs()
* g_corr1s() (g_corr1 with scaling)
* scaleExcite()
* Post filtering:
* pitchPreFilt()
* agcGain()
* lpcIir()
* r0BasedEnergyShft()
* spectralPostFilter()
* lpcFir()
*
*
* Routines not referenced by speechDecoder()
* Filtering routines:
* lpcIrZsIir()
* lpcZiIir()
* lpcZsFir()
* lpcZsIir()
* lpcZsIirP()
* Square root:
* sqroot()
*
**************************************************************************/
/*_________________________________________________________________________
| |
| Include Files |
|_________________________________________________________________________|
*/
#include "typedefs.h"
#include "mathhalf.h"
#include "sp_rom.h"
#include "sp_dec.h"
#include "err_conc.h"
#include "dtx.h"
/*_________________________________________________________________________
| |
| Local Functions (scope is limited to this file) |
|_________________________________________________________________________|
*/
static void a_sst(Shortword swAshift, Shortword swAscale,
Shortword pswDirectFormCoefIn[],
Shortword pswDirectFormCoefOut[]);
static short aToRc(Shortword swAshift, Shortword pswAin[],
Shortword pswRc[]);
static Shortword agcGain(Shortword pswStateCurr[],
struct NormSw snsInSigEnergy,
Shortword swEngyRShft);
static Shortword lagDecode(Shortword swDeltaLag);
static void lookupVq(Shortword pswVqCodeWds[], Shortword pswRCOut[]);
static void pitchPreFilt(Shortword pswExcite[],
Shortword swRxGsp0,
Shortword swRxLag,
Shortword swUvCode,
Shortword swSemiBeta,
struct NormSw snsSqrtRs,
Shortword pswExciteOut[],
Shortword pswPPreState[]);
static void spectralPostFilter(Shortword pswSPFIn[],
Shortword pswNumCoef[], Shortword pswDenomCoef[],
Shortword pswSPFOut[]);
/*_________________________________________________________________________
| |
| Local Defines |
|_________________________________________________________________________|
*/
#define P_INT_MACS 10
#define ASCALE 0x0800
#define ASHIFT 4
#define DELTA_LEVELS 16
#define GSP0_SCALE 1
#define C_BITS_V 9 /* number of bits in any voiced VSELP
* codeword */
#define C_BITS_UV 7 /* number of bits in a unvoiced VSELP
* codeword */
#define MAXBITS C_BITS_V /* max number of bits in any VSELP
* codeword */
#define LTP_LEN 147 /* 147==0x93 length of LTP history */
#define SQRT_ONEHALF 0x5a82 /* the 0.5 ** 0.5 */
#define LPC_ROUND 0x00000800L /* 0x8000 >> ASHIFT */
#define AFSHIFT 2 /* number of right shifts to be
* applied to the autocorrelation
* sequence in aFlatRcDp */
/*_________________________________________________________________________
| |
| State variables (globals) |
|_________________________________________________________________________|
*/
Shortword gswPostFiltAgcGain,
gpswPostFiltStateNum[NP],
gpswPostFiltStateDenom[NP],
swPostEmphasisState,
pswSynthFiltState[NP],
pswOldFrmKsDec[NP],
pswOldFrmAsDec[NP],
pswOldFrmPFNum[NP],
pswOldFrmPFDenom[NP],
swOldR0Dec,
pswLtpStateBaseDec[LTP_LEN + S_LEN],
pswPPreState[LTP_LEN + S_LEN];
Shortword swMuteFlagOld; /* error concealment */
/* DTX state variables */
/* ------------------- */
Shortword swRxDTXState = CNINTPER - 1; /* DTX State at the rx.
* Modulo */
/* counter [0,11]. */
Shortword swDecoMode = SPEECH;
Shortword swDtxMuting = 0;
Shortword swDtxBfiCnt = 0;
Shortword swOldR0IndexDec = 0;
Shortword swRxGsHistPtr = 0;
Longword pL_RxGsHist[(OVERHANG - 1) * N_SUB];
/*_________________________________________________________________________
| |
| Global Data |
| (scope is global to this file) |
|_________________________________________________________________________|
*/
Shortword swR0Dec;
Shortword swVoicingMode, /* MODE */
pswVq[3], /* LPC1, LPC2, LPC3 */
swSi, /* INT_LPC */
swEngyRShift; /* for use by spectral postfilter */
Shortword swR0NewCN; /* DTX mode */
extern LongwordRom ppLr_gsTable[4][32]; /* DTX mode */
/***************************************************************************
*
* FUNCTION NAME: aFlatRcDp
*
* PURPOSE:
*
* Given a Longword autocorrelation sequence, representing LPC
* information, aFlatRcDp converts the vector to one of NP
* Shortword reflection coefficients.
*
* INPUT:
*
*
* pL_R[0:NP] - An input Longword autocorrelation sequence, (pL_R[0] =
* not necessarily 0x7fffffffL). pL_R is altered in the
* call, by being right shifted by global constant
* AFSHIFT bits.
*
* The input array pL_R[] should be shifted left as much
* as possible to improve precision.
*
* AFSHIFT - The number of right shifts to be applied to the
* normalized autocorrelation sequence pL_R.
*
* OUTPUT:
*
* pswRc[0:NP-1] - A Shortword output vector of NP reflection
* coefficients.
*
* RETURN VALUE:
*
* None
*
* DESCRIPTION:
*
* This routine transforms LPC information from one set of
* parameters to another. It is better suited for fixed point
* implementations than the Levinson-Dubin recursion.
*
* The function is called by a_sst(), and getNWCoefs(). In a_sst()
* direct form coefficients are converted to autocorrelations,
* and smoothed in that domain. Conversion back to direct form
* coefficients is done by calling aFlatRc(), followed by rcToADp().
*
* In getNwCoefs() again the conversion back to direct form
* coefficients is done by calling aFlatRc(), followed by rcToADp().
* In getNwCoefs() an autocorrelation sequence is generated from the
* impulse response of the weighting filters.
*
* The fundamental recursion is derived from AFLAT, which is
* described in section 4.1.4.1.
*
* Unlike in AFLAT where the reflection coefficients are known, here
* they are the unknowns. PBar and VBar for j==0 are initially
* known, as is rSub1. From this information the next set of P's
* and V's are generated. At the end of the recursion the next,
* reflection coefficient rSubj (pswRc[j]) can be calcluated by
* dividing Vsubj by Psubj.
*
* Precision is crucial in this routine. At each stage, a
* normalization is performed prior to the reflection coefficient
* calculation. In addition, to prevent overflow, the
* autocorrelation sequence is scaled down by ASHIFT (4) right
* shifts.
*
*
* REFERENCES: Sub_Clause 4.1.9 and 4.2.1 of GSM Recomendation 06.20
*
* KEYWORDS: reflection coefficients, AFLAT, aflat, recursion, LPC
* KEYWORDS: autocorrelation
*
*************************************************************************/
void aFlatRcDp(Longword *pL_R, Shortword *pswRc)
{
/*_________________________________________________________________________
| |
| Automatic Variables |
|_________________________________________________________________________|
*/
Longword pL_pjNewSpace[NP];
Longword pL_pjOldSpace[NP];
Longword pL_vjNewSpace[2 * NP - 1];
Longword pL_vjOldSpace[2 * NP - 1];
Longword *pL_pjOld;
Longword *pL_pjNew;
Longword *pL_vjOld;
Longword *pL_vjNew;
Longword *pL_swap;
Longword L_temp;
Longword L_sum;
Shortword swRc,
swRcSq,
swTemp,
swTemp1,
swAbsTemp1,
swTemp2;
int i,
j;
/*_________________________________________________________________________
| |
| Executable Code |
|_________________________________________________________________________|
*/
pL_pjOld = pL_pjOldSpace;
pL_pjNew = pL_pjNewSpace;
pL_vjOld = pL_vjOldSpace + NP - 1;
pL_vjNew = pL_vjNewSpace + NP - 1;
/* Extract the 0-th reflection coefficient */
/*-----------------------------------------*/
swTemp1 = round(pL_R[1]);
swTemp2 = round(pL_R[0]);
swAbsTemp1 = abs_s(swTemp1);
if (swTemp2 <= 0 || sub(swAbsTemp1, swTemp2) >= 0)
{
j = 0;
for (i = j; i < NP; i++)
{
pswRc[i] = 0;
}
return;
}
swRc = divide_s(swAbsTemp1, swTemp2);/* return division result */
if (sub(swTemp1, swAbsTemp1) == 0)
swRc = negate(swRc); /* negate reflection Rc[j] */
pswRc[0] = swRc; /* copy into the output Rc array */
for (i = 0; i <= NP; i++)
{
pL_R[i] = L_shr(pL_R[i], AFSHIFT);
}
/* Initialize the pjOld and vjOld recursion arrays */
/*-------------------------------------------------*/
for (i = 0; i < NP; i++)
{
pL_pjOld[i] = pL_R[i];
pL_vjOld[i] = pL_R[i + 1];
}
for (i = -1; i > -NP; i--)
pL_vjOld[i] = pL_R[-(i + 1)];
/* Compute the square of the j=0 reflection coefficient */
/*------------------------------------------------------*/
swRcSq = mult_r(swRc, swRc);
/* Update pjNew and vjNew arrays for lattice stage j=1 */
/*-----------------------------------------------------*/
/* Updating pjNew: */
/*-------------------*/
for (i = 0; i <= NP - 2; i++)
{
L_temp = L_mpy_ls(pL_vjOld[i], swRc);
L_sum = L_add(L_temp, pL_pjOld[i]);
L_temp = L_mpy_ls(pL_pjOld[i], swRcSq);
L_sum = L_add(L_temp, L_sum);
L_temp = L_mpy_ls(pL_vjOld[-i], swRc);
pL_pjNew[i] = L_add(L_sum, L_temp);
}
/* Updating vjNew: */
/*-------------------*/
for (i = -NP + 2; i <= NP - 2; i++)
{
L_temp = L_mpy_ls(pL_vjOld[-i - 1], swRcSq);
L_sum = L_add(L_temp, pL_vjOld[i + 1]);
L_temp = L_mpy_ls(pL_pjOld[(((i + 1) >= 0) ? i + 1 : -(i + 1))], swRc);
L_temp = L_shl(L_temp, 1);
pL_vjNew[i] = L_add(L_temp, L_sum);
}
j = 0;
/* Compute reflection coefficients Rc[1],...,Rc[9] */
/*-------------------------------------------------*/
for (j = 1; j < NP; j++)
{
/* Swap pjNew and pjOld buffers */
/*------------------------------*/
pL_swap = pL_pjNew;
pL_pjNew = pL_pjOld;
pL_pjOld = pL_swap;
/* Swap vjNew and vjOld buffers */
/*------------------------------*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -