little "click" when re-triggering envelope monophonic synth

emmanuel63

Well-known member
Hello,

I want to make a mono synth with one oscillator and one envelope. I experience little "clicks" when the envelope is re-triggered, even using te releaseNoteOn parameter. Any workaround ?
Emmanuel

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

// GUItool: begin automatically generated code
AudioSynthWaveformModulated waveformMod1;   //xy=407.7777862548828,293.3332977294922
AudioEffectEnvelope      envelope1;      //xy=589.9999847412109,293.33334159851074
AudioOutputI2S           i2s1;           //xy=742.2221412658691,292.2222366333008
AudioConnection          patchCord1(waveformMod1, envelope1);
AudioConnection          patchCord2(envelope1, 0, i2s1, 0);
AudioConnection          patchCord3(envelope1, 0, i2s1, 1);
// GUItool: end automatically generated code


byte MIDI_CHANNEL = 1;

//MIDI notes frequencies
const float noteFreqs[128] = {8.176, 8.662, 9.177, 9.723, 10.301, 10.913, 11.562, 12.25, 12.978, 13.75, 14.568, 15.434, 16.352, 17.324, 18.354, 19.445, 20.602, 21.827, 23.125, 24.5, 25.957, 27.5, 29.135, 30.868, 32.703, 34.648, 36.708, 38.891, 41.203, 43.654, 46.249, 48.999, 51.913, 55, 58.27, 61.735, 65.406, 69.296, 73.416, 77.782, 82.407, 87.307, 92.499, 97.999, 103.826, 110, 116.541, 123.471, 130.813, 138.591, 146.832, 155.563, 164.814, 174.614, 184.997, 195.998, 207.652, 220, 233.082, 246.942, 261.626, 277.183, 293.665, 311.127, 329.628, 349.228, 369.994, 391.995, 415.305, 440, 466.164, 493.883, 523.251, 554.365, 587.33, 622.254, 659.255, 698.456, 739.989, 783.991, 830.609, 880, 932.328, 987.767, 1046.502, 1108.731, 1174.659, 1244.508, 1318.51, 1396.913, 1479.978, 1567.982, 1661.219, 1760, 1864.655, 1975.533, 2093.005, 2217.461, 2349.318, 2489.016, 2637.02, 2793.826, 2959.955, 3135.963, 3322.438, 3520, 3729.31, 3951.066, 4186.009, 4434.922, 4698.636, 4978.032, 5274.041, 5587.652, 5919.911, 6271.927, 6644.875, 7040, 7458.62, 7902.133, 8372.018, 8869.844, 9397.273, 9956.063, 10548.08, 11175.3, 11839.82, 12543.85};


const byte queue_size = 10;
byte queue[queue_size];
int head = 0;  // Points to the front of the queue (oldest note)
int tail = 0;  // Points to the end of the queue (newest note)


void setup() {
  AudioMemory(10);
  waveformMod1.begin(0.05, 300, WAVEFORM_SINE);
  envelope1.attack(4);
  envelope1.decay(0);
  envelope1.sustain(1);
  envelope1.release(400);
  envelope1.releaseNoteOn(2);

  //***************************************************************MIDI************************************************************//
  usbMIDI.setHandleNoteOn(myNoteOn);
  usbMIDI.setHandleNoteOff(myNoteOff);
}

void loop() {
  usbMIDI.read(MIDI_CHANNEL);
}


void myNoteOn(byte channel, byte note, byte velocity) {

  waveformMod1.frequency(noteFreqs[note]);     // Set oscillator to the note frequency
  envelope1.noteOn();                          // Trigger envelope

  // Add the note to the queue (tail of the array)
  if (tail < queue_size) {
    queue[tail] = note;
    tail++;
  }
}

void myNoteOff(byte channel, byte note, byte velocity) {

  // Remove the note from the queue (search for it)
  for (int i = head; i < tail; i++) {
    if (queue[i] == note) {
      // Shift all elements after the removed note one position forward
      for (int j = i; j < tail - 1; j++) {
        queue[j] = queue[j + 1];
      }
      tail--;  // Decrease tail since we removed a note
      break;
    }
  }

  // If there are still active notes, re-trigger the most recent note
  if (tail > head) {
    byte mostRecentNote = queue[tail - 1];
    waveformMod1.frequency(noteFreqs[mostRecentNote]);  // Set to most recent note's frequency
    envelope1.noteOn();
  } else {
    // If no notes are left, close the envelope
    envelope1.noteOff();
  }
}
 
4ms attack and 2ms releaseNoteOn seem quite short and quick. Have you tried longer times, e.g. 20ms or so?
Are you planning to make the envelope settings a parameter you can change? You could start to control it via MIDI to play around with it.
 
Thanks for your answer. I have tried 20ms releaseNoteOn and it is indeed better. But I noticed that high releaseNoteOn setting causes stuck notes when playing very fast. I guess I have to find a compromis.
 
Back
Top