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

git clone <repo-url> oplabs-mixer-daemon
cd oplabs-mixer-daemon
mkdir build && cd build
cmake ..
make -j$(nproc)

Run

# 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.

# 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

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.

S
Description
OPLabs Standalone Mixer Engine Daemon — JACK audio I/O, Unix socket JSON control
Readme 1.9 MiB
Languages
Makefile 72.2%
C++ 18%
CMake 9.7%