void autotest_iirfiltsos_impulse_n2()
{
    // initialize filter with 2nd-order low-pass butterworth filter
    float a[3] = {
        1.000000000000000,
       -0.942809041582063,
        0.333333333333333};

    float b[3] = {
        0.0976310729378175,
        0.1952621458756350,
        0.0976310729378175};

    iirfiltsos_rrrf f = iirfiltsos_rrrf_create(b,a);

    // initialize oracle; expected output (generated with octave)
    float test[15] = {
       9.76310729378175e-02,
       2.87309604180767e-01,
       3.35965474513536e-01,
       2.20981418970514e-01,
       9.63547883225231e-02,
       1.71836926400291e-02,
      -1.59173219853878e-02,
      -2.07348926322729e-02,
      -1.42432702548109e-02,
      -6.51705310050832e-03,
      -1.39657983602602e-03,
       8.55642936806248e-04,
       1.27223450919543e-03,
       9.14259886013424e-04,
       4.37894317157432e-04};

    unsigned int i;
    float v, y;
    float tol=1e-4f;

    // hit filter with impulse, compare output
    for (i=0; i<15; i++) {
        v = (i==0) ? 1.0f : 0.0f;

        iirfiltsos_rrrf_execute(f, v, &y);

        CONTEND_DELTA(test[i], y, tol);
    }

    iirfiltsos_rrrf_destroy(f);
}
void autotest_iirfiltsos_step_n2()
{
    // initialize filter with 2nd-order low-pass butterworth filter
    float a[3] = {
        1.000000000000000,
       -0.942809041582063,
        0.333333333333333};

    float b[3] = {
        0.0976310729378175,
        0.1952621458756350,
        0.0976310729378175};

    iirfiltsos_rrrf f = iirfiltsos_rrrf_create(b,a);

    float test[15] = {
       0.0976310729378175,
       0.3849406771185847,
       0.7209061516321208,
       0.9418875706026352,
       1.0382423589251584,
       1.0554260515651877,
       1.0395087295798000,
       1.0187738369475272,
       1.0045305666927162,
       0.9980135135922078,
       0.9966169337561817,
       0.9974725766929878,
       0.9987448112021832,
       0.9996590710881966,
       1.0000969654053542};

    unsigned int i;
    float y;
    float tol=1e-4f;

    // hit filter with step, compare output
    for (i=0; i<15; i++) {
        iirfiltsos_rrrf_execute(f, 1.0f, &y);

        CONTEND_DELTA(test[i], y, tol );
    }

    iirfiltsos_rrrf_destroy(f);
}
예제 #3
0
파일: symsync.c 프로젝트: GRDSP/grdsp
// create synchronizer object from external coefficients
//  _k      : samples per symbol
//  _M      : number of filters in the bank
//  _h      : matched filter coefficients
//  _h_len  : length of matched filter
SYMSYNC() SYMSYNC(_create)(unsigned int _k,
                           unsigned int _M,
                           TC *         _h,
                           unsigned int _h_len)
{
    // validate input
    if (_k < 2) {
        fprintf(stderr,"error: symsync_%s_create(), input sample rate must be at least 2\n", EXTENSION_FULL);
        exit(1);
    } else if (_h_len == 0) {
        fprintf(stderr,"error: symsync_%s_create(), filter length must be greater than zero\n", EXTENSION_FULL);
        exit(1);
    } else if (_M == 0) {
        fprintf(stderr,"error: symsync_%s_create(), number of filter banks must be greater than zero\n", EXTENSION_FULL);
        exit(1);
    }

    SYMSYNC() q = (SYMSYNC()) malloc(sizeof(struct SYMSYNC(_s)));
    q->k = _k;

    q->M = _M;
    q->tau = 0.0f;
    q->bf  = 0.0f;
    q->b   = 0;

    // set output rate (nominally 1, full decimation)
    SYMSYNC(_set_output_rate)(q, 1);

    // TODO: validate length
    q->h_len = (_h_len-1)/q->M;
    
    // compute derivative filter
    TC dh[_h_len];
    float hdh_max = 0.0f;
    unsigned int i;
    for (i=0; i<_h_len; i++) {
        if (i==0) {
            dh[i] = _h[i+1] - _h[_h_len-1];
        } else if (i==_h_len-1) {
            dh[i] = _h[0]   - _h[i-1];
        } else {
            dh[i] = _h[i+1] - _h[i-1];
        }

        // find maximum of h*dh
        if ( fabsf(_h[i]*dh[i]) > hdh_max || i==0 )
            hdh_max = fabsf(_h[i]*dh[i]);
    }

    // apply scaling factor for normalized response
    // TODO: scale to 1.0 for consistency
    for (i=0; i<_h_len; i++)
        dh[i] *= 0.06f / hdh_max;
    
    q->mf  = FIRPFB(_create)(q->M, _h, _h_len);
    q->dmf = FIRPFB(_create)(q->M, dh, _h_len);

    // reset state and initialize loop filter
    q->A[0] = 1.0f;     q->B[0] = 0.0f;
    q->A[1] = 0.0f;     q->B[1] = 0.0f;
    q->A[2] = 0.0f;     q->B[2] = 0.0f;
    q->pll = iirfiltsos_rrrf_create(q->B, q->A);
    SYMSYNC(_reset)(q);
    SYMSYNC(_set_lf_bw)(q, 0.01f);

    // set output rate nominally at 1 sample/symbol (full decimation)
    SYMSYNC(_set_output_rate)(q, 1);

    // unlock loop control
    SYMSYNC(_unlock)(q);

#if DEBUG_SYMSYNC
    q->debug_del   = windowf_create(DEBUG_BUFFER_LEN);
    q->debug_tau   = windowf_create(DEBUG_BUFFER_LEN);
    q->debug_bsoft = windowf_create(DEBUG_BUFFER_LEN);
    q->debug_b     = windowf_create(DEBUG_BUFFER_LEN);
    q->debug_q_hat = windowf_create(DEBUG_BUFFER_LEN);
#endif

    // return main object
    return q;
}