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