Esempio n. 1
0
static opus_val32 loss_distortion(const opus_val16 *eBands, opus_val16 *oldEBands, int start, int end, int len, int C)
{
   int c, i;
   opus_val32 dist = 0;
   c=0; do {
      for (i=start;i<end;i++)
      {
         opus_val16 d = SUB16(SHR16(eBands[i+c*len], 3), SHR16(oldEBands[i+c*len], 3));
         dist = MAC16_16(dist, d,d);
      }
   } while (++c<C);
   return MIN32(200,SHR32(dist,2*DB_SHIFT-6));
}
Esempio n. 2
0
/*Makes sure the LSPs are stable*/
void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin)
{
   int i;
   spx_word16_t m = margin;
   spx_word16_t m2 = 25736-margin;
  
   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);
   }
}
Esempio n. 3
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);
   }
}
/*Makes sure the LSPs are stable*/
void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin)
{
#ifndef FIXED_LPC_SIZE
   int i;
#endif
   spx_word16_t m = margin;
   spx_word16_t m2 = 25736-margin;

   if (lsp[0]<m)
      lsp[0]=m;
   if (lsp[len-1]>m2)
      lsp[len-1]=m2;

#ifndef FIXED_LPC_SIZE
   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);
   }
#else
   if (lsp[1]<lsp[1-1]+m)
      lsp[1]=lsp[1-1]+m;
   if (lsp[1]>lsp[1+1]-m)
      lsp[1]= SHR16(lsp[1],1) + SHR16(lsp[1+1]-m,1);

   if (lsp[2]<lsp[2-1]+m)
      lsp[2]=lsp[2-1]+m;
   if (lsp[2]>lsp[2+1]-m)
      lsp[2]= SHR16(lsp[2],1) + SHR16(lsp[2+1]-m,1);

   if (lsp[3]<lsp[3-1]+m)
      lsp[3]=lsp[3-1]+m;
   if (lsp[3]>lsp[3+1]-m)
      lsp[3]= SHR16(lsp[3],1) + SHR16(lsp[3+1]-m,1);

   if (lsp[4]<lsp[4-1]+m)
      lsp[4]=lsp[4-1]+m;
   if (lsp[4]>lsp[4+1]-m)
      lsp[4]= SHR16(lsp[4],1) + SHR16(lsp[4+1]-m,1);

   if (lsp[5]<lsp[5-1]+m)
      lsp[5]=lsp[5-1]+m;
   if (lsp[5]>lsp[5+1]-m)
      lsp[5]= SHR16(lsp[5],1) + SHR16(lsp[5+1]-m,1);

   if (lsp[6]<lsp[6-1]+m)
      lsp[6]=lsp[6-1]+m;
   if (lsp[6]>lsp[6+1]-m)
      lsp[6]= SHR16(lsp[6],1) + SHR16(lsp[6+1]-m,1);

   if (lsp[7]<lsp[7-1]+m)
      lsp[7]=lsp[7-1]+m;
   if (lsp[7]>lsp[7+1]-m)
      lsp[7]= SHR16(lsp[7],1) + SHR16(lsp[7+1]-m,1);

   if (lsp[8]<lsp[8-1]+m)
      lsp[8]=lsp[8-1]+m;
   if (lsp[8]>lsp[8+1]-m)
      lsp[8]= SHR16(lsp[8],1) + SHR16(lsp[8+1]-m,1);
