diff --git a/makefile b/makefile index 7c28436..9009737 100644 --- a/makefile +++ b/makefile @@ -22,7 +22,7 @@ clean: rm -f looper integration_test src/*.o check: - cppcheck --enable=all --error-exitcode=1 src/*.c --library=posix . + cppcheck --enable=all --error-exitcode=1 --suppress=missingIncludeSystem --suppress=usleepCalled --suppress=unreadVariable --suppress=normalCheckLevelMaxBranches src/*.c --library=posix . # Optional: Format code using clang-format format: diff --git a/src/channel.c b/src/channel.c index 713024f..e68e371 100644 --- a/src/channel.c +++ b/src/channel.c @@ -1,42 +1,39 @@ -#include -#include +#include "channel.h" #include #include -#include "channel.h" +#include +#include -void channel_add(jack_client_t *client, int idx) -{ - char in_name[64], out_name[64]; - snprintf(in_name, sizeof(in_name), "channel%d_input", next_channel_id); - snprintf(out_name, sizeof(out_name), "channel%d_output", next_channel_id); +void channel_add(jack_client_t *client, int idx) { + char in_name[64], out_name[64]; + snprintf(in_name, sizeof(in_name), "channel%d_input", next_channel_id); + snprintf(out_name, sizeof(out_name), "channel%d_output", next_channel_id); - channels[idx].audio_in = jack_port_register(client, in_name, - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsInput, 0); - channels[idx].audio_out = jack_port_register(client, out_name, - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsOutput, 0); - if (!channels[idx].audio_in || !channels[idx].audio_out) { - fprintf(stderr, "Failed to register ports for channel %d\n", next_channel_id); - /* Do NOT mark channel active – process loop will skip it */ - atomic_store(&channels[idx].active, 0); - return; - } - - atomic_store(&channels[idx].active, 1); - atomic_store(&channels[idx].state, STATE_IDLE); - channels[idx].prev_state = -1; - channels[idx].loop_count = 0; - channels[idx].record_pos = 0; - channels[idx].playback_pos = 0; - - next_channel_id++; - channel_count++; -} - -void channel_remove(jack_client_t *client, int idx) -{ - (void)client; + channels[idx].audio_in = jack_port_register( + client, in_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); + channels[idx].audio_out = jack_port_register( + client, out_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); + if (!channels[idx].audio_in || !channels[idx].audio_out) { + fprintf(stderr, "Failed to register ports for channel %d\n", + next_channel_id); + /* Do NOT mark channel active – process loop will skip it */ atomic_store(&channels[idx].active, 0); - channel_count--; + return; + } + + atomic_store(&channels[idx].active, 1); + atomic_store(&channels[idx].state, STATE_IDLE); + channels[idx].prev_state = -1; + channels[idx].loop_count = 0; + channels[idx].record_pos = 0; + channels[idx].playback_pos = 0; + + next_channel_id++; + channel_count++; +} + +void channel_remove(jack_client_t *client, int idx) { + (void)client; + atomic_store(&channels[idx].active, 0); + channel_count--; } diff --git a/src/midi.c b/src/midi.c index df70369..e3471cf 100644 --- a/src/midi.c +++ b/src/midi.c @@ -1,102 +1,110 @@ +#include "midi.h" +#include "channel.h" #include #include #include -#include "midi.h" -#include "channel.h" extern atomic_int control_key_active; extern atomic_int cmd_add; extern atomic_int cmd_remove; extern atomic_int bind_channel; -void midi_handle_events(void *port_buffer, jack_nframes_t nframes) -{ - (void)nframes; - jack_nframes_t nevents = jack_midi_get_event_count(port_buffer); - jack_midi_event_t ev; +void midi_handle_events(void *port_buffer, jack_nframes_t nframes) { + (void)nframes; + jack_nframes_t nevents = jack_midi_get_event_count(port_buffer); + jack_midi_event_t ev; - for (jack_nframes_t i = 0; i < nevents; i++) { - if (jack_midi_event_get(&ev, port_buffer, i) != 0) continue; - if (ev.size < 3) continue; + for (jack_nframes_t i = 0; i < nevents; i++) { + if (jack_midi_event_get(&ev, port_buffer, i) != 0) + continue; + if (ev.size < 3) + continue; - unsigned char status = ev.buffer[0]; - unsigned char note = ev.buffer[1]; - unsigned char vel = ev.buffer[2]; + unsigned char status = ev.buffer[0]; + unsigned char note = ev.buffer[1]; + unsigned char vel = ev.buffer[2]; - /* note‑on */ - if ((status & 0xf0) == 0x90 && vel > 0) { - if (note == 64) { - atomic_store(&control_key_active, 1); - } else { - int ck = atomic_load(&control_key_active); - if (ck) { - atomic_store(&control_key_active, 0); - if (note < 16) { - atomic_store(&bind_channel, note); - } else { - switch (note) { - case 60: atomic_store(&cmd_add, 1); break; - case 61: atomic_store(&cmd_remove, 1); break; - case 62: /* trigger looper – channel via bind_channel */ - { - int bch = atomic_load(&bind_channel); - if (bch >= 0 && bch < MAX_CHANNELS) { - int cur = atomic_load(&channels[bch].state); - switch (cur) { - case STATE_IDLE: - atomic_store(&channels[bch].state, STATE_RECORD); - break; - case STATE_RECORD: - atomic_store(&channels[bch].state, STATE_LOOPING); - break; - case STATE_LOOPING: - atomic_store(&channels[bch].state, STATE_PAUSED); - break; - case STATE_PAUSED: - atomic_store(&channels[bch].state, STATE_LOOPING); - break; - } - } - } - break; - case 63: /* unbind – reset bind to channel 0 */ - atomic_store(&bind_channel, 0); - break; - default: - break; - } - } - } else { - /* direct mapping */ - switch (note) { - case 1: /* toggle channel 0 */ - { - int cur0 = atomic_load(&channels[0].state); - switch (cur0) { - case STATE_IDLE: - atomic_store(&channels[0].state, STATE_RECORD); - break; - case STATE_RECORD: - atomic_store(&channels[0].state, STATE_LOOPING); - break; - case STATE_LOOPING: - atomic_store(&channels[0].state, STATE_PAUSED); - break; - case STATE_PAUSED: - atomic_store(&channels[0].state, STATE_LOOPING); - break; - } - } - break; - case 60: atomic_store(&cmd_add, 1); break; - case 61: atomic_store(&cmd_remove, 1); break; - default: - break; - } + /* note‑on */ + if ((status & 0xf0) == 0x90 && vel > 0) { + if (note == 64) { + atomic_store(&control_key_active, 1); + } else { + int ck = atomic_load(&control_key_active); + if (ck) { + atomic_store(&control_key_active, 0); + if (note < 16) { + atomic_store(&bind_channel, note); + } else { + switch (note) { + case 60: + atomic_store(&cmd_add, 1); + break; + case 61: + atomic_store(&cmd_remove, 1); + break; + case 62: /* trigger looper – channel via bind_channel */ + { + int bch = atomic_load(&bind_channel); + if (bch >= 0 && bch < MAX_CHANNELS) { + int cur = atomic_load(&channels[bch].state); + switch (cur) { + case STATE_IDLE: + atomic_store(&channels[bch].state, STATE_RECORD); + break; + case STATE_RECORD: + atomic_store(&channels[bch].state, STATE_LOOPING); + break; + case STATE_LOOPING: + atomic_store(&channels[bch].state, STATE_PAUSED); + break; + case STATE_PAUSED: + atomic_store(&channels[bch].state, STATE_LOOPING); + break; } + } + } break; + case 63: /* unbind – reset bind to channel 0 */ + atomic_store(&bind_channel, 0); + break; + default: + break; } - } else if ((status & 0xf0) == 0x80 || ((status & 0xf0) == 0x90 && vel == 0)) { - atomic_store(&control_key_active, 0); + } + } else { + /* direct mapping */ + switch (note) { + case 1: /* toggle channel 0 */ + { + int cur0 = atomic_load(&channels[0].state); + switch (cur0) { + case STATE_IDLE: + atomic_store(&channels[0].state, STATE_RECORD); + break; + case STATE_RECORD: + atomic_store(&channels[0].state, STATE_LOOPING); + break; + case STATE_LOOPING: + atomic_store(&channels[0].state, STATE_PAUSED); + break; + case STATE_PAUSED: + atomic_store(&channels[0].state, STATE_LOOPING); + break; + } + } break; + case 60: + atomic_store(&cmd_add, 1); + break; + case 61: + atomic_store(&cmd_remove, 1); + break; + default: + break; + } } + } + } else if ((status & 0xf0) == 0x80 || + ((status & 0xf0) == 0x90 && vel == 0)) { + atomic_store(&control_key_active, 0); } + } }