From 52b734021340a375acf15910d6071b57c014e45b Mon Sep 17 00:00:00 2001 From: falkTX Date: Wed, 11 Dec 2019 10:23:11 +0000 Subject: [PATCH] Continue stuff for cv controls Signed-off-by: falkTX --- source/backend/CarlaEngine.hpp | 14 +++- source/backend/engine/CarlaEngineGraph.cpp | 4 +- source/backend/engine/CarlaEngineInternal.hpp | 42 ++++++++++ source/backend/engine/CarlaEnginePorts.cpp | 76 +++++++++++-------- .../backend/plugin/CarlaPluginLADSPADSSI.cpp | 30 +++++--- 5 files changed, 119 insertions(+), 47 deletions(-) diff --git a/source/backend/CarlaEngine.hpp b/source/backend/CarlaEngine.hpp index 2efb7304c..fc3bcad60 100644 --- a/source/backend/CarlaEngine.hpp +++ b/source/backend/CarlaEngine.hpp @@ -527,6 +527,16 @@ public: return kEnginePortTypeEvent; } + /*! + * Add a CV port as a source of events. + */ + void addCVSource(CarlaEngineCVPort* port) noexcept; + + /*! + * Remove a CV port as a source of events. + */ + void removeCVSource(CarlaEngineCVPort* port) noexcept; + /*! * Initialize the port's internal buffer for @a engine. */ @@ -583,8 +593,8 @@ public: #ifndef DOXYGEN protected: - EngineEvent* fBuffer; - const EngineProcessMode kProcessMode; + struct ProtectedData; + ProtectedData* const pData; friend class CarlaPluginInstance; CARLA_DECLARE_NON_COPY_CLASS(CarlaEngineEventPort) diff --git a/source/backend/engine/CarlaEngineGraph.cpp b/source/backend/engine/CarlaEngineGraph.cpp index c1c73c7fb..0cd592fab 100644 --- a/source/backend/engine/CarlaEngineGraph.cpp +++ b/source/backend/engine/CarlaEngineGraph.cpp @@ -1430,7 +1430,7 @@ public: if (CarlaEngineEventPort* const port = fPlugin->getDefaultEventInPort()) { - EngineEvent* const engineEvents(port->fBuffer); + EngineEvent* const engineEvents(port->pData->buffer); CARLA_SAFE_ASSERT_RETURN(engineEvents != nullptr,); carla_zeroStructs(engineEvents, kMaxEngineEventInternalCount); @@ -1505,7 +1505,7 @@ public: if (CarlaEngineEventPort* const port = fPlugin->getDefaultEventOutPort()) { - /*const*/ EngineEvent* const engineEvents(port->fBuffer); + /*const*/ EngineEvent* const engineEvents(port->pData->buffer); CARLA_SAFE_ASSERT_RETURN(engineEvents != nullptr,); fillWaterMidiBufferFromEngineEvents(midi, engineEvents); diff --git a/source/backend/engine/CarlaEngineInternal.hpp b/source/backend/engine/CarlaEngineInternal.hpp index 5f53b405d..32d0efd86 100644 --- a/source/backend/engine/CarlaEngineInternal.hpp +++ b/source/backend/engine/CarlaEngineInternal.hpp @@ -20,6 +20,7 @@ #include "CarlaEngineThread.hpp" #include "CarlaEngineUtils.hpp" +#include "LinkedList.hpp" #ifndef BUILD_BRIDGE # include "CarlaEngineOsc.hpp" @@ -208,6 +209,47 @@ struct EnginePluginData { float peaks[4]; }; +// ----------------------------------------------------------------------- +// CarlaEngineEventPortProtectedData + +struct CarlaEngineEventCV { + CarlaEngineCVPort* cvPort; + float previousValue; +}; + +struct CarlaEngineEventPort::ProtectedData { + EngineEvent* buffer; + const EngineProcessMode processMode; + LinkedList cvs; + + ProtectedData(const EngineProcessMode pm) noexcept + : buffer(nullptr), + processMode(pm), + cvs() + { + if (processMode == ENGINE_PROCESS_MODE_PATCHBAY) + { + buffer = new EngineEvent[kMaxEngineEventInternalCount]; + carla_zeroStructs(buffer, kMaxEngineEventInternalCount); + } + } + + ~ProtectedData() noexcept + { + cvs.clear(); + + if (processMode == ENGINE_PROCESS_MODE_PATCHBAY) + { + CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,); + + delete[] buffer; + buffer = nullptr; + } + } + + CARLA_DECLARE_NON_COPY_STRUCT(ProtectedData) +}; + // ----------------------------------------------------------------------- // CarlaEngineProtectedData diff --git a/source/backend/engine/CarlaEnginePorts.cpp b/source/backend/engine/CarlaEnginePorts.cpp index 0eaeded29..979bcc7f0 100644 --- a/source/backend/engine/CarlaEnginePorts.cpp +++ b/source/backend/engine/CarlaEnginePorts.cpp @@ -1,6 +1,6 @@ /* * Carla Plugin Host - * Copyright (C) 2011-2014 Filipe Coelho + * Copyright (C) 2011-2019 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -15,6 +15,7 @@ * For a full copy of the GNU General Public License see the doc/GPL.txt file. */ +#include "CarlaEngineInternal.hpp" #include "CarlaEngineUtils.hpp" #include "CarlaMathUtils.hpp" #include "CarlaMIDI.h" @@ -89,50 +90,61 @@ void CarlaEngineCVPort::initBuffer() noexcept CarlaEngineEventPort::CarlaEngineEventPort(const CarlaEngineClient& client, const bool isInputPort, const uint32_t indexOffset) noexcept : CarlaEnginePort(client, isInputPort, indexOffset), - fBuffer(nullptr), - kProcessMode(client.getEngine().getProccessMode()) + pData(new ProtectedData(client.getEngine().getProccessMode())) { carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s)", bool2str(isInputPort)); - - if (kProcessMode == ENGINE_PROCESS_MODE_PATCHBAY) - { - fBuffer = new EngineEvent[kMaxEngineEventInternalCount]; - carla_zeroStructs(fBuffer, kMaxEngineEventInternalCount); - } } CarlaEngineEventPort::~CarlaEngineEventPort() noexcept { carla_debug("CarlaEngineEventPort::~CarlaEngineEventPort()"); + delete pData; +} - if (kProcessMode == ENGINE_PROCESS_MODE_PATCHBAY) - { - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); +void CarlaEngineEventPort::addCVSource(CarlaEngineCVPort* const port) noexcept +{ + CARLA_SAFE_ASSERT_RETURN(port != nullptr,); + CARLA_SAFE_ASSERT_RETURN(port->isInput(),); + carla_debug("CarlaEngineEventPort::addCVSource(%p)", port); - delete[] fBuffer; - fBuffer = nullptr; - } + const CarlaEngineEventCV ecv { port, 0.0f }; + pData->cvs.append(ecv); +} + +void CarlaEngineEventPort::removeCVSource(CarlaEngineCVPort* const port) noexcept +{ + carla_debug("CarlaEngineEventPort::removeCVSource(%p)", port); + + // pData->cvPorts.removeOne(port); + // TODO + return; + (void)port; } void CarlaEngineEventPort::initBuffer() noexcept { - if (kProcessMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == ENGINE_PROCESS_MODE_BRIDGE) - fBuffer = kClient.getEngine().getInternalEventBuffer(kIsInput); - else if (kProcessMode == ENGINE_PROCESS_MODE_PATCHBAY && ! kIsInput) - carla_zeroStructs(fBuffer, kMaxEngineEventInternalCount); + if (pData->processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->processMode == ENGINE_PROCESS_MODE_BRIDGE) + pData->buffer = kClient.getEngine().getInternalEventBuffer(kIsInput); + else if (pData->processMode == ENGINE_PROCESS_MODE_PATCHBAY && ! kIsInput) + carla_zeroStructs(pData->buffer, kMaxEngineEventInternalCount); + + for (LinkedList::Itenerator it = pData->cvs.begin2(); it.valid(); it.next()) + { + // TODO append events to buffer + } } uint32_t CarlaEngineEventPort::getEventCount() const noexcept { CARLA_SAFE_ASSERT_RETURN(kIsInput, 0); - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, 0); - CARLA_SAFE_ASSERT_RETURN(kProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && kProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, 0); + CARLA_SAFE_ASSERT_RETURN(pData->buffer != nullptr, 0); + CARLA_SAFE_ASSERT_RETURN(pData->processMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && pData->processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, 0); uint32_t i=0; for (; i < kMaxEngineEventInternalCount; ++i) { - if (fBuffer[i].type == kEngineEventTypeNull) + if (pData->buffer[i].type == kEngineEventTypeNull) break; } @@ -142,16 +154,16 @@ uint32_t CarlaEngineEventPort::getEventCount() const noexcept const EngineEvent& CarlaEngineEventPort::getEvent(const uint32_t index) const noexcept { CARLA_SAFE_ASSERT_RETURN(kIsInput, kFallbackEngineEvent); - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, kFallbackEngineEvent); - CARLA_SAFE_ASSERT_RETURN(kProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && kProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, kFallbackEngineEvent); + CARLA_SAFE_ASSERT_RETURN(pData->buffer != nullptr, kFallbackEngineEvent); + CARLA_SAFE_ASSERT_RETURN(pData->processMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && pData->processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, kFallbackEngineEvent); CARLA_SAFE_ASSERT_RETURN(index < kMaxEngineEventInternalCount, kFallbackEngineEvent); - return fBuffer[index]; + return pData->buffer[index]; } const EngineEvent& CarlaEngineEventPort::getEventUnchecked(const uint32_t index) const noexcept { - return fBuffer[index]; + return pData->buffer[index]; } bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEvent& ctrl) noexcept @@ -162,8 +174,8 @@ bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t param, const float value) noexcept { CARLA_SAFE_ASSERT_RETURN(! kIsInput, false); - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); - CARLA_SAFE_ASSERT_RETURN(kProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && kProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); + CARLA_SAFE_ASSERT_RETURN(pData->buffer != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(pData->processMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && pData->processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false); CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f); @@ -174,7 +186,7 @@ bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t for (uint32_t i=0; i < kMaxEngineEventInternalCount; ++i) { - EngineEvent& event(fBuffer[i]); + EngineEvent& event(pData->buffer[i]); if (event.type != kEngineEventTypeNull) continue; @@ -208,15 +220,15 @@ bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t cha bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t size, const uint8_t* const data) noexcept { CARLA_SAFE_ASSERT_RETURN(! kIsInput, false); - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); - CARLA_SAFE_ASSERT_RETURN(kProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && kProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); + CARLA_SAFE_ASSERT_RETURN(pData->buffer != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(pData->processMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && pData->processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); CARLA_SAFE_ASSERT_RETURN(size > 0 && size <= EngineMidiEvent::kDataSize, false); CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); for (uint32_t i=0; i < kMaxEngineEventInternalCount; ++i) { - EngineEvent& event(fBuffer[i]); + EngineEvent& event(pData->buffer[i]); if (event.type != kEngineEventTypeNull) continue; diff --git a/source/backend/plugin/CarlaPluginLADSPADSSI.cpp b/source/backend/plugin/CarlaPluginLADSPADSSI.cpp index 38899c5ac..e96b2451f 100644 --- a/source/backend/plugin/CarlaPluginLADSPADSSI.cpp +++ b/source/backend/plugin/CarlaPluginLADSPADSSI.cpp @@ -1056,10 +1056,6 @@ public: const char* const paramName(fDescriptor->PortNames[i] != nullptr ? fDescriptor->PortNames[i] : "unknown"); - // CV stuff - portName = paramName; - portName.truncate(portNameSize); - float min, max, def, step, stepSmall, stepLarge; // min value @@ -1127,10 +1123,6 @@ public: pData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE; needsCtrlIn = true; - // Parameter as CV - pData->param.cvPorts[j] = (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, true, j); - CARLA_SAFE_ASSERT(pData->param.cvPorts[j] != nullptr); - // MIDI CC value if (fDssiDescriptor != nullptr && fDssiDescriptor->get_midi_controller_for_port != nullptr) { @@ -1147,9 +1139,6 @@ public: { pData->param.data[j].type = PARAMETER_OUTPUT; - // Parameter as CV - pData->param.cvPorts[j] = (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, false, j); - if (std::strcmp(paramName, "latency") == 0 || std::strcmp(paramName, "_latency") == 0) { min = 0.0f; @@ -1232,6 +1221,25 @@ public: portName.truncate(portNameSize); pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, 0); + + for (uint32_t i=0; i < params; ++i) + { + const int32_t rindex = pData->param.data[i].rindex; + CARLA_SAFE_ASSERT_CONTINUE(rindex >= 0); + + if (pData->param.data[i].type != PARAMETER_INPUT) + continue; + if (fDescriptor->PortNames[rindex] == nullptr || fDescriptor->PortNames[rindex][0] == '\0') + continue; + + portName = fDescriptor->PortNames[rindex]; + portName.truncate(portNameSize); + + // Parameter as CV + CarlaEngineCVPort* const cvPort = + (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, true, i); + pData->event.portIn->addCVSource(cvPort); + } } if (needsCtrlOut)