Esempio n. 1
0
/*-----------------------------------------------------------*
 * procedure Cod_cng:                                        *
 *           ~~~~~~~~                                        *
 *   computes DTX decision                                   *
 *   encodes SID frames                                      *
 *   computes CNG excitation for encoder update              *
 *-----------------------------------------------------------*/
void Cod_cng(
  DtxStatus *handle,
  Word16 *exc,          /* (i/o) : excitation array                     */
  Word16 pastVad,       /* (i)   : previous VAD decision                */
  Word16 *lsp_old_q,    /* (i/o) : previous quantized lsp               */
  Word16 *Aq,           /* (o)   : set of interpolated LPC coefficients */
  Word16 *ana,          /* (o)   : coded SID parameters                 */
  Word16 freq_prev[MA_NP][M],
                        /* (i/o) : previous LPS for quantization        */
  Word16 *seed          /* (i/o) : random generator seed                */
)
{

  Word16 i;

  Word16 curAcf[MP1];
  Word16 bid[M], zero[MP1];
  Word16 curCoeff[MP1];
  Word16 lsp_new[M];
  Word16 *lpcCoeff;
  Word16 cur_igain;
  Word16 energyq, temp;

  /* Update Ener and sh_ener */
  for(i = NB_GAIN-1; i>=1; i--) {
    handle->ener[i] = handle->ener[i-1];
    handle->sh_ener[i] = handle->sh_ener[i-1];
  }

  /* Compute current Acfs */
  Calc_sum_acf(handle->Acf, handle->sh_Acf, curAcf, &(handle->sh_ener[0]), NB_CURACF);

  /* Compute LPC coefficients and residual energy */
  if(curAcf[0] == 0) {
    handle->ener[0] = 0;                /* should not happen */
  }
  else {
    Set_zero(zero, MP1);
    Levinson(handle, curAcf, zero, curCoeff, bid, &(handle->ener[0]));
  }

  /* if first frame of silence => SID frame */
  if(pastVad != 0) {
    ana[0] = 2;
    handle->count_fr0 = 0;
    handle->nb_ener = 1;
    Qua_Sidgain(handle->ener, handle->sh_ener, handle->nb_ener, &energyq, &cur_igain);

  }
  else {
    handle->nb_ener = add(handle->nb_ener, 1);
    if(sub(handle->nb_ener, NB_GAIN) > 0) handle->nb_ener = NB_GAIN;
    Qua_Sidgain(handle->ener, handle->sh_ener, handle->nb_ener, &energyq, &cur_igain);
      
    /* Compute stationarity of current filter   */
    /* versus reference filter                  */
    if(Cmp_filt(handle->RCoeff, handle->sh_RCoeff, curAcf, handle->ener[0], FRAC_THRESH1) != 0) {
      handle->flag_chang = 1;
    }
      
    /* compare energy difference between current frame and last frame */
    temp = abs_s(sub(handle->prev_energy, energyq));
    temp = sub(temp, 2);
    if (temp > 0) handle->flag_chang = 1;
      
    handle->count_fr0 = add(handle->count_fr0, 1);
    if(sub(handle->count_fr0, FR_SID_MIN) < 0) {
      ana[0] = 0;               /* no transmission */
    }
    else {
      if(handle->flag_chang != 0) {
        ana[0] = 2;             /* transmit SID frame */
      }
      else{
        ana[0] = 0;
      }
        
      handle->count_fr0 = FR_SID_MIN;   /* to avoid overflow */
    }
  }


  if(sub(ana[0], 2) == 0) {
      
    /* Reset frame count and change flag */
    handle->count_fr0 = 0;
    handle->flag_chang = 0;
      
    /* Compute past average filter */
    Calc_pastfilt(handle, handle->pastCoeff);
    Calc_RCoeff(handle->pastCoeff, handle->RCoeff, &(handle->sh_RCoeff));

    /* Compute stationarity of current filter   */
    /* versus past average filter               */


    /* if stationary */
    /* transmit average filter => new ref. filter */
    if(Cmp_filt(handle->RCoeff, handle->sh_RCoeff, curAcf, handle->ener[0], FRAC_THRESH2) == 0) {
      lpcCoeff = handle->pastCoeff;
    }

    /* else */
    /* transmit current filter => new ref. filter */
    else {
      lpcCoeff = curCoeff;
      Calc_RCoeff(curCoeff, handle->RCoeff, &(handle->sh_RCoeff));
    }

    /* Compute SID frame codes */

    Az_lsp(lpcCoeff, lsp_new, lsp_old_q); /* From A(z) to lsp */

    /* LSP quantization */
    lsfq_noise(lsp_new, handle->lspSid_q, freq_prev, &ana[1]);

    handle->prev_energy = energyq;
    ana[4] = cur_igain;
    handle->sid_gain = tab_Sidgain[cur_igain];


  } /* end of SID frame case */

  /* Compute new excitation */
  if(pastVad != 0) {
    handle->cur_gain = handle->sid_gain;
  }
  else {
    handle->cur_gain = mult_r(handle->cur_gain, A_GAIN0);
    handle->cur_gain = add(handle->cur_gain, mult_r(handle->sid_gain, A_GAIN1));
  }

  Calc_exc_rand(handle->L_exc_err, handle->cur_gain, exc, seed, FLAG_COD);

  Int_qlpc(lsp_old_q, handle->lspSid_q, Aq);
  for(i=0; i<M; i++) {
    lsp_old_q[i]   = handle->lspSid_q[i];
  }

  /* Update sumAcf if fr_cur = 0 */
  if(handle->fr_cur == 0) {
    Update_sumAcf(handle);
  }

  return;
}
Esempio n. 2
0
/*-----------------------------------------------------------*
* procedure cod_cng:                                        *
*           ~~~~~~~~                                        *
*   computes DTX decision                                   *
*   encodes SID frames                                      *
*   computes CNG excitation for encoder update              *
*-----------------------------------------------------------*/
void cod_cng(float * exc,	/* (i/o) : excitation array                     */
	     int pastVad,	/* (i)   : previous VAD decision                */
	     float * lsp_old_q,	/* (i/o) : previous quantized lsp               */
	     float * old_A,	/* (i/o) : last stable filter LPC coefficients  */
	     float * old_rc,	/* (i/o) : last stable filter Reflection coefficients. */
	     float * Aq,	/* (o)   : set of interpolated LPC coefficients */
	     int *ana,		/* (o)   : coded SID parameters                 */
	     float freq_prev[MA_NP][M],	/* (i/o) : previous LPS for quantization        */
	     int16_t * seed	/* (i/o) : random generator seed                */
    )
{
	int i;

	float curAcf[MP1];
	float bid[MP1];
	float curCoeff[MP1];
	float lsp_new[M];
	float *lpcCoeff;
	int cur_igain;
	float energyq;

	/* Update Ener */
	for (i = NB_GAIN - 1; i >= 1; i--) {
		ener[i] = ener[i - 1];
	}

	/* Compute current Acfs */
	calc_sum_acf(Acf, curAcf, NB_CURACF);

	/* Compute LPC coefficients and residual energy */
	if (curAcf[0] == (float) 0.) {
		ener[0] = (float) 0.;	/* should not happen */
	} else {
		ener[0] = levinsone(M, curAcf, curCoeff, bid, old_A, old_rc);
	}

	/* if first frame of silence => SID frame */
	if (pastVad != 0) {
		ana[0] = 1;
		count_fr0 = 0;
		nb_ener = 1;
		qua_Sidgain(ener, nb_ener, &energyq, &cur_igain);
	} else {
		nb_ener++;
		if (nb_ener > NB_GAIN)
			nb_ener = NB_GAIN;
		qua_Sidgain(ener, nb_ener, &energyq, &cur_igain);

		/* Compute stationarity of current filter   */
		/* versus reference filter                  */
		if (cmp_filt(RCoeff, curAcf, ener[0], THRESH1) != 0) {
			flag_chang = 1;
		}

		/* compare energy difference between current frame and last frame */
		if ((float) fabs(prev_energy - energyq) > (float) 2.0)
			flag_chang = 1;

		count_fr0++;
		if (count_fr0 < FR_SID_MIN) {
			ana[0] = 0;	/* no transmission */
		} else {
			if (flag_chang != 0) {
				ana[0] = 1;	/* transmit SID frame */
			} else {
				ana[0] = 0;
			}
			count_fr0 = FR_SID_MIN;	/* to avoid overflow */
		}
	}

	if (ana[0] == 1) {

		/* Reset frame count and change flag */
		count_fr0 = 0;
		flag_chang = 0;

		/* Compute past average filter */
		calc_pastfilt(pastCoeff, old_A, old_rc);
		calc_RCoeff(pastCoeff, RCoeff);

		/* Compute stationarity of current filter   */
		/* versus past average filter               */

		/* if stationary */
		/* transmit average filter => new ref. filter */
		if (cmp_filt(RCoeff, curAcf, ener[0], THRESH2) == 0) {
			lpcCoeff = pastCoeff;
		}

		/* else */
		/* transmit current filter => new ref. filter */
		else {
			lpcCoeff = curCoeff;
			calc_RCoeff(curCoeff, RCoeff);
		}

		/* Compute SID frame codes */
		az_lsp(lpcCoeff, lsp_new, lsp_old_q);	/* From A(z) to lsp */

		/* LSP quantization */
		lsfq_noise(lsp_new, lspSid_q, freq_prev, &ana[1]);

		prev_energy = energyq;
		ana[4] = cur_igain;
		sid_gain = tab_Sidgain[cur_igain];

	}

	/* end of SID frame case */
	/* Compute new excitation */
	if (pastVad != 0) {
		cur_gain = sid_gain;
	} else {
		cur_gain *= A_GAIN0;
		cur_gain += A_GAIN1 * sid_gain;
	}

	calc_exc_rand(cur_gain, exc, seed, FLAG_COD);

	int_qlpc(lsp_old_q, lspSid_q, Aq);
	for (i = 0; i < M; i++) {
		lsp_old_q[i] = lspSid_q[i];
	}

	/* Update sumAcf if fr_cur = 0 */
	if (fr_cur == 0) {
		update_sumAcf();
	}

	return;
}