4-implement-scene-switching-engine #4

Merged
boomjacky merged 16 commits from 4-implement-scene-switching-engine into master 2026-05-13 12:51:04 -04:00
Showing only changes of commit 86d9bc72f1 - Show all commits

View File

@@ -145,13 +145,15 @@ int process_callback(jack_nframes_t nframes, void *arg) {
/* Guard against NULL ports (e.g. if port registration failed) */ /* Guard against NULL ports (e.g. if port registration failed) */
if (active_channels[c].type == CHANNEL_AUDIO) { if (active_channels[c].type == CHANNEL_AUDIO) {
if (!active_channels[c].audio_in || !active_channels[c].audio_out) { if (!active_channels[c].audio_in || !active_channels[c].audio_out) {
fprintf(stderr, "WARN: channel %d has NULL audio port(s), skipping\n", c); fprintf(stderr, "WARN: channel %d has NULL audio port(s), skipping\n",
c);
continue; continue;
} }
} else { } else {
/* CHANNEL_MIDI */ /* CHANNEL_MIDI */
if (!active_channels[c].midi_in || !active_channels[c].midi_out) { if (!active_channels[c].midi_in || !active_channels[c].midi_out) {
fprintf(stderr, "WARN: channel %d has NULL MIDI port(s), skipping\n", c); fprintf(stderr, "WARN: channel %d has NULL MIDI port(s), skipping\n",
c);
continue; continue;
} }
} }
@@ -187,26 +189,38 @@ int process_callback(jack_nframes_t nframes, void *arg) {
/* MIDI channel handling */ /* MIDI channel handling */
switch (state) { switch (state) {
case STATE_RECORD: { case STATE_RECORD: {
void *midi_in_buf = jack_port_get_buffer(active_channels[c].midi_in, nframes); void *midi_in_buf =
jack_port_get_buffer(active_channels[c].midi_in, nframes);
if (midi_in_buf) { if (midi_in_buf) {
jack_nframes_t nevents = jack_midi_get_event_count(midi_in_buf); jack_nframes_t nevents = jack_midi_get_event_count(midi_in_buf);
jack_midi_event_t ev; jack_midi_event_t ev;
for (jack_nframes_t j = 0; j < nevents; j++) { for (jack_nframes_t j = 0; j < nevents; j++) {
if (jack_midi_event_get(&ev, midi_in_buf, j) != 0) continue; if (jack_midi_event_get(&ev, midi_in_buf, j) != 0)
continue;
if (active_channels[c].record_pos < MAX_MIDI_EVENTS) { if (active_channels[c].record_pos < MAX_MIDI_EVENTS) {
active_channels[c].loop.midi_events[active_channels[c].record_pos].timestamp = ev.time; active_channels[c]
active_channels[c].loop.midi_events[active_channels[c].record_pos].status = ev.buffer[0]; .loop.midi_events[active_channels[c].record_pos]
active_channels[c].loop.midi_events[active_channels[c].record_pos].note = (ev.size > 1) ? ev.buffer[1] : 0; .timestamp = ev.time;
active_channels[c].loop.midi_events[active_channels[c].record_pos].velocity = (ev.size > 2) ? ev.buffer[2] : 0; active_channels[c]
.loop.midi_events[active_channels[c].record_pos]
.status = ev.buffer[0];
active_channels[c]
.loop.midi_events[active_channels[c].record_pos]
.note = (ev.size > 1) ? ev.buffer[1] : 0;
active_channels[c]
.loop.midi_events[active_channels[c].record_pos]
.velocity = (ev.size > 2) ? ev.buffer[2] : 0;
active_channels[c].record_pos++; active_channels[c].record_pos++;
} }
} }
/* forward incoming MIDI to output during record */ /* forward incoming MIDI to output during record */
void *midi_out_buf = jack_port_get_buffer(active_channels[c].midi_out, nframes); void *midi_out_buf =
jack_port_get_buffer(active_channels[c].midi_out, nframes);
if (midi_out_buf) { if (midi_out_buf) {
jack_midi_clear_buffer(midi_out_buf); jack_midi_clear_buffer(midi_out_buf);
for (jack_nframes_t j = 0; j < nevents; j++) { for (jack_nframes_t j = 0; j < nevents; j++) {
if (jack_midi_event_get(&ev, midi_in_buf, j) != 0) continue; if (jack_midi_event_get(&ev, midi_in_buf, j) != 0)
continue;
jack_midi_event_write(midi_out_buf, ev.time, ev.buffer, ev.size); jack_midi_event_write(midi_out_buf, ev.time, ev.buffer, ev.size);
} }
} }
@@ -214,10 +228,12 @@ int process_callback(jack_nframes_t nframes, void *arg) {
break; break;
} }
case STATE_LOOPING: { case STATE_LOOPING: {
void *midi_out_buf = jack_port_get_buffer(active_channels[c].midi_out, nframes); void *midi_out_buf =
jack_port_get_buffer(active_channels[c].midi_out, nframes);
if (midi_out_buf) { if (midi_out_buf) {
jack_midi_clear_buffer(midi_out_buf); jack_midi_clear_buffer(midi_out_buf);
int cnt = active_channels[c].loop_count; /* number of recorded events */ int cnt =
active_channels[c].loop_count; /* number of recorded events */
if (cnt > 0) { if (cnt > 0) {
/* simple: output all recorded events at frame 0 of each cycle */ /* simple: output all recorded events at frame 0 of each cycle */
for (int e = 0; e < cnt; e++) { for (int e = 0; e < cnt; e++) {
@@ -237,14 +253,17 @@ int process_callback(jack_nframes_t nframes, void *arg) {
default: /* IDLE */ default: /* IDLE */
/* pass through MIDI input to output */ /* pass through MIDI input to output */
{ {
void *midi_in_buf = jack_port_get_buffer(active_channels[c].midi_in, nframes); void *midi_in_buf =
void *midi_out_buf = jack_port_get_buffer(active_channels[c].midi_out, nframes); jack_port_get_buffer(active_channels[c].midi_in, nframes);
void *midi_out_buf =
jack_port_get_buffer(active_channels[c].midi_out, nframes);
if (midi_in_buf && midi_out_buf) { if (midi_in_buf && midi_out_buf) {
jack_midi_clear_buffer(midi_out_buf); jack_midi_clear_buffer(midi_out_buf);
jack_nframes_t nevents = jack_midi_get_event_count(midi_in_buf); jack_nframes_t nevents = jack_midi_get_event_count(midi_in_buf);
jack_midi_event_t ev; jack_midi_event_t ev;
for (jack_nframes_t j = 0; j < nevents; j++) { for (jack_nframes_t j = 0; j < nevents; j++) {
if (jack_midi_event_get(&ev, midi_in_buf, j) != 0) continue; if (jack_midi_event_get(&ev, midi_in_buf, j) != 0)
continue;
jack_midi_event_write(midi_out_buf, ev.time, ev.buffer, ev.size); jack_midi_event_write(midi_out_buf, ev.time, ev.buffer, ev.size);
} }
} }
@@ -265,8 +284,8 @@ int process_callback(jack_nframes_t nframes, void *arg) {
const float *f_in = (const float *)in; const float *f_in = (const float *)in;
for (i = 0; i < nframes; i++) { for (i = 0; i < nframes; i++) {
if (active_channels[c].record_pos < LOOP_BUF_SIZE) if (active_channels[c].record_pos < LOOP_BUF_SIZE)
active_channels[c].loop.audio_buffer[active_channels[c].record_pos++] = active_channels[c]
f_in[i]; .loop.audio_buffer[active_channels[c].record_pos++] = f_in[i];
f_out[i] = f_in[i]; f_out[i] = f_in[i];
} }
} else { } else {
@@ -278,8 +297,8 @@ int process_callback(jack_nframes_t nframes, void *arg) {
if (active_channels[c].loop_count > 0) { if (active_channels[c].loop_count > 0) {
float *outf = (float *)out; float *outf = (float *)out;
for (i = 0; i < nframes; i++) { for (i = 0; i < nframes; i++) {
outf[i] = outf[i] = active_channels[c]
active_channels[c].loop.audio_buffer[active_channels[c].playback_pos]; .loop.audio_buffer[active_channels[c].playback_pos];
active_channels[c].playback_pos = active_channels[c].playback_pos =
(active_channels[c].playback_pos + 1) % (active_channels[c].playback_pos + 1) %
active_channels[c].loop_count; active_channels[c].loop_count;