LFO/VCO with Map & Constrain

Status
Not open for further replies.
Hi all,

I'm using 2 x waveforms going into a mixer & trying to map/constrain each so that one acts as an LFO and one acts as an audible range oscillator.
Having a strange issue where knob2/4 are mapping/constraining correctly, but knob6/7 does not seem to read the potentiometer whatsoever and stays at the same rate, regardless of the pot value unless map/constrain is done after the following line:

Code:
waveform3.frequency(360 * knob6 + 0.25);

Meaning that the mapping/constraining of the values is done after the frequency is set. So obviously does nothing.

In the commented code, you can see how I tried to do this initially.
I could not figure out how to do that way, by mapping/constraining waveform1.frequency, etc.
I do not have access to an oscilloscope until next week, but I was wondering what the maximum/minimum frequency of the waveform object is?
My guess was 20Hz-20kHz, hence 1.023 = 20Hz & 1023.0 = 20kHz...

Code:
  // use the knobs to adjust parameters
  //float knob1 = (float)analogRead(A1) / 1023.0;
  float knob2 = (float)analogRead(A2) / 1023.0;
  knob2 = map(knob2, 0.0, 1023.0, 0.0, 1.023);
  knob2 = constrain(knob2, 0.0, 1.023);
  waveform1.frequency(360 * knob2 + 0.25);
  
  float knob3 = (float)analogRead(A3) / 1023.0;
  sine_fm1.frequency(knob3 * 1500 + 50);
  
  float knob6 = (float)analogRead(A18) / 1023.0; 
  waveform3.frequency(360 * knob6 + 0.25);
  knob6 = map(knob6, 0.0, 1023.0, 1.023, 1023.0);
  knob6 = constrain(knob6, 1.023, 1023.0);
  //map(waveform1.frequency, 0.0, 20000.0, 0.0, 20.0);
  //constrain(waveform1.frequency, 0.0, 20.0);
  //map(waveform3.frequency, 0.0, 20000.0, 20.0, 20000.0);
  //constrain(waveform3.frequency, 20.0, 20000.0);

  float knob4 = (float)analogRead(A6) / 1023.0;
  knob4 = map(knob4, 0.0, 1023.0, 0.0, 1.023);
  knob4 = constrain(knob4, 0.0, 1.023);
  waveform2.frequency(360 * knob4 + 0.25);

  float knob5 = (float)analogRead(A7) / 1023.0;
  sine_fm2.frequency(knob5 * 1500 + 50);
  
  float knob7 = (float)analogRead(A20) / 1023.0;
  waveform4.frequency(360 * knob7 + 0.25);
  knob7 = map(knob7, 0.0, 1023.0, 1.023, 1023.0);
  knob7 = constrain(knob7, 1.023, 1023.0);
  //map(waveform1.frequency, 0.0, 20000.0, 0.0, 20.0);
  //constrain(waveform1.frequency, 0.0, 20.0);
  //map(waveform3.frequency, 0.0, 20000.0, 20.0, 20000.0);
  //constrain(waveform3.frequency, 20.0, 20000.0);

Any clarification on this would be much appreciated.
 
Apologies for not posting the complete code:
Code:
#include <Bounce.h>

Bounce button0 = Bounce(0, 15);
Bounce button1 = Bounce(1, 15);  // 15 = 15 ms debounce time
Bounce button2 = Bounce(2, 15);

Bounce button3 = Bounce(3, 15);
Bounce button4 = Bounce(4, 15);  // 15 = 15 ms debounce time
Bounce button5 = Bounce(5, 15);
/*
Bounce button6 = Bounce(24, 15);
Bounce button7 = Bounce(25, 15);
*/
///////////////////////////////////
// copy the Design Tool code here
///////////////////////////////////

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

// GUItool: begin automatically generated code
AudioSynthWaveform       waveform1;      //xy=140,129
AudioSynthWaveform       waveform2;      //xy=170,392
AudioSynthWaveformSineModulated sine_fm2;       //xy=214,452
AudioSynthWaveformSineModulated sine_fm1;       //xy=219,187
AudioSynthWaveform       waveform3;      //xy=226,234
AudioSynthWaveform       waveform4;      //xy=235,498
AudioSynthKarplusStrong  string1;        //xy=242,535
AudioSynthSimpleDrum     drum1;          //xy=251,280
AudioEffectEnvelope      envelope1;      //xy=414,294
AudioMixer4              mixer1;         //xy=425,183
AudioEffectEnvelope      envelope2;      //xy=437,542
AudioMixer4              mixer3;         //xy=444,464
AudioMixer4              mixer2;         //xy=561,264
AudioMixer4              mixer4;         //xy=564,524
AudioOutputI2S           i2s1;           //xy=702,335
AudioConnection          patchCord1(waveform1, sine_fm1);
AudioConnection          patchCord2(waveform1, 0, mixer1, 0);
AudioConnection          patchCord3(waveform2, sine_fm2);
AudioConnection          patchCord4(waveform2, 0, mixer3, 0);
AudioConnection          patchCord5(sine_fm2, 0, mixer3, 2);
AudioConnection          patchCord6(sine_fm1, 0, mixer1, 2);
AudioConnection          patchCord7(waveform3, 0, mixer1, 1);
AudioConnection          patchCord8(waveform4, 0, mixer3, 1);
AudioConnection          patchCord9(string1, 0, mixer3, 3);
AudioConnection          patchCord10(drum1, 0, mixer1, 3);
AudioConnection          patchCord11(envelope1, 0, mixer2, 1);
AudioConnection          patchCord12(mixer1, 0, mixer2, 0);
AudioConnection          patchCord13(mixer1, envelope1);
AudioConnection          patchCord14(envelope2, 0, mixer4, 1);
AudioConnection          patchCord15(mixer3, 0, mixer4, 0);
AudioConnection          patchCord16(mixer3, envelope2);
AudioConnection          patchCord17(mixer2, 0, i2s1, 0);
AudioConnection          patchCord18(mixer4, 0, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=424,110
// GUItool: end automatically generated code

void setup() {
  Serial.begin(9600);
  AudioMemory(20);
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.32);
  
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  
  mixer1.gain(0, 0.75);
  mixer1.gain(1, 0.0);
  mixer1.gain(2, 0.0);
  mixer1.gain(3, 0.0);
  mixer2.gain(0, 0.15);
  mixer2.gain(1, 0.0);
  mixer2.gain(2, 0.0);
  mixer2.gain(3, 0.0);
  mixer3.gain(0, 0.75);
  mixer3.gain(1, 0.0);
  mixer3.gain(2, 0.0);
  mixer3.gain(3, 0.0);
  mixer4.gain(0, 0.15);
  mixer4.gain(1, 0.0);
  mixer4.gain(2, 0.0);
  mixer4.gain(3, 0.0);

  
  waveform1.begin(WAVEFORM_SAWTOOTH);
  waveform1.amplitude(0.75);
  waveform1.frequency(50);
  waveform1.pulseWidth(0.15);
  sine_fm1.frequency(440);
  sine_fm1.amplitude(0.75);
  waveform3.begin(WAVEFORM_SAWTOOTH);
  waveform3.frequency(200);
  waveform3.amplitude(0.75);
  waveform3.pulseWidth(0.15);
  //pink1.amplitude(0.75); //
  envelope1.attack(10);
  envelope1.hold(10);
  envelope1.decay(25);
  envelope1.sustain(0.4);
  envelope1.release(70);

  waveform2.begin(WAVEFORM_SAWTOOTH);
  waveform2.amplitude(0.75);
  waveform2.frequency(50);
  waveform2.pulseWidth(0.15);
  sine_fm2.frequency(440);
  sine_fm2.amplitude(0.75);
  waveform4.begin(WAVEFORM_SAWTOOTH);
  waveform4.frequency(200);
  waveform4.amplitude(0.75);
  waveform4.pulseWidth(0.15);
  //pink2.amplitude(0.75); //
  envelope2.attack(10);
  envelope2.hold(10);
  envelope2.decay(25);
  envelope2.sustain(0.4);
  envelope2.release(70);
}

int waveform_type = WAVEFORM_SAWTOOTH;
int mixer1_setting = 0;
int mixer2_setting = 0;
int mixer3_setting = 0;
int mixer4_setting = 0;
elapsedMillis timeout = 0;
bool mixer2_envelope = false;
bool mixer4_envelope = false;

void loop() {
  button0.update();
  button1.update();
  button2.update();
  button3.update();
  button4.update();
  button5.update();
  //button6.update();
  //button7.update();

  // Left changes the type of control waveform
  if (button0.fallingEdge()) {
    Serial.print("Control waveform 1: ");
    if (waveform_type == WAVEFORM_SAWTOOTH) {
      waveform_type = WAVEFORM_SINE;
      Serial.println("Sine");
    } else if (waveform_type == WAVEFORM_SINE) {
      waveform_type = WAVEFORM_SQUARE;
      Serial.println("Square");
    } else if (waveform_type == WAVEFORM_SQUARE) {
      waveform_type = WAVEFORM_TRIANGLE;
      Serial.println("Triangle");
    } else if (waveform_type == WAVEFORM_TRIANGLE) {
      waveform_type = WAVEFORM_PULSE;
      Serial.println("Pulse");
    } else if (waveform_type == WAVEFORM_PULSE) {
      waveform_type = WAVEFORM_SAWTOOTH;
      Serial.println("Sawtooth");
    }
    waveform1.begin(waveform_type);
    waveform3.begin(waveform_type);
  }

    if (button3.fallingEdge()) {
    Serial.print("Control waveform 2: ");
    if (waveform_type == WAVEFORM_SAWTOOTH) {
      waveform_type = WAVEFORM_SINE;
      Serial.println("Sine");
    } else if (waveform_type == WAVEFORM_SINE) {
      waveform_type = WAVEFORM_SQUARE;
      Serial.println("Square");
    } else if (waveform_type == WAVEFORM_SQUARE) {
      waveform_type = WAVEFORM_TRIANGLE;
      Serial.println("Triangle");
    } else if (waveform_type == WAVEFORM_TRIANGLE) {
      waveform_type = WAVEFORM_PULSE;
      Serial.println("Pulse");
    } else if (waveform_type == WAVEFORM_PULSE) {
      waveform_type = WAVEFORM_SAWTOOTH;
      Serial.println("Sawtooth");
    }
    waveform2.begin(waveform_type);
    waveform4.begin(waveform_type);
  }

  // middle button switch which source we hear from mixer1
  if (button1.fallingEdge()) {
    if (mixer1_setting == 0) {
      mixer1.gain(0, 0.75);
      mixer1.gain(1, 0.0);
      mixer1.gain(2, 0.0);
      mixer1.gain(3, 0.0);
      Serial.println("Mixer1: LFO");
      mixer1_setting = 1;
    } else if (mixer1_setting == 1) {
      mixer1.gain(0, 0.0);
      mixer1.gain(1, 0.75);
      mixer1.gain(2, 0.0);
      mixer1.gain(3, 0.0);
      Serial.println("Mixer1: VCO");
      mixer1_setting = 2;
    } else if (mixer1_setting == 2) {
      mixer1.gain(0, 0.0);
      mixer1.gain(1, 0.0);
      mixer1.gain(2, 0.75);
      mixer1.gain(3, 0.0);
      Serial.println("Mixer1: FM");
      mixer1_setting = 3;
    } else if (mixer1_setting == 3) {
      mixer1.gain(0, 0.0);
      mixer1.gain(1, 0.0);
      mixer1.gain(2, 0.0);
      mixer1.gain(3, 0.75);
      Serial.println("Mixer1: DRUM");
      mixer1_setting = 0;
    }
  }

  if (button4.fallingEdge()) {
    if (mixer3_setting == 0) {
      mixer3.gain(0, 0.75);
      mixer3.gain(1, 0.0);
      mixer3.gain(2, 0.0);
      mixer3.gain(3, 0.0);
      Serial.println("Mixer3: LFO");
      mixer3_setting = 1;
    } else if (mixer3_setting == 1) {
      mixer3.gain(0, 0.0);
      mixer3.gain(1, 0.75);
      mixer3.gain(2, 0.0);
      mixer3.gain(3, 0.0);
      Serial.println("Mixer3: VCO");
      mixer3_setting = 2;
    } else if (mixer3_setting == 2) {
      mixer3.gain(0, 0.0);
      mixer3.gain(1, 0.0);
      mixer3.gain(2, 0.75);
      mixer3.gain(3, 0.0);
      Serial.println("Mixer3: FM");
      mixer3_setting = 3;
    } else if (mixer3_setting == 3) {
      mixer3.gain(0, 0.0);
      mixer3.gain(1, 0.0);
      mixer3.gain(2, 0.0);
      mixer3.gain(3, 0.75);
      Serial.println("Mixer3: STRING");
      mixer3_setting = 0;
    }
  }

  // Right button activates the envelope
  if (button2.fallingEdge()) {
    mixer2.gain(0, 0.0);
    mixer2.gain(1, 1.0);
    mixer2_envelope = true;
    timeout = 0;
    envelope1.noteOn();
  }
  if (button2.risingEdge()) {
    envelope1.noteOff();
    timeout = 0;
  }

  if (button5.fallingEdge()) {
    mixer4.gain(0, 0.0);
    mixer4.gain(1, 1.0);
    mixer4_envelope = true;
    timeout = 0;
    envelope2.noteOn();
  }
  if (button5.risingEdge()) {
    envelope2.noteOff();
    timeout = 0;
  }

  // after 4 seconds of inactivity, go back to
  // steady listening instead of the envelope
  if (mixer2_envelope == true && timeout > 4000) {
    mixer2.gain(0, 0.15);
    mixer2.gain(1, 0.0);
    mixer2_envelope = false;
  }

    if (mixer4_envelope == true && timeout > 4000) { 
    mixer4.gain(0, 0.15);
    mixer4.gain(1, 0.0);
    mixer4_envelope = false;
  }
/*
    if (button6.fallingEdge) {
    Serial.println("VCO");
    constrain(waveform1.frequency, 20.0, 20000.0)

    else if ({
    Serial.println("VCO");
    constrain(waveform1.frequency, 20.0, 20000.0)
  })
  }
*/
  // use the knobs to adjust parameters
  //float knob1 = (float)analogRead(A1) / 1023.0;
  float knob2 = (float)analogRead(A2) / 1023.0;
  knob2 = map(knob2, 0.0, 1023.0, 0.0, 1.023);
  knob2 = constrain(knob2, 0.0, 1.023);
  waveform1.frequency(360 * knob2 + 0.25);
  
  float knob3 = (float)analogRead(A3) / 1023.0;
  sine_fm1.frequency(knob3 * 1500 + 50);
  
  float knob6 = (float)analogRead(A18) / 1023.0; 
  waveform3.frequency(360 * knob6 + 0.25);
  knob6 = map(knob6, 0.0, 1023.0, 1.023, 1023.0);
  knob6 = constrain(knob6, 1.023, 1023.0);
  //map(waveform1.frequency, 0.0, 20000.0, 0.0, 20.0);
  //constrain(waveform1.frequency, 0.0, 20.0);
  //map(waveform3.frequency, 0.0, 20000.0, 20.0, 20000.0);
  //constrain(waveform3.frequency, 20.0, 20000.0);

  float knob4 = (float)analogRead(A6) / 1023.0;
  knob4 = map(knob4, 0.0, 1023.0, 0.0, 1.023);
  knob4 = constrain(knob4, 0.0, 1.023);
  waveform2.frequency(360 * knob4 + 0.25);

  float knob5 = (float)analogRead(A7) / 1023.0;
  sine_fm2.frequency(knob5 * 1500 + 50);
  
  float knob7 = (float)analogRead(A20) / 1023.0;
  waveform4.frequency(360 * knob7 + 0.25);
  knob7 = map(knob7, 0.0, 1023.0, 1.023, 1023.0);
  knob7 = constrain(knob7, 1.023, 1023.0);
  //map(waveform1.frequency, 0.0, 20000.0, 0.0, 20.0);
  //constrain(waveform1.frequency, 0.0, 20.0);
  //map(waveform3.frequency, 0.0, 20000.0, 20.0, 20000.0);
  //constrain(waveform3.frequency, 20.0, 20000.0);
}

My aim is for this to be made for Eurorack, hence the left and right channels acting as separate mono channels.
 
I was wondering what the maximum/minimum frequency of the waveform object is?
My guess was 20Hz-20kHz, hence 1.023 = 20Hz & 1023.0 = 20kHz...

Sorry, meant to say 0Hz-20kHz here. 20Hz for the audible rate oscillator.
Also I am using the beta, does the above issue relate to that possibly?
 
Status
Not open for further replies.
Back
Top