Пример #1
0
void IQSSBDemodulator::agc(Ipp32f* b, int len)
{
	const Ipp32f MAX_GAIN = 1000.0f;
	const int AGC_HANG = 10;
	const int AGC_ATTACK_COUNT = 48;
	static Ipp32f prev_gain = 0;
	static int agcloop = 0;
	static Ipp32f* gain_mult = ippsMalloc_32f(BLKSIZE);
	static Ipp32f* gain_factor = ippsMalloc_32f(AGC_HANG);

	agcloop = (agcloop+1)%AGC_HANG;
	
	Ipp32f Vpk;
	ippsMax_32f(b, len, &Vpk);
	Ipp32f gain = MAX_GAIN;
	if (Vpk>(100*IPP_MINABS_32F))
	{
		gain_factor[agcloop] = 0.5/Vpk;
		ippsMin_32f(gain_factor, AGC_HANG, &gain);
	}
	if (gain>MAX_GAIN)
	{
		gain = MAX_GAIN;
	}
	ippsSet_32f(gain, gain_mult, len);
	Ipp32f gain_step = (gain-prev_gain)/(AGC_ATTACK_COUNT+0.0);
	for(int n=0; n<AGC_ATTACK_COUNT; n++)
	{
		gain_mult[n] = prev_gain+n*gain_step;
	}
	prev_gain = gain;
	ippsMul_32f_I(gain_mult, b, len);
}
Пример #2
0
static void ssr_compensate(Ipp32f   *input,
                           SSR_GAIN **SSRInfo,
                           SSR_GAIN *prevSSRInfo,
                           Ipp32s   len,
                           Ipp32s   window_sequence,
                           Ipp32f   **out,
                           Ipp32f   *m_gcOverlapBuffer)
{
  IPP_ALIGNED_ARRAY(32, Ipp32f, a_gcwind, 512);
  Ipp32f *gcOverlapBuffer[4];
  Ipp32s i, band, k;

  Ipp32s  last_cur_block = 0;

  for (i = 0; i < 4; i++) {
    gcOverlapBuffer[i] = m_gcOverlapBuffer + 512 * i;
  }

  if (window_sequence == EIGHT_SHORT_SEQUENCE){
    for (band = 0; band < 4; band++) {
      for (k = 0; k < 8; k++) {
        ssr_gainc_window(len/16,
                         &prevSSRInfo[band],
                         &SSRInfo[band][k], &SSRInfo[band][k],
                         a_gcwind, window_sequence);

        ippsMul_32f_I(a_gcwind, input+band*len/2 + k*len/16,
                      len/32);

        ippsAdd_32f_I(input+band*len/2+k*len/16,
                      &gcOverlapBuffer[band][len*7/64+len/32*k],
                      len/32);

        ippsMul_32f(input+band*len/2+k*len/16+len/32,
                    a_gcwind+len/32,
                    &gcOverlapBuffer[band][len*7/64+(k+1)*len/32],
                    len/32);
        prevSSRInfo[band] = SSRInfo[band][k];
      }

      ippsMove_32f(&gcOverlapBuffer[band][0], &out[band][0],
                   len/4);

      ippsMove_32f(&gcOverlapBuffer[band][len/4],
                   &gcOverlapBuffer[band][0],
                   len/4);
    }
  } else {
    last_cur_block = 0;
    if (window_sequence != ONLY_LONG_SEQUENCE)
      last_cur_block = 1;

    for (band = 0; band < 4; band++) {
      ssr_gainc_window(len/2,
                       &prevSSRInfo[band],
                       &SSRInfo[band][0], &SSRInfo[band][1],
                       a_gcwind, window_sequence);

      ippsMul_32f_I(a_gcwind, input+band*len/2,
                    len/4);
      ippsAdd_32f(&gcOverlapBuffer[band][0], input+band*len/2,
                  &out[band][0], len/4);

      ippsMul_32f(input+band*len/2+len/4,
                  a_gcwind + len/4,
                  &gcOverlapBuffer[band][0], len/4);

      prevSSRInfo[band] = SSRInfo[band][last_cur_block];
    }
  }
}
Пример #3
0
int G729FPVAD(VADmemory* vadObj,const Ipp16s* src, Ipp16s* dst, Ipp32s *frametype ){
   LOCAL_ALIGN_ARRAY(32, Ipp32f, forwardAutoCorr, (LPC_ORDERP2+1),vadObj);       /* Autocorrelations (forward) */
   LOCAL_ALIGN_ARRAY(32, Ipp32f, forwardLPC, LPC_ORDERP1*2,vadObj);      /* A(z) forward unquantized for the 2 subframes */
   LOCAL_ALIGN_ARRAY(32, Ipp32f, TmpAlignVec, WINDOW_LEN,vadObj);
   LOCAL_ARRAY(Ipp32f, forwardReflectCoeff, LPC_ORDER,vadObj);
   LOCAL_ARRAY(Ipp32f, CurrLSP, LPC_ORDER,vadObj);
   LOCAL_ARRAY(Ipp32f, CurrLSF, LPC_ORDER,vadObj);

   Ipp32f *pWindow;
   Ipp32f *newSpeech;
   /* Excitation vector */
   Ipp16s isVAD;
   Ipp32f tmp_lev;
   Ipp32s VADDecision;
   Ipp32f EnergydB;
   IppStatus sts;

   *frametype = 3;
   if(NULL==vadObj || NULL==src || NULL ==dst)
      return -10;
   if(vadObj->objPrm.objSize <= 0)
      return -8;
   if(ENC_KEY != vadObj->objPrm.key)
      return -5;
   isVAD = (Ipp16s)(vadObj->objPrm.mode == G729Encode_VAD_Enabled);

   if(!isVAD) return 0;

   newSpeech = vadObj->OldSpeechBuffer + SPEECH_BUFF_LEN - FRM_LEN;         /* New speech     */
   pWindow   = vadObj->OldSpeechBuffer + SPEECH_BUFF_LEN - WINDOW_LEN;        /* For LPC window */

   if (vadObj->sFrameCounter == 32767) vadObj->sFrameCounter = 256;
   else vadObj->sFrameCounter++;

   ippsConvert_16s32f(src,newSpeech,FRM_LEN);
   ownAutoCorr_G729_32f(pWindow, LPC_ORDERP2, forwardAutoCorr,TmpAlignVec);             /* Autocorrelations */

   /* Lag windowing    */
   ippsMul_32f_I(lwindow, &forwardAutoCorr[1], LPC_ORDERP2);
   /* Levinson Durbin  */
   tmp_lev = 0;
   sts = ippsLevinsonDurbin_G729_32f(forwardAutoCorr, LPC_ORDER, &forwardLPC[LPC_ORDERP1], forwardReflectCoeff, &tmp_lev);
   if(sts == ippStsOverflow) {
      ippsCopy_32f(vadObj->OldForwardLPC,&forwardLPC[LPC_ORDERP1],LPC_ORDER+1);
      forwardReflectCoeff[0] = vadObj->OldForwardRC[0];
      forwardReflectCoeff[1] = vadObj->OldForwardRC[1];
   } else {
      ippsCopy_32f(&forwardLPC[LPC_ORDERP1],vadObj->OldForwardLPC,LPC_ORDER+1);
      vadObj->OldForwardRC[0] = forwardReflectCoeff[0];
      vadObj->OldForwardRC[1] = forwardReflectCoeff[1];
   }

   /* Convert A(z) to lsp */
   ippsLPCToLSP_G729_32f(&forwardLPC[LPC_ORDERP1], vadObj->OldLSP, CurrLSP);

   if (vadObj->objPrm.mode == G729Encode_VAD_Enabled) {
      ownACOS_G729_32f(CurrLSP, CurrLSF, LPC_ORDER);
      VoiceActivityDetect_G729_32f(forwardReflectCoeff[1], CurrLSF, forwardAutoCorr, pWindow, vadObj->sFrameCounter,
                  vadObj->prevVADDec, vadObj->prevPrevVADDec, &VADDecision, &EnergydB,(Ipp8s *)vadObj,TmpAlignVec);
   } else VADDecision = 1;

   if(VADDecision == 0) {
      /* Inactive frame */
      vadObj->prevVADDec = 0;
      *frametype=1; /* SID*/
   }
   else vadObj->prevVADDec = VADDecision;

   vadObj->prevPrevVADDec = vadObj->prevVADDec;
   ippsMove_32f(&vadObj->OldSpeechBuffer[FRM_LEN], &vadObj->OldSpeechBuffer[0], SPEECH_BUFF_LEN-FRM_LEN);
   CLEAR_SCRATCH_MEMORY(vadObj);
   return 0;
}
Пример #4
0
void IQSSBDemodulator::process_block(Ipp32f* iq_block, Ipp32f* out_block)
{
	static bool flip=false;
	// Deinterleave to real and imaginary (I and Q) buffers
	ippsDeinterleave_32f(iq_block, 2, BLKSIZE, _iq);
	ippsZero_32f(_in_re+BLKSIZE, NFFT-BLKSIZE);
	ippsZero_32f(_in_im+BLKSIZE, NFFT-BLKSIZE);
	// _in_re now contains the real/I part and 
	// _in_im now contains the imaginary/Q part
	
	ippsFFTFwd_CToC_32f_I(_in_re, _in_im,
	                       _fft_specs, _fft_buf);
	ippsCartToPolar_32f(_in_re, _in_im,
	                    _in_m, _in_p,
	                    NFFT);

	// layout of frequency bins is
	// NFFT/2 to NFFT-1 and then continues from 0 to NFFT/2-1

	// shift desired part to 0Hz
	int lo = _lo*NFFT;
	circshift(_in_m, NFFT, lo);	
	circshift(_in_p, NFFT, lo);	
	// zero out undesired sideband
	if(_sideband == USB)
	{
		// zero out LSB, that is NFFT/2 to NFFT-1
		ippsZero_32f(_in_m+NFFT/2, NFFT/2);
		ippsZero_32f(_in_p+NFFT/2, NFFT/2);
	}
	else // _sideband must be LSB
	{
		// zero out USB, that is 0 to NFFT/2-1
		ippsZero_32f(_in_m, NFFT/2);
		ippsZero_32f(_in_p, NFFT/2);
	}
	// filter the passband
	ippsMul_32f_I(_fir_taps_m, _in_m, NFFT);
	ippsAdd_32f_I(_fir_taps_p, _in_p, NFFT);
	// return to time domain
	ippsPolarToCart_32f(_in_m, _in_p,
	                    _in_re, _in_im,
	                    NFFT);
	ippsFFTInv_CToC_32f_I(_in_re, _in_im,
	                    _fft_specs, _fft_buf);
	// do overlap/add
	//
	// 1) add the residual from last round
	ippsAdd_32f_I(_residual_re, _in_re, _residual_length);
	ippsAdd_32f_I(_residual_im, _in_im, _residual_length);
	// 2) Store the new residual
	if(flip)
	{
		ippsMulC_32f_I(-1.0, _in_re, NFFT);
		ippsMulC_32f_I(-1.0, _in_im, NFFT);
		flip=!flip;
	}
	ippsCopy_32f(_in_re+BLKSIZE, _residual_re, _residual_length);
	ippsCopy_32f(_in_im+BLKSIZE, _residual_im, _residual_length);

	// agc
	agc(_in_re, BLKSIZE);
	
	// deliver the result
	ippsCopy_32f(_in_re, out_block, BLKSIZE);
}