Ejemplo n.º 1
0
// create WLAN framing synchronizer object
//  _callback   :   user-defined callback function
//  _userdata   :   user-defined data structure
wlanframesync wlanframesync_create(wlanframesync_callback _callback,
                                   void *                 _userdata)
{
    // allocate main object memory
    wlanframesync q = (wlanframesync) malloc(sizeof(struct wlanframesync_s));
    
    // set callback data
    q->callback = _callback;
    q->userdata = _userdata;

    // create transform object
    q->X = (float complex*) malloc(64*sizeof(float complex));
    q->x = (float complex*) malloc(64*sizeof(float complex));
    q->fft = FFT_CREATE_PLAN(64, q->x, q->X, FFT_DIR_FORWARD, FFT_METHOD);
 
    // create input buffer the length of the transform
    q->input_buffer = windowcf_create(80);

    // synchronizer objects
    q->nco_rx = nco_crcf_create(LIQUID_VCO);
    q->ms_pilot = wlan_lfsr_create(7, 0x91, 0x7f);
    q->mod_scheme = WLAN_MODEM_BPSK;

    // set initial properties
    q->rate   = WLANFRAME_RATE_6;
    q->length = 100;
    q->seed   = 0x5d;

    // allocate memory for encoded message
    q->enc_msg_len = wlan_packet_compute_enc_msg_len(q->rate, q->length);
    q->msg_enc = (unsigned char*) malloc(q->enc_msg_len*sizeof(unsigned char));

    // allocate memory for decoded message
    q->dec_msg_len = 1;
    q->msg_dec = (unsigned char*) malloc(q->dec_msg_len*sizeof(unsigned char));

    // reset object
    wlanframesync_reset(q);
    
#if DEBUG_WLANFRAMESYNC
    // debugging structures
    q->debug_enabled   = 0;
    q->agc_rx          = NULL;
    q->debug_x         = NULL;
    q->debug_rssi      = NULL;
    q->debug_framesyms = NULL;
#endif

    // return object
    return q;
}
Ejemplo n.º 2
0
void FFTransformer::fillComplexSub()
{
    auto plan = FFT_CREATE_PLAN(m_bufferSize, m_complexSub, m_complexSub, FFTW_FORWARD, FFTW_ESTIMATE);
    double speed = Options::getInstance()->getSignalSpeed();
    double rxRate = Options::getInstance()->getBand();
    for(size_t i = 0; i < m_bufferSize; i++)
    {
        double t = i / rxRate;
        t *= t;

        auto iter = *(m_complexSub + i);
        iter[0] = cos(M_PI * t * speed);
        iter[1] = sin(M_PI * t * speed);
    }

    FFT_EXECUTE(plan);
    for(size_t i = 0; i < m_bufferSize; i++)
      m_complexSub[i][1] *= -1;
      
    FFT_DESTROY_PLAN(plan);
}
Ejemplo n.º 3
0
// create OFDM framing synchronizer object
//  _M          :   number of subcarriers, >10 typical
//  _cp_len     :   cyclic prefix length
//  _taper_len  :   taper length (OFDM symbol overlap)
//  _p          :   subcarrier allocation (null, pilot, data), [size: _M x 1]
//  _callback   :   user-defined callback function
//  _userdata   :   user-defined data pointer
ofdmframesync ofdmframesync_create(unsigned int           _M,
                                   unsigned int           _cp_len,
                                   unsigned int           _taper_len,
                                   unsigned char *        _p,
                                   ofdmframesync_callback _callback,
                                   void *                 _userdata)
{
    ofdmframesync q = (ofdmframesync) malloc(sizeof(struct ofdmframesync_s));

    // validate input
    if (_M < 8) {
        fprintf(stderr,"warning: ofdmframesync_create(), less than 8 subcarriers\n");
    } else if (_M % 2) {
        fprintf(stderr,"error: ofdmframesync_create(), number of subcarriers must be even\n");
        exit(1);
    } else if (_cp_len > _M) {
        fprintf(stderr,"error: ofdmframesync_create(), cyclic prefix length cannot exceed number of subcarriers\n");
        exit(1);
    }
    q->M = _M;
    q->cp_len = _cp_len;

    // derived values
    q->M2 = _M/2;

    // subcarrier allocation
    q->p = (unsigned char*) malloc((q->M)*sizeof(unsigned char));
    if (_p == NULL) {
        ofdmframe_init_default_sctype(q->M, q->p);
    } else {
        memmove(q->p, _p, q->M*sizeof(unsigned char));
    }

    // validate and count subcarrier allocation
    ofdmframe_validate_sctype(q->p, q->M, &q->M_null, &q->M_pilot, &q->M_data);
    if ( (q->M_pilot + q->M_data) == 0) {
        fprintf(stderr,"error: ofdmframesync_create(), must have at least one enabled subcarrier\n");
        exit(1);
    } else if (q->M_data == 0) {
        fprintf(stderr,"error: ofdmframesync_create(), must have at least one data subcarriers\n");
        exit(1);
    } else if (q->M_pilot < 2) {
        fprintf(stderr,"error: ofdmframesync_create(), must have at least two pilot subcarriers\n");
        exit(1);
    }

    // create transform object
    q->X = (float complex*) malloc((q->M)*sizeof(float complex));
    q->x = (float complex*) malloc((q->M)*sizeof(float complex));
    q->fft = FFT_CREATE_PLAN(q->M, q->x, q->X, FFT_DIR_FORWARD, FFT_METHOD);
 
    // create input buffer the length of the transform
    q->input_buffer = windowcf_create(q->M + q->cp_len);

    // allocate memory for PLCP arrays
    q->S0 = (float complex*) malloc((q->M)*sizeof(float complex));
    q->s0 = (float complex*) malloc((q->M)*sizeof(float complex));
    q->S1 = (float complex*) malloc((q->M)*sizeof(float complex));
    q->s1 = (float complex*) malloc((q->M)*sizeof(float complex));
    ofdmframe_init_S0(q->p, q->M, q->S0, q->s0, &q->M_S0);
    ofdmframe_init_S1(q->p, q->M, q->S1, q->s1, &q->M_S1);

    // compute scaling factor
    q->g_data = sqrtf(q->M) / sqrtf(q->M_pilot + q->M_data);
    q->g_S0   = sqrtf(q->M) / sqrtf(q->M_S0);
    q->g_S1   = sqrtf(q->M) / sqrtf(q->M_S1);

    // gain
    q->g0 = 1.0f;
    q->G0 = (float complex*) malloc((q->M)*sizeof(float complex));
    q->G1 = (float complex*) malloc((q->M)*sizeof(float complex));
    q->G  = (float complex*) malloc((q->M)*sizeof(float complex));
    q->B  = (float complex*) malloc((q->M)*sizeof(float complex));
    q->R  = (float complex*) malloc((q->M)*sizeof(float complex));

#if 1
    memset(q->G0, 0x00, q->M*sizeof(float complex));
    memset(q->G1, 0x00, q->M*sizeof(float complex));
    memset(q->G , 0x00, q->M*sizeof(float complex));
    memset(q->B,  0x00, q->M*sizeof(float complex));
#endif

    // timing backoff
    q->backoff = q->cp_len < 2 ? q->cp_len : 2;
    float phi = (float)(q->backoff)*2.0f*M_PI/(float)(q->M);
    unsigned int i;
    for (i=0; i<q->M; i++)
        q->B[i] = liquid_cexpjf(i*phi);

    // set callback data
    q->callback = _callback;
    q->userdata = _userdata;

    // 
    // synchronizer objects
    //

    // numerically-controlled oscillator
    q->nco_rx = nco_crcf_create(LIQUID_NCO);

    // set pilot sequence
    q->ms_pilot = msequence_create_default(8);

#if OFDMFRAMESYNC_ENABLE_SQUELCH
    // coarse detection
    q->squelch_threshold = -25.0f;
    q->squelch_enabled = 0;
#endif

    // reset object
    ofdmframesync_reset(q);

#if DEBUG_OFDMFRAMESYNC
    q->debug_enabled = 0;
    q->debug_objects_created = 0;

    q->debug_x =        NULL;
    q->debug_rssi =     NULL;
    q->debug_framesyms =NULL;
    
    q->G_hat = NULL;
    q->px    = NULL;
    q->py    = NULL;
    
    q->debug_pilot_0 = NULL;
    q->debug_pilot_1 = NULL;
#endif

    // return object
    return q;
}
Ejemplo n.º 4
0
// create OFDM framing generator object
//  _M          :   number of subcarriers, >10 typical
//  _cp_len     :   cyclic prefix length
//  _taper_len  :   taper length (OFDM symbol overlap)
//  _p          :   subcarrier allocation (null, pilot, data), [size: _M x 1]
ofdmframegen ofdmframegen_create(unsigned int    _M,
                                 unsigned int    _cp_len,
                                 unsigned int    _taper_len,
                                 unsigned char * _p)
{
    // validate input
    if (_M < 2) {
        fprintf(stderr,"error: ofdmframegen_create(), number of subcarriers must be at least 2\n");
        exit(1);
    } else if (_M % 2) {
        fprintf(stderr,"error: ofdmframegen_create(), number of subcarriers must be even\n");
        exit(1);
    } else if (_cp_len > _M) {
        fprintf(stderr,"error: ofdmframegen_create(), cyclic prefix cannot exceed symbol length\n");
        exit(1);
    } else if (_taper_len > _cp_len) {
        fprintf(stderr,"error: ofdmframegen_create(), taper length cannot exceed cyclic prefix\n");
        exit(1);
    }

    ofdmframegen q = (ofdmframegen) malloc(sizeof(struct ofdmframegen_s));
    q->M         = _M;
    q->cp_len    = _cp_len;
    q->taper_len = _taper_len;

    // allocate memory for subcarrier allocation IDs
    q->p = (unsigned char*) malloc((q->M)*sizeof(unsigned char));
    if (_p == NULL) {
        // initialize default subcarrier allocation
        ofdmframe_init_default_sctype(q->M, q->p);
    } else {
        // copy user-defined subcarrier allocation
        memmove(q->p, _p, q->M*sizeof(unsigned char));
    }

    // validate and count subcarrier allocation
    ofdmframe_validate_sctype(q->p, q->M, &q->M_null, &q->M_pilot, &q->M_data);
    if ( (q->M_pilot + q->M_data) == 0) {
        fprintf(stderr,"error: ofdmframegen_create(), must have at least one enabled subcarrier\n");
        exit(1);
    } else if (q->M_data == 0) {
        fprintf(stderr,"error: ofdmframegen_create(), must have at least one data subcarriers\n");
        exit(1);
    } else if (q->M_pilot < 2) {
        fprintf(stderr,"error: ofdmframegen_create(), must have at least two pilot subcarriers\n");
        exit(1);
    }

    unsigned int i;

    // allocate memory for transform objects
    q->X = (float complex*) malloc((q->M)*sizeof(float complex));
    q->x = (float complex*) malloc((q->M)*sizeof(float complex));
    q->ifft = FFT_CREATE_PLAN(q->M, q->X, q->x, FFT_DIR_BACKWARD, FFT_METHOD);

    // allocate memory for PLCP arrays
    q->S0 = (float complex*) malloc((q->M)*sizeof(float complex));
    q->s0 = (float complex*) malloc((q->M)*sizeof(float complex));
    q->S1 = (float complex*) malloc((q->M)*sizeof(float complex));
    q->s1 = (float complex*) malloc((q->M)*sizeof(float complex));
    ofdmframe_init_S0(q->p, q->M, q->S0, q->s0, &q->M_S0);
    ofdmframe_init_S1(q->p, q->M, q->S1, q->s1, &q->M_S1);

    // create tapering window and transition buffer
    q->taper   = (float*)         malloc(q->taper_len * sizeof(float));
    q->postfix = (float complex*) malloc(q->taper_len * sizeof(float complex));
    for (i=0; i<q->taper_len; i++) {
        float t = ((float)i + 0.5f) / (float)(q->taper_len);
        float g = sinf(M_PI_2*t);
        q->taper[i] = g*g;
    }
#if 0
    // validate window symmetry
    for (i=0; i<q->taper_len; i++) {
        printf("    taper[%2u] = %12.8f (%12.8f)\n", i, q->taper[i],
            q->taper[i] + q->taper[q->taper_len - i - 1]);
    }
#endif

    // compute scaling factor
    q->g_data = 1.0f / sqrtf(q->M_pilot + q->M_data);

    // set pilot sequence
    q->ms_pilot = msequence_create_default(8);

    return q;
}
Ejemplo n.º 5
0
// create fskdem object (frequency demodulator)
//  _m          :   bits per symbol, _m > 0
//  _k          :   samples/symbol, _k >= 2^_m
//  _bandwidth  :   total signal bandwidth, (0,0.5)
fskdem fskdem_create(unsigned int _m,
                     unsigned int _k,
                     float        _bandwidth)
{
    // validate input
    if (_m == 0) {
        fprintf(stderr,"error: fskdem_create(), bits/symbol must be greater than 0\n");
        exit(1);
    } else if (_k < 2 || _k > 2048) {
        fprintf(stderr,"error: fskdem_create(), samples/symbol must be in [2^_m, 2048]\n");
        exit(1);
    } else if (_bandwidth <= 0.0f || _bandwidth >= 0.5f) {
        fprintf(stderr,"error: fskdem_create(), bandwidth must be in (0,0.5)\n");
        exit(1);
    }

    // create main object memory
    fskdem q = (fskdem) malloc(sizeof(struct fskdem_s));

    // set basic internal properties
    q->m         = _m;              // bits per symbol
    q->k         = _k;              // samples per symbol
    q->bandwidth = _bandwidth;      // signal bandwidth

    // derived values
    q->M  = 1 << q->m;              // constellation size
    q->M2 = 0.5f*(float)(q->M-1);   // (M-1)/2

    // compute demodulation FFT size such that FFT output bin frequencies are
    // as close to modulated frequencies as possible
    float        df = q->bandwidth / q->M2;         // frequency spacing
    float        err_min = 1e9f;                    // minimum error value
    unsigned int K_min = q->k;                      // minimum FFT size
    unsigned int K_max = q->k*4 < 16 ? 16 : q->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

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

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

        // perfect match; no need to continue searching
        if (err < 1e-6f)
            break;
    }
    
    // determine demodulation mapping between tones and frequency bins
    // TODO: use gray coding
    q->demod_map = (unsigned int *) malloc(q->M * sizeof(unsigned int));
    unsigned int i;
    for (i=0; i<q->M; i++) {
        // print frequency bins
        float freq = ((float)i - q->M2) * q->bandwidth / q->M2;
        float idx  = freq * (float)(q->K);
        unsigned int index = (unsigned int) (idx < 0 ? roundf(idx + q->K) : roundf(idx));
        q->demod_map[i] = index;
#if DEBUG_FSKDEM
        printf("  s=%3u, f = %12.8f, index=%3u\n", i, freq, index);
#endif
    }

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

    // allocate memory for transform
    q->buf_time = (float complex*) malloc(q->K * sizeof(float complex));
    q->buf_freq = (float complex*) malloc(q->K * sizeof(float complex));
    q->fft = FFT_CREATE_PLAN(q->K, q->buf_time, q->buf_freq, FFT_DIR_FORWARD, 0);

    // reset modem object
    fskdem_reset(q);

    // return main object
    return q;
}
Ejemplo n.º 6
0
firpfbch firpfbch_create(unsigned int _num_channels,
                         unsigned int _m,
                         float _beta,
                         float _dt,
                         int _nyquist,
                         int _gradient)
{
    firpfbch c = (firpfbch) malloc(sizeof(struct firpfbch_s));
    c->num_channels = _num_channels;
    c->m            = _m;
    c->beta         = _beta;
    c->dt           = _dt;
    c->nyquist      = _nyquist;

    // validate inputs
    if (_m < 1) {
        printf("error: firpfbch_create(), invalid filter delay (must be greater than 0)\n");
        exit(1);
    }

    // create bank of filters
    c->dp   = (DOTPROD()*) malloc((c->num_channels)*sizeof(DOTPROD()));
    c->w    = (WINDOW()*) malloc((c->num_channels)*sizeof(WINDOW()));

    // design filter
    // TODO: use filter prototype object
    c->h_len = 2*(c->m)*(c->num_channels);
    c->h = (float*) malloc((c->h_len+1)*sizeof(float));

    if (c->nyquist == FIRPFBCH_NYQUIST) {
        float fc = 0.5f/(float)(c->num_channels);  // cutoff frequency
        liquid_firdes_kaiser(c->h_len+1, fc, c->beta, 0.0f, c->h);
    } else if (c->nyquist == FIRPFBCH_ROOTNYQUIST) {
        design_rkaiser_filter(c->num_channels, c->m, c->beta, c->dt, c->h);
    } else {
        printf("error: firpfbch_create(), unsupported nyquist flag: %d\n", _nyquist);
        exit(1);
    }
    
    unsigned int i;
    if (_gradient) {
        float dh[c->h_len];
        for (i=0; i<c->h_len; i++) {
            if (i==0) {
                dh[i] = c->h[i+1] - c->h[c->h_len-1];
            } else if (i==c->h_len-1) {
                dh[i] = c->h[0]   - c->h[i-1];
            } else {
                dh[i] = c->h[i+1] - c->h[i-1];
            }
        }
        memmove(c->h, dh, (c->h_len)*sizeof(float));
    }

    // generate bank of sub-samped filters
    unsigned int n;
    unsigned int h_sub_len = 2*(c->m);  // length of each sub-sampled filter
    float h_sub[h_sub_len];
    for (i=0; i<c->num_channels; i++) {
        // sub-sample prototype filter, loading coefficients in reverse order
        for (n=0; n<h_sub_len; n++) {
            h_sub[h_sub_len-n-1] = c->h[i + n*(c->num_channels)];
        }
        // create window buffer and dotprod object (coefficients
        // loaded in reverse order)
        c->dp[i] = DOTPROD(_create)(h_sub,h_sub_len);
        c->w[i]  = WINDOW(_create)(h_sub_len);

#if DEBUG_FIRPFBCH_PRINT
        printf("h_sub[%u] :\n", i);
        for (n=0; n<h_sub_len; n++)
            printf("  h[%3u] = %8.4f\n", n, h_sub[n]);
#endif
    }

#if DEBUG_FIRPFBCH_PRINT
    for (i=0; i<c->h_len+1; i++)
        printf("h(%4u) = %12.4e;\n", i+1, c->h[i]);
#endif

    // allocate memory for buffers
    // TODO : use fftw_malloc if HAVE_FFTW3_H
    c->x = (float complex*) malloc((c->num_channels)*sizeof(float complex));
    c->X = (float complex*) malloc((c->num_channels)*sizeof(float complex));
    c->X_prime = (float complex*) malloc((c->num_channels)*sizeof(float complex));
    firpfbch_clear(c);

    // create fft plan
    c->fft = FFT_CREATE_PLAN(c->num_channels, c->X, c->x, FFT_DIR_BACKWARD, FFT_METHOD);

    return c;
}
Ejemplo n.º 7
0
// create FFT-based FIR filter using external coefficients
//  _h      : filter coefficients [size: _h_len x 1]
//  _h_len  : filter length, _h_len > 0
//  _n      : block size = nfft/2, at least _h_len-1
FFTFILT() FFTFILT(_create)(TC *         _h,
                           unsigned int _h_len,
                           unsigned int _n)
{
    // validate input
    if (_h_len == 0) {
        fprintf(stderr,"error: fftfilt_%s_create(), filter length must be greater than zero\n",
                EXTENSION_FULL);
        exit(1);
    } else if (_n < _h_len-1) {
        fprintf(stderr,"error: fftfilt_%s_create(), block length must be greater than _h_len-1 (%u)\n",
                EXTENSION_FULL,
                _h_len-1);
        exit(1);
    }

    // create filter object and initialize
    FFTFILT() q = (FFTFILT()) malloc(sizeof(struct FFTFILT(_s)));
    q->h_len    = _h_len;
    q->n        = _n;

    // copy filter coefficients
    q->h = (TC *) malloc((q->h_len)*sizeof(TC));
    memmove(q->h, _h, _h_len*sizeof(TC));

    // allocate internal memory arrays
    q->time_buf = (float complex *) malloc((2*q->n)* sizeof(float complex)); // time buffer
    q->freq_buf = (float complex *) malloc((2*q->n)* sizeof(float complex)); // frequency buffer
    q->H        = (float complex *) malloc((2*q->n)* sizeof(float complex)); // FFT{ h }
    q->w        = (float complex *) malloc((  q->n)* sizeof(float complex)); // delay buffer

    // create internal FFT objects
#ifdef LIQUID_FFTOVERRIDE
    q->fft  = fft_create_plan(2*q->n, q->time_buf, q->freq_buf, LIQUID_FFT_FORWARD,  0);
    q->ifft = fft_create_plan(2*q->n, q->freq_buf, q->time_buf, LIQUID_FFT_BACKWARD, 0);
#else
    q->fft  = FFT_CREATE_PLAN(2*q->n, q->time_buf, q->freq_buf, FFT_DIR_FORWARD,  FFT_METHOD);
    q->ifft = FFT_CREATE_PLAN(2*q->n, q->freq_buf, q->time_buf, FFT_DIR_BACKWARD, FFT_METHOD);
#endif

    // compute FFT of filter coefficients and copy to internal H array
    unsigned int i;
    for (i=0; i<2*q->n; i++)
        q->time_buf[i] = (i < q->h_len) ? q->h[i] : 0;
    // time_buf > {FFT} > freq_buf
#ifdef LIQUID_FFTOVERRIDE
    fft_execute(q->fft);
#else
    FFT_EXECUTE(q->fft);
#endif
    memmove(q->H, q->freq_buf, 2*q->n*sizeof(float complex));

    // set default scaling
    FFTFILT(_set_scale)(q, 1);

    // reset filter state (clear buffer)
    FFTFILT(_reset)(q);

    // return object
    return q;
}
Ejemplo n.º 8
0
// create spgram object
//  _nfft       : FFT size
//  _wtype      : window type, e.g. LIQUID_WINDOW_HAMMING
//  _window_len : window length
//  _delay      : delay between transforms, _delay > 0
SPGRAM() SPGRAM(_create)(unsigned int _nfft,
                         int          _wtype,
                         unsigned int _window_len,
                         unsigned int _delay)
{
    // validate input
    if (_nfft < 2) {
        fprintf(stderr,"error: spgram%s_create(), fft size must be at least 2\n", EXTENSION);
        exit(1);
    } else if (_window_len > _nfft) {
        fprintf(stderr,"error: spgram%s_create(), window size cannot exceed fft size\n", EXTENSION);
        exit(1);
    } else if (_window_len == 0) {
        fprintf(stderr,"error: spgram%s_create(), window size must be greater than zero\n", EXTENSION);
        exit(1);
    } else if (_wtype == LIQUID_WINDOW_KBD && _window_len % 2) {
        fprintf(stderr,"error: spgram%s_create(), KBD window length must be even\n", EXTENSION);
        exit(1);
    } else if (_delay == 0) {
        fprintf(stderr,"error: spgram%s_create(), delay must be greater than 0\n", EXTENSION);
        exit(1);
    }

    // allocate memory for main object
    SPGRAM() q = (SPGRAM()) malloc(sizeof(struct SPGRAM(_s)));

    // set input parameters
    q->nfft       = _nfft;
    q->wtype      = _wtype;
    q->window_len = _window_len;
    q->delay      = _delay;
    q->frequency  =  0;
    q->sample_rate= -1;

    // set object for full accumulation
    SPGRAM(_set_alpha)(q, -1.0f);

    // create FFT arrays, object
    q->buf_time = (TC*) malloc((q->nfft)*sizeof(TC));
    q->buf_freq = (TC*) malloc((q->nfft)*sizeof(TC));
    q->psd      = (T *) malloc((q->nfft)*sizeof(T ));
    q->fft      = FFT_CREATE_PLAN(q->nfft, q->buf_time, q->buf_freq, FFT_DIR_FORWARD, FFT_METHOD);

    // create buffer
    q->buffer = WINDOW(_create)(q->window_len);

    // create window
    q->w = (T*) malloc((q->window_len)*sizeof(T));
    unsigned int i;
    unsigned int n = q->window_len;
    float beta = 10.0f;
    float zeta =  3.0f;
    for (i=0; i<n; i++) {
        switch (q->wtype) {
        case LIQUID_WINDOW_HAMMING:         q->w[i] = hamming(i,n);         break;
        case LIQUID_WINDOW_HANN:            q->w[i] = hann(i,n);            break;
        case LIQUID_WINDOW_BLACKMANHARRIS:  q->w[i] = blackmanharris(i,n);  break;
        case LIQUID_WINDOW_BLACKMANHARRIS7: q->w[i] = blackmanharris7(i,n); break;
        case LIQUID_WINDOW_KAISER:          q->w[i] = kaiser(i,n,beta,0);   break;
        case LIQUID_WINDOW_FLATTOP:         q->w[i] = flattop(i,n);         break;
        case LIQUID_WINDOW_TRIANGULAR:      q->w[i] = triangular(i,n,n);    break;
        case LIQUID_WINDOW_RCOSTAPER:       q->w[i] = liquid_rcostaper_windowf(i,n/3,n); break;
        case LIQUID_WINDOW_KBD:             q->w[i] = liquid_kbd(i,n,zeta); break;
        default:
            fprintf(stderr,"error: spgram%s_create(), invalid window\n", EXTENSION);
            exit(1);
        }
    }

    // scale by window magnitude, FFT size
    float g = 0.0f;
    for (i=0; i<q->window_len; i++)
        g += q->w[i] * q->w[i];
    g = M_SQRT2 / ( sqrtf(g / q->window_len) * sqrtf((float)(q->nfft)) );

    // scale window and copy
    for (i=0; i<q->window_len; i++)
        q->w[i] = g * q->w[i];

    // reset the spgram object
    q->num_samples_total    = 0;
    q->num_transforms_total = 0;
    SPGRAM(_reset)(q);

    // return new object
    return q;
}
Ejemplo n.º 9
0
// create FIR polyphase filterbank channelizer object
//  _type   : channelizer type (LIQUID_ANALYZER | LIQUID_SYNTHESIZER)
//  _M      : number of channels
//  _p      : filter length (symbols)
//  _h      : filter coefficients, [size: _M*_p x 1]
FIRPFBCH() FIRPFBCH(_create)(int          _type,
                             unsigned int _M,
                             unsigned int _p,
                             TC *         _h)
{
    // validate input
    if (_type != LIQUID_ANALYZER && _type != LIQUID_SYNTHESIZER) {
        fprintf(stderr,"error: firpfbch_%s_create(), invalid type %d\n", EXTENSION_FULL, _type);
        exit(1);
    } else if (_M == 0) {
        fprintf(stderr,"error: firpfbch_%s_create(), number of channels must be greater than 0\n", EXTENSION_FULL);
        exit(1);
    } else if (_p == 0) {
        fprintf(stderr,"error: firpfbch_%s_create(), invalid filter size (must be greater than 0)\n", EXTENSION_FULL);
        exit(1);
    }

    // create main object
    FIRPFBCH() q = (FIRPFBCH()) malloc(sizeof(struct FIRPFBCH(_s)));

    // set user-defined properties
    q->type         = _type;
    q->num_channels = _M;
    q->p            = _p;

    // derived values
    q->h_len = q->num_channels * q->p;

    // create bank of filters
    q->dp = (DOTPROD()*) malloc((q->num_channels)*sizeof(DOTPROD()));
    q->w  = (WINDOW()*)  malloc((q->num_channels)*sizeof(WINDOW()));

    // copy filter coefficients
    q->h = (TC*) malloc((q->h_len)*sizeof(TC));
    unsigned int i;
    for (i=0; i<q->h_len; i++)
        q->h[i] = _h[i];

    // generate bank of sub-samped filters
    unsigned int n;
    unsigned int h_sub_len = q->p;
    TC h_sub[h_sub_len];
    for (i=0; i<q->num_channels; i++) {
        // sub-sample prototype filter, loading coefficients in reverse order
        for (n=0; n<h_sub_len; n++) {
            h_sub[h_sub_len-n-1] = q->h[i + n*(q->num_channels)];
        }
        // create window buffer and dotprod object (coefficients
        // loaded in reverse order)
        q->dp[i] = DOTPROD(_create)(h_sub,h_sub_len);
        q->w[i]  = WINDOW(_create)(h_sub_len);
    }

    // allocate memory for buffers
    // TODO : use fftw_malloc if HAVE_FFTW3_H
    q->x = (T*) malloc((q->num_channels)*sizeof(T));
    q->X = (T*) malloc((q->num_channels)*sizeof(T));

    // create fft plan
    if (q->type == LIQUID_ANALYZER)
        q->fft = FFT_CREATE_PLAN(q->num_channels, q->X, q->x, FFT_DIR_FORWARD, FFT_METHOD);
    else
        q->fft = FFT_CREATE_PLAN(q->num_channels, q->X, q->x, FFT_DIR_BACKWARD, FFT_METHOD);

    // reset filterbank object
    FIRPFBCH(_reset)(q);

    // return filterbank object
    return q;
}