#endif
}
Esempio n. 5
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);*/
}
Esempio n. 6
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;
}
Esempio n. 7
0
void open_loop_nbest_pitch(spx_word16_t* sw, int start, int end, int len, int* pitch, spx_word16_t* gain, int N, char* stack) {
    int i, j, k;
    VARDECL(spx_word32_t * best_score);
    VARDECL(spx_word32_t * best_ener);
    spx_word32_t e0;
    VARDECL(spx_word32_t * corr);
#ifdef FIXED_POINT
    /* In fixed-point, we need only one (temporary) array of 32-bit values and two (corr16, ener16)
       arrays for (normalized) 16-bit values */
    VARDECL(spx_word16_t * corr16);
    VARDECL(spx_word16_t * ener16);
    spx_word32_t* energy;
    int cshift = 0, eshift = 0;
    int scaledown = 0;
    ALLOC(corr16, end - start + 1, spx_word16_t);
    ALLOC(ener16, end - start + 1, spx_word16_t);
    ALLOC(corr, end - start + 1, spx_word32_t);
    energy = corr;
#else
    /* In floating-point, we need to float arrays and no normalized copies */
    VARDECL(spx_word32_t * energy);
    spx_word16_t* corr16;
    spx_word16_t* ener16;
    ALLOC(energy, end - start + 2, spx_word32_t);
    ALLOC(corr, end - start + 1, spx_word32_t);
    corr16 = corr;
    ener16 = energy;
#endif

    ALLOC(best_score, N, spx_word32_t);
    ALLOC(best_ener, N, spx_word32_t);
    for (i = 0; i < N; i++) {
        best_score[i] = -1;
        best_ener[i] = 0;
        pitch[i] = start;
    }

#ifdef FIXED_POINT
    for (i = -end; i < len; i++) {
        if (ABS16(sw[i]) > 16383) {
            scaledown = 1;
            break;
        }
    }
    /* If the weighted input is close to saturation, then we scale it down */
    if (scaledown) {
        for (i = -end; i < len; i++) {
            sw[i] = SHR16(sw[i], 1);
        }
    }
#endif
    energy[0] = inner_prod(sw - start, sw - start, len);
    e0 = inner_prod(sw, sw, len);
    for (i = start; i < end; i++) {
        /* Update energy for next pitch*/
        energy[i - start + 1] = SUB32(ADD32(energy[i - start], SHR32(MULT16_16(sw[-i - 1], sw[-i - 1]), 6)), SHR32(MULT16_16(sw[-i + len - 1], sw[-i + len - 1]), 6));
        if (energy[i - start + 1] < 0)
            energy[i - start + 1] = 0;
    }

#ifdef FIXED_POINT
    eshift = normalize16(energy, ener16, 32766, end - start + 1);
#endif

    /* In fixed-point, this actually overrites the energy array (aliased to corr) */
    pitch_xcorr(sw, sw - end, corr, len, end - start + 1, stack);

#ifdef FIXED_POINT
    /* Normalize to 180 so we can square it and it still fits in 16 bits */
    cshift = normalize16(corr, corr16, 180, end - start + 1);
    /* If we scaled weighted input down, we need to scale it up again (OK, so we've just lost the LSB, who cares?) */
    if (scaledown) {
        for (i = -end; i < len; i++) {
            sw[i] = SHL16(sw[i], 1);
        }
    }
#endif

    /* Search for the best pitch prediction gain */
    for (i = start; i <= end; i++) {
        spx_word16_t tmp = MULT16_16_16(corr16[i - start], corr16[i - start]);
        /* Instead of dividing the tmp by the energy, we multiply on the other side */
        if (MULT16_16(tmp, best_ener[N - 1]) > MULT16_16(best_score[N - 1], ADD16(1, ener16[i - start]))) {
            /* We can safely put it last and then check */
            best_score[N - 1] = tmp;
            best_ener[N - 1] = ener16[i - start] + 1;
            pitch[N - 1] = i;
            /* Check if it comes in front of others */
            for (j = 0; j < N - 1; j++) {
                if (MULT16_16(tmp, best_ener[j]) > MULT16_16(best_score[j], ADD16(1, ener16[i - start]))) {
                    for (k = N - 1; k > j; k--) {
                        best_score[k] = best_score[k - 1];
                        best_ener[k] = best_ener[k - 1];
                        pitch[k] = pitch[k - 1];
                    }
                    best_score[j] = tmp;
                    best_ener[j] = ener16[i - start] + 1;
                    pitch[j] = i;
                    break;
                }
            }
        }
    }

    /* Compute open-loop gain if necessary */
    if (gain) {
        for (j = 0; j < N; j++) {
            spx_word16_t g;
            i = pitch[j];
            g = DIV32(SHL32(EXTEND32(corr16[i - start]), cshift), 10 + SHR32(MULT16_16(spx_sqrt(e0), spx_sqrt(SHL32(EXTEND32(ener16[i - start]), eshift))), 6));
            /* FIXME: g = max(g,corr/energy) */
            if (g < 0)
                g = 0;
            gain[j] = g;
        }
    }


}
Esempio n. 8
0
EXPORT void speex_encode_stereo_int(spx_int16_t * data, int frame_size,
				    SpeexBits * bits)
{
	int i, tmp;
	spx_word32_t e_left = 0, e_right = 0, e_tot = 0;
	spx_word32_t balance, e_ratio;
	spx_word32_t largest, smallest;
	int balance_id;
#ifdef FIXED_POINT
	int shift;
#endif

	/* In band marker */
	speex_bits_pack(bits, 14, 5);
	/* Stereo marker */
	speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);

	for (i = 0; i < frame_size; i++) {
		e_left += SHR32(MULT16_16(data[2 * i], data[2 * i]), 8);
		e_right +=
		    SHR32(MULT16_16(data[2 * i + 1], data[2 * i + 1]), 8);
#ifdef FIXED_POINT
		/* I think this is actually unbiased */
		data[i] = SHR16(data[2 * i], 1) + PSHR16(data[2 * i + 1], 1);
#else
		data[i] = .5 * (((float)data[2 * i]) + data[2 * i + 1]);
#endif
		e_tot += SHR32(MULT16_16(data[i], data[i]), 8);
	}
	if (e_left > e_right) {
		speex_bits_pack(bits, 0, 1);
		largest = e_left;
		smallest = e_right;
	} else {
		speex_bits_pack(bits, 1, 1);
		largest = e_right;
		smallest = e_left;
	}

	/* Balance quantization */
