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

📄 acelp_e.c

📁 E729国际标准的语音编码
💻 C
📖 第 1 页 / 共 3 页
字号:

    h = h_buf;
    h_inv = h_buf + (2*L_SUBFR);
    for (i=0; i<L_SUBFR; i++) {
        *h++ = 0;
        *h_inv++ = 0;
    }

    /* Compute correlation between target x[] and H[] */
    cor_h_x_e(H, x, dn);

    /* find the sign of each pulse position */
    set_sign(32767, cn, dn, sign, vec, pos_max, corr);

    /* Compute correlations of h[] needed for the codebook search. */
    cor_h_e(H, sign, vec, h, h_inv, rrixix, rrixiy);

    /*-------------------------------------------------------------------*
    * Search starting position for pulse i0 and i1.                     *
    *    In the deep first search, we start 4 times with different      *
    * position for i0 and i1.  At all, we have 5 possible positions to  *
    * start (position 0 to 5).  The following loop remove 1 position    *
    * to keep 4 positions for deep first search step.                   *
    *-------------------------------------------------------------------*/
    s = L_add(corr[4], corr[0]);
    for (k=0; k<NB_TRACK-1; k++) corr[k] = L_add(corr[k], corr[k+1]);
    corr[4] = s;

    for (k=0; k<3; k++) {
        s = corr[0];
        track = 0;
        for (i=1; i<NB_TRACK; i++) {
            L_tmp = L_sub(corr[i], s);
            if (L_tmp > 0) {
                s = corr[i];
                track = i;
            }
        }
        corr[track] = -1;
        itrk[k] = track;
    }

    /*-------------------------------------------------------------------*
    * Deep first search: 4 iterations of 256 tests = 1024 tests.        *
    *                                                                   *
    * Stages of deep first search:                                      *
    *     stage 1 : fix i0 and i1 --> 2 positions is fixed previously.  *
    *     stage 2 : fix i2 and i3 --> try 8x8 = 64 positions.           *
    *     stage 3 : fix i4 and i5 --> try 8x8 = 64 positions.           *
    *     stage 4 : fix i6 and i7 --> try 8x8 = 64 positions.           *
    *     stage 5 : fix i8 and i9 --> try 8x8 = 64 positions.           *
    *-------------------------------------------------------------------*/
    psk = -1;
    alpk = 1;
    for (pos=0; pos<3; pos++) {
        k = itrk[pos];       /* starting position index */

    /* stage 1: fix pulse i0 and i1 according to max of correlation */
        ix = pos_max[ipos[k]];
        iy = pos_max[ipos[k+1]];
        ps = add(dn[ix], dn[iy]);
        i = mult(ix, Q15_1_5);
        j = mult(iy, Q15_1_5);
        alp = add(rrixix[ipos[k]][i], rrixix[ipos[k+1]][j]);
        i = add(shl(i,3), j);
        alp = add(alp, rrixiy[ipos[k]][i]);
        ip[0] = ix;
        ip[1] = iy;

        for (i=0; i<L_SUBFR; i++) vec[i] = 0;

        /* stage 2..5: fix pulse i2,i3,i4,i5,i6,i7,i8 and i9 */
        for (j=2; j<10; j+=2) {

            /*--------------------------------------------------*
            * Store all impulse response of all fixed pulses   *
            * in vector vec[] for the "cor_h_vec()" function.  *
            *--------------------------------------------------*/
            if (sign[ix] < 0) p0 = h_inv - ix;
            else p0 = h - ix;

            if (sign[iy] < 0) p1 = h_inv - iy;
            else p1 = h - iy;

            for (i=0; i<L_SUBFR; i++) {
                vec[i] = add(vec[i], add(*p0, *p1));
                p0++; p1++;
            }

            /*--------------------------------------------------*
            * Calculate correlation of all possible positions  *
            * of the next 2 pulses with previous fixed pulses. *
            * Each pulse can have 8 possible positions         *
            *--------------------------------------------------*/
            cor_h_vec(h, vec, ipos[k+j], sign, rrixix, cor_x);
            cor_h_vec(h, vec, ipos[k+j+1], sign, rrixix, cor_y);

            /*--------------------------------------------------*
            * Fix 2 pulses, try 8x8 = 64 positions.            *
            *--------------------------------------------------*/
            search_ixiy(ipos[k+j], ipos[k+j+1], &ps, &alp, &ix, &iy,
                  dn, cor_x, cor_y, rrixiy);
            ip[j] = ix;
            ip[j+1] = iy;
        }

        /* memorise new codevector if it's better than the last one. */
        ps = mult(ps,ps);
        s = L_msu(L_mult(alpk,ps),psk,alp);

        if (s > 0) {
            psk = ps;
            alpk = alp;
            for (i=0; i<10; i++) codvec[i] = ip[i];
        }

    } /* end of for (pos=0; pos<3; pos++) */

    /*-------------------------------------------------------------------*
    * index of 10 pulses = 35 bits on 5 words                           *
    * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                           *
    * indx[0] = 7 bits --> 3(pos#6) + 1(sign#1) + 3(pos#1)              *
    * indx[1] = 7 bits --> 3(pos#7) + 1(sign#2) + 3(pos#2)              *
    * indx[2] = 7 bits --> 3(pos#8) + 1(sign#3) + 3(pos#3)              *
    * indx[3] = 7 bits --> 3(pos#9) + 1(sign#4) + 3(pos#4)              *
    * indx[4] = 7 bits --> 3(pos#10)+ 1(sign#5) + 3(pos#5)              *
    *-------------------------------------------------------------------*/
    build_code(codvec, sign, 10, H, code, y, indx);

    for (i=0; i<NB_TRACK; i++) indx[i] = indx[i] & (Word16)127;

    return;

}

