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); }
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]; } } }
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; }
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); }