Browse Source

Add note off timings to app deadline timing

master
cancel 6 years ago
parent
commit
749a8cdea6
  1. 23
      osc_out.c
  2. 8
      osc_out.h
  3. 31
      tui_main.c

23
osc_out.c

@ -147,16 +147,21 @@ void susnote_list_add_notes(Susnote_list* sl, Susnote const* restrict notes,
*end_removed = rem; *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 start_removed,
Usz* restrict end_removed) { Usz* restrict end_removed,
double* soonest_deadline) {
Susnote* restrict buffer = sl->buffer; Susnote* restrict buffer = sl->buffer;
Usz count = sl->count; Usz count = sl->count;
*end_removed = count; *end_removed = count;
float delta_float = (float)delta_time;
float soonest = 1.0f;
for (Usz i = 0; i < count;) { for (Usz i = 0; i < count;) {
Susnote sn = buffer[i]; Susnote sn = buffer[i];
sn.remaining -= delta_time; sn.remaining -= delta_float;
if (sn.remaining > 0) { if (sn.remaining > 0) {
if (sn.remaining < soonest)
soonest = sn.remaining;
buffer[i].remaining = sn.remaining; buffer[i].remaining = sn.remaining;
++i; ++i;
} else { } else {
@ -166,5 +171,17 @@ void susnote_list_advance_time(Susnote_list* sl, float delta_time,
} }
} }
*start_removed = count; *start_removed = count;
*soonest_deadline = (double)soonest;
sl->count = count; 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;
}

8
osc_out.h

@ -32,6 +32,10 @@ void susnote_list_clear(Susnote_list* sl);
void susnote_list_add_notes(Susnote_list* sl, Susnote const* restrict notes, void susnote_list_add_notes(Susnote_list* sl, Susnote const* restrict notes,
Usz count, Usz* restrict start_removed, Usz count, Usz* restrict start_removed,
Usz* restrict end_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 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);

31
tui_main.c

@ -511,6 +511,7 @@ typedef struct {
Tui_input_mode input_mode; Tui_input_mode input_mode;
Usz bpm; Usz bpm;
double accum_secs; double accum_secs;
double time_to_next_note_off;
char const* filename; char const* filename;
Oosc_dev* oosc_dev; Oosc_dev* oosc_dev;
Midi_mode const* midi_mode; Midi_mode const* midi_mode;
@ -537,6 +538,7 @@ void app_init(App_state* a) {
a->input_mode = Tui_input_mode_normal; a->input_mode = Tui_input_mode_normal;
a->bpm = 120; a->bpm = 120;
a->accum_secs = 0.0; a->accum_secs = 0.0;
a->time_to_next_note_off = 1.0;
a->filename = NULL; a->filename = NULL;
a->oosc_dev = NULL; a->oosc_dev = NULL;
a->midi_mode = NULL; a->midi_mode = NULL;
@ -585,6 +587,12 @@ void send_midi_note_offs(Oosc_dev* oosc_dev, Midi_mode const* midi_mode,
Susnote const* start, Susnote const* end) { Susnote const* start, Susnote const* end) {
Midi_mode_type midi_mode_type = midi_mode->any.type; Midi_mode_type midi_mode_type = midi_mode->any.type;
for (; start != end; ++start) { 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; U16 chan_note = start->chan_note;
Usz chan = chan_note >> 8u; Usz chan = chan_note >> 8u;
Usz note = chan_note & 0xFFu; Usz note = chan_note & 0xFFu;
@ -606,10 +614,11 @@ void send_midi_note_offs(Oosc_dev* oosc_dev, Midi_mode const* midi_mode,
void apply_time_to_sustained_notes(Oosc_dev* oosc_dev, void apply_time_to_sustained_notes(Oosc_dev* oosc_dev,
Midi_mode const* midi_mode, Midi_mode const* midi_mode,
double time_elapsed, double time_elapsed,
Susnote_list* susnote_list) { Susnote_list* susnote_list,
double* next_note_off_deadline) {
Usz start_removed, end_removed; Usz start_removed, end_removed;
susnote_list_advance_time(susnote_list, (float)time_elapsed, &start_removed, susnote_list_advance_time(susnote_list, time_elapsed, &start_removed,
&end_removed); &end_removed, next_note_off_deadline);
if (ORCA_UNLIKELY(start_removed != end_removed)) { if (ORCA_UNLIKELY(start_removed != end_removed)) {
Susnote const* restrict susnotes_off = susnote_list->buffer; Susnote const* restrict susnotes_off = susnote_list->buffer;
send_midi_note_offs(oosc_dev, midi_mode, susnotes_off + start_removed, send_midi_note_offs(oosc_dev, midi_mode, susnotes_off + start_removed,
@ -622,6 +631,7 @@ void app_stop_all_sustained_notes(App_state* a) {
send_midi_note_offs(a->oosc_dev, a->midi_mode, sl->buffer, send_midi_note_offs(a->oosc_dev, a->midi_mode, sl->buffer,
sl->buffer + sl->count); sl->buffer + sl->count);
susnote_list_clear(sl); 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, void send_output_events(Oosc_dev* oosc_dev, Midi_mode const* midi_mode, Usz bpm,
@ -647,7 +657,7 @@ void send_output_events(Oosc_dev* oosc_dev, Midi_mode const* midi_mode, Usz bpm,
switch ((Oevent_types)e->any.oevent_type) { switch ((Oevent_types)e->any.oevent_type) {
case Oevent_type_midi: { case Oevent_type_midi: {
Oevent_midi const* em = (Oevent_midi const*)&e->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 channel = em->channel;
Usz bar_div = em->bar_divisor; Usz bar_div = em->bar_divisor;
midi_note_ons[midi_note_count] = midi_note_ons[midi_note_count] =
@ -658,6 +668,10 @@ void send_output_events(Oosc_dev* oosc_dev, Midi_mode const* midi_mode, Usz bpm,
.remaining = .remaining =
bar_div == 0 ? 0.0f : (float)(bar_secs / (double)bar_div), bar_div == 0 ? 0.0f : (float)(bar_secs / (double)bar_div),
.chan_note = (U16)((channel << 8u) | note_number)}; .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; ++midi_note_count;
} break; } break;
} }
@ -695,8 +709,11 @@ double app_secs_to_deadline(App_state const* a) {
if (a->is_playing) { if (a->is_playing) {
double secs_span = 60.0 / (double)a->bpm / 4.0; double secs_span = 60.0 / (double)a->bpm / 4.0;
double rem = secs_span - a->accum_secs; double rem = secs_span - a->accum_secs;
double next_note_off = a->time_to_next_note_off;
if (rem < 0.0) if (rem < 0.0)
rem = 0.0; rem = 0.0;
else if (next_note_off < rem)
rem = next_note_off;
return rem; return rem;
} else { } else {
return 1.0; return 1.0;
@ -708,7 +725,8 @@ void app_apply_delta_secs(App_state* a, double secs) {
a->accum_secs += secs; a->accum_secs += secs;
Oosc_dev* oosc_dev = a->oosc_dev; Oosc_dev* oosc_dev = a->oosc_dev;
Midi_mode const* midi_mode = a->midi_mode; 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 @@ void app_do_stuff(App_state* a) {
a->oevent_list.buffer, count); 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.
} }
} }

Loading…
Cancel
Save