// step receiver mixer, matched filter, decimator // _q : frame synchronizer // _x : input sample // _y : output symbol int flexframesync_step(flexframesync _q, float complex _x, float complex * _y) { // mix sample down float complex v; nco_crcf_mix_down(_q->mixer, _x, &v); nco_crcf_step (_q->mixer); // push sample into filterbank firpfb_crcf_push (_q->mf, v); firpfb_crcf_execute(_q->mf, _q->pfb_index, &v); #if FLEXFRAMESYNC_ENABLE_EQ // push sample through equalizer eqlms_cccf_push(_q->equalizer, v); #endif // increment counter to determine if sample is available _q->mf_counter++; int sample_available = (_q->mf_counter >= 1) ? 1 : 0; // set output sample if available if (sample_available) { #if FLEXFRAMESYNC_ENABLE_EQ // compute equalizer output eqlms_cccf_execute(_q->equalizer, &v); #endif // set output *_y = v; // decrement counter by k=2 samples/symbol _q->mf_counter -= 2; } // return flag return sample_available; }
// update symbol synchronizer internal state (filtered error, index, etc.) // _q : frame synchronizer // _x : input sample // _y : output symbol int flexframesync_update_symsync(flexframesync _q, float complex _x, float complex * _y) { // push sample into filterbanks firpfb_crcf_push(_q->mf, _x); firpfb_crcf_push(_q->dmf, _x); // float complex mf_out = 0.0f; // matched-filter output float complex dmf_out = 0.0f; // derivatived matched-filter output int sample_available = 0; // compute output if timeout if (_q->pfb_timer <= 0) { sample_available = 1; // reset timer _q->pfb_timer = 2; // k samples/symbol firpfb_crcf_execute(_q->mf, _q->pfb_index, &mf_out); firpfb_crcf_execute(_q->dmf, _q->pfb_index, &dmf_out); // update filtered timing error // hi bandwidth parameters: {0.92, 1.20}, about 100 symbols settling time // med bandwidth parameters: {0.98, 0.20}, about 200 symbols settling time // lo bandwidth parameters: {0.99, 0.05}, about 500 symbols settling time _q->pfb_q = 0.99f*_q->pfb_q + 0.05f*crealf( conjf(mf_out)*dmf_out ); // accumulate error into soft filterbank value _q->pfb_soft += _q->pfb_q; // compute actual filterbank index _q->pfb_index = roundf(_q->pfb_soft); // contrain index to be in [0, npfb-1] while (_q->pfb_index < 0) { _q->pfb_index += _q->npfb; _q->pfb_soft += _q->npfb; // adjust pfb output timer _q->pfb_timer--; } while (_q->pfb_index > _q->npfb-1) { _q->pfb_index -= _q->npfb; _q->pfb_soft -= _q->npfb; // adjust pfb output timer _q->pfb_timer++; } } // decrement symbol timer _q->pfb_timer--; // set output and return *_y = mf_out; return sample_available; }