Пример #1
0
// 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;
}
Пример #2
0
// 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;
}
Пример #3
0
// 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);
}
Пример #4
0
// 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;
}
Пример #5
0
// 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;
}
Пример #6
0
// 
// 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 );
}