示例#1
0
// create multi-stage half-band resampler
//  _type       : resampler type (e.g. LIQUID_RESAMP_DECIM)
//  _num_stages : number of resampling stages
//  _fc         : filter cut-off frequency 0 < _fc < 0.5
//  _f0         : filter center frequency
//  _As         : stop-band attenuation [dB]
MSRESAMP2() MSRESAMP2(_create)(int          _type,
                               unsigned int _num_stages,
                               float        _fc,
                               float        _f0,
                               float        _As)
{
    // validate input
    if (_num_stages > 10) {
        fprintf(stderr,"error: msresamp2_%s_create(), number of stages should not exceed 10\n", EXTENSION_FULL);
        exit(1);
    }

    // ensure cut-off frequency is valid
    if ( _fc <= 0.0f || _fc >= 0.5f ) {
        fprintf(stderr,"error: msresamp2_%s_create(), cut-off frequency must be in (0,0.5)\n", EXTENSION_FULL);
        exit(1);
    } else if ( _fc > 0.45f ) {
        fprintf(stderr,"warning: msresamp2_%s_create(), cut-off frequency greater than 0.45\n", EXTENSION_FULL);
        fprintf(stderr,"    >> truncating to 0.45\n");
        _fc = 0.45f;
    }

    // check center frequency
    if ( _f0 != 0. ) {
        fprintf(stderr,"warning: msresamp2_%s_create(), non-zero center frequency not yet supported\n", EXTENSION_FULL);
        _f0 = 0.;
    }

    unsigned int i;

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

    // set internal properties
    q->type       = _type == LIQUID_RESAMP_INTERP ? LIQUID_RESAMP_INTERP : LIQUID_RESAMP_DECIM;
    q->num_stages = _num_stages;
    q->fc         = _fc;
    q->f0         = _f0;
    q->As         = _As;

    // derived values
    q->M    = 1 << q->num_stages;
    q->zeta = 1.0f / (float)(q->M);

    // allocate memory for buffers
    q->buffer0 = (T*) malloc( q->M * sizeof(T) );
    q->buffer1 = (T*) malloc( q->M * sizeof(T) );

    // allocate arrays for half-band resampler parameters
    q->fc_stage = (float*)        malloc(q->num_stages*sizeof(float)       );
    q->f0_stage = (float*)        malloc(q->num_stages*sizeof(float)       );
    q->As_stage = (float*)        malloc(q->num_stages*sizeof(float)       );
    q->m_stage  = (unsigned int*) malloc(q->num_stages*sizeof(unsigned int));

    // determine half-band resampler parameters
    float fc = q->fc;
    float f0 = q->f0;
    for (i=0; i<q->num_stages; i++) {
        // compute parameters based on filter requirements;
        f0 = 0.5f*f0;   // update center frequency
        fc = 0.5f*fc;   // update cutoff frequency

        // estiamte required filter length
        float ft = (0.5f - fc)/2.0f;
        unsigned int h_len = estimate_req_filter_len(ft, q->As);
        unsigned int m = ceilf( (float)(h_len-1) / 4.0f );

        q->fc_stage[i] = fc;            // filter cut-of
        q->f0_stage[i] = f0;            // filter center frequency
        q->As_stage[i] = q->As;         // filter stop-band attenuation
        q->m_stage[i]  = m < 3 ? 3 : m; // minimum 2
    }

    // create half-band resampler objects
    q->resamp2 = (RESAMP2()*) malloc(q->num_stages*sizeof(RESAMP2()));
    for (i=0; i<q->num_stages; i++) {
        // create half-band resampler
        q->resamp2[i] = RESAMP2(_create)(q->m_stage[i],
                                         q->f0_stage[i],
                                         q->As_stage[i]);
    }

    // reset object
    MSRESAMP2(_reset)(q);

    // return main object
    return q;
}
示例#2
0
// create msresamp object
//  TODO: add signal bandwidth parameter?
//  TODO: add center frequency parameter; facilitates DDS object synthesis
//  _r              :   resampling rate [output/input]
//  _As             :   stop-band attenuation
MSRESAMP() MSRESAMP(_create)(float _r,
                             float _As)
{
    // validate input
    if (_r <= 0.0f) {
        fprintf(stderr,"error: msresamp_%s_create(), resampling rate must be greater than zero\n", EXTENSION_FULL);
        exit(1);
    }

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

    // set internal properties
    q->rate = _r;       // composite rate
    q->As   = _As;      // stop-band suppression

    // decimation or interpolation?
    q->type = (q->rate > 1.0f) ? LIQUID_RESAMP_INTERP : LIQUID_RESAMP_DECIM;

    // compute derived values
    q->rate_arbitrary = q->rate;
    q->rate_halfband  = 1.0f;
    q->num_halfband_stages = 0;
    switch(q->type) {
        case LIQUID_RESAMP_INTERP:
            while (q->rate_arbitrary > 2.0f) {
                q->num_halfband_stages++;
                q->rate_halfband  *= 2.0f;
                q->rate_arbitrary *= 0.5f;
            }
            break;
        case LIQUID_RESAMP_DECIM:
            while (q->rate_arbitrary < 0.5f) {
                q->num_halfband_stages++;
                q->rate_halfband  *= 0.5f;
                q->rate_arbitrary *= 2.0f;
            }
            break;
        default:;
    }

    // allocate memory for buffer
    q->buffer_len = 4 + (1 << q->num_halfband_stages);
    q->buffer = (T*) malloc( q->buffer_len*sizeof(T) );

    // create single multi-stage half-band resampler object
    // TODO: compute appropriate cut-off frequency
    q->halfband_resamp = MSRESAMP2(_create)(q->type,
                                            q->num_halfband_stages,
                                            0.4f, 0.0f, q->As);

    // create arbitrary resampler object
    // TODO: compute appropriate parameters
    q->arbitrary_resamp = RESAMP(_create)(q->rate_arbitrary, 7, 0.4f, q->As, 64);

    // reset object
    MSRESAMP(_reset)(q);

    // return main object
    return q;
}
示例#3
0
    float * fc_stage;           // cut-off frequency for each stage
    float * f0_stage;           // center frequency for each stage
    float * As_stage;           // stop-band attenuation for each stage
    unsigned int * m_stage;     // filter semi-length for each stage
    RESAMP2() * resamp2;        // array of half-band resamplers
    T * buffer0;                // buffer[0]
    T * buffer1;                // buffer[1]
    unsigned int buffer_index;  // index of buffer
    float zeta;                 // scaling factor
};

// execute multi-stage resampler as interpolator
//  _q      : msresamp object
//  _x      : input sample
//  _y      : output sample array  [size:2^_num_stages x 1]
void MSRESAMP2(_interp_execute)(MSRESAMP2() _q,
                                TI          _x,
                                TO *        _y);

// execute multi-stage resampler as decimator
//  _q      : msresamp object
//  _x      : input sample array  [size: 2^_num_stages x 1]
//  _y      : output sample pointer
void MSRESAMP2(_decim_execute)(MSRESAMP2() _q,
                               TI *        _x,
                               TO *        _y);

// create multi-stage half-band resampler
//  _type       : resampler type (e.g. LIQUID_RESAMP_DECIM)
//  _num_stages : number of resampling stages
//  _fc         : filter cut-off frequency 0 < _fc < 0.5