// create window buffer object of length _n WINDOW() WINDOW(_create)(unsigned int _n) { // validate input if (_n == 0) { fprintf(stderr,"error: window%s_create(), window size must be greater than zero\n", EXTENSION); exit(1); } // create initial object WINDOW() q = (WINDOW()) malloc(sizeof(struct WINDOW(_s))); // set internal parameters q->len = _n; // nominal window size q->m = liquid_msb_index(_n); // effectively floor(log2(len))+1 q->n = 1<<(q->m); // 2^m q->mask = q->n - 1; // bit mask // number of elements to allocate to memory q->num_allocated = q->n + q->len - 1; // allocte memory q->v = (T*) malloc((q->num_allocated)*sizeof(T)); q->read_index = 0; // reset window WINDOW(_reset)(q); // return object 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; }
// create a maximal-length sequence (m-sequence) object from a generator polynomial msequence msequence_create_genpoly(unsigned int _g) { unsigned int t = liquid_msb_index(_g); // validate input if (t < 2) { fprintf(stderr,"error: msequence_create_genpoly(), invalid generator polynomial: 0x%x\n", _g); exit(1); } // compute derived values unsigned int m = t - 1; // m-sequence shift register length unsigned int a = 1; // m-sequence initial state // generate object and return return msequence_create(m,_g,a); }
// create firfilt object // _h : coefficients (filter taps) [size: _n x 1] // _n : filter length FIRFILT() FIRFILT(_create)(TC * _h, unsigned int _n) { // validate input if (_n == 0) { fprintf(stderr,"error: firfilt_%s_create(), filter length must be greater than zero\n", EXTENSION_FULL); exit(1); } // create filter object and initialize FIRFILT() q = (FIRFILT()) malloc(sizeof(struct FIRFILT(_s))); q->h_len = _n; q->h = (TC *) malloc((q->h_len)*sizeof(TC)); #if LIQUID_FIRFILT_USE_WINDOW // create window (internal buffer) q->w = WINDOW(_create)(q->h_len); #else // initialize array for buffering q->w_len = 1<<liquid_msb_index(q->h_len); // effectively 2^{floor(log2(len))+1} q->w_mask = q->w_len - 1; q->w = (TI *) malloc((q->w_len + q->h_len + 1)*sizeof(TI)); q->w_index = 0; #endif // load filter in reverse order unsigned int i; for (i=_n; i>0; i--) q->h[i-1] = _h[_n-i]; // create dot product object q->dp = DOTPROD(_create)(q->h, q->h_len); // set default scaling q->scale = 1; // reset filter state (clear buffer) FIRFILT(_reset)(q); return q; }
// create FFT plan for regular DFT // _nfft : FFT size // _x : input array [size: _nfft x 1] // _y : output array [size: _nfft x 1] // _dir : fft direction: {LIQUID_FFT_FORWARD, LIQUID_FFT_BACKWARD} // _method : fft method FFT(plan) FFT(_create_plan_radix2)(unsigned int _nfft, TC * _x, TC * _y, int _dir, int _flags) { // allocate plan and initialize all internal arrays to NULL FFT(plan) q = (FFT(plan)) malloc(sizeof(struct FFT(plan_s))); q->nfft = _nfft; q->x = _x; q->y = _y; q->flags = _flags; q->type = (_dir == LIQUID_FFT_FORWARD) ? LIQUID_FFT_FORWARD : LIQUID_FFT_BACKWARD; q->direction = (_dir == LIQUID_FFT_FORWARD) ? LIQUID_FFT_FORWARD : LIQUID_FFT_BACKWARD; q->method = LIQUID_FFT_METHOD_RADIX2; q->execute = FFT(_execute_radix2); // initialize twiddle factors, indices for radix-2 transforms q->data.radix2.m = liquid_msb_index(q->nfft) - 1; // m = log2(nfft) q->data.radix2.index_rev = (unsigned int *) malloc((q->nfft)*sizeof(unsigned int)); unsigned int i; for (i=0; i<q->nfft; i++) q->data.radix2.index_rev[i] = fft_reverse_index(i,q->data.radix2.m); // initialize twiddle factors q->data.radix2.twiddle = (TC *) malloc(q->nfft * sizeof(TC)); T d = (q->direction == LIQUID_FFT_FORWARD) ? -1.0 : 1.0; for (i=0; i<q->nfft; i++) q->data.radix2.twiddle[i] = cexpf(_Complex_I*d*2*M_PI*(T)i / (T)(q->nfft)); return q; }
// // AUTOTEST: find location of most-significant bit // void autotest_msb_index() { // NOTE: this tests assumes a 4-byte integer CONTEND_EQUALITY( liquid_msb_index(0x00000000), 0 ); CONTEND_EQUALITY( liquid_msb_index(0x00000001), 1 ); CONTEND_EQUALITY( liquid_msb_index(0x00000002), 2 ); CONTEND_EQUALITY( liquid_msb_index(0x00000004), 3 ); CONTEND_EQUALITY( liquid_msb_index(0x00000008), 4 ); CONTEND_EQUALITY( liquid_msb_index(0x00000010), 5 ); CONTEND_EQUALITY( liquid_msb_index(0x00000020), 6 ); CONTEND_EQUALITY( liquid_msb_index(0x00000040), 7 ); CONTEND_EQUALITY( liquid_msb_index(0x00000080), 8 ); CONTEND_EQUALITY( liquid_msb_index(0x00000100), 9 ); CONTEND_EQUALITY( liquid_msb_index(0x00000200), 10 ); CONTEND_EQUALITY( liquid_msb_index(0x00000400), 11 ); CONTEND_EQUALITY( liquid_msb_index(0x00000800), 12 ); CONTEND_EQUALITY( liquid_msb_index(0x00001000), 13 ); CONTEND_EQUALITY( liquid_msb_index(0x00002000), 14 ); CONTEND_EQUALITY( liquid_msb_index(0x00004000), 15 ); CONTEND_EQUALITY( liquid_msb_index(0x00008000), 16 ); CONTEND_EQUALITY( liquid_msb_index(0x00010000), 17 ); CONTEND_EQUALITY( liquid_msb_index(0x00020000), 18 ); CONTEND_EQUALITY( liquid_msb_index(0x00040000), 19 ); CONTEND_EQUALITY( liquid_msb_index(0x00080000), 20 ); CONTEND_EQUALITY( liquid_msb_index(0x00100000), 21 ); CONTEND_EQUALITY( liquid_msb_index(0x00200000), 22 ); CONTEND_EQUALITY( liquid_msb_index(0x00400000), 23 ); CONTEND_EQUALITY( liquid_msb_index(0x00800000), 24 ); CONTEND_EQUALITY( liquid_msb_index(0x01000000), 25 ); CONTEND_EQUALITY( liquid_msb_index(0x02000000), 26 ); CONTEND_EQUALITY( liquid_msb_index(0x04000000), 27 ); CONTEND_EQUALITY( liquid_msb_index(0x08000000), 28 ); CONTEND_EQUALITY( liquid_msb_index(0x10000000), 29 ); CONTEND_EQUALITY( liquid_msb_index(0x20000000), 30 ); CONTEND_EQUALITY( liquid_msb_index(0x40000000), 31 ); CONTEND_EQUALITY( liquid_msb_index(0x80000000), 32 ); }