123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- /*
- *****************************************************************************
- *
- * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
- * R99 Version 3.3.0
- * REL-4 Version 4.1.0
- *
- *****************************************************************************
- *
- * File : c2_11pf.c
- * Purpose : Searches a 11 bit algebraic codebook containing 2 pulses
- * in a frame of 40 samples.
- *
- *****************************************************************************
- */
- /*
- *****************************************************************************
- * MODULE INCLUDE FILE AND VERSION ID
- *****************************************************************************
- */
- #include "c2_11pf.h"
- const char c2_11pf_id[] = "@(#)$Id $" c2_11pf_h;
-
- /*
- *****************************************************************************
- * INCLUDE FILES
- *****************************************************************************
- */
- #include "typedef.h"
- #include "basic_op.h"
- #include "count.h"
- #include "inv_sqrt_ex.h"
- #include "cnst.h"
- #include "cor_h.h"
- #include "set_sign.h"
- /*
- *****************************************************************************
- * LOCAL VARIABLES AND TABLES
- *****************************************************************************
- */
- #define NB_PULSE 2
- #include "c2_11pf.tab"
- /*
- *****************************************************************************
- * DECLARATION OF PROTOTYPES
- *****************************************************************************
- */
- static void search_2i40(
- Word16 dn[], /* i : correlation between target and h[] */
- Word16 rr[][L_CODE],/* i : matrix of autocorrelation */
- Word16 codvec[] /* o : algebraic codebook vector */
- );
- static Word16 build_code(
- Word16 codvec[], /* i : algebraic codebook vector */
- Word16 dn_sign[], /* i : sign of dn[] */
- Word16 cod[], /* o : algebraic (fixed) codebook excitation */
- Word16 h[], /* i : impulse response of weighted synthesis filter */
- Word16 y[], /* o : filtered fixed codebook excitation */
- Word16 sign[] /* o : sign of 2 pulses */
- );
- /*
- *****************************************************************************
- * PUBLIC PROGRAM CODE
- *****************************************************************************
- */
- /*************************************************************************
- *
- * FUNCTION: code_2i40_11bits()
- *
- * PURPOSE: Searches a 11 bit algebraic codebook containing 2 pulses
- * in a frame of 40 samples.
- *
- * DESCRIPTION:
- * The code length is 40, containing 2 nonzero pulses: i0...i1.
- * All pulses can have two possible amplitudes: +1 or -1.
- * Pulse i0 can have 2x8=16 possible positions, pulse i1 can have
- * 4x8=32 positions.
- *
- * i0 : 1, 6, 11, 16, 21, 26, 31, 36.
- * 3, 8, 13, 18, 23, 28, 33, 38.
- * i1 : 0, 5, 10, 15, 20, 25, 30, 35.
- * 1, 6, 11, 16, 21, 26, 31, 36.
- * 2, 7, 12, 17, 22, 27, 32, 37.
- * 4, 9, 14, 19, 24, 29, 34, 39.
- *
- *************************************************************************/
- Word16 code_2i40_11bits(
- Word16 x[], /* i : target vector */
- Word16 h[], /* i : impulse response of weighted synthesis filter */
- /* h[-L_subfr..-1] must be set to zero. */
- Word16 T0, /* i : Pitch lag */
- Word16 pitch_sharp, /* i : Last quantized pitch gain */
- Word16 code[], /* o : Innovative codebook */
- Word16 y[], /* o : filtered fixed codebook excitation */
- Word16 * sign /* o : Signs of 2 pulses */
- )
- {
- Word16 codvec[NB_PULSE];
- Word16 dn[L_CODE], dn2[L_CODE], dn_sign[L_CODE];
- Word16 rr[L_CODE][L_CODE];
- Word16 i, index, sharp;
- sharp = shl_ex(pitch_sharp, 1);
- test ();
- if (sub_ex(T0, L_CODE) < 0)
- {
- for (i = T0; i < L_CODE; i++) {
- h[i] = add_ex(h[i], mult_ex(h[i - T0], sharp)); move16 ();
- }
- }
-
- cor_h_x_ex(h, x, dn, 1);
- set_sign(dn, dn_sign, dn2, 8); /* dn2[] not used in this codebook search */
- cor_h(h, dn_sign, rr);
- search_2i40(dn, rr, codvec);
- move16 (); /* function result */
- index = build_code(codvec, dn_sign, code, h, y, sign);
- /*-----------------------------------------------------------------*
- * Compute innovation vector gain. *
- * Include fixed-gain pitch contribution into code[]. *
- *-----------------------------------------------------------------*/
- test ();
- if (sub_ex(T0, L_CODE) < 0)
- {
- for (i = T0; i < L_CODE; i++)
- {
- code[i] = add_ex(code[i], mult_ex(code[i - T0], sharp)); move16 ();
- }
- }
- return index;
- }
- /*
- *****************************************************************************
- * PRIVATE PROGRAM CODE
- *****************************************************************************
- */
- /*************************************************************************
- *
- * FUNCTION search_2i40()
- *
- * PURPOSE: Search the best codevector; determine positions of the 2 pulses
- * in the 40-sample frame.
- *
- *************************************************************************/
- #define _1_2 (Word16)(32768L/2)
- #define _1_4 (Word16)(32768L/4)
- #define _1_8 (Word16)(32768L/8)
- #define _1_16 (Word16)(32768L/16)
- static void search_2i40(
- 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, track2, ipos[NB_PULSE];
- Word16 psk, ps0, ps1, sq, sq1;
- Word16 alpk, alp, alp_16;
- Word32 s, alp0, alp1;
- Word16 i;
- psk = -1; move16 ();
- alpk = 1; move16 ();
- for (i = 0; i < NB_PULSE; i++)
- {
- codvec[i] = i; move16 ();
- }
- /*------------------------------------------------------------------*
- * main loop: try 2x4 tracks. *
- *------------------------------------------------------------------*/
- for (track1 = 0; track1 < 2; track1++)
- {
- for (track2 = 0; track2 < 4; track2++)
- {
- /* fix starting position */
- ipos[0] = startPos1[track1]; move16 ();
- ipos[1] = startPos2[track2]; move16 ();
-
- /*----------------------------------------------------------------*
- * i0 loop: try 8 positions. *
- *----------------------------------------------------------------*/
- move16 (); /* account for ptr. init. (rr[io]) */
- for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP)
- {
- ps0 = dn[i0]; move16 ();
- alp0 = L_mult_ex(rr[i0][i0], _1_4);
-
- /*-------------------------------------------------------------*
- * i1 loop: 8 positions. *
- *-------------------------------------------------------------*/
-
- sq = -1; move16 ();
- alp = 1; move16 ();
- ix = ipos[1]; move16 ();
-
- /*---------------------------------------------------------------*
- * 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". *
- *---------------------------------------------------------------*/
-
- move16 (); /* account for ptr. init. (rr[i1]) */
- move16 (); /* account for ptr. init. (dn[i1]) */
- move16 (); /* account for ptr. init. (rr[io]) */
- for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) {
- ps1 = add_ex(ps0, dn[i1]); /* idx increment = STEP */
-
- /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */
-
- alp1 = L_mac_ex(alp0, rr[i1][i1], _1_4); /* idx incr = STEP */
- alp1 = L_mac_ex(alp1, rr[i0][i1], _1_2); /* idx incr = STEP */
-
- sq1 = mult_ex(ps1, ps1);
-
- alp_16 = round_ex(alp1);
-
- s = L_msu_ex(L_mult_ex(alp, sq1), sq, alp_16);
-
- test ();
- if (s > 0)
- {
- sq = sq1; move16 ();
- alp = alp_16; move16 ();
- ix = i1; move16 ();
- }
- }
-
- /*---------------------------------------------------------------*
- * memorise codevector if this one is better than the last one. *
- *---------------------------------------------------------------*/
-
- s = L_msu_ex(L_mult_ex(alpk, sq), psk, alp);
-
- test ();
- if (s > 0)
- {
- psk = sq; move16 ();
- alpk = alp; move16 ();
- codvec[0] = i0; move16 ();
- codvec[1] = ix; move16 ();
- }
- }
- }
- }
- return;
- }
- /*************************************************************************
- *
- * FUNCTION: build_code()
- *
- * PURPOSE: Builds the codeword, the filtered codeword and index of the
- * codevector, based on the signs and positions of 2 pulses.
- *
- *************************************************************************/
- static Word16 build_code(
- Word16 codvec[], /* i : position of pulses */
- Word16 dn_sign[], /* i : sign of pulses */
- Word16 cod[], /* o : innovative code vector */
- Word16 h[], /* i : impulse response of weighted synthesis filter */
- Word16 y[], /* o : filtered innovative code */
- Word16 sign[] /* o : sign of 2 pulses */
- )
- {
- Word16 i, j, k, track, index, _sign[NB_PULSE], indx, rsign;
- Word16 *p0, *p1;
- Word32 s;
- for (i = 0; i < L_CODE; i++)
- {
- cod[i] = 0; move16 ();
- }
- indx = 0; move16 ();
- rsign = 0; move16 ();
- for (k = 0; k < NB_PULSE; k++)
- {
- i = codvec[k]; /* read pulse position */ move16 ();
- j = dn_sign[i]; /* read sign */ move16 ();
- index = mult_ex(i, 6554); /* index = pos/5 */
- /* track = pos%5 */
- track = sub_ex(i, extract_l_ex(L_shr_ex(L_mult_ex(index, 5), 1)));
-
- test (); test (); test (); test ();
- if (sub_ex(track, 0) == 0)
- {
- track = 1; move16 ();
- index = shl_ex(index, 6);
- }
- else if (sub_ex(track, 1) == 0)
- {
- test ();
- if (sub_ex(k, 0) == 0)
- {
- track = 0; move16 ();
- index = shl_ex(index, 1);
- }
- else
- {
- track = 1; move16 ();
- index = add_ex(shl_ex(index, 6), 16);
- }
- }
- else if (sub_ex(track, 2) == 0)
- {
- track = 1; move16 ();
- index = add_ex(shl_ex(index, 6), 32);
- }
- else if (sub_ex(track, 3) == 0)
- {
- track = 0; move16 ();
- index = add_ex(shl_ex(index, 1), 1);
- }
- else if (sub_ex(track, 4) == 0)
- {
- track = 1; move16 ();
- index = add_ex(shl_ex(index, 6), 48);
- }
- test ();
- if (j > 0)
- {
- cod[i] = 8191; move16 ();
- _sign[k] = 32767; move16 ();
- rsign = add_ex(rsign, shl_ex(1, track));
- }
- else
- {
- cod[i] = -8192; move16 ();
- _sign[k] = (Word16) - 32768L; move16 ();
- }
-
- indx = add_ex(indx, index);
- }
- *sign = rsign; move16 ();
-
- p0 = h - codvec[0]; move16 ();
- p1 = h - codvec[1]; move16 ();
- for (i = 0; i < L_CODE; i++)
- {
- s = 0; move32 ();
- s = L_mac_ex(s, *p0++, _sign[0]);
- s = L_mac_ex(s, *p1++, _sign[1]);
- y[i] = round_ex(s); move16 ();
- }
- return indx;
- }
|