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.
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
// Copyright (c) 2026 Ourpad Network
|
||||
// See LICENSE file in the project root for full license text.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include "mixer/Types.hpp"
|
||||
|
||||
namespace mixer {
|
||||
|
||||
/// An audio bus that accumulates contributions from multiple sources.
|
||||
///
|
||||
/// Buses form the mixing topology:
|
||||
/// Channels → subgroups → master
|
||||
/// Channels → aux sends → aux buses (monitor mixes)
|
||||
/// Aux buses → FxReturn buses → subgroup or master
|
||||
class MixerBus {
|
||||
public:
|
||||
MixerBus(int64_t id, MixerBusType type, const std::string& name, int channels = 2);
|
||||
~MixerBus() = default;
|
||||
|
||||
/// Bus identity
|
||||
int64_t id() const { return id_; }
|
||||
MixerBusType type() const { return type_; }
|
||||
const std::string& name() const { return name_; }
|
||||
void setName(const std::string& name) { name_ = name; }
|
||||
|
||||
/// Channel count (1 = mono, 2 = stereo, N = multi-channel)
|
||||
int channelCount() const { return channelCount_; }
|
||||
|
||||
/// --- Control surface (atomic for RT-safe writes) ---
|
||||
|
||||
/// Master volume in dB (-inf to +12.0)
|
||||
float volume() const { return volume_.load(); }
|
||||
void setVolume(float db);
|
||||
|
||||
/// Mute
|
||||
bool mute() const { return mute_.load(); }
|
||||
void setMute(bool mute);
|
||||
|
||||
/// --- Audio buffers ---
|
||||
|
||||
/// Allocate internal buffers. Must be called before processing.
|
||||
void allocateBuffers(size_t maxFrames);
|
||||
|
||||
/// Get read/write pointer to internal buffer for a channel
|
||||
float* buffer(int channel) {
|
||||
if (channel >= 0 && channel < (int)buffers_.size())
|
||||
return buffers_[channel].data();
|
||||
return nullptr;
|
||||
}
|
||||
const float* buffer(int channel) const {
|
||||
if (channel >= 0 && channel < (int)buffers_.size())
|
||||
return buffers_[channel].data();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// Accumulate (sum) audio from a source into this bus with gain.
|
||||
void accumulate(
|
||||
const float* const* source,
|
||||
uint32_t frames,
|
||||
float gain,
|
||||
int sourceChannels
|
||||
);
|
||||
|
||||
/// Same as accumulate but for a single interleaved source buffer
|
||||
void accumulateMono(
|
||||
const float* source,
|
||||
uint32_t frames,
|
||||
float gain
|
||||
);
|
||||
|
||||
/// Clear all bus buffers to zero (must be called at start of each cycle)
|
||||
void clear();
|
||||
|
||||
/// Apply bus-level processing (volume, mute) to the internal mix.
|
||||
void process(uint32_t frames);
|
||||
|
||||
/// VU meter values after processing
|
||||
float vuLeft() const { return vuLeft_.load(); }
|
||||
float vuRight() const { return vuRight_.load(); }
|
||||
|
||||
/// Max frames this bus can handle
|
||||
size_t maxFrames() const { return maxFrames_; }
|
||||
|
||||
private:
|
||||
int64_t id_;
|
||||
MixerBusType type_;
|
||||
std::string name_;
|
||||
int channelCount_;
|
||||
|
||||
std::atomic<float> volume_{0.0f}; // dB
|
||||
std::atomic<bool> mute_{false};
|
||||
|
||||
// Internal accumulation buffers [channel][sample]
|
||||
std::vector<std::vector<float>> buffers_;
|
||||
|
||||
// VU tracking
|
||||
std::atomic<float> vuLeft_{-96.0f};
|
||||
std::atomic<float> vuRight_{-96.0f};
|
||||
|
||||
size_t maxFrames_ = 512;
|
||||
};
|
||||
|
||||
} // namespace mixer
|
||||
Reference in New Issue
Block a user