#ifndef MIDI_H #define MIDI_H #ifndef _WIN32 # define _POSIX_C_SOURCE 200809L # include #endif #include #include "synth.h" #define MIDI_MAX_INPUTS 16 typedef struct { int active; float *valuePtr; // direct pointer into Synth for CC to write float min, max; // CC 0 → min, CC 127 → max int controlId; // stable UI control ID, used for persistence } CcMapping; typedef struct { int client; int port; char clientName[64]; char portName[64]; } MidiInputInfo; typedef struct { #ifdef _WIN32 void *hMidiIn; // HMIDIIN; kept opaque to avoid including windows.h here #else snd_seq_t *seq; int port; int client; #endif Synth *synth; int connectedClient; // WinMM device index on Windows, ALSA client on Linux; -1 if not connected int connectedPort; // always 0 on Windows, ALSA port on Linux MidiInputInfo inputs[MIDI_MAX_INPUTS]; int inputCount; atomic_int midiLearnMode; // 1 while waiting for CC wiggle atomic_int midiLearnCC; // -1 or the CC number received CcMapping ccMappings[128]; } MidiState; int midiInit(MidiState *m, Synth *synth); void midiScanInputs(MidiState *m); void midiDevConnect(MidiState *m, int srcClient, int srcPort); void midiDevDisconnect(MidiState *m); void midiClose(MidiState *m); void *midiThread(void *arg); #endif