top of page

VCF

Stereo effect using the waveform object to modulate the filter. The toggle selects between lowpass/bandpass/highpass.


The mixers are controlled by the toggle switch, silencing all but one filter output (lp/bp/hp) at a time. The biquad filters smooth over the waveforms very slightly, removing the hard edges of square waves etc to prevent audible ticking.



Stereo VCF Sketch


A0 = waveform (sine, saw, reverse saw, square, triangle, pulse, s&h)

A1 = LFO rate

A2 = LFO Depth

A3 = resonance

Toggle = LP / BP / HP


#define LED 3
#include <Bounce.h>

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

// GUItool: begin automatically generated code
AudioSynthWaveform       waveform1;      //xy=328,196
AudioSynthWaveform       waveform2; //xy=327,492
AudioInputI2S            i2s1;           //xy=336,339
AudioFilterBiquad        biquad1;        //xy=478,197
AudioFilterBiquad        biquad2; //xy=477,493
AudioFilterStateVariable filter1;        //xy=624,258
AudioFilterStateVariable filter2; //xy=636,452
AudioMixer4              mixer1;         //xy=811,256
AudioMixer4              mixer2; //xy=814,458
AudioOutputI2S           i2s2;           //xy=986,368
AudioConnection          patchCord1(waveform1, biquad1);
AudioConnection          patchCord2(waveform2, biquad2);
AudioConnection          patchCord3(i2s1, 0, filter1, 0);
AudioConnection          patchCord4(i2s1, 1, filter2, 0);
AudioConnection          patchCord5(biquad1, 0, filter1, 1);
AudioConnection          patchCord6(biquad2, 0, filter2, 1);
AudioConnection          patchCord7(filter1, 0, mixer1, 0);
AudioConnection          patchCord8(filter1, 1, mixer1, 1);
AudioConnection          patchCord9(filter1, 2, mixer1, 2);
AudioConnection          patchCord10(filter2, 0, mixer2, 0);
AudioConnection          patchCord11(filter2, 1, mixer2, 1);
AudioConnection          patchCord12(filter2, 2, mixer2, 2);
AudioConnection          patchCord13(mixer1, 0, i2s2, 0);
AudioConnection          patchCord14(mixer2, 0, i2s2, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=1028,555
// GUItool: end automatically generated code

Bounce footswitch = Bounce(0, 50);  // debounce the footswitch
Bounce D1 = Bounce(1, 50);          // debounce the toggle switch
Bounce D2 = Bounce(2, 50);          // "  "  "  "  "  "  "  "  "

// this section includes the function to check the toggle position
bool right;
bool middle;
bool left;
void checkToggle () {               // this is our function to check toggle position...
D1.update();  D2.update();          // check digital inputs connected to toggle (can delete I think)
if(digitalRead(1) && !digitalRead(2))   {right = 1; middle = 0; left = 0;}    // toggle is right
if(digitalRead(1) && digitalRead(2))  {right = 0; middle = 1; left = 0;}      // toggle is in the middle
if(!digitalRead(1) && digitalRead(2))   {right = 0; middle = 0; left = 1;}    // toggle is left
}

// filter variables
byte wavepot;
byte waveform;
int pitch;
float q;
float depth;
float rate;

void setup() {
 
  AudioMemory(40); // the "40" represents how much internal memory (in the Teensy, not the external RAM chip) is allotted for audio recording. It is measured in sample blocks, each providing 2.9ms of audio.
  sgtl5000_1.enable();    // this turns on the SGTL5000, which is the audio codec on the audio board
  sgtl5000_1.volume(1);   // this sets the output volume (it can be between 0 and 1)
  sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN); // selects the audio input, we always use Line In
  analogReadResolution(12); // configure the pots to give 12 bit readings
  pinMode(0, INPUT_PULLUP); // internal pull-up resistor for footswitch
  pinMode(1, INPUT_PULLUP); // internal pull-up resistor for toggle
  pinMode(2, INPUT_PULLUP); // internal pull-up resistor for toggle
  pinMode(3, OUTPUT);       // pin 3 (the LED) is an output;
  Serial.begin(9600);       // initiate the serial monitor. USB is always 12 Mbit/sec

  // waveform filtering
  biquad1.setLowpass(0, 500, 0.2);
  biquad2.setLowpass(0, 500, 0.2);

  // filter set up
  filter1.octaveControl(3);
  filter2.octaveControl(3);
}

void loop() {
  
  // A0 = waveform
  wavepot = analogRead(A0) >> 9;                              // read waveform pot
  if(wavepot == 0) waveform = WAVEFORM_SINE;                  // assign waveform ....
  else if(wavepot == 1) waveform = WAVEFORM_SAWTOOTH;
  else if(wavepot == 2) waveform = WAVEFORM_SAWTOOTH_REVERSE;
  else if(wavepot == 3) waveform = WAVEFORM_SQUARE;
  else if(wavepot == 4) waveform = WAVEFORM_TRIANGLE;
  else if(wavepot == 5) waveform = WAVEFORM_PULSE;
  else if(wavepot == 6) waveform = WAVEFORM_SAMPLE_HOLD;
  if(wavepot == 7) { }

  // A1 = rate
  rate = (float) (analogRead(A1)/ 200) + 0.3;

  // A2 = depth
  depth = (float) analogRead(A2)/4095;                   // not working ?
  
  // set waveform
  waveform1.begin(depth, rate, waveform);
  waveform2.begin(depth, rate, waveform);

  // A3 = resonance
  q = (float)(analogRead(A3)/1000)+0.1;        // set Q with pot A2
  filter1.resonance(q);
  filter2.resonance(q);

  // lp / bp / hp
  checkToggle();
  // set mixers to allow lp, bp or hp through and adjust waveform offsets
  if(left) {mixer1.gain(0,1); mixer1.gain(1,0);mixer1.gain(2,0); waveform1.offset(1); mixer2.gain(0,1); mixer2.gain(1,0);mixer2.gain(2,0); waveform2.offset(1);}
  if(middle) {mixer1.gain(0,0); mixer1.gain(1,1);mixer1.gain(2,0); waveform1.offset(0.5); mixer2.gain(0,0); mixer2.gain(1,1);mixer2.gain(2,0); waveform2.offset(0.5);}
  if(right) {mixer1.gain(0,0); mixer1.gain(1,0);mixer1.gain(2,1); waveform1.offset(0); mixer2.gain(0,0); mixer2.gain(1,0);mixer2.gain(2,1); waveform2.offset(0);}
}




Recent Posts
Search By Tags
Glowfly_Logo_RGB_inv.png
bottom of page