feat(midi): add device routing and bounded external note output (phase 101)

This commit is contained in:
Johannes Findeisen 2026-11-06 02:23:37 +01:00
commit 75dee16b6a
9 changed files with 251 additions and 15 deletions

View file

@ -10,8 +10,8 @@
#include <time.h>
#include <unistd.h>
typedef struct {
jack_port_t *input, *right, *midi;
unsigned int command, seen, loud, right_loud, heard, bad;
jack_port_t *input, *right, *midi, *receive;
unsigned int command, seen, loud, right_loud, heard, bad, midi_on, midi_off;
} probe;
static int process(jack_nframes_t frames, void *context)
{
@ -23,6 +23,11 @@ static int process(jack_nframes_t frames, void *context)
unsigned int command = __atomic_load_n(&p->command, __ATOMIC_ACQUIRE), loud = 0;
jack_nframes_t i;
if (!input || !right || !midi) { __atomic_store_n(&p->bad, 1U, __ATOMIC_RELAXED); return 0; }
{void *received=jack_port_get_buffer(p->receive,frames);uint32_t count=jack_midi_get_event_count(received),j;
for(j=0;j<count;++j){jack_midi_event_t e;if(jack_midi_event_get(&e,received,j)==0 && e.size==3){
if((e.buffer[0]&0xf0)==0x90 && e.buffer[2])__atomic_fetch_add(&p->midi_on,1U,__ATOMIC_RELAXED);
if((e.buffer[0]&0xf0)==0x80 || ((e.buffer[0]&0xf0)==0xb0 && e.buffer[1]==123))__atomic_fetch_add(&p->midi_off,1U,__ATOMIC_RELAXED);
}}}
jack_midi_clear_buffer(midi);
if (command && command != p->seen) {
unsigned char bytes[3] = {0x90, 69, command % 2 ? 127 : 0};
@ -68,7 +73,9 @@ int main(void)
state.input = jack_port_register(client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
state.right = jack_port_register(client, "right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
state.midi = jack_port_register(client, "midi", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
REQUIRE(state.input && state.right && state.midi);
state.receive=jack_port_register(client,"receive",JACK_DEFAULT_MIDI_TYPE,JackPortIsInput,0);
REQUIRE(state.input && state.right && state.midi && state.receive);
REQUIRE(xtc_backend_set_midi_options(backend,-1,-1,1)==XTC_OK);
REQUIRE(jack_set_process_callback(client, process, &state) == 0 && jack_activate(client) == 0);
REQUIRE(xtc_backend_start(backend) == XTC_OK);
REQUIRE(xtc_backend_midi_port_name(backend, &destination) == XTC_OK);
@ -83,10 +90,12 @@ int main(void)
int connected = jack_connect(client, own, jack_port_name(state.right)); REQUIRE(connected == 0 || connected == EEXIST); }
{ const char *own; REQUIRE(xtc_backend_output_name(backend, 1, &own) == XTC_OK);
int connected = jack_connect(client, own, jack_port_name(state.right)); REQUIRE(connected == 0 || connected == EEXIST); }
REQUIRE(xtc_backend_route_midi(backend,XTC_PORT_OUTPUT,jack_port_name(state.receive),0)==XTC_OK);
__atomic_store_n(&state.command, 1U, __ATOMIC_RELEASE); wait_blocks();
REQUIRE(__atomic_load_n(&state.loud, __ATOMIC_RELAXED));
__atomic_store_n(&state.command, 2U, __ATOMIC_RELEASE); wait_blocks();
REQUIRE(!__atomic_load_n(&state.loud, __ATOMIC_RELAXED));
REQUIRE(__atomic_load_n(&state.midi_on,__ATOMIC_RELAXED)>0 && __atomic_load_n(&state.midi_off,__ATOMIC_RELAXED)>0);
__atomic_store_n(&state.command, 3U, __ATOMIC_RELEASE); wait_blocks();
REQUIRE(__atomic_load_n(&state.loud, __ATOMIC_RELAXED));
REQUIRE(xtc_backend_panic(backend) == XTC_OK); wait_blocks();