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

📄 acelp_e.c

📁 E729国际标准的语音编码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Version 1.1    Last modified: February 1998 */

/* ----------------------------------------------------------------- */
/*   New ACELP dictionnaries for higher bit rate extension of G729   */
/*                      Bit rate : 11.8 kb/s                         */
/*                                                                   */
/*   (C) Copyright 1997 : France Telecom / Universite de Sherbrooke  */
/*   All rights reserved.                                            */
/*                                                                   */
/* ----------------------------------------------------------------- */
#include <stdio.h>
#include <stdlib.h>

#include "typedef.h"
#include "basic_op.h"
#include "ld8k.h"
#include "ld8e.h"
#include "tab_ld8e.h"

/* locals functions */
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[]            */
);

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) */
);

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 */
);

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              */
);

static void cor_h_e(
  Word16 H[],              /* (i) Q12 :Impulse response of filters */
  Word16 sign[],           /* (i) Q15: sign vector                 */
  Word16 inv_sign[],       /* (i) Q15: inverse of sign[]           */
  Word16 h[],              /* (o)     : scaled h[]                 */
  Word16 h_inv[],          /* (o)     : inverse of scaled h[]      */
  Word16 rrixix[][NB_POS], /* (o) energy of h[].                   */
  Word16 rrixiy[][MSIZE]   /* (o) correlation between 2 pulses.    */
);

static void build_code(
  Word16 codvec[],      /* (i)    : positions of each pulse */
  Word16 sign[],        /* (i) Q15: sign vector             */
  Word16 nb_of_pulse,   /* (i)    : number of pulses        */
  Word16 H[],    /* (i) Q12: impulse response of weighted synthesis filter */
  Word16 code[], /* (o) Q12: algebraic (fixed) codebook excitation         */
  Word16 y[],    /* (o) Q11: filtered fixed codebook excitation            */
  Word16 indx[]  /* (o)    : index of pulses (5 words, 1 per track).       */
);

static Word16 pack3(Word16 index1, Word16 index2, Word16 index3);

/*-------------------------------------------------------------------*
 * Function  ACELP_12i40_44bits()                                    *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                    *
 * Algebraic codebook; 44 bits: 12 pulses in a frame of 40 samples.  *
 *-------------------------------------------------------------------*
 * The code length is 40, containing 12 nonzero pulses: i0...i11.    *
 * 12 pulses can have two (2) possible amplitudes: +1 or -1.         *
 * 10 pulses can have eight (8) possible positions:                  *
 * i2,i7  :  0, 5, 10, 15, 20, 25, 30, 35.  --> t0                   *
 * i3,i8  :  1, 6, 11, 16, 21, 26, 31, 36.  --> t1                   *
 * i4,i9  :  2, 7, 12, 17, 22, 27, 32, 37.  --> t2                   *
 * i5,i10 :  3, 8, 13, 18, 23, 28, 33, 38.  --> t3                   *
 * i6,i11 :  4, 9, 14, 19, 24, 29, 34, 39.  --> t4                   *
 *                                                                   *
 * The 2 other pulses can be on the following track:                 *
 *   t0-t1,t1-t2,t2-t3,t3-t4,t4-t0.                                  *
 *-------------------------------------------------------------------*/
