BSYNC() BSYNC(_create)(unsigned int _n, TC * _v) { BSYNC() fs = (BSYNC()) malloc(sizeof(struct BSYNC(_s))); fs->n = _n; fs->sync_i = bsequence_create(fs->n); #ifdef TC_COMPLEX fs->sync_q = bsequence_create(fs->n); #endif fs->sym_i = bsequence_create(fs->n); #ifdef TI_COMPLEX fs->sym_q = bsequence_create(fs->n); #endif unsigned int i; for (i=0; i<fs->n; i++) { bsequence_push(fs->sync_i, crealf(_v[i])>0); #ifdef TC_COMPLEX bsequence_push(fs->sync_q, cimagf(_v[i])>0); #endif } return fs; }
bpacketsync bpacketsync_create(unsigned int _m, bpacketsync_callback _callback, void * _userdata) { // create bpacketsync object bpacketsync q = (bpacketsync) malloc(sizeof(struct bpacketsync_s)); q->callback = _callback; q->userdata = _userdata; // default values q->dec_msg_len = 1; q->crc = LIQUID_CRC_NONE; q->fec0 = LIQUID_FEC_NONE; q->fec1 = LIQUID_FEC_NONE; // implied values q->g = 0; q->pnsequence_len = 8; // derived values q->enc_msg_len = packetizer_compute_enc_msg_len(q->dec_msg_len, q->crc, q->fec0, q->fec1); q->header_len = packetizer_compute_enc_msg_len(6, LIQUID_CRC_16, LIQUID_FEC_NONE, LIQUID_FEC_HAMMING128); // arrays q->pnsequence = (unsigned char*) malloc((q->pnsequence_len)*sizeof(unsigned char*)); q->payload_enc = (unsigned char*) malloc((q->enc_msg_len)*sizeof(unsigned char*)); q->payload_dec = (unsigned char*) malloc((q->dec_msg_len)*sizeof(unsigned char*)); // create m-sequence generator // TODO : configure sequence from generator polynomial q->ms = msequence_create_default(6); // create header packet encoder q->p_header = packetizer_create(6, LIQUID_CRC_16, LIQUID_FEC_NONE, LIQUID_FEC_HAMMING128); assert(q->header_len == packetizer_get_enc_msg_len(q->p_header)); // create payload packet encoder q->p_payload = packetizer_create(q->dec_msg_len, q->crc, q->fec0, q->fec1); // create binary sequence objects q->bpn = bsequence_create(q->pnsequence_len*8); q->brx = bsequence_create(q->pnsequence_len*8); // assemble semi-static framing structures bpacketsync_assemble_pnsequence(q); // reset synchronizer bpacketsync_reset(q); return q; }
/* _m : number of correlators */ BPRESYNC() BPRESYNC(_create)(TC * _v, unsigned int _n, float _dphi_max, unsigned int _m) { // validate input if (_n < 1) { fprintf(stderr, "error: bpresync_%s_create(), invalid input length\n", EXTENSION_FULL); exit(1); } else if (_m == 0) { fprintf(stderr, "error: bpresync_%s_create(), number of correlators must be at least 1\n", EXTENSION_FULL); exit(1); } // allocate main object memory and initialize BPRESYNC() _q = (BPRESYNC()) malloc(sizeof(struct BPRESYNC(_s))); _q->n = _n; _q->m = _m; _q->n_inv = 1.0f / (float)(_q->n); unsigned int i; // create internal receive buffers _q->rx_i = bsequence_create(_q->n); _q->rx_q = bsequence_create(_q->n); // create internal array of frequency offsets _q->dphi = (float*) malloc( _q->m*sizeof(float) ); // create internal synchronizers _q->sync_i = (bsequence*) malloc( _q->m*sizeof(bsequence) ); _q->sync_q = (bsequence*) malloc( _q->m*sizeof(bsequence) ); for (i=0; i<_q->m; i++) { _q->sync_i[i] = bsequence_create(_q->n); _q->sync_q[i] = bsequence_create(_q->n); // generate signal with frequency offset _q->dphi[i] = (float)i / (float)(_q->m-1)*_dphi_max; unsigned int k; for (k=0; k<_q->n; k++) { TC v_prime = _v[k] * cexpf(-_Complex_I*k*_q->dphi[i]); bsequence_push(_q->sync_i[i], crealf(v_prime)>0); bsequence_push(_q->sync_q[i], cimagf(v_prime)>0); } } // allocate memory for cross-correlation _q->rxy = (float*) malloc( _q->m*sizeof(float) ); // reset object BPRESYNC(_reset)(_q); return _q; }
// TODO : test this method BSYNC() BSYNC(_create_msequence)(unsigned int _g, unsigned int _k) { // validate input if (_k == 0) { fprintf(stderr,"bsync_xxxt_create_msequence(), samples/symbol must be greater than zero\n"); exit(1); } unsigned int m = liquid_msb_index(_g) - 1; // create/initialize msequence msequence ms = msequence_create(m, _g, 1); BSYNC() fs = (BSYNC()) malloc(sizeof(struct BSYNC(_s))); unsigned int n = msequence_get_length(ms); fs->sync_i = bsequence_create(n * _k); #ifdef TC_COMPLEX fs->sync_q = bsequence_create(n * _k); #endif fs->sym_i = bsequence_create(n * _k); #ifdef TI_COMPLEX fs->sym_q = bsequence_create(n * _k); #endif msequence_reset(ms); #if 0 bsequence_init_msequence(fs->sync_i,ms); #ifdef TC_COMPLEX msequence_reset(ms); bsequence_init_msequence(fs->sync_q,ms); #endif #else unsigned int i; unsigned int j; for (i=0; i<n; i++) { unsigned int bit = msequence_advance(ms); for (j=0; j<_k; j++) { bsequence_push(fs->sync_i, bit); #ifdef TC_COMPLEX bsequence_push(fs->sync_q, bit); #endif } } #endif msequence_destroy(ms); fs->n = _k*n; return fs; }
// // test initialization of binary sequence // void autotest_bsequence_init() { // 1111 0000 1100 1010 unsigned char v[2] = {0xf0, 0xca}; // create and initialize sequence bsequence q = bsequence_create(16); bsequence_init(q,v); // run tests CONTEND_EQUALITY( bsequence_index(q,15), 1 ); CONTEND_EQUALITY( bsequence_index(q,14), 1 ); CONTEND_EQUALITY( bsequence_index(q,13), 1 ); CONTEND_EQUALITY( bsequence_index(q,12), 1 ); CONTEND_EQUALITY( bsequence_index(q,11), 0 ); CONTEND_EQUALITY( bsequence_index(q,10), 0 ); CONTEND_EQUALITY( bsequence_index(q, 9), 0 ); CONTEND_EQUALITY( bsequence_index(q, 8), 0 ); CONTEND_EQUALITY( bsequence_index(q, 7), 1 ); CONTEND_EQUALITY( bsequence_index(q, 6), 1 ); CONTEND_EQUALITY( bsequence_index(q, 5), 0 ); CONTEND_EQUALITY( bsequence_index(q, 4), 0 ); CONTEND_EQUALITY( bsequence_index(q, 3), 1 ); CONTEND_EQUALITY( bsequence_index(q, 2), 0 ); CONTEND_EQUALITY( bsequence_index(q, 1), 1 ); CONTEND_EQUALITY( bsequence_index(q, 0), 0 ); // clean up memory bsequence_destroy(q); }
// // test add operations on two sequences // void autotest_bsequence_add() { // v0 : 1111 0000 1100 1010 // v1 : 1100 1011 0001 1110 // sum : 0011 1011 1101 0100 unsigned char v0[2] = {0xf0, 0xca}; unsigned char v1[2] = {0xcb, 0x1e}; // create and initialize sequences bsequence q0 = bsequence_create(16); bsequence q1 = bsequence_create(16); bsequence_init(q0,v0); bsequence_init(q1,v1); // create result sequence bsequence r = bsequence_create(16); bsequence_add(q0, q1, r); // run tests CONTEND_EQUALITY( bsequence_index(r,15), 0 ); CONTEND_EQUALITY( bsequence_index(r,14), 0 ); CONTEND_EQUALITY( bsequence_index(r,13), 1 ); CONTEND_EQUALITY( bsequence_index(r,12), 1 ); CONTEND_EQUALITY( bsequence_index(r,11), 1 ); CONTEND_EQUALITY( bsequence_index(r,10), 0 ); CONTEND_EQUALITY( bsequence_index(r, 9), 1 ); CONTEND_EQUALITY( bsequence_index(r, 8), 1 ); CONTEND_EQUALITY( bsequence_index(r, 7), 1 ); CONTEND_EQUALITY( bsequence_index(r, 6), 1 ); CONTEND_EQUALITY( bsequence_index(r, 5), 0 ); CONTEND_EQUALITY( bsequence_index(r, 4), 1 ); CONTEND_EQUALITY( bsequence_index(r, 3), 0 ); CONTEND_EQUALITY( bsequence_index(r, 2), 1 ); CONTEND_EQUALITY( bsequence_index(r, 1), 0 ); CONTEND_EQUALITY( bsequence_index(r, 0), 0 ); // clean up memory bsequence_destroy(q0); bsequence_destroy(q1); bsequence_destroy(r); }
// // test correlation between to sequences // void autotest_bsequence_correlate() { // v0 : 1111 0000 1100 1010 // v1 : 1100 1011 0001 1110 // sim : 1100 0100 0010 1011 (7 similar bits) unsigned char v0[2] = {0xf0, 0xca}; unsigned char v1[2] = {0xcb, 0x1e}; // create and initialize sequences bsequence q0 = bsequence_create(16); bsequence q1 = bsequence_create(16); bsequence_init(q0,v0); bsequence_init(q1,v1); // run tests CONTEND_EQUALITY( bsequence_correlate(q0,q1), 7 ); // clean up memory bsequence_destroy(q0); bsequence_destroy(q1); }
// // AUTOTEST: validate autocorrelation properties of // complementary codes // void complementary_codes_test(unsigned int _n) { // create and initialize codes bsequence a = bsequence_create(_n); bsequence b = bsequence_create(_n); bsequence_create_ccodes(a, b); // print if (liquid_autotest_verbose) { bsequence_print(a); bsequence_print(b); } // generate test sequences bsequence ax = bsequence_create(_n); bsequence bx = bsequence_create(_n); bsequence_create_ccodes(ax, bx); unsigned int i; signed int raa, rbb; for (i=0; i<_n; i++) { // correlate like sequences raa = 2*bsequence_correlate(a,ax) - _n; rbb = 2*bsequence_correlate(b,bx) - _n; if (i==0) { CONTEND_EQUALITY(raa+rbb,2*_n); } else { CONTEND_EQUALITY(raa+rbb,0); } bsequence_circshift(ax); bsequence_circshift(bx); } // clean up memory bsequence_destroy(a); bsequence_destroy(b); bsequence_destroy(ax); bsequence_destroy(bx); }
// // test accumulation of binary sequence // void autotest_bsequence_accumulate() { // 1111 0000 1100 1010 (8 total bits) unsigned char v[2] = {0xf0, 0xca}; // create and initialize sequence bsequence q = bsequence_create(16); bsequence_init(q,v); // run tests CONTEND_EQUALITY( bsequence_accumulate(q), 8 ); // clean up memory bsequence_destroy(q); }
int main(int argc, char*argv[]) { // options unsigned int m=5; // shift register length, n=2^m - 1 // create and initialize m-sequence msequence ms = msequence_create_default(m); msequence_print(ms); unsigned int n = msequence_get_length(ms); signed int rxx[n]; // auto-correlation // create and initialize first binary sequence on m-sequence bsequence bs1 = bsequence_create(n); bsequence_init_msequence(bs1, ms); // create and initialize second binary sequence on same m-sequence bsequence bs2 = bsequence_create(n); bsequence_init_msequence(bs2, ms); // when sequences are aligned, autocorrelation is equal to length rxx[0] = 2*bsequence_correlate(bs1, bs2) - n; // when sequences are misaligned, autocorrelation is equal to -1 unsigned int i; for (i=0; i<n; i++) { // compute auto-correlation rxx[i] = 2*bsequence_correlate(bs1, bs2)-n; // circular shift the second sequence bsequence_circshift(bs2); } // p/n sequence signed int x[n]; for (i=0; i<n; i++) x[i] = bsequence_index(bs1, i); // clean up memory bsequence_destroy(bs1); bsequence_destroy(bs2); msequence_destroy(ms); // print results for (i=0; i<n; i++) printf("rxx[%3u] = %3d\n", i, rxx[i]); // // export results // FILE * fid = fopen(OUTPUT_FILENAME,"w"); if (!fid) { fprintf(stderr,"error: %s, cannot open output file '%s' for writing\n", argv[0], OUTPUT_FILENAME); exit(1); } fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME); fprintf(fid,"clear all;\n"); fprintf(fid,"close all;\n\n"); fprintf(fid,"n = %u;\n", n); fprintf(fid,"p = zeros(1,n);\n"); for (i=0; i<n; i++) { fprintf(fid,"x(%6u) = %3d;\n", i+1, x[i]); fprintf(fid,"rxx(%6u) = %12.8f;\n", i+1, rxx[i] / (float)n); } // plot results fprintf(fid,"figure;\n"); fprintf(fid,"t = 0:(n-1);\n"); fprintf(fid,"subplot(2,1,1);\n"); fprintf(fid," stairs(t,x);\n"); fprintf(fid," axis([-1 n -0.2 1.2]);\n"); fprintf(fid," ylabel('x');\n"); fprintf(fid,"subplot(2,1,2);\n"); fprintf(fid," plot(t,rxx,t,rxx);\n"); fprintf(fid," axis([-1 n -0.5 1.2]);\n"); fprintf(fid," xlabel('delay (samples)');\n"); fprintf(fid," ylabel('auto-correlation');\n"); fclose(fid); printf("results written to %s.\n", OUTPUT_FILENAME); return 0; }
int main(int argc, char*argv[]) { // options unsigned int m=5; // shift register length, n=2^m - 1 char filename[64] = ""; // output filename int dopt; while ((dopt = getopt(argc,argv,"uhm:f:")) != EOF) { switch (dopt) { case 'u': case 'h': usage(); return 0; case 'm': m = atoi(optarg); break; case 'f': // copy output filename string strncpy(filename,optarg,64); filename[63] = '\0'; break; default: exit(1); } } // ensure output filename is set if (strcmp(filename,"")==0) { fprintf(stderr,"error: %s, filename not set\n", argv[0]); exit(1); } // validate m if (m < 2) { fprintf(stderr,"error: %s, m is out of range\n", argv[0]); exit(1); } // create and initialize m-sequence msequence ms = msequence_create_default(m); msequence_print(ms); unsigned int n = msequence_get_length(ms); unsigned int sequence[n]; // sequence signed int rxx[n]; // auto-correlation // initialize sequence unsigned int i; for (i=0; i<n; i++) sequence[i] = msequence_advance(ms); // reset sequence msequence_reset(ms); // create and initialize first binary sequence on m-sequence bsequence bs1 = bsequence_create(n); bsequence_init_msequence(bs1, ms); // create and initialize second binary sequence on same m-sequence bsequence bs2 = bsequence_create(n); bsequence_init_msequence(bs2, ms); // when sequences are aligned, autocorrelation is equal to length unsigned int k=0; rxx[k++] = 2*bsequence_correlate(bs1, bs2) - n; // when sequences are misaligned, autocorrelation is equal to -1 for (i=0; i<n-1; i++) { bsequence_push(bs2, msequence_advance(ms)); rxx[k++] = 2*bsequence_correlate(bs1, bs2)-n; } // clean up memory bsequence_destroy(bs1); bsequence_destroy(bs2); msequence_destroy(ms); // // generate auto-correlation plot // // open output file FILE * fid = fopen(filename,"w"); if (fid == NULL) { fprintf(stderr,"error: %s, could not open file \"%s\" for writing.\n", argv[0], filename); exit(1); } // print header fprintf(fid,"# %s : auto-generated file (do not edit)\n", filename); fprintf(fid,"# invoked as :"); for (i=0; i<argc; i++) fprintf(fid," %s",argv[i]); fprintf(fid,"reset\n"); fprintf(fid,"set terminal postscript eps enhanced color solid rounded\n"); fprintf(fid,"set xrange [-1:%u];\n", n+1); fprintf(fid,"set size ratio 0.3\n"); fprintf(fid,"set xlabel 'delay (number of samples)'\n"); fprintf(fid,"set nokey # disable legned\n"); //fprintf(fid,"set grid xtics ytics\n"); //fprintf(fid,"set grid linetype 1 linecolor rgb '%s' lw 1\n", LIQUID_DOC_COLOR_GRID); fprintf(fid,"set multiplot layout 2,1 scale 1.0,1.0\n"); fprintf(fid,"# sequence\n"); fprintf(fid,"set ylabel 'sequence'\n"); fprintf(fid,"set yrange [-0.1:1.1]\n"); fprintf(fid,"plot '-' using 1:2 with steps linetype 1 linewidth 4 linecolor rgb '%s'\n",LIQUID_DOC_COLOR_BLUE); for (i=0; i<n; i++) { fprintf(fid," %6u %6u\n", i, sequence[i]); } fprintf(fid,"e\n"); fprintf(fid,"# auto-correlation\n"); fprintf(fid,"set ylabel 'auto-correlation'\n"); fprintf(fid,"set yrange [%f:1.1]\n", -5.0f / (float)n); fprintf(fid,"plot '-' using 1:2 with lines linetype 1 linewidth 4 linecolor rgb '%s'\n",LIQUID_DOC_COLOR_GREEN); for (i=0; i<n; i++) { fprintf(fid," %6u %12.4e\n", i, (float)rxx[i] / (float)n); } fprintf(fid,"e\n"); fprintf(fid,"unset multiplot\n"); // close output file fclose(fid); printf("results written to %s.\n", filename); return 0; }