Closed MucAcoustics closed 6 months ago
Hi, ApplyTo()
methods were initially designed to carry out the convolution, so the output length is signal_length + filter_size - 1
(although in case of diff equation the length is indeed identical to the input length).
First of all, you say you use IIR filter. It means that the impulse response (the filter kernel) has infinite length. For classic OverlapSave implementation it needs to be finite. In NWaves code the impulse response is just truncated at some particular size, i.e. the result can be close to what you expect, but still not precisely correct. So, did you try just auto mode (i.e. not a difference equation)? I.e. DiscreteSignal pOut = MyFilter.ApplyTo(p);
or DiscreteSignal pOut = MyFilter.FilterOnline(p);
?
If both still produce problems, can you try to use IirFilter64
class (with double precision and call the same methods above?
If you stick with OverlapSave then there are possible solutions (I assume you'll prefer the first one, but maybe 2 and 3 are also ok):
1) use OlsBlockConvolver
and FilterOnline()
method that processes the signal sample in a loop (just like in online scenario):
// not really correct because yours is IIR filter!
var length = 128; // we'll truncate impulse response by this length
var olsFilter = new OlsBlockConvolver(MyFilter.Tf.ImpulseResponse(length), 512);
var filtered = olsFilter.FilterOnline(signal);
// 512 is the FFT size, should be power of 2: 512, 1024, 2048, etc. (often it's ~4*filter_size)
2) simply ignore last filter_size - 1
samples
3) copy (if you don't care much about the memory): filteredSignal.First(signal.Length)
Lesson learnt! Thanks a lot for your hints. The IirFilter64 solution does the job. It runs MyFilter.ApplyTo(p), MyFilter now based on an IirFilter64 resp. FilterChain64, without any problems. Straightforward and stable. The default setting "Auto" for the FilterMethod is just as right. Great!
I made a DiscreteSignal variable from a float[] vector containing 5120 samples:
DiscreteSignal p = new DiscreteSignal(samplingFrequency, rawsamples, true);
The sampling frequency is 51200 1/s. Applying an iir Filter gives more samples at the output than the raw vector contains:
DiscreteSignal pOut = MyFilter.ApplyTo(p, FilteringMethod.OverlapSave);
where pOut has 5631 samples. Apparently, the extra samples chunk is related to the FilteringMethod setting. Using the FilteringMethod.DifferenceEquation pOut does not show the effect. pOut has 5120 samples then. However, this filtering method gives a garbled output signal. If I feed the filter with a pure 1 kHz tone, a low frequent signal interferes with the 1 kHz signal. The interfering signal seems to come from an unstable condition because the amplitude increases with time. To avoid this unstable condition I use the OverlapSave filtering method. But where do the extra samples come from then? What could the solution be to avoid them?