Main Archive Specials Wiki | FAQ Links Submit Forum


Fast Downsampling With Antialiasing

References : Posted by mumart[AT]gmail[DOT]com

Notes :
A quick and simple method of downsampling a signal by a factor of two with a useful amount of antialiasing. Each source sample is convolved with { 0.25, 0.5, 0.25 } before downsampling.

Code :
int filter_state;

/* input_buf can be equal to output_buf */
void downsample( int *input_buf, int *output_buf, int output_count ) {
int input_idx, input_end, output_idx, output_sam;
input_idx = output_idx = 0;
input_end = output_count * 2;
while( input_idx < input_end ) {
output_sam = filter_state + ( input_buf[ input_idx++ ] >> 1 );
filter_state = input_buf[ input_idx++ ] >> 2;
output_buf[ output_idx++ ] = output_sam + filter_state;
}
}



Comments


Added on : 06/01/06 by dsp[ AT ]dsparsons[ DOT ]nospam[ DOT ]co[ DOT ]uk
Comment :
I see this is designed for integers; what are you thoughts on altering it to floats and doing simple division rather than bit shifts?



Added on : 06/01/06 by mumart[ AT ]gmail[ DOT ]com
Comment :
It will work fine in floating point. I would probably use multiplication rather than division though, as I would expect that to be faster (ie. >> 1 --> *0.5, >>2 --> *0.25).



Added on : 11/03/06 by dfl[ AT ]ccrma[ DOT ]stanford[ DOT ]edu
Comment :
this triangular window is still not the greatest antialiaser... but it's probably fine for something like an oversampled lowpass filter!



Added on : 17/03/06 by mumart[ AT ]gmail[ DOT ]com
Comment :
For my purposes(modelling a first-order-hold dac) it was fine. The counterpart to it I suppose is this one - a classic exponential decay, which gives a lovely warm sound. Each sample is convolved with { 0.5, 0.25, 0.125, ...etc }

int filter_state;

void downsample( int *input_buf, int *output_buf, int output_count ) {
    int input_idx, output_idx, input_ep1;
    output_idx = 0;
    input_idx = 0;
    input_ep1 = output_count * 2;
    while( input_idx < input_ep1 ) {
        filter_state = ( filter_state + input_buf[ input_idx ] ) >> 1;
        output_buf[ output_idx ] = filter_state;
        filter_state = ( filter_state + input_buf[ input_idx + 1 ] ) >> 1;
        input_idx += 2;
        output_idx += 1;
    }
}

I'm not a great fan of all these high-order filters, the mathematics are more than I can cope with :)

Cheers,
Martin




Added on : 05/11/08 by k-asche[ AT ]web[ DOT ]de
Comment :
Hi @ all,

what is a good initialization value of filter_state?

Greetings

Karsten




Added on : 02/05/09 by mumart[ AT ]gmail[ DOT ]com
Comment :
filter_state is the previous input sample * 0.25, so zero is a good starting value for a non-periodic waveform.



Added on : 07/07/09 by bob[ AT ]yahoo[ DOT ]com
Comment :
I'm curious - as you're generating 1 sample for every 2, is it possible to then upsample with zero padding to get a half band filter at the original sample rate?

Cheers
B




Add your own comment
Comments are displayed in fixed width, no HTML code allowed!
Email:

Comment:

Are you human?



Site created and maintained by Bram
Graphic design by line.out | Server sponsered by fxpansion