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

📄 c4t64fx.c

📁 通讯协议
💻 C
📖 第 1 页 / 共 3 页
字号:
/*------------------------------------------------------------------------*
 *                         C4T64FX.C									  *
 *------------------------------------------------------------------------*
 * Performs algebraic codebook search for higher modes	                  *
 *------------------------------------------------------------------------*/


/*-----------------------------------------------------------------------*
 * Function  ACELP_4t64_fx()                                             *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~                                             *
 * 20, 36, 44, 52, 64, 72, 88 bits algebraic codebook.                   *
 * 4 tracks x 16 positions per track = 64 samples.                       *
 *                                                                       *
 * 20 bits --> 4 pulses in a frame of 64 samples.                        *
 * 36 bits --> 8 pulses in a frame of 64 samples.                        *
 * 44 bits --> 10 pulses in a frame of 64 samples.                       *
 * 52 bits --> 12 pulses in a frame of 64 samples.                       *
 * 64 bits --> 16 pulses in a frame of 64 samples.                       *
 * 72 bits --> 18 pulses in a frame of 64 samples.                       *
 * 88 bits --> 24 pulses in a frame of 64 samples.                       *
 *                                                                       *
 * All pulses can have two (2) possible amplitudes: +1 or -1.            *
 * Each pulse can have sixteen (16) possible positions.                  *
 *-----------------------------------------------------------------------*/

#include "typedef.h"
#include "basic_op.h"
#include "math_op.h"
#include "acelp.h"
#include "count.h"
#include "cnst.h"

#include "q_pulse.h"

static Word16 tipos[36] = {
    0, 1, 2, 3,                            /* starting point &ipos[0], 1st iter */
    1, 2, 3, 0,                            /* starting point &ipos[4], 2nd iter */
    2, 3, 0, 1,                            /* starting point &ipos[8], 3rd iter */
    3, 0, 1, 2,                            /* starting point &ipos[12], 4th iter */
    0, 1, 2, 3,
    1, 2, 3, 0,
    2, 3, 0, 1,
    3, 0, 1, 2,
    0, 1, 2, 3};                           /* end point for 24 pulses &ipos[35], 4th iter */

#define NB_PULSE_MAX  24

#define L_SUBFR   64
#define NB_TRACK  4
#define STEP      4
#define NB_POS    16
#define MSIZE     256
#define NB_MAX    8
#define NPMAXPT   ((NB_PULSE_MAX+NB_TRACK-1)/NB_TRACK)


/* locals functions */

static void cor_h_vec(
     Word16 h[],                           /* (i) scaled impulse response                 */
     Word16 vec[],                         /* (i) scaled vector (/8) 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 nb_pos_ix,                     /* (i) nb of pos for pulse 1 (1..8)       */
     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 dn2[],                         /* (i) vector of selected positions       */
     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   */
);