void ACELP_12i40_44bits(
  Word16 x[],    /* (i) Q0 : target vector                                 */
  Word16 cn[],   /* (i) Q0 : residual after long term prediction           */
  Word16 H[],    /* (i) Q12: impulse response of weighted synthesis filter */
  Word16 code[], /* (o) Q12: algebraic (fixed) codebook excitation         */
  Word16 y[],    /* (o) Q11: filtered fixed codebook excitation            */
  Word16 indx[]  /* (o)    : index 5 words: 13,10,7,7,7 = 44 bits          */
)
{
  Word16 i, j, k, ix, iy, itrk[3], track, pos, index, idx[NB_TRACK];
  Word16 psk, ps, alpk, alp;
  Word32 s, corr[NB_TRACK];
  Word16 *p0, *p1, *h, *h_inv;

  Word16 dn[L_SUBFR], sign[L_SUBFR], vec[L_SUBFR];
  Word16 ip[12], codvec[12], pos_max[NB_TRACK];
  Word16 cor_x[NB_POS], cor_y[NB_POS];
  Word16 h_buf[4*L_SUBFR];
  Word16 rrixix[NB_TRACK][NB_POS], rrixiy[NB_TRACK][MSIZE];
  Word32 L_tmp;



    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 position for pulse i0 and i1.                              *
    *-------------------------------------------------------------------*/
    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: 3 iterations of 320 tests = 960 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.           *
    *   stage 6 : fix i10 and i11 --> try 8x8 = 64 positions.           *
    *-------------------------------------------------------------------*/

    /* stage 0: fix pulse i0 and i1 according to max of correlation */
    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<12; 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<12; i++) codvec[i] = ip[i];
        }
    } /* end of for (pos=0; pos<3; pos++) */

    /*-------------------------------------------------------------------*
    * index of 12 pulses = 44 bits on 5 words                           *
    * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                           *
    * indx[0] =13 bits --> 3(track) +                                   *
    *                      3(pos#11) + 3(pos#6) + 1(sign#1) + 3(pos#1)  *
    * indx[1] =10 bits --> 3(pos#12) + 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+2, sign, 10, H, code, y, idx);

    for (k=0; k<2; k++) {

        pos = codvec[k];
        index = mult(pos, Q15_1_5);    /* index = pos/5       */
        track = sub(pos, extract_l(L_shr(L_mult(index, 5), 1)));
        if (sign[pos] > 0) {
            code[pos] = add(code[pos], 4096);     /* 1.0 in Q12 */
            for (i=pos, j=0; i<L_SUBFR; i++, j++) y[i] = add(y[i], H[j]);
        }
        else {
            code[pos] = sub(code[pos], 4096);     /* 1.0 in Q12 */
            for (i=pos, j=0; i<L_SUBFR; i++, j++) y[i] = sub(y[i], H[j]);
            index = add(index, 8);
        }

        ix = shr(idx[track], (Word16)4) & (Word16)15;
        iy = idx[track] & (Word16)15;

        index = pack3(ix, iy, index);
        if (k == 0) index = add(shl(track, 10), index);
        indx[k] = index;

    }

    for (k=2; k<NB_TRACK; k++) {
        track = add(track, 1);
        if (track >= NB_TRACK) track = 0;
        indx[k] = (idx[track] & (Word16)127);
    }

    return;
}

/*-------------------------------------------------------------------*
 * Function  ACELP_10i40_35bits()                                    *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                    *
 * Algebraic codebook; 35 bits: 10 pulses in a frame of 40 samples.  *
 *-------------------------------------------------------------------*
 * The code length is 40, containing 10 nonzero pulses: i0...i9.     *
 * All pulses can have two (2) possible amplitudes: +1 or -1.        *
 * Each pulse can have eight (8) possible positions:                 *
 *                                                                   *
 * i0,i5 :  0, 5, 10, 15, 20, 25, 30, 35.                            *
 * i1,i6 :  1, 6, 11, 16, 21, 26, 31, 36.                            *
 * i2,i7 :  2, 7, 12, 17, 22, 27, 32, 37.                            *
 * i3,i8 :  3, 8, 13, 18, 23, 28, 33, 38.                            *
 * i4,i9 :  4, 9, 14, 19, 24, 29, 34, 39.                            *
 *-------------------------------------------------------------------*/
void ACELP_10i40_35bits(
  Word16 x[],    /* (i) Q0 : target vector                                 */
  Word16 cn[],   /* (i) Q0 : residual after long term prediction           */
  Word16 H[],    /* (i) Q12: impulse response of weighted synthesis filter */
  Word16 code[], /* (o) Q12: algebraic (fixed) codebook excitation         */
  Word16 y[],    /* (o) Q11: filtered fixed codebook excitation            */
  Word16 indx[]  /* (o)    : index 5 words: 7,7,7,7,7 = 35 bits            */
)
{
    Word16 i, j, k, ix, iy, pos, track;
    Word16 psk, ps, alpk, alp, itrk[3];
    Word32 s, corr[NB_TRACK], L_tmp;
    Word16 *p0, *p1, *h, *h_inv;

    /* these vectors are not static */
    Word16 dn[L_SUBFR], sign[L_SUBFR], vec[L_SUBFR];
    Word16 ip[10], codvec[10], pos_max[NB_TRACK];
    Word16 cor_x[NB_POS], cor_y[NB_POS];
    Word16 h_buf[4*L_SUBFR];
    Word16 rrixix[NB_TRACK][NB_POS], rrixiy[NB_TRACK][MSIZE];

⌨️ 快捷键说明

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