Exemple #1
0
static void update_status_bar(struct view_s* v, int x2, int y2)
{
	float pos[DIMS];

	for (int i = 0; i < DIMS; i++)
		pos[i] = v->pos[i];

	pos[v->xdim] = x2;
	pos[v->ydim] = y2;

	complex float val = sample(DIMS, pos, v->dims, v->strs, v->data);

	// FIXME: make sure this matches exactly the pixel
	char buf[100];
	snprintf(buf, 100, "Pos: %03d %03d Magn: %.3e Val: %+.3e%+.3ei Arg: %+.2f", x2, y2,
			cabsf(val), crealf(val), cimagf(val), cargf(val));

	gtk_entry_set_text(v->gtk_entry, buf);
}
Exemple #2
0
// estimate carrier frequency offset from S0 gains
float wlanframesync_estimate_cfo_S0(float complex * _G0a,
                                    float complex * _G0b)
{
    // compute carrier frequency offset estimate using freq. domain method
    float complex g_hat = 0.0f;
    g_hat += _G0b[40] * conjf(_G0a[40]);
    g_hat += _G0b[44] * conjf(_G0a[44]);
    g_hat += _G0b[48] * conjf(_G0a[48]);
    g_hat += _G0b[52] * conjf(_G0a[52]);
    g_hat += _G0b[56] * conjf(_G0a[56]);
    g_hat += _G0b[60] * conjf(_G0a[60]);
    //
    g_hat += _G0b[ 4] * conjf(_G0a[ 4]);
    g_hat += _G0b[ 8] * conjf(_G0a[ 8]);
    g_hat += _G0b[12] * conjf(_G0a[12]);
    g_hat += _G0b[16] * conjf(_G0a[16]);
    g_hat += _G0b[20] * conjf(_G0a[20]);
    g_hat += _G0b[24] * conjf(_G0a[24]);

    return 4.0f * cargf(g_hat) / 64.0f;
}
Exemple #3
0
float complex
cpowf(float complex a, float complex z)
{
	float complex w;
	float x, y, r, theta, absa, arga;

	x = crealf(z);
	y = cimagf(z);
	absa = cabsf(a);
	if (absa == 0.0f) {
		return (0.0f + 0.0f * I);
	}
	arga = cargf(a);
	r = powf(absa, x);
	theta = x * arga;
	if (y != 0.0f) {
		r = r * expf(-y * arga);
		theta = theta + y * logf(absa);
	}
	w = r * cosf(theta) + (r * sinf(theta)) * I;
	return w;
}
int main(int argc, char**argv)
{
   float complex z1 = 1.0 + 3.0 * I;
   printf("value = real %.2f imag %.2f\n",creal(z1),cimag(z1));
   float abs_value = cabsf(z1);
   printf("abs = %.2f\n",abs_value);
   float complex z2 =  conjf(z1); 
   printf("value = real %.2f imag %.2f\n",creal(z2),cimag(z2));
   float complex z3 =  cexpf(z1); 
   printf("value = real %.2f imag %.2f\n",creal(z3),cimag(z3));
   float complex z4 =  conj(z1); 
   printf("value = real %.2f imag %.2f\n",creal(z4),cimag(z4));
   float complex z5 =  cargf(z1); 
   printf("value = real %.2f imag %.2f\n",creal(z5),cimag(z5));
   float complex z6 = 0.5 + 0.5 * I;
   float complex z7 = 0.5 - 0.5 * I;
   float complex z8 = z6 * z7;
   printf("value = real %.2f imag %.2f\n",creal(z8),cimag(z8));
   float complex z9 = z6 / z7;
   printf("value = real %.2f imag %.2f\n",creal(z9),cimag(z9));
   return 0;
}
// iterative derivative estimation step
//  _t      :   time vector
//  _g      :   complex input
//  _n      :   size of inputs _t, _g
float liquid_unwrapcf_iterative_step(float * _t,
                                     float complex * _g_hat,
                                     unsigned int _n)
{
    // find mean of phase difference
    float dphi;
    float dphi_mean=0.0f;
    unsigned int i;
    for (i=1; i<_n; i++) {
        // unwrap phase
        dphi = cargf( _g_hat[i] * conjf(_g_hat[i-1]) );

        // constrain dphi to be in [-pi,pi)
        while ( dphi >  M_PI ) dphi -= 2*M_PI;
        while ( dphi < -M_PI ) dphi += 2*M_PI;

        dphi_mean += dphi;
    }

    dphi_mean /= (float)(_n-1);

    return dphi_mean;
}
Exemple #6
0
void fbdip(int n3, int n4, float ****in, float **dip, int nit, float eta)
/*< omnidirectional dip estimation >*/
{
	int it, i1, j1, j2;
	double  norm, s1, c1;

	for(i1=0; i1<n1*n2; i1++)
		p[0][i1] = p0;

	for (it=0; it<nit; it++)
	{
		for(i1=0; i1<n1*n2; i1++)
		{
			s1 = cimagf(p[0][i1]);
			c1 = crealf(p[0][i1]);
			u1[0][i1] = 0.0;
			u2[0][i1] = 0.0;
			u3[0][i1] = 0.0;
			for(j2=0; j2<n4; j2++)
			for(j1=0; j1<n3; j1++)
			{
				if((j1+j2)%2==0) continue;
				u1[0][i1] += 2.0*in[j2][j1][0][i1]*POW(s1, j1)*POW(c1,j2);
				u2[0][i1] += 2.0*in[j2][j1][0][i1]*j1*POW(s1, j1-1)*POW(c1,j2);
				u3[0][i1] += 2.0*in[j2][j1][0][i1]*POW(s1, j1)*j2*POW(c1,j2-1);
			}
		}

		if(verb)
		{
			for(i1=0, norm=0.0; i1<n1*n2; i1++)
				norm += (u1[0][i1]*u1[0][i1]);
			sf_warning("res1 %d %g", it+1, sqrtf(norm/n1/n2));
		}

		if(use_divn)
		{
			for(i1=0, c1=0.0, s1=0.0; i1<n1*n2; i1++)
			{
				c1 += (u2[0][i1]*u2[0][i1]);
				s1 += (u3[0][i1]*u3[0][i1]);
			}
			c1=sqrtf(c1/(n1*n2));
			s1=sqrtf(s1/(n1*n2));
			for(i1=0; i1<n1*n2; i1++)
			{
				u1[0][i1] /= c1;
				u2[0][i1] /= c1;
			}
			sf_divn(u1[0], u2[0], u4[0]);
			for(i1=0; i1<n1*n2; i1++)
			{
				u1[0][i1] *= c1/s1;
				u3[0][i1] /= s1;
			}
			sf_divn(u1[0], u3[0], u5[0]);
		}else{
			for(i1=0; i1<n1*n2; i1++)
			{
				u4[0][i1] = divn(u1[0][i1], u2[0][i1]);
				u5[0][i1] = divn(u1[0][i1], u3[0][i1]);
			}
		}
		for(i1=0; i1<n1*n2; i1++)
		{
			p[0][i1] -= eta * sf_cmplx(u5[0][i1], u4[0][i1]);
			p[0][i1] = p[0][i1]*r/(cabsf(p[0][i1])+ 1E-15);
		}

	}
	for(i1=0; i1<n1*n2; i1++)
		dip[0][i1] = atan(tan(cargf(p[0][i1])));
}
Exemple #7
0
     ld = clogl(ld);
     TEST_TRACE(C99 7.3.8.1)
     d = cabs(d);
     f = cabsf(f);
     ld = cabsl(ld);
     TEST_TRACE(C99 7.3.8.2)
     d = cpow(d, d);
     f = cpowf(f, f);
     ld = cpowl(ld, ld);
     TEST_TRACE(C99 7.3.8.3)
     d = csqrt(d);
     f = csqrtf(f);
     ld = csqrtl(ld);
     TEST_TRACE(C99 7.3.9.1)
     d = carg(d);
     f = cargf(f);
     ld = cargl(ld);
     TEST_TRACE(C99 7.3.9.2)
     d = cimag(d);
     f = cimagf(f);
     ld = cimagl(ld);
     TEST_TRACE(C99 7.3.9.3)
     d = conj(d);
     f = conjf(f);
     ld = conjl(ld);
     TEST_TRACE(C99 7.3.9.4)
     d = cproj(d);
     f = cprojf(f);
     ld = cprojl(ld);
 }
 TEST_TRACE(C99 7.3.9.5)
