ref: 749a8cdea6c25a5a2ae02da035d51cb70d960518
parent: 73ceecdec47633af90ba738ddedf19a6795d1639
author: cancel <cancel@cancel.fm>
date: Sun Dec 9 14:17:39 EST 2018
Add note off timings to app deadline timing
--- a/osc_out.c
+++ b/osc_out.c
@@ -147,16 +147,21 @@
*end_removed = rem;
}
-void susnote_list_advance_time(Susnote_list* sl, float delta_time,
+void susnote_list_advance_time(Susnote_list* sl, double delta_time,
Usz* restrict start_removed,
- Usz* restrict end_removed) {
+ Usz* restrict end_removed,
+ double* soonest_deadline) {
Susnote* restrict buffer = sl->buffer;
Usz count = sl->count;
*end_removed = count;
+ float delta_float = (float)delta_time;
+ float soonest = 1.0f;
for (Usz i = 0; i < count;) {
Susnote sn = buffer[i];
- sn.remaining -= delta_time;
+ sn.remaining -= delta_float;
if (sn.remaining > 0) {
+ if (sn.remaining < soonest)
+ soonest = sn.remaining;
buffer[i].remaining = sn.remaining;
++i;
} else {
@@ -166,5 +171,17 @@
}
}
*start_removed = count;
+ *soonest_deadline = (double)soonest;
sl->count = count;
+}
+
+double susnote_list_soonest_deadline(Susnote_list const* sl) {
+ float soonest = 1.0f;
+ Susnote const* buffer = sl->buffer;
+ for (Usz i = 0, n = sl->count; i < n; ++i) {
+ float rem = buffer[i].remaining;
+ if (rem < soonest)
+ soonest = rem;
+ }
+ return (double)soonest;
}
--- a/osc_out.h
+++ b/osc_out.h
@@ -32,6 +32,10 @@
void susnote_list_add_notes(Susnote_list* sl, Susnote const* restrict notes,
Usz count, Usz* restrict start_removed,
Usz* restrict end_removed);
-void susnote_list_advance_time(Susnote_list* sl, float delta_time,
+void susnote_list_advance_time(Susnote_list* sl, double delta_time,
Usz* restrict start_removed,
- Usz* restrict end_removed);
+ Usz* restrict end_removed,
+ // 1.0 if no notes remain or none shorter than 1.0
+ double* soonest_deadline);
+// 1.0 if no notes remain or none shorter than 1.0
+double susnote_list_soonest_deadline(Susnote_list const* sl);
--- a/tui_main.c
+++ b/tui_main.c
@@ -511,6 +511,7 @@
Tui_input_mode input_mode;
Usz bpm;
double accum_secs;
+ double time_to_next_note_off;
char const* filename;
Oosc_dev* oosc_dev;
Midi_mode const* midi_mode;
@@ -537,6 +538,7 @@
a->input_mode = Tui_input_mode_normal;
a->bpm = 120;
a->accum_secs = 0.0;
+ a->time_to_next_note_off = 1.0;
a->filename = NULL;
a->oosc_dev = NULL;
a->midi_mode = NULL;
@@ -585,6 +587,12 @@
Susnote const* start, Susnote const* end) {
Midi_mode_type midi_mode_type = midi_mode->any.type;
for (; start != end; ++start) {
+#if 0
+ float under = start->remaining;
+ if (under < 0.0) {
+ fprintf(stderr, "cutoff slop: %f\n", under);
+ }
+#endif
U16 chan_note = start->chan_note;
Usz chan = chan_note >> 8u;
Usz note = chan_note & 0xFFu;
@@ -606,10 +614,11 @@
void apply_time_to_sustained_notes(Oosc_dev* oosc_dev,
Midi_mode const* midi_mode,
double time_elapsed,
- Susnote_list* susnote_list) {
+ Susnote_list* susnote_list,
+ double* next_note_off_deadline) {
Usz start_removed, end_removed;
- susnote_list_advance_time(susnote_list, (float)time_elapsed, &start_removed,
- &end_removed);
+ susnote_list_advance_time(susnote_list, time_elapsed, &start_removed,
+ &end_removed, next_note_off_deadline);
if (ORCA_UNLIKELY(start_removed != end_removed)) {
Susnote const* restrict susnotes_off = susnote_list->buffer;
send_midi_note_offs(oosc_dev, midi_mode, susnotes_off + start_removed,
@@ -622,6 +631,7 @@
send_midi_note_offs(a->oosc_dev, a->midi_mode, sl->buffer,
sl->buffer + sl->count);
susnote_list_clear(sl);
+ a->time_to_next_note_off = 1.0;
}
void send_output_events(Oosc_dev* oosc_dev, Midi_mode const* midi_mode, Usz bpm,
@@ -647,7 +657,7 @@
switch ((Oevent_types)e->any.oevent_type) {
case Oevent_type_midi: {
Oevent_midi const* em = (Oevent_midi const*)&e->midi;
- Usz note_number = (Usz)(12u * em->octave + em->note);
+ Usz note_number = (Usz)(12u * em->octave + em->note) + 48;
Usz channel = em->channel;
Usz bar_div = em->bar_divisor;
midi_note_ons[midi_note_count] =
@@ -658,6 +668,10 @@
.remaining =
bar_div == 0 ? 0.0f : (float)(bar_secs / (double)bar_div),
.chan_note = (U16)((channel << 8u) | note_number)};
+#if 0
+ fprintf(stderr, "bar div: %d, time: %f\n", (int)bar_div,
+ new_susnotes[midi_note_count].remaining);
+#endif
++midi_note_count;
} break;
}
@@ -695,8 +709,11 @@
if (a->is_playing) {
double secs_span = 60.0 / (double)a->bpm / 4.0;
double rem = secs_span - a->accum_secs;
+ double next_note_off = a->time_to_next_note_off;
if (rem < 0.0)
rem = 0.0;
+ else if (next_note_off < rem)
+ rem = next_note_off;
return rem;
} else {
return 1.0;
@@ -708,7 +725,8 @@
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);
+ apply_time_to_sustained_notes(oosc_dev, midi_mode, secs, &a->susnote_list,
+ &a->time_to_next_note_off);
}
}
@@ -734,6 +752,9 @@
a->oevent_list.buffer, count);
}
}
+ // note for future: sustained note deadlines may have changed due to note
+ // on. will need to update stored deadline in memory if
+ // app_apply_delta_secs isn't called again immediately after app_do_stuff.
}
}