A Collection of Useful C++ Classes for Signal Processing
-
- KVRist
- 239 posts since 13 Oct, 2001 from montreal
Thanks for this! Have you considered hosting your code on google code or sourceforge? Seems to me it would be easier for both you and everyoe else that way...
- KVRian
- Topic Starter
- 775 posts since 30 Nov, 2008
Yes I will do all of the above, once I am "done". I don't want to publish unfinished code. I put it up here so I can get feedback on what I need to do to make it perfect. So when we have it bronzed there are no defects.mateo wrote:Thanks for this! Have you considered hosting your code on google code or sourceforge? Seems to me it would be easier for both you and everyoe else that way...
Before I put it out for wide distribution I would like to let it settle for a couple of weeks and give people a chance to play with it. And also, independent confirmation of the filter's output (by measuring the magnitude and phase response).
I'm working on SSE3 optimized version of CascadeFilter, its looking promising.
-
- KVRist
- 499 posts since 11 Jul, 2004 from Southern California, USA
No, sorry to say. A filter should produce bounded output for any bounded input.thevinn wrote:I wrote a simple loop to time the performance of the filter. I generate random noise in a buffer and then run the low pass on the data over and over again.
After just 3000 iterations, I get denormals. The debugger shows the samples as -1.#IND00000000
Is running a filter on the same block of data over and over again supposed to do that?
- KVRian
- Topic Starter
- 775 posts since 30 Nov, 2008
What if I'm using a Biquad that has a bit of resonance from the Q? If you filter the same block of noise over and over again it will get high values in the resonating part of the frequency spectrum, I think...MackTuesday wrote:No, sorry to say. A filter should produce bounded output for any bounded input.
When I lowered the Q the problem went away
- KVRian
- Topic Starter
- 775 posts since 30 Nov, 2008
File is updated:
- Added optimized template specialization for CascadeFilter::ProcessI()
in SSE3 intrinsics (MSVC) when channels=2 and stages=1 (all Biquads)
Sorry for the compiler specific stuff. If someone wants to help me add the necessary stuff to make it work with compilers other than MSVC, I would gladly add it in.
For the case of Biquads, and any Butterworth or Chebyshev filters with poles=2 channels=2, the SSE3_OPTIMIZED version is 38% faster.
- Added optimized template specialization for CascadeFilter::ProcessI()
in SSE3 intrinsics (MSVC) when channels=2 and stages=1 (all Biquads)
Sorry for the compiler specific stuff. If someone wants to help me add the necessary stuff to make it work with compilers other than MSVC, I would gladly add it in.
For the case of Biquads, and any Butterworth or Chebyshev filters with poles=2 channels=2, the SSE3_OPTIMIZED version is 38% faster.
-
- KVRist
- 499 posts since 11 Jul, 2004 from Southern California, USA
If the Q value was the cause and you lowered the Q, great. The fact remains that a useful filter gives bounded output no matter what bounded input it receives.thevinn wrote:What if I'm using a Biquad that has a bit of resonance from the Q? If you filter the same block of noise over and over again it will get high values in the resonating part of the frequency spectrum, I think...MackTuesday wrote:No, sorry to say. A filter should produce bounded output for any bounded input.
When I lowered the Q the problem went away
- KVRian
- Topic Starter
- 775 posts since 30 Nov, 2008
I agree but now that I think about it, the filter's input was unbounded. Because I was passing the same buffer back in over and over - each successive pass kept raising the value until it overflowed.MackTuesday wrote:If the Q value was the cause and you lowered the Q, great. The fact remains that a useful filter gives bounded output no matter what bounded input it receives.thevinn wrote:What if I'm using a Biquad that has a bit of resonance from the Q? If you filter the same block of noise over and over again it will get high values in the resonating part of the frequency spectrum, I think...MackTuesday wrote:No, sorry to say. A filter should produce bounded output for any bounded input.
When I lowered the Q the problem went away
-
- KVRian
- 769 posts since 18 Nov, 2008
Wow, this code looks cool.
But since I don't understand those depths of dsp programming, I'm sorry I can't say anything about the quality of the code itself, but how it is documented and how it is written (I mean it's style) is great.
One thing I noticed is the use of the postfix decrement and increment operators. Whenever possible, you should use the prefix versions of them for better efficiency. Most modern compilers will optimize the postfix versions of them under specific circumstances, but to be sure you should go for the prefix versions yourself. Especially the for loops seem to be predestinated for this little change, some other code must not be changed for sure, since it relies on the not yet incremented/decremented value of the variables.
If you do not already know, see e.g. here
http://www.thunderguy.com/semicolon/200 ... r-postfix/
for a more detailed explanation.
Keep up the good work,
Patrik
But since I don't understand those depths of dsp programming, I'm sorry I can't say anything about the quality of the code itself, but how it is documented and how it is written (I mean it's style) is great.
One thing I noticed is the use of the postfix decrement and increment operators. Whenever possible, you should use the prefix versions of them for better efficiency. Most modern compilers will optimize the postfix versions of them under specific circumstances, but to be sure you should go for the prefix versions yourself. Especially the for loops seem to be predestinated for this little change, some other code must not be changed for sure, since it relies on the not yet incremented/decremented value of the variables.
If you do not already know, see e.g. here
http://www.thunderguy.com/semicolon/200 ... r-postfix/
for a more detailed explanation.
Keep up the good work,
Patrik
-
- KVRist
- 499 posts since 11 Jul, 2004 from Southern California, USA
Do you mean that you were feeding the output data back into the input? That can cause a perfectly good filter to overflow. On the other hand, if you keep your input and output buffers separate, never changing your input buffer data, feeding it to the filter repeatedly, and the filter overflows, you have a problem.thevinn wrote:I agree but now that I think about it, the filter's input was unbounded. Because I was passing the same buffer back in over and over - each successive pass kept raising the value until it overflowed.MackTuesday wrote:If the Q value was the cause and you lowered the Q, great. The fact remains that a useful filter gives bounded output no matter what bounded input it receives.thevinn wrote:What if I'm using a Biquad that has a bit of resonance from the Q? If you filter the same block of noise over and over again it will get high values in the resonating part of the frequency spectrum, I think...MackTuesday wrote:No, sorry to say. A filter should produce bounded output for any bounded input.
When I lowered the Q the problem went away
- KVRian
- Topic Starter
- 775 posts since 30 Nov, 2008
Yes that is what I was doing. I wrote a loop to time the performance and it filtered the same buffer repeatedly. Eventually as you said, it overflowed.MackTuesday wrote:Do you mean that you were feeding the output data back into the input?
-
- KVRian
- 646 posts since 18 Feb, 2006 from California
I'm not sure I'm following the conversation here, because it morphed from denormals to overflow... unless I'm missing something in which case just ignore me. But one thing I learned recently is that filters often use internal saturation to prevent 'overflow' and keep things stable under all conditions. The result in your case (the feedback loop) will be a ringing at the center frequency.
- KVRian
- Topic Starter
- 775 posts since 30 Nov, 2008
Updated the file:
- Added SSE3 optimization for a general number of stages in
ProcessI() when channels==2
The general case of N stage 2 channel filtering in ProcessI() is now 65% faster with SSE3 instructions.
- Added SSE3 optimization for a general number of stages in
ProcessI() when channels==2
The general case of N stage 2 channel filtering in ProcessI() is now 65% faster with SSE3 instructions.
- KVRian
- Topic Starter
- 775 posts since 30 Nov, 2008
Updated the file. Provided lots of examples (see the function at the bottom) on how to use the classes for template-impaired folks (which I was not too long ago).
- KVRian
- Topic Starter
- 775 posts since 30 Nov, 2008
