shithub: orca

Download patch

ref: 20ec36ba667768a0a5c5a91a09802b07eae6fa59
parent: 0f2188554518cf23b26efd3edd487319943cce9e
author: cancel <cancel@cancel.fm>
date: Fri Dec 21 00:46:36 EST 2018

Change to use new timing method for main loop

--- a/tui_main.c
+++ b/tui_main.c
@@ -656,6 +656,7 @@
   Usz ruler_spacing_y, ruler_spacing_x;
   Ged_input_mode input_mode;
   Usz bpm;
+  U64 clock;
   double accum_secs;
   double time_to_next_note_off;
   char const* filename;
@@ -695,6 +696,7 @@
   a->ruler_spacing_x = 8;
   a->input_mode = Ged_input_mode_normal;
   a->bpm = 120;
+  a->clock = 0;
   a->accum_secs = 0.0;
   a->time_to_next_note_off = 1.0;
   a->filename = NULL;
@@ -889,10 +891,12 @@
   }
 }
 
+static double ms_to_sec(double ms) { return ms / 1000.0; }
+
 double ged_secs_to_deadline(Ged const* a) {
   if (a->is_playing) {
     double secs_span = 60.0 / (double)a->bpm / 4.0;
-    double rem = secs_span - a->accum_secs;
+    double rem = secs_span - (stm_sec(stm_since(a->clock)) + a->accum_secs);
     double next_note_off = a->time_to_next_note_off;
     if (rem < 0.0)
       rem = 0.0;
@@ -913,28 +917,35 @@
   return a;
 }
 
-void ged_apply_delta_secs(Ged* a, double secs) {
-  if (a->is_playing) {
-    a->accum_secs += secs;
-    Oosc_dev* oosc_dev = a->oosc_dev;
-    Midi_mode const* midi_mode = a->midi_mode;
-    apply_time_to_sustained_notes(oosc_dev, midi_mode, secs, &a->susnote_list,
-                                  &a->time_to_next_note_off);
-  }
-  a->meter_level -= (float)secs;
-  a->meter_level = float_clamp(a->meter_level, 0.0f, 1.0f);
-}
+void ged_reset_clock(Ged* a) { a->clock = stm_now(); }
 
 void ged_do_stuff(Ged* a) {
   double secs_span = 60.0 / (double)a->bpm / 4.0;
   Oosc_dev* oosc_dev = a->oosc_dev;
   Midi_mode const* midi_mode = a->midi_mode;
-  // Clamp to 1 second of buffered play time, in case the process get frozen,
-  // we don't want to play back a ton of steps all at once.
-  if (a->accum_secs > 1.0)
-    a->accum_secs = 1.0;
-  while (a->accum_secs > secs_span) {
-    a->accum_secs -= secs_span;
+  double secs = stm_sec(stm_since(a->clock));
+  a->meter_level -= (float)secs;
+  a->meter_level = float_clamp(a->meter_level, 0.0f, 1.0f);
+  apply_time_to_sustained_notes(oosc_dev, midi_mode, secs, &a->susnote_list,
+                                &a->time_to_next_note_off);
+  if (!a->is_playing)
+    return;
+  bool do_play = false;
+  for (;;) {
+    U64 now = stm_now();
+    U64 diff = stm_diff(now, a->clock);
+    double sdiff = stm_sec(diff) + a->accum_secs;
+    if (sdiff >= secs_span) {
+      a->clock = now;
+      a->accum_secs = sdiff - secs_span;
+      fprintf(stderr, "err: %f\n", a->accum_secs);
+      do_play = true;
+      break;
+    }
+    if (secs_span - sdiff > ms_to_sec(2.0))
+      break;
+  }
+  if (do_play) {
     orca_run(a->field.buffer, a->markmap_r.buffer, a->field.height,
              a->field.width, a->tick_num, &a->bank, &a->oevent_list,
              a->piano_bits);
@@ -956,8 +967,6 @@
   }
 }
 
-static double ms_to_sec(double ms) { return ms / 1000.0; }
-
 static inline Isz isz_clamp(Isz x, Isz low, Isz high) {
   return x < low ? low : x > high ? high : x;
 }
@@ -1417,11 +1426,11 @@
     if (a->is_playing) {
       ged_stop_all_sustained_notes(a);
       a->is_playing = false;
-      a->accum_secs = 0.0;
       a->meter_level = 0.0f;
     } else {
       undo_history_push(&a->undo_hist, &a->field, a->tick_num);
       a->is_playing = true;
+      a->clock = stm_now();
       // dumb'n'dirty, get us close to the next step time, but not quite
       a->accum_secs = 60.0 / (double)a->bpm / 4.0 - 0.02;
     }
@@ -1842,14 +1851,11 @@
 
   int key = KEY_RESIZE;
   wtimeout(stdscr, 0);
-  U64 last_time = 0;
   int cur_timeout = 0;
 
   for (;;) {
     switch (key) {
     case ERR: {
-      U64 diff = stm_laptime(&last_time);
-      ged_apply_delta_secs(&ged_state, stm_sec(diff));
       ged_do_stuff(&ged_state);
       bool drew_any = false;
       if (qnav_stack.stack_changed)
@@ -1872,17 +1878,15 @@
       qnav_stack.stack_changed = false;
       if (drew_any)
         doupdate();
-      diff = stm_laptime(&last_time);
-      ged_apply_delta_secs(&ged_state, stm_sec(diff));
       double secs_to_d = ged_secs_to_deadline(&ged_state);
       // fprintf(stderr, "to deadline: %f\n", secs_to_d);
       int new_timeout;
       if (secs_to_d < ms_to_sec(0.5)) {
         new_timeout = 0;
-      } else if (secs_to_d < ms_to_sec(3.0)) {
-        new_timeout = 1;
+      } else if (secs_to_d < ms_to_sec(2.0)) {
+        new_timeout = 0;
       } else if (secs_to_d < ms_to_sec(10.0)) {
-        new_timeout = 5;
+        new_timeout = 2;
       } else if (secs_to_d < ms_to_sec(50.0)) {
         new_timeout = 15;
       } else {
@@ -2107,9 +2111,6 @@
         ged_input_character(&ged_state, '.');
       } else {
         ged_input_cmd(&ged_state, Ged_input_cmd_toggle_play_pause);
-        // flush lap time -- quick hack to prevent time before hitting spacebar
-        // to play being applied as actual playback time
-        stm_laptime(&last_time);
       }
       break;
     case 27: // Escape