void ofdmoqamframe64sync_reset(ofdmoqamframe64sync _q) { // reset pilot sequence generator msequence_reset(_q->ms_pilot); // reset auto-correlators autocorr_cccf_clear(_q->autocorr); _q->rxx_mag_max = 0.0f; // reset frequency offset estimation, correction _q->nu_hat = 0.0f; nco_crcf_reset(_q->nco_rx); nco_crcf_reset(_q->nco_pilot); pll_reset(_q->pll_pilot); // clear input buffer windowcf_clear(_q->input_buffer); // clear analysis filter bank objects firpfbch_clear(_q->ca0); firpfbch_clear(_q->ca1); // reset gain parameters _q->g = 1.0f; // coarse gain estimate unsigned int i; for (i=0; i<_q->num_subcarriers; i++) _q->G[i] = 1.0f; for (i=0; i<4; i++) _q->y_phase[i] = 0.0f; // reset state _q->state = OFDMOQAMFRAME64SYNC_STATE_PLCPSHORT; //_q->state = OFDMOQAMFRAME64SYNC_STATE_PLCPLONG0; _q->timer = 0; _q->num_symbols = 0; _q->num_data_symbols = 0; _q->num_samples = 0; _q->sample_phase = 0; }
firpfbch firpfbch_create(unsigned int _num_channels, unsigned int _m, float _beta, float _dt, int _nyquist, int _gradient) { firpfbch c = (firpfbch) malloc(sizeof(struct firpfbch_s)); c->num_channels = _num_channels; c->m = _m; c->beta = _beta; c->dt = _dt; c->nyquist = _nyquist; // validate inputs if (_m < 1) { printf("error: firpfbch_create(), invalid filter delay (must be greater than 0)\n"); exit(1); } // create bank of filters c->dp = (DOTPROD()*) malloc((c->num_channels)*sizeof(DOTPROD())); c->w = (WINDOW()*) malloc((c->num_channels)*sizeof(WINDOW())); // design filter // TODO: use filter prototype object c->h_len = 2*(c->m)*(c->num_channels); c->h = (float*) malloc((c->h_len+1)*sizeof(float)); if (c->nyquist == FIRPFBCH_NYQUIST) { float fc = 0.5f/(float)(c->num_channels); // cutoff frequency liquid_firdes_kaiser(c->h_len+1, fc, c->beta, 0.0f, c->h); } else if (c->nyquist == FIRPFBCH_ROOTNYQUIST) { design_rkaiser_filter(c->num_channels, c->m, c->beta, c->dt, c->h); } else { printf("error: firpfbch_create(), unsupported nyquist flag: %d\n", _nyquist); exit(1); } unsigned int i; if (_gradient) { float dh[c->h_len]; for (i=0; i<c->h_len; i++) { if (i==0) { dh[i] = c->h[i+1] - c->h[c->h_len-1]; } else if (i==c->h_len-1) { dh[i] = c->h[0] - c->h[i-1]; } else { dh[i] = c->h[i+1] - c->h[i-1]; } } memmove(c->h, dh, (c->h_len)*sizeof(float)); } // generate bank of sub-samped filters unsigned int n; unsigned int h_sub_len = 2*(c->m); // length of each sub-sampled filter float h_sub[h_sub_len]; for (i=0; i<c->num_channels; i++) { // sub-sample prototype filter, loading coefficients in reverse order for (n=0; n<h_sub_len; n++) { h_sub[h_sub_len-n-1] = c->h[i + n*(c->num_channels)]; } // create window buffer and dotprod object (coefficients // loaded in reverse order) c->dp[i] = DOTPROD(_create)(h_sub,h_sub_len); c->w[i] = WINDOW(_create)(h_sub_len); #if DEBUG_FIRPFBCH_PRINT printf("h_sub[%u] :\n", i); for (n=0; n<h_sub_len; n++) printf(" h[%3u] = %8.4f\n", n, h_sub[n]); #endif } #if DEBUG_FIRPFBCH_PRINT for (i=0; i<c->h_len+1; i++) printf("h(%4u) = %12.4e;\n", i+1, c->h[i]); #endif // allocate memory for buffers // TODO : use fftw_malloc if HAVE_FFTW3_H c->x = (float complex*) malloc((c->num_channels)*sizeof(float complex)); c->X = (float complex*) malloc((c->num_channels)*sizeof(float complex)); c->X_prime = (float complex*) malloc((c->num_channels)*sizeof(float complex)); firpfbch_clear(c); // create fft plan c->fft = FFT_CREATE_PLAN(c->num_channels, c->X, c->x, FFT_DIR_BACKWARD, FFT_METHOD); return c; }