示例#1
0
文件: resamp2.c 项目: GRDSP/grdsp
// create a resamp2 object
//  _m      :   filter semi-length (effective length: 4*_m+1)
//  _fc     :   center frequency of half-band filter
//  _As     :   stop-band attenuation [dB], _As > 0
RESAMP2() RESAMP2(_create)(unsigned int _m,
                           float        _fc,
                           float        _As)
{
    // validate input
    if (_m < 2) {
        fprintf(stderr,"error: resamp2_%s_create(), filter semi-length must be at least 2\n", EXTENSION_FULL);
        exit(1);
    }

    RESAMP2() q = (RESAMP2()) malloc(sizeof(struct RESAMP2(_s)));
    q->m  = _m;
    q->fc = _fc;
    q->As = _As;
    if ( q->fc < -0.5f || q->fc > 0.5f ) {
        fprintf(stderr,"error: resamp2_%s_create(), fc (%12.4e) must be in (-1,1)\n", EXTENSION_FULL, q->fc);
        exit(1);
    }

    // change filter length as necessary
    q->h_len = 4*(q->m) + 1;
    q->h = (TC *) malloc((q->h_len)*sizeof(TC));

    q->h1_len = 2*(q->m);
    q->h1 = (TC *) malloc((q->h1_len)*sizeof(TC));

    // design filter prototype
    unsigned int i;
    float t, h1, h2;
    TC h3;
    float beta = kaiser_beta_As(q->As);
    for (i=0; i<q->h_len; i++) {
        t = (float)i - (float)(q->h_len-1)/2.0f;
        h1 = sincf(t/2.0f);
        h2 = kaiser(i,q->h_len,beta,0);
#if TC_COMPLEX == 1
        h3 = cosf(2.0f*M_PI*t*q->fc) + _Complex_I*sinf(2.0f*M_PI*t*q->fc);
#else
        h3 = cosf(2.0f*M_PI*t*q->fc);
#endif
        q->h[i] = h1*h2*h3;
    }

    // resample, alternate sign, [reverse direction]
    unsigned int j=0;
    for (i=1; i<q->h_len; i+=2)
        q->h1[j++] = q->h[q->h_len - i - 1];

    // create dotprod object
    q->dp = DOTPROD(_create)(q->h1, 2*q->m);

    // create window buffers
    q->w0 = WINDOW(_create)(2*(q->m));
    q->w1 = WINDOW(_create)(2*(q->m));

    RESAMP2(_clear)(q);

    return q;
}
示例#2
0
文件: firdes.c 项目: 0xLeo/liquid-dsp
// Design FIR using kaiser window
//  _n      : filter length, _n > 0
//  _fc     : cutoff frequency, 0 < _fc < 0.5
//  _As     : stop-band attenuation [dB], _As > 0
//  _mu     : fractional sample offset, -0.5 < _mu < 0.5
//  _h      : output coefficient buffer, [size: _n x 1]
void liquid_firdes_kaiser(unsigned int _n,
                          float _fc,
                          float _As,
                          float _mu,
                          float *_h)
{
    // validate inputs
    if (_mu < -0.5f || _mu > 0.5f) {
        fprintf(stderr,"error: liquid_firdes_kaiser(), _mu (%12.4e) out of range [-0.5,0.5]\n", _mu);
        exit(1);
    } else if (_fc < 0.0f || _fc > 0.5f) {
        fprintf(stderr,"error: liquid_firdes_kaiser(), cutoff frequency (%12.4e) out of range (0, 0.5)\n", _fc);
        exit(1);
    } else if (_n == 0) {
        fprintf(stderr,"error: liquid_firdes_kaiser(), filter length must be greater than zero\n");
        exit(1);
    }

    // choose kaiser beta parameter (approximate)
    float beta = kaiser_beta_As(_As);

    float t, h1, h2; 
    unsigned int i;
    for (i=0; i<_n; i++) {
        t = (float)i - (float)(_n-1)/2 + _mu;
     
        // sinc prototype
        h1 = sincf(2.0f*_fc*t);

        // kaiser window
        h2 = kaiser(i,_n,beta,_mu);

        //printf("t = %f, h1 = %f, h2 = %f\n", t, h1, h2);

        // composite
        _h[i] = h1*h2;
    }
}
示例#3
0
// Design frequency-shifted root-Nyquist filter based on
// the Kaiser-windowed sinc using approximation for rho.
//
//  _k      :   filter over-sampling rate (samples/symbol)
//  _m      :   filter delay (symbols)
//  _beta   :   filter excess bandwidth factor (0,1)
//  _dt     :   filter fractional sample delay
//  _h      :   resulting filter [size: 2*_k*_m+1]
void liquid_firdes_arkaiser(unsigned int _k,
                            unsigned int _m,
                            float _beta,
                            float _dt,
                            float * _h)
{
    // validate input
    if (_k < 2) {
        fprintf(stderr,"error: liquid_firdes_arkaiser(), k must be at least 2\n");
        exit(1);
    } else if (_m < 1) {
        fprintf(stderr,"error: liquid_firdes_arkaiser(), m must be at least 1\n");
        exit(1);
    } else if (_beta <= 0.0f || _beta >= 1.0f) {
        fprintf(stderr,"error: liquid_firdes_arkaiser(), beta must be in (0,1)\n");
        exit(1);
    } else if (_dt < -1.0f || _dt > 1.0f) {
        fprintf(stderr,"error: liquid_firdes_arkaiser(), dt must be in [-1,1]\n");
        exit(1);
    }

#if 0
    // compute bandwidth adjustment estimate
    float rho_hat = rkaiser_approximate_rho(_m,_beta);  // bandwidth correction factor
#else
    // rho ~ c0 + c1*log(_beta) + c2*log^2(_beta)

    // c0 ~ 0.762886 + 0.067663*log(m)
    // c1 ~ 0.065515
    // c2 ~ log( 1 - 0.088*m^-1.6 )

    float c0 = 0.762886 + 0.067663*logf(_m);
    float c1 = 0.065515;
    float c2 = logf( 1 - 0.088*powf(_m,-1.6 ) );

    float log_beta = logf(_beta);

    float rho_hat = c0 + c1*log_beta + c2*log_beta*log_beta;

    // ensure range is valid
    if (rho_hat <= 0.0f || rho_hat >= 1.0f)
        rho_hat = rkaiser_approximate_rho(_m,_beta);
#endif

    unsigned int n=2*_k*_m+1;                       // filter length
    float kf = (float)_k;                           // samples/symbol (float)
    float del = _beta*rho_hat / kf;                 // transition bandwidth
    float As = estimate_req_filter_As(del, n);      // stop-band suppression
    float fc  = 0.5f*(1 + _beta*(1.0f-rho_hat))/kf; // filter cutoff
    
#if DEBUG_RKAISER
    printf("rho-hat : %12.8f (compare to %12.8f)\n", rho_hat, rkaiser_approximate_rho(_m,_beta));
    printf("fc      : %12.8f\n", fc);
    printf("delta-f : %12.8f\n", del);
    printf("As      : %12.8f dB\n", As);
    printf("alpha   : %12.8f\n", kaiser_beta_As(As));
#endif

    // compute filter coefficients
    liquid_firdes_kaiser(n,fc,As,_dt,_h);

    // normalize coefficients
    float e2 = 0.0f;
    unsigned int i;
    for (i=0; i<n; i++) e2 += _h[i]*_h[i];
    for (i=0; i<n; i++) _h[i] *= sqrtf(_k/e2);
}