A Collection of Useful C++ Classes for Signal Processing

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

BTW, regarding this http://www.kvraudio.com/forum/viewtopic ... 0#p6188078:

Dsp::SmoothedFilterDesign seems to produce a filter that does smooth real-time transitions. The last parameter "(1024)" is the transition length.

e.g.
Dsp::Filter * filt = new Dsp::SmoothedFilterDesign<Dsp::Bessel::Design::BandPass <1>, 2, Dsp::DirectFormII>(1024);

Post

Fluky wrote:Can you use the DSP::Filter::process function for numSamples = 1?
In real-time processing this is often the case that the samples are being read through one at a time, so can they be filtered one by one?

Or what would be the way to do filtering in real-time?
Hi Fluky. I don't know the lib and don't know if it will process a single sample at a time. It would be most reasonable if the lib could do so.

In what passes for "real time" processing in ordinary current computers, the audio is delivered in buffers. Sometimes 32 samples or less, sometimes 1024 or greater.

Though there is no guarantee how someone would write a library, it is possible to write multisample processing loops such that it is faster to process n samples in a tight loop with one call, rather than calling a 1 sample process for n times in a row.

In many cases it can be beneficial to do each stage of processing in blocks the same size as whatever is the audio buffer size, because it can be made faster. If you do 4 things to the audio, first do thing 1 on the entire buffer, then do thing 2 on an entire buffer, etc.

Sometimes this might require some temp buffers, just depending on what you wish to accomplish.

In very complicated cases maybe it would be less brain work to write the code so it does thing 1 thru thing 4 one sample at a time. But that one sample at a time method might be slower and offer fewer opportunities for speed optimization.

Post

Passes for real time?
The definition of real time processing is that it can be deterministically end in a certain time frame: https://en.wikipedia.org/wiki/Real-time_computing
The fact that it is done by buffers of size > 1 has nothing to do with this.

The main benefit is when using a modular library. This means that there are some virtual functions somewhere, and using a bigger buffer means that the overhead of calling these virtual function will be split accross several samples. Better than having several virtual calls per samples.

Post

Is there a scalable notch filter? A notch whose "depth" can be adjusted? Or a way to implement one?
Chebyshev II?

Also are the band-stop filters inverses of the band-passes or are the algos truly different?
If different, then is there are way to invert a band-stop filter to get a band-pass of the same shape?

Post

How to know the parameters (Dsp::Params) passable to any particular filter design and their order?

Code: Select all

That is, how to know:

Given some:

Dsp::Filter * f = new Dsp::SmoothedFilterDesign<Dsp::Bessel::Design::BandPass <1>, 2, Dsp::DirectFormII>(1024);

Then:

Dsp::Params params;
params[0] = ; // What
params[1] = ; // Are
params[2] = ; // These
params[3] = ; // ?
//Is there more?
f->setParams(params);
Also how to pass negative gain parameter (e.g. -24 in Butterworth BandShelf)?

Post

I have to say that I don't know directly how to go from a band pass to a band stop. At least for the general order. For a second order, it is possible to see an transformationbetween a band pass and a band stop. Usually transform go from low pass to XXX.

Post

Dsp::Filter * f = new Dsp::SmoothedFilterDesign<Dsp::Bessel::Design::BandShelf <1>, 2, Dsp::DirectFormII>(1024);

Produces error:
error C2039: 'getKind' : is not a member of 'Dsp::Butterworth::BandShelf<1>

What's wrong?

Post

Miles1981 wrote:Passes for real time?
The definition of real time processing is that it can be deterministically end in a certain time frame: https://en.wikipedia.org/wiki/Real-time_computing
The fact that it is done by buffers of size > 1 has nothing to do with this.

The main benefit is when using a modular library. This means that there are some virtual functions somewhere, and using a bigger buffer means that the overhead of calling these virtual function will be split accross several samples. Better than having several virtual calls per samples.
Thanks Miles. I "mostly retired" full time programming a couple years ago, and was never the sharpest tool in the shed.

Yes saving cpu cycles in function calling overhead. In some cases saving init time as well, "getting ready to work" depending on the task and method.

