Modulating filter patch

Hi,

here is a first version of my first patch. This is a filter (the filter itself is Moog VCF filter) with a modulation on the resonance (Q factor). It actually sounds more like a tremolo.

////////////////////////////////////////////////////////////////////////////////////////////////////
// 2014-01-12 - blondinou - first version
////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef PsycheFilterPatch_hpp
#define PsycheFilterPatch_hpp

#include “StompBox.h”
#include <math.h>

#define TWOPI 6.2831853071f

#define MOD_SPEED 0.14f
#define MOD_LEVEL 1.0f
#define WET_DRY_COMPENSATION 1.5f
#define RES_MIN 0.1f
#define RES_MULT 0.4f

class PsycheFilterPatch : public Patch {
public:
PsycheFilterPatch() :
k(0.0f),
p(0.0f),
r(0.0f),
oldX(0.0f),
oldBuf0(0.0f),
oldBuf1(0.0f),
oldBuf2(0.0f),
x(0.0f),
buf0(0.0f),
buf1(0.0f),
buf2(0.0f),
buf3(0.0f),
phase(0.0f)
{
registerParameter(PARAMETER_A, “Resonance”);
registerParameter(PARAMETER_B, “Cutoff”, “Cutoff frequency”);
registerParameter(PARAMETER_C, “Modulation”, “Resonance modulation speed”);
registerParameter(PARAMETER_D, “Level”, “Effect level”);

	sampleRate = getSampleRate();
	for (int i = 0; i &lt; 6; i++) { knobs[i] = 0.f; }
}

void processAudio(AudioBuffer &amp;buffer) {
	if (parametersChanged()) {
		// update filter factors if knobs were moved
		updateFactors();
	}

	// modulation resonance
	float q = r;
	if (knobs[PARAMETER_C] &gt; 0.0f) {
		phase += MOD_SPEED * knobs[PARAMETER_C];
		if (phase &gt;= 1.0) {
			phase -= 1.0;
		}
		q += q * MOD_LEVEL * sinf(phase * TWOPI);
	}

	// apply filter
	float level = knobs[PARAMETER_D];
	int size = buffer.getSize();
	for (int ch = 0; ch &lt; buffer.getChannels(); ++ch) {
		float* buf = buffer.getSamples(ch);
		for (int i = 0; i &lt; size; i++) {
			x = buf[i] - q * buf3;

			buf0 = x * p + oldX * p - k * buf0;
			buf1 = buf0 * p + oldBuf0 * p - k * buf1;
			buf2 = buf1 * p + oldBuf1 * p - k * buf2;
			buf3 = buf2 * p + oldBuf2 * p - k * buf3;

			buf3 -= (buf3 * buf3 * buf3) / 6.f;

			oldX = x;
			oldBuf0 = buf0;
			oldBuf1 = buf1;
			oldBuf2 = buf2;

			buf[i] = (1.0f - level) * buf[i] + level * buf3 * WET_DRY_COMPENSATION;
		}
	}
}

private:
float knobs[6];
float k;
float p;
float r;
float oldX;
float oldBuf0;
float oldBuf1;
float oldBuf2;
float x;
float buf0;
float buf1;
float buf2;
float buf3;
float phase;
double sampleRate;

bool parametersChanged() {
	return getParameterValue(PARAMETER_A) != knobs[PARAMETER_A]
		|| getParameterValue(PARAMETER_B) != knobs[PARAMETER_B]
		|| getParameterValue(PARAMETER_C) != knobs[PARAMETER_C]
		|| getParameterValue(PARAMETER_D) != knobs[PARAMETER_D];
}

void updateFactors() {
	// update 
	knobs[PARAMETER_A] = getParameterValue(PARAMETER_A);
	knobs[PARAMETER_B] = getParameterValue(PARAMETER_B);
	knobs[PARAMETER_C] = getParameterValue(PARAMETER_C);
	knobs[PARAMETER_D] = getParameterValue(PARAMETER_D);

	// compute filter factors
	float resonance = RES_MIN + RES_MULT * knobs[PARAMETER_A];
	float cutoff = knobs[PARAMETER_B];
	cutoff = (cutoff * 4250.f) + 250.f;
	double sampleRate = getSampleRate();

	if (sampleRate == 0) {
		sampleRate = 44100.0;
	}

	float f = (cutoff + cutoff) / (float)sampleRate;
	p = f * (1.8f - 0.8f * f);
	k = p + p - 1.f;
	
	float t = (1.f - p) * 1.386249f;
	float t2 = 12.f + t * t;
	r = resonance * (t2 + 6.f*t) / (t2 - 6.f * t);
}

};

#endif // PsycheFilterPatch_hpp

Cool !
It is nice to have a first implementation of the Moog VCF.
Makes me wanna add a distortion term in the feedback loop!

I will test it on the Owl and include it in OwlPatches if you like.

Nice one -
if you send a git pull request then I will pull it into the OwlPatches main branch.

If you don’t fancy doing the whole git thing, let me know and I’ll simply add the source file.

The distortion in the feedback loop seems a nice idea. As all four knobs are already used, maybe I should find the better spot for the resonance to reuse the knob.

I think I’ve done a commit. That git thing seems very complicated, although I’m accustomed to SVN and ClearCase.

I think you have to fork the OwlPatches repository on github, create a branch, add and commit your file, then send a pull request to merge it with the master branch…
It’s a hassle if you’re not used to it, but it sets you up to submit more changes and patches in the future. If not, I’ll happily just add the file in, if you like. I’ve got it compiling and running on the pedal already - sounds good!

Ok, I think I managed to send the pull request.

Thanks for putting this together!

Here is a sample :
PsycheFilter

I set up a blog to publish the sample and introduce the patch :

I added the possibility to use an expression pedal to control the cutoff. To do this, cutoff and resonance must be set at 0.

Pull request sent ! It also fix clicks in stereo mode.

ok cool, thanks!

With the expression pedal, we’ve found that using it to modulate another parameter works well. You can see this in the Overdrive (latest version, just pushed to github).

    float expr = 1 - getParameterValue(PARAMETER_E);
    float drive = expr*getParameterValue(PARAMETER_A);

This way, if no pedal is plugged in the drive value will be set simply by knob A (multiplier is 1). If the pedal is active, it will control the drive from 0 up to whatever value A is set to. Thus A sets the upper limit of the drive - quite useful!