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