Exemplo n.º 1
0
Arquivo: ltp.c Projeto: Affix/fgcom
void pitch_unquant_3tap(
    spx_sig_t exc[],                    /* Excitation */
    int   start,                    /* Smallest pitch value allowed */
    int   end,                      /* Largest pitch value allowed */
    spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
    const void *par,
    int   nsf,                      /* Number of samples in subframe */
    int *pitch_val,
    spx_word16_t *gain_val,
    SpeexBits *bits,
    char *stack,
    int count_lost,
    int subframe_offset,
    spx_word16_t last_pitch_gain,
    int cdbk_offset
)
{
    int i;
    int pitch;
    int gain_index;
    spx_word16_t gain[3];
    const signed char *gain_cdbk;
    int gain_cdbk_size;
    const ltp_params *params;

    params = (const ltp_params*) par;
    gain_cdbk_size = 1<<params->gain_bits;
    gain_cdbk = params->gain_cdbk + 3*gain_cdbk_size*cdbk_offset;

    pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits);
    pitch += start;
    gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits);
    /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/
#ifdef FIXED_POINT
    gain[0] = 32+(spx_word16_t)gain_cdbk[gain_index*3];
    gain[1] = 32+(spx_word16_t)gain_cdbk[gain_index*3+1];
    gain[2] = 32+(spx_word16_t)gain_cdbk[gain_index*3+2];
#else
    gain[0] = 0.015625*gain_cdbk[gain_index*3]+.5;
    gain[1] = 0.015625*gain_cdbk[gain_index*3+1]+.5;
    gain[2] = 0.015625*gain_cdbk[gain_index*3+2]+.5;
#endif

    if (count_lost && pitch > subframe_offset)
    {
        float gain_sum;
        if (1) {
            float tmp = count_lost < 4 ? GAIN_SCALING_1*last_pitch_gain : 0.4 * GAIN_SCALING_1 * last_pitch_gain;
            if (tmp>.95)
                tmp=.95;
            gain_sum = GAIN_SCALING_1*gain_3tap_to_1tap(gain);

            if (gain_sum > tmp) {
                float fact = tmp/gain_sum;
                for (i=0; i<3; i++)
                    gain[i]*=fact;

            }

        }

    }

    *pitch_val = pitch;
    gain_val[0]=gain[0];
    gain_val[1]=gain[1];
    gain_val[2]=gain[2];

    {
        spx_sig_t *e[3];
        VARDECL(spx_sig_t *tmp2);
        ALLOC(tmp2, 3*nsf, spx_sig_t);
        e[0]=tmp2;
        e[1]=tmp2+nsf;
        e[2]=tmp2+2*nsf;

        for (i=0; i<3; i++)
        {
            int j;
            int pp=pitch+1-i;
#if 0
            for (j=0; j<nsf; j++)
            {
                if (j-pp<0)
                    e[i][j]=exc[j-pp];
                else if (j-pp-pitch<0)
                    e[i][j]=exc[j-pp-pitch];
                else
                    e[i][j]=0;
            }
#else
            {
                int tmp1, tmp3;
                tmp1=nsf;
                if (tmp1>pp)
                    tmp1=pp;
                for (j=0; j<tmp1; j++)
                    e[i][j]=exc[j-pp];
                tmp3=nsf;
                if (tmp3>pp+pitch)
                    tmp3=pp+pitch;
                for (j=tmp1; j<tmp3; j++)
                    e[i][j]=exc[j-pp-pitch];
                for (j=tmp3; j<nsf; j++)
                    e[i][j]=0;
            }
#endif
        }

#ifdef FIXED_POINT
        {
            for (i=0; i<nsf; i++)
                exc[i]=SHL32(ADD32(ADD32(MULT16_32_Q15(SHL16(gain[0],7),e[2][i]), MULT16_32_Q15(SHL16(gain[1],7),e[1][i])),
                                   MULT16_32_Q15(SHL16(gain[2],7),e[0][i])), 2);
        }
#else
        for (i=0; i<nsf; i++)
            exc[i]=VERY_SMALL+gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i];
