📄 c2_9pf.cpp
字号:
mult( *(code + i - T0), sharp, pOverflow); *(code + i) = add( *(code + i), temp, pOverflow); } } return(index); } /****************************************************************************/ /* ------------------------------------------------------------------------------ FUNCTION NAME: search_2i40 ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: subNr = subframe number (Word16) dn = vector containing the correlation between target and the impulse response of the weighted synthesis filter (Word16) rr = autocorrelation matrix (Word16) codvec = algebraic codebook vector (Word16) Outputs: codvec contains the newly calculated codevectors Returns: None Global Variables Used: None Local Variables Needed: startPos = table containing the start positions used by fixed codebook routines (const Word16) ------------------------------------------------------------------------------ FUNCTION DESCRIPTION This function searches the best codevector and determines the positions of the 2 pulses in the 40-sample frame. ------------------------------------------------------------------------------ REQUIREMENTS None ------------------------------------------------------------------------------ REFERENCES [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 ------------------------------------------------------------------------------ PSEUDO-CODE static void search_2i40( Word16 subNr, // i : subframe number Word16 dn[], // i : correlation between target and h[] Word16 rr[][L_CODE], // i : matrix of autocorrelation Word16 codvec[] // o : algebraic codebook vector ) { Word16 i0, i1; Word16 ix = 0; // initialization only needed to keep gcc silent Word16 track1, ipos[NB_PULSE]; Word16 psk, ps0, ps1, sq, sq1; Word16 alpk, alp, alp_16; Word32 s, alp0, alp1; Word16 i; psk = -1; alpk = 1; for (i = 0; i < NB_PULSE; i++) { codvec[i] = i; } for (track1 = 0; track1 < 2; track1++) { // fix starting position ipos[0] = startPos[subNr*2+8*track1]; ipos[1] = startPos[subNr*2+1+8*track1]; *----------------------------------------------------------------* * i0 loop: try 8 positions. * *----------------------------------------------------------------* for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP) { ps0 = dn[i0]; alp0 = L_mult(rr[i0][i0], _1_4); *----------------------------------------------------------------* * i1 loop: 8 positions. * *----------------------------------------------------------------* sq = -1; alp = 1; ix = ipos[1]; *-------------------------------------------------------------------* * These index have low complexity address computation because * * they are, in fact, pointers with fixed increment. For example, * * "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]" * * and incremented by "STEP". * *-------------------------------------------------------------------* for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) { ps1 = add(ps0, dn[i1]); // idx increment = STEP // alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; alp1 = L_mac(alp0, rr[i1][i1], _1_4); // idx incr = STEP alp1 = L_mac(alp1, rr[i0][i1], _1_2); // idx incr = STEP sq1 = mult(ps1, ps1); alp_16 = pv_round(alp1); s = L_msu(L_mult(alp, sq1), sq, alp_16); if (s > 0) { sq = sq1; alp = alp_16; ix = i1; } } *----------------------------------------------------------------* * memorise codevector if this one is better than the last one. * *----------------------------------------------------------------* s = L_msu(L_mult(alpk, sq), psk, alp); if (s > 0) { psk = sq; alpk = alp; codvec[0] = i0; codvec[1] = ix; } } } return; } ------------------------------------------------------------------------------ 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] ------------------------------------------------------------------------------ */ static void search_2i40( Word16 subNr, /* i : subframe number */ Word16 dn[], /* i : correlation between target and h[] */ Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ Word16 codvec[], /* o : algebraic codebook vector */ Flag * pOverflow /* o : Flag set when overflow occurs */ ) { register Word16 i0; register Word16 i1; Word16 ix = 0; /* initialization only needed to keep gcc silent */ register Word16 track1; Word16 ipos[NB_PULSE]; Word16 psk; Word16 ps0; Word16 ps1; Word16 sq; Word16 sq1; Word16 alpk; Word16 alp; Word16 alp_16; Word32 s; Word32 alp0; Word32 alp1; register Word16 i; Word32 L_temp; Word16 *p_codvec = &codvec[0]; OSCL_UNUSED_ARG(pOverflow); psk = -1; alpk = 1; /* Unrolled the following FOR loop to save MIPS */ /* for (i = 0; i < NB_PULSE; i++) */ /* { */ /* *(codvec + i) = i; */ /* } */ *(p_codvec++) = 0; *(p_codvec) = 1; for (track1 = 0; track1 < 2; track1++) { /* fix starting position */ i = (subNr << 1) + (track1 << 3); *ipos = *(startPos + i); *(ipos + 1) = *(startPos + i + 1); /*----------------------------------------------------------* * i0 loop: try 8 positions. * *----------------------------------------------------------*/ for (i0 = *ipos; i0 < L_CODE; i0 += STEP) { ps0 = *(dn + i0); /* Left shift by 1 converts integer product to */ /* fractional product. */ alp0 = (Word32) rr[i0][i0] << 14; /*--------------------------------------------------* * i1 loop: 8 positions. * *--------------------------------------------------*/ sq = -1; alp = 1; ix = *(ipos + 1); /*--------------------------------------------------* * These index have low complexity address * * computation because they are, in fact, pointers * * with fixed increment. For example, "rr[i0][i2]" * * is a pointer initialized to "&rr[i0][ipos[2]]" * * and incremented by "STEP". * *---------------------------------------------------*/ for (i1 = *(ipos + 1); i1 < L_CODE; i1 += STEP) { /* idx increment = STEP */ /* ps1 = add(ps0, *(dn + i1), pOverflow); */ ps1 = ps0 + dn[i1]; /* alp1 = alp0+rr[i0][i1]+1/2*rr[i1][i1]; */ /* idx incr = STEP */ /* Extra left shift by 1 converts integer */ /* product to fractional product */ /* alp1 = L_add(alp0, s, pOverflow); */ alp1 = alp0 + ((Word32) rr[i1][i1] << 14); /* idx incr = STEP */ /* Extra left shift by 1 converts integer */ /* product to fractional product */ /* alp1 = L_add(alp1, s, pOverflow); */ alp1 += (Word32) rr[i0][i1] << 15; /* sq1 = mult(ps1, ps1, pOverflow); */ sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); /* alp_16 = pv_round(alp1, pOverflow); */ alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); /* L_temp = L_mult(alp, sq1, pOverflow); */ L_temp = ((Word32) alp * sq1) << 1; /* s = L_msu(L_temp, sq, alp_16, pOverflow); */ s = L_temp - (((Word32) sq * alp_16) << 1); if (s > 0) { sq = sq1; alp = alp_16; ix = i1; } } /* memorize codevector if this one is better than the last one. */ /* L_temp = L_mult(alpk, sq, pOverflow); */ L_temp = ((Word32) alpk * sq) << 1; /* s = L_msu(L_temp, psk, alp, pOverflow); */ s = L_temp - (((Word32) psk * alp) << 1); if (s > 0) { psk = sq; alpk = alp; p_codvec = &codvec[0]; *(p_codvec++) = i0; *(p_codvec) = ix; } } } return; } /****************************************************************************/ /* ------------------------------------------------------------------------------ FUNCTION NAME: Test_search_2i40 ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: subNr = subframe number (Word16) dn = vector containing the correlation between target and the impulse response of the weighted synthesis filter (Word16) rr = autocorrelation matrix (Word16) codvec = algebraic codebook vector (Word16) Outputs: codvec contains the newly calculated codevectors Returns: None Global Variables Used: None Local Variables Needed: startPos = table containing the start positions used by fixed codebook routines (const Word16) ------------------------------------------------------------------------------ FUNCTION DESCRIPTION This function provides external access to the local function search_2i40. ------------------------------------------------------------------------------ REQUIREMENTS None ------------------------------------------------------------------------------ REFERENCES [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 ------------------------------------------------------------------------------ PSEUDO-CODE CALL search_2i40 ( subNr = subNr dn = dn rr = rr codvec = codvec ) MODIFYING(nothing) RETURNING(nothing) ------------------------------------------------------------------------------ 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 Test_search_2i40( Word16 subNr, /* i : subframe number */ Word16 dn[], /* i : correlation between target and h[] */ Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ Word16 codvec[], /* o : algebraic codebook vector */ Flag * pOverflow /* o : Flag set when overflow occurs */ ) { /*---------------------------------------------------------------------------- CALL search_2i40 ( subNr = subNr dn = dn
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -