From 883f12080e2a4dd1a0eafbb3ca38aee282e43c40 Mon Sep 17 00:00:00 2001 From: falkTX Date: Fri, 21 Sep 2012 20:54:40 +0100 Subject: [PATCH] Carla: More of the same, misc fixing --- c++/carla-backend/carla_bridge.cpp | 2 + c++/carla-backend/carla_native.cpp | 638 ++++++++++++++++++++- c++/carla-backend/dssi.cpp | 2 + c++/carla-backend/ladspa.cpp | 2 + c++/carla-backend/lv2.cpp | 2 + c++/carla-backend/plugins/bypass.c | 75 ++- c++/carla-backend/plugins/carla_native.h | 25 +- c++/carla-backend/plugins/carla_nativemm.h | 84 ++- c++/carla-backend/plugins/midi-split.cpp | 23 +- c++/carla-backend/vst.cpp | 15 +- 10 files changed, 779 insertions(+), 89 deletions(-) diff --git a/c++/carla-backend/carla_bridge.cpp b/c++/carla-backend/carla_bridge.cpp index a9898cf..9774190 100644 --- a/c++/carla-backend/carla_bridge.cpp +++ b/c++/carla-backend/carla_bridge.cpp @@ -916,6 +916,8 @@ public: params = nullptr; + CarlaPlugin::deleteBuffers(); + qDebug("BridgePlugin::delete_buffers() - end"); } diff --git a/c++/carla-backend/carla_native.cpp b/c++/carla-backend/carla_native.cpp index 4a05d77..87e89b0 100644 --- a/c++/carla-backend/carla_native.cpp +++ b/c++/carla-backend/carla_native.cpp @@ -20,6 +20,17 @@ CARLA_BACKEND_START_NAMESPACE +struct NativePluginMidiData { + uint32_t count; + uint32_t* rindexes; + CarlaEngineMidiPort** ports; + + NativePluginMidiData() + : count(0), + rindexes(nullptr), + ports(nullptr) {} +}; + class NativePluginScopedInitiliazer { public: @@ -75,8 +86,24 @@ public: { qDebug("NativePlugin::~NativePlugin()"); - if (handle) - pass(); + if (descriptor) + { + if (descriptor->deactivate && m_activeBefore) + { + if (handle) + descriptor->deactivate(handle); + //if (h2) + // descriptor->deactivate(h2); + } + + if (descriptor->cleanup) + { + if (handle) + descriptor->cleanup(handle); + //if (h2) + // descriptor->cleanup(h2); + } + } } // ------------------------------------------------------------------- @@ -92,15 +119,73 @@ public: return getPluginCategoryFromName(m_name); } + // ------------------------------------------------------------------- + // Information (count) + + uint32_t midiInCount() + { + return mIn.count; + } + + uint32_t midiOutCount() + { + return mOut.count; + } + + uint32_t parameterScalePointCount(const uint32_t parameterId) + { + Q_ASSERT(descriptor); + Q_ASSERT(parameterId < param.count); + + int32_t rindex = param.data[parameterId].rindex; + + if (descriptor && rindex < (int32_t)descriptor->portCount) + { + const PluginPort* const port = &descriptor->ports[rindex]; + + if (port) + return port->scalePointCount; + } + + return 0; + } + // ------------------------------------------------------------------- // Information (per-plugin data) double getParameterValue(const uint32_t parameterId) { Q_ASSERT(descriptor); + Q_ASSERT(handle); Q_ASSERT(parameterId < param.count); - //return descriptor->get_parameter_value(); + if (descriptor && handle) + return descriptor->get_parameter_value(handle, parameterId); + + return 0.0; + } + + double getParameterScalePointValue(const uint32_t parameterId, const uint32_t scalePointId) + { + Q_ASSERT(descriptor); + Q_ASSERT(parameterId < param.count); + Q_ASSERT(scalePointId < parameterScalePointCount(parameterId)); + + const int32_t rindex = param.data[parameterId].rindex; + + if (descriptor && rindex < (int32_t)descriptor->portCount) + { + const PluginPort* const port = &descriptor->ports[rindex]; + + if (port && scalePointId < port->scalePointCount) + { + const PluginPortScalePoint* const scalePoint = &port->scalePoints[scalePointId]; + + if (scalePoint) + return scalePoint->value; + } + } + return 0.0; } @@ -149,12 +234,537 @@ public: Q_ASSERT(descriptor); Q_ASSERT(parameterId < param.count); + const int32_t rindex = param.data[parameterId].rindex; + + if (descriptor && rindex < (int32_t)descriptor->portCount) + { + const PluginPort* const port = &descriptor->ports[rindex]; + + if (port && port->name) + { + strncpy(strBuf, port->name, STR_MAX); + return; + } + } + + CarlaPlugin::getParameterName(parameterId, strBuf); + } + + void getParameterText(const uint32_t parameterId, char* const strBuf) + { + Q_ASSERT(descriptor); + Q_ASSERT(handle); + Q_ASSERT(parameterId < param.count); + + if (descriptor && handle) + { + const int32_t rindex = param.data[parameterId].rindex; + + const char* const text = descriptor->get_parameter_text(handle, rindex); + + if (text) + { + strncpy(strBuf, text, STR_MAX); + return; + } + } + + CarlaPlugin::getParameterText(parameterId, strBuf); + } + + void getParameterUnit(const uint32_t parameterId, char* const strBuf) + { + Q_ASSERT(descriptor); + Q_ASSERT(handle); + Q_ASSERT(parameterId < param.count); + + if (descriptor && handle) + { + const int32_t rindex = param.data[parameterId].rindex; + + const char* const unit = descriptor->get_parameter_unit(handle, rindex); + + if (unit) + { + strncpy(strBuf, unit, STR_MAX); + return; + } + } + + CarlaPlugin::getParameterUnit(parameterId, strBuf); + } + + void getParameterScalePointLabel(const uint32_t parameterId, const uint32_t scalePointId, char* const strBuf) + { + Q_ASSERT(descriptor); + Q_ASSERT(parameterId < param.count); + Q_ASSERT(scalePointId < parameterScalePointCount(parameterId)); + int32_t rindex = param.data[parameterId].rindex; if (descriptor && rindex < (int32_t)descriptor->portCount) - strncpy(strBuf, descriptor->ports[rindex].name, STR_MAX); - else - CarlaPlugin::getParameterName(parameterId, strBuf); + { + const PluginPort* const port = &descriptor->ports[rindex]; + + if (port && scalePointId < port->scalePointCount) + { + const PluginPortScalePoint* const scalePoint = &port->scalePoints[scalePointId]; + + if (scalePoint && scalePoint->label) + { + strncpy(strBuf, scalePoint->label, STR_MAX); + return; + } + } + } + + CarlaPlugin::getParameterScalePointLabel(parameterId, scalePointId, strBuf); + } + + // ------------------------------------------------------------------- + // Set data (plugin-specific stuff) + + void setParameterValue(const uint32_t parameterId, double value, const bool sendGui, const bool sendOsc, const bool sendCallback) + { + Q_ASSERT(descriptor); + Q_ASSERT(handle); + Q_ASSERT(parameterId < param.count); + + if (descriptor && handle) + descriptor->set_parameter_value(handle, parameterId, fixParameterValue(value, param.ranges[parameterId])); + + CarlaPlugin::setParameterValue(parameterId, value, sendGui, sendOsc, sendCallback); + } + + void setCustomData(const CustomDataType type, const char* const key, const char* const value, const bool sendGui) + { + Q_ASSERT(descriptor); + Q_ASSERT(handle); + Q_ASSERT(type == CUSTOM_DATA_STRING); + Q_ASSERT(key); + Q_ASSERT(value); + + if (type != CUSTOM_DATA_STRING) + return qCritical("NativePlugin::setCustomData(%s, \"%s\", \"%s\", %s) - type is not string", CustomDataType2str(type), key, value, bool2str(sendGui)); + + if (! key) + return qCritical("NativePlugin::setCustomData(%s, \"%s\", \"%s\", %s) - key is null", CustomDataType2str(type), key, value, bool2str(sendGui)); + + if (! value) + return qCritical("Nativelugin::setCustomData(%s, \"%s\", \"%s\", %s) - value is null", CustomDataType2str(type), key, value, bool2str(sendGui)); + + if (descriptor && handle) + descriptor->set_custom_data(handle, key, value); + + CarlaPlugin::setCustomData(type, key, value, sendGui); + } + + void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block) + { + Q_ASSERT(descriptor); + Q_ASSERT(handle); + Q_ASSERT(index >= -1 && index < (int32_t)midiprog.count); + + if (index < -1) + index = -1; + else if (index > (int32_t)midiprog.count) + return; + + if (descriptor && handle && index >= 0) + { + if (x_engine->isOffline()) + { + const CarlaEngine::ScopedLocker m(x_engine, block); + descriptor->set_midi_program(handle, midiprog.data[index].bank, midiprog.data[index].program); + } + else + { + const ScopedDisabler m(this, block); + descriptor->set_midi_program(handle, midiprog.data[index].bank, midiprog.data[index].program); + } + } + + CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback, block); + } + + // ------------------------------------------------------------------- + // Set gui stuff + + void showGui(const bool yesNo) + { + Q_ASSERT(descriptor); + + if (descriptor && handle) + descriptor->show_gui(handle, yesNo); + } + + void idleGui() + { + // FIXME - this should not be called if there's no GUI! + Q_ASSERT(descriptor); + + if (descriptor && descriptor->idle_gui && handle) + descriptor->idle_gui(handle); + } + + // ------------------------------------------------------------------- + // Plugin state + + void reload() + { + qDebug("NativePlugin::reload() - start"); + Q_ASSERT(descriptor); + + // Safely disable plugin for reload + const ScopedDisabler m(this); + + if (x_client->isActive()) + x_client->deactivate(); + + // Remove client ports + removeClientPorts(); + + // Delete old data + deleteBuffers(); + + uint32_t aIns, aOuts, mIns, mOuts, params, j; + aIns = aOuts = mIns = mOuts = params = 0; + + const double sampleRate = x_engine->getSampleRate(); + const uint32_t portCount = descriptor->portCount; + + for (uint32_t i=0; i < portCount; i++) + { + const PortType portType = descriptor->ports[i].type; + const uint32_t portHints = descriptor->ports[i].hints; + + if (portType == PORT_TYPE_AUDIO) + { + if (portHints & PORT_HINT_IS_OUTPUT) + aOuts += 1; + else + aIns += 1; + } + else if (portType == PORT_TYPE_MIDI) + { + if (portHints & PORT_HINT_IS_OUTPUT) + mOuts += 1; + else + mIns += 1; + } + else if (portType == PORT_TYPE_PARAMETER) + params += 1; + } + + if (aIns > 0) + { + aIn.ports = new CarlaEngineAudioPort*[aIns]; + aIn.rindexes = new uint32_t[aIns]; + } + + if (aOuts > 0) + { + aOut.ports = new CarlaEngineAudioPort*[aOuts]; + aOut.rindexes = new uint32_t[aOuts]; + } + + if (mIns > 0) + { + mIn.ports = new CarlaEngineMidiPort*[mIns]; + mIn.rindexes = new uint32_t[mIns]; + } + + if (mOuts > 0) + { + mOut.ports = new CarlaEngineMidiPort*[mOuts]; + mOut.rindexes = new uint32_t[mOuts]; + } + + if (params > 0) + { + param.data = new ParameterData[params]; + param.ranges = new ParameterRanges[params]; + } + + const int portNameSize = CarlaEngine::maxPortNameSize() - 2; + char portName[portNameSize]; + bool needsCtrlIn = false; + bool needsCtrlOut = false; + + for (uint32_t i=0; i < portCount; i++) + { + const PortType portType = descriptor->ports[i].type; + const uint32_t portHints = descriptor->ports[i].hints; + + if (portType == PORT_TYPE_AUDIO || portType == PORT_TYPE_MIDI) + { + if (carlaOptions.processMode != PROCESS_MODE_MULTIPLE_CLIENTS) + { + strcpy(portName, m_name); + strcat(portName, ":"); + strncat(portName, descriptor->ports[i].name, portNameSize/2); + } + else + strncpy(portName, descriptor->ports[i].name, portNameSize); + } + + if (portType == PORT_TYPE_AUDIO) + { + if (portHints & PORT_HINT_IS_OUTPUT) + { + j = aOut.count++; + aOut.ports[j] = (CarlaEngineAudioPort*)x_client->addPort(CarlaEnginePortTypeAudio, portName, false); + aOut.rindexes[j] = i; + needsCtrlIn = true; + } + else + { + j = aIn.count++; + aIn.ports[j] = (CarlaEngineAudioPort*)x_client->addPort(CarlaEnginePortTypeAudio, portName, true); + aIn.rindexes[j] = i; + } + } + else if (portType == PORT_TYPE_MIDI) + { + if (portHints & PORT_HINT_IS_OUTPUT) + { + j = aOut.count++; + mOut.ports[j] = (CarlaEngineMidiPort*)x_client->addPort(CarlaEnginePortTypeMIDI, portName, false); + mOut.rindexes[j] = i; + } + else + { + j = aIn.count++; + mIn.ports[j] = (CarlaEngineMidiPort*)x_client->addPort(CarlaEnginePortTypeMIDI, portName, true); + mIn.rindexes[j] = i; + } + } + else if (portType == PORT_TYPE_PARAMETER) + { + j = param.count++; + param.data[j].index = j; + param.data[j].rindex = i; + param.data[j].hints = 0; + param.data[j].midiChannel = 0; + param.data[j].midiCC = -1; + + double min, max, def, step, stepSmall, stepLarge; + + ::ParameterRanges ranges = { 0.0, 0.0, 1.0, 0.01, 0.0001, 0.1 }; + descriptor->get_parameter_ranges(handle, i, &ranges); + + // min value + min = ranges.min; + + // max value + min = ranges.max; + + if (min > max) + max = min; + else if (max < min) + min = max; + + if (max - min == 0.0) + { + qWarning("Broken plugin parameter: max - min == 0"); + max = min + 0.1; + } + + // default value + def = ranges.def; + + if (def < min) + def = min; + else if (def > max) + def = max; + + if (portHints & PORT_HINT_USES_SAMPLE_RATE) + { + min *= sampleRate; + max *= sampleRate; + def *= sampleRate; + param.data[j].hints |= PARAMETER_USES_SAMPLERATE; + } + + if (portHints & PORT_HINT_IS_BOOLEAN) + { + step = max - min; + stepSmall = step; + stepLarge = step; + param.data[j].hints |= PARAMETER_IS_BOOLEAN; + } + else if (portHints & PORT_HINT_IS_INTEGER) + { + step = 1.0; + stepSmall = 1.0; + stepLarge = 10.0; + param.data[j].hints |= PARAMETER_IS_INTEGER; + } + else + { + double range = max - min; + step = range/100.0; + stepSmall = range/1000.0; + stepLarge = range/10.0; + } + + if (portHints & PORT_HINT_IS_OUTPUT) + { + param.data[j].type = PARAMETER_OUTPUT; + needsCtrlOut = true; + } + else + { + param.data[j].type = PARAMETER_INPUT; + needsCtrlIn = true; + } + + // extra parameter hints + if (portHints & PORT_HINT_IS_ENABLED) + param.data[j].hints |= PARAMETER_IS_ENABLED; + + if (portHints & PORT_HINT_IS_AUTOMABLE) + param.data[j].hints |= PARAMETER_IS_AUTOMABLE; + + if (portHints & PORT_HINT_IS_LOGARITHMIC) + param.data[j].hints |= PARAMETER_IS_LOGARITHMIC; + + if (portHints & PORT_HINT_USES_SCALEPOINTS) + param.data[j].hints |= PARAMETER_USES_SCALEPOINTS; + + if (portHints & PORT_HINT_USES_CUSTOM_TEXT) + param.data[j].hints |= PARAMETER_USES_CUSTOM_TEXT; + + param.ranges[j].min = min; + param.ranges[j].max = max; + param.ranges[j].def = def; + param.ranges[j].step = step; + param.ranges[j].stepSmall = stepSmall; + param.ranges[j].stepLarge = stepLarge; + } + } + + if (needsCtrlIn) + { + if (carlaOptions.processMode != PROCESS_MODE_MULTIPLE_CLIENTS) + { + strcpy(portName, m_name); + strcat(portName, ":control-in"); + } + else + strcpy(portName, "control-in"); + + param.portCin = (CarlaEngineControlPort*)x_client->addPort(CarlaEnginePortTypeControl, portName, true); + } + + if (needsCtrlOut) + { + if (carlaOptions.processMode != PROCESS_MODE_MULTIPLE_CLIENTS) + { + strcpy(portName, m_name); + strcat(portName, ":control-out"); + } + else + strcpy(portName, "control-out"); + + param.portCout = (CarlaEngineControlPort*)x_client->addPort(CarlaEnginePortTypeControl, portName, false); + } + + aIn.count = aIns; + aOut.count = aOuts; + param.count = params; + + // plugin checks + m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE); + + if (aOuts > 0 && (aIns == aOuts || aIns == 1)) + m_hints |= PLUGIN_CAN_DRYWET; + + if (aOuts > 0) + m_hints |= PLUGIN_CAN_VOLUME; + + if (aOuts >= 2 && aOuts%2 == 0) + m_hints |= PLUGIN_CAN_BALANCE; + + m_hints |= getPluginHintsFromNative(descriptor->hints); + + reloadPrograms(true); + + x_client->activate(); + + qDebug("NativePlugin::reload() - end"); + } + + // ------------------------------------------------------------------- + // Cleanup + + void removeClientPorts() + { + qDebug("NativePlugin::removeClientPorts() - start"); + + for (uint32_t i=0; i < mIn.count; i++) + { + delete mIn.ports[i]; + mIn.ports[i] = nullptr; + } + + for (uint32_t i=0; i < mOut.count; i++) + { + delete mOut.ports[i]; + mOut.ports[i] = nullptr; + } + + CarlaPlugin::removeClientPorts(); + + qDebug("NativePlugin::removeClientPorts() - end"); + } + + void initBuffers() + { + uint32_t i; + + for (i=0; i < mIn.count; i++) + { + if (mIn.ports[i]) + mIn.ports[i]->initBuffer(x_engine); + } + + for (i=0; i < mOut.count; i++) + { + if (mOut.ports[i]) + mOut.ports[i]->initBuffer(x_engine); + } + + CarlaPlugin::initBuffers(); + } + + void deleteBuffers() + { + qDebug("NativePlugin::deleteBuffers() - start"); + + if (mIn.count > 0) + { + delete[] mIn.ports; + delete[] mIn.rindexes; + } + + if (mOut.count > 0) + { + delete[] mOut.ports; + delete[] mOut.rindexes; + } + + mIn.count = 0; + mIn.ports = nullptr; + mIn.rindexes = nullptr; + + mOut.count = 0; + mOut.ports = nullptr; + mOut.rindexes = nullptr; + + CarlaPlugin::deleteBuffers(); + + qDebug("NativePlugin::deleteBuffers() - end"); } // ------------------------------------------------------------------- @@ -184,7 +794,7 @@ public: bool init(const char* const name, const char* const label) { // --------------------------------------------------------------- - // get plugin + // get descriptor that matches label for (size_t i=0; i < pluginDescriptors.size(); i++) { @@ -206,6 +816,17 @@ public: scopedInitliazer.initializeIfNeeded(descriptor); + // --------------------------------------------------------------- + // initialize plugin + + handle = descriptor->instantiate((struct _PluginDescriptor*)descriptor, nullptr); // TODO - host + + if (! handle) + { + setLastError("Plugin failed to initialize"); + return false; + } + // --------------------------------------------------------------- // get info @@ -232,6 +853,9 @@ private: const PluginDescriptor* descriptor; PluginHandle handle; + NativePluginMidiData mIn; + NativePluginMidiData mOut; + static std::vector pluginDescriptors; }; diff --git a/c++/carla-backend/dssi.cpp b/c++/carla-backend/dssi.cpp index 607aecd..ba56114 100644 --- a/c++/carla-backend/dssi.cpp +++ b/c++/carla-backend/dssi.cpp @@ -1411,6 +1411,8 @@ public: paramBuffers = nullptr; + CarlaPlugin::deleteBuffers(); + qDebug("DssiPlugin::deleteBuffers() - end"); } diff --git a/c++/carla-backend/ladspa.cpp b/c++/carla-backend/ladspa.cpp index 182601d..cd6f016 100644 --- a/c++/carla-backend/ladspa.cpp +++ b/c++/carla-backend/ladspa.cpp @@ -1031,6 +1031,8 @@ public: paramBuffers = nullptr; + CarlaPlugin::deleteBuffers(); + qDebug("LadspaPlugin::deleteBuffers() - end"); } diff --git a/c++/carla-backend/lv2.cpp b/c++/carla-backend/lv2.cpp index 838fb46..a87a6d5 100644 --- a/c++/carla-backend/lv2.cpp +++ b/c++/carla-backend/lv2.cpp @@ -2925,6 +2925,8 @@ public: paramBuffers = nullptr; + CarlaPlugin::deleteBuffers(); + qDebug("Lv2Plugin::deleteBuffers() - end"); } diff --git a/c++/carla-backend/plugins/bypass.c b/c++/carla-backend/plugins/bypass.c index 7589db5..67e1791 100644 --- a/c++/carla-backend/plugins/bypass.c +++ b/c++/carla-backend/plugins/bypass.c @@ -18,6 +18,7 @@ #include "carla_native.h" #include +#include enum ByPassPorts { PORT_IN, @@ -25,9 +26,6 @@ enum ByPassPorts { PORT_MAX }; -struct ByPassInstance { -}; - void bypass_init(struct _PluginDescriptor* _this_) { _this_->portCount = PORT_MAX; @@ -37,7 +35,6 @@ void bypass_init(struct _PluginDescriptor* _this_) _this_->ports[PORT_IN].hints = 0; _this_->ports[PORT_IN].name = "in"; - _this_->ports[PORT_OUT].type = PORT_TYPE_AUDIO; _this_->ports[PORT_OUT].hints = PORT_HINT_IS_OUTPUT; _this_->ports[PORT_OUT].name = "out"; @@ -51,15 +48,69 @@ void bypass_fini(struct _PluginDescriptor* _this_) _this_->ports = NULL; } +PluginHandle bypass_instantiate(struct _PluginDescriptor* _this_, HostDescriptor* host) +{ + // dummy, return non-NULL + return (PluginHandle)1; + + // unused + (void)_this_; + (void)host; +} + +void bypass_process(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents) +{ + float* input1 = inBuffer[0]; + float* input2 = inBuffer[1]; + float* output1 = outBuffer[1]; + float* output2 = outBuffer[1]; + + memcpy(output1, input1, sizeof(float)*frames); + memcpy(output2, input2, sizeof(float)*frames); + + return; + + // unused + (void)handle; + (void)midiEventCount; + (void)midiEvents; +} + static PluginDescriptor bypassDesc = { - .category = PLUGIN_CATEGORY_NONE, - .name = "ByPass", - .label = "bypass", - .portCount = 0, - .ports = NULL, - ._handle = NULL, - ._init = NULL, - ._fini = NULL + .category = PLUGIN_CATEGORY_NONE, + .name = "ByPass", + .label = "bypass", + .maker = "falkTX", + .copyright = "GNU GPL v2+", + + .portCount = 0, + .ports = NULL, + + .midiProgramCount = 0, + .midiPrograms = NULL, + + .instantiate = bypass_instantiate, + .activate = NULL, + .deactivate = NULL, + .cleanup = NULL, + + .get_parameter_ranges = NULL, + .get_parameter_value = NULL, + .get_parameter_text = NULL, + .get_parameter_unit = NULL, + + .set_parameter_value = NULL, + .set_midi_program = NULL, + .set_custom_data = NULL, + + .show_gui = NULL, + .idle_gui = NULL, + + .process = bypass_process, + + ._singleton = NULL, + ._init = bypass_init, + ._fini = bypass_fini }; CARLA_REGISTER_NATIVE_PLUGIN(bypass, bypassDesc) diff --git a/c++/carla-backend/plugins/carla_native.h b/c++/carla-backend/plugins/carla_native.h index 8d04d8f..1258bd9 100644 --- a/c++/carla-backend/plugins/carla_native.h +++ b/c++/carla-backend/plugins/carla_native.h @@ -102,6 +102,13 @@ typedef struct _TimeInfo { TimeInfoBBT bbt; } TimeInfo; +typedef struct _HostDescriptor { + uint32_t (*get_buffer_size)(); + double (*get_sample_rate)(); + const TimeInfo* (*get_time_info)(); + bool (*write_midi_event)(uint32_t port_offset, MidiEvent* event); +} HostDescriptor; + typedef struct _PluginPortScalePoint { const char* label; double value; @@ -130,7 +137,7 @@ typedef struct _PluginDescriptor { uint32_t midiProgramCount; MidiProgram* midiPrograms; - PluginHandle (*instantiate)(struct _PluginDescriptor* _this_); + PluginHandle (*instantiate)(struct _PluginDescriptor* _this_, HostDescriptor* host); void (*activate)(PluginHandle handle); void (*deactivate)(PluginHandle handle); void (*cleanup)(PluginHandle handle); @@ -152,7 +159,7 @@ typedef struct _PluginDescriptor { void (*process)(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents); // TODO - midi stuff^ - PluginHandle _handle; + void* _singleton; void (*_init)(struct _PluginDescriptor* _this_); void (*_fini)(struct _PluginDescriptor* _this_); } PluginDescriptor; @@ -161,20 +168,6 @@ typedef struct _PluginDescriptor { void carla_register_native_plugin(const PluginDescriptor* desc); -// remove? -#define CARLA_NATIVE_PARAMETER_RANGES_INIT { 0.0, 0.0, 1.0, 0.01, 0.0001, 0.1 } - -#define CARLA_NATIVE_PLUGIN_INIT { \ - PLUGIN_CATEGORY_NONE, 0, NULL, NULL, NULL, NULL, \ - 0, NULL, 0, NULL, \ - NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, \ - NULL, NULL, NULL, \ - NULL, NULL, \ - NULL, \ - NULL, NULL, NULL \ - } - #define CARLA_REGISTER_NATIVE_PLUGIN(label, desc) \ void carla_register_native_plugin_##label () __attribute__((constructor)); \ void carla_register_native_plugin_##label () { carla_register_native_plugin(&desc); } diff --git a/c++/carla-backend/plugins/carla_nativemm.h b/c++/carla-backend/plugins/carla_nativemm.h index 806827d..db11d94 100644 --- a/c++/carla-backend/plugins/carla_nativemm.h +++ b/c++/carla-backend/plugins/carla_nativemm.h @@ -38,28 +38,9 @@ public: desc.midiProgramCount = 0; desc.midiPrograms = nullptr; - desc.instantiate = _instantiate; - desc.activate = _activate; - desc.deactivate = _deactivate; - desc.cleanup = _cleanup; - - desc.get_parameter_ranges = _get_parameter_ranges; - desc.get_parameter_value = _get_parameter_value; - desc.get_parameter_text = _get_parameter_text; - desc.get_parameter_unit = _get_parameter_unit; + host = nullptr; - desc.set_parameter_value = _set_parameter_value; - desc.set_midi_program = _set_midi_program; - desc.set_custom_data = _set_custom_data; - - desc.show_gui = _show_gui; - desc.idle_gui = _idle_gui; - - desc.process = _process; - - desc._handle = this; - desc._init = _init; - desc._fini = _fini; + _initDescriptor(); } PluginDescriptorClass(PluginDescriptorClass* that) @@ -77,28 +58,9 @@ public: desc.midiProgramCount = that->desc.midiProgramCount; desc.midiPrograms = that->desc.midiPrograms; - desc.instantiate = _instantiate; - desc.activate = _activate; - desc.deactivate = _deactivate; - desc.cleanup = _cleanup; - - desc.get_parameter_ranges = _get_parameter_ranges; - desc.get_parameter_value = _get_parameter_value; - desc.get_parameter_text = _get_parameter_text; - desc.get_parameter_unit = _get_parameter_unit; - - desc.set_parameter_value = _set_parameter_value; - desc.set_midi_program = _set_midi_program; - desc.set_custom_data = _set_custom_data; + host = that->host; - desc.show_gui = _show_gui; - desc.idle_gui = _idle_gui; - - desc.process = _process; - - desc._handle = this; - desc._init = _init; - desc._fini = _fini; + _initDescriptor(); } virtual ~PluginDescriptorClass() @@ -277,10 +239,40 @@ protected: private: PluginDescriptor desc; + const HostDescriptor* host; + + void _initDescriptor() + { + + desc.instantiate = _instantiate; + desc.activate = _activate; + desc.deactivate = _deactivate; + desc.cleanup = _cleanup; + + desc.get_parameter_ranges = _get_parameter_ranges; + desc.get_parameter_value = _get_parameter_value; + desc.get_parameter_text = _get_parameter_text; + desc.get_parameter_unit = _get_parameter_unit; + + desc.set_parameter_value = _set_parameter_value; + desc.set_midi_program = _set_midi_program; + desc.set_custom_data = _set_custom_data; + + desc.show_gui = _show_gui; + desc.idle_gui = _idle_gui; + + desc.process = _process; + + desc._singleton = this; + desc._init = _init; + desc._fini = _fini; + } - static PluginHandle _instantiate(struct _PluginDescriptor* _this_) + static PluginHandle _instantiate(struct _PluginDescriptor* _this_, HostDescriptor* host) { - return ((PluginDescriptorClass*)_this_->_handle)->createMe(); + PluginDescriptorClass* handle = ((PluginDescriptorClass*)_this_->_singleton)->createMe(); + handle->host = host; + return handle; } static void _activate(PluginHandle handle) @@ -350,12 +342,12 @@ private: static void _init(PluginDescriptor* const _this_) { - ((PluginDescriptorClass*)_this_->_handle)->handleInit(); + ((PluginDescriptorClass*)_this_->_singleton)->handleInit(); } static void _fini(PluginDescriptor* const _this_) { - ((PluginDescriptorClass*)_this_->_handle)->handleFini(); + ((PluginDescriptorClass*)_this_->_singleton)->handleFini(); } void handleInit() diff --git a/c++/carla-backend/plugins/midi-split.cpp b/c++/carla-backend/plugins/midi-split.cpp index eed91ae..6b56a11 100644 --- a/c++/carla-backend/plugins/midi-split.cpp +++ b/c++/carla-backend/plugins/midi-split.cpp @@ -148,11 +148,26 @@ protected: // ------------------------------------------------------------------- - void process(float** inBuffer, float** outBuffer, const uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents) + void process(float**, float**, uint32_t, uint32_t midiEventCount, MidiEvent* midiEvents) { - Q_UNUSED(inBuffer); - Q_UNUSED(outBuffer); - Q_UNUSED(frames); + MidiEvent midiEvent; + + for (uint32_t i=0; i < midiEventCount; i++) + { + memcpy(&midiEvent, &midiEvents[i], sizeof(MidiEvent)); + + uint8_t status = midiEvent.data[0]; + uint8_t channel = status & 0x0F; + + Q_ASSERT(channel < 16); + + if (channel >= 16) + continue; + + status -= channel; + midiEvent.data[0] = status; + //writeMidiEvent(channel, midiEvent); + } } // ------------------------------------------------------------------- diff --git a/c++/carla-backend/vst.cpp b/c++/carla-backend/vst.cpp index 2bba2f0..dba921b 100644 --- a/c++/carla-backend/vst.cpp +++ b/c++/carla-backend/vst.cpp @@ -425,11 +425,18 @@ public: void idleGui() { - if (gui.type != GUI_EXTERNAL_OSC) - effect->dispatcher(effect, effEditIdle, 0, 0, nullptr, 0.0f); +#ifdef VESTIGE_HEADER + if (effect && effect->ptr1) +#else + if (effect && effect->resvd1) +#endif + { + if (gui.type != GUI_EXTERNAL_OSC) + effect->dispatcher(effect, effEditIdle, 0, 0, nullptr, 0.0f); - if (needIdle) - effect->dispatcher(effect, effIdle, 0, 0, nullptr, 0.0f); + if (needIdle) + effect->dispatcher(effect, effIdle, 0, 0, nullptr, 0.0f); + } CarlaPlugin::idleGui(); }