static inline spx_word32_t cheb_poly_eva(
  spx_word16_t *coef, /* P or Q coefs in Q13 format               */
  spx_word16_t     x, /* cos of freq (-1.0 to 1.0) in Q14 format  */
  int              m, /* LPC order/2                              */
  char         *stack
)
{
    int i;
    spx_word16_t b0, b1;
    spx_word32_t sum;

    /*Prevents overflows*/
    if (x>16383)
       x = 16383;
    if (x<-16383)
       x = -16383;

    /* Initialise values */
    b1=16384;
    b0=x;

    /* Evaluate Chebyshev series formulation usin g iterative approach  */
    sum = ADD32(EXTEND32(coef[m]), EXTEND32(MULT16_16_P14(coef[m-1],x)));
    for(i=2;i<=m;i++)
    {
       spx_word16_t tmp=b0;
       b0 = SUB16(MULT16_16_Q13(x,b0), b1);
       b1 = tmp;
       sum = ADD32(sum, EXTEND32(MULT16_16_P14(coef[m-i],b0)));
    }

    return sum;
}
Пример #2
0
void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *_stereo)
{
   int i;
   spx_word32_t balance;
   spx_word16_t e_left, e_right, e_ratio;
   RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo;

   /* COMPATIBILITY_HACK(stereo); */
   
   balance=stereo->balance;
   e_ratio=stereo->e_ratio;
   
   /* These two are Q14, with max value just below 2. */
   e_right = DIV32(QCONST32(1., 22), spx_sqrt(MULT16_32_Q15(e_ratio, ADD32(QCONST32(1., 16), balance))));
   e_left = SHR32(MULT16_16(spx_sqrt(balance), e_right), 8);

   for (i=frame_size-1;i>=0;i--)
   {
      spx_int16_t tmp=data[i];
      stereo->smooth_left = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_left, QCONST16(0.98, 15)), e_left, QCONST16(0.02, 15)), 15));
      stereo->smooth_right = EXTRACT16(PSHR32(MAC16_16(MULT16_16(stereo->smooth_right, QCONST16(0.98, 15)), e_right, QCONST16(0.02, 15)), 15));
      data[2*i] = (spx_int16_t)MULT16_16_P14(stereo->smooth_left, tmp);
      data[2*i+1] = (spx_int16_t)MULT16_16_P14(stereo->smooth_right, tmp);
   }
}
Пример #3
0
void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes)
{
   int i;
   spx_word16_t tmp = DIV32_16(SHL(1 + subframe,14),nb_subframes);
   spx_word16_t tmp2 = 16384-tmp;
   for (i=0;i<len;i++)
   {
      interp_lsp[i] = MULT16_16_P14(tmp2,old_lsp[i]) + MULT16_16_P14(tmp,new_lsp[i]);
   }
}
Пример #4
0
static inline spx_word32_t cheb_poly_eva(spx_word32_t *coef,spx_word16_t x,int m,char *stack)
/*  float coef[]  	coefficients of the polynomial to be evaluated 	*/
/*  float x   		the point where polynomial is to be evaluated 	*/
/*  int m 		order of the polynomial 			*/
{
    int i;
    spx_word16_t *T;
    spx_word32_t sum;
    int m2=m>>1;
    spx_word16_t *coefn;

    /*Prevents overflows*/
    if (x>16383)
       x = 16383;
    if (x<-16383)
       x = -16383;

    /* Allocate memory for Chebyshev series formulation */
    T=PUSH(stack, m2+1, spx_word16_t);
    coefn=PUSH(stack, m2+1, spx_word16_t);

    for (i=0;i<m2+1;i++)
    {
       coefn[i] = coef[i];
       /*printf ("%f ", coef[i]);*/
    }
    /*printf ("\n");*/

    /* Initialise values */
    T[0]=16384;
    T[1]=x;

    /* Evaluate Chebyshev series formulation using iterative approach  */
    /* Evaluate polynomial and return value also free memory space */
    sum = ADD32(coefn[m2], MULT16_16_P14(coefn[m2-1],x));
    /*x *= 2;*/
    for(i=2;i<=m2;i++)
    {
       T[i] = MULT16_16_Q13(x,T[i-1]) - T[i-2];
       sum = ADD32(sum, MULT16_16_P14(coefn[m2-i],T[i]));
       /*printf ("%f ", sum);*/
    }
    
    /*printf ("\n");*/
    return sum;
}
Пример #5
0
void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *lsp, int len, int subframe, int nb_subframes, spx_word16_t margin)
{
   int i;
   spx_word16_t m = margin;
   spx_word16_t m2 = 25736-margin;
   spx_word16_t tmp = DIV32_16(SHL32(EXTEND32(1 + subframe),14),nb_subframes);
   spx_word16_t tmp2 = 16384-tmp;
   for (i=0;i<len;i++)
      lsp[i] = MULT16_16_P14(tmp2,old_lsp[i]) + MULT16_16_P14(tmp,new_lsp[i]);
   /* Enforce margin to sure the LSPs are stable*/
   if (lsp[0]<m)
      lsp[0]=m;
   if (lsp[len-1]>m2)
      lsp[len-1]=m2;
   for (i=1;i<len-1;i++)
   {
      if (lsp[i]<lsp[i-1]+m)
         lsp[i]=lsp[i-1]+m;

      if (lsp[i]>lsp[i+1]-m)
         lsp[i]= SHR16(lsp[i],1) + SHR16(lsp[i+1]-m,1);
   }
}
void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes)
{
#ifndef FIXED_LPC_SIZE
   int i;
#endif

   spx_word16_t tmp = DIV32_16(SHL32(EXTEND32(1 + subframe),14),nb_subframes);
   spx_word16_t tmp2 = 16384-tmp;

#ifndef FIXED_LPC_SIZE
   for (i=0;i<len;i++)
   {
      interp_lsp[i] = MULT16_16_P14(tmp2,old_lsp[i]) + MULT16_16_P14(tmp,new_lsp[i]);
   }
#else
   interp_lsp[0] = MULT16_16_P14(tmp2,old_lsp[0]) + MULT16_16_P14(tmp,new_lsp[0]);
   interp_lsp[1] = MULT16_16_P14(tmp2,old_lsp[1]) + MULT16_16_P14(tmp,new_lsp[1]);
   interp_lsp[2] = MULT16_16_P14(tmp2,old_lsp[2]) + MULT16_16_P14(tmp,new_lsp[2]);
   interp_lsp[3] = MULT16_16_P14(tmp2,old_lsp[3]) + MULT16_16_P14(tmp,new_lsp[3]);
   interp_lsp[4] = MULT16_16_P14(tmp2,old_lsp[4]) + MULT16_16_P14(tmp,new_lsp[4]);
   interp_lsp[5] = MULT16_16_P14(tmp2,old_lsp[5]) + MULT16_16_P14(tmp,new_lsp[5]);
   interp_lsp[6] = MULT16_16_P14(tmp2,old_lsp[6]) + MULT16_16_P14(tmp,new_lsp[6]);
   interp_lsp[7] = MULT16_16_P14(tmp2,old_lsp[7]) + MULT16_16_P14(tmp,new_lsp[7]);
   interp_lsp[8] = MULT16_16_P14(tmp2,old_lsp[8]) + MULT16_16_P14(tmp,new_lsp[8]);
   interp_lsp[9] = MULT16_16_P14(tmp2,old_lsp[9]) + MULT16_16_P14(tmp,new_lsp[9]);
#endif
}
Пример #7
0
/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
static spx_word32_t pitch_gain_search_3tap(
    const spx_word16_t target[],       /* Target vector */
    const spx_coef_t ak[],          /* LPCs for this subframe */
    const spx_coef_t awk1[],        /* Weighted LPCs #1 for this subframe */
    const spx_coef_t awk2[],        /* Weighted LPCs #2 for this subframe */
    spx_sig_t exc[],                /* Excitation */
    const signed char* gain_cdbk,
    int gain_cdbk_size,
    int   pitch,                    /* Pitch value */
    int   p,                        /* Number of LPC coeffs */
    int   nsf,                      /* Number of samples in subframe */
    SpeexBits* bits,
    char* stack,
    const spx_word16_t* exc2,
    const spx_word16_t* r,
    spx_word16_t* new_target,
    int*  cdbk_index,
    int plc_tuning,
    spx_word32_t cumul_gain,
    int scaledown
) {
    int i, j;
    VARDECL(spx_word16_t * tmp1);
    VARDECL(spx_word16_t * e);
    spx_word16_t* x[3];
    spx_word32_t corr[3];
    spx_word32_t A[3][3];
    spx_word16_t gain[3];
    spx_word32_t err;
    spx_word16_t max_gain = 128;
    int          best_cdbk = 0;

    ALLOC(tmp1, 3 * nsf, spx_word16_t);
    ALLOC(e, nsf, spx_word16_t);

    if (cumul_gain > 262144)
        max_gain = 31;

    x[0] = tmp1;
    x[1] = tmp1 + nsf;
    x[2] = tmp1 + 2 * nsf;

    for (j = 0; j < nsf; j++)
        new_target[j] = target[j];

    {
        VARDECL(spx_mem_t * mm);
        int pp = pitch - 1;
        ALLOC(mm, p, spx_mem_t);
        for (j = 0; j < nsf; j++) {
            if (j - pp < 0)
                e[j] = exc2[j - pp];
            else if (j - pp - pitch < 0)
                e[j] = exc2[j - pp - pitch];
            else
                e[j] = 0;
        }
#ifdef FIXED_POINT
        /* Scale target and excitation down if needed (avoiding overflow) */
        if (scaledown) {
            for (j = 0; j < nsf; j++)
                e[j] = SHR16(e[j], 1);
            for (j = 0; j < nsf; j++)
                new_target[j] = SHR16(new_target[j], 1);
        }
#endif
        for (j = 0; j < p; j++)
            mm[j] = 0;
        iir_mem16(e, ak, e, nsf, p, mm, stack);
        for (j = 0; j < p; j++)
            mm[j] = 0;
        filter_mem16(e, awk1, awk2, e, nsf, p, mm, stack);
        for (j = 0; j < nsf; j++)
            x[2][j] = e[j];
    }
    for (i = 1; i >= 0; i--) {
        spx_word16_t e0 = exc2[-pitch - 1 + i];
#ifdef FIXED_POINT
        /* Scale excitation down if needed (avoiding overflow) */
        if (scaledown)
            e0 = SHR16(e0, 1);
#endif
        x[i][0] = MULT16_16_Q14(r[0], e0);
        for (j = 0; j < nsf - 1; j++)
            x[i][j + 1] = ADD32(x[i + 1][j], MULT16_16_P14(r[j + 1], e0));
    }

    for (i = 0; i < 3; i++)
        corr[i] = inner_prod(x[i], new_target, nsf);
    for (i = 0; i < 3; i++)
        for (j = 0; j <= i; j++)
            A[i][j] = A[j][i] = inner_prod(x[i], x[j], nsf);

    {
        spx_word32_t C[9];
#ifdef FIXED_POINT
        spx_word16_t C16[9];
#else
        spx_word16_t* C16 = C;
#endif
        C[0] = corr[2];
        C[1] = corr[1];
        C[2] = corr[0];
        C[3] = A[1][2];
        C[4] = A[0][1];
        C[5] = A[0][2];
        C[6] = A[2][2];
        C[7] = A[1][1];
        C[8] = A[0][0];

        /*plc_tuning *= 2;*/
        if (plc_tuning < 2)
            plc_tuning = 2;
        if (plc_tuning > 30)
            plc_tuning = 30;
#ifdef FIXED_POINT
        C[0] = SHL32(C[0], 1);
        C[1] = SHL32(C[1], 1);
        C[2] = SHL32(C[2], 1);
        C[3] = SHL32(C[3], 1);
        C[4] = SHL32(C[4], 1);
        C[5] = SHL32(C[5], 1);
        C[6] = MAC16_32_Q15(C[6], MULT16_16_16(plc_tuning, 655), C[6]);
        C[7] = MAC16_32_Q15(C[7], MULT16_16_16(plc_tuning, 655), C[7]);
        C[8] = MAC16_32_Q15(C[8], MULT16_16_16(plc_tuning, 655), C[8]);
        normalize16(C, C16, 32767, 9);
#else
        C[6] *= .5 * (1 + .02 * plc_tuning);
        C[7] *= .5 * (1 + .02 * plc_tuning);
        C[8] *= .5 * (1 + .02 * plc_tuning);
#endif

        best_cdbk = pitch_gain_search_3tap_vq(gain_cdbk, gain_cdbk_size, C16, max_gain);

#ifdef FIXED_POINT
        gain[0] = ADD16(32, (spx_word16_t)gain_cdbk[best_cdbk * 4]);
        gain[1] = ADD16(32, (spx_word16_t)gain_cdbk[best_cdbk * 4 + 1]);
        gain[2] = ADD16(32, (spx_word16_t)gain_cdbk[best_cdbk * 4 + 2]);
        /*printf ("%d %d %d %d\n",gain[0],gain[1],gain[2], best_cdbk);*/
#else
        gain[0] = 0.015625 * gain_cdbk[best_cdbk * 4]  + .5;
        gain[1] = 0.015625 * gain_cdbk[best_cdbk * 4 + 1] + .5;
        gain[2] = 0.015625 * gain_cdbk[best_cdbk * 4 + 2] + .5;
#endif
        *cdbk_index = best_cdbk;
    }

    SPEEX_MEMSET(exc, 0, nsf);
    for (i = 0; i < 3; i++) {
        int j;
        int tmp1, tmp3;
        int pp = pitch + 1 - i;
        tmp1 = nsf;
        if (tmp1 > pp)
            tmp1 = pp;
        for (j = 0; j < tmp1; j++)
            exc[j] = MAC16_16(exc[j], SHL16(gain[2 - i], 7), exc2[j - pp]);
        tmp3 = nsf;
        if (tmp3 > pp + pitch)
            tmp3 = pp + pitch;
        for (j = tmp1; j < tmp3; j++)
            exc[j] = MAC16_16(exc[j], SHL16(gain[2 - i], 7), exc2[j - pp - pitch]);
    }
    for (i = 0; i < nsf; i++) {
        spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0], x[2][i]), MULT16_16(gain[1], x[1][i])),
                                 MULT16_16(gain[2], x[0][i]));
        new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp, 6)));
    }
    err = inner_prod(new_target, new_target, nsf);

    return err;
}