#endif
    }
}
Exemplo n.º 2
0
void pitch_unquant_3tap(
    spx_word16_t exc[],             /* Input excitation */
    spx_word32_t exc_out[],         /* Output excitation */
    int   start,                    /* Smallest pitch value allowed */
    int   end,                      /* Largest pitch value allowed */
    spx_word16_t pitch_coef,        /* Voicing (pitch) coefficient */
    const void* par,
    int   nsf,                      /* Number of samples in subframe */
    int* pitch_val,
    spx_word16_t* gain_val,
    SpeexBits* bits,
    char* stack,
    int count_lost,
    int subframe_offset,
    spx_word16_t last_pitch_gain,
    int cdbk_offset
) {
    int i;
    int pitch;
    int gain_index;
    spx_word16_t gain[3];
    const signed char* gain_cdbk;
    int gain_cdbk_size;
    const ltp_params* params;

    params = (const ltp_params*) par;
    gain_cdbk_size = 1 << params->gain_bits;
    gain_cdbk = params->gain_cdbk + 4 * gain_cdbk_size * cdbk_offset;

    pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits);
    pitch += start;
    gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits);
    /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/
#ifdef FIXED_POINT
    gain[0] = ADD16(32, (spx_word16_t)gain_cdbk[gain_index * 4]);
    gain[1] = ADD16(32, (spx_word16_t)gain_cdbk[gain_index * 4 + 1]);
    gain[2] = ADD16(32, (spx_word16_t)gain_cdbk[gain_index * 4 + 2]);
#else
    gain[0] = 0.015625 * gain_cdbk[gain_index * 4] + .5;
    gain[1] = 0.015625 * gain_cdbk[gain_index * 4 + 1] + .5;
    gain[2] = 0.015625 * gain_cdbk[gain_index * 4 + 2] + .5;
