#ifndef OPLABSBANDBUS_HPP #define OPLABSBANDBUS_HPP #include #include #include #include #include #include /** * OPLabsBandBus — 8-channel stereo bus mixer LV2 plugin. * * Sums 8 stereo input pairs into a stereo output with per-channel * volume, pan, mute controls and peak level metering. Includes master * volume and mute. Compatible with PiPedal and any LV2 host. * * Port layout (62 ports total): * Audio inputs: ch1L..ch8R (0–15, 16 ports) * Audio outputs: outL, outR (16–17, 2 ports) * Controls in: ch1Vol..ch8Vol (18–25, 8 ports) * ch1Pan..ch8Pan (26–33, 8 ports) * ch1Mute..ch8Mute(34–41, 8 ports) * masterVol (42, 1 port) * masterMute (43, 1 port) * Controls out: ch1LevelL..ch8LevelL (44–51, 8 ports) * ch1LevelR..ch8LevelR (52–59, 8 ports) * masterLevelL, masterLevelR (60–61, 2 ports) * * URI: http://ourpad.casa/plugins/oplabs-band-bus# */ class OPLabsBandBus { public: static constexpr const char* URI = "http://ourpad.casa/plugins/oplabs-band-bus#"; static constexpr uint32_t kNumChannels = 8; enum Ports : uint32_t { // Audio inputs (16) kCh1L = 0, kCh1R = 1, kCh2L = 2, kCh2R = 3, kCh3L = 4, kCh3R = 5, kCh4L = 6, kCh4R = 7, kCh5L = 8, kCh5R = 9, kCh6L = 10, kCh6R = 11, kCh7L = 12, kCh7R = 13, kCh8L = 14, kCh8R = 15, // Audio outputs (2) kOutL = 16, kOutR = 17, // Per-channel volume (8) kCh1Vol = 18, kCh2Vol = 19, kCh3Vol = 20, kCh4Vol = 21, kCh5Vol = 22, kCh6Vol = 23, kCh7Vol = 24, kCh8Vol = 25, // Per-channel pan (8) kCh1Pan = 26, kCh2Pan = 27, kCh3Pan = 28, kCh4Pan = 29, kCh5Pan = 30, kCh6Pan = 31, kCh7Pan = 32, kCh8Pan = 33, // Per-channel mute (8) kCh1Mute = 34, kCh2Mute = 35, kCh3Mute = 36, kCh4Mute = 37, kCh5Mute = 38, kCh6Mute = 39, kCh7Mute = 40, kCh8Mute = 41, // Master controls (2) kMasterVol = 42, kMasterMute = 43, // Per-channel level L (8) kCh1LevelL = 44, kCh2LevelL = 45, kCh3LevelL = 46, kCh4LevelL = 47, kCh5LevelL = 48, kCh6LevelL = 49, kCh7LevelL = 50, kCh8LevelL = 51, // Per-channel level R (8) kCh1LevelR = 52, kCh2LevelR = 53, kCh3LevelR = 54, kCh4LevelR = 55, kCh5LevelR = 56, kCh6LevelR = 57, kCh7LevelR = 58, kCh8LevelR = 59, // Master level (2) kMasterLevelL = 60, kMasterLevelR = 61, kNumPorts = 62 }; // ---- Static LV2 callbacks ---- static LV2_Handle instantiate(const LV2_Descriptor* descriptor, double sampleRate, const char* bundlePath, const LV2_Feature* const* features); static void connectPort(LV2_Handle instance, uint32_t port, void* data); static void activate(LV2_Handle instance); static void run(LV2_Handle instance, uint32_t nSamples); static void deactivate(LV2_Handle instance); static void cleanup(LV2_Handle instance); static const void* extensionData(const char* uri); // ---- State callbacks ---- static LV2_State_Status saveState(LV2_Handle instance, LV2_State_Store_Function store, LV2_State_Handle handle, uint32_t flags, const LV2_Feature* const* features); static LV2_State_Status restoreState(LV2_Handle instance, LV2_State_Retrieve_Function retrieve, LV2_State_Handle handle, uint32_t flags, const LV2_Feature* const* features); private: OPLabsBandBus(double sampleRate, const LV2_Feature* const* features); ~OPLabsBandBus() = default; OPLabsBandBus(const OPLabsBandBus&) = delete; OPLabsBandBus& operator=(const OPLabsBandBus&) = delete; bool initUrids(const LV2_Feature* const* features); static inline float dBToGain(float dB) { return std::pow(10.0f, dB / 20.0f); } // URID map LV2_URID_Map* uridMap = nullptr; LV2_URID urid__stateDummy = 0; // Audio port pointers [ch][0=L,1=R] const float* pAudioIn[8][2] = {}; float* pAudioOut[2] = {}; // Control input port pointers const float* pVol[8] = {}; const float* pPan[8] = {}; const float* pMute[8] = {}; const float* pMasterVol = nullptr; const float* pMasterMute = nullptr; // Control output port pointers (meters) float* pLevelL[8] = {}; float* pLevelR[8] = {}; float* pMasterLevelL = nullptr; float* pMasterLevelR = nullptr; // Cached parameter values float cachedVol[8] = {}; float cachedPan[8] = {}; bool cachedMute[8] = {}; float cachedMasterVol = 0.0f; bool cachedMasterMute = false; // Peak meter state float peakL[8] = {}; float peakR[8] = {}; float peakMasterL = -70.0f; float peakMasterR = -70.0f; }; #endif // OPLABSBANDBUS_HPP