Basic FIR Filtering


#1

Hello good people. I have tried to implement basic FIR filtering into my audio plugin. I have generated some coefficients with matlab,tried filtering a signal in matlab with those coeffs and everything was fine. Then I’ve tried the same thing in C++ but the results was not same nor close enough. Here are my coefficients,filter is order of 8 so i have 9 of them:

double filterCoefs[9] = { 0.0180524263969752, 0.0486396239380447, 0.122649723887587,
0.196847395914674, 0.227621659725439, 0.196847395914674,
0.122649723887587, 0.0486396239380447, 0.0180524263969752 };

Filter is basic low pass filter designed with fir1 function,cutoff frequency of 800Hz,where sample frequency is 44100Hz.
C++ code is next:

AudioBuffer output = buffer;

const int N = 8; //filter order

for (int channel = 0; channel < getTotalNumInputChannels(); ++channel)
{
	output.setSample(channel, 0, filterCoefs[0] * buffer.getSample(channel, 0));
	for (int n = 1; n < numSamples; n++)
	{
		if ((n - N) <= 0) {
			double tempSample = 0;
			for (int k = 0; k <= n; k++)
				tempSample = tempSample + filterCoefs[k] * buffer.getSample(channel, n - k);
			output.setSample(channel, n, tempSample);
		}
		else {
			double tempSample = 0;
			for (int k = 0; k <= N; k++)
				tempSample = tempSample + filterCoefs[k] * buffer.getSample(channel, n - k);
			output.setSample(channel, n, tempSample);
		}
	}
}

buffer = output;

Where buffer is the audio buffer I have in processBlock method of my processor class.
Is there something wrong with that C++ implementation or this whole way of realizing FIR filtering in C++ is wrong way to do that.

Best regards,Cila.

P.S. I have tried with more different coefficients and signals,I never get good results.


#2

JUCE already has a FIR filter implementation.

You can use the following method to use your specific coefficients.

FIR::Coefficients< NumericType >::Coefficients(const NumericType samples, size_t numSamples)

then you can instantiate one or more filters and use them in your processBlock with:

FIR::Filter< SampleType >::Filter(Coefficients< NumericType > * CoefficientsToUse)

Sorry if your question is more about algorithm correctness, I just guessed you might benefit from these handy methods.


#3

Thank you,I will try that later when i get home,I hope I can make it work.But it would be nice if someone can help me with the code I’ve posted,it is driving me crazy.


#4

It doesn’t look like you’re saving the filter state between callbacks, usually you’d write the audio buffer to a FIFO and use that as your delay line.


#5

Thank you a lot! It is working much better now. :slight_smile:


#6

Hi, sorry to hijack your thread - I’m also attempting to use the FIR methods with my own filter coefficients, but I can’t work out how to use an array of doubles as the coefficients. Would you mind sharing the relevant part of your code? I’m not having much luck with the snippest T4GG gave.


#7

Yes I will gladly share how I did my FIR filtering as soon as I get back home,around tuesday. I dont have my computrer with me.
Cila.


#8

Hello back. I have not forgot about you. Here it is my simple implementation of FIR filtering.
First I have defined some filter coefficients in header file of processor and delay line in length of number of coefficients.

 double filterCoefs[9] = { 0.0180524263969752,	0.0486396239380447,	0.122649723887587,
    		0.196847395914674,	0.227621659725439,	0.196847395914674,
    		0.122649723887587,	0.0486396239380447,	0.0180524263969752 };
 float delayLine[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};

After that, in cpp file in processBlock method:
AudioBuffer<FloatType> output = buffer;

for (int channel = 0; channel < getTotalNumInputChannels(); ++channel)
        		{

			float result = 0; // initialisation to 0 of the result

			for (int sample = 0; sample < buffer.getNumSamples(); sample++) { // for each sample

																			  // moving the samples in the delay line
				for (int i = 7; i >= 0; i--) { // delayLine being 9 values long
					delayLine[i + 1] = delayLine[i];
				}
				delayLine[0] = buffer.getSample(channel, sample);

				result = 0;
				for (int i = 0; i < 9; i++) { // for each tap
					result = result + delayLine[i] * filterCoefs[i]; // multiply     
				}
				output.setSample(channel, sample, result); // output
			}

		}

		buffer = output;
	}

Clearly it works for 9 coefficients only but it can easily be changed to different one, you will figure how easily. Try if that works and suites your needs, and if someone has some remarks please do say.


FIR Filter for decimation
#9

Hi, sorry it took a while to reply. I really appreciate you sharing your code, I’ll test out implementing something similar now!