#endif

    if (count_lost && pitch > subframe_offset) {
        spx_word16_t gain_sum;
        if (1) {
#ifdef FIXED_POINT
            spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : SHR16(last_pitch_gain, 1);
            if (tmp > 62)
                tmp = 62;
#else
            spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : 0.5 * last_pitch_gain;
            if (tmp > .95)
                tmp = .95;
#endif
            gain_sum = gain_3tap_to_1tap(gain);

            if (gain_sum > tmp) {
                spx_word16_t fact = DIV32_16(SHL32(EXTEND32(tmp), 14), gain_sum);
                for (i = 0; i < 3; i++)
                    gain[i] = MULT16_16_Q14(fact, gain[i]);
            }

        }

    }

    *pitch_val = pitch;
    gain_val[0] = gain[0];
    gain_val[1] = gain[1];
    gain_val[2] = gain[2];
    gain[0] = SHL16(gain[0], 7);
    gain[1] = SHL16(gain[1], 7);
    gain[2] = SHL16(gain[2], 7);
    SPEEX_MEMSET(exc_out, 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_out[j] = MAC16_16(exc_out[j], gain[2 - i], exc[j - pp]);
        tmp3 = nsf;
        if (tmp3 > pp + pitch)
            tmp3 = pp + pitch;
        for (j = tmp1; j < tmp3; j++)
            exc_out[j] = MAC16_16(exc_out[j], gain[2 - i], exc[j - pp - pitch]);
    }
    /*for (i=0;i<nsf;i++)
    exc[i]=PSHR32(exc32[i],13);*/
}
Exemplo n.º 3
0
void comb_filter(
spx_sig_t *exc,          /*decoded excitation*/
spx_sig_t *new_exc,      /*enhanced excitation*/
spx_coef_t *ak,           /*LPC filter coefs*/
int p,               /*LPC order*/
int nsf,             /*sub-frame size*/
int pitch,           /*pitch period*/
spx_word16_t *pitch_gain,   /*pitch gain (3-tap)*/
spx_word16_t  comb_gain,    /*gain of comb filter*/
CombFilterMem *mem
)
{
   int i;
   spx_word16_t exc_energy=0, new_exc_energy=0;
   spx_word16_t gain;
   spx_word16_t step;
   spx_word16_t fact;

   /*Compute excitation amplitude prior to enhancement*/
   exc_energy = compute_rms(exc, nsf);
   /*for (i=0;i<nsf;i++)
     exc_energy+=((float)exc[i])*exc[i];*/

   /*Some gain adjustment if pitch is too high or if unvoiced*/
#ifdef FIXED_POINT
   {
      spx_word16_t g = gain_3tap_to_1tap(pitch_gain)+gain_3tap_to_1tap(mem->last_pitch_gain);
      if (g > 166)
         comb_gain = MULT16_16_Q15(DIV32_16(SHL(165,15),g), comb_gain);
      if (g < 64)
         comb_gain = MULT16_16_Q15(SHL(g, 9), comb_gain);
   }
#else
   {
      float g=0;
      g = GAIN_SCALING_1*.5*(gain_3tap_to_1tap(pitch_gain)+gain_3tap_to_1tap(mem->last_pitch_gain));
      if (g>1.3)
         comb_gain*=1.3/g;
      if (g<.5)
         comb_gain*=2.*g;
   }
#endif
   step = DIV32(COMB_STEP, nsf);
   fact=0;

   /*Apply pitch comb-filter (filter out noise between pitch harmonics)*/
   for (i=0;i<nsf;i++)
   {
      spx_word32_t exc1, exc2;

      fact += step;
      
      exc1 = SHL(MULT16_32_Q15(SHL(pitch_gain[0],7),exc[i-pitch+1]) +
                 MULT16_32_Q15(SHL(pitch_gain[1],7),exc[i-pitch]) +
                 MULT16_32_Q15(SHL(pitch_gain[2],7),exc[i-pitch-1]) , 2);
      exc2 = SHL(MULT16_32_Q15(SHL(mem->last_pitch_gain[0],7),exc[i-mem->last_pitch+1]) +
                 MULT16_32_Q15(SHL(mem->last_pitch_gain[1],7),exc[i-mem->last_pitch]) +
                 MULT16_32_Q15(SHL(mem->last_pitch_gain[2],7),exc[i-mem->last_pitch-1]),2);

      new_exc[i] = exc[i] + MULT16_32_Q15(comb_gain,MULT16_32_Q15(fact,exc1)  + MULT16_32_Q15(SUB16(COMB_STEP,fact), exc2));
   }

   mem->last_pitch_gain[0] = pitch_gain[0];
   mem->last_pitch_gain[1] = pitch_gain[1];
   mem->last_pitch_gain[2] = pitch_gain[2];
   mem->last_pitch = pitch;

   /*Amplitude after enhancement*/
   new_exc_energy = compute_rms(new_exc, nsf);

   if (exc_energy > new_exc_energy)
      exc_energy = new_exc_energy;
   
   gain = DIV32_16(SHL(exc_energy,15),1+new_exc_energy);

#ifdef FIXED_POINT
   if (gain < 16384)
      gain = 16384;
#else
   if (gain < .5)
      gain=.5;
#endif

#ifdef FIXED_POINT
   for (i=0;i<nsf;i++)
   {
      mem->smooth_gain = MULT16_16_Q15(31457,mem->smooth_gain) + MULT16_16_Q15(1311,gain);
      new_exc[i] = MULT16_32_Q15(mem->smooth_gain, new_exc[i]);
   }
#else
   for (i=0;i<nsf;i++)
   {
      mem->smooth_gain = .96*mem->smooth_gain + .04*gain;
      new_exc[i] *= mem->smooth_gain;
   }
#endif
}