/*-------------------------------------------------------------------*
 * Function  cor_h_x_e()                                               *
 * ~~~~~~~~~~~~~~~~~~~                                               *
 * Compute correlation between target "x[]" and "h[]".               *
 *-------------------------------------------------------------------*/

static void cor_h_x_e(
  Word16 h[],    /* (i) Q12 : impulse response of weighted synthesis filter */
  Word16 x[],    /* (i) Q0  : correlation between target and h[]            */
  Word16 dn[]    /* (o) Q0  : correlation between target and h[]            */
)
{
    Word16 i, j, k;
    Word32 s, y32[L_SUBFR], max, tot, L_tmp;

    /* first keep the result on 32 bits and find absolute maximum */
    tot = 5;
    for (k=0; k<NB_TRACK; k++) {
        max = 0;

        for (i=k; i<L_SUBFR; i+=STEP) {
            s = 0;
            for (j=i; j<L_SUBFR; j++) s = L_mac(s, x[j], h[j-i]);
            y32[i] = s;
            s = L_abs(s);
            L_tmp = L_sub(s, max);
            if (L_tmp > (Word32)0) max = s;
        }
        tot = L_add(tot, L_shr(max, 1));    /* tot += (2.0 x max) / 4.0 */
    }

    /* Find the number of right shifts to do on y32[] so that */
    /* 2.0 x sumation of all max of dn[] in each track not saturate. */
    j = sub(norm_l(tot), 2);     /* multiply tot by 4 */
    for (i=0; i<L_SUBFR; i++) {
        dn[i] = round(L_shl(y32[i], j));
    }
    return;
}

/*-------------------------------------------------------------------*
 * Function  cor_h_vec()                                             *
 * ~~~~~~~~~~~~~~~~~~~~~                                             *
 * Compute correlations of h[] with vec[] for the specified track.   *
 *-------------------------------------------------------------------*
 *-------------------------------------------------------------------*/
static void cor_h_vec(
  Word16 h[],           /* (i) scaled impulse response */
  Word16 vec[],         /* (i) vector to correlate with h[] */
  Word16 track,         /* (i) track to use */
  Word16 sign[],        /* (i) sign vector */
  Word16 rrixix[][NB_POS],  /* (i) correlation of h[x] with h[x] */
  Word16 cor[]          /* (o) result of correlation (NB_POS elements) */
)
{
    Word16 i, j, pos;
    Word16 *p0, *p1, *p2;
    Word32 s;

    p0 = rrixix[track];
    pos = track;
    for (i=0; i<NB_POS; i++, pos+=STEP) {
        s = 0;
        p1 = h;
        p2 = &vec[pos];
        for (j=pos; j<L_SUBFR; j++) {
            s = L_mac(s, *p1, *p2);
            p1++; p2++;
        }
        cor[i] = add(mult(round(s), sign[pos]), *p0++);
    }

    return;
}