int main(int argc, char*argv[]) {
    srand( time(NULL) );

    // options
    float phase_offset = M_PI / 4.0f;   // phase offset
    float frequency_offset = 0.3f;      // frequency offset
    float pll_bandwidth = 0.01f;        // PLL bandwidth
    float zeta = 1/sqrtf(2.0f);         // PLL damping factor
    float K = 1000.0f;                  // PLL loop gain
    unsigned int n=512;                 // number of iterations

    int dopt;
    while ((dopt = getopt(argc,argv,"uhb:z:K:n:p:f:")) != EOF) {
        switch (dopt) {
        case 'u':
        case 'h':
            usage();
            return 0;
        case 'b':
            pll_bandwidth = atof(optarg);
            break;
        case 'z':
            zeta = atof(optarg);
            break;
        case 'K':
            K = atof(optarg);
            break;
        case 'n':
            n = atoi(optarg);
            break;
        case 'p':
            phase_offset = atof(optarg);
            break;
        case 'f':
            frequency_offset= atof(optarg);
            break;
        default:
            exit(1);
        }
    }
    unsigned int d=n/32;      // print every "d" lines

    // validate input
    if (pll_bandwidth <= 0.0f) {
        fprintf(stderr,"error: bandwidth must be greater than 0\n");
        exit(1);
    } else if (zeta <= 0.0f) {
        fprintf(stderr,"error: damping factor must be greater than 0\n");
        exit(1);
    } else if (K <= 0.0f) {
        fprintf(stderr,"error: loop gain must be greater than 0\n");
        exit(1);
    }

    // data arrays
    float complex x[n];         // input complex sinusoid
    float complex y[n];         // output complex sinusoid
    float phase_error[n];       // output phase error

    // generate PLL filter
    float b[3];
    float a[3];
    iirdes_pll_active_lag(pll_bandwidth, zeta, K, b, a);
    iirfilt_rrrf pll = iirfilt_rrrf_create(b,3,a,3);
    iirfilt_rrrf_print(pll);

    unsigned int i;
    float phi;
    for (i=0; i<n; i++) {
        phi = phase_offset + i*frequency_offset;
        x[i] = cexpf(_Complex_I*phi);
    }

    // run loop
    float theta = 0.0f;
    y[0] = 1.0f;
    for (i=0; i<n; i++) {

        // generate complex sinusoid
        y[i] = cexpf(_Complex_I*theta);

        // compute phase error
        phase_error[i] = cargf(x[i]*conjf(y[i]));

        // update pll
        iirfilt_rrrf_execute(pll, phase_error[i], &theta);

        // print phase error
        if ((i)%d == 0 || i==n-1 || i==0)
            printf("%4u : phase error = %12.8f\n", i, phase_error[i]);
    }

    // destroy filter object
    iirfilt_rrrf_destroy(pll);

    // write output file
    FILE * fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME);
    fprintf(fid,"clear all;\n");
    fprintf(fid,"close all;\n");
    fprintf(fid,"n = %u;\n", n);
    fprintf(fid,"x = zeros(1,n);\n");
    fprintf(fid,"y = zeros(1,n);\n");
    for (i=0; i<n; 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,"e(%4u) = %12.4e;\n", i+1, phase_error[i]);
    }
    fprintf(fid,"t=0:(n-1);\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"subplot(2,1,1);\n");
    fprintf(fid,"  plot(t,real(x),t,real(y));\n");
    fprintf(fid,"  xlabel('time');\n");
    fprintf(fid,"  ylabel('real');\n");
    fprintf(fid,"subplot(2,1,2);\n");
    fprintf(fid,"  plot(t,imag(x),t,imag(y));\n");
    fprintf(fid,"  xlabel('time');\n");
    fprintf(fid,"  ylabel('imag');\n");

    fprintf(fid,"figure;\n");
    fprintf(fid,"plot(t,e);\n");
    fprintf(fid,"xlabel('time');\n");
    fprintf(fid,"ylabel('phase error');\n");
    fprintf(fid,"grid on;\n");

    fclose(fid);
    printf("results written to %s.\n",OUTPUT_FILENAME);

    printf("done.\n");
    return 0;
}
Exemple #9
0
int main() {
    // parameters
    float phase_offset      = 0.8f;     // carrier phase offset
    float frequency_offset  = 0.01f;    // carrier frequency offset
    float wn                = 0.05f;    // pll bandwidth
    float zeta              = 0.707f;   // pll damping factor
    float K                 = 1000;     // pll loop gain
    unsigned int n          = 256;      // number of samples
    unsigned int d          = n/32;     // print every "d" lines

    //
    float theta[n];         // input phase
    float complex x[n];     // input sinusoid
    float phi[n];           // output phase
    float complex y[n];     // output sinusoid

    // generate iir loop filter object
    iirfilt_rrrf H = iirfilt_rrrf_create_pll(wn, zeta, K);
    iirfilt_rrrf_print(H);

    unsigned int i;

    // generate input
    float t=phase_offset;
    float dt = frequency_offset;
    for (i=0; i<n; i++) {
        theta[i] = t;
        x[i] = cexpf(_Complex_I*theta[i]);

        t += dt;
    }

    // run loop
    float phi_hat=0.0f;
    for (i=0; i<n; i++) {
        y[i] = cexpf(_Complex_I*phi_hat);

        // compute error
        float e = cargf(x[i]*conjf(y[i]));

        if ( (i%d)==0 )
            printf("e(%3u) = %12.8f;\n", i, e);

        // filter error
        iirfilt_rrrf_execute(H,e,&phi_hat);

        phi[i] = phi_hat;
    }

    // destroy filter
    iirfilt_rrrf_destroy(H);

    // open output file
    FILE * fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"clear all;\n");
    fprintf(fid,"n=%u;\n",n);

    for (i=0; i<n; i++) {
        fprintf(fid,"theta(%3u) = %16.8e;\n", i+1, theta[i]);
        fprintf(fid,"  phi(%3u) = %16.8e;\n", i+1, phi[i]);
    }
    fprintf(fid,"t=0:(n-1);\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"plot(t,theta,t,phi);\n");
    fprintf(fid,"xlabel('sample index');\n");
    fprintf(fid,"ylabel('phase');\n");

    fclose(fid);

    printf("output written to %s.\n", OUTPUT_FILENAME);

    printf("done.\n");
    return 0;
}
Exemple #10
0
// complex logarithm
float complex liquid_clogf(float complex _z)
{
    return logf(cabsf(_z)) + _Complex_I*cargf(_z);
}
Exemple #11
0
void ofdmframesync_execute_S1(ofdmframesync _q)
{
    _q->timer--;

    if (_q->timer > 0)
        return;

    // increment number of symbols observed
    _q->num_symbols++;

    // run fft
    float complex * rc;
    windowcf_read(_q->input_buffer, &rc);

    // estimate S1 gain
    // TODO : add backoff in gain estimation
    ofdmframesync_estimate_gain_S1(_q, &rc[_q->cp_len], _q->G);

    // compute detector output
    float complex g_hat = 0.0f;
    unsigned int i;
    for (i=0; i<_q->M; i++) {
        //g_hat += _q->G[(i+1+_q->M)%_q->M]*conjf(_q->G[(i+_q->M)%_q->M]);
        g_hat += _q->G[(i+1)%_q->M]*conjf(_q->G[i]);
    }
    g_hat /= _q->M_S1; // normalize output
    g_hat *= _q->g0;

    // rotate by complex phasor relative to timing backoff
    g_hat *= liquid_cexpjf((float)(_q->backoff)*2.0f*M_PI/(float)(_q->M));

#if DEBUG_OFDMFRAMESYNC_PRINT
    printf("    g_hat   :   %12.4f <%12.8f>\n", cabsf(g_hat), cargf(g_hat));
#endif

    // check conditions for g_hat:
    //  1. magnitude should be large (near unity) when aligned
    //  2. phase should be very near zero (time aligned)
    if (cabsf(g_hat) > _q->plcp_sync_thresh && fabsf(cargf(g_hat)) < 0.1f*M_PI ) {
        //printf("    acquisition\n");
        _q->state = OFDMFRAMESYNC_STATE_RXSYMBOLS;
        // reset timer
        _q->timer = _q->M + _q->cp_len + _q->backoff;
        _q->num_symbols = 0;

        // normalize gain by subcarriers, apply timing backoff correction
        float g = (float)(_q->M) / sqrtf(_q->M_pilot + _q->M_data);
        for (i=0; i<_q->M; i++) {
            _q->G[i] *= g;          // gain due to relative subcarrier allocation
            _q->G[i] *= _q->B[i];   // timing backoff correction
        }

#if 0
        // TODO : choose number of taps more appropriately
        //unsigned int ntaps = _q->M / 4;
        unsigned int ntaps = (_q->M < 8) ? 2 : 8;
        // FIXME : this is by far the most computationally complex part of synchronization
        ofdmframesync_estimate_eqgain(_q, ntaps);
#else
        unsigned int poly_order = 4;
        if (poly_order >= _q->M_pilot + _q->M_data)
            poly_order = _q->M_pilot + _q->M_data - 1;
        ofdmframesync_estimate_eqgain_poly(_q, poly_order);
#endif

#if 1
        // compute composite gain
        unsigned int i;
        for (i=0; i<_q->M; i++)
            _q->R[i] = _q->B[i] / _q->G[i];
#endif

        return;
#if 0
        printf("exiting prematurely\n");
        ofdmframesync_destroy(_q);
        exit(1);
#endif
    }

    // check if we are stuck searching for the S1 symbol
    if (_q->num_symbols == 16) {
#if DEBUG_OFDMFRAMESYNC_PRINT
        printf("could not find S1 symbol. bailing...\n");
#endif
        ofdmframesync_reset(_q);
    }

    // 'reset' timer (wait another half symbol)
    _q->timer = _q->M2;
}
Exemple #12
0
// recover symbol, correcting for gain, pilot phase, etc.
void ofdmframesync_rxsymbol(ofdmframesync _q)
{
    // apply gain
    unsigned int i;
    for (i=0; i<_q->M; i++)
        _q->X[i] *= _q->R[i];

    // polynomial curve-fit
    float x_phase[_q->M_pilot];
    float y_phase[_q->M_pilot];
    float p_phase[2];

    unsigned int n=0;
    unsigned int k;
    float complex pilot = 1.0f;
    for (i=0; i<_q->M; i++) {

        // start at mid-point (effective fftshift)
        k = (i + _q->M2) % _q->M;

        if (_q->p[k]==OFDMFRAME_SCTYPE_PILOT) {
            if (n == _q->M_pilot) {
                fprintf(stderr,"warning: ofdmframesync_rxsymbol(), pilot subcarrier mismatch\n");
                return;
            }
            pilot = (msequence_advance(_q->ms_pilot) ? 1.0f : -1.0f);
#if 0
            printf("pilot[%3u] = %12.4e + j*%12.4e (expected %12.4e + j*%12.4e)\n",
                    k,
                    crealf(_q->X[k]), cimagf(_q->X[k]),
                    crealf(pilot),    cimagf(pilot));
#endif
            // store resulting...
            x_phase[n] = (k > _q->M2) ? (float)k - (float)(_q->M) : (float)k;
            y_phase[n] = cargf(_q->X[k]*conjf(pilot));

            // update counter
            n++;

        }
    }

    if (n != _q->M_pilot) {
        fprintf(stderr,"warning: ofdmframesync_rxsymbol(), pilot subcarrier mismatch\n");
        return;
    }

    // try to unwrap phase
    for (i=1; i<_q->M_pilot; i++) {
        while ((y_phase[i] - y_phase[i-1]) >  M_PI)
            y_phase[i] -= 2*M_PI;
        while ((y_phase[i] - y_phase[i-1]) < -M_PI)
            y_phase[i] += 2*M_PI;
    }

    // fit phase to 1st-order polynomial (2 coefficients)
    polyf_fit(x_phase, y_phase, _q->M_pilot, p_phase, 2);

    // filter slope estimate (timing offset)
    float alpha = 0.3f;
    p_phase[1] = alpha*p_phase[1] + (1-alpha)*_q->p1_prime;
    _q->p1_prime = p_phase[1];

#if DEBUG_OFDMFRAMESYNC
    if (_q->debug_enabled) {
        // save pilots
        memmove(_q->px, x_phase, _q->M_pilot*sizeof(float));
        memmove(_q->py, y_phase, _q->M_pilot*sizeof(float));

        // NOTE : swapping values for octave
        _q->p_phase[0] = p_phase[1];
        _q->p_phase[1] = p_phase[0];

        windowf_push(_q->debug_pilot_0, p_phase[0]);
        windowf_push(_q->debug_pilot_1, p_phase[1]);
    }
#endif

    // compensate for phase offset
    // TODO : find more computationally efficient way to do this
    for (i=0; i<_q->M; i++) {
        // only apply to data/pilot subcarriers
        if (_q->p[i] == OFDMFRAME_SCTYPE_NULL) {
            _q->X[i] = 0.0f;
        } else {
            float fx    = (i > _q->M2) ? (float)i - (float)(_q->M) : (float)i;
            float theta = polyf_val(p_phase, 2, fx);
            _q->X[i] *= liquid_cexpjf(-theta);
        }
    }

    // adjust NCO frequency based on differential phase
    if (_q->num_symbols > 0) {
        // compute phase error (unwrapped)
        float dphi_prime = p_phase[0] - _q->phi_prime;
        while (dphi_prime >  M_PI) dphi_prime -= M_2_PI;
        while (dphi_prime < -M_PI) dphi_prime += M_2_PI;

        // adjust NCO proportionally to phase error
        nco_crcf_adjust_frequency(_q->nco_rx, 1e-3f*dphi_prime);
    }
    // set internal phase state
    _q->phi_prime = p_phase[0];
    //printf("%3u : theta : %12.8f, nco freq: %12.8f\n", _q->num_symbols, p_phase[0], nco_crcf_get_frequency(_q->nco_rx));
    
    // increment symbol counter
    _q->num_symbols++;

#if 0
    for (i=0; i<_q->M_pilot; i++)
        printf("x_phase(%3u) = %12.8f; y_phase(%3u) = %12.8f;\n", i+1, x_phase[i], i+1, y_phase[i]);
    printf("poly : p0=%12.8f, p1=%12.8f\n", p_phase[0], p_phase[1]);
#endif
}
Exemple #13
0
void wlanframesync_execute_rxlong1(wlanframesync _q)
{
    _q->timer++;
    if (_q->timer < 64)
        return;

    // run fft
    float complex * rc;
    windowcf_read(_q->input_buffer, &rc);

    // estimate S1 gain, adding backoff in gain estimation
    wlanframesync_estimate_gain_S1(_q, &rc[16-2], _q->G1b);

    // compute S1 metrics
    float complex s_hat;
    wlanframesync_S1_metrics(_q, _q->G1b, &s_hat);
    s_hat *= _q->g0;    // scale output by raw gain estimate

    // rotate by complex phasor relative to timing backoff
    //s_hat *= cexpf(_Complex_I * 2.0f * 2.0f * M_PI / 64.0f);
    s_hat *= cexpf(_Complex_I * 0.19635f);

    // save second 'long' symbol statistic
    _q->s1b_hat = s_hat;

    // rotate by complex phasor relative to timing backoff
    //s_hat *= liquid_cexpjf((float)(_q->backoff)*2.0f*M_PI/(float)(_q->M));

#if DEBUG_WLANFRAMESYNC_PRINT
    printf("    s_hat   :   %12.8f <%12.8f>\n", cabsf(s_hat), cargf(s_hat));
#endif

    // check conditions for s_hat
    float s_hat_abs = cabsf(s_hat);
    float s_hat_arg = cargf(s_hat);
    if (s_hat_arg >  M_PI) s_hat_arg -= 2.0f*M_PI;
    if (s_hat_arg < -M_PI) s_hat_arg += 2.0f*M_PI;
        
    // check conditions for s_hat:
    //  1. magnitude should be large (near unity) when aligned
    //  2. phase should be very near zero (time aligned)
    if (s_hat_abs        > WLANFRAMESYNC_S1B_ABS_THRESH &&
        fabsf(s_hat_arg) < WLANFRAMESYNC_S1B_ARG_THRESH)
    {
#if DEBUG_WLANFRAMESYNC_PRINT
        printf("    acquisition S1[b]\n");
#endif
        
        // refine CFO estimate with G1a, G1b and adjust NCO appropriately
        float nu_hat = wlanframesync_estimate_cfo_S1(_q->G1a, _q->G1b);
        nco_crcf_adjust_frequency(_q->nco_rx, nu_hat);
#if DEBUG_WLANFRAMESYNC_PRINT
        printf("   nu_hat[1]:   %12.8f\n", nu_hat);
#endif
        // TODO : de-rotate S1b by phase offset (help with equalizer)

        // estimate equalizer with G1a, G1b
        wlanframesync_estimate_eqgain_poly(_q);
        
        // set state
        _q->state = WLANFRAMESYNC_STATE_RXLONG1;

        // reset timer
        _q->timer = 0;
    }

    // set state
    _q->state = WLANFRAMESYNC_STATE_RXSIGNAL;

    // reset timer
    _q->timer = 0;

}
Exemple #14
0
float complex sandbox_clogf(float complex _z)
{
    return logf(cabsf(_z)) + _Complex_I*cargf(_z);
}
Exemple #15
0
int main(int argc, char*argv[])
{
    // options
    unsigned int m           =   3;     // number of bits/symbol
    unsigned int k           =   0;     // filter samples/symbol
    unsigned int num_symbols = 200;     // number of data symbols
    float        SNRdB       = 40.0f;   // signal-to-noise ratio [dB]
    float        cfo         = 0.0f;    // carrier frequency offset
    float        cpo         = 0.0f;    // carrier phase offset
    float        tau         = 0.0f;    // fractional symbol timing offset
    float        bandwidth   = 0.20;    // frequency spacing

    int dopt;
    while ((dopt = getopt(argc,argv,"hm:k:b:n:s:F:P:T:")) != EOF) {
        switch (dopt) {
        case 'h': usage();                      return 0;
        case 'm': m           = atoi(optarg);   break;
        case 'k': k           = atoi(optarg);   break;
        case 'b': bandwidth   = atof(optarg);   break;
        case 'n': num_symbols = atoi(optarg);   break;
        case 's': SNRdB       = atof(optarg);   break;
        case 'F': cfo         = atof(optarg);   break;
        case 'P': cpo         = atof(optarg);   break;
        case 'T': tau         = atof(optarg);   break;
        default:
            exit(1);
        }
    }

    unsigned int i;
    unsigned int j;

    // derived values
    if (k == 0) k = 2 << m; // set samples per symbol if not otherwise specified
    unsigned int num_samples = k*num_symbols;
    unsigned int M           = 1 << m;
    float        nstd        = powf(10.0f, -SNRdB/20.0f);
    float        M2          = 0.5f*(float)(M-1);

    // validate input
    if (k < M) {
        fprintf(stderr,"errors: %s, samples/symbol must be at least modulation size (M=%u)\n", __FILE__,M);
        exit(1);
    } else if (k > 2048) {
        fprintf(stderr,"errors: %s, samples/symbol exceeds maximum (2048)\n", __FILE__);
        exit(1);
    } else if (M > 1024) {
        fprintf(stderr,"errors: %s, modulation size (M=%u) exceeds maximum (1024)\n", __FILE__, M);
        exit(1);
    } else if (bandwidth <= 0.0f || bandwidth >= 0.5f) {
        fprintf(stderr,"errors: %s, bandwidht must be in (0,0.5)\n", __FILE__);
        exit(1);
    }

    // compute demodulation FFT size such that FFT output bin frequencies are
    // as close to modulated frequencies as possible
    unsigned int K = 0;                 // demodulation FFT size
    float        df = bandwidth / M2;   // frequency spacing
    float        err_min = 1e9f;
    unsigned int K_min = k;                     // minimum FFT size
    unsigned int K_max = k*4 < 16 ? 16 : k*4;   // maximum FFT size
    unsigned int K_hat;
    for (K_hat=K_min; K_hat<=K_max; K_hat++) {
        // compute candidate FFT size
        float v     = 0.5f*df * (float)K_hat;   // bin spacing
        float err = fabsf( roundf(v) - v );     // fractional bin spacing

        // print results
        printf("  K_hat = %4u : v = %12.8f, err=%12.8f %s\n", K_hat, v, err, err < err_min ? "*" : "");

        // save best result
        if (K_hat==K_min || err < err_min) {
            K = K_hat;
            err_min = err;
        }

        // perfect match; no need to continue searching
        if (err < 1e-6f)
            break;
    }

    // arrays
    unsigned int  sym_in[num_symbols];      // input symbols
    float complex x[num_samples];           // transmitted signal
    float complex y[num_samples];           // received signal
    unsigned int  sym_out[num_symbols];     // output symbols

    // determine demodulation mapping between tones and frequency bins
    // TODO: use gray coding
    unsigned int demod_map[M];
    for (i=0; i<M; i++) {
        // print frequency bins
        float freq = ((float)i - M2) * bandwidth / M2;
        float idx  = freq * (float)K;
        unsigned int index = (unsigned int) (idx < 0 ? roundf(idx + K) : roundf(idx));
        demod_map[i] = index;
        printf("  s=%3u, f = %12.8f, index=%3u\n", i, freq, index);
    }

    // check for uniqueness
    for (i=1; i<M; i++) {
        if (demod_map[i] == demod_map[i-1]) {
            fprintf(stderr,"warning: demod map is not unique; consider increasing bandwidth\n");
            break;
        }
    }

    // generate message symbols and modulate
    // TODO: use gray coding
    for (i=0; i<num_symbols; i++) {
        // generate random symbol
        sym_in[i] = rand() % M;

        // compute frequency
        float dphi = 2*M_PI*((float)sym_in[i] - M2) * bandwidth / M2;

        // generate random phase
        float phi  = randf() * 2 * M_PI;
        
        // modulate symbol
        for (j=0; j<k; j++)
            x[i*k+j] = cexpf(_Complex_I*phi + _Complex_I*j*dphi);
    }

    // push through channel
    for (i=0; i<num_samples; i++)
        y[i] = x[i] + nstd*(randnf() + _Complex_I*randnf())*M_SQRT1_2;

#if 0
    // demodulate signal: high SNR method
    float complex buf_time[k];
    unsigned int n = 0;
    j = 0;
    for (i=0; i<num_samples; i++) {
        // start filling time buffer with samples (assume perfect symbol timing)
        buf_time[n++] = y[i];

        // demodulate symbol
        if (n==k) {
            // reset counter
            n = 0;

            // estimate frequency
            float complex metric = 0;
            unsigned int s;
            for (s=1; s<k; s++)
                metric += buf_time[s] * conjf(buf_time[s-1]);
            float dphi_hat = cargf(metric) / (2*M_PI);
            unsigned int v=( (unsigned int) roundf(dphi_hat*M2/bandwidth + M2) ) % M;
            sym_out[j++] = v;
            printf("%3u : %12.8f : %u\n", j, dphi_hat, v);
        }
    }
#else
    // demodulate signal: least-squares method
    float complex buf_time[K];
    float complex buf_freq[K];
    fftplan fft = fft_create_plan(K, buf_time, buf_freq, LIQUID_FFT_FORWARD, 0);

    for (i=0; i<K; i++)
        buf_time[i] = 0.0f;
    unsigned int n = 0;
    j = 0;
    for (i=0; i<num_samples; i++) {
        // start filling time buffer with samples (assume perfect symbol timing)
        buf_time[n++] = y[i];

        // demodulate symbol
        if (n==k) {
            // reset counter
            n = 0;

            // compute transform, storing result in 'buf_freq'
            fft_execute(fft);

            // find maximum by looking at particular bins
            float vmax = 0;
            unsigned int s;
            unsigned int s_opt = 0;
            for (s=0; s<M; s++) {
                float v = cabsf( buf_freq[demod_map[s]] );
                if (s==0 || v > vmax) {
                    s_opt = s;
                    vmax  =v;
                }
            }

            // save best result
            sym_out[j++] = s_opt;
        }
    }
    // destroy fft object
    fft_destroy_plan(fft);
#endif

    // count errors
    unsigned int num_symbol_errors = 0;
    for (i=0; i<num_symbols; i++)
        num_symbol_errors += (sym_in[i] == sym_out[i]) ? 0 : 1;

    printf("symbol errors: %u / %u\n", num_symbol_errors, num_symbols);

    // compute power spectral density of received signal
    unsigned int nfft = 1200;
    float psd[nfft];
    spgramcf_estimate_psd(nfft, y, num_samples, psd);

    // 
    // export results
    //
    
    // truncate to at most 10 symbols
    if (num_symbols > 10)
        num_symbols = 10;
    num_samples = k*num_symbols;
    FILE * fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME);
    fprintf(fid,"clear all\n");
    fprintf(fid,"close all\n");
    fprintf(fid,"k = %u;\n", k);
    fprintf(fid,"M = %u;\n", M);
    fprintf(fid,"num_symbols = %u;\n", num_symbols);
    fprintf(fid,"num_samples = %u;\n", num_samples);
    fprintf(fid,"nfft        = %u;\n", nfft);

    fprintf(fid,"x   = zeros(1,num_samples);\n");
    fprintf(fid,"y   = zeros(1,num_samples);\n");
    for (i=0; i<num_samples; i++) {
        fprintf(fid,"x(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(x[i]), cimagf(x[i]));
        fprintf(fid,"y(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(y[i]), cimagf(y[i]));
    }
    // save power spectral density
    fprintf(fid,"psd = zeros(1,nfft);\n");
    for (i=0; i<nfft; i++)
        fprintf(fid,"psd(%4u) = %12.8f;\n", i+1, psd[i]);

    fprintf(fid,"t=[0:(num_samples-1)]/k;\n");
    fprintf(fid,"i = 1:k:num_samples;\n");
    fprintf(fid,"figure;\n");

    // plot time signal
    fprintf(fid,"subplot(2,1,1),\n");
    fprintf(fid,"hold on;\n");
    fprintf(fid,"  plot(t,real(y),'-', 'Color',[0 0.3 0.5]);\n");
    fprintf(fid,"  plot(t,imag(y),'-', 'Color',[0 0.5 0.3]);\n");
    fprintf(fid,"hold off;\n");
    fprintf(fid,"ymax = ceil(max(abs(y))*5)/5;\n");
    fprintf(fid,"axis([0 num_symbols -ymax ymax]);\n");
    fprintf(fid,"xlabel('time');\n");
    fprintf(fid,"ylabel('x(t)');\n");
    fprintf(fid,"grid on;\n");

    // plot PSD
    fprintf(fid,"subplot(2,1,2),\n");
    fprintf(fid,"f = [0:(nfft-1)]/nfft - 0.5;\n");
    fprintf(fid,"plot(f,psd,'LineWidth',1.5,'Color',[0.5 0 0]);\n");
    fprintf(fid,"axis([-0.5 0.5 -40 40]);\n");
    fprintf(fid,"xlabel('Normalized Frequency [f/F_s]');\n");
    fprintf(fid,"ylabel('PSD [dB]');\n");
    fprintf(fid,"grid on;\n");

    fclose(fid);
    printf("results written to '%s'\n", OUTPUT_FILENAME);

    return 0;
}
Exemple #16
0
// frame detection
void wlanframesync_execute_seekplcp(wlanframesync _q)
{
    _q->timer++;

    // TODO : only check every 100 - 150 (decimates/reduced complexity)
    if (_q->timer < 64)
        return;

    // reset timer
    _q->timer = 0;

    // read contents of input buffer
    float complex * rc;
    windowcf_read(_q->input_buffer, &rc);
    
    // estimate gain
    // TODO : use gain from result of FFT
    unsigned int i;
    float g = 0.0f;
    for (i=16; i<80; i+=4) {
        // compute |rc[i]|^2 efficiently
        g += crealf(rc[i  ])*crealf(rc[i  ]) + cimagf(rc[i  ])*cimagf(rc[i  ]);
        g += crealf(rc[i+1])*crealf(rc[i+1]) + cimagf(rc[i+1])*cimagf(rc[i+1]);
        g += crealf(rc[i+2])*crealf(rc[i+2]) + cimagf(rc[i+2])*cimagf(rc[i+2]);
        g += crealf(rc[i+3])*crealf(rc[i+3]) + cimagf(rc[i+3])*cimagf(rc[i+3]);
    }
    g = 64.0f / (g + 1e-12f);
    
    // save gain (permits dynamic invocation of get_rssi() method)
    _q->g0 = g;

    // estimate S0 gain
    wlanframesync_estimate_gain_S0(_q, &rc[16], _q->G0a);
    
    // compute S0 metrics
    float complex s_hat;
    wlanframesync_S0_metrics(_q, _q->G0a, &s_hat);
    s_hat *= g;

    float tau_hat  = cargf(s_hat) * (float)(16.0f) / (2*M_PI);
#if DEBUG_WLANFRAMESYNC_PRINT
    printf(" - gain=%12.3f, rssi=%8.2f dB, s_hat=%12.4f <%12.8f>, tau_hat=%8.3f\n",
            sqrt(g),
            -10*log10(g),
            cabsf(s_hat), cargf(s_hat),
            tau_hat);
#endif

    // 
    if (cabsf(s_hat) > WLANFRAMESYNC_S0A_ABS_THRESH) {

        int dt = (int)roundf(tau_hat);
        // set timer appropriately...
        _q->timer = (16 + dt) % 16;
        //_q->timer += 32; // add delay to help ensure good S0 estimate (multiple of 16)
        _q->state = WLANFRAMESYNC_STATE_RXSHORT0;

#if DEBUG_WLANFRAMESYNC_PRINT
        printf("********** frame detected! ************\n");
        printf("    s_hat   :   %12.8f <%12.8f>\n", cabsf(s_hat), cargf(s_hat));
        printf("  tau_hat   :   %12.8f\n", tau_hat);
        printf("    dt      :   %12d\n", dt);
        printf("    timer   :   %12u\n", _q->timer);
#endif
    }

}
int main(int argc, char*argv[]) {
    // options
    unsigned int k  = 8;        // filter samples/symbol
    unsigned int bps= 1;        // number of bits/symbol
    float h         = 0.5f;     // modulation index (h=1/2 for MSK)
    unsigned int num_data_symbols = 20; // number of data symbols
    float SNRdB     = 80.0f;    // signal-to-noise ratio [dB]
    float cfo       = 0.0f;     // carrier frequency offset
    float cpo       = 0.0f;     // carrier phase offset
    float tau       = 0.0f;     // fractional symbol offset
    enum {
        TXFILT_SQUARE=0,
        TXFILT_RCOS_FULL,
        TXFILT_RCOS_HALF,
        TXFILT_GMSK,
    } tx_filter_type = TXFILT_SQUARE;
    float gmsk_bt = 0.35f;              // GMSK bandwidth-time factor

    int dopt;
    while ((dopt = getopt(argc,argv,"ht:k:b:H:B:n:s:F:P:T:")) != EOF) {
        switch (dopt) {
        case 'h': usage();                         return 0;
        case 't':
            if (strcmp(optarg,"square")==0) {
                tx_filter_type = TXFILT_SQUARE;
            } else if (strcmp(optarg,"rcos-full")==0) {
                tx_filter_type = TXFILT_RCOS_FULL;
            } else if (strcmp(optarg,"rcos-half")==0) {
                tx_filter_type = TXFILT_RCOS_HALF;
            } else if (strcmp(optarg,"gmsk")==0) {
                tx_filter_type = TXFILT_GMSK;
            } else {
                fprintf(stderr,"error: %s, unknown filter type '%s'\n", argv[0], optarg);
                exit(1);
            }
            break;
        case 'k': k = atoi(optarg);                break;
        case 'b': bps = atoi(optarg);              break;
        case 'H': h = atof(optarg);                break;
        case 'B': gmsk_bt = atof(optarg);          break;
        case 'n': num_data_symbols = atoi(optarg); break;
        case 's': SNRdB = atof(optarg);            break;
        case 'F': cfo   = atof(optarg);            break;
        case 'P': cpo   = atof(optarg);            break;
        case 'T': tau   = atof(optarg);            break;
        default:
            exit(1);
        }
    }

    unsigned int i;

    // derived values
    unsigned int num_symbols = num_data_symbols;
    unsigned int num_samples = k*num_symbols;
    unsigned int M = 1 << bps;              // constellation size
    float nstd = powf(10.0f, -SNRdB/20.0f);

    // arrays
    unsigned char sym_in[num_symbols];      // input symbols
    float phi[num_samples];                 // transmitted phase
    float complex x[num_samples];           // transmitted signal
    float complex y[num_samples];           // received signal
    float complex z[num_samples];           // output...
    //unsigned char sym_out[num_symbols];     // output symbols

    unsigned int ht_len = 0;
    unsigned int tx_delay = 0;
    float * ht = NULL;
    switch (tx_filter_type) {
    case TXFILT_SQUARE:
        // regular MSK
        ht_len = k;
        tx_delay = 1;
        ht = (float*) malloc(ht_len *sizeof(float));
        for (i=0; i<ht_len; i++)
            ht[i] = h * M_PI / (float)k;
        break;
    case TXFILT_RCOS_FULL:
        // full-response raised-cosine pulse
        ht_len = k;
        tx_delay = 1;
        ht = (float*) malloc(ht_len *sizeof(float));
        for (i=0; i<ht_len; i++)
            ht[i] = h * M_PI / (float)k * (1.0f - cosf(2.0f*M_PI*i/(float)ht_len));
        break;
    case TXFILT_RCOS_HALF:
        // partial-response raised-cosine pulse
        ht_len = 3*k;
        tx_delay = 2;
        ht = (float*) malloc(ht_len *sizeof(float));
        for (i=0; i<ht_len; i++)
            ht[i] = 0.0f;
        for (i=0; i<2*k; i++)
            ht[i+k/2] = h * 0.5f * M_PI / (float)k * (1.0f - cosf(2.0f*M_PI*i/(float)(2*k)));
        break;
    case TXFILT_GMSK:
        ht_len = 2*k*3+1+k;
        tx_delay = 4;
        ht = (float*) malloc(ht_len *sizeof(float));
        for (i=0; i<ht_len; i++)
            ht[i] = 0.0f;
        liquid_firdes_gmsktx(k,3,gmsk_bt,0.0f,&ht[k/2]);
        for (i=0; i<ht_len; i++)
            ht[i] *= h * 2.0f / (float)k;
        break;
    default:
        fprintf(stderr,"error: %s, invalid tx filter type\n", argv[0]);
        exit(1);
    }
    for (i=0; i<ht_len; i++)
        printf("ht(%3u) = %12.8f;\n", i+1, ht[i]);
    firinterp_rrrf interp_tx = firinterp_rrrf_create(k, ht, ht_len);

    // generate symbols and interpolate
    // phase-accumulating filter (trapezoidal integrator)
    float b[2] = {0.5f,  0.5f};
    if (tx_filter_type == TXFILT_SQUARE) {
        // square filter: rectangular integration with one sample of delay
        b[0] = 0.0f;
        b[1] = 1.0f;
    }
    float a[2] = {1.0f, -1.0f};
    iirfilt_rrrf integrator = iirfilt_rrrf_create(b,2,a,2);
    float theta = 0.0f;
    for (i=0; i<num_symbols; i++) {
        sym_in[i] = rand() % M;
        float v = 2.0f*sym_in[i] - (float)(M-1);    // +/-1, +/-3, ... +/-(M-1)
        firinterp_rrrf_execute(interp_tx, v, &phi[k*i]);

        // accumulate phase
        unsigned int j;
        for (j=0; j<k; j++) {
            iirfilt_rrrf_execute(integrator, phi[i*k+j], &theta);
            x[i*k+j] = cexpf(_Complex_I*theta);
        }
    }
    iirfilt_rrrf_destroy(integrator);

    // push through channel
    for (i=0; i<num_samples; i++) {
        // add carrier frequency/phase offset
        y[i] = x[i]*cexpf(_Complex_I*(cfo*i + cpo));

        // add noise
        y[i] += nstd*(randnf() + _Complex_I*randnf())*M_SQRT1_2;
    }
    
    // create decimator
    unsigned int m = 3;
    float bw = 0.0f;
    float beta = 0.0f;
    firfilt_crcf decim_rx = NULL;
    switch (tx_filter_type) {
    case TXFILT_SQUARE:
        //bw = 0.9f / (float)k;
        bw = 0.4f;
        decim_rx = firfilt_crcf_create_kaiser(2*k*m+1, bw, 60.0f, 0.0f);
        firfilt_crcf_set_scale(decim_rx, 2.0f * bw);
        break;
    case TXFILT_RCOS_FULL:
        if (M==2) {
            decim_rx = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,k,m,0.5f,0);
            firfilt_crcf_set_scale(decim_rx, 1.33f / (float)k);
        } else {
            decim_rx = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,k/2,2*m,0.9f,0);
            firfilt_crcf_set_scale(decim_rx, 3.25f / (float)k);
        }
        break;
    case TXFILT_RCOS_HALF:
        if (M==2) {
            decim_rx = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,k,m,0.3f,0);
            firfilt_crcf_set_scale(decim_rx, 1.10f / (float)k);
        } else {
            decim_rx = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,k/2,2*m,0.27f,0);
            firfilt_crcf_set_scale(decim_rx, 2.90f / (float)k);
        }
        break;
    case TXFILT_GMSK:
        bw = 0.5f / (float)k;
        // TODO: figure out beta value here
        beta = (M == 2) ? 0.8*gmsk_bt : 1.0*gmsk_bt;
        decim_rx = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,k,m,beta,0);
        firfilt_crcf_set_scale(decim_rx, 2.0f * bw);
        break;
    default:
        fprintf(stderr,"error: %s, invalid tx filter type\n", argv[0]);
        exit(1);
    }
    printf("bw = %f\n", bw);

    // run receiver
    unsigned int n=0;
    unsigned int num_errors = 0;
    unsigned int num_symbols_checked = 0;
    float complex z_prime = 0.0f;
    for (i=0; i<num_samples; i++) {
        // push through filter
        firfilt_crcf_push(decim_rx, y[i]);
        firfilt_crcf_execute(decim_rx, &z[i]);

        // decimate output
        if ( (i%k)==0 ) {
            // compute instantaneous frequency scaled by modulation index
            float phi_hat = cargf(conjf(z_prime) * z[i]) / (h * M_PI);

            // estimate transmitted symbol
            float v = (phi_hat + (M-1.0))*0.5f;
            unsigned int sym_out = ((int) roundf(v)) % M;

            // save current point
            z_prime = z[i];

            // print result to screen
            printf("%3u : %12.8f + j%12.8f, <f=%8.4f : %8.4f> (%1u)",
                    n, crealf(z[i]), cimagf(z[i]), phi_hat, v, sym_out);
            if (n >= m+tx_delay) {
                num_errors += (sym_out == sym_in[n-m-tx_delay]) ? 0 : 1;
                num_symbols_checked++;
                printf(" (%1u)\n", sym_in[n-m-tx_delay]);
            } else {
                printf("\n");
            }
            n++;
        }
    }

    // print number of errors
    printf("errors : %3u / %3u\n", num_errors, num_symbols_checked);

    // destroy objects
    firinterp_rrrf_destroy(interp_tx);
    firfilt_crcf_destroy(decim_rx);

    // compute power spectral density of transmitted signal
    unsigned int nfft = 1024;
    float psd[nfft];
    spgramcf periodogram = spgramcf_create_kaiser(nfft, nfft/2, 8.0f);
    spgramcf_estimate_psd(periodogram, y, num_samples, psd);
    spgramcf_destroy(periodogram);

    // 
    // export results
    //
    FILE * fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME);
    fprintf(fid,"clear all\n");
    fprintf(fid,"close all\n");
    fprintf(fid,"k = %u;\n", k);
    fprintf(fid,"h = %f;\n", h);
    fprintf(fid,"num_symbols = %u;\n", num_symbols);
    fprintf(fid,"num_samples = %u;\n", num_samples);
    fprintf(fid,"nfft        = %u;\n", nfft);
    fprintf(fid,"delay       = %u; %% receive filter delay\n", tx_delay);

    fprintf(fid,"x   = zeros(1,num_samples);\n");
    fprintf(fid,"y   = zeros(1,num_samples);\n");
    fprintf(fid,"z   = zeros(1,num_samples);\n");
    fprintf(fid,"phi = zeros(1,num_samples);\n");
    for (i=0; i<num_samples; i++) {
        fprintf(fid,"x(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(x[i]), cimagf(x[i]));
        fprintf(fid,"y(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(y[i]), cimagf(y[i]));
        fprintf(fid,"z(%4u) = %12.8f + j*%12.8f;\n", i+1, crealf(z[i]), cimagf(z[i]));
        fprintf(fid,"phi(%4u) = %12.8f;\n", i+1, phi[i]);
    }
    // save PSD
    fprintf(fid,"psd = zeros(1,nfft);\n");
    for (i=0; i<nfft; i++)
        fprintf(fid,"psd(%4u) = %12.8f;\n", i+1, psd[i]);

    fprintf(fid,"t=[0:(num_samples-1)]/k;\n");
    fprintf(fid,"i = 1:k:num_samples;\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"subplot(3,4,1:3);\n");
    fprintf(fid,"  plot(t,real(x),'-', t(i),real(x(i)),'bs','MarkerSize',4,...\n");
    fprintf(fid,"       t,imag(x),'-', t(i),imag(x(i)),'gs','MarkerSize',4);\n");
    fprintf(fid,"  axis([0 num_symbols -1.2 1.2]);\n");
    fprintf(fid,"  xlabel('time');\n");
    fprintf(fid,"  ylabel('x(t)');\n");
    fprintf(fid,"  grid on;\n");
    fprintf(fid,"subplot(3,4,5:7);\n");
    fprintf(fid,"  plot(t-delay,real(z),'-', t(i)-delay,real(z(i)),'bs','MarkerSize',4,...\n");
    fprintf(fid,"       t-delay,imag(z),'-', t(i)-delay,imag(z(i)),'gs','MarkerSize',4);\n");
    fprintf(fid,"  axis([0 num_symbols -1.2 1.2]);\n");
    fprintf(fid,"  xlabel('time');\n");
    fprintf(fid,"  ylabel('\"matched\" filter output');\n");
    fprintf(fid,"  grid on;\n");
    // plot I/Q constellations
    fprintf(fid,"subplot(3,4,4);\n");
    fprintf(fid,"  plot(real(y),imag(y),'-',real(y(i)),imag(y(i)),'rs','MarkerSize',3);\n");
    fprintf(fid,"  xlabel('I');\n");
    fprintf(fid,"  ylabel('Q');\n");
    fprintf(fid,"  axis([-1 1 -1 1]*1.2);\n");
    fprintf(fid,"  axis square;\n");
    fprintf(fid,"  grid on;\n");
    fprintf(fid,"subplot(3,4,8);\n");
    fprintf(fid,"  plot(real(z),imag(z),'-',real(z(i)),imag(z(i)),'rs','MarkerSize',3);\n");
    fprintf(fid,"  xlabel('I');\n");
    fprintf(fid,"  ylabel('Q');\n");
    fprintf(fid,"  axis([-1 1 -1 1]*1.2);\n");
    fprintf(fid,"  axis square;\n");
    fprintf(fid,"  grid on;\n");
    // plot PSD
    fprintf(fid,"f = [0:(nfft-1)]/nfft - 0.5;\n");
    fprintf(fid,"subplot(3,4,9:12);\n");
    fprintf(fid,"  plot(f,psd,'LineWidth',1.5);\n");
    fprintf(fid,"  axis([-0.5 0.5 -40 20]);\n");
    fprintf(fid,"  xlabel('Normalized Frequency [f/F_s]');\n");
    fprintf(fid,"  ylabel('PSD [dB]');\n");
    fprintf(fid,"  grid on;\n");

#if 0
    fprintf(fid,"figure;\n");
    fprintf(fid,"  %% compute instantaneous received frequency\n");
    fprintf(fid,"  freq_rx = arg( conj(z(:)) .* circshift(z(:),-1) )';\n");
    fprintf(fid,"  freq_rx(1:(k*delay)) = 0;\n");
    fprintf(fid,"  freq_rx(end) = 0;\n");
    fprintf(fid,"  %% compute instantaneous tx/rx phase\n");
    if (tx_filter_type == TXFILT_SQUARE) {
        fprintf(fid,"  theta_tx = filter([0 1],[1 -1],phi)/(h*pi);\n");
        fprintf(fid,"  theta_rx = filter([0 1],[1 -1],freq_rx)/(h*pi);\n");
    } else {
        fprintf(fid,"  theta_tx = filter([0.5 0.5],[1 -1],phi)/(h*pi);\n");
        fprintf(fid,"  theta_rx = filter([0.5 0.5],[1 -1],freq_rx)/(h*pi);\n");
    }
    fprintf(fid,"  %% plot instantaneous tx/rx phase\n");
    fprintf(fid,"  plot(t,      theta_tx,'-b', t(i),      theta_tx(i),'sb',...\n");
    fprintf(fid,"       t-delay,theta_rx,'-r', t(i)-delay,theta_rx(i),'sr');\n");
    fprintf(fid,"  xlabel('time');\n");
    fprintf(fid,"  ylabel('instantaneous phase/(h \\pi)');\n");
    fprintf(fid,"  legend('transmitted','syms','received/filtered','syms','location','northwest');\n");
    fprintf(fid,"  grid on;\n");
#else
    // plot filter response
    fprintf(fid,"ht_len = %u;\n", ht_len);
    fprintf(fid,"ht     = zeros(1,ht_len);\n");
    for (i=0; i<ht_len; i++)
        fprintf(fid,"ht(%4u) = %12.8f;\n", i+1, ht[i]);
    fprintf(fid,"gt1 = filter([0.5 0.5],[1 -1],ht) / (pi*h);\n");
    fprintf(fid,"gt2 = filter([0.0 1.0],[1 -1],ht) / (pi*h);\n");
    fprintf(fid,"tfilt = [0:(ht_len-1)]/k - delay + 0.5;\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"plot(tfilt,ht, '-x','MarkerSize',4,...\n");
    fprintf(fid,"     tfilt,gt1,'-x','MarkerSize',4,...\n");
    fprintf(fid,"     tfilt,gt2,'-x','MarkerSize',4);\n");
    fprintf(fid,"axis([tfilt(1) tfilt(end) -0.1 1.1]);\n");
    fprintf(fid,"legend('pulse','trap. int.','rect. int.','location','northwest');\n");
    fprintf(fid,"grid on;\n");
#endif

    fclose(fid);
    printf("results written to '%s'\n", OUTPUT_FILENAME);
    
    // free allocated filter memory
    free(ht);

    return 0;
}
Exemple #18
0
void
docomplexf (void)
{
#ifndef NO_FLOAT
  complex float ca, cb, cc;
  float f1;

  ca = 1.0 + 1.0 * I;
  cb = 1.0 - 1.0 * I;

  f1 = cabsf (ca);
  fprintf (stdout, "cabsf  : %f\n", f1);

  cc = cacosf (ca);
  fprintf (stdout, "cacosf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = cacoshf (ca);
  fprintf (stdout, "cacoshf: %f %fi\n", crealf (cc),
	   cimagf (cc));

  f1 = cargf (ca);
  fprintf (stdout, "cargf  : %f\n", f1);

  cc = casinf (ca);
  fprintf (stdout, "casinf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = casinhf (ca);
  fprintf (stdout, "casinhf: %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = catanf (ca);
  fprintf (stdout, "catanf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = catanhf (ca);
  fprintf (stdout, "catanhf: %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = ccosf (ca);
  fprintf (stdout, "ccosf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = ccoshf (ca);
  fprintf (stdout, "ccoshf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = cexpf (ca);
  fprintf (stdout, "cexpf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  f1 = cimagf (ca);
  fprintf (stdout, "cimagf : %f\n", f1);

  cc = clogf (ca);
  fprintf (stdout, "clogf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = conjf (ca);
  fprintf (stdout, "conjf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = cpowf (ca, cb);
  fprintf (stdout, "cpowf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = cprojf (ca);
  fprintf (stdout, "cprojf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  f1 = crealf (ca);
  fprintf (stdout, "crealf : %f\n", f1);

  cc = csinf (ca);
  fprintf (stdout, "csinf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = csinhf (ca);
  fprintf (stdout, "csinhf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = csqrtf (ca);
  fprintf (stdout, "csqrtf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = ctanf (ca);
  fprintf (stdout, "ctanf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = ctanhf (ca);
  fprintf (stdout, "ctanhf : %f %fi\n", crealf (cc),
	   cimagf (cc));
#endif
}
TEST(complex, cargf) {
  ASSERT_EQ(0.0, cargf(0));
}
Exemple #20
0
// frame detection
void ofdmframesync_execute_seekplcp(ofdmframesync _q)
{
    _q->timer++;

    if (_q->timer < _q->M)
        return;

    // reset timer
    _q->timer = 0;

    //
    float complex * rc;
    windowcf_read(_q->input_buffer, &rc);

    // estimate gain
    unsigned int i;
    float g = 0.0f;
    for (i=_q->cp_len; i<_q->M + _q->cp_len; i++) {
        // compute |rc[i]|^2 efficiently
        g += crealf(rc[i])*crealf(rc[i]) + cimagf(rc[i])*cimagf(rc[i]);
    }
    g = (float)(_q->M) / g;

#if OFDMFRAMESYNC_ENABLE_SQUELCH
    // TODO : squelch here
    if ( -10*log10f( sqrtf(g) ) < _q->squelch_threshold &&
         _q->squelch_enabled)
    {
        printf("squelch\n");
        return;
    }
#endif

    // estimate S0 gain
    ofdmframesync_estimate_gain_S0(_q, &rc[_q->cp_len], _q->G0);

    float complex s_hat;
    ofdmframesync_S0_metrics(_q, _q->G0, &s_hat);
    s_hat *= g;

    float tau_hat  = cargf(s_hat) * (float)(_q->M2) / (2*M_PI);
#if DEBUG_OFDMFRAMESYNC_PRINT
    printf(" - gain=%12.3f, rssi=%12.8f, s_hat=%12.4f <%12.8f>, tau_hat=%8.3f\n",
            sqrt(g),
            -10*log10(g),
            cabsf(s_hat), cargf(s_hat),
            tau_hat);
#endif

    // save gain (permits dynamic invocation of get_rssi() method)
    _q->g0 = g;

    // 
    if (cabsf(s_hat) > _q->plcp_detect_thresh) {

        int dt = (int)roundf(tau_hat);
        // set timer appropriately...
        _q->timer = (_q->M + dt) % (_q->M2);
        _q->timer += _q->M; // add delay to help ensure good S0 estimate
        _q->state = OFDMFRAMESYNC_STATE_PLCPSHORT0;

#if DEBUG_OFDMFRAMESYNC_PRINT
        printf("********** frame detected! ************\n");
        printf("    s_hat   :   %12.8f <%12.8f>\n", cabsf(s_hat), cargf(s_hat));
        printf("  tau_hat   :   %12.8f\n", tau_hat);
        printf("    dt      :   %12d\n", dt);
        printf("    timer   :   %12u\n", _q->timer);
#endif
        //printf("exiting prematurely\n");
        //ofdmframesync_destroy(_q);
        //exit(1);
    }

}
Exemple #21
0
int main(int argc, char*argv[])
{
    // set random seed
    srand( time(NULL) );

    // parameters
    float phase_offset     = 0.0f;      // initial phase offset
    float frequency_offset = 0.40f;     // initial frequency offset
    float pll_bandwidth    = 0.003f;    // phase-locked loop bandwidth
    unsigned int n         = 512;       // number of iterations

    int dopt;
    while ((dopt = getopt(argc,argv,"uhb:n:p:f:")) != EOF) {
        switch (dopt) {
        case 'u':
        case 'h':   usage();    return 0;
        case 'b':   pll_bandwidth = atof(optarg);   break;
        case 'n':   n = atoi(optarg);               break;
        case 'p':   phase_offset = atof(optarg);    break;
        case 'f':   frequency_offset= atof(optarg); break;
        default:
            exit(1);
        }
    }

    // objects
    nco_crcf nco_tx = nco_crcf_create(LIQUID_VCO);
    nco_crcf nco_rx = nco_crcf_create(LIQUID_VCO);

    // initialize objects
    nco_crcf_set_phase(nco_tx, phase_offset);
    nco_crcf_set_frequency(nco_tx, frequency_offset);
    nco_crcf_pll_set_bandwidth(nco_rx, pll_bandwidth);

    // generate input
    float complex x[n];
    float complex y[n];
    float phase_error[n];

    unsigned int i;
    for (i=0; i<n; i++) {
        // generate complex sinusoid
        nco_crcf_cexpf(nco_tx, &x[i]);

        // update nco
        nco_crcf_step(nco_tx);
    }

    // run loop
    for (i=0; i<n; i++) {
#if 0
        // test resetting bandwidth in middle of acquisition
        if (i == 100) nco_pll_set_bandwidth(nco_rx, pll_bandwidth*0.2f);
#endif

        // generate input
        nco_crcf_cexpf(nco_rx, &y[i]);

        // update rx nco object
        nco_crcf_step(nco_rx);

        // compute phase error
        phase_error[i] = cargf(x[i]*conjf(y[i]));

        // update pll
        nco_crcf_pll_step(nco_rx, phase_error[i]);

        // print phase error
        if ( (i+1)%50 == 0 || i==n-1 || i==0)
            printf("%4u : phase error = %12.8f\n", i+1, phase_error[i]);
    }
    nco_crcf_destroy(nco_tx);
    nco_crcf_destroy(nco_rx);

    // write output file
    FILE * fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME);
    fprintf(fid,"clear all;\n");
    fprintf(fid,"close all;\n");
    fprintf(fid,"n = %u;\n", n);
    fprintf(fid,"x = zeros(1,n);\n");
    fprintf(fid,"y = zeros(1,n);\n");
    for (i=0; i<n; 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,"e(%4u) = %12.4e;\n", i+1, phase_error[i]);
    }
    fprintf(fid,"t=0:(n-1);\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"subplot(3,1,1);\n");
    fprintf(fid,"  hold on;\n");
    fprintf(fid,"  plot(t,real(x),'Color',[1 1 1]*0.8);\n");
    fprintf(fid,"  plot(t,real(y),'Color',[0 0.2 0.5]);\n");
    fprintf(fid,"  hold off;\n");
    fprintf(fid,"  xlabel('time');\n");
    fprintf(fid,"  ylabel('real');\n");
    fprintf(fid,"  axis([0 n -1.2 1.2]);\n");
    fprintf(fid,"  grid on;\n");
    fprintf(fid,"subplot(3,1,2);\n");
    fprintf(fid,"  hold on;\n");
    fprintf(fid,"  plot(t,imag(x),'Color',[1 1 1]*0.8);\n");
    fprintf(fid,"  plot(t,imag(y),'Color',[0 0.5 0.2]);\n");
    fprintf(fid,"  hold off;\n");
    fprintf(fid,"  xlabel('time');\n");
    fprintf(fid,"  ylabel('imag');\n");
    fprintf(fid,"  axis([0 n -1.2 1.2]);\n");
    fprintf(fid,"  grid on;\n");
    fprintf(fid,"subplot(3,1,3);\n");
    fprintf(fid,"  plot(t,e,'Color',[0.5 0 0]);\n");
    fprintf(fid,"  xlabel('time');\n");
    fprintf(fid,"  ylabel('phase error');\n");
    fprintf(fid,"  axis([0 n -pi pi]);\n");
    fprintf(fid,"  grid on;\n");

    fclose(fid);
    printf("results written to %s.\n",OUTPUT_FILENAME);

    printf("done.\n");
    return 0;
}
Exemple #22
0
// frame detection
void ofdmframesync_execute_S0b(ofdmframesync _q)
{
    //printf("t = %u\n", _q->timer);
    _q->timer++;

    if (_q->timer < _q->M2)
        return;

    // reset timer
    _q->timer = _q->M + _q->cp_len - _q->backoff;

    //
    float complex * rc;
    windowcf_read(_q->input_buffer, &rc);

    // estimate S0 gain
    ofdmframesync_estimate_gain_S0(_q, &rc[_q->cp_len], _q->G1);

    float complex s_hat;
    ofdmframesync_S0_metrics(_q, _q->G1, &s_hat);
    s_hat *= _q->g0;

    _q->s_hat_1 = s_hat;

#if DEBUG_OFDMFRAMESYNC_PRINT
    float tau_hat  = cargf(s_hat) * (float)(_q->M2) / (2*M_PI);
    printf("********** S0[1] received ************\n");
    printf("    s_hat   :   %12.8f <%12.8f>\n", cabsf(s_hat), cargf(s_hat));
    printf("  tau_hat   :   %12.8f\n", tau_hat);

    // new timing offset estimate
    tau_hat  = cargf(_q->s_hat_0 + _q->s_hat_1) * (float)(_q->M2) / (2*M_PI);
    printf("  tau_hat * :   %12.8f\n", tau_hat);

    printf("**********\n");
#endif

    // re-adjust timer accordingly
    float tau_prime = cargf(_q->s_hat_0 + _q->s_hat_1) * (float)(_q->M2) / (2*M_PI);
    _q->timer -= (int)roundf(tau_prime);

#if 0
    if (cabsf(s_hat) < 0.3f) {
#if DEBUG_OFDMFRAMESYNC_PRINT
        printf("false alarm S0[1]\n");
#endif
        // false alarm
        ofdmframesync_reset(_q);
        return;
    }
#endif

    float complex g_hat = 0.0f;
    unsigned int i;
    for (i=0; i<_q->M; i++)
        g_hat += _q->G1[i] * conjf(_q->G0[i]);

#if 0
    // compute carrier frequency offset estimate using freq. domain method
    float nu_hat = 2.0f * cargf(g_hat) / (float)(_q->M);
#else
    // compute carrier frequency offset estimate using ML method
    float complex t0 = 0.0f;
    for (i=0; i<_q->M2; i++) {
        t0 += conjf(rc[i])       *       _q->s0[i] * 
                    rc[i+_q->M2] * conjf(_q->s0[i+_q->M2]);
    }
    float nu_hat = cargf(t0) / (float)(_q->M2);
#endif

#if DEBUG_OFDMFRAMESYNC_PRINT
    printf("   nu_hat   :   %12.8f\n", nu_hat);
#endif

    // set NCO frequency
    nco_crcf_set_frequency(_q->nco_rx, nu_hat);

    _q->state = OFDMFRAMESYNC_STATE_PLCPLONG;
}
Exemple #23
0
int sync_block(int blocksize, csample_t **buffers, float *timediffs, float *phasediffs) {
	int ri, i;
	if(blocksize < corrlen) return -1;
	
	for(ri = 0; ri < nreceivers; ri++) {
		csample_t *buf = buffers[ri];
		fftwf_complex *floatbuf = fft1in + ri * fft1n;
		for(i = 0; i < corrlen; i++)
			floatbuf[i] = (buf[i][0] + I*buf[i][1]) - (127.4f+127.4f*I);
	}
	fftwf_execute(fft1plan);

	for(ri = 1; ri < nreceivers; ri++) {
		/* cross correlation of receiver number ri and receiver 0 */
		fftwf_complex *f1o = fft1out + ri * fft1n;
		fftwf_complex *f2i = fft2in  + (ri-1) * fft2n;
		/* positive frequencies: */
		for(i = 0; i < fft1n/2; i++)
			f2i[i] = fft1out[i] * conjf(f1o[i]);
		/* negative frequencies: */
		f2i += fft2n - fft1n;
		for(i = fft1n/2; i < fft1n; i++)
			f2i[i] = fft1out[i] * conjf(f1o[i]);
	}
	fftwf_execute(fft2plan);
	
	timediffs[0] = 0;
	phasediffs[0] = 0;
	if(sync_debug) 
		printf("%d ",(int)time(NULL));
	for(ri = 1; ri < nreceivers; ri++) {
		fftwf_complex *f2o = fft2out  + (ri-1) * fft2n;
		float maxmagsq = 0, phasedifference;
		float timedifference = 0;
		float complex maxc = 0;
		float y1, y2, y3;
		int maxi = 1;
		for(i = 0; i < fft2n; i++) {
			float complex c = f2o[i];
			float magsq = crealf(c)*crealf(c) + cimagf(c)*cimagf(c);
			if(magsq > maxmagsq) {
				maxmagsq = magsq;
				maxc = c;
				maxi = i;
			}
		}
		/* parabolic interpolation for more fractional sample resolution
		(math from http://dspguru.com/dsp/howtos/how-to-interpolate-fft-peak ) */
		y1 = cabsf(f2o[(maxi-1 + fft2n) % fft2n]);
		y2 = cabsf(maxc);
		y3 = cabsf(f2o[(maxi+1 + fft2n) % fft2n]);
		//printf("%E %E %E   ", y1, y2, y3);

		if(maxi >= fft2n/2) maxi -= fft2n;
		timedifference = maxi;
		timedifference += (y3-y1) / (2*(2*y2-y1-y3));
		timedifference *= 1.0 / CORRELATION_OVERSAMPLE;
		timediffs[ri] = timedifference;
		
		phasediffs[ri] = phasedifference = cargf(maxc);
		if(sync_debug)
			printf("%9.2f %E %6.2f  ", timedifference, maxmagsq, 57.2957795 * phasedifference);
	}
	if(sync_debug) {
		printf("\n");
		fflush(stdout);
	}
	return 0;
}
Exemple #24
0
// estimate complex equalizer gain from G0 and G1 using polynomial fit
//  _q      :   ofdmframesync object
//  _order  :   polynomial order
void ofdmframesync_estimate_eqgain_poly(ofdmframesync _q,
                                        unsigned int _order)
{
#if DEBUG_OFDMFRAMESYNC
    if (_q->debug_enabled) {
        // copy pre-smoothed gain
        memmove(_q->G_hat, _q->G, _q->M*sizeof(float complex));
    }
#endif

    // polynomial interpolation
    unsigned int i;
    unsigned int N = _q->M_pilot + _q->M_data;
    if (_order > N-1) _order = N-1;
    if (_order > 10)  _order = 10;
    float x_freq[N];
    float y_abs[N];
    float y_arg[N];
    float p_abs[_order+1];
    float p_arg[_order+1];

    unsigned int n=0;
    unsigned int k;
    for (i=0; i<_q->M; i++) {

        // start at mid-point (effective fftshift)
        k = (i + _q->M2) % _q->M;

        if (_q->p[k] != OFDMFRAME_SCTYPE_NULL) {
            if (n == N) {
                fprintf(stderr, "error: ofdmframesync_estimate_eqgain_poly(), pilot subcarrier mismatch\n");
                exit(1);
            }
            // store resulting...
            x_freq[n] = (k > _q->M2) ? (float)k - (float)(_q->M) : (float)k;
            x_freq[n] = x_freq[n] / (float)(_q->M);
            y_abs[n] = cabsf(_q->G[k]);
            y_arg[n] = cargf(_q->G[k]);

            // update counter
            n++;
        }
    }

    if (n != N) {
        fprintf(stderr, "error: ofdmframesync_estimate_eqgain_poly(), pilot subcarrier mismatch\n");
        exit(1);
    }

    // try to unwrap phase
    for (i=1; i<N; i++) {
        while ((y_arg[i] - y_arg[i-1]) >  M_PI)
            y_arg[i] -= 2*M_PI;
        while ((y_arg[i] - y_arg[i-1]) < -M_PI)
            y_arg[i] += 2*M_PI;
    }

    // fit to polynomial
    polyf_fit(x_freq, y_abs, N, p_abs, _order+1);
    polyf_fit(x_freq, y_arg, N, p_arg, _order+1);

    // compute subcarrier gain
    for (i=0; i<_q->M; i++) {
        float freq = (i > _q->M2) ? (float)i - (float)(_q->M) : (float)i;
        freq = freq / (float)(_q->M);
        float A     = polyf_val(p_abs, _order+1, freq);
        float theta = polyf_val(p_arg, _order+1, freq);
        _q->G[i] = (_q->p[i] == OFDMFRAME_SCTYPE_NULL) ? 0.0f : A * liquid_cexpjf(theta);
    }

#if 0
    for (i=0; i<N; i++)
        printf("x(%3u) = %12.8f; y_abs(%3u) = %12.8f; y_arg(%3u) = %12.8f;\n",
                i+1, x_freq[i],
                i+1, y_abs[i],
                i+1, y_arg[i]);

    for (i=0; i<=_order; i++)
        printf("p_abs(%3u) = %12.8f;\n", i+1, p_abs[i]);
    for (i=0; i<=_order; i++)
        printf("p_arg(%3u) = %12.8f;\n", i+1, p_arg[i]);
#endif
}
Exemple #25
0
static void zarg(long N, complex float* dst, const complex float* src)
{
	for (long i = 0; i < N; i++)
		dst[i] = cargf( src[i] );
}
Exemple #26
0
// estimate complex equalizer gain from G0 and G1 using polynomial fit
void wlanframesync_estimate_eqgain_poly(wlanframesync _q)
{
    // polynomial order
    unsigned int order = 2;

    // equalizer (polynomial)
    float x_eq[52];             // frequency array
    float y_eq_abs[52];         // magnitude array
    float y_eq_arg[52];         // phase array
    float p_eq_abs[order+1];    // polynomial coefficients (magnitude)
    float p_eq_arg[order+1];    // polynomial coefficients (phase)

    // average complex gains
    unsigned int i;
    unsigned int k;
    unsigned int n=0;
    for (i=0; i<64; i++) {
        // start at mid-point (effective fftshift)
        k = (i + 32) % 64;

        if (k == 0 || (k>26 && k<38) ) {
            // NULL subcarrier
        } else {
            // validate counter
            assert(n < 52);

            // DATA/PILOT subcarrier (S1 enabled)
            //float complex G = 0.5f*(_q->G1a + _q->G1b);
            float complex G = _q->G1b[k];

            // store resulting...
            x_eq[n] = (k > 31) ? (float)k - (float)(64) : (float)k;
            x_eq[n] = x_eq[n] / (float)(64);
            y_eq_abs[n] = cabsf(G);
            y_eq_arg[n] = cargf(G);

            // update counter
            n++;
        }
    }
    
    // validate counter
    assert(n == 52);

    // try to unwrap phase
    for (i=1; i<52; i++) {
        while ((y_eq_arg[i] - y_eq_arg[i-1]) >  M_PI)
            y_eq_arg[i] -= 2*M_PI;
        while ((y_eq_arg[i] - y_eq_arg[i-1]) < -M_PI)
            y_eq_arg[i] += 2*M_PI;
    }

    // fit to polynomial(s)
    polyf_fit(x_eq, y_eq_abs, 52, p_eq_abs, order+1);
    polyf_fit(x_eq, y_eq_arg, 52, p_eq_arg, order+1);

    // compute subcarrier gain
    for (i=0; i<64; i++) {
        
        if (i == 0 || (i>26 && i<38) ) {
            // NULL subcarrier
            _q->G[i] = 0.0f;
            _q->R[i] = 0.0f;
        } else {
            // DATA/PILOT subcarrier (S1 enabled)
            float freq = (i > 31) ? (float)i - (float)(64) : (float)i;
            freq = freq / (float)(64);
            float A     = polyf_val(p_eq_abs, order+1, freq);
            float theta = polyf_val(p_eq_arg, order+1, freq);

            // composite channel estimation
            _q->G[i] = A * cexpf(_Complex_I*theta);

            // composite channel correction
            // 0.11267 = sqrt(52)/64
            _q->R[i] = 0.11267f / (A + 1e-12f) * cexpf(-_Complex_I*theta);
        }
    }

}
Exemple #27
0
int main(int argc, char **argv) {
	chest_t eq;
	cf_t *input = NULL, *ce = NULL, *h = NULL;
	refsignal_t refs;
	int i, j, n_port, n_slot, cid, num_re;
	int ret = -1;
	int max_cid;
	FILE *fmatlab = NULL;
	float mse_mag, mse_phase;

	parse_args(argc,argv);

	if (output_matlab) {
		fmatlab=fopen(output_matlab, "w");
		if (!fmatlab) {
			perror("fopen");
			goto do_exit;
		}
	}

	num_re = nof_prb * RE_X_RB * CP_NSYMB(cp);

	input = malloc(num_re * sizeof(cf_t));
	if (!input) {
		perror("malloc");
		goto do_exit;
	}
	h = malloc(num_re * sizeof(cf_t));
	if (!h) {
		perror("malloc");
		goto do_exit;
	}
	ce = malloc(num_re * sizeof(cf_t));
	if (!ce) {
		perror("malloc");
		goto do_exit;
	}

	if (cell_id == -1) {
		cid = 0;
		max_cid = 504;
	} else {
		cid = cell_id;
		max_cid = cell_id;
	}
	while(cid <= max_cid) {
		if (chest_init(&eq, LINEAR, cp, nof_prb, MAX_PORTS)) {
			fprintf(stderr, "Error initializing equalizer\n");
			goto do_exit;
		}

		if (chest_ref_LTEDL(&eq, cid)) {
			fprintf(stderr, "Error initializing reference signal\n");
			goto do_exit;
		}

		for (n_slot=0;n_slot<NSLOTS_X_FRAME;n_slot++) {
			for (n_port=0;n_port<MAX_PORTS;n_port++) {

				if (refsignal_init_LTEDL(&refs, n_port, n_slot, cid, cp, nof_prb)) {
					fprintf(stderr, "Error initiating CRS slot=%d\n", i);
					return -1;
				}

				bzero(input, sizeof(cf_t) * num_re);
				for (i=0;i<num_re;i++) {
					input[i] = 0.5-rand()/RAND_MAX+I*(0.5-rand()/RAND_MAX);
				}

				bzero(ce, sizeof(cf_t) * num_re);
				bzero(h, sizeof(cf_t) * num_re);

				refsignal_put(&refs, input);

				refsignal_free(&refs);

				for (i=0;i<CP_NSYMB(cp);i++) {
					for (j=0;j<nof_prb * RE_X_RB;j++) {
						float x = -1+(float) i/CP_NSYMB(cp) + cosf(2 * M_PI * (float) j/nof_prb/RE_X_RB);
						h[i*nof_prb * RE_X_RB+j] = (3+x) * cexpf(I * x);
						input[i*nof_prb * RE_X_RB+j] *= h[i*nof_prb * RE_X_RB+j];
					}
				}

				chest_ce_slot_port(&eq, input, ce, n_slot, n_port);

				mse_mag = mse_phase = 0;
				for (i=0;i<num_re;i++) {
					mse_mag += (cabsf(h[i]) - cabsf(ce[i])) * (cabsf(h[i]) - cabsf(ce[i])) / num_re;
					mse_phase += (cargf(h[i]) - cargf(ce[i])) * (cargf(h[i]) - cargf(ce[i])) / num_re;
				}

				if (check_mse(mse_mag, mse_phase, n_port)) {
					goto do_exit;
				}

				if (fmatlab) {
					fprintf(fmatlab, "input=");
					vec_fprint_c(fmatlab, input, num_re);
					fprintf(fmatlab, ";\n");
					fprintf(fmatlab, "h=");
					vec_fprint_c(fmatlab, h, num_re);
					fprintf(fmatlab, ";\n");
					fprintf(fmatlab, "ce=");
					vec_fprint_c(fmatlab, ce, num_re);
					fprintf(fmatlab, ";\n");
					chest_fprint(&eq, fmatlab, n_slot, n_port);
				}
			}
		}
		chest_free(&eq);
		cid+=10;
		INFO("cid=%d\n", cid);
	}


	ret = 0;

do_exit:

	if (ce) {
		free(ce);
	}
	if (input) {
		free(input);
	}
	if (h) {
		free(h);
	}

	if (!ret) {
		printf("OK\n");
	} else {
		printf("Error at cid=%d, slot=%d, port=%d\n",cid, n_slot, n_port);
	}

	exit(ret);
}
Exemple #28
0
void iceFsk3(int * data, const size_t len){

	int i,j;
	
	int * output =  (int* ) malloc(sizeof(int) * len);	
	memset(output, 0x00, len);
	float fc           = 0.1125f;          // center frequency
	size_t adjustedLen = len;
	
    // create very simple low-pass filter to remove images (2nd-order Butterworth)
    float complex iir_buf[3] = {0,0,0};
    float b[3] = {0.003621681514929,  0.007243363029857, 0.003621681514929};
    float a[3] = {1.000000000000000, -1.822694925196308, 0.837181651256023};
    
    float sample           = 0;      // input sample read from file
    float complex x_prime  = 1.0f;   // save sample for estimating frequency
    float complex x;
		
	for (i=0; i<adjustedLen; ++i) {

		sample = data[i]+128;
		
        // remove DC offset and mix to complex baseband
        x = (sample - 127.5f) * cexpf( _Complex_I * 2 * M_PI * fc * i );

        // apply low-pass filter, removing spectral image (IIR using direct-form II)
        iir_buf[2] = iir_buf[1];
        iir_buf[1] = iir_buf[0];
        iir_buf[0] = x - a[1]*iir_buf[1] - a[2]*iir_buf[2];
        x          = b[0]*iir_buf[0] +
                     b[1]*iir_buf[1] +
                     b[2]*iir_buf[2];
					 
        // compute instantaneous frequency by looking at phase difference
        // between adjacent samples
        float freq = cargf(x*conjf(x_prime));
        x_prime = x;    // retain this sample for next iteration

		output[i] =(freq > 0)? 10 : -10;
    } 

	// show data
	for (j=0; j<adjustedLen; ++j)
		data[j] = output[j];
		
	CmdLtrim("30");
	adjustedLen -= 30;
	
	// zero crossings.
	for (j=0; j<adjustedLen; ++j){
		if ( data[j] == 10) break;
	}
	int startOne =j;
	
	for (;j<adjustedLen; ++j){
		if ( data[j] == -10 ) break;
	}
	int stopOne = j-1;
	
	int fieldlen = stopOne-startOne;
	
	fieldlen = (fieldlen == 39 || fieldlen == 41)? 40 : fieldlen;
	fieldlen = (fieldlen == 59 || fieldlen == 51)? 50 : fieldlen;
	if ( fieldlen != 40 && fieldlen != 50){
		printf("Detected field Length: %d \n", fieldlen);
		printf("Can only handle 40 or 50.  Aborting...\n");
		return;
	}
	
	// FSK sequence start == 000111
	int startPos = 0;
	for (i =0; i<adjustedLen; ++i){
		int dec = 0;
		for ( j = 0; j < 6*fieldlen; ++j){
			dec += data[i + j];
		}
		if (dec == 0) {
			startPos = i;
			break;
		}
	}
	
	printf("000111 position: %d \n", startPos);

	startPos += 6*fieldlen+5;
	
	int bit =0;
	printf("BINARY\n");
	printf("R/40 :  ");
	for (i =startPos ; i < adjustedLen; i += 40){
		bit = data[i]>0 ? 1:0;
		printf("%d", bit );
	}
	printf("\n");	
	
	printf("R/50 :  ");
	for (i =startPos ; i < adjustedLen; i += 50){
		bit = data[i]>0 ? 1:0;
		printf("%d", bit );	}
	printf("\n");	
	
	free(output);
}
Exemple #29
0
int main() {
    // parameters
    float phase_offset = 0.8f;
    float frequency_offset = 0.01f;
    float pll_bandwidth = 0.05f;
    float pll_damping_factor = 0.707f;
    unsigned int n=256;     // number of iterations
    unsigned int d=n/32;    // print every "d" lines

    //
    float theta[n];         // input phase
    float complex x[n];     // input sinusoid
    float phi[n];           // output phase
    float complex y[n];     // output sinusoid

    // generate iir loop filter(s)
    float a[3];
    float b[3];
    float wn = pll_bandwidth;
    float zeta = pll_damping_factor;
    float K = 10; // loop gain

#if 0
    // loop filter (active lag)
    float t1 = K/(wn*wn);
    float t2 = 2*zeta/wn - 1/K;

    b[0] = 2*K*(1.+t2/2.0f);
    b[1] = 2*K*2.;
    b[2] = 2*K*(1.-t2/2.0f);

    a[0] =  1 + t1/2.0f;
    a[1] = -t1;
    a[2] = -1 + t1/2.0f;
#else
    // loop filter (active PI)
    float t1 = K/(wn*wn);
    float t2 = 2*zeta/wn;

    b[0] = 2*K*(1.+t2/2.0f);
    b[1] = 2*K*2.;
    b[2] = 2*K*(1.-t2/2.0f);

    a[0] =  t1/2.0f;
    a[1] = -t1;
    a[2] =  t1/2.0f;
#endif
    iirfilt_rrrf H = iirfilt_rrrf_create(b,3,a,3);
    iirfilt_rrrf_print(H);

    unsigned int i;

    // generate input
    float t=phase_offset;
    float dt = frequency_offset;
    for (i=0; i<n; i++) {
        theta[i] = t;
        x[i] = cexpf(_Complex_I*theta[i]);

        t += dt;
    }

    // run loop
    float phi_hat=0.0f;
    for (i=0; i<n; i++) {
        y[i] = cexpf(_Complex_I*phi_hat);

        // compute error
        float e = cargf(x[i]*conjf(y[i]));

        if ( (i%d)==0 )
            printf("e(%3u) = %12.8f;\n", i, e);

        // filter error
        iirfilt_rrrf_execute(H,e,&phi_hat);

        phi[i] = phi_hat;
    }

    // destroy filter
    iirfilt_rrrf_destroy(H);

    // open output file
    FILE * fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"clear all;\n");
    fprintf(fid,"n=%u;\n",n);

    fprintf(fid,"a(1) = %16.8e;\n", a[0]);
    fprintf(fid,"a(2) = %16.8e;\n", a[1]);
    fprintf(fid,"a(3) = %16.8e;\n", a[2]);

    fprintf(fid,"b(1) = %16.8e;\n", b[0]);
    fprintf(fid,"b(2) = %16.8e;\n", b[1]);
    fprintf(fid,"b(3) = %16.8e;\n", b[2]);

    //fprintf(fid,"figure;\n");
    //fprintf(fid,"freqz(b,a);\n");

    for (i=0; i<n; i++) {
        fprintf(fid,"theta(%3u) = %16.8e;\n", i+1, theta[i]);
        fprintf(fid,"  phi(%3u) = %16.8e;\n", i+1, phi[i]);
    }
    fprintf(fid,"t=0:(n-1);\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"plot(t,theta,t,phi);\n");
    fprintf(fid,"xlabel('sample index');\n");
    fprintf(fid,"ylabel('phase');\n");

    fclose(fid);

    printf("output written to %s.\n", OUTPUT_FILENAME);

    printf("done.\n");
    return 0;
}