// Copyright (c) 2026 Ourpad Network // See LICENSE file in the project root for full license text. #pragma once #include #include #include #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 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