I am using resonant bandpasses to simulate modes of guitar/piano strings for audio synthesis. While attempting to introduce coupling effects I have encountered a problem.
I will illustrate with some simple code:
exciterFinal = exciter - (output * scalar_0to1);
resoBP.setInput(exciterFinal);
resoBP.setFilterCutoff(frequency);
resoBP.setFilterQ(Q);
output = resoBP.getOutput();
In other words, I am subtracting the prior sample's output multiplied by a scalar from 0 to 1 from the usual input of the bandpass to simulate a damping effect.
The most extreme effect would be with a scalar of 1 which should immediately damp the bandpass completely.
This works fine at frequencies below around ~9.4 kHz with normal damping behavior at 48 kHz sample rate. But once you go above that frequency with a scalar of 1, the filters tend to immediately self oscillate to overload. I tried with a State Variable Filter and a Butterworth Filter and had the same result with both.
Increasing the sample rate to 96 kHz allows it to work up to about 17.7 kHz. Above that point it still oscillates. So sampling seems to be the limiting factor. But I cannot afford the processing power to go up this high or higher to get the full spectrum of sound.
What is the reason for this behavior and why does it only happen at frequencies above roughly 19% of the sample rate? Is there any way to fix it?
Update: It just seems the filters become unstable when they are too aggressively damped this way at high frequency and low sample rate. My solution is to damp the filters instead by modifying their Q values when I need aggressive damping and be more gentle when I need to use the subtraction-from-input method. Good enough I guess.