 
   virtual void function_loop()
   {
-    if (retrigger)
-    {
-      env = selected_env;
-      gate_time = 0;
-      release_time = 0;
-      retrigger = false;
-    }
-
-    if (gate_time)
-    {
-      if (gate)
-      {
-        uint16_t elapsed = millis() - gate_time;
-        if (elapsed < adsr_values[env].A)
+    if (retrigger_)
+    {
+      env_ = selected_env_;
+      gate_time_ = 0;
+      release_time_ = 0;
+      retrigger_ = false;
+    }
+
+    if (gate_time_)
+    {
+      if (gate_)
+      {
+        uint16_t elapsed = millis() - gate_time_;
+        if (elapsed < adsr_values_[env_].A)
         {
           // attack
-          cv_current = ENV_PEAK * ENV_SATURATION * (1.0 - exp(-(float(elapsed) / float(adsr_values[env].A))));
+          cv_current_ = ENV_PEAK * ENV_SATURATION * (1.0 - exp(-(float(elapsed) / float(adsr_values_[env_].A))));
         }
         else
         {
           // decay/sustain
-          cv_current = adsr_values[env].S + (ENV_PEAK - adsr_values[env].S)
-              * exp(ENV_DECAY_COEFF * (float(elapsed - adsr_values[env].A) / float(adsr_values[env].D)));
+          cv_current_ = adsr_values_[env_].S + (ENV_PEAK - adsr_values_[env_].S)
+              * exp(ENV_DECAY_COEFF * (float(elapsed - adsr_values_[env_].A) / float(adsr_values_[env_].D)));
         }
       }
       else
       {
-        if (release_time)
+        if (release_time_)
         {
-          uint16_t elapsed = millis() - release_time;
-          if(elapsed < adsr_values[env].R * ENV_RELEASE_HOLD)
+          uint16_t elapsed = millis() - release_time_;
+          if(elapsed < adsr_values_[env_].R * ENV_RELEASE_HOLD)
           {
             // release
-            cv_current = exp(ENV_RELEASE_COEFF * (float(elapsed) / float(adsr_values[env].R))) * cv_released;
+            cv_current_ = exp(ENV_RELEASE_COEFF * (float(elapsed) / float(adsr_values_[env_].R))) * cv_released_;
           }
           else
           {
-            cv_current = 0.0;
-            release_time = 0;
-            gate_time = 0;
+            cv_current_ = 0.0;
+            release_time_ = 0;
+            gate_time_ = 0;
           }
         }
         else
         {
-          release_time = millis();
-          cv_released = cv_current;
+          release_time_ = millis();
+          cv_released_ = cv_current_;
         }
       }
 
-      cv_out(CO1, cv_current);
-      cv_out(CO3, cv_current / 2.0);
-    }
-    else if (gate)
-    {
-      gate_time = millis()
-          - (unsigned long)(-float(adsr_values[env].A) * log(1 - (cv_current / (ENV_PEAK * ENV_SATURATION))));
+      cv_out(CO1, cv_current_);
+      cv_out(CO3, cv_current_ / 2.0);
+    }
+    else if (gate_)
+    {
+      gate_time_ = millis()
+          - (unsigned long)(-float(adsr_values_[env_].A) * log(1 - (cv_current_ / (ENV_PEAK * ENV_SATURATION))));
     }
 
     widget_loop();
 
     // display selected envelope
-    if (selected_env != last_selected_env)
-    {
-      last_selected_env = selected_env;
+    if (selected_env_ != last_selected_env_)
+    {
+      last_selected_env_ = selected_env_;
       Display.fill_rect(53, 55, 7, 9, DUINO_SH1106::Inverse);
       Display.fill_rect(68, 55, 7, 9, DUINO_SH1106::Inverse);
       Display.display(53, 74, 6, 7);
     }
 
     // display gate
-    if (gate != last_gate)
-    {
-      last_gate = gate;
-      if (gate)
+    if (gate_ != last_gate_)
+    {
+      last_gate_ = gate_;
+      if (gate_)
       {
         Display.draw_bitmap_7(60, 25, icons, 0, DUINO_SH1106::White);
       }

    container_outer_->attach_child(container_adsr_, 1);
    container_adsr_->attach_scroll_callback_array(adsr_scroll_callback);

    gate = retrigger = false;
    selected_env = 0;
    debounce = 0;
    env = 0;
    gate_time = 0;
    release_time = 0;
    last_selected_env = 0;
    last_gate = false;

    gt_attach_interrupt(GT3, gate_isr, CHANGE);
    gt_attach_interrupt(GT4, switch_isr, FALLING);

  DUINO_SaveWidget<ParameterValues> * widget_save_;
  DUINO_DisplayWidget * widgets_adsr_[8];

  volatile bool gate_, retrigger_;
  volatile uint8_t selected_env_;
  volatile unsigned long debounce_;
  DU_ADSR_Values adsr_values_[2];
  uint8_t env_;
  unsigned long gate_time_, release_time_;
  float cv_current_, cv_released_;
  uint8_t last_selected_env_;
  bool last_gate_;
};

DU_ADSR_Function * function;
