Initial extraction: C++ MixerEngine standalone daemon
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.
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
// Copyright (c) 2026 Ourpad Network
|
||||
// See LICENSE file in the project root for full license text.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include "mixer/MixerEngine.hpp"
|
||||
|
||||
namespace mixer {
|
||||
|
||||
/// Unix domain socket JSON control server for the MixerEngine.
|
||||
///
|
||||
/// Listens on a Unix domain socket (default: /tmp/mixer-daemon.sock).
|
||||
/// Each client connection sends one JSON command per line and receives
|
||||
/// one JSON response per line.
|
||||
///
|
||||
/// Supported commands:
|
||||
/// {"cmd":"getState"} → full mixer state snapshot
|
||||
/// {"cmd":"getVU"} → VU levels for all channels
|
||||
/// {"cmd":"setChannelVolume","channel":N,"volume":-6.0}
|
||||
/// {"cmd":"setChannelPan","channel":N,"pan":0.0}
|
||||
/// {"cmd":"setChannelMute","channel":N,"mute":true}
|
||||
/// {"cmd":"setChannelSolo","channel":N,"solo":false}
|
||||
/// {"cmd":"setChannelLabel","channel":N,"label":"Guitar"}
|
||||
/// {"cmd":"setBusVolume","busId":N,"volume":0.0}
|
||||
/// {"cmd":"setBusMute","busId":N,"mute":false}
|
||||
/// {"cmd":"routeChannelToBus","channel":N,"busId":N,"level":0.0}
|
||||
/// {"cmd":"routeBusToBus","sourceBusId":N,"targetBusId":N,"level":0.0}
|
||||
/// {"cmd":"removeRoute","sourceId":N,"targetBusId":N}
|
||||
/// {"cmd":"autoCreateChannels","inputs":N,"outputs":N}
|
||||
/// {"cmd":"addChannel","physicalInput":N} → {"status":"ok","channelIndex":N}
|
||||
/// {"cmd":"removeChannel","channel":N}
|
||||
class MixerControlServer {
|
||||
public:
|
||||
MixerControlServer(MixerEngine* engine, const std::string& socketPath = "/tmp/mixer-daemon.sock");
|
||||
~MixerControlServer();
|
||||
|
||||
// Disable copy
|
||||
MixerControlServer(const MixerControlServer&) = delete;
|
||||
MixerControlServer& operator=(const MixerControlServer&) = delete;
|
||||
|
||||
/// Start the control server in a background thread.
|
||||
/// Returns true if the socket was created successfully.
|
||||
bool start();
|
||||
|
||||
/// Stop the control server and join the thread.
|
||||
void stop();
|
||||
|
||||
/// True if the server is running.
|
||||
bool running() const { return running_.load(); }
|
||||
|
||||
private:
|
||||
MixerEngine* engine_;
|
||||
std::string socketPath_;
|
||||
int serverFd_ = -1;
|
||||
std::thread serverThread_;
|
||||
std::atomic<bool> running_{false};
|
||||
|
||||
// Server thread main loop
|
||||
void serverLoop();
|
||||
|
||||
// Handle one client connection
|
||||
void handleClient(int clientFd);
|
||||
|
||||
// Process a single JSON command and return JSON response
|
||||
std::string processCommand(const std::string& commandJson);
|
||||
|
||||
// Helper: build full state JSON
|
||||
std::string buildStateJson() const;
|
||||
|
||||
// Helper: build VU JSON
|
||||
std::string buildVuJson() const;
|
||||
};
|
||||
|
||||
} // namespace mixer
|
||||
Reference in New Issue
Block a user