Browse Source

Change output activity indicator to be a visual counter

This changes the output meter from a VU/peak-like meter of recent
activity to an incrementing visual counter. I believe this is an
improvement, because it's now easier to discern output activity across a
broader range of activity levels.
master
cancel 5 years ago
parent
commit
62bad19cae
  1. 85
      tui_main.c

85
tui_main.c

@ -433,35 +433,67 @@ void undo_history_apply(Undo_history* hist, Field* out_field,
Usz undo_history_count(Undo_history* hist) { return hist->count; } Usz undo_history_count(Undo_history* hist) { return hist->count; }
void print_meter(WINDOW* win, float meter_level) { void print_activity_indicator(WINDOW* win, Usz activity_counter) {
enum { Segments = 7 }; // 7 segments that can each light up as Colors different colors.
int segs = (int)(meter_level * (float)Segments + 0.5f); // This gives us Colors^Segments total configurations.
if (segs < 0) enum { Segments = 7, Colors = 4 };
segs = 0; Usz states = 1; // calculate Colors^Segments
else if (segs > Segments) for (Usz i = 0; i < Segments; ++i)
segs = Segments; states *= Colors;
// Wrap the counter to the range of displayable configurations.
Usz val = activity_counter % states;
chtype lamps[Colors];
#if 1 // Appearance where segments are always lit
lamps[0] = ACS_HLINE | fg_bg(C_black, C_natural) | A_bold;
lamps[1] = ACS_HLINE | fg_bg(C_white, C_natural) | A_normal;
lamps[2] = ACS_HLINE | A_bold;
lamps[3] = lamps[1];
#elif 0 // Brighter appearance where segments are always lit
lamps[0] = ACS_HLINE | fg_bg(C_black, C_natural) | A_bold;
lamps[1] = ACS_HLINE | A_normal;
lamps[2] = ACS_HLINE | A_bold;
lamps[3] = lamps[1];
#else // Appearance where segments can turn off completely
lamps[0] = ' ';
lamps[1] = ACS_HLINE | fg_bg(C_black, C_natural) | A_bold;
lamps[2] = ACS_HLINE | A_normal;
lamps[3] = lamps[1];
#endif
chtype buffer[Segments]; chtype buffer[Segments];
int i = 0; for (Usz i = 0; i < Segments; ++i) {
for (; i < segs; ++i) { // Instead of a left-to-right, straightforward ascending least-to-most
buffer[i] = (i % 2 ? ACS_PLUS : ACS_HLINE) | A_REVERSE; // significant digits display, we'll display it as a spiral.
} Usz j = i % 2 ? (6 - i / 2) : (i / 2);
for (; i < Segments; ++i) { buffer[j] = lamps[val % Colors];
buffer[i] = ACS_HLINE | A_DIM; val = val / Colors;
} }
waddchnstr(win, buffer, Segments); waddchnstr(win, buffer, Segments);
// If you want to see what various combinations of colors and attributes look
// like in different terminals.
#if 0
waddch(win, 'a' | fg_bg(C_black, C_natural) | A_dim);
waddch(win, 'b' | fg_bg(C_black, C_natural) | A_normal);
waddch(win, 'c' | fg_bg(C_black, C_natural) | A_bold);
waddch(win, 'd' | A_dim);
waddch(win, 'e' | A_normal);
waddch(win, 'f' | A_bold);
waddch(win, 'g' | fg_bg(C_white, C_natural) | A_dim);
waddch(win, 'h' | fg_bg(C_white, C_natural) | A_normal);
waddch(win, 'i' | fg_bg(C_white, C_natural) | A_bold);
#endif
} }
void draw_hud(WINDOW* win, int win_y, int win_x, int height, int width, void draw_hud(WINDOW* win, int win_y, int win_x, int height, int width,
const char* filename, Usz field_h, Usz field_w, const char* filename, Usz field_h, Usz field_w,
Usz ruler_spacing_y, Usz ruler_spacing_x, Usz tick_num, Usz bpm, Usz ruler_spacing_y, Usz ruler_spacing_x, Usz tick_num, Usz bpm,
Ged_cursor* const ged_cursor, Ged_input_mode input_mode, Ged_cursor* const ged_cursor, Ged_input_mode input_mode,
float meter_level) { Usz activity_counter) {
(void)height; (void)height;
(void)width; (void)width;
wmove(win, win_y, win_x); wmove(win, win_y, win_x);
wprintw(win, "%dx%d\t%d/%d\t%df\t%d\t", (int)field_w, (int)field_h, wprintw(win, "%dx%d\t%d/%d\t%df\t%d\t", (int)field_w, (int)field_h,
(int)ruler_spacing_x, (int)ruler_spacing_y, (int)tick_num, (int)bpm); (int)ruler_spacing_x, (int)ruler_spacing_y, (int)tick_num, (int)bpm);
print_meter(win, meter_level); print_activity_indicator(win, activity_counter);
wmove(win, win_y + 1, win_x); wmove(win, win_y + 1, win_x);
wprintw(win, "%d,%d\t%d:%d\t", (int)ged_cursor->x, (int)ged_cursor->y, wprintw(win, "%d,%d\t%d:%d\t", (int)ged_cursor->x, (int)ged_cursor->y,
(int)ged_cursor->w, (int)ged_cursor->h); (int)ged_cursor->w, (int)ged_cursor->h);
@ -782,7 +814,7 @@ typedef struct {
Usz random_seed; Usz random_seed;
Usz drag_start_y; Usz drag_start_y;
Usz drag_start_x; Usz drag_start_x;
float meter_level; Usz activity_counter;
int win_h; int win_h;
int win_w; int win_w;
int grid_h; int grid_h;
@ -822,7 +854,7 @@ void ged_init(Ged* a, Usz undo_limit, Usz init_bpm, Usz init_seed) {
a->random_seed = init_seed; a->random_seed = init_seed;
a->drag_start_y = 0; a->drag_start_y = 0;
a->drag_start_x = 0; a->drag_start_x = 0;
a->meter_level = 0.0f; a->activity_counter = 0;
a->win_h = 0; a->win_h = 0;
a->win_w = 0; a->win_w = 0;
a->grid_h = 0; a->grid_h = 0;
@ -1074,15 +1106,6 @@ double ged_secs_to_deadline(Ged const* a) {
} }
} }
ORCA_FORCE_INLINE
static float float_clamp(float a, float low, float high) {
if (a < low)
return low;
if (a > high)
return high;
return a;
}
void ged_reset_clock(Ged* a) { a->clock = stm_now(); } void ged_reset_clock(Ged* a) { a->clock = stm_now(); }
void ged_do_stuff(Ged* a) { void ged_do_stuff(Ged* a) {
@ -1090,8 +1113,7 @@ void ged_do_stuff(Ged* a) {
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;
double secs = stm_sec(stm_since(a->clock)); double secs = stm_sec(stm_since(a->clock));
a->meter_level -= (float)secs; (void)secs; // unused, was previously used for activity meter decay
a->meter_level = float_clamp(a->meter_level, 0.0f, 1.0f);
if (!a->is_playing) if (!a->is_playing)
return; return;
bool do_play = false; bool do_play = false;
@ -1143,9 +1165,8 @@ void ged_do_stuff(Ged* a) {
if (count > 0) { if (count > 0) {
send_output_events(oosc_dev, midi_mode, a->bpm, &a->susnote_list, send_output_events(oosc_dev, midi_mode, a->bpm, &a->susnote_list,
a->oevent_list.buffer, count); a->oevent_list.buffer, count);
a->activity_counter += count;
} }
a->meter_level += (float)count * 0.2f;
a->meter_level = float_clamp(a->meter_level, 0.0f, 1.0f);
// note for future: sustained note deadlines may have changed due to note // note for future: sustained note deadlines may have changed due to note
// on. will need to update stored deadline in memory if // on. will need to update stored deadline in memory if
// ged_apply_delta_secs isn't called again immediately after ged_do_stuff. // ged_apply_delta_secs isn't called again immediately after ged_do_stuff.
@ -1246,7 +1267,7 @@ void ged_draw(Ged* a, WINDOW* win) {
draw_hud(win, win_h - Hud_height, 0, Hud_height, win_w, filename, draw_hud(win, win_h - Hud_height, 0, Hud_height, win_w, filename,
a->field.height, a->field.width, a->ruler_spacing_y, a->field.height, a->field.width, a->ruler_spacing_y,
a->ruler_spacing_x, a->tick_num, a->bpm, &a->ged_cursor, a->ruler_spacing_x, a->tick_num, a->bpm, &a->ged_cursor,
a->input_mode, a->meter_level); a->input_mode, a->activity_counter);
} }
if (a->draw_event_list) { if (a->draw_event_list) {
draw_oevent_list(win, &a->oevent_list); draw_oevent_list(win, &a->oevent_list);
@ -1653,6 +1674,7 @@ void ged_input_cmd(Ged* a, Ged_input_cmd ev) {
orca_run(a->field.buffer, a->mbuf_r.buffer, a->field.height, a->field.width, orca_run(a->field.buffer, a->mbuf_r.buffer, a->field.height, a->field.width,
a->tick_num, &a->oevent_list, a->piano_bits, a->random_seed); a->tick_num, &a->oevent_list, a->piano_bits, a->random_seed);
++a->tick_num; ++a->tick_num;
a->activity_counter += a->oevent_list.count;
a->piano_bits = ORCA_PIANO_BITS_NONE; a->piano_bits = ORCA_PIANO_BITS_NONE;
a->needs_remarking = true; a->needs_remarking = true;
a->is_draw_dirty = true; a->is_draw_dirty = true;
@ -1661,7 +1683,6 @@ void ged_input_cmd(Ged* a, Ged_input_cmd ev) {
if (a->is_playing) { if (a->is_playing) {
ged_stop_all_sustained_notes(a); ged_stop_all_sustained_notes(a);
a->is_playing = false; a->is_playing = false;
a->meter_level = 0.0f;
send_control_message(a->oosc_dev, "/orca/stopped"); send_control_message(a->oosc_dev, "/orca/stopped");
} else { } else {
undo_history_push(&a->undo_hist, &a->field, a->tick_num); undo_history_push(&a->undo_hist, &a->field, a->tick_num);

Loading…
Cancel
Save