// execute framing synchronizer on input buffer // _q : framing synchronizer object // _buffer : input buffer [size: _n x 1] // _n : input buffer size void wlanframesync_execute(wlanframesync _q, liquid_float_complex * _buffer, unsigned int _n) { unsigned int i; float complex x; for (i=0; i<_n; i++) { x = _buffer[i]; // correct for carrier frequency offset (only if not in // initial 'seek PLCP' state) if (_q->state != WLANFRAMESYNC_STATE_SEEKPLCP) { nco_crcf_mix_down(_q->nco_rx, x, &x); nco_crcf_step(_q->nco_rx); } // save input sample to buffer windowcf_push(_q->input_buffer,x); #if DEBUG_WLANFRAMESYNC if (_q->debug_enabled) { // apply agc (estimate initial signal gain) float complex y; agc_crcf_execute(_q->agc_rx, x, &y); windowcf_push(_q->debug_x, x); windowf_push(_q->debug_rssi, agc_crcf_get_rssi(_q->agc_rx)); } #endif switch (_q->state) { case WLANFRAMESYNC_STATE_SEEKPLCP: wlanframesync_execute_seekplcp(_q); break; case WLANFRAMESYNC_STATE_RXSHORT0: wlanframesync_execute_rxshort0(_q); break; case WLANFRAMESYNC_STATE_RXSHORT1: wlanframesync_execute_rxshort1(_q); break; case WLANFRAMESYNC_STATE_RXLONG0: wlanframesync_execute_rxlong0(_q); break; case WLANFRAMESYNC_STATE_RXLONG1: wlanframesync_execute_rxlong1(_q); break; case WLANFRAMESYNC_STATE_RXSIGNAL: wlanframesync_execute_rxsignal(_q); break; case WLANFRAMESYNC_STATE_RXDATA: wlanframesync_execute_rxdata(_q); break; default:; // should never get to this point fprintf(stderr,"error: wlanframesync_execute(), invalid state\n"); exit(1); } } // for (i=0; i<_n; i++) }
// // Test RSSI on noise input // void autotest_agc_crcf_rssi_noise() { // set paramaters float gamma = -30.0f; // nominal signal level [dB] float bt = 0.01f; // agc bandwidth float tol = 0.2f; // error tolerance [dB] // signal properties float nstd = powf(10.0f, gamma/20); // create AGC object and initialize agc_crcf q = agc_crcf_create(); agc_crcf_set_bandwidth(q, bt); unsigned int i; float complex x, y; for (i=0; i<2000; i++) { // generate sample (circular complex noise) x = nstd*(randnf() + _Complex_I*randnf())*M_SQRT1_2; // execute agc agc_crcf_execute(q, x, &y); } // get received signal strength indication float rssi = agc_crcf_get_rssi(q); if (liquid_autotest_verbose) printf("gamma : %12.8f, rssi : %12.8f\n", gamma, rssi); // Check results CONTEND_DELTA( rssi, gamma, tol ); // destroy agc object agc_crcf_destroy(q); }
int main(int argc, char*argv[]) { // options float noise_floor= -40.0f; // noise floor [dB] float SNRdB = 20.0f; // signal-to-noise ratio [dB] float bt = 0.05f; // loop bandwidth unsigned int num_symbols= 100; // number of iterations unsigned int d = 5; // print every d iterations unsigned int k = 2; // interpolation factor (samples/symbol) unsigned int m = 3; // filter delay (symbols) float beta = 0.3f; // filter excess bandwidth factor float dt = 0.0f; // filter fractional sample delay // derived values unsigned int num_samples=num_symbols*k; float gamma = powf(10.0f, (SNRdB+noise_floor)/20.0f); // channel gain float nstd = powf(10.0f, noise_floor / 20.0f); // arrays float complex x[num_samples]; float complex y[num_samples]; float rssi[num_samples]; // create objects modem mod = modem_create(LIQUID_MODEM_QPSK); firinterp_crcf interp = firinterp_crcf_create_prototype(LIQUID_FIRFILT_RRC,k,m,beta,dt); agc_crcf p = agc_crcf_create(); agc_crcf_set_bandwidth(p, bt); unsigned int i; // print info printf("automatic gain control // loop bandwidth: %4.2e\n",bt); unsigned int sym; float complex s; for (i=0; i<num_symbols; i++) { // generate random symbol sym = modem_gen_rand_sym(mod); modem_modulate(mod, sym, &s); s *= gamma; firinterp_crcf_execute(interp, s, &x[i*k]); } // add noise for (i=0; i<num_samples; i++) x[i] += nstd*(randnf() + _Complex_I*randnf()) * M_SQRT1_2; // run agc for (i=0; i<num_samples; i++) { agc_crcf_execute(p, x[i], &y[i]); rssi[i] = agc_crcf_get_rssi(p); } // destroy objects modem_destroy(mod); agc_crcf_destroy(p); firinterp_crcf_destroy(interp); // print results to screen printf("received signal strength indication (rssi):\n"); for (i=0; i<num_samples; i+=d) { printf("%4u : %8.2f\n", i, rssi[i]); } // // export results // FILE* fid = fopen(OUTPUT_FILENAME,"w"); if (!fid) { fprintf(stderr,"error: %s, could not open '%s' for writing\n", argv[0], OUTPUT_FILENAME); exit(1); } fprintf(fid,"%% %s: auto-generated file\n\n",OUTPUT_FILENAME); fprintf(fid,"n = %u;\n", num_samples); fprintf(fid,"clear all;\n"); fprintf(fid,"close all;\n\n"); for (i=0; i<num_samples; i++) { fprintf(fid," x(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(x[i]), cimagf(x[i])); fprintf(fid," y(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(y[i]), cimagf(y[i])); fprintf(fid,"rssi(%4u) = %12.4e;\n", i+1, rssi[i]); } fprintf(fid,"\n\n"); fprintf(fid,"n = length(x);\n"); fprintf(fid,"t = 0:(n-1);\n"); fprintf(fid,"figure('position',[100 100 800 600]);\n"); fprintf(fid,"subplot(2,1,1);\n"); fprintf(fid," plot(t,rssi,'-k','LineWidth',2);\n"); fprintf(fid," xlabel('sample index');\n"); fprintf(fid," ylabel('rssi [dB]');\n"); fprintf(fid," grid on;\n"); fprintf(fid,"subplot(2,1,2);\n"); fprintf(fid," plot(t,real(y),t,imag(y));\n"); fprintf(fid," xlabel('sample index');\n"); fprintf(fid," ylabel('agc output');\n"); fprintf(fid," grid on;\n"); fclose(fid); printf("results written to %s\n", OUTPUT_FILENAME); printf("done.\n"); return 0; }