# OPLabs Mixer Engine — Standalone Daemon C++ standalone audio mixer daemon, extracted from the op-pedal mixer-engine branch. JACK audio I/O with Unix socket JSON control. ## Architecture ``` JACK Ports → MixerEngine::process() → JACK Ports ↕ MixerControlServer (Unix socket) ↕ FastAPI bridge (future) / socat / nc ↕ React Mixer Console (browser) ``` ### Processing Pipeline (per audio cycle) 1. Clear all bus buffers 2. For each channel: apply HPF → volume/pan → accumulate to routed buses 3. Process aux sends (pre/post fader) 4. Route buses to buses according to routing matrix 5. Process each bus (apply volume, compute VU) 6. Write to physical outputs per output routing table ## Dependencies - **JACK** (libjack-jackd2-dev on Debian, jack-audio-connection-kit-devel on Fedora) - **CMake** >= 3.16 - **C++17** compiler - **nlohmann/json** (auto-fetched by CMake) ## Build ```bash git clone oplabs-mixer-daemon cd oplabs-mixer-daemon mkdir build && cd build cmake .. make -j$(nproc) ``` ## Run ```bash # Start JACK first jackd -d alsa -r 48000 -p 256 -n 3 & # Run the daemon (auto-connects to JACK) ./mixer-daemon # With custom config ./mixer-daemon --inputs 4 --outputs 2 --buffer-size 128 ``` ### Command-line Options | Option | Default | Description | |--------|---------|-------------| | `--socket ` | `/tmp/mixer-daemon.sock` | Unix socket path | | `--inputs ` | 2 | Number of JACK input channels | | `--outputs ` | 2 | Number of JACK output channels | | `--sample-rate ` | 48000 | Audio sample rate (overridden by JACK) | | `--buffer-size ` | 256 | Audio buffer size in frames (overridden by JACK) | | `--help` | | Show help | ### Headless Mode If JACK is not running, the daemon starts in headless mode — no audio I/O, but the control socket is active for testing. ## Control Protocol The daemon listens on a Unix domain socket. Send one JSON command per line, receive one JSON response per line. ```bash # Get full mixer state echo '{"cmd":"getState"}' | nc -U /tmp/mixer-daemon.sock # Set channel volume echo '{"cmd":"setChannelVolume","channel":0,"volume":-6.0}' | nc -U /tmp/mixer-daemon.sock # Get VU levels echo '{"cmd":"getVU"}' | nc -U /tmp/mixer-daemon.sock # Auto-create channels echo '{"cmd":"autoCreateChannels","inputs":4,"outputs":2}' | nc -U /tmp/mixer-daemon.sock ``` ### Commands | Command | Parameters | Description | |---------|------------|-------------| | `getState` | — | Full mixer state as JSON | | `getVU` | — | VU levels per channel and bus | | `setChannelVolume` | `channel`, `volume` | Set channel fader (-96..+12 dB) | | `setChannelPan` | `channel`, `pan` | Set pan (-1.0 left to 1.0 right) | | `setChannelMute` | `channel`, `mute` | Mute toggle | | `setChannelSolo` | `channel`, `solo` | Solo toggle | | `setChannelLabel` | `channel`, `label` | Set channel name | | `setBusVolume` | `busId`, `volume` | Set bus fader (-96..+12 dB) | | `setBusMute` | `busId`, `mute` | Bus mute toggle | | `routeChannelToBus` | `channel`, `busId`, `level` | Route channel to bus | | `routeBusToBus` | `sourceBusId`, `targetBusId`, `level` | Route bus to bus | | `removeRoute` | `sourceId`, `targetBusId` | Remove a route | | `autoCreateChannels` | `inputs`, `outputs` | Recreate all channels for N inputs | | `addChannel` | `physicalInput` | Add a new channel strip | | `removeChannel` | `channel` | Remove a channel strip | ## Run Tests ```bash cd build && ctest # or ./mixer-test ``` ## Integration The daemon is designed to sit behind a FastAPI Python bridge that translates HTTP/WebSocket to Unix socket commands. That bridge then serves the React Mixer Console UI. ## License Copyright (c) 2026 Ourpad Network. See LICENSE file.