feat: midi/keyboard cross working codes
Clang Lint CI / lint-no-video (push) Successful in 1m17s
Clang Build CI / run-no-video (push) Successful in 1m18s
Clang Build CI / run-video (push) Successful in 1m17s
Clang Build CI / build-release (push) Successful in 1m54s
Clang Lint CI / lint-video (push) Successful in 1m22s

This commit is contained in:
2026-05-14 22:52:08 +02:00
parent 6abf050bcc
commit 7b9f5ca032
4 changed files with 120 additions and 73 deletions
+2 -2
View File
@@ -286,9 +286,9 @@ We will not dig down all the variables here but feel free to read either:
Each input code can be either a midi event or a key code.
* 1 - 999 -> midi event
* 1001 - 1999 -> key code
* 0 - 999 -> midi event
* Keyboard modifiers are encoded like this:
* 1000 -> keyboard event
* 10000 -> shift
* 100000 -> control
* 1000000 -> alt
+2 -2
View File
@@ -138,9 +138,9 @@ FRAG_MONITOR=10
# I/O Inputs
# ==========
# Each code either maps to a midi event or a key code
# 1 - 999 -> midi event
# 1001 - 1999 -> key code
# 0 - 999 -> midi event
# Keyboard modifiers are encoded like this:
# 1000 -> keyboard event
# 10000 -> shift
# 100000 -> control
# 1000000 -> alt
+2 -2
View File
@@ -83,9 +83,9 @@ FRAG_MONITOR=2
# I/O Inputs
# ==========
# Each code either maps to a midi event or a key code
# 1 - 999 -> midi event
# 1001 - 1999 -> key code
# 0 - 999 -> midi event
# Keyboard modifiers are encoded like this:
# 1000 -> keyboard event
# 10000 -> shift
# 100000 -> control
# 1000000 -> alt
+114 -67
View File
@@ -402,64 +402,60 @@ void state_parse_config(StateConfig *state_config, const ConfigFile *config) {
}
}
void state_midi_event(Context *context, StateConfig state_config,
MidiDevice midi, unsigned char code, unsigned char value,
bool trace_midi) {
static bool compute_event(Context *context, StateConfig state_config,
MidiDevice midi, unsigned int code,
unsigned int value) {
unsigned int i;
unsigned int j;
unsigned int k;
unsigned int part;
bool found;
found = false;
// PAGE CHANGE
i = arr_uint_index_of(state_config.select_page_codes, code);
if (i != ARRAY_NOT_FOUND) {
found = true;
if (value > 0) {
context->page = i;
update_page(context, state_config, midi);
}
return true;
}
// TARGET CHANGE
i = arr_uint_index_of(state_config.select_frag_codes, code);
if (i != ARRAY_NOT_FOUND) {
found = true;
if (value > 0) {
context->selected = i;
update_page(context, state_config, midi);
}
return true;
}
// ITEM CHANGE
i = arr_uint_index_of(state_config.select_item_codes, code);
if (i != ARRAY_NOT_FOUND) {
found = true;
if (value > 0) {
context->state.values[context->selected] =
context->page * state_config.select_item_codes.length + i;
update_page(context, state_config, midi);
}
return true;
}
// ACTIVE CHANGE
i = arr_uint_index_of(state_config.group_active_codes, code);
if (i != ARRAY_NOT_FOUND) {
found = true;
if (value > 0) {
part = arr_uint_remap_index(state_config.group_active_offsets, &i);
context->active[part] = i;
update_active(context, state_config, midi, true);
update_values(context, state_config, midi);
}
return true;
}
// VALUE CHANGE
i = arr_uint_index_of(state_config.codes, code);
if (i != ARRAY_NOT_FOUND) {
found = true;
j = i / 3;
part = arr_uint_remap_index(state_config.group_offsets, &j);
k = state_config.values_offsets.values[part] +
@@ -476,20 +472,121 @@ void state_midi_event(Context *context, StateConfig state_config,
safe_midi_write(midi, code, MIDI_MAX);
}
}
return true;
}
// TAP TEMPO
if (code == state_config.tap_tempo_code) {
found = true;
safe_midi_write(midi, code, value);
if (value > 0) {
tempo_tap(&context->tempo);
}
return true;
}
if (!found) {
if (trace_midi) {
log_trace("unknown midi: %d %d", code, value);
// OTHER KEYS
if (code == state_config.key_randomize) {
if (value > 0) {
log_info("[%d] Randomized", code);
randomize(context, state_config);
update_values(context, state_config, midi);
}
return true;
}
if (code == state_config.key_reset) {
if (value > 0) {
log_info("[%d] Reset", code);
reset(context);
update_values(context, state_config, midi);
}
return true;
}
if (code == state_config.key_demo) {
if (value > 0) {
log_info((context->demo ? "[%d] Demo OFF" : "[%d] Demo ON"), code);
context->demo = !context->demo;
}
return true;
}
if (code == state_config.key_autorand) {
if (value > 0) {
log_info((context->auto_random ? "[%d] Auto Random OFF"
: "[%d] Auto Random ON"),
code);
context->auto_random = !context->auto_random;
}
return true;
}
if (code == state_config.key_autorand_down) {
if (value > 0) {
if (context->auto_random_cycle > 1) {
context->auto_random_cycle -= 1;
}
log_info("[%d] Auto Random Cycle: %d", code, context->auto_random_cycle);
}
return true;
}
if (code == state_config.key_autorand_up) {
if (value > 0) {
context->auto_random_cycle += 1;
log_info("[%d] Auto Random Cycle: %d", code, context->auto_random_cycle);
}
return true;
}
if (code == state_config.key_tempo_up) {
if (value > 0) {
tempo_set(&context->tempo, context->tempo.tempo + 1);
log_info("[%d] Tempo: %f", code, context->tempo);
}
return true;
}
if (code == state_config.key_tempo_down) {
if (value > 0) {
if (context->tempo.tempo > 0) {
tempo_set(&context->tempo, context->tempo.tempo - 1);
}
log_info("[%d] Tempo: %f", code, context->tempo);
}
return true;
}
// LOAD STATE
i = arr_uint_index_of(state_config.key_load, code);
if (i != ARRAY_NOT_FOUND) {
if (value > 0) {
log_info("[%d] Loading state %d", code, i + 1);
load_from_index_file(context, state_config, i + 1);
}
return true;
}
// SAVE STATE
i = arr_uint_index_of(state_config.key_save, code);
if (i != ARRAY_NOT_FOUND) {
if (value > 0) {
log_info("[%d] Saving state %d", code, i + 1);
save_to_index_file(context, state_config, i + 1);
}
return true;
}
return false;
}
void state_midi_event(Context *context, StateConfig state_config,
MidiDevice midi, unsigned char code, unsigned char value,
bool trace_midi) {
if (!compute_event(context, state_config, midi, code, value)) {
log_warn("unknown midi: %d %d", code, value);
safe_midi_write(midi, code, value);
} else if (trace_midi) {
log_trace("midi: %d %d", code, value);
@@ -498,58 +595,8 @@ void state_midi_event(Context *context, StateConfig state_config,
void state_key_event(Context *context, StateConfig state_config,
unsigned int code, MidiDevice midi) {
unsigned int index;
if (code == state_config.key_randomize) {
log_info("[%d] Randomized", code);
randomize(context, state_config);
update_values(context, state_config, midi);
} else if (code == state_config.key_reset) {
log_info("[%d] Reset", code);
reset(context);
update_values(context, state_config, midi);
} else if (code == state_config.key_demo) {
log_info((context->demo ? "[%d] Demo OFF" : "[%d] Demo ON"), code);
context->demo = !context->demo;
} else if (code == state_config.key_autorand) {
log_info(
(context->auto_random ? "[%d] Auto Random OFF" : "[%d] Auto Random ON"),
code);
context->auto_random = !context->auto_random;
} else if (code == state_config.key_autorand_down) {
if (context->auto_random_cycle > 1) {
context->auto_random_cycle -= 1;
}
log_info("[%d] Auto Random Cycle: %d", code, context->auto_random_cycle);
} else if (code == state_config.key_autorand_up) {
context->auto_random_cycle += 1;
log_info("[%d] Auto Random Cycle: %d", code, context->auto_random_cycle);
} else if (code == state_config.key_tempo_up) {
tempo_set(&context->tempo, context->tempo.tempo + 1);
log_info("[%d] Tempo: %f", code, context->tempo);
} else if (code == state_config.key_tempo_down) {
if (context->tempo.tempo > 0) {
tempo_set(&context->tempo, context->tempo.tempo - 1);
}
log_info("[%d] Tempo: %f", code, context->tempo);
} else {
index = arr_uint_index_of(state_config.key_load, code);
if (index != ARRAY_NOT_FOUND) {
log_info("[%d] Loading state %d", code, index + 1);
load_from_index_file(context, state_config, index + 1);
return;
}
index = arr_uint_index_of(state_config.key_save, code);
if (index != ARRAY_NOT_FOUND) {
log_info("[%d] Saving state %d", code, index + 1);
save_to_index_file(context, state_config, index + 1);
return;
}
log_info("[%d] No hotkey defined", code);
if (!compute_event(context, state_config, midi, code, MIDI_MAX)) {
log_warn("[%d] No hotkey defined", code);
}
}