diff --git a/src/forge.c b/src/forge.c index bfb5f1a..7789270 100644 --- a/src/forge.c +++ b/src/forge.c @@ -62,7 +62,7 @@ static void compute_fps() { static void init_context() { context.stop = false; - state_init(&context, &project.state_config, init_params.demo, + state_init(&context, project.state_config, init_params.demo, init_params.auto_random, init_params.auto_random_cycle, init_params.base_tempo, init_params.load_state); @@ -181,12 +181,12 @@ static void key_callback(Window *window, int key, log_info("[ESC] Closing..."); window_close(window); } else if (event > 0) { - state_key_event(&context, &project.state_config, event, &midi); + state_key_event(&context, project.state_config, event, &midi); } } static void midi_callback(unsigned char code, unsigned char value) { - state_midi_event(&context, &project.state_config, &midi, code, value, + state_midi_event(&context, project.state_config, &midi, code, value, init_params.trace_midi); } @@ -336,7 +336,7 @@ static void shutdown() { context.stop = true; if (init_params.save_state) { - state_save(&context, &project.state_config); + state_save(&context, project.state_config); } shaders_free(&program); diff --git a/src/state.c b/src/state.c index c733e6c..3c69b09 100644 --- a/src/state.c +++ b/src/state.c @@ -20,64 +20,62 @@ static void safe_midi_write(const MidiDevice *midi, unsigned int code, } } -static void update_page(const Context *context, const StateConfig *state_config, +static void update_page(const Context *context, StateConfig state_config, const MidiDevice *midi) { unsigned int page_item_min; unsigned int page_item_max; // SHOW PAGE - for (unsigned int i = 0; i < state_config->select_page_codes.length; i++) { - safe_midi_write(midi, state_config->select_page_codes.values[i], + for (unsigned int i = 0; i < state_config.select_page_codes.length; i++) { + safe_midi_write(midi, state_config.select_page_codes.values[i], i == context->page ? MIDI_MAX : 0); } // SHOW PAGE ITEM - page_item_min = state_config->select_item_codes.length * context->page; - page_item_max = page_item_min + state_config->select_item_codes.length; + page_item_min = state_config.select_item_codes.length * context->page; + page_item_max = page_item_min + state_config.select_item_codes.length; if (context->state.values[context->selected] >= page_item_min && context->state.values[context->selected] < page_item_max) { - for (unsigned int i = 0; i < state_config->select_item_codes.length; i++) { - safe_midi_write(midi, state_config->select_item_codes.values[i], + for (unsigned int i = 0; i < state_config.select_item_codes.length; i++) { + safe_midi_write(midi, state_config.select_item_codes.values[i], i == context->state.values[context->selected] - page_item_min ? MIDI_MAX : 0); } } else { - for (unsigned int i = 0; i < state_config->select_item_codes.length; i++) { - safe_midi_write(midi, state_config->select_item_codes.values[i], 0); + for (unsigned int i = 0; i < state_config.select_item_codes.length; i++) { + safe_midi_write(midi, state_config.select_item_codes.values[i], 0); } } } -static void update_active(const Context *context, - const StateConfig *state_config, +static void update_active(const Context *context, StateConfig state_config, const MidiDevice *midi) { unsigned int k; - for (unsigned int i = 0; i < state_config->midi_active_counts.length; i++) { - for (unsigned int j = 0; j < state_config->midi_active_counts.values[i]; + for (unsigned int i = 0; i < state_config.midi_active_counts.length; i++) { + for (unsigned int j = 0; j < state_config.midi_active_counts.values[i]; j++) { - k = state_config->midi_active_offsets.values[i] + j; - safe_midi_write(midi, state_config->midi_active_codes.values[k], + k = state_config.midi_active_offsets.values[i] + j; + safe_midi_write(midi, state_config.midi_active_codes.values[k], context->active[i] == j ? MIDI_MAX : 0); } } } -static void update_values(const Context *context, - const StateConfig *state_config, +static void update_values(const Context *context, StateConfig state_config, const MidiDevice *midi) { unsigned int j; unsigned int k; unsigned int part; - for (unsigned int i = 0; i < state_config->midi_codes.length; i++) { + for (unsigned int i = 0; i < state_config.midi_codes.length; i++) { j = i / 3; - part = arr_uint_remap_index(state_config->midi_offsets, &j); - k = state_config->values_offsets.values[part] + - context->active[part] * state_config->midi_counts.values[part] + j; - safe_midi_write(midi, state_config->midi_codes.values[i], + part = arr_uint_remap_index(state_config.midi_offsets, &j); + k = state_config.values_offsets.values[part] + + context->active[part] * state_config.midi_counts.values[part] + j; + safe_midi_write(midi, state_config.midi_codes.values[i], context->values[k][i % 3] * MIDI_MAX); } } @@ -87,21 +85,21 @@ static void reset(Context *context) { memset(context->state.values, 0, sizeof(context->state.values)); } -static void randomize(Context *context, const StateConfig *state_config) { +static void randomize(Context *context, StateConfig state_config) { unsigned int j; unsigned int l; unsigned int part; - for (unsigned int i = 0; i < state_config->midi_codes.length; i++) { + for (unsigned int i = 0; i < state_config.midi_codes.length; i++) { j = i / 3; - part = arr_uint_remap_index(state_config->midi_offsets, &j); - for (unsigned int k = 0; k < state_config->midi_active_counts.values[part]; + part = arr_uint_remap_index(state_config.midi_offsets, &j); + for (unsigned int k = 0; k < state_config.midi_active_counts.values[part]; k++) { - l = state_config->values_offsets.values[part] + - k * state_config->midi_counts.values[part] + j; + l = state_config.values_offsets.values[part] + + k * state_config.midi_counts.values[part] + j; - if (arr_uint_index_of(state_config->fader_codes, - state_config->midi_codes.values[i]) != + if (arr_uint_index_of(state_config.fader_codes, + state_config.midi_codes.values[i]) != ARRAY_NOT_FOUND) { context->values[l][i % 3] = (float)rand_uint(MIDI_MAX + 1) / MIDI_MAX; } else { @@ -111,11 +109,11 @@ static void randomize(Context *context, const StateConfig *state_config) { } for (unsigned int i = 0; i < context->state.length; i++) { - context->state.values[i] = rand_uint(state_config->state_max); + context->state.values[i] = rand_uint(state_config.state_max); } } -static void load_from_file(Context *context, const StateConfig *state_config, +static void load_from_file(Context *context, StateConfig state_config, const char *state_file) { ConfigFile saved_state; char key[STR_LEN]; @@ -139,12 +137,12 @@ static void load_from_file(Context *context, const StateConfig *state_config, context->state.values[i] = config_file_get_int(&saved_state, key, 0); } - for (unsigned int i = 0; i < state_config->midi_active_counts.length; i++) { + for (unsigned int i = 0; i < state_config.midi_active_counts.length; i++) { snprintf(key, STR_LEN, "active_%d", i); context->active[i] = config_file_get_int(&saved_state, key, 0); } - for (unsigned int i = 0; i < state_config->value_count; i++) { + for (unsigned int i = 0; i < state_config.value_count; i++) { snprintf(key, STR_LEN, "value_%d_x", i); context->values[i][0] = (float)config_file_get_int(&saved_state, key, 0) / MIDI_MAX; @@ -159,28 +157,25 @@ static void load_from_file(Context *context, const StateConfig *state_config, config_file_free(&saved_state); } -static void load_from_default_file(Context *context, - const StateConfig *state_config) { +static void load_from_default_file(Context *context, StateConfig state_config) { char state_file[STR_LEN]; - snprintf(state_file, STR_LEN, "%s.txt", state_config->save_file_prefix); + snprintf(state_file, STR_LEN, "%s.txt", state_config.save_file_prefix); load_from_file(context, state_config, state_file); } -static void load_from_index_file(Context *context, - const StateConfig *state_config, +static void load_from_index_file(Context *context, StateConfig state_config, unsigned int index) { char state_file[STR_LEN]; - snprintf(state_file, STR_LEN, "%s.%d.txt", state_config->save_file_prefix, + snprintf(state_file, STR_LEN, "%s.%d.txt", state_config.save_file_prefix, index); load_from_file(context, state_config, state_file); } -static void save_to_file(const Context *context, - const StateConfig *state_config, +static void save_to_file(const Context *context, StateConfig state_config, const char *state_file) { StringArray lines; @@ -201,12 +196,12 @@ static void save_to_file(const Context *context, context->state.values[i]); } - for (unsigned int i = 0; i < state_config->midi_active_counts.length; i++) { + for (unsigned int i = 0; i < state_config.midi_active_counts.length; i++) { snprintf(lines.values[lines.length++], STR_LEN, "active_%d=%d", i, context->active[i]); } - for (unsigned int i = 0; i < state_config->value_count; i++) { + for (unsigned int i = 0; i < state_config.value_count; i++) { snprintf(lines.values[lines.length++], STR_LEN, "value_%d_x=%d", i, (unsigned int)(context->values[i][0] * MIDI_MAX)); snprintf(lines.values[lines.length++], STR_LEN, "value_%d_y=%d", i, @@ -219,20 +214,19 @@ static void save_to_file(const Context *context, } static void save_to_default_file(const Context *context, - const StateConfig *state_config) { + StateConfig state_config) { char state_file[STR_LEN]; - snprintf(state_file, STR_LEN, "%s.txt", state_config->save_file_prefix); + snprintf(state_file, STR_LEN, "%s.txt", state_config.save_file_prefix); save_to_file(context, state_config, state_file); } -static void save_to_index_file(const Context *context, - const StateConfig *state_config, +static void save_to_index_file(const Context *context, StateConfig state_config, unsigned int index) { char state_file[STR_LEN]; - snprintf(state_file, STR_LEN, "%s.%d.txt", state_config->save_file_prefix, + snprintf(state_file, STR_LEN, "%s.%d.txt", state_config.save_file_prefix, index); save_to_file(context, state_config, state_file); @@ -412,7 +406,7 @@ void state_parse_config(StateConfig *state_config, const ConfigFile *config) { } } -void state_midi_event(Context *context, const StateConfig *state_config, +void state_midi_event(Context *context, StateConfig state_config, const MidiDevice *midi, unsigned char code, unsigned char value, bool trace_midi) { unsigned int i; @@ -424,7 +418,7 @@ void state_midi_event(Context *context, const StateConfig *state_config, found = false; // PAGE CHANGE - i = arr_uint_index_of(state_config->select_page_codes, code); + i = arr_uint_index_of(state_config.select_page_codes, code); if (i != ARRAY_NOT_FOUND) { found = true; if (value > 0) { @@ -434,7 +428,7 @@ void state_midi_event(Context *context, const StateConfig *state_config, } // TARGET CHANGE - i = arr_uint_index_of(state_config->select_frag_codes, code); + i = arr_uint_index_of(state_config.select_frag_codes, code); if (i != ARRAY_NOT_FOUND) { found = true; if (value > 0) { @@ -444,22 +438,22 @@ void state_midi_event(Context *context, const StateConfig *state_config, } // ITEM CHANGE - i = arr_uint_index_of(state_config->select_item_codes, code); + 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; + context->page * state_config.select_item_codes.length + i; update_page(context, state_config, midi); } } // ACTIVE CHANGE - i = arr_uint_index_of(state_config->midi_active_codes, code); + i = arr_uint_index_of(state_config.midi_active_codes, code); if (i != ARRAY_NOT_FOUND) { found = true; if (value > 0) { - part = arr_uint_remap_index(state_config->midi_active_offsets, &i); + part = arr_uint_remap_index(state_config.midi_active_offsets, &i); context->active[part] = i; update_active(context, state_config, midi); update_values(context, state_config, midi); @@ -467,15 +461,15 @@ void state_midi_event(Context *context, const StateConfig *state_config, } // VALUE CHANGE - i = arr_uint_index_of(state_config->midi_codes, code); + i = arr_uint_index_of(state_config.midi_codes, code); if (i != ARRAY_NOT_FOUND) { found = true; j = i / 3; - part = arr_uint_remap_index(state_config->midi_offsets, &j); - k = state_config->values_offsets.values[part] + - context->active[part] * state_config->midi_counts.values[part] + j; + part = arr_uint_remap_index(state_config.midi_offsets, &j); + k = state_config.values_offsets.values[part] + + context->active[part] * state_config.midi_counts.values[part] + j; - if (arr_uint_index_of(state_config->fader_codes, code) != ARRAY_NOT_FOUND) { + if (arr_uint_index_of(state_config.fader_codes, code) != ARRAY_NOT_FOUND) { context->values[k][i % 3] = (float)value / MIDI_MAX; } else if (value > 0) { if (context->values[k][i % 3] > 0.5) { @@ -488,7 +482,7 @@ void state_midi_event(Context *context, const StateConfig *state_config, } } - if (code == state_config->tap_tempo_code) { + if (code == state_config.tap_tempo_code) { found = true; midi_write(midi, code, value); if (value > 0) { @@ -506,44 +500,44 @@ void state_midi_event(Context *context, const StateConfig *state_config, } } -void state_key_event(Context *context, const StateConfig *state_config, +void state_key_event(Context *context, StateConfig state_config, unsigned int code, const MidiDevice *midi) { unsigned int index; - if (code == state_config->hotkey_randomize) { + if (code == state_config.hotkey_randomize) { log_info("[%d] Randomized", code); randomize(context, state_config); update_values(context, state_config, midi); - } else if (code == state_config->hotkey_reset) { + } else if (code == state_config.hotkey_reset) { log_info("[%d] Reset", code); reset(context); update_values(context, state_config, midi); - } else if (code == state_config->hotkey_demo) { + } else if (code == state_config.hotkey_demo) { log_info((context->demo ? "[%d] Demo OFF" : "[%d] Demo ON"), code); context->demo = !context->demo; - } else if (code == state_config->hotkey_autorand) { + } else if (code == state_config.hotkey_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->hotkey_autorand_down) { + } else if (code == state_config.hotkey_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->hotkey_autorand_up) { + } else if (code == state_config.hotkey_autorand_up) { context->auto_random_cycle += 1; log_info("[%d] Auto Random Cycle: %d", code, context->auto_random_cycle); - } else if (code == state_config->hotkey_tempo_up) { + } else if (code == state_config.hotkey_tempo_up) { tempo_set(&context->tempo, context->tempo.tempo + 1); log_info("[%d] Tempo: %f", code, context->tempo); - } else if (code == state_config->hotkey_tempo_down) { + } else if (code == state_config.hotkey_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->hotkey_load, code); + index = arr_uint_index_of(state_config.hotkey_load, code); if (index != ARRAY_NOT_FOUND) { log_info("[%d] Loading state %d", code, index + 1); @@ -551,7 +545,7 @@ void state_key_event(Context *context, const StateConfig *state_config, return; } - index = arr_uint_index_of(state_config->hotkey_save, code); + index = arr_uint_index_of(state_config.hotkey_save, code); if (index != ARRAY_NOT_FOUND) { log_info("[%d] Saving state %d", code, index + 1); @@ -577,9 +571,9 @@ void *state_background_write(void *args) { log_info("(state) background writing started"); if (!midi->error) { - update_page(context, &state_config, midi); - update_active(context, &state_config, midi); - update_values(context, &state_config, midi); + update_page(context, state_config, midi); + update_active(context, state_config, midi); + update_values(context, state_config, midi); } last_active = false; @@ -603,9 +597,9 @@ void *state_background_write(void *args) { (double)context->auto_random_cycle) < 0.5; if (context->auto_random && change && !last_change) { - randomize(context, &state_config); + randomize(context, state_config); - update_values(context, &state_config, midi); + update_values(context, state_config, midi); } last_change = change; @@ -615,7 +609,7 @@ void *state_background_write(void *args) { pthread_exit(NULL); } -void state_init(Context *context, const StateConfig *state_config, bool demo, +void state_init(Context *context, StateConfig state_config, bool demo, bool auto_random, unsigned int auto_random_cycles, unsigned int base_tempo, bool load_state) { tempo_init(&context->tempo, base_tempo); @@ -623,7 +617,7 @@ void state_init(Context *context, const StateConfig *state_config, bool demo, context->auto_random = auto_random; context->auto_random_cycle = auto_random_cycles; - context->state.length = state_config->select_frag_codes.length; + context->state.length = state_config.select_frag_codes.length; memset(context->state.values, 0, sizeof(context->state.values)); if (auto_random) { @@ -647,6 +641,6 @@ void state_init(Context *context, const StateConfig *state_config, bool demo, } } -void state_save(const Context *context, const StateConfig *state_config) { +void state_save(const Context *context, StateConfig state_config) { save_to_default_file(context, state_config); } diff --git a/src/state.h b/src/state.h index 4346837..f350b64 100644 --- a/src/state.h +++ b/src/state.h @@ -5,19 +5,19 @@ void state_parse_config(StateConfig *state_config, const ConfigFile *config); -void state_midi_event(Context *context, const StateConfig *state_config, +void state_midi_event(Context *context, StateConfig state_config, const MidiDevice *midi, unsigned char code, unsigned char value, bool trace_midi); -void state_key_event(Context *context, const StateConfig *state_config, +void state_key_event(Context *context, StateConfig state_config, unsigned int code, const MidiDevice *midi); void *state_background_write(void *args); -void state_init(Context *context, const StateConfig *state_config, bool demo, +void state_init(Context *context, StateConfig state_config, bool demo, bool auto_random, unsigned int auto_random_cycles, unsigned int base_tempo, bool load_state); -void state_save(const Context *context, const StateConfig *state_config); +void state_save(const Context *context, StateConfig state_config); #endif /* STATE_H */