void ACELP_4t64_fx(
     Word16 dn[],                          /* (i) <12b : correlation between target x[] and H[]      */
     Word16 cn[],                          /* (i) <12b : residual after long term prediction         */
     Word16 H[],                           /* (i) Q12: impulse response of weighted synthesis filter */
     Word16 code[],                        /* (o) Q9 : algebraic (fixed) codebook excitation         */
     Word16 y[],                           /* (o) Q9 : filtered fixed codebook excitation            */
     Word16 nbbits,                        /* (i) : 20, 36, 44, 52, 64, 72 or 88 bits                */
     Word16 ser_size,                      /* (i) : bit rate                                         */
     Word16 _index[]                       /* (o) : index (20): 5+5+5+5 = 20 bits.                   */
                                           /* (o) : index (36): 9+9+9+9 = 36 bits.                   */
                                           /* (o) : index (44): 13+9+13+9 = 44 bits.                 */
                                           /* (o) : index (52): 13+13+13+13 = 52 bits.               */
                                           /* (o) : index (64): 2+2+2+2+14+14+14+14 = 64 bits.       */
                                           /* (o) : index (72): 10+2+10+2+10+14+10+14 = 72 bits.     */
                                           /* (o) : index (88): 11+11+11+11+11+11+11+11 = 88 bits.   */
)
{
    Word16 i, j, k, st, ix, iy, pos, index, track, nb_pulse, nbiter;
    Word16 psk, ps, alpk, alp, val, k_cn, k_dn, exp;
    Word16 *p0, *p1, *p2, *p3, *psign;
    Word16 *h, *h_inv, *ptr_h1, *ptr_h2, *ptr_hf, h_shift;
    Word32 s, cor, L_tmp, L_index;

    Word16 dn2[L_SUBFR], sign[L_SUBFR], vec[L_SUBFR];
    Word16 ind[NPMAXPT * NB_TRACK];
    Word16 codvec[NB_PULSE_MAX], nbpos[10];
    Word16 cor_x[NB_POS], cor_y[NB_POS], pos_max[NB_TRACK];
    Word16 h_buf[4 * L_SUBFR];
    Word16 rrixix[NB_TRACK][NB_POS], rrixiy[NB_TRACK][MSIZE];
    Word16 ipos[NB_PULSE_MAX];

    switch (nbbits)
    {
    case 20:                               /* 20 bits, 4 pulses, 4 tracks */
        nbiter = 4;                        move16();  /* 4x16x16=1024 loop */
        alp = 8192;                        move16();  /* alp = 2.0 (Q12) */
        nb_pulse = 4;                      move16();
        nbpos[0] = 4;                      move16();
        nbpos[1] = 8;                      move16();
        break;
    case 36:                               /* 36 bits, 8 pulses, 4 tracks */
        nbiter = 4;                        move16();  /* 4x20x16=1280 loop */
        alp = 4096;                        move16();  /* alp = 1.0 (Q12) */
        nb_pulse = 8;                      move16();
        nbpos[0] = 4;                      move16();
        nbpos[1] = 8;                      move16();
        nbpos[2] = 8;                      move16();
        break;
    case 44:                               /* 44 bits, 10 pulses, 4 tracks */
        nbiter = 4;                        move16();  /* 4x26x16=1664 loop */
        alp = 4096;                        move16();  /* alp = 1.0 (Q12) */
        nb_pulse = 10;                     move16();
        nbpos[0] = 4;                      move16();
        nbpos[1] = 6;                      move16();
        nbpos[2] = 8;                      move16();
        nbpos[3] = 8;                      move16();
        break;
    case 52:                               /* 52 bits, 12 pulses, 4 tracks */
        nbiter = 4;                        move16();  /* 4x26x16=1664 loop */
        alp = 4096;                        move16();  /* alp = 1.0 (Q12) */
        nb_pulse = 12;                     move16();
        nbpos[0] = 4;                      move16();
        nbpos[1] = 6;                      move16();
        nbpos[2] = 8;                      move16();
        nbpos[3] = 8;                      move16();
        break;
    case 64:                               /* 64 bits, 16 pulses, 4 tracks */
        nbiter = 3;                        move16();  /* 3x36x16=1728 loop */
        alp = 3277;                        move16();  /* alp = 0.8 (Q12) */
        nb_pulse = 16;                     move16();
        nbpos[0] = 4;                      move16();
        nbpos[1] = 4;                      move16();
        nbpos[2] = 6;                      move16();
        nbpos[3] = 6;                      move16();
        nbpos[4] = 8;                      move16();
        nbpos[5] = 8;                      move16();
        break;
    case 72:                               /* 72 bits, 18 pulses, 4 tracks */
        nbiter = 3;                        move16();  /* 3x35x16=1680 loop */
        alp = 3072;                        move16();  /* alp = 0.75 (Q12) */
        nb_pulse = 18;                     move16();
        nbpos[0] = 2;                      move16();
        nbpos[1] = 3;                      move16();
        nbpos[2] = 4;                      move16();
        nbpos[3] = 5;                      move16();
        nbpos[4] = 6;                      move16();
        nbpos[5] = 7;                      move16();
        nbpos[6] = 8;                      move16();
        break;
    case 88:                               /* 88 bits, 24 pulses, 4 tracks */
        test();move16();
        if (sub(ser_size, 462) > 0)
            nbiter = 1;
        else
            nbiter = 2;                    /* 2x53x16=1696 loop */

        alp = 2048;                        move16();  /* alp = 0.5 (Q12) */
        nb_pulse = 24;                     move16();
        nbpos[0] = 2;                      move16();
        nbpos[1] = 2;                      move16();
        nbpos[2] = 3;                      move16();
        nbpos[3] = 4;                      move16();
        nbpos[4] = 5;                      move16();
        nbpos[5] = 6;                      move16();
        nbpos[6] = 7;                      move16();
        nbpos[7] = 8;                      move16();
        nbpos[8] = 8;                      move16();
        nbpos[9] = 8;                      move16();
        break;
    default:
        nbiter = 0;
        alp = 0;
        nb_pulse = 0;
    }

    for (i = 0; i < nb_pulse; i++)
    {
        codvec[i] = i;                     move16();
    }

    /*----------------------------------------------------------------*
     * Find sign for each pulse position.                             *
     *----------------------------------------------------------------*/

    /* calculate energy for normalization of cn[] and dn[] */

    /* set k_cn = 32..32767 (ener_cn = 2^30..256-0) */
    s = Dot_product12(cn, cn, L_SUBFR, &exp);
    Isqrt_n(&s, &exp);
    s = L_shl(s, add(exp, 5));             /* saturation can occur here */
    k_cn = round(s);

    /* set k_dn = 32..512 (ener_dn = 2^30..2^22) */
    s = Dot_product12(dn, dn, L_SUBFR, &exp);
    Isqrt_n(&s, &exp);
    k_dn = round(L_shl(s, add(exp, 5 + 3)));    /* k_dn = 256..4096 */
    k_dn = mult_r(alp, k_dn);              /* alp in Q12 */

    /* mix normalized cn[] and dn[] */
    for (i = 0; i < L_SUBFR; i++)
    {
        s = L_mac(L_mult(k_cn, cn[i]), k_dn, dn[i]);
        dn2[i] = extract_h(L_shl(s, 8));   move16();
    }

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

    for (k = 0; k < NB_TRACK; k++)
    {
        for (i = k; i < L_SUBFR; i += STEP)
        {
            val = dn[i];                   move16();
            ps = dn2[i];                   move16();

            test();
            if (ps >= 0)
            {
                sign[i] = 32767;           move16();  /* sign = +1 (Q12) */
                vec[i] = -32768;           move16();
            } else
            {
                sign[i] = -32768;          move16();  /* sign = -1 (Q12) */
                vec[i] = 32767;            move16();
                val = negate(val);
                ps = negate(ps);
            }
            dn[i] = val;                   move16();  /* modify dn[] according to the fixed sign */
            dn2[i] = ps;                   move16();  /* dn2[] = mix of dn[] and cn[]            */
        }
    }

    /*----------------------------------------------------------------*
     * Select NB_MAX position per track according to max of dn2[].    *
     *----------------------------------------------------------------*/

    pos = 0;
    for (i = 0; i < NB_TRACK; i++)
    {
        for (k = 0; k < NB_MAX; k++)
        {
            ps = -1;                       move16();
            for (j = i; j < L_SUBFR; j += STEP)
            {
                test();
                if (sub(dn2[j], ps) > 0)
                {
                    ps = dn2[j];           move16();
                    pos = j;               move16();
                }
            }
            move16();
            dn2[pos] = sub(k, NB_MAX);     /* dn2 < 0 when position is selected */
            test();
            if (k == 0)
            {
                pos_max[i] = pos;          move16();
            }
        }
    }

    /*--------------------------------------------------------------*
     * Scale h[] to avoid overflow and to get maximum of precision  *
     * on correlation.                                              *
     *                                                              *
     * Maximum of h[] (h[0]) is fixed to 2048 (MAX16 / 16).         *
     *  ==> This allow addition of 16 pulses without saturation.    *
     *                                                              *
     * Energy worst case (on resonant impulse response),            *
     * - energy of h[] is approximately MAX/16.                     *
     * - During search, the energy is divided by 8 to avoid         *
     *   overflow on "alp". (energy of h[] = MAX/128).              *
     *  ==> "alp" worst case detected is 22854 on sinusoidal wave.  *
     *--------------------------------------------------------------*/

    /* impulse response buffer for fast computation */

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

⌨️ 快捷键说明

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