     cv_out(CO1, seq_values.stage_cv[cached_stage]);
 
     // set gate and clock states
-    if(gate && (clock_gate || retrigger))
-    {
-      gt_out(GT_MULTI | (1 << GT5) | (1 << GT6), true);
-    }
-    else
-    {
-      gt_out(GT5, gate);
-      gt_out(GT6, clock_gate || retrigger);
-    }
-
-    // reset retrigger
-    if(retrigger)
-    {
-      retrigger = false;
-      clock_gate &= seq_values.clock_ext;
-    }
+    gt_out(GT5, gate);
+    gt_out(GT6, cached_clock_gate);
   }
 
  private:
   bool partial_gate()
   {
-    return (seq_values.clock_ext && clock_gate)
-           || (millis() - clock_time < (seq_values.gate_time * (seq_values.clock_period / 16000)))
-           || retrigger;
-  }
-
+    return (seq_values.clock_ext && cached_clock_gate)
+           || cached_retrigger
+           || ((millis() - clock_time) < seq_values.gate_ms);
+  }
+
+  uint8_t cached_stage, cached_step;
+  bool cached_clock_gate, cached_retrigger;
   unsigned long clock_time;
 };
 


  virtual void loop()
  {
    // cache stage and step
    uint8_t cached_stage, cached_step;
    ATOMIC_BLOCK(ATOMIC_FORCEON)
    {
      cached_stage = stage;
      cached_step = step;
    }

    if(retrigger)
    {
      if(!cached_step)
      {

 private:
  void update_clock()
  {
    Timer1.detachInterrupt();
    if(!seq_values.clock_ext)
    {
      Timer1.attachInterrupt(clock_isr, seq_values.clock_period);
    }
  }