/*-------------------------------------------------------------------*
* Function  search_ixiy()                                           *
* ~~~~~~~~~~~~~~~~~~~~~~~                                           *
* Find the best positions of 2 pulses in a subframe.                *
*-------------------------------------------------------------------*/
static void search_ixiy(
  Word16 track_x,       /* (i) track of pulse 1 */
  Word16 track_y,       /* (i) track of pulse 2 */
  Word16 *ps,           /* (i/o) correlation of all fixed pulses */
  Word16 *alp,          /* (i/o) energy of all fixed pulses */
  Word16 *ix,           /* (o) position of pulse 1 */
  Word16 *iy,           /* (o) position of pulse 2 */
  Word16 dn[],          /* (i) corr. between target and h[] */
  Word16 cor_x[],       /* (i) corr. of pulse 1 with fixed pulses */
  Word16 cor_y[],       /* (i) corr. of pulse 2 with fixed pulses */
  Word16 rrixiy[][MSIZE]  /* (i) corr. of pulse 1 with pulse 2 */
)
{
    Word16 x, y, pos;
    Word16 ps1, ps2, sq, sqk;
    Word16 alp1, alp2, alpk;
    Word16 *p0, *p1, *p2;
    Word32 s;

    p0 = cor_x;
    p1 = cor_y;
    p2 = rrixiy[track_x];
    sqk = -1;
    alpk = 1;
    for (x=track_x; x<L_SUBFR; x+=STEP) {
        ps1 = add(*ps, dn[x]);
        alp1 = add(*alp, *p0++);
        pos = -1;
        for (y=track_y; y<L_SUBFR; y+=STEP) {
            ps2 = add(ps1, dn[y]);
            alp2 = add(alp1, add(*p1++, *p2++));
            sq = mult(ps2, ps2);
            s = L_msu(L_mult(alpk,sq),sqk,alp2);
            if (s > 0) {
                sqk = sq;
                alpk = alp2;
                pos = y;
            }
        }
        p1 -= NB_POS;
        if (pos >= 0) {
            *ix = x;
            *iy = pos;
        }
    }
    *ps = add(*ps, add(dn[*ix], dn[*iy]));
    *alp = alpk;

    return;
}

/*-------------------------------------------------------------------*
* Function  set_sign()                                              *
* ~~~~~~~~~~~~~~~~~~~~                                              *
* Set the sign of each pulse position.                              *
*-------------------------------------------------------------------*/
static void set_sign(
  Word16 fac_cn,     /* (i) Q15: residual weight for sign determination */
  Word16 cn[],       /* (i) Q0 : residual after long term prediction    */
  Word16 dn[],       /* (i) Q0 : correlation between target and h[]     */
  Word16 sign[],     /* (o) Q15: sign vector (sign of each position)    */
  Word16 inv_sign[], /* (o) Q15: inverse of sign[]                      */
  Word16 pos_max[],  /* (o)    : pos of max of correlation              */
  Word32 corr[]      /* (o)    : correlation of each track              */
)
{
    Word16 i, k, pos, k_cn, k_dn, val;
    Word32 s, max;

    /* calculate energy for normalization of cn[] and dn[] */
    s = 0;
    for (i=0; i<L_SUBFR; i++) s = L_mac(s, cn[i], cn[i]);
    if (s < 512) s = 512;
    s = Inv_sqrt(s);
    k_cn = extract_h(L_shl(s, 5));     /* k_cn = 11..23170 */
    k_cn = mult(k_cn, fac_cn);

    s = 0;
    for (i=0; i<L_SUBFR; i++) s = L_mac(s, dn[i], dn[i]);
    if (s < 512) s = 512;
    s = Inv_sqrt(s);
    k_dn = extract_h(L_shl(s, 5));     /* k_dn = 11..23170 */

    /* set sign according to en[] = k_cn*cn[] + k_dn*dn[]    */

    /* find position of maximum of correlation in each track */
    for (k=0; k<NB_TRACK; k++) {
        max = -1;
        for (i=k; i<L_SUBFR; i+=STEP) {
            val = dn[i];
            s = L_mac(L_mult(k_cn, cn[i]), k_dn, val);
            if (s >= 0) {
                sign[i] = 32767L;         /* sign = +1 (Q15) */
                inv_sign[i] = -32768L;
            }
            else {
                sign[i] = -32768L;        /* sign = -1 (Q15) */
                inv_sign[i] = 32767L;
                val = negate(val);
            }

⌨️ 快捷键说明

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