Mixer engine: output routing, full state restore, MIDI learn API, PipeWire multi-channel support

This commit is contained in:
2026-06-20 16:20:30 -04:00
parent 01584f50da
commit 8068f5d168
12 changed files with 435 additions and 19 deletions
+48
View File
@@ -11,6 +11,7 @@
#include <functional>
#include "MixerChannelStrip.hpp"
#include "MixerBus.hpp"
#include "MidiMapper.hpp"
namespace pipedal {
@@ -70,6 +71,11 @@ public:
/// Returns a pointer to the new channel (valid until removed).
MixerChannelStrip* addChannel(int physicalInputIndex);
/// Auto-create channels based on the number of detected input channels.
/// Removes existing channels and creates one strip per input.
/// Also sets up default output routes.
void autoCreateChannels(uint32_t inputChannelCount);
/// Remove a channel by its channel index.
void removeChannel(int channelIndex);
@@ -113,6 +119,32 @@ public:
/// Clear all routes.
void clearRoutes();
/// --- Output Routing ---
/// Describes a mapping from a mixer bus to physical output channels.
/// Multiple routes can be active simultaneously (e.g. Master→1-2, Aux1→3-4).
struct MixerOutputRoute {
int64_t sourceBusId; // Bus to route from
int sourceStartChannel; // Starting channel on the bus (0=L, 1=R)
int targetStartChannel; // Starting physical output channel
int channels; // Number of consecutive channels to route (1 or 2 typically)
};
/// Get the current output routing table (bus → physical output channel mapping).
const std::vector<MixerOutputRoute>& outputRoutes() const { return outputRoutes_; }
/// Set the entire output routing table.
void setOutputRoutes(const std::vector<MixerOutputRoute>& routes);
/// Add a single output route.
void addOutputRoute(int64_t busId, int sourceStartChannel, int targetStartChannel, int channels);
/// Remove all output routes for a given bus.
void removeOutputRoutes(int64_t busId);
/// Get all routes for a given bus.
std::vector<MixerOutputRoute> findOutputRoutesForBus(int64_t busId) const;
/// Get all current routes.
const std::vector<MixerRouteEntry>& routes() const { return routes_; }
@@ -143,6 +175,16 @@ public:
/// True if any channel has solo engaged.
bool anySoloActive() const;
/// --- MIDI Control Surface Mapping ---
/// Access the MIDI mapper for CC control surface mapping.
MidiMapper& midiMapper() { return midiMapper_; }
const MidiMapper& midiMapper() const { return midiMapper_; }
/// Process a MIDI event (typically from the real-time audio thread).
/// Routes CC messages to the midi mapper. Returns true if consumed.
bool processMidiEvent(const struct MidiEvent& event);
/// --- State Serialization ---
struct MixerSnapshot {
@@ -181,6 +223,9 @@ private:
// Routing entries
std::vector<MixerRouteEntry> routes_;
// Output routing entries (bus → physical output channel mapping)
std::vector<MixerOutputRoute> outputRoutes_;
// Audio configuration
uint32_t sampleRate_ = 48000;
size_t maxBufferSize_ = 512;
@@ -188,6 +233,9 @@ private:
// IHost reference for FX preparation
IHost* pHost_ = nullptr;
// MIDI CC control surface mapper
MidiMapper midiMapper_;
// Next bus ID counter
static std::atomic<int64_t> nextBusId_;