In 32 bit code, a favorite strategy I used a lot for things simple enough such as IIR filters-- Write fpu asm, load up the fpu stack with coeffs and state variables, load up all the loop control and such in integer registers, then rip thru a buffer with no memory access at all except for sample read and sample write.

In fact, over the years wrote so many utility functions like that (they work fine on both intel mac and pc), that if I ever get off my butt and do any 64 bit programming, it will be a PITA to adapt them. Have read that one can still use the fpu in 64 bit but apparently few people do so. Probably have to rewrite in higher level language or learn sse and rewrite in that.
Last edited by JCJR on Mon Jul 20, 2015 9:07 pm, edited 2 times in total.

Post

Duplicate message deleted

Post

Yes, everything changed, and the FPU is not a real FPU anymore, so you have to change everything. Or indeed rely on a higher level language (which is what I do, although it's not as fast as custom tailored code :/).

Post

Fluky wrote:Dsp::Filter * f = new Dsp::SmoothedFilterDesign<Dsp::Bessel::Design::BandShelf <1>, 2, Dsp::DirectFormII>(1024);

Produces error:
error C2039: 'getKind' : is not a member of 'Dsp::Butterworth::BandShelf<1>

What's wrong?
Help.

Post

@Fluky I was never able to get any of the Dsp::SmoothedFilterDesign examples to compile and stuck with Dsp::FilterDesign which was all I needed. Perhaps it was the version I was using or the author changed the setup. However, if you can get his demo to build, you can probably look there for usage examples.

The params[] vary by filter. For example, a Butterworth LPF needs the sample rate, order, and cutoff freq, and those are the first and only 3 params used when you call yourFilter->process(). Different filters and types may use similar or different params, so you need to look at the coded as to how to set up each of them.

I don't know of any real-time system that wants to process 1 sample at a time. Typically, you have an output rate to meet (e.g. 48000Hz) and you will need to supply a fixed amount of samples at a specific periodic rate. Usually, you get a signal telling you that the hardware is ready for another buffer block of samples. The hardware will have a fixed number of internal buffer blocks set up in a ring that will allow you time to process your audio. The total size of the hardware buffers determine your latency. The size of an individual buffer determines the time you have to process your audio. As an example, if you have a system running at 48 kHz, it may use a buffer size of 256 samples, which would mean you have ~5 milliseconds to process and supply the next block. If it uses 4 internal buffers, that gives you ~20 milliseconds of latency from the time you output a block to when it's heard.

Actually, I just remembered a system that processed 1 sample at a time. Back in the Stone Age, you made sound on PC's by toggling the internal speaker in real time, same as the old Apple ][. Fortunately, those days are a distant memory.

Post

ChocoBilly wrote:@Fluky I was never able to get any of the Dsp::SmoothedFilterDesign examples to compile and stuck with Dsp::FilterDesign which was all I needed. Perhaps it was the version I was using or the author changed the setup. However, if you can get his demo to build, you can probably look there for usage examples.
I've had some other Dsp::SmoothedFilterDesign working, but this one produces an error. Being a beginner in C++ understanding the code is slightly difficult, because to me it seems "correctish". I can't spot where the error even occurs as there's no line numbers or anything in the error message. getKind() seems to be defined, but I don't know what causes it to be not defined.

My whole project is now sort of dependent on this one particular filter, because I cannot do with other filter types than smooth-transition bandshelf.

Post

The main issue is because the library is a little bit overdesigned, and some templates should have restrictions that are not clearly explained...

Post

Miles1981 wrote:The main issue is because the library is a little bit overdesigned, and some templates should have restrictions that are not clearly explained...
I'd say not just a little bit... ;)

And of course now that Vinnie Falco seems to have abandoned it, nobody will be able to update/fix it. The code in the library is so overcomplicated I hardly ever look at the insides at all. It's hard enough to just try using the library.

I sometimes enjoy tinkering with overcomplicated C++ structures in my own code, but I don't particularly enjoy trying to figure out what other people have done in their code...

Post Reply

Return to “DSP and Plugin Development”