ar1st0crat / NWaves

.NET DSP library with a lot of audio processing functions
MIT License
453 stars 71 forks source link

Bandpass frequencies #27

Closed CodeWithMichal closed 4 years ago

CodeWithMichal commented 4 years ago

Hi, I am trying to use Butterworth BandPass filter. I have a signal with sampling rate of 250Hz and I want to filter for frequencies 22-32. I Dont understand what exactly should I put in BandPassFilter constructor. The constructor takes f1 and f2 but that seems no to be frequency. I tried with:

myFilter = new BandPassFilter(22, 32, 6);

and then simply for online processing:

myFilter.Process(mySample)

but it returns NaN all the time. I believe it is because f1 and f2 should be float in range 0-1 but how can I tranform it into particular frequencies ?

ar1st0crat commented 4 years ago

Hi! You need to pass normalized frequencies. See here

CodeWithMichal commented 4 years ago

Hi, thank you for reply!

So having Sampling Rate 250Hz should I rather do following?

myFilter = new BandPassFilter(22/250, 32/250, 6);

or rather

myFilter = new BandPassFilter(22/125, 32/125, 6);

If I use 250 instead of 125 my filter is unstable

Edit:

If I reduce sampling rate to 125Hz and use myFilter = new BandPassFilter(22/125, 32/125, 6); then its fine but working with sampling rate 250Hz and myFilter = new BandPassFilter(22/250, 32/250, 6); makes filter usntable. What could be the root cause?

ar1st0crat commented 4 years ago

I guess the similar issue is described here. I checked the coefficients for your filter specs - they are the same (or at least very close to sciPy/MATLAB).

According to suggestion in the link I've provided, you can try applying SOS. Something like this:


var f1 = 22000 / 250000f;
var f2 = 32000 / 250000f;
var filter = new Filters.Butterworth.BandPassFilter(f1, f2, 6);

// break filter into second-order-sections:
var sos = DesignFilter.TfToSos(filter.Tf);
var sosFilter = new FilterChain(sos);

// apply SOS
var filteredSignal = sosFilter.ApplyTo(signal);

// or process online:
// foreach (var sample in signal)
//     var output = sosFilter.Process(sample);
CodeWithMichal commented 4 years ago

Thank you, applying SOS helped :)