Biquad stage reset

Status
Not open for further replies.

brabudu

Member
Hello everybody.
i'm working with biqad filters, and sometimes i would like to reset a stage.
For example, i do

biquad.setBandpass(0,1000,1);
biquad.setBandpass(1,2000,1);

then i want to delete de second stage, to return to a one-stage filter.
It's possible?
Thank you
 
Just do

biquad.setBandpass(0,1000,1);

again. Each stage definition will terminate the string of filter stages unless it is for a stage one more than the last one,
so redefining the first stage will disable any subsequent stages.
 
Thank you Mark.
So if i do
biquad.setBandpass(0,1000,1);
biquad.setBandpass(1,2000,1);
biquad.setBandpass(1,3000,1);

it's equivalent to :
biquad.setBandpass(0,1000,1);
biquad.setBandpass(1,3000,1);

If i do:
biquad.setBandpass(0,1000,1);
biquad.setBandpass(1,2000,1);
biquad.setBandpass(1,3000,1);
biquad.setBandpass(0,2000,1);

it's equivalent to:
biquad.setBandpass(0,2000,1);

did I understand correctly?
 
Hello.
I tried to reset the filter with a new setting of the lower stage of the biquad (0) but the upper stage (1) remains set.
So in the following code the final noise is different from the initial noise (at 400Hz)

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioSynthNoiseWhite     noise1;         //xy=157,165
AudioFilterBiquad        biquad1;        //xy=462,172
AudioOutputAnalogStereo  dacs1;          //xy=693,173
AudioConnection          patchCord1(noise1, biquad1);
AudioConnection          patchCord2(biquad1, 0, dacs1, 0);
AudioConnection          patchCord3(biquad1, 0, dacs1, 1);
// GUItool: end automatically generated code



void setup() {
   AudioMemory(20);
  // put your setup code here, to run once:
  noise1.amplitude(.5);
  biquad1.setBandpass(0,400,1); //Low freq noise
  delay(2000);
  biquad1.setBandpass(0,5000,1); //High freq noise OK
  delay(2000);
  biquad1.setBandpass(1,5000,1); //More High freq noise OK
  delay(2000);
  biquad1.setBandpass(0,400,1); //Low freq noise? NO
  
}

void loop() {
  // put your main code here, to run repeatedly:

}
 
I've stared at the code again and think I've found a bug to do with this:
Code:
void AudioFilterBiquad::setCoefficients(uint32_t stage, const int *coefficients)
{
	if (stage >= 4) return;
	int32_t *dest = definition + (stage << 3);
	__disable_irq();
	if (stage > 0) *(dest - 1) |= 0x80000000;   // <<<<< this sets the continuation flag in previous stage, all as expected
	*dest++ = *coefficients++;
	*dest++ = *coefficients++;
	*dest++ = *coefficients++;
	*dest++ = *coefficients++ * -1;
	*dest++ = *coefficients++ * -1;
	//*dest++ = 0;
	//*dest++ = 0;  // clearing filter state causes loud pop
	dest += 2;
	*dest   &= 0x80000000;   // <<<<<  I assumed this should be clearing the cont flag, but to do that it needs to be  " *dest &= ~0x80000000; "
	__enable_irq();
}
However I'm not quite sure if this is the intention as the low order bits of the flag word are also
used to store the dither carry-over during filtering for that stage. Perhaps there was never an intention
to allow resetting, but changing that line to "* dest = 0 ;" would clear the cont flag and zero out the
dither carry (called sum in the rest of the code in filter_biquad.cpp).

The current code allows stages to be changed independently after the fact, which could be useful.

Perhaps the real fix is to add a method to reset the number of active stages explicitly.
 
Hi,

i think it's operating as intended, certainly the way I thought it operated i.e. once you have set a stage that is it set until you change it and the stage is independent of others.

I've used one stage to say set a low shelf and another with a high shelf then vary the gains of each of them independently to provide tone control.

If after you've set a stage you want to pass through then just open up the filter or set the coefficients directly (b0 = 1 and all the rest 0 for pass through?)

Cheers, Paul
 
Hi,
If after you've set a stage you want to pass through then just open up the filter or set the coefficients directly (b0 = 1 and all the rest 0 for pass through?)

Yes! I will try this,
cheers
 
Status
Not open for further replies.
Back
Top