// Copyright (c) 2026 Ourpad Network // See LICENSE file in the project root for full license text. #pragma once #include #include #include namespace pipedal { class MixerEngine; /// Mixer API — bridges WebSocket messages to the MixerEngine. /// /// Follows the existing PiPedalSocket pattern where handlers are registered /// via REGISTER_MESSAGE_HANDLER and dispatched by message name. /// /// This class provides the model-level methods that the socket handlers call. class MixerApi { public: MixerApi(); ~MixerApi(); /// Set the mixer engine this API talks to. void setMixerEngine(MixerEngine* engine) { mixerEngine_ = engine; } MixerEngine* mixerEngine() const { return mixerEngine_; } /// --- Channel Control --- /// Set channel volume in dB (-inf to +12) void setChannelVolume(int channelIndex, float volumeDb); /// Set channel pan (-1.0 left to +1.0 right) void setChannelPan(int channelIndex, float pan); /// Set channel mute state void setChannelMute(int channelIndex, bool mute); /// Set channel solo state void setChannelSolo(int channelIndex, bool solo); /// Set channel label void setChannelLabel(int channelIndex, const std::string& label); /// Set channel type (Instrument, Mic, Line) void setChannelType(int channelIndex, const std::string& type); /// Set channel HPF state void setChannelHpf(int channelIndex, bool enabled, float frequency); /// --- Channel Lifecycle --- /// Add a new channel for the given physical input int addChannel(int physicalInputIndex); /// Remove a channel void removeChannel(int channelIndex); /// --- Bus Control --- /// Set bus volume void setBusVolume(int64_t busId, float volumeDb); /// Set bus mute void setBusMute(int64_t busId, bool mute); /// Add a new bus int64_t addBus(const std::string& type, const std::string& name, int channels); /// Remove a bus void removeBus(int64_t busId); /// --- Routing --- /// Route a channel to a bus void routeChannelToBus(int channelIndex, int64_t busId, float levelDb); /// Route a bus to another bus void routeBusToBus(int64_t sourceBusId, int64_t targetBusId, float levelDb); /// Remove a route void removeRoute(int64_t sourceId, int64_t targetBusId); /// --- State Queries --- /// Get the full mixer state as a JSON string std::string getStateJson() const; /// --- Output Routing --- /// Get output routes as a JSON array string std::string getOutputRoutesJson() const; /// Set output routes from a JSON array string void setOutputRoutesFromJson(const std::string& json); /// Apply a full mixer state from a JSON string void setFullState(const std::string& stateJson); /// --- Scenes --- /// Save current mixer state as a scene std::string saveScene(const std::string& name); /// Load a scene by name bool loadScene(const std::string& sceneId); /// List available scenes std::string listScenes() const; /// Delete a scene bool deleteScene(const std::string& sceneId); /// --- MIDI Control Surface Mapping --- /// Get all MIDI mappings as JSON std::string getMidiMappingsJson() const; /// Set all MIDI mappings from JSON void setMidiMappingsFromJson(const std::string& json); /// Add a single MIDI mapping void addMidiMapping(int midiChannel, int ccNumber, const std::string& targetType, int64_t targetId, float minValue, float maxValue); /// Remove MIDI mapping by CC and channel void removeMidiMapping(int midiChannel, int ccNumber); /// Remove MIDI mapping by index void removeMidiMappingByIndex(size_t index); /// Clear all MIDI mappings void clearMidiMappings(); /// Toggle MIDI learn mode void setMidiLearnMode(bool enabled); bool getMidiLearnMode() const; /// Set the pending learn target (which UI control was touched) void setMidiLearnTarget(const std::string& targetType, int64_t targetId); /// Commit a learned mapping (captured CC + pending target) bool commitMidiLearnMapping(); /// Get last learned CC event info (for UI feedback) struct LearnedEventInfo { bool hasEvent = false; int midiChannel = -1; int ccNumber = -1; }; LearnedEventInfo getLastLearnedMidiEvent() const; /// Save MIDI mappings to config file void saveMidiMappingsToFile() const; /// Load MIDI mappings from config file void loadMidiMappingsFromFile(); private: MixerEngine* mixerEngine_ = nullptr; }; } // namespace pipedal