#ifdef FIXED_POINT
	shift = spx_ilog2(largest) - 15;
	largest = VSHR32(largest, shift - 4);
	smallest = VSHR32(smallest, shift);
	balance = DIV32(largest, ADD32(smallest, 1));
	if (balance > 32767)
		balance = 32767;
	balance_id = scal_quant(EXTRACT16(balance), balance_bounds, 32);
#else
	balance = (largest + 1.) / (smallest + 1.);
	balance = 4 * log(balance);
	balance_id = floor(.5 + fabs(balance));
	if (balance_id > 30)
		balance_id = 31;
#endif

	speex_bits_pack(bits, balance_id, 5);

	/* "coherence" quantisation */
#ifdef FIXED_POINT
	shift = spx_ilog2(e_tot);
	e_tot = VSHR32(e_tot, shift - 25);
	e_left = VSHR32(e_left, shift - 10);
	e_right = VSHR32(e_right, shift - 10);
	e_ratio = DIV32(e_tot, e_left + e_right + 1);
#else
	e_ratio = e_tot / (1. + e_left + e_right);
#endif

	tmp = scal_quant(EXTRACT16(e_ratio), e_ratio_quant_bounds, 4);
	/*fprintf (stderr, "%d %d %d %d\n", largest, smallest, balance_id, e_ratio); */
	speex_bits_pack(bits, tmp, 2);
}
Esempio n. 9
0
static int quant_coarse_energy_impl(const CELTMode *m, int start, int end,
      const opus_val16 *eBands, opus_val16 *oldEBands,
      opus_int32 budget, opus_int32 tell,
      const unsigned char *prob_model, opus_val16 *error, ec_enc *enc,
      int C, int LM, int intra, opus_val16 max_decay)
{
   int i, c;
   int badness = 0;
   opus_val32 prev[2] = {0,0};
   opus_val16 coef;
   opus_val16 beta;

   if (tell+3 <= budget)
      ec_enc_bit_logp(enc, intra, 3);
   if (intra)
   {
      coef = 0;
      beta = beta_intra;
   } else {
      beta = beta_coef[LM];
      coef = pred_coef[LM];
   }

   /* Encode at a fixed coarse resolution */
   for (i=start;i<end;i++)
   {
      c=0;
      do {
         int bits_left;
         int qi, qi0;
         opus_val32 q;
         opus_val16 x;
         opus_val32 f, tmp;
         opus_val16 oldE;
         opus_val16 decay_bound;
         x = eBands[i+c*m->nbEBands];
         oldE = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]);
#ifdef FIXED_POINT
         f = SHL32(EXTEND32(x),7) - PSHR32(MULT16_16(coef,oldE), 8) - prev[c];
         /* Rounding to nearest integer here is really important! */
         qi = (f+QCONST32(.5f,DB_SHIFT+7))>>(DB_SHIFT+7);
         decay_bound = EXTRACT16(MAX32(-QCONST16(28.f,DB_SHIFT),
               SUB32((opus_val32)oldEBands[i+c*m->nbEBands],max_decay)));
#else
         f = x-coef*oldE-prev[c];
         /* Rounding to nearest integer here is really important! */
         qi = (int)floor(.5f+f);
         decay_bound = MAX16(-QCONST16(28.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]) - max_decay;
#endif
         /* Prevent the energy from going down too quickly (e.g. for bands
            that have just one bin) */
         if (qi < 0 && x < decay_bound)
         {
            qi += (int)SHR16(SUB16(decay_bound,x), DB_SHIFT);
            if (qi > 0)
               qi = 0;
         }
         qi0 = qi;
         /* If we don't have enough bits to encode all the energy, just assume
             something safe. */
         tell = ec_tell(enc);
         bits_left = budget-tell-3*C*(end-i);
         if (i!=start && bits_left < 30)
         {
            if (bits_left < 24)
               qi = IMIN(1, qi);
            if (bits_left < 16)
               qi = IMAX(-1, qi);
         }
         if (budget-tell >= 15)
         {
            int pi;
            pi = 2*IMIN(i,20);
            ec_laplace_encode(enc, &qi,
                  prob_model[pi]<<7, prob_model[pi+1]<<6);
         }
         else if(budget-tell >= 2)
         {
            qi = IMAX(-1, IMIN(qi, 1));
            ec_enc_icdf(enc, 2*qi^-(qi<0), small_energy_icdf, 2);
         }
         else if(budget-tell >= 1)
         {
            qi = IMIN(0, qi);
            ec_enc_bit_logp(enc, -qi, 1);
         }
         else
            qi = -1;
         error[i+c*m->nbEBands] = PSHR32(f,7) - SHL16(qi,DB_SHIFT);
         badness += abs(qi0-qi);
         q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT);

         tmp = PSHR32(MULT16_16(coef,oldE),8) + prev[c] + SHL32(q,7);
