Play a note when button is hold and metro ticks

Hi all, I am trying to play a note as long as a push button is being held and the metro ticks. I also have an adsr apply to the note being played. I currently get the button trigger adsr works very well, but I couldn’t figure out how the metro part.

I have a boolean variable called “gate” for the adsr, and trying to make the env.Process() when tick.process() && gate == true. Could someone help me with this question? Thank you!

#include "DaisyDuino.h"
DaisyHardware hw;
// Pin assignments
const int buttonPin = 26; // Pin for the button
const int ledPin = 27;   // Pin for the LED (built-in on most boards)
// Audio stuff
static Oscillator osc; // oscillator
float amp_button;// Button for amplitude control
size_t num_channels; // NUmber of audio output channel
//Envelope
Adsr env; // Create envelope from Adsr class
bool gate; // Gate for activate/inactivate envelope
Metro tick;

void MyCallback(float **in, float **out, size_t size){
  float osc_out, env_out;

  //Processing Audio
  for(size_t i = 0; i < size; i++){

    if(tick.Process() && gate){
      env_out = env.Process(true);
    }else{
      env_out = env.Process(false);
    }

    // env_out = env.Process(gate);
    osc.SetAmp(env_out);
    osc.SetFreq(440);// Put it here to avoid click
    osc_out = osc.Process();

    out[0][i] = osc_out;
    out[1][i] = osc_out;
  }
}

void setup() {
  // Initializations
  float sample_rate;
  hw = DAISY.init(DAISY_SEED, AUDIO_SR_48K);
  num_channels = hw.num_channels;
  sample_rate = DAISY.get_samplerate();

  //Set sample rate
  env.Init(sample_rate);
  osc.Init(sample_rate);

  // Set up metro to pulse
  tick.Init(1.0f, sample_rate);

  //Set envelope parameters
  env.SetTime(ADSR_SEG_ATTACK, .3);
  env.SetTime(ADSR_SEG_DECAY, .1);
  env.SetTime(ADSR_SEG_RELEASE, .5);

  env.SetSustainLevel(0.1);
  //Set waveform to sine
  osc.SetWaveform(osc.WAVE_SIN);

  //Start Audio Callback
  DAISY.begin(MyCallback);

  // Set up pin modes
  pinMode(buttonPin, INPUT_PULLUP); // Use internal pull-up resistor for the button
  pinMode(ledPin, OUTPUT);          // Set the LED pin as an output
}

void loop() {
  // Read the button state
  int buttonState = digitalRead(buttonPin);
  amp_button = buttonState;
  
  // Toggle the LED based on the button state
  if (buttonState == HIGH) { // Button pressed
    digitalWrite(ledPin, HIGH); // Turn LED on
    gate = true;
  } else {
    digitalWrite(ledPin, LOW);  // Turn LED off
    gate = false;
  }
}

I declared a new boolean variable “play”, and modified the part in the audiocallback by

bool play;

void MyCallback(float **in, float **out, size_t size){
  float osc_out, env_out;

  //Processing Audio
  for(size_t i = 0; i < size; i++){

    if(tick.Process() && gate){
      play = !play;
    }

    env_out = env.Process(play);

Now the note does triggered at the metro rate when I holding down the button , but the envelope seems not being triggered accurately sometimes as the note goes on forever as I release the button. I think there must be something wrong in my logic with the envelope gate signal? Could someone please help me with that? Thank you!