How to mute minim filter

So I am building a synthesizer using the minim and oscP5 (controlling the synthesizer via touchOSC). Now I have this minim bandPass Filter set up, but I only want the filter to be active when a certain button is active (when its value == 1). The problem is that the filter is patched to the wave in setup, so I can’t just put an if statement there.

I tried finding a certain frequency and bandwidth so that it sounds like the filter is disabled, but the filter is still hearable and also visible in the waveform. I think the solution lies in unpatching the filter from the output, but I can’t seem to find the right syntax to make that work.

Here is my very stripped down code:

import ddf.minim.*;
import ddf.minim.ugens.*; 
import ddf.minim.effects.*; 

Minim       minim;
AudioOutput out;
Oscil       wave;
BandPass    filt1;

float freq1;
float amp = .5;
int thresh = 8;
int fps = 60;


void setup() {
  size(960, 540);
  frameRate(fps);
  background(0);
  rectMode(CENTER);


  minim = new Minim(this);
  out = minim.getLineOut();

  filt1 = new BandPass(440, 20, out.sampleRate());
  wave = new Oscil( 440, 0.5f, Waves.SQUARE );


  wave.patch(filt1).patch( out );
  //uncomment for wave w/o filter
  //wave.patch( out );
}


void draw() {
  background (#64C6A6);

  float passBand = map(mouseX, 0, width, 300, 2000);
  filt1.setFreq(passBand);
  float bandWidth = map(mouseY, 0, height, 300, 600);
  filt1.setBandWidth(bandWidth);



  float ellipseSize = height*.6;
  stroke(255);
  strokeWeight(4);
  float margin = 10;
  float waveAmp = 30;
  pushMatrix();
  translate(0, height/2);
  for (int i = 0; i < out.bufferSize() - 1; i++) {
    if (i> (width/2)-(ellipseSize/2)+margin && i< (width/2)+(ellipseSize/2)-margin) {
      line( i, - out.left.get(i)*waveAmp, i+1, - out.left.get(i+1)*waveAmp );
    }
  }
  popMatrix();
}

thanks for any help!

1 Like

Did you try “unpatch” ?

http://code.compartmental.net/minim/javadoc/ddf/minim/UGen.html#unpatch(ddf.minim.AudioOutput)

I am not a minim expert, but one methodical way is to:

  1. unpatch out from filt1
  2. unpatch filt1 from wave
  3. patch wave to out

Then, to switch it back

  1. unpatch wave from out
  2. patch wave to filt1
  3. patch filt1 to out

You can put this on a boolean flag and flip back and forth between these two patching transitions, like this:

import ddf.minim.*;
import ddf.minim.ugens.*; 
import ddf.minim.effects.*; 

Minim       minim;
AudioOutput out;
Oscil       wave;
BandPass    filt1;

float freq1;
float amp = .5;
int thresh = 8;
int fps = 60;

boolean bandOn;

void setup() {
  size(960, 540);
  frameRate(fps);
  background(0);
  rectMode(CENTER);

  minim = new Minim(this);
  out = minim.getLineOut();

  filt1 = new BandPass(440, 20, out.sampleRate());
  wave = new Oscil( 440, 0.5f, Waves.SQUARE );

  wave.patch(filt1).patch( out );
  bandOn = true;
}

void draw() {
  background (#64C6A6);

  float passBand = map(mouseX, 0, width, 300, 2000);
  filt1.setFreq(passBand);
  float bandWidth = map(mouseY, 0, height, 300, 600);
  filt1.setBandWidth(bandWidth);



  float ellipseSize = height*.6;
  stroke(255);
  strokeWeight(4);
  float margin = 10;
  float waveAmp = 30;
  pushMatrix();
  translate(0, height/2);
  for (int i = 0; i < out.bufferSize() - 1; i++) {
    if (i> (width/2)-(ellipseSize/2)+margin && i< (width/2)+(ellipseSize/2)-margin) {
      line( i, - out.left.get(i)*waveAmp, i+1, - out.left.get(i+1)*waveAmp );
    }
  }
  popMatrix();
}

void keyReleased() {
  if (bandOn) {
    filt1.unpatch(out);
    wave.unpatch(filt1);
    wave.patch(out);
    bandOn = false;
  } else {
    wave.unpatch(out);
    wave.patch(filt1);
    filt1.patch(out);
    bandOn = true;
  }
}

That’s almost exactly what I was looking for! But as I’m not using a keyboard as a controller, is there a way to make a function without keyReleased, but depending on the value of a OSC controller? So if one variable’s value is 1, unpatch. If its value is 0, patch.

Sure. Try moving the keyPressed code into a custom swap function. if your OSC signal is tested to true, then call the swap function.

import ddf.minim.*;
import ddf.minim.ugens.*; 
import ddf.minim.effects.*; 

Minim       minim;
AudioOutput out;
Oscil       wave;
BandPass    filt1;

float freq1;
float amp = .5;
int thresh = 8;
int fps = 60;

boolean bandOn;

void setup() {
  size(960, 540);
  frameRate(fps);
  background(0);
  rectMode(CENTER);

  minim = new Minim(this);
  out = minim.getLineOut();

  filt1 = new BandPass(440, 20, out.sampleRate());
  wave = new Oscil( 440, 0.5f, Waves.SQUARE );

  wave.patch(filt1).patch( out );
  bandOn = true;
}

void draw() {
  if (bandOn) {
    background (#64C6A6);
  } else {
    background (#C6A664);
  }

  boolean fakeOSCsignal = random(1.00)<0.01;
  if (fakeOSCsignal) {
    bandSwapper();
  }

  float passBand = map(mouseX, 0, width, 300, 2000);
  filt1.setFreq(passBand);
  float bandWidth = map(mouseY, 0, height, 300, 600);
  filt1.setBandWidth(bandWidth);

  float ellipseSize = height*.6;
  stroke(255);
  strokeWeight(4);
  float margin = 10;
  float waveAmp = 30;
  pushMatrix();
  translate(0, height/2);
  for (int i = 0; i < out.bufferSize() - 1; i++) {
    if (i> (width/2)-(ellipseSize/2)+margin && i< (width/2)+(ellipseSize/2)-margin) {
      line( i, - out.left.get(i)*waveAmp, i+1, - out.left.get(i+1)*waveAmp );
    }
  }
  popMatrix();
}

void bandSwapper() {
  if (bandOn) {
    filt1.unpatch(out);
    wave.unpatch(filt1);
    wave.patch(out);
    bandOn = false;
  } else {
    wave.unpatch(out);
    wave.patch(filt1);
    filt1.patch(out);
    bandOn = true;
  }
}

You may be able to simplify / speed up the patching like this:

  if (bandOn) {
    // filt1.unpatch(out);
    wave.unpatch(filt1);
    wave.patch(out);
    bandOn = false;
  } else {
    wave.unpatch(out);
    wave.patch(filt1);
    // filt1.patch(out);
    bandOn = true;
  }

…but minim is not my area of expertise, so experiment and see what works.

Thank you! Now the only problem was the bandSwapper was looping. constantly when the OSC trigger was activated as it was constantly returning 1. So i had to introduce two new variables, one storing the actual value of the OSC trigger and one storing the previous value and only trig bandSwapper when trigger!=ptrigger

1 Like

That’s right! Your “signal” to trigger a swap should be when your OSC value changes – and this requires comparing the new value to the previous value – OR changing the new value into a requested state, then comparing that to the previous state (bandOn).