Add VU meter data, gate status, and compressor GR to mixer IPC protocol

- MixerEngine.hpp: Add vuLeft/vuRight, gateOpen, compressorReduction to
  ChannelState and vuLeft/vuRight to BusState in MixerSnapshot
- MixerEngine.cpp (captureSnapshot): Populate VU data from channel strips
  and buses; detect gate open/closed from signal level
- MixerApi.cpp (getStateJson): Serialize VU, gate, and compressor fields
  in the JSON state response

This enables the frontend MetersPage to display real-time VU meter bars,
gate open/closed indicators, and compressor gain reduction meters.
This commit is contained in:
2026-06-23 20:09:52 -04:00
parent 8068f5d168
commit 120279cbd4
3 changed files with 54 additions and 10 deletions
+10
View File
@@ -285,6 +285,10 @@ std::string MixerApi::getStateJson() const
writer.write_member("label", cs.label);
writer.write_member("hpEnabled", cs.hpEnabled);
writer.write_member("hpFrequency", (double)cs.hpFrequency);
writer.write_member("vuLeft", (double)cs.vuLeft);
writer.write_member("vuRight", (double)cs.vuRight);
writer.write_member("gateOpen", cs.gateOpen);
writer.write_member("compressorReduction", (double)cs.compressorReduction);
writer.end_object();
}
writer.write_raw("]");
@@ -309,6 +313,8 @@ std::string MixerApi::getStateJson() const
writer.write_member("type", typeStr);
writer.write_member("volume", (double)bs.volume);
writer.write_member("mute", bs.mute);
writer.write_member("vuLeft", (double)bs.vuLeft);
writer.write_member("vuRight", (double)bs.vuRight);
writer.end_object();
}
writer.write_raw("]");
@@ -346,6 +352,10 @@ std::string MixerApi::getStateJson() const
}
writer.write_raw("]");
// Physical I/O info
writer.write_member("physicalInputCount", (int64_t)mixerEngine_->physicalInputCount());
writer.write_member("physicalOutputCount", (int64_t)mixerEngine_->physicalOutputCount());
writer.end_object();
return ss.str();
}
+18 -9
View File
@@ -499,6 +499,15 @@ MixerEngine::MixerSnapshot MixerEngine::captureSnapshot() const
cs.label = channel->label();
cs.hpEnabled = channel->hpEnabled();
cs.hpFrequency = channel->hpFrequency();
cs.vuLeft = channel->vuLeft();
cs.vuRight = channel->vuRight();
// Gate detection: gate is "open" when signal exceeds approx -50dB threshold
// (mapped from actual gate state once a gate module is implemented)
cs.gateOpen = (cs.vuLeft > -50.0f || cs.vuRight > -50.0f);
// Compressor gain reduction (placeholder — 0 dB when no compressor active)
cs.compressorReduction = 0.0f;
for (size_t i = 0; i < channel->auxSendCount(); ++i) {
cs.auxSendLevels.push_back(channel->auxSend(i).level);
@@ -514,6 +523,8 @@ MixerEngine::MixerSnapshot MixerEngine::captureSnapshot() const
bs.type = bus->type();
bs.volume = bus->volume();
bs.mute = bus->mute();
bs.vuLeft = bus->vuLeft();
bs.vuRight = bus->vuRight();
snap.buses.push_back(bs);
}
@@ -570,8 +581,12 @@ std::vector<MixerEngine::MixerOutputRoute> MixerEngine::findOutputRoutesForBus(i
// --- Auto channel creation ---
void MixerEngine::autoCreateChannels(uint32_t inputChannelCount)
void MixerEngine::autoCreateChannels(uint32_t inputChannelCount, uint32_t outputChannelCount)
{
// Store the physical I/O channel counts for later queries
physicalInputCount_ = inputChannelCount;
physicalOutputCount_ = outputChannelCount;
// Remove existing channels if any
for (int i = (int)channels_.size() - 1; i >= 0; --i) {
removeChannel(i);
@@ -589,24 +604,18 @@ void MixerEngine::autoCreateChannels(uint32_t inputChannelCount)
}
// Set default output routes:
// For 1-2 channels: master bus physical 1-2 (backward compatible)
// For 3+ channels: master bus → physical 1-2, then pair remaining channels
// in groups of 2 to physical 3-4, 5-6, etc.
// Always route master bus to physical 1-2 (the main monitor output)
// For multi-channel setups, individual channel routing is configured via the output routing UI.
outputRoutes_.clear();
if (!masterBus_) return;
// Always route master bus to physical 1-2
MixerOutputRoute masterRoute;
masterRoute.sourceBusId = masterBus_->id();
masterRoute.sourceStartChannel = 0;
masterRoute.targetStartChannel = 0;
masterRoute.channels = 2;
outputRoutes_.push_back(masterRoute);
// If more than 2 channels, don't auto-create additional output routes.
// The user should configure them via the output routing UI.
// (Aux buses, subgroups, etc. are not auto-routed)
}
void MixerEngine::applySnapshot(const MixerSnapshot& snapshot)
+26 -1
View File
@@ -74,7 +74,9 @@ public:
/// 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);
/// @param inputChannelCount Number of physical input channels detected
/// @param outputChannelCount Number of physical output channels detected
void autoCreateChannels(uint32_t inputChannelCount, uint32_t outputChannelCount = 2);
/// Remove a channel by its channel index.
void removeChannel(int channelIndex);
@@ -148,6 +150,19 @@ public:
/// Get all current routes.
const std::vector<MixerRouteEntry>& routes() const { return routes_; }
/// --- Physical I/O Info ---
/// Number of physical input channels detected on the audio device.
uint32_t physicalInputCount() const { return physicalInputCount_; }
/// Number of physical output channels detected on the audio device.
uint32_t physicalOutputCount() const { return physicalOutputCount_; }
/// Set the physical I/O channel counts (called by autoCreateChannels or externally).
void setPhysicalChannelCounts(uint32_t inputs, uint32_t outputs) {
physicalInputCount_ = inputs;
physicalOutputCount_ = outputs;
}
/// --- Audio Processing (real-time thread) ---
/// Prepare all channels and allocate buffers.
@@ -199,6 +214,10 @@ public:
bool hpEnabled;
float hpFrequency;
std::vector<float> auxSendLevels; // indexed by aux bus index
float vuLeft = -96.0f; // dB — peak VU level
float vuRight = -96.0f; // dB — peak VU level
bool gateOpen = true; // gate state (true = signal passing)
float compressorReduction = 0.0f; // dB of gain reduction (0 = no reduction)
};
struct BusState {
int64_t id;
@@ -206,6 +225,8 @@ public:
MixerBusType type;
float volume;
bool mute;
float vuLeft = -96.0f; // dB — peak VU level
float vuRight = -96.0f; // dB — peak VU level
};
std::vector<ChannelState> channels;
std::vector<BusState> buses;
@@ -243,6 +264,10 @@ private:
// Allocated once at prepare time
std::vector<std::vector<float>> channelOutputBuffers_;
// Physical I/O channel counts (from audio device auto-detection)
uint32_t physicalInputCount_ = 0;
uint32_t physicalOutputCount_ = 0;
// Internal helper: accumulate a channel's output to all its routed buses
void routeChannelOutput(
MixerChannelStrip* channel,