- MixerEngine.hpp: Add vuLeft/vuRight, gateOpen, compressorReduction to
ChannelState and vuLeft/vuRight to BusState in MixerSnapshot
- MixerEngine.cpp (captureSnapshot): Populate VU data from channel strips
and buses; detect gate open/closed from signal level
- MixerApi.cpp (getStateJson): Serialize VU, gate, and compressor fields
in the JSON state response
This enables the frontend MetersPage to display real-time VU meter bars,
gate open/closed indicators, and compressor gain reduction meters.
Add MixerEngine creation and wiring after model.Load() in main.cpp.
The mixer engine now gets created with current audio settings (sample rate,
buffer size from JackServerSettings), activated, and attached to the model.
This enables WebSocket mixer commands (mixerGetState, mixerAddChannel,
mixerAddBus, etc.) to work through /pipedal endpoint.
Missing initialization was the root cause of 'Invalid format' errors when
sending mixer commands via WebSocket.
- PipeWireDriver.hpp/cpp: new AudioDriver implementation using pw_filter API
- Full-duplex I/O via pw_filter (capture + playback in one RT callback)
- Dynamic channel count support (tested: 1-8 channels, extensible beyond)
- Uses SPA_AUDIO_FORMAT_F32 for zero-copy-compatible float processing
- Channel position mapping: MONO, stereo, 5.1, 7.1, plus Aux for N>8
- Follows the same buffer management pattern as AlsaDriverImpl
- Channel routing: main/aux input/output mapping with mix ops
- CLI flag: --driver pipewire|alsa (default: alsa)
- AudioHost: conditional driver selection based on driverType_
- PiPedalModel: stores and passes driver type to AudioHost
- CMakeLists.txt: added PipeWireDriver source files
- Implement saveScene: captures full mixer state via getStateJson(),
stores in ~/op-pedal/default_config/scenes.json with auto-incrementing ID
- Implement loadScene: manual JSON walk to restore channel/bus state
from saved scene JSON, routes skipped for safety
- Implement listScenes: returns JSON array of {id, name}
- Implement deleteScene: remove by ID from scenes file
- Add WS handlers: mixerSaveScene, mixerLoadScene, mixerGetScenes
registered in PiPedalSocket.cpp message dispatcher
- Uses project's JSON_MAP/raw_json_string for file persistence
- Compiles cleanly against existing build
New files:
- MixerApi.hpp/cpp: Model-level API bridging WebSocket messages to
MixerEngine control (channel volume/pan/mute/solo/hpf, bus control,
routing, state queries)
- 15 new WebSocket message handlers in PiPedalSocket.cpp for full
mixer control surface
Integration:
- MixerEngine member added to PiPedalModel with Get/Set accessors
- SetMixerEngine propagates to AudioHost rt processing pipeline
- Socket handler auto-wires MixerEngine to MixerApi on connect
Messages implemented:
mixerSetChannelVolume, mixerSetChannelPan, mixerSetChannelMute,
mixerSetChannelSolo, mixerSetChannelLabel, mixerSetChannelHpf,
mixerGetState, mixerAddChannel, mixerRemoveChannel,
mixerSetBusVolume, mixerSetBusMute, mixerAddBus, mixerRemoveBus,
mixerRouteChannelToBus
When SetMixerEngine() is called with a MixerEngine instance, the
audio processing thread routes all device input/output channels
through the mixer (channel strips → buses → master) instead of
the legacy Lv2Pedalboard. Falls back when no mixer engine is set.
- Thread-safe via mutex + realtime raw pointer swap (same pattern
as existing SetPedalboard)
- Preserves existing pedalboard processing — both modes coexist
- New ProcessLv2Pedalboard() path when realtimeActiveMixerEngine
is non-null uses device buffers directly for multi-channel I/O
MixerEngine architecture:
- MixerChannelStrip: per-input FX chain (Lv2Pedalboard reuse),
volume, pan, mute, solo, HPF, aux sends, VU metering
- MixerBus: accumulation bus with volume, mute, VU. Supports
master, subgroup, aux, and FX-return bus types
- MixerEngine: orchestrator managing channel→bus routing graph,
bus→bus routing, solo override, and the full real-time audio
processing cycle
All new code compiles cleanly with the existing C++20 build and
follows the existing PiPedal codebase conventions (namespaces,
error handling, buffer patterns). CPU-efficient real-time thread
processing with atomic control surface interaction.
Reset midiEventMemoryIndex in AlsaDriver.cpp when starting MIDI processing and when clearing midiEventCount to avoid stale index/state issues while using expression pedals.
- Add missing <unistd.h> include in AlsaDriverTest.cpp for sleep().
- Link Catch2::Catch2WithMain alongside Catch2::Catch2 for pipedaltest
and jsonTest test targets. Catch2 v3 requires this for CATCH_CONFIG_MAIN
to provide the main() entry point.
GCC 16 on Arch Linux no longer implicitly includes certain standard
headers. This causes 'not declared' errors for POSIX functions.
- PiPedalCommon/src/CMakeLists.txt: Link asound library for ALSA sequencer
- DBusDispatcher.cpp: Add <unistd.h> for read()/write()/close()
- AuxInTest.cpp: Add <unistd.h> for sleep()
- kconfigMain.cpp: Add <unistd.h> for getuid()
- ModFileTypes.cpp: Add <mutex> for std::mutex/std::lock_guard
Replace dpkg --print-architecture (Debian-specific) with a portable
cmake-based approach using CMAKE_SYSTEM_PROCESSOR mapped to Debian
architecture names (x86_64→amd64, aarch64→arm64, armv7l→armhf, i686→i386).