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;
}
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 @@ void susnote_list_advance_time(Susnote_list* sl, float delta_time,
}
}
*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;
}

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,
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);

31
tui_main.c

@ -511,6 +511,7 @@ typedef struct {
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 @@ void app_init(App_state* a) {
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 @@ void send_midi_note_offs(Oosc_dev* oosc_dev, Midi_mode const* midi_mode,
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 send_midi_note_offs(Oosc_dev* oosc_dev, Midi_mode const* midi_mode,
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 @@ void app_stop_all_sustained_notes(App_state* a) {
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 @@ void send_output_events(Oosc_dev* oosc_dev, Midi_mode const* midi_mode, Usz bpm,
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 @@ void send_output_events(Oosc_dev* oosc_dev, Midi_mode const* midi_mode, Usz bpm,
.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 @@ double app_secs_to_deadline(App_state const* a) {
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 @@ void app_apply_delta_secs(App_state* a, double secs) {
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 @@ void app_do_stuff(App_state* a) {
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