a5423b7f55
Extracted from op-pedal mixer-engine branch. Core components: - MixerEngine / MixerChannelStrip / MixerBus — cleaned of LV2/Pedalboard/IHost/MidiMapper deps - MixerControlServer — Unix domain socket JSON control interface - main.cpp — JACK audio I/O client with headless fallback - CMake build — auto-fetches nlohmann/json, links JACK - 9 core tests passing Architecture: JACK ports → MixerEngine::process() → JACK ports, controlled via Unix socket JSON commands.
124 lines
3.7 KiB
Markdown
124 lines
3.7 KiB
Markdown
# 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 <repo-url> 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 <path>` | `/tmp/mixer-daemon.sock` | Unix socket path |
|
|
| `--inputs <N>` | 2 | Number of JACK input channels |
|
|
| `--outputs <N>` | 2 | Number of JACK output channels |
|
|
| `--sample-rate <N>` | 48000 | Audio sample rate (overridden by JACK) |
|
|
| `--buffer-size <N>` | 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.
|