| @@ -0,0 +1,267 @@ | |||
| /* | |||
| * Carla Backend | |||
| * Copyright (C) 2012 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or modify | |||
| * it under the terms of the GNU General Public License as published by | |||
| * the Free Software Foundation; either version 2 of the License, or | |||
| * any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| */ | |||
| #include "carla_plugin.h" | |||
| #include "plugins/carla_native.h" | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| class NativePluginScopedInitiliazer | |||
| { | |||
| public: | |||
| NativePluginScopedInitiliazer() | |||
| { | |||
| } | |||
| ~NativePluginScopedInitiliazer() | |||
| { | |||
| for (size_t i=0; i < descriptors.size(); i++) | |||
| { | |||
| const PluginDescriptor* const desc = descriptors[i]; | |||
| if (desc->_fini) | |||
| desc->_fini((struct _PluginDescriptor*)desc); | |||
| } | |||
| descriptors.clear(); | |||
| } | |||
| void initializeIfNeeded(const PluginDescriptor* const desc) | |||
| { | |||
| if (descriptors.empty() || std::find(descriptors.begin(), descriptors.end(), desc) == descriptors.end()) | |||
| { | |||
| if (desc->_init) | |||
| desc->_init((struct _PluginDescriptor*)desc); | |||
| descriptors.push_back(desc); | |||
| } | |||
| } | |||
| private: | |||
| std::vector<const PluginDescriptor*> descriptors; | |||
| }; | |||
| static NativePluginScopedInitiliazer scopedInitliazer; | |||
| class NativePlugin : public CarlaPlugin | |||
| { | |||
| public: | |||
| NativePlugin(CarlaEngine* const engine, const unsigned short id) | |||
| : CarlaPlugin(engine, id) | |||
| { | |||
| qDebug("NativePlugin::NativePlugin()"); | |||
| m_type = PLUGIN_NONE; | |||
| descriptor = nullptr; | |||
| handle = nullptr; | |||
| } | |||
| ~NativePlugin() | |||
| { | |||
| qDebug("NativePlugin::~NativePlugin()"); | |||
| if (handle) | |||
| pass(); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // Information (base) | |||
| PluginCategory category() | |||
| { | |||
| Q_ASSERT(descriptor); | |||
| if (descriptor) | |||
| return (PluginCategory)descriptor->category; | |||
| return getPluginCategoryFromName(m_name); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // Information (per-plugin data) | |||
| double getParameterValue(const uint32_t parameterId) | |||
| { | |||
| Q_ASSERT(descriptor); | |||
| Q_ASSERT(parameterId < param.count); | |||
| //return descriptor->get_parameter_value(); | |||
| return 0.0; | |||
| } | |||
| void getLabel(char* const strBuf) | |||
| { | |||
| Q_ASSERT(descriptor); | |||
| if (descriptor && descriptor->label) | |||
| strncpy(strBuf, descriptor->label, STR_MAX); | |||
| else | |||
| CarlaPlugin::getLabel(strBuf); | |||
| } | |||
| void getMaker(char* const strBuf) | |||
| { | |||
| Q_ASSERT(descriptor); | |||
| //if (descriptor && descriptor->maker) | |||
| // strncpy(strBuf, descriptor->maker, STR_MAX); | |||
| //else | |||
| CarlaPlugin::getMaker(strBuf); | |||
| } | |||
| void getCopyright(char* const strBuf) | |||
| { | |||
| Q_ASSERT(descriptor); | |||
| //if (descriptor && descriptor->copyright) | |||
| // strncpy(strBuf, descriptor->copyright, STR_MAX); | |||
| //else | |||
| CarlaPlugin::getCopyright(strBuf); | |||
| } | |||
| void getRealName(char* const strBuf) | |||
| { | |||
| Q_ASSERT(descriptor); | |||
| if (descriptor && descriptor->name) | |||
| strncpy(strBuf, descriptor->name, STR_MAX); | |||
| else | |||
| CarlaPlugin::getRealName(strBuf); | |||
| } | |||
| void getParameterName(const uint32_t parameterId, char* const strBuf) | |||
| { | |||
| Q_ASSERT(descriptor); | |||
| Q_ASSERT(parameterId < param.count); | |||
| 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); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| static size_t getPluginCount() | |||
| { | |||
| return pluginDescriptors.size(); | |||
| } | |||
| static void registerPlugin(const PluginDescriptor* desc) | |||
| { | |||
| pluginDescriptors.push_back(desc); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| bool init(const char* const name, const char* const label) | |||
| { | |||
| // --------------------------------------------------------------- | |||
| // get plugin | |||
| for (size_t i=0; i < pluginDescriptors.size(); i++) | |||
| { | |||
| descriptor = pluginDescriptors[i]; | |||
| if (! descriptor) | |||
| break; | |||
| if (strcmp(descriptor->label, label) == 0) | |||
| break; | |||
| descriptor = nullptr; | |||
| } | |||
| if (! descriptor) | |||
| { | |||
| setLastError("Invalid internal plugin"); | |||
| return false; | |||
| } | |||
| scopedInitliazer.initializeIfNeeded(descriptor); | |||
| // --------------------------------------------------------------- | |||
| // get info | |||
| if (name) | |||
| m_name = x_engine->getUniqueName(name); | |||
| else | |||
| m_name = x_engine->getUniqueName(descriptor->name); | |||
| // --------------------------------------------------------------- | |||
| // register client | |||
| x_client = x_engine->addClient(this); | |||
| if (! x_client->isOk()) | |||
| { | |||
| setLastError("Failed to register plugin client"); | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| private: | |||
| const PluginDescriptor* descriptor; | |||
| PluginHandle handle; | |||
| static std::vector<const PluginDescriptor*> pluginDescriptors; | |||
| }; | |||
| std::vector<const PluginDescriptor*> NativePlugin::pluginDescriptors; | |||
| CarlaPlugin* CarlaPlugin::newNative(const initializer& init) | |||
| { | |||
| qDebug("CarlaPlugin::newNative(%p, \"%s\", \"%s\", \"%s\")", init.engine, init.filename, init.name, init.label); | |||
| short id = init.engine->getNewPluginId(); | |||
| if (id < 0 || id > CarlaEngine::maxPluginNumber()) | |||
| { | |||
| setLastError("Maximum number of plugins reached"); | |||
| return nullptr; | |||
| } | |||
| NativePlugin* const plugin = new NativePlugin(init.engine, id); | |||
| if (! plugin->init(init.name, init.label)) | |||
| { | |||
| delete plugin; | |||
| return nullptr; | |||
| } | |||
| plugin->reload(); | |||
| plugin->registerToOsc(); | |||
| return plugin; | |||
| } | |||
| size_t CarlaPlugin::getNativePluginCount() | |||
| { | |||
| return NativePlugin::getPluginCount(); | |||
| } | |||
| CARLA_BACKEND_END_NAMESPACE | |||
| void carla_register_native_plugin(const PluginDescriptor* desc) | |||
| { | |||
| printf("contructing plugin, THERE \"%s\"\n", desc->name); | |||
| CarlaBackend::NativePlugin::registerPlugin(desc); | |||
| } | |||
| @@ -0,0 +1,65 @@ | |||
| /* | |||
| * Carla Native Plugins | |||
| * Copyright (C) 2012 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or modify | |||
| * it under the terms of the GNU General Public License as published by | |||
| * the Free Software Foundation; either version 2 of the License, or | |||
| * any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| */ | |||
| #include "carla_native.h" | |||
| #include <stdlib.h> | |||
| enum ByPassPorts { | |||
| PORT_IN, | |||
| PORT_OUT, | |||
| PORT_MAX | |||
| }; | |||
| struct ByPassInstance { | |||
| }; | |||
| void bypass_init(struct _PluginDescriptor* _this_) | |||
| { | |||
| _this_->portCount = PORT_MAX; | |||
| _this_->ports = malloc(sizeof(PluginPort) * PORT_MAX); | |||
| _this_->ports[PORT_IN].type = PORT_TYPE_AUDIO; | |||
| _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"; | |||
| } | |||
| void bypass_fini(struct _PluginDescriptor* _this_) | |||
| { | |||
| free(_this_->ports); | |||
| _this_->portCount = 0; | |||
| _this_->ports = NULL; | |||
| } | |||
| static PluginDescriptor bypassDesc = { | |||
| .category = PLUGIN_CATEGORY_NONE, | |||
| .name = "ByPass", | |||
| .label = "bypass", | |||
| .portCount = 0, | |||
| .ports = NULL, | |||
| ._handle = NULL, | |||
| ._init = NULL, | |||
| ._fini = NULL | |||
| }; | |||
| CARLA_REGISTER_NATIVE_PLUGIN(bypass, bypassDesc) | |||
| @@ -0,0 +1,185 @@ | |||
| /* | |||
| * Carla Native Plugin API | |||
| * Copyright (C) 2012 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or modify | |||
| * it under the terms of the GNU General Public License as published by | |||
| * the Free Software Foundation; either version 2 of the License, or | |||
| * any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| */ | |||
| #ifndef CARLA_NATIVE_H | |||
| #define CARLA_NATIVE_H | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #else | |||
| #include <stdbool.h> | |||
| #endif | |||
| #include <stddef.h> | |||
| #include <stdint.h> | |||
| typedef void* PluginHandle; | |||
| const uint32_t PLUGIN_IS_SYNTH = 1 << 0; | |||
| const uint32_t PLUGIN_HAS_GUI = 1 << 1; | |||
| const uint32_t PLUGIN_USES_SINGLE_THREAD = 1 << 2; | |||
| const uint32_t PORT_HINT_IS_OUTPUT = 1 << 0; | |||
| const uint32_t PORT_HINT_IS_ENABLED = 1 << 1; | |||
| const uint32_t PORT_HINT_IS_AUTOMABLE = 1 << 2; | |||
| const uint32_t PORT_HINT_IS_BOOLEAN = 1 << 3; | |||
| const uint32_t PORT_HINT_IS_INTEGER = 1 << 4; | |||
| const uint32_t PORT_HINT_IS_LOGARITHMIC = 1 << 5; | |||
| const uint32_t PORT_HINT_USES_SAMPLE_RATE = 1 << 6; | |||
| const uint32_t PORT_HINT_USES_SCALEPOINTS = 1 << 7; | |||
| const uint32_t PORT_HINT_USES_CUSTOM_TEXT = 1 << 8; | |||
| typedef enum _PluginCategory { | |||
| PLUGIN_CATEGORY_NONE = 0, //!< Null plugin category. | |||
| PLUGIN_CATEGORY_SYNTH = 1, //!< A synthesizer or generator. | |||
| PLUGIN_CATEGORY_DELAY = 2, //!< A delay or reverberator. | |||
| PLUGIN_CATEGORY_EQ = 3, //!< An equalizer. | |||
| PLUGIN_CATEGORY_FILTER = 4, //!< A filter. | |||
| PLUGIN_CATEGORY_DYNAMICS = 5, //!< A 'dynamic' plugin (amplifier, compressor, gate, etc). | |||
| PLUGIN_CATEGORY_MODULATOR = 6, //!< A 'modulator' plugin (chorus, flanger, phaser, etc). | |||
| PLUGIN_CATEGORY_UTILITY = 7, //!< An 'utility' plugin (analyzer, converter, mixer, etc). | |||
| PLUGIN_CATEGORY_OTHER = 8 //!< Misc plugin (used to check if the plugin has a category). | |||
| } PluginCategory; | |||
| typedef enum _PortType { | |||
| PORT_TYPE_NULL = 0, | |||
| PORT_TYPE_AUDIO = 1, | |||
| PORT_TYPE_MIDI = 2, | |||
| PORT_TYPE_PARAMETER = 3 | |||
| } PortType; | |||
| typedef struct _ParameterRanges { | |||
| double def; | |||
| double min; | |||
| double max; | |||
| double step; | |||
| double stepSmall; | |||
| double stepLarge; | |||
| } ParameterRanges; | |||
| typedef struct _MidiEvent { | |||
| uint32_t time; | |||
| uint8_t size; | |||
| uint8_t data[4]; | |||
| } MidiEvent; | |||
| typedef struct _MidiProgram { | |||
| uint32_t bank; | |||
| uint32_t program; | |||
| const char* name; | |||
| } MidiProgram; | |||
| typedef struct _TimeInfoBBT { | |||
| int32_t bar; | |||
| int32_t beat; | |||
| int32_t tick; | |||
| double bar_start_tick; | |||
| float beats_per_bar; | |||
| float beat_type; | |||
| double ticks_per_beat; | |||
| double beats_per_minute; | |||
| } TimeInfoBBT; | |||
| typedef struct _TimeInfo { | |||
| bool playing; | |||
| uint32_t frame; | |||
| uint32_t time; | |||
| uint32_t valid; | |||
| TimeInfoBBT bbt; | |||
| } TimeInfo; | |||
| typedef struct _PluginPortScalePoint { | |||
| const char* label; | |||
| double value; | |||
| } PluginPortScalePoint; | |||
| typedef struct _PluginPort { | |||
| PortType type; | |||
| uint32_t hints; | |||
| const char* name; | |||
| uint32_t scalePointCount; | |||
| PluginPortScalePoint* scalePoints; | |||
| } PluginPort; | |||
| typedef struct _PluginDescriptor { | |||
| PluginCategory category; | |||
| uint32_t hints; | |||
| const char* name; | |||
| const char* label; | |||
| const char* maker; | |||
| const char* copyright; | |||
| uint32_t portCount; | |||
| PluginPort* ports; | |||
| uint32_t midiProgramCount; | |||
| MidiProgram* midiPrograms; | |||
| PluginHandle (*instantiate)(struct _PluginDescriptor* _this_); | |||
| void (*activate)(PluginHandle handle); | |||
| void (*deactivate)(PluginHandle handle); | |||
| void (*cleanup)(PluginHandle handle); | |||
| void (*get_parameter_ranges)(PluginHandle handle, uint32_t index, ParameterRanges* ranges); | |||
| double (*get_parameter_value)(PluginHandle handle, uint32_t index); | |||
| const char* (*get_parameter_text)(PluginHandle handle, uint32_t index); | |||
| const char* (*get_parameter_unit)(PluginHandle handle, uint32_t index); | |||
| void (*set_parameter_value)(PluginHandle handle, uint32_t index, double value); | |||
| void (*set_midi_program)(PluginHandle handle, uint32_t bank, uint32_t program); | |||
| void (*set_custom_data)(PluginHandle handle, const char* key, const char* value); | |||
| void (*show_gui)(PluginHandle handle, bool show); | |||
| void (*idle_gui)(PluginHandle handle); | |||
| // TODO - ui_set_* | |||
| void (*process)(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents); | |||
| // TODO - midi stuff^ | |||
| PluginHandle _handle; | |||
| void (*_init)(struct _PluginDescriptor* _this_); | |||
| void (*_fini)(struct _PluginDescriptor* _this_); | |||
| } PluginDescriptor; | |||
| // ----------------------------------------------------------------------- | |||
| void carla_register_native_plugin(const PluginDescriptor* desc); | |||
| #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); } | |||
| #ifdef __cplusplus | |||
| } /* extern "C" */ | |||
| #endif | |||
| #endif // CARLA_NATIVE_H | |||
| @@ -0,0 +1,412 @@ | |||
| /* | |||
| * Carla Native Plugin API | |||
| * Copyright (C) 2012 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or modify | |||
| * it under the terms of the GNU General Public License as published by | |||
| * the Free Software Foundation; either version 2 of the License, or | |||
| * any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| */ | |||
| #ifndef CARLA_NATIVE_MM_H | |||
| #define CARLA_NATIVE_MM_H | |||
| #include "carla_native.h" | |||
| #include "carla_includes.h" | |||
| class PluginDescriptorClass { | |||
| public: | |||
| PluginDescriptorClass() | |||
| { | |||
| desc.category = PLUGIN_CATEGORY_NONE; | |||
| desc.hints = 0; | |||
| desc.name = nullptr; | |||
| desc.label = nullptr; | |||
| desc.maker = nullptr; | |||
| desc.copyright = nullptr; | |||
| desc.portCount = 0; | |||
| desc.ports = nullptr; | |||
| 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; | |||
| 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; | |||
| } | |||
| PluginDescriptorClass(PluginDescriptorClass* that) | |||
| { | |||
| desc.category = that->desc.category; | |||
| desc.hints = that->desc.hints; | |||
| desc.name = that->desc.name; | |||
| desc.label = that->desc.label; | |||
| desc.maker = that->desc.maker; | |||
| desc.copyright = that->desc.copyright; | |||
| desc.portCount = that->desc.portCount; | |||
| desc.ports = that->desc.ports; | |||
| 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; | |||
| desc.show_gui = _show_gui; | |||
| desc.idle_gui = _idle_gui; | |||
| desc.process = _process; | |||
| desc._handle = this; | |||
| desc._init = _init; | |||
| desc._fini = _fini; | |||
| } | |||
| virtual ~PluginDescriptorClass() | |||
| { | |||
| } | |||
| PluginDescriptor* descriptorInit() | |||
| { | |||
| desc.category = getCategory(); | |||
| desc.hints = getHints(); | |||
| desc.name = getName(); | |||
| desc.label = getLabel(); | |||
| desc.maker = getMaker(); | |||
| desc.copyright = getCopyright(); | |||
| return &desc; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| protected: | |||
| virtual PluginDescriptorClass* createMe() = 0; | |||
| virtual void deleteMe() = 0; | |||
| virtual PluginCategory getCategory() | |||
| { | |||
| return PLUGIN_CATEGORY_NONE; | |||
| } | |||
| virtual uint32_t getHints() | |||
| { | |||
| return 0; | |||
| } | |||
| virtual const char* getName() | |||
| { | |||
| return nullptr; | |||
| } | |||
| virtual const char* getLabel() | |||
| { | |||
| return nullptr; | |||
| } | |||
| virtual const char* getMaker() | |||
| { | |||
| return nullptr; | |||
| } | |||
| virtual const char* getCopyright() | |||
| { | |||
| return nullptr; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| virtual uint32_t getPortCount() | |||
| { | |||
| return 0; | |||
| } | |||
| virtual PortType getPortType(uint32_t index) | |||
| { | |||
| Q_ASSERT(index < getPortCount()); | |||
| return PORT_TYPE_NULL; | |||
| } | |||
| virtual uint32_t getPortHints(uint32_t index) | |||
| { | |||
| Q_ASSERT(index < getPortCount()); | |||
| return 0; | |||
| } | |||
| virtual const char* getPortName(uint32_t index) | |||
| { | |||
| Q_ASSERT(index < getPortCount()); | |||
| return nullptr; | |||
| } | |||
| virtual void getParameterRanges(uint32_t index, ParameterRanges* ranges) | |||
| { | |||
| Q_ASSERT(index < getPortCount()); | |||
| Q_ASSERT(ranges); | |||
| } | |||
| virtual double getParameterValue(uint32_t index) | |||
| { | |||
| Q_ASSERT(index < getPortCount()); | |||
| return 0.0; | |||
| } | |||
| virtual const char* getParameterText(uint32_t index) | |||
| { | |||
| Q_ASSERT(index < getPortCount()); | |||
| return nullptr; | |||
| } | |||
| virtual const char* getParameterUnit(uint32_t index) | |||
| { | |||
| Q_ASSERT(index < getPortCount()); | |||
| return nullptr; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| virtual uint32_t getMidiProgramCount() | |||
| { | |||
| return 0; | |||
| } | |||
| virtual void getMidiProgram(uint32_t index, MidiProgram* midiProgram) | |||
| { | |||
| Q_ASSERT(index < getMidiProgramCount()); | |||
| Q_ASSERT(midiProgram); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| virtual void setParameterValue(uint32_t index, double value) | |||
| { | |||
| Q_ASSERT(index < getPortCount()); | |||
| Q_UNUSED(value); | |||
| } | |||
| virtual void setMidiProgram(uint32_t bank, uint32_t program) | |||
| { | |||
| Q_ASSERT(program < 128); | |||
| Q_UNUSED(bank); | |||
| } | |||
| virtual void setCustomData(const char* key, const char* value) | |||
| { | |||
| Q_ASSERT(key); | |||
| Q_ASSERT(value); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| virtual void activate() | |||
| { | |||
| } | |||
| virtual void deactivate() | |||
| { | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| virtual void showGui(bool show) | |||
| { | |||
| Q_UNUSED(show); | |||
| } | |||
| virtual void idleGui() | |||
| { | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| virtual void process(float** inBuffer, float** outBuffer, const uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents) | |||
| { | |||
| Q_ASSERT(inBuffer); | |||
| Q_ASSERT(outBuffer); | |||
| Q_ASSERT(midiEvents); | |||
| Q_UNUSED(frames); | |||
| Q_UNUSED(midiEventCount); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| private: | |||
| PluginDescriptor desc; | |||
| static PluginHandle _instantiate(struct _PluginDescriptor* _this_) | |||
| { | |||
| return ((PluginDescriptorClass*)_this_->_handle)->createMe(); | |||
| } | |||
| static void _activate(PluginHandle handle) | |||
| { | |||
| ((PluginDescriptorClass*)handle)->activate(); | |||
| } | |||
| static void _deactivate(PluginHandle handle) | |||
| { | |||
| ((PluginDescriptorClass*)handle)->deactivate(); | |||
| } | |||
| static void _cleanup(PluginHandle handle) | |||
| { | |||
| ((PluginDescriptorClass*)handle)->deleteMe(); | |||
| } | |||
| static void _get_parameter_ranges(PluginHandle handle, uint32_t index, ParameterRanges* ranges) | |||
| { | |||
| ((PluginDescriptorClass*)handle)->getParameterRanges(index, ranges); | |||
| } | |||
| static double _get_parameter_value(PluginHandle handle, uint32_t index) | |||
| { | |||
| return ((PluginDescriptorClass*)handle)->getParameterValue(index); | |||
| } | |||
| static const char* _get_parameter_text(PluginHandle handle, uint32_t index) | |||
| { | |||
| return ((PluginDescriptorClass*)handle)->getParameterText(index); | |||
| } | |||
| static const char* _get_parameter_unit(PluginHandle handle, uint32_t index) | |||
| { | |||
| return ((PluginDescriptorClass*)handle)->getParameterUnit(index); | |||
| } | |||
| static void _set_parameter_value(PluginHandle handle, uint32_t index, double value) | |||
| { | |||
| return ((PluginDescriptorClass*)handle)->setParameterValue(index, value); | |||
| } | |||
| static void _set_midi_program(PluginHandle handle, uint32_t bank, uint32_t program) | |||
| { | |||
| return ((PluginDescriptorClass*)handle)->setMidiProgram(bank, program); | |||
| } | |||
| static void _set_custom_data(PluginHandle handle, const char* key, const char* value) | |||
| { | |||
| return ((PluginDescriptorClass*)handle)->setCustomData(key, value); | |||
| } | |||
| static void _show_gui(PluginHandle handle, bool show) | |||
| { | |||
| return ((PluginDescriptorClass*)handle)->showGui(show); | |||
| } | |||
| static void _idle_gui(PluginHandle handle) | |||
| { | |||
| return ((PluginDescriptorClass*)handle)->idleGui(); | |||
| } | |||
| static void _process(PluginHandle handle, float** inBuffer, float** outBuffer, const uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents) | |||
| { | |||
| return ((PluginDescriptorClass*)handle)->process(inBuffer, outBuffer, frames, midiEventCount, midiEvents); | |||
| } | |||
| static void _init(PluginDescriptor* const _this_) | |||
| { | |||
| ((PluginDescriptorClass*)_this_->_handle)->handleInit(); | |||
| } | |||
| static void _fini(PluginDescriptor* const _this_) | |||
| { | |||
| ((PluginDescriptorClass*)_this_->_handle)->handleFini(); | |||
| } | |||
| void handleInit() | |||
| { | |||
| desc.portCount = getPortCount(); | |||
| if (desc.portCount > 0) | |||
| { | |||
| desc.ports = new PluginPort [desc.portCount]; | |||
| for (uint32_t i=0; i < desc.portCount; i++) | |||
| { | |||
| PluginPort* const port = &desc.ports[i]; | |||
| port->type = getPortType(i); | |||
| port->hints = getPortHints(i); | |||
| port->name = getPortName(i); | |||
| } | |||
| } | |||
| desc.midiProgramCount = getMidiProgramCount(); | |||
| if (desc.midiProgramCount > 0) | |||
| { | |||
| desc.midiPrograms = new MidiProgram [desc.midiProgramCount]; | |||
| for (uint32_t i=0; i < desc.midiProgramCount; i++) | |||
| getMidiProgram(i, &desc.midiPrograms[i]); | |||
| } | |||
| } | |||
| void handleFini() | |||
| { | |||
| if (desc.midiProgramCount > 0 && desc.midiPrograms) | |||
| delete[] desc.midiPrograms; | |||
| desc.midiProgramCount = 0; | |||
| desc.midiPrograms = nullptr; | |||
| if (desc.portCount > 0 && desc.ports) | |||
| delete[] desc.ports; | |||
| desc.portCount = 0; | |||
| desc.ports = nullptr; | |||
| } | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| #define CARLA_REGISTER_NATIVE_PLUGIN_MM(label, descMM) \ | |||
| void carla_register_native_plugin_##label () __attribute__((constructor)); \ | |||
| void carla_register_native_plugin_##label () { carla_register_native_plugin(descMM.descriptorInit()); } | |||
| #endif // CARLA_NATIVE_MM_H | |||
| @@ -0,0 +1,189 @@ | |||
| /* | |||
| * Carla Native Plugins | |||
| * Copyright (C) 2012 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or modify | |||
| * it under the terms of the GNU General Public License as published by | |||
| * the Free Software Foundation; either version 2 of the License, or | |||
| * any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| */ | |||
| #include "carla_nativemm.h" | |||
| #include <cstring> | |||
| class MidiSplitPlugin : public PluginDescriptorClass | |||
| { | |||
| public: | |||
| MidiSplitPlugin() : PluginDescriptorClass() | |||
| { | |||
| } | |||
| MidiSplitPlugin(PluginDescriptorClass* that) : PluginDescriptorClass(that) | |||
| { | |||
| } | |||
| ~MidiSplitPlugin() | |||
| { | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| protected: | |||
| PluginDescriptorClass* createMe() | |||
| { | |||
| return new MidiSplitPlugin(this); | |||
| } | |||
| void deleteMe() | |||
| { | |||
| delete this; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| PluginCategory getCategory() | |||
| { | |||
| return PLUGIN_CATEGORY_UTILITY; | |||
| } | |||
| uint32_t getHints() | |||
| { | |||
| return 0; | |||
| } | |||
| const char* getName() | |||
| { | |||
| return "MIDI Split"; | |||
| } | |||
| const char* getLabel() | |||
| { | |||
| return "midiSplit"; | |||
| } | |||
| const char* getMaker() | |||
| { | |||
| return "falkTX"; | |||
| } | |||
| const char* getCopyright() | |||
| { | |||
| return "GNU GPL v2+"; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| uint32_t getPortCount() | |||
| { | |||
| return PORT_MAX; | |||
| } | |||
| PortType getPortType(uint32_t) | |||
| { | |||
| return PORT_TYPE_MIDI; | |||
| } | |||
| uint32_t getPortHints(uint32_t index) | |||
| { | |||
| return (index == 0) ? 0 : PORT_HINT_IS_OUTPUT; | |||
| } | |||
| const char* getPortName(const uint32_t index) | |||
| { | |||
| switch (index) | |||
| { | |||
| case PORT_INPUT: | |||
| return "input"; | |||
| case PORT_OUTPUT_1: | |||
| return "output-01"; | |||
| case PORT_OUTPUT_2: | |||
| return "output-02"; | |||
| case PORT_OUTPUT_3: | |||
| return "output-03"; | |||
| case PORT_OUTPUT_4: | |||
| return "output-04"; | |||
| case PORT_OUTPUT_5: | |||
| return "output-05"; | |||
| case PORT_OUTPUT_6: | |||
| return "output-06"; | |||
| case PORT_OUTPUT_7: | |||
| return "output-07"; | |||
| case PORT_OUTPUT_8: | |||
| return "output-08"; | |||
| case PORT_OUTPUT_9: | |||
| return "output-09"; | |||
| case PORT_OUTPUT_10: | |||
| return "output-10"; | |||
| case PORT_OUTPUT_11: | |||
| return "output-11"; | |||
| case PORT_OUTPUT_12: | |||
| return "output-12"; | |||
| case PORT_OUTPUT_13: | |||
| return "output-13"; | |||
| case PORT_OUTPUT_14: | |||
| return "output-14"; | |||
| case PORT_OUTPUT_15: | |||
| return "output-15"; | |||
| case PORT_OUTPUT_16: | |||
| return "output-16"; | |||
| default: | |||
| return ""; | |||
| } | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| void activate() | |||
| { | |||
| memset(events, 0, sizeof(MidiEvent) * MAX_MIDI_EVENTS); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| void process(float** inBuffer, float** outBuffer, const uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents) | |||
| { | |||
| Q_UNUSED(inBuffer); | |||
| Q_UNUSED(outBuffer); | |||
| Q_UNUSED(frames); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| private: | |||
| enum Ports { | |||
| PORT_INPUT = 0, | |||
| PORT_OUTPUT_1, | |||
| PORT_OUTPUT_2, | |||
| PORT_OUTPUT_3, | |||
| PORT_OUTPUT_4, | |||
| PORT_OUTPUT_5, | |||
| PORT_OUTPUT_6, | |||
| PORT_OUTPUT_7, | |||
| PORT_OUTPUT_8, | |||
| PORT_OUTPUT_9, | |||
| PORT_OUTPUT_10, | |||
| PORT_OUTPUT_11, | |||
| PORT_OUTPUT_12, | |||
| PORT_OUTPUT_13, | |||
| PORT_OUTPUT_14, | |||
| PORT_OUTPUT_15, | |||
| PORT_OUTPUT_16, | |||
| PORT_MAX | |||
| }; | |||
| static const unsigned short MAX_MIDI_EVENTS = 512; | |||
| MidiEvent events[MAX_MIDI_EVENTS]; | |||
| }; | |||
| static MidiSplitPlugin midiSplitPlugin; | |||
| CARLA_REGISTER_NATIVE_PLUGIN_MM(midiSplit, midiSplitPlugin) | |||