Files
oplabs-mixer-daemon/include/mixer/MixerControlServer.hpp
T
shawn a5423b7f55 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.
2026-06-23 12:17:45 -04:00

78 lines
2.6 KiB
C++

// 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