#ifdef FIXED_POINT
         tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp);
#endif
         oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7);
         prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8));
      } while (++c < C);
   }
   return badness;
}
Esempio n. 10
0
File: ltp.c Progetto: Affix/fgcom
void open_loop_nbest_pitch(spx_sig_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack)
{
    int i,j,k;
    VARDECL(spx_word32_t *best_score);
    spx_word32_t e0;
    VARDECL(spx_word32_t *corr);
    VARDECL(spx_word32_t *energy);
    VARDECL(spx_word32_t *score);
#ifdef FIXED_POINT
    VARDECL(spx_word16_t *swn2);
#endif
    spx_word16_t *swn;

    ALLOC(best_score, N, spx_word32_t);
    ALLOC(corr, end-start+1, spx_word32_t);
    ALLOC(energy, end-start+2, spx_word32_t);
    ALLOC(score, end-start+1, spx_word32_t);

#ifdef FIXED_POINT
    ALLOC(swn2, end+len, spx_word16_t);
    normalize16(sw-end, swn2, 16384, end+len);
    swn = swn2 + end;
#else
    swn = sw;
#endif

    for (i=0; i<N; i++)
    {
        best_score[i]=-1;
        pitch[i]=start;
    }


    energy[0]=inner_prod(swn-start, swn-start, len);
    e0=inner_prod(swn, swn, len);
    for (i=start; i<=end; i++)
    {
        /* Update energy for next pitch*/
        energy[i-start+1] = SUB32(ADD32(energy[i-start],SHR32(MULT16_16(swn[-i-1],swn[-i-1]),6)), SHR32(MULT16_16(swn[-i+len-1],swn[-i+len-1]),6));
    }

    pitch_xcorr(swn, swn-end, corr, len, end-start+1, stack);

#ifdef FIXED_POINT
    {
        VARDECL(spx_word16_t *corr16);
        VARDECL(spx_word16_t *ener16);
        ALLOC(corr16, end-start+1, spx_word16_t);
        ALLOC(ener16, end-start+1, spx_word16_t);
        normalize16(corr, corr16, 16384, end-start+1);
        normalize16(energy, ener16, 16384, end-start+1);

        for (i=start; i<=end; i++)
        {
            spx_word16_t g;
            spx_word32_t tmp;
            tmp = corr16[i-start];
            if (tmp>0)
            {
                if (SHR16(corr16[i-start],4)>ener16[i-start])
                    tmp = SHL32(EXTEND32(ener16[i-start]),14);
                else if (-SHR16(corr16[i-start],4)>ener16[i-start])
                    tmp = -SHL32(EXTEND32(ener16[i-start]),14);
                else
                    tmp = SHL32(tmp,10);
                g = DIV32_16(tmp, 8+ener16[i-start]);
                score[i-start] = MULT16_16(corr16[i-start],g);
            } else
            {
                score[i-start] = 1;
            }
        }
    }
#else
    for (i=start; i<=end; i++)
    {
        float g = corr[i-start]/(1+energy[i-start]);
        if (g>16)
            g = 16;
        else if (g<-16)
            g = -16;
        score[i-start] = g*corr[i-start];
    }
#endif

    /* Extract best scores */
    for (i=start; i<=end; i++)
    {
        if (score[i-start]>best_score[N-1])
        {
            for (j=0; j<N; j++)
            {
                if (score[i-start] > best_score[j])
                {
                    for (k=N-1; k>j; k--)
                    {
                        best_score[k]=best_score[k-1];
                        pitch[k]=pitch[k-1];
                    }
                    best_score[j]=score[i-start];
                    pitch[j]=i;
                    break;
                }
            }
        }
    }

    /* Compute open-loop gain */
    if (gain)
    {
        for (j=0; j<N; j++)
        {
            spx_word16_t g;
            i=pitch[j];
            g = DIV32(corr[i-start], 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(energy[i-start])),6));
            /* FIXME: g = max(g,corr/energy) */
            if (g<0)
                g = 0;
            gain[j]=g;
        }
    }
}