Can't make my Mozzi ADSR envelope to work

Hi everyone,

I’m trying to make a simple 4 steps sequencer, and I’m stuck at a point where my ADSR envelope is not taked in account.

I followed every documentation and tutorial I could find, and I’m pretty sure I’m doing as they do (probably not).

What am I missing here please ?

​
#include <MozziGuts.h>
#include <Oscil.h> // oscillator template
#include <tables/saw2048_int8.h> // sine table for oscillator
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <EventDelay.h>
#include <LowPassFilter.h>
#include <ADSR.h>

Oscil <SAW2048_NUM_CELLS, AUDIO_RATE> saw(SAW2048_DATA);

// Current step
uint8_t seq=0;

// Frequencies
int frequencies[4] = {0, 0, 0, 0};

EventDelay stepRate(200);
EventDelay modeChange(5000);

LowPassFilter lpf;

// use #define for CONTROL_RATE, not a constant
#define CONTROL_RATE 32 // powers of 2 please

ADSR <CONTROL_RATE, AUDIO_RATE> envelope;

void setup(){
  startMozzi(CONTROL_RATE);
  
  stepRate.start();
  modeChange.start();
  
  lpf.setResonance(200);

  envelope.setADLevels(255, 64);
  envelope.setTimes(160, 30, 30, 30);

  getKnobsValuesToFrequencies();  
}


void updateControl(){
  getKnobsValuesToFrequencies();
  
  if(stepRate.ready()) {
    
    seq=(seq+1)%4;

    saw.setFreq(frequencies[seq]);
    
    envelope.noteOn();

    stepRate.start();
  }

  envelope.update();
}

// Sets the frequencies according to knob values
void getKnobsValuesToFrequencies() {
  frequencies[0] = map(readKnob(0),0,1023,10,1000);
  frequencies[1] = map(readKnob(1),0,1023,10,1000);
  frequencies[2] = map(readKnob(2),0,1023,10,1000);
  frequencies[3] = map(readKnob(3),0,1023,10,1000);
}

// Read the knob value on given pin
int readKnob(int pin) {
  int val = 0;
  for (int i=0; i< 2; i++) val += mozziAnalogRead(pin);
  val /= 2;

  return (int)val;
}

int updateAudio(){  
  int synth = saw.next();
  synth *= envelope.next();
  synth /= 150;
  synth >>= 8;
  return synth;
}

void loop(){
  audioHook(); // required here
}

mozzi_step.ino (1.76 KB)

stepRate.ready() will always be true after the 200ms delay, so you call noteOn every time.

You need to detect the change from false to true of the result of the call.

Thanks for the answer @MarkT !

I'm not sure on where I should test this.

So what I miss here is to send ans envelope.noteOff() when step is not ready ?

StateChangeDetection example in the Arduino software shows how to detect a change
in state, so that you don't repeatedly fire off noteOn()'s forever.

Thanks for this @MarkT,

I can't try it right now, but I will complete this post once it's done.

See you.