IIRFilter Help!


#1

Hi I’m experimenting with the IIRFilter and have a few questions:

1- The filters require the sample rate as a parameter, is there a way or how can I get this from the AudioSampleBuffer?

2- With the code below I have a lowpass filter at 100Hz but all I get is a weird sound that sounds ringy! and distorted What am I doing wrong? This is straight out of the vst demo, ps. for testing I’m only implementing process replacing at the moment

[code]// if we’re not accumulating, the output buffer’s contents are undefined
// (don’t assume they’re zero!) and we should overwrite it.
if (input.getNumChannels() > 0)
{
for (int channel = 0; channel < output.getNumChannels(); ++channel)
{
// for each output channel, copy the contents of the corresponding
// input channel (or if there are more outputs than inputs, just
// keep using the last input channel)

			output.copyFrom (channel, 
                             0, 
                             input, 
                             jmin (channel, input.getNumChannels() - 1),
                             0, 
                             input.getNumSamples());

		
		myfilter.makeLowPass(44100,100);
		myfilter.processSamples(output.getSampleData(channel,0),output.getNumSamples());
		

        }
		
		output.applyGain (0, output.getNumSamples(), gain);[/code]

Also if I replace the makeLowPass with BandPass it seems to have no effect. Any help welcome on setting up the IIRFilters.


#2

AudioBuffers don’t have a sample rate - they’re just a block of data. When your audiodevice is about to start, it makes a callback to tell you what sample rate it’s going to use, and that’s when you should initialise the filter - if you re-initialise it (like you’re doing here) before every block, then it’s not going to sound too great!


#3

Thanksl, so now I’m initializing it in prepare to play as:

void DemoJuceFilter::prepareToPlay (double sampleRate, int samplesPerBlock) { // do your pre-playback setup stuff here.. keyboardState.reset(); const double freq = 100.0f;//Hz myfilter.makeLowPass(sampleRate,freq); }

But its still pretty much the same still getting a weird sound!, could there be something wrong with the line:

also when and where should I reset the filter.


#4

Maybe you’ve got some feedback going on?

You have removed the makeLowPass call in the audio callback, haven’t you?


#5

Yes I’ve removed the makeLowPass from the ProcessBlock and added it to prepareToPlay but same problem still there. I would very much appreciate if you could outline exactly how I could get the IIRFilter working step by step. I’m not changing anything in the VST demo just building on top of it.

Another thing I’ve noticed is if I replace the makeLowPass with makeBandPass as follows, the IIRFilter seems to have no effect at all! on the signal no matter what frequency or Q value I choose

void DemoJuceFilter::prepareToPlay (double sampleRate, int samplesPerBlock) { // do your pre-playback setup stuff here.. keyboardState.reset(); const double freq = 1000.0f;//Hz myfilter.makeBandPass(sampleRate,freq,100,1.0f); }


#6

Looks like you’re doing the right thing - create the filter with a method like makeBandPass before you start using it, then repeatedly call the process method. You should probably also call reset() after makeBandPass(), to avoid clicks at the start of processing.


#7

Ive tried all of that!!!, Ive tested it in many different hosts sounding very strange to put it bluntly crap. I didn’t think it should be that difficult as there is only a few lines of code. I’m only trying to focus on the lowpassfilter at the moment.

Are your filters working ok? Is there any example you can provide me with? I know this sounds trivial however I can’t seem to get a clean sound out of it. You are welcome to replicate exactly what I did and you will notice the problem, please help as I’ve already spent a few hours on this.

I like to purchase a commercial license for juce as soon as possible however I’m just trying to get to learn it at this stage.


#8

Sorry, doh! I just looked again at your code and noticed the silly mistake that I should have seen immediately:

You can’t loop through the channels using a single filter on each one - a filter is stateful, and needs to be given a continuous stream of audio, so each channel needs its own separate filter.


#9

Your Da Man! working like a charm now!.. Now why couldn’t you have said that before:)


#10

one more question, as I’m initialising the filter in preparetoplay what would be the best method to be able to change the filters frequecy in realtime, as is now the filters frequency is preset at preparetoplay however I like to change it say with a slider to different values. Thanx again


#11

You can change the filter’s settings whenever you like - it’s all thread-safe, so there’s no problem tweaking it on a UI thread.


#12

Sorry, I’m a bit new to audio processing and still trying to wrap my head around some of the math. I need to use the IIRFilter for two purposes:

  1. as a biquad filter… so my coeffs are:

b0, b1, b2, a0, a1, a2

  1. as a first order (arbitrary?) filter… so my coeffs are:

b0, b1, a0, a1

I have my own code to set up the EQ (highpass, lowpass, etc.) on the coeffs so I imagine I can just call:

myFilter.setCoefficients(b0, b1, b2, a0, a1, a2);
myFilter.processSamples(buff, len);

My questions are:

a) How do I implement first order? (2) What do I set for b2 and a2? Zeros?

b) Do I need to normalize the coeffs before passing them to setCoefficients?

Thanks :slight_smile:

edit: answered b) myself… I see setcoeffs does this :wink:


#13