1-multichannel #1

Merged
boomjacky merged 31 commits from 1-multichannel into multichannel 2026-05-09 15:47:09 -04:00
2 changed files with 19 additions and 3 deletions
Showing only changes of commit b0dda3d8ed - Show all commits

View File

@@ -19,7 +19,7 @@ void channel_add(jack_client_t *client, int idx)
if (!channels[idx].audio_in || !channels[idx].audio_out) { if (!channels[idx].audio_in || !channels[idx].audio_out) {
fprintf(stderr, "Failed to register ports for channel %d\n", next_channel_id); fprintf(stderr, "Failed to register ports for channel %d\n", next_channel_id);
/* Do NOT mark channel active process loop will skip it */ /* Do NOT mark channel active process loop will skip it */
channels[idx].active = 0; atomic_store(&channels[idx].active, 0);
return; return;
} }
@@ -36,8 +36,7 @@ void channel_add(jack_client_t *client, int idx)
void channel_remove(jack_client_t *client, int idx) void channel_remove(jack_client_t *client, int idx)
{ {
jack_port_unregister(client, channels[idx].audio_in); (void)client;
jack_port_unregister(client, channels[idx].audio_out);
atomic_store(&channels[idx].active, 0); atomic_store(&channels[idx].active, 0);
channel_count--; channel_count--;
} }

View File

@@ -19,6 +19,9 @@ jack_port_t *midi_control_port = NULL;
jack_port_t *midi_clock_port = NULL; jack_port_t *midi_clock_port = NULL;
atomic_int control_key_active = 0; atomic_int control_key_active = 0;
/* Deferred removal index (1 second grace) */
static int pending_unregister_idx = -1;
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
* process callback * process callback
* ---------------------------------------------------------------- */ * ---------------------------------------------------------------- */
@@ -198,6 +201,18 @@ int looper_init(jack_client_t *client)
* ---------------------------------------------------------------- */ * ---------------------------------------------------------------- */
void looper_process_commands(jack_client_t *client) void looper_process_commands(jack_client_t *client)
{ {
/* Unregister any ports that were marked for deferred removal.
By now the realtime thread has had at least one full cycle
to see the `active = 0` store. */
if (pending_unregister_idx != -1) {
int idx = pending_unregister_idx;
if (channels[idx].audio_in)
jack_port_unregister(client, channels[idx].audio_in);
if (channels[idx].audio_out)
jack_port_unregister(client, channels[idx].audio_out);
pending_unregister_idx = -1;
}
if (atomic_exchange(&cmd_add, 0)) { if (atomic_exchange(&cmd_add, 0)) {
int idx; int idx;
for (idx = 0; idx < MAX_CHANNELS; idx++) for (idx = 0; idx < MAX_CHANNELS; idx++)
@@ -212,7 +227,9 @@ void looper_process_commands(jack_client_t *client)
for (int idx = 1; idx < MAX_CHANNELS; idx++) for (int idx = 1; idx < MAX_CHANNELS; idx++)
if (channels[idx].active) remove_idx = idx; if (channels[idx].active) remove_idx = idx;
if (remove_idx != -1) { if (remove_idx != -1) {
/* Mark inactive now; ports will be unregistered next round */
channel_remove(client, remove_idx); channel_remove(client, remove_idx);
pending_unregister_idx = remove_idx;
} }
} }
} }