| @@ -0,0 +1,581 @@ | |||||
| /* | |||||
| * Carla Backend | |||||
| * Copyright (C) 2011-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_BACKEND_HPP | |||||
| #define CARLA_BACKEND_HPP | |||||
| #include "carla_defines.hpp" | |||||
| #include <cstdint> | |||||
| #define CARLA_BACKEND_START_NAMESPACE namespace CarlaBackend { | |||||
| #define CARLA_BACKEND_END_NAMESPACE } | |||||
| #define CARLA_BACKEND_USE_NAMESPACE using namespace CarlaBackend; | |||||
| CARLA_BACKEND_START_NAMESPACE | |||||
| #define STR_MAX 0xFF | |||||
| /*! | |||||
| * @defgroup CarlaBackendAPI Carla Backend API | |||||
| * | |||||
| * The Carla Backend API | |||||
| * | |||||
| * @{ | |||||
| */ | |||||
| #ifdef BUILD_BRIDGE | |||||
| const unsigned short MAX_PLUGINS = 1; | |||||
| #else | |||||
| const unsigned short MAX_PLUGINS = 99; //!< Maximum number of loadable plugins | |||||
| #endif | |||||
| const unsigned int MAX_PARAMETERS = 200; //!< Default value for the maximum number of parameters allowed.\see OPTION_MAX_PARAMETERS | |||||
| /*! | |||||
| * @defgroup PluginHints Plugin Hints | |||||
| * | |||||
| * Various plugin hints. | |||||
| * \see CarlaPlugin::hints() | |||||
| * @{ | |||||
| */ | |||||
| #ifndef BUILD_BRIDGE | |||||
| const unsigned int PLUGIN_IS_BRIDGE = 0x001; //!< Plugin is a bridge (ie, BridgePlugin). This hint is required because "bridge" itself is not a plugin type. | |||||
| #endif | |||||
| const unsigned int PLUGIN_IS_SYNTH = 0x002; //!< Plugin is a synthesizer (produces sound). | |||||
| const unsigned int PLUGIN_HAS_GUI = 0x004; //!< Plugin has its own custom GUI. | |||||
| const unsigned int PLUGIN_USES_CHUNKS = 0x008; //!< Plugin uses chunks to save internal data.\see CarlaPlugin::chunkData() | |||||
| const unsigned int PLUGIN_USES_SINGLE_THREAD = 0x010; //!< Plugin needs a single thread for both DSP processing and UI events. | |||||
| const unsigned int PLUGIN_CAN_DRYWET = 0x020; //!< Plugin can make use of Dry/Wet controls. | |||||
| const unsigned int PLUGIN_CAN_VOLUME = 0x040; //!< Plugin can make use of Volume controls. | |||||
| const unsigned int PLUGIN_CAN_BALANCE = 0x080; //!< Plugin can make use of Left & Right Balance controls. | |||||
| const unsigned int PLUGIN_CAN_FORCE_STEREO = 0x100; //!< Plugin can be used in forced-stereo mode. | |||||
| /**@}*/ | |||||
| /*! | |||||
| * @defgroup ParameterHints Parameter Hints | |||||
| * | |||||
| * Various parameter hints. | |||||
| * \see CarlaPlugin::parameterData() | |||||
| * @{ | |||||
| */ | |||||
| const unsigned int PARAMETER_IS_BOOLEAN = 0x01; //!< Parameter value is of boolean type (always at minimum or maximum). | |||||
| const unsigned int PARAMETER_IS_INTEGER = 0x02; //!< Parameter values are always integer. | |||||
| const unsigned int PARAMETER_IS_LOGARITHMIC = 0x04; //!< Parameter is logarithmic (informative only, not really implemented). | |||||
| const unsigned int PARAMETER_IS_ENABLED = 0x08; //!< Parameter is enabled and will be shown in the host built-in editor. | |||||
| const unsigned int PARAMETER_IS_AUTOMABLE = 0x10; //!< Parameter is automable (realtime safe) | |||||
| const unsigned int PARAMETER_USES_SAMPLERATE = 0x20; //!< Parameter needs sample rate to work (value and ranges are multiplied by SR, and divided by SR on save). | |||||
| const unsigned int PARAMETER_USES_SCALEPOINTS = 0x40; //!< Parameter uses scalepoints to define internal values in a meaninful way. | |||||
| const unsigned int PARAMETER_USES_CUSTOM_TEXT = 0x80; //!< Parameter uses custom text for displaying its value.\see CarlaPlugin::getParameterText() | |||||
| /**@}*/ | |||||
| /*! | |||||
| * @defgroup CustomDataTypes Custom Data types | |||||
| * | |||||
| * The type defines how the \param value in CustomData is stored. | |||||
| * | |||||
| * Types are valid URIs.\n | |||||
| * Any non-string type is saved in a base64 encoded format. | |||||
| */ | |||||
| const char* const CUSTOM_DATA_INVALID = nullptr; //!< Null/Invalid data. | |||||
| const char* const CUSTOM_DATA_CHUNK = "http://kxstudio.sf.net/ns/carla/chunk"; //!< Carla Chunk | |||||
| const char* const CUSTOM_DATA_STRING = "http://kxstudio.sf.net/ns/carla/string"; //!< Carla String | |||||
| /**@}*/ | |||||
| /*! | |||||
| * @defgroup BridgeMessages Bridge Messages | |||||
| * | |||||
| * Various bridge related messages, used as configure(<message>, value). | |||||
| * \note This is for internal use only. | |||||
| * @{ | |||||
| */ | |||||
| const char* const CARLA_BRIDGE_MSG_HIDE_GUI = "CarlaBridgeHideGUI"; //!< Plugin -> Host call, tells host GUI is now hidden | |||||
| const char* const CARLA_BRIDGE_MSG_SAVED = "CarlaBridgeSaved"; //!< Plugin -> Host call, tells host state is saved | |||||
| const char* const CARLA_BRIDGE_MSG_SAVE_NOW = "CarlaBridgeSaveNow"; //!< Host -> Plugin call, tells plugin to save state now | |||||
| const char* const CARLA_BRIDGE_MSG_SET_CHUNK = "CarlaBridgeSetChunk"; //!< Host -> Plugin call, tells plugin to set chunk in file \a value | |||||
| const char* const CARLA_BRIDGE_MSG_SET_CUSTOM = "CarlaBridgeSetCustom"; //!< Host -> Plugin call, tells plugin to set a custom data set using \a value ("type·key·rvalue").\n If \a type is 'chunk' or 'binary' \a rvalue refers to chunk file. | |||||
| /**@}*/ | |||||
| /*! | |||||
| * The binary type of a plugin. | |||||
| */ | |||||
| enum BinaryType { | |||||
| BINARY_NONE = 0, //!< Null binary type. | |||||
| BINARY_POSIX32 = 1, //!< POSIX 32bit. | |||||
| BINARY_POSIX64 = 2, //!< POSIX 64bit. | |||||
| BINARY_WIN32 = 3, //!< Windows 32bit. | |||||
| BINARY_WIN64 = 4, //!< Windows 64bit. | |||||
| BINARY_OTHER = 5 //!< Other. | |||||
| }; | |||||
| /*! | |||||
| * All the available plugin types, as provided by subclasses of CarlaPlugin.\n | |||||
| * \note Some plugin classes might provide more than 1 plugin type. | |||||
| */ | |||||
| enum PluginType { | |||||
| PLUGIN_NONE = 0, //!< Null plugin type. | |||||
| PLUGIN_INTERNAL = 1, //!< Internal plugin.\see NativePlugin | |||||
| PLUGIN_LADSPA = 2, //!< LADSPA plugin.\see LadspaPlugin | |||||
| PLUGIN_DSSI = 3, //!< DSSI plugin.\see DssiPlugin | |||||
| PLUGIN_LV2 = 4, //!< LV2 plugin.\see Lv2Plugin | |||||
| PLUGIN_VST = 5, //!< VST plugin.\see VstPlugin | |||||
| PLUGIN_GIG = 6, //!< GIG sound kit, implemented via LinuxSampler.\see LinuxSamplerPlugin | |||||
| PLUGIN_SF2 = 7, //!< SF2 sound kit (aka SoundFont), implemented via FluidSynth.\see FluidSynthPlugin | |||||
| PLUGIN_SFZ = 8 //!< SFZ sound kit, implemented via LinuxSampler.\see LinuxSamplerPlugin | |||||
| }; | |||||
| /*! | |||||
| * Plugin category, describing the funtionality of a plugin.\n | |||||
| * When a plugin fails to tell his own category, one is atributted to it based on its name. | |||||
| */ | |||||
| 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). | |||||
| }; | |||||
| /*! | |||||
| * Plugin parameter type. | |||||
| */ | |||||
| enum ParameterType { | |||||
| PARAMETER_UNKNOWN = 0, //!< Null parameter type. | |||||
| PARAMETER_INPUT = 1, //!< Input parameter. | |||||
| PARAMETER_OUTPUT = 2, //!< Ouput parameter. | |||||
| PARAMETER_LATENCY = 3, //!< Special latency parameter, used in LADSPA, DSSI and LV2 plugins. | |||||
| PARAMETER_SAMPLE_RATE = 4, //!< Special sample-rate parameter, used in LADSPA, DSSI and LV2 plugins. | |||||
| PARAMETER_LV2_FREEWHEEL = 5, //!< Special LV2 Plugin parameter used to report freewheel (offline) mode. | |||||
| PARAMETER_LV2_TIME = 6 //!< Special LV2 Plugin parameter used to report time information. | |||||
| }; | |||||
| /*! | |||||
| * Internal parameter indexes.\n | |||||
| * These are special parameters used internally, plugins do not know about their existence. | |||||
| */ | |||||
| enum InternalParametersIndex { | |||||
| PARAMETER_NULL = -1, //!< Null parameter. | |||||
| PARAMETER_ACTIVE = -2, //!< Active parameter, can only be 'true' or 'false'; default is 'false'. | |||||
| PARAMETER_DRYWET = -3, //!< Dry/Wet parameter, range 0.0...1.0; default is 1.0. | |||||
| PARAMETER_VOLUME = -4, //!< Volume parameter, range 0.0...1.27; default is 1.0. | |||||
| PARAMETER_BALANCE_LEFT = -5, //!< Balance-Left parameter, range -1.0...1.0; default is -1.0. | |||||
| PARAMETER_BALANCE_RIGHT = -6 //!< Balance-Right parameter, range -1.0...1.0; default is 1.0. | |||||
| }; | |||||
| /*! | |||||
| * Plugin custom GUI type. | |||||
| * \see OPTION_PREFER_UI_BRIDGES | |||||
| */ | |||||
| enum GuiType { | |||||
| GUI_NONE = 0, //!< Null type, plugin has no custom GUI. | |||||
| GUI_INTERNAL_QT4 = 1, //!< Qt4 type, handled internally. | |||||
| GUI_INTERNAL_COCOA = 2, //!< Reparented MacOS native type, handled internally. | |||||
| GUI_INTERNAL_HWND = 3, //!< Reparented Windows native type, handled internally. | |||||
| GUI_INTERNAL_X11 = 4, //!< Reparented X11 native type, handled internally. | |||||
| GUI_EXTERNAL_LV2 = 5, //!< External LV2-UI type, handled internally. | |||||
| GUI_EXTERNAL_SUIL = 6, //!< SUIL type, currently used only for lv2 gtk2 direct-access UIs.\note This type will be removed in the future! | |||||
| GUI_EXTERNAL_OSC = 7 //!< External, osc-bridge controlled, UI. | |||||
| }; | |||||
| /*! | |||||
| * Options used in the set_option() call.\n | |||||
| * These options must be set before calling engine_init() or after engine_close(). | |||||
| */ | |||||
| enum OptionsType { | |||||
| /*! | |||||
| * Try to set the current process name.\n | |||||
| * \note Not available on all platforms. | |||||
| */ | |||||
| OPTION_PROCESS_NAME = 0, | |||||
| /*! | |||||
| * Set the engine processing mode.\n | |||||
| * Default is PROCESS_MODE_MULTIPLE_CLIENTS. | |||||
| * \see ProcessMode | |||||
| */ | |||||
| OPTION_PROCESS_MODE = 1, | |||||
| /*! | |||||
| * High-Precision processing mode.\n | |||||
| * When enabled, audio will be processed by blocks of 8 samples at a time, indenpendently of the buffer size.\n | |||||
| * Default is off.\n | |||||
| * EXPERIMENTAL! | |||||
| */ | |||||
| OPTION_PROCESS_HIGH_PRECISION = 2, | |||||
| /*! | |||||
| * Maximum number of parameters allowed.\n | |||||
| * Default is MAX_PARAMETERS. | |||||
| */ | |||||
| OPTION_MAX_PARAMETERS = 3, | |||||
| /*! | |||||
| * Prefered buffer size, currently unused. | |||||
| */ | |||||
| OPTION_PREFERRED_BUFFER_SIZE = 4, | |||||
| /*! | |||||
| * Prefered sample rate, currently unused. | |||||
| */ | |||||
| OPTION_PREFERRED_SAMPLE_RATE = 5, | |||||
| /*! | |||||
| * Force mono plugins as stereo, by running 2 instances at the same time.\n | |||||
| * Not supported in VST plugins. | |||||
| */ | |||||
| OPTION_FORCE_STEREO = 6, | |||||
| /*! | |||||
| * Use (unofficial) dssi-vst chunks feature.\n | |||||
| * Default is no.\n | |||||
| * EXPERIMENTAL! | |||||
| */ | |||||
| OPTION_USE_DSSI_VST_CHUNKS = 7, | |||||
| /*! | |||||
| * Use plugin bridges whenever possible.\n | |||||
| * Default is no, and not recommended at this point!. | |||||
| * EXPERIMENTAL! | |||||
| */ | |||||
| OPTION_PREFER_PLUGIN_BRIDGES = 8, | |||||
| /*! | |||||
| * Use OSC-UI bridges whenever possible, otherwise UIs will be handled in the main thread.\n | |||||
| * Default is yes. | |||||
| */ | |||||
| OPTION_PREFER_UI_BRIDGES = 9, | |||||
| /*! | |||||
| * Timeout value in ms for how much to wait for OSC-UIs to respond.\n | |||||
| * Default is 4000 ms (4 secs). | |||||
| */ | |||||
| OPTION_OSC_UI_TIMEOUT = 10, | |||||
| /*! | |||||
| * Set path to the POSIX 32bit plugin bridge executable.\n | |||||
| * Default unset. | |||||
| */ | |||||
| OPTION_PATH_BRIDGE_POSIX32 = 11, | |||||
| /*! | |||||
| * Set path to the POSIX 64bit plugin bridge executable.\n | |||||
| * Default unset. | |||||
| */ | |||||
| OPTION_PATH_BRIDGE_POSIX64 = 12, | |||||
| /*! | |||||
| * Set path to the Windows 32bit plugin bridge executable.\n | |||||
| * Default unset. | |||||
| */ | |||||
| OPTION_PATH_BRIDGE_WIN32 = 13, | |||||
| /*! | |||||
| * Set path to the Windows 64bit plugin bridge executable.\n | |||||
| * Default unset. | |||||
| */ | |||||
| OPTION_PATH_BRIDGE_WIN64 = 14, | |||||
| /*! | |||||
| * Set path to the LV2 Gtk2 UI bridge executable.\n | |||||
| * Default unset. | |||||
| */ | |||||
| OPTION_PATH_BRIDGE_LV2_GTK2 = 15, | |||||
| /*! | |||||
| * Set path to the LV2 Gtk3 UI bridge executable.\n | |||||
| * Default unset. | |||||
| */ | |||||
| OPTION_PATH_BRIDGE_LV2_GTK3 = 16, | |||||
| /*! | |||||
| * Set path to the LV2 Qt4 UI bridge executable.\n | |||||
| * Default unset. | |||||
| */ | |||||
| OPTION_PATH_BRIDGE_LV2_QT4 = 17, | |||||
| /*! | |||||
| * Set path to the LV2 Qt5 UI bridge executable.\n | |||||
| * Default unset. | |||||
| */ | |||||
| OPTION_PATH_BRIDGE_LV2_QT5 = 18, | |||||
| /*! | |||||
| * Set path to the LV2 Cocoa UI bridge executable.\n | |||||
| * Default unset. | |||||
| */ | |||||
| OPTION_PATH_BRIDGE_LV2_COCOA = 19, | |||||
| /*! | |||||
| * Set path to the LV2 Windows UI bridge executable.\n | |||||
| * Default unset. | |||||
| */ | |||||
| OPTION_PATH_BRIDGE_LV2_WINDOWS = 20, | |||||
| /*! | |||||
| * Set path to the LV2 X11 UI bridge executable.\n | |||||
| * Default unset. | |||||
| */ | |||||
| OPTION_PATH_BRIDGE_LV2_X11 = 21, | |||||
| /*! | |||||
| * Set path to the VST Cocoa UI bridge executable.\n | |||||
| * Default unset. | |||||
| */ | |||||
| OPTION_PATH_BRIDGE_VST_COCOA = 22, | |||||
| /*! | |||||
| * Set path to the VST HWND UI bridge executable.\n | |||||
| * Default unset. | |||||
| */ | |||||
| OPTION_PATH_BRIDGE_VST_HWND = 23, | |||||
| /*! | |||||
| * Set path to the VST X11 UI bridge executable.\n | |||||
| * Default unset. | |||||
| */ | |||||
| OPTION_PATH_BRIDGE_VST_X11 = 24 | |||||
| }; | |||||
| /*! | |||||
| * Opcodes sent from the engine callback, as defined by CallbackFunc. | |||||
| * | |||||
| * \see set_callback_function() | |||||
| */ | |||||
| enum CallbackType { | |||||
| /*! | |||||
| * Debug.\n | |||||
| * This opcode is undefined and used only for testing purposes. | |||||
| */ | |||||
| CALLBACK_DEBUG = 0, | |||||
| /*! | |||||
| * A parameter has been changed. | |||||
| * | |||||
| * \param value1 Parameter index | |||||
| * \param value3 Value | |||||
| */ | |||||
| CALLBACK_PARAMETER_VALUE_CHANGED = 1, | |||||
| /*! | |||||
| * A parameter's MIDI channel has been changed. | |||||
| * | |||||
| * \param value1 Parameter index | |||||
| * \param value2 MIDI channel | |||||
| */ | |||||
| CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED = 2, | |||||
| /*! | |||||
| * A parameter's MIDI CC has been changed. | |||||
| * | |||||
| * \param value1 Parameter index | |||||
| * \param value2 MIDI CC | |||||
| */ | |||||
| CALLBACK_PARAMETER_MIDI_CC_CHANGED = 3, | |||||
| /*! | |||||
| * The current program has has been changed. | |||||
| * | |||||
| * \param value1 Program index | |||||
| */ | |||||
| CALLBACK_PROGRAM_CHANGED = 4, | |||||
| /*! | |||||
| * The current MIDI program has been changed. | |||||
| * | |||||
| * \param value1 MIDI bank | |||||
| * \param value2 MIDI program | |||||
| */ | |||||
| CALLBACK_MIDI_PROGRAM_CHANGED = 5, | |||||
| /*! | |||||
| * A note has been pressed. | |||||
| * | |||||
| * \param value1 Channel | |||||
| * \param value2 Note | |||||
| * \param value3 Velocity | |||||
| */ | |||||
| CALLBACK_NOTE_ON = 6, | |||||
| /*! | |||||
| * A note has been released. | |||||
| * | |||||
| * \param value1 Channel | |||||
| * \param value2 Note | |||||
| */ | |||||
| CALLBACK_NOTE_OFF = 7, | |||||
| /*! | |||||
| * The plugin's custom GUI state has changed. | |||||
| * | |||||
| * \param value1 State, as follows:.\n | |||||
| * 0: GUI has been closed or hidden\n | |||||
| * 1: GUI has been shown\n | |||||
| * -1: GUI has crashed and should not be shown again\n | |||||
| */ | |||||
| CALLBACK_SHOW_GUI = 8, | |||||
| /*! | |||||
| * The plugin's custom GUI has been resized. | |||||
| * | |||||
| * \param value1 Width | |||||
| * \param value2 Height | |||||
| */ | |||||
| CALLBACK_RESIZE_GUI = 9, | |||||
| /*! | |||||
| * The plugin needs update. | |||||
| */ | |||||
| CALLBACK_UPDATE = 10, | |||||
| /*! | |||||
| * The plugin's data/information has changed. | |||||
| */ | |||||
| CALLBACK_RELOAD_INFO = 11, | |||||
| /*! | |||||
| * The plugin's parameters have changed. | |||||
| */ | |||||
| CALLBACK_RELOAD_PARAMETERS = 12, | |||||
| /*! | |||||
| * The plugin's programs have changed. | |||||
| */ | |||||
| CALLBACK_RELOAD_PROGRAMS = 13, | |||||
| /*! | |||||
| * The plugin's state has changed. | |||||
| */ | |||||
| CALLBACK_RELOAD_ALL = 14, | |||||
| /*! | |||||
| * Non-Session-Manager Announce message. | |||||
| */ | |||||
| CALLBACK_NSM_ANNOUNCE = 15, | |||||
| /*! | |||||
| * Non-Session-Manager Open message #1. | |||||
| */ | |||||
| CALLBACK_NSM_OPEN1 = 16, | |||||
| /*! | |||||
| * Non-Session-Manager Open message #2. | |||||
| */ | |||||
| CALLBACK_NSM_OPEN2 = 17, | |||||
| /*! | |||||
| * Non-Session-Manager Save message. | |||||
| */ | |||||
| CALLBACK_NSM_SAVE = 18, | |||||
| /*! | |||||
| * An error occurred, show last error to user. | |||||
| */ | |||||
| CALLBACK_ERROR = 19, | |||||
| /*! | |||||
| * The engine has crashed or malfunctioned and will no longer work. | |||||
| */ | |||||
| CALLBACK_QUIT = 20 | |||||
| }; | |||||
| /*! | |||||
| * Engine process mode, changed using set_option(). | |||||
| * | |||||
| * \see OPTION_PROCESS_MODE | |||||
| */ | |||||
| enum ProcessMode { | |||||
| PROCESS_MODE_SINGLE_CLIENT = 0, //!< Single client mode (dynamic input/outputs as needed by plugins) | |||||
| PROCESS_MODE_MULTIPLE_CLIENTS = 1, //!< Multiple client mode (1 master client + 1 client per plugin) | |||||
| PROCESS_MODE_CONTINUOUS_RACK = 2, //!< Single client, 'rack' mode. Processes plugins in order of id, with forced stereo. | |||||
| PROCESS_MODE_PATCHBAY = 3 //!< Single client, 'patchbay' mode. | |||||
| }; | |||||
| /*! | |||||
| * Callback function the backend will call when something interesting happens. | |||||
| * | |||||
| * \see set_callback_function() | |||||
| */ | |||||
| typedef void (*CallbackFunc)(void* ptr, CallbackType action, unsigned short pluginId, int value1, int value2, double value3, const char* valueStr); | |||||
| struct ParameterData { | |||||
| ParameterType type; | |||||
| int32_t index; | |||||
| int32_t rindex; | |||||
| int32_t hints; | |||||
| uint8_t midiChannel; | |||||
| int16_t midiCC; | |||||
| ParameterData() | |||||
| : type(PARAMETER_UNKNOWN), | |||||
| index(-1), | |||||
| rindex(-1), | |||||
| hints(0), | |||||
| midiChannel(0), | |||||
| midiCC(-1) {} | |||||
| }; | |||||
| struct ParameterRanges { | |||||
| double def; | |||||
| double min; | |||||
| double max; | |||||
| double step; | |||||
| double stepSmall; | |||||
| double stepLarge; | |||||
| ParameterRanges() | |||||
| : def(0.0), | |||||
| min(0.0), | |||||
| max(1.0), | |||||
| step(0.01), | |||||
| stepSmall(0.0001), | |||||
| stepLarge(0.1) {} | |||||
| }; | |||||
| struct MidiProgramData { | |||||
| uint32_t bank; | |||||
| uint32_t program; | |||||
| const char* name; | |||||
| MidiProgramData() | |||||
| : bank(0), | |||||
| program(0), | |||||
| name(nullptr) {} | |||||
| }; | |||||
| struct CustomData { | |||||
| const char* type; | |||||
| const char* key; | |||||
| const char* value; | |||||
| CustomData() | |||||
| : type(nullptr), | |||||
| key(nullptr), | |||||
| value(nullptr) {} | |||||
| }; | |||||
| /**@}*/ | |||||
| // forward declarations of commonly used Carla classes | |||||
| class CarlaEngine; | |||||
| class CarlaPlugin; | |||||
| CARLA_BACKEND_END_NAMESPACE | |||||
| #endif // CARLA_BACKEND_HPP | |||||
| @@ -0,0 +1,985 @@ | |||||
| /* | |||||
| * Carla Engine | |||||
| * 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_ENGINE_HPP | |||||
| #define CARLA_ENGINE_HPP | |||||
| #include "carla_engine_osc.hpp" | |||||
| #include "carla_engine_thread.hpp" | |||||
| #include <QtCore/QProcessEnvironment> | |||||
| CARLA_BACKEND_START_NAMESPACE | |||||
| /*! | |||||
| * @defgroup CarlaBackendEngine Carla Backend Engine | |||||
| * | |||||
| * The Carla Backend Engine | |||||
| * @{ | |||||
| */ | |||||
| /*! | |||||
| * @defgroup TimeInfoValidHints TimeInfo Valid Hints | |||||
| * | |||||
| * Various hints used for CarlaTimeInfo::valid. | |||||
| * @{ | |||||
| */ | |||||
| const uint32_t CarlaEngineTimeBBT = 0x1; | |||||
| /**@}*/ | |||||
| /*! | |||||
| * The type of an engine. | |||||
| */ | |||||
| enum CarlaEngineType { | |||||
| /*! | |||||
| * Null engine type. | |||||
| */ | |||||
| CarlaEngineTypeNull = 0, | |||||
| /*! | |||||
| * Jack engine type.\n | |||||
| * Provides single, multi-client, and rack processing modes. | |||||
| */ | |||||
| CarlaEngineTypeJack = 1, | |||||
| /*! | |||||
| * RtAudio engine type, used to provide ALSA, PulseAudio, DirectSound, ASIO and CoreAudio/Midi support.\n | |||||
| * Provides rack mode processing only. | |||||
| */ | |||||
| CarlaEngineTypeRtAudio = 2, | |||||
| /*! | |||||
| * Plugin engine type, used to export the engine as a plugin (DSSI, LV2 and VST) via the DISTRHO Plugin Toolkit.\n | |||||
| * Works in rack mode only. | |||||
| */ | |||||
| CarlaEngineTypePlugin = 3 | |||||
| }; | |||||
| /*! | |||||
| * The type of an engine port. | |||||
| */ | |||||
| enum CarlaEnginePortType { | |||||
| /*! | |||||
| * Null engine port type. | |||||
| */ | |||||
| CarlaEnginePortTypeNull = 0, | |||||
| /*! | |||||
| * Audio port. | |||||
| */ | |||||
| CarlaEnginePortTypeAudio = 1, | |||||
| /*! | |||||
| * Control port.\n | |||||
| * These are MIDI ports on some engine types, by handling MIDI-CC as control. | |||||
| */ | |||||
| CarlaEnginePortTypeControl = 2, | |||||
| /*! | |||||
| * MIDI port. | |||||
| */ | |||||
| CarlaEnginePortTypeMIDI = 3 | |||||
| }; | |||||
| /*! | |||||
| * The type of a control event. | |||||
| */ | |||||
| enum CarlaEngineControlEventType { | |||||
| /*! | |||||
| * Null event type. | |||||
| */ | |||||
| CarlaEngineNullEvent = 0, | |||||
| /*! | |||||
| * Parameter change event.\n | |||||
| * \note Value uses a range of 0.0<->1.0. | |||||
| */ | |||||
| CarlaEngineParameterChangeEvent = 1, | |||||
| /*! | |||||
| * MIDI Bank change event. | |||||
| */ | |||||
| CarlaEngineMidiBankChangeEvent = 2, | |||||
| /*! | |||||
| * MIDI Program change event. | |||||
| */ | |||||
| CarlaEngineMidiProgramChangeEvent = 3, | |||||
| /*! | |||||
| * All sound off event. | |||||
| */ | |||||
| CarlaEngineAllSoundOffEvent = 4, | |||||
| /*! | |||||
| * All notes off event. | |||||
| */ | |||||
| CarlaEngineAllNotesOffEvent = 5 | |||||
| }; | |||||
| /*! | |||||
| * Engine control event. | |||||
| */ | |||||
| struct CarlaEngineControlEvent { | |||||
| CarlaEngineControlEventType type; | |||||
| uint32_t time; | |||||
| uint8_t channel; | |||||
| uint16_t parameter; | |||||
| double value; | |||||
| CarlaEngineControlEvent() | |||||
| : type(CarlaEngineNullEvent), | |||||
| time(0), | |||||
| channel(0), | |||||
| parameter(0), | |||||
| value(0.0) {} | |||||
| }; | |||||
| /*! | |||||
| * Engine MIDI event. | |||||
| */ | |||||
| struct CarlaEngineMidiEvent { | |||||
| uint32_t time; | |||||
| uint8_t size; | |||||
| uint8_t data[3]; | |||||
| CarlaEngineMidiEvent() | |||||
| : time(0), | |||||
| size(0), | |||||
| data{0} {} | |||||
| }; | |||||
| /*! | |||||
| * Engine BBT Time information. | |||||
| */ | |||||
| struct CarlaEngineTimeInfoBBT { | |||||
| 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; | |||||
| CarlaEngineTimeInfoBBT() | |||||
| : bar(0), | |||||
| beat(0), | |||||
| tick(0), | |||||
| bar_start_tick(0.0), | |||||
| beats_per_bar(0.0f), | |||||
| beat_type(0.0f), | |||||
| ticks_per_beat(0.0), | |||||
| beats_per_minute(0.0) {} | |||||
| }; | |||||
| /*! | |||||
| * Engine Time information. | |||||
| */ | |||||
| struct CarlaEngineTimeInfo { | |||||
| bool playing; | |||||
| uint32_t frame; | |||||
| uint32_t time; | |||||
| uint32_t valid; | |||||
| CarlaEngineTimeInfoBBT bbt; | |||||
| CarlaEngineTimeInfo() | |||||
| : playing(false), | |||||
| frame(0), | |||||
| time(0), | |||||
| valid(0) {} | |||||
| }; | |||||
| /*! | |||||
| * Engine options. | |||||
| */ | |||||
| struct CarlaEngineOptions { | |||||
| ProcessMode processMode; | |||||
| bool processHighPrecision; | |||||
| uint maxParameters; | |||||
| uint preferredBufferSize; | |||||
| uint preferredSampleRate; | |||||
| bool forceStereo; | |||||
| bool useDssiVstChunks; | |||||
| bool preferPluginBridges; | |||||
| bool preferUiBridges; | |||||
| uint oscUiTimeout; | |||||
| CarlaString bridge_posix32; | |||||
| CarlaString bridge_posix64; | |||||
| CarlaString bridge_win32; | |||||
| CarlaString bridge_win64; | |||||
| CarlaString bridge_lv2gtk2; | |||||
| CarlaString bridge_lv2gtk3; | |||||
| CarlaString bridge_lv2qt4; | |||||
| CarlaString bridge_lv2qt5; | |||||
| CarlaString bridge_lv2cocoa; | |||||
| CarlaString bridge_lv2win; | |||||
| CarlaString bridge_lv2x11; | |||||
| CarlaString bridge_vstcocoa; | |||||
| CarlaString bridge_vsthwnd; | |||||
| CarlaString bridge_vstx11; | |||||
| CarlaEngineOptions() | |||||
| : processMode(PROCESS_MODE_CONTINUOUS_RACK), | |||||
| processHighPrecision(false), | |||||
| maxParameters(MAX_PARAMETERS), | |||||
| preferredBufferSize(512), | |||||
| preferredSampleRate(44100), | |||||
| forceStereo(false), | |||||
| useDssiVstChunks(false), | |||||
| preferPluginBridges(false), | |||||
| preferUiBridges(true), | |||||
| oscUiTimeout(4000/100) {} | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | |||||
| /*! | |||||
| * Engine port (Base).\n | |||||
| * This is the base class for all Carla engine ports. | |||||
| */ | |||||
| class CarlaEngineBasePort | |||||
| { | |||||
| public: | |||||
| /*! | |||||
| * The contructor.\n | |||||
| * Param \a isInput defines wherever this is an input port or not (output otherwise).\n | |||||
| * Input/output state is constant for the lifetime of the port. | |||||
| */ | |||||
| CarlaEngineBasePort(const bool isInput, const ProcessMode processMode); | |||||
| /*! | |||||
| * The decontructor. | |||||
| */ | |||||
| virtual ~CarlaEngineBasePort(); | |||||
| /*! | |||||
| * Get the type of the port, as provided by the respective subclasses. | |||||
| */ | |||||
| virtual CarlaEnginePortType type() const = 0; | |||||
| /*! | |||||
| * Initialize the port's internal buffer for \a engine. | |||||
| */ | |||||
| virtual void initBuffer(CarlaEngine* const engine) = 0; | |||||
| protected: | |||||
| const bool isInput; | |||||
| const ProcessMode processMode; | |||||
| void* buffer; | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | |||||
| /*! | |||||
| * Engine port (Audio). | |||||
| */ | |||||
| class CarlaEngineAudioPort : public CarlaEngineBasePort | |||||
| { | |||||
| public: | |||||
| /*! | |||||
| * The contructor.\n | |||||
| * Param \a isInput defines wherever this is an input port or not (output otherwise).\n | |||||
| * Input/output state is constant for the lifetime of the port. | |||||
| */ | |||||
| CarlaEngineAudioPort(const bool isInput, const ProcessMode processMode); | |||||
| /*! | |||||
| * The decontructor. | |||||
| */ | |||||
| virtual ~CarlaEngineAudioPort(); | |||||
| /*! | |||||
| * Get the type of the port, in this case CarlaEnginePortTypeAudio. | |||||
| */ | |||||
| CarlaEnginePortType type() const | |||||
| { | |||||
| return CarlaEnginePortTypeAudio; | |||||
| } | |||||
| /*! | |||||
| * Initialize the port's internal buffer for \a engine. | |||||
| */ | |||||
| virtual void initBuffer(CarlaEngine* const engine); | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | |||||
| /*! | |||||
| * Engine port (Control). | |||||
| */ | |||||
| class CarlaEngineControlPort : public CarlaEngineBasePort | |||||
| { | |||||
| public: | |||||
| /*! | |||||
| * The contructor.\n | |||||
| * Param \a isInput defines wherever this is an input port or not (output otherwise).\n | |||||
| * Input/output state is constant for the lifetime of the port. | |||||
| */ | |||||
| CarlaEngineControlPort(const bool isInput, const ProcessMode processMode); | |||||
| /*! | |||||
| * The decontructor. | |||||
| */ | |||||
| virtual ~CarlaEngineControlPort(); | |||||
| /*! | |||||
| * Get the type of the port, in this case CarlaEnginePortTypeControl. | |||||
| */ | |||||
| CarlaEnginePortType type() const | |||||
| { | |||||
| return CarlaEnginePortTypeControl; | |||||
| } | |||||
| /*! | |||||
| * Initialize the port's internal buffer for \a engine. | |||||
| */ | |||||
| virtual void initBuffer(CarlaEngine* const engine); | |||||
| /*! | |||||
| * Get the number of control events present in the buffer. | |||||
| * \note You must only call this for input ports. | |||||
| */ | |||||
| virtual uint32_t getEventCount(); | |||||
| /*! | |||||
| * Get the control event at \a index. | |||||
| ** \note You must only call this for input ports. | |||||
| */ | |||||
| virtual const CarlaEngineControlEvent* getEvent(const uint32_t index); | |||||
| /*! | |||||
| * Write a control event to the buffer.\n | |||||
| * Arguments are the same as in the CarlaEngineControlEvent struct. | |||||
| ** \note You must only call this for output ports. | |||||
| */ | |||||
| virtual void writeEvent(const CarlaEngineControlEventType type, const uint32_t time, const uint8_t channel, const uint16_t parameter, const double value); | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | |||||
| /*! | |||||
| * Engine port (MIDI). | |||||
| */ | |||||
| class CarlaEngineMidiPort : public CarlaEngineBasePort | |||||
| { | |||||
| public: | |||||
| /*! | |||||
| * The contructor.\n | |||||
| * Param \a isInput defines wherever this is an input port or not (output otherwise).\n | |||||
| * Input/output state is constant for the lifetime of the port. | |||||
| */ | |||||
| CarlaEngineMidiPort(const bool isInput, const ProcessMode processMode); | |||||
| /*! | |||||
| * The decontructor. | |||||
| */ | |||||
| virtual ~CarlaEngineMidiPort(); | |||||
| /*! | |||||
| * Get the type of the port, in this case CarlaEnginePortTypeMIDI. | |||||
| */ | |||||
| CarlaEnginePortType type() const | |||||
| { | |||||
| return CarlaEnginePortTypeMIDI; | |||||
| } | |||||
| /*! | |||||
| * Initialize the port's internal buffer for \a engine. | |||||
| */ | |||||
| virtual void initBuffer(CarlaEngine* const engine); | |||||
| /*! | |||||
| * Get the number of MIDI events present in the buffer. | |||||
| * \note You must only call this for input ports. | |||||
| */ | |||||
| virtual uint32_t getEventCount(); | |||||
| /*! | |||||
| * Get the MIDI event at \a index. | |||||
| ** \note You must only call this for input ports. | |||||
| */ | |||||
| virtual const CarlaEngineMidiEvent* getEvent(const uint32_t index); | |||||
| /*! | |||||
| * Write a MIDI event to the buffer.\n | |||||
| * Arguments are the same as in the CarlaEngineMidiEvent struct. | |||||
| ** \note You must only call this for output ports. | |||||
| */ | |||||
| virtual void writeEvent(const uint32_t time, const uint8_t* const data, const uint8_t size); | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | |||||
| /*! | |||||
| * Engine client.\n | |||||
| * Each plugin requires one client from the engine (created via CarlaEngine::addPort()).\n | |||||
| * \note This is a virtual class, each engine type provides its own funtionality. | |||||
| */ | |||||
| class CarlaEngineClient | |||||
| { | |||||
| public: | |||||
| /*! | |||||
| * The contructor.\n | |||||
| * All constructor parameters are constant and will never change in the lifetime of the client.\n | |||||
| * Client starts in deactivated state. | |||||
| */ | |||||
| CarlaEngineClient(const CarlaEngineType engineType, const ProcessMode processMode); | |||||
| /*! | |||||
| * The decontructor. | |||||
| */ | |||||
| virtual ~CarlaEngineClient(); | |||||
| /*! | |||||
| * Activate this client.\n | |||||
| * \note Client must be deactivated before calling this function. | |||||
| */ | |||||
| virtual void activate(); | |||||
| /*! | |||||
| * Deactivate this client.\n | |||||
| * \note Client must be activated before calling this function. | |||||
| */ | |||||
| virtual void deactivate(); | |||||
| /*! | |||||
| * Check if the client is activated. | |||||
| */ | |||||
| virtual bool isActive() const; | |||||
| /*! | |||||
| * Check if the client is ok.\n | |||||
| * Plugins will refuse to instantiate if this returns false. | |||||
| * \note This is always true in rack and patchbay processing modes. | |||||
| */ | |||||
| virtual bool isOk() const; | |||||
| /*! | |||||
| * Get the current latency, in samples. | |||||
| */ | |||||
| virtual uint32_t getLatency() const; | |||||
| /*! | |||||
| * Change the client's latency. | |||||
| */ | |||||
| virtual void setLatency(const uint32_t samples); | |||||
| /*! | |||||
| * Add a new port of type \a portType. | |||||
| * \note This function does nothing in rack processing mode since its ports are static (2 audio, 1 midi and 1 control for both input and output). | |||||
| */ | |||||
| virtual const CarlaEngineBasePort* addPort(const CarlaEnginePortType portType, const char* const name, const bool isInput) = 0; | |||||
| protected: | |||||
| const CarlaEngineType engineType; | |||||
| const ProcessMode processMode; | |||||
| private: | |||||
| bool m_active; | |||||
| uint32_t m_latency; | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | |||||
| /*! | |||||
| * Carla Engine. | |||||
| * \note This is a virtual class for all available engine types available in Carla. | |||||
| */ | |||||
| class CarlaEngine | |||||
| { | |||||
| public: | |||||
| /*! | |||||
| * The decontructor. | |||||
| * The engine must have been closed before this happens. | |||||
| */ | |||||
| virtual ~CarlaEngine(); | |||||
| // ------------------------------------------------------------------- | |||||
| // Static values and calls | |||||
| /*! | |||||
| * Maximum number of peaks per plugin.\n | |||||
| * \note There are both input and output peaks. | |||||
| */ | |||||
| static const unsigned short MAX_PEAKS = 2; | |||||
| /*! | |||||
| * Get the number of available engine drivers. | |||||
| */ | |||||
| static unsigned int getDriverCount(); | |||||
| /*! | |||||
| * Get the name of the engine driver at \a index. | |||||
| */ | |||||
| static const char* getDriverName(unsigned int index); | |||||
| /*! | |||||
| * Create a new engine, using driver \a driverName.\n | |||||
| * Returned variable must be deleted when no longer needed. | |||||
| */ | |||||
| static CarlaEngine* newDriverByName(const char* const driverName); | |||||
| // ------------------------------------------------------------------- | |||||
| // Maximum values | |||||
| /*! | |||||
| * Maximum client name size. | |||||
| */ | |||||
| virtual int maxClientNameSize(); | |||||
| /*! | |||||
| * Maximum port name size. | |||||
| */ | |||||
| virtual int maxPortNameSize(); | |||||
| /*! | |||||
| * Maximum number of loadable plugins. | |||||
| * \note This function returns 0 if engine is not started. | |||||
| */ | |||||
| unsigned short maxPluginNumber() const; | |||||
| // ------------------------------------------------------------------- | |||||
| // Virtual, per-engine type calls | |||||
| /*! | |||||
| * Initialize engine, using \a clientName. | |||||
| */ | |||||
| virtual bool init(const char* const clientName); | |||||
| /*! | |||||
| * Close engine. | |||||
| */ | |||||
| virtual bool close(); | |||||
| /*! | |||||
| * Check if engine is running. | |||||
| */ | |||||
| virtual bool isRunning() const = 0; | |||||
| /*! | |||||
| * Check if engine is running offline (aka freewheel mode). | |||||
| */ | |||||
| virtual bool isOffline() const = 0; | |||||
| /*! | |||||
| * Get engine type. | |||||
| */ | |||||
| virtual CarlaEngineType type() const = 0; | |||||
| /*! | |||||
| * Add new engine client. | |||||
| * \note This must only be called within a plugin class. | |||||
| */ | |||||
| virtual CarlaEngineClient* addClient(CarlaPlugin* const plugin) = 0; | |||||
| // ------------------------------------------------------------------- | |||||
| // Plugin management | |||||
| /*! | |||||
| * Get next available plugin id.\n | |||||
| * Returns -1 if no more plugins can be loaded. | |||||
| */ | |||||
| short getNewPluginId() const; | |||||
| /*! | |||||
| * Get plugin with id \a id. | |||||
| */ | |||||
| CarlaPlugin* getPlugin(const unsigned short id) const; | |||||
| /*! | |||||
| * Get plugin with id \a id, faster unchecked version. | |||||
| */ | |||||
| CarlaPlugin* getPluginUnchecked(const unsigned short id) const; | |||||
| /*! | |||||
| * Get a unique plugin name within the engine.\n | |||||
| * Returned variable must be free'd when no longer needed. | |||||
| */ | |||||
| const char* getUniquePluginName(const char* const name); | |||||
| /*! | |||||
| * Add new plugin.\n | |||||
| * Returns the id of the plugin, or -1 if the operation failed. | |||||
| */ | |||||
| short addPlugin(const BinaryType btype, const PluginType ptype, const char* const filename, const char* const name, const char* const label, void* const extra = nullptr); | |||||
| /*! | |||||
| * Add new plugin, using native binary type.\n | |||||
| * Returns the id of the plugin, or -1 if the operation failed. | |||||
| */ | |||||
| short addPlugin(const PluginType ptype, const char* const filename, const char* const name, const char* const label, void* const extra = nullptr); | |||||
| /*! | |||||
| * Remove plugin with id \a id. | |||||
| */ | |||||
| bool removePlugin(const unsigned short id); | |||||
| /*! | |||||
| * Remove all plugins. | |||||
| */ | |||||
| void removeAllPlugins(); | |||||
| /*! | |||||
| * Idle all plugins GUIs. | |||||
| */ | |||||
| void idlePluginGuis(); | |||||
| // bridge, internal use only | |||||
| // TODO - find a better way for this | |||||
| void __bridgePluginRegister(const unsigned short id, CarlaPlugin* const plugin) | |||||
| { | |||||
| m_carlaPlugins[id] = plugin; | |||||
| } | |||||
| // ------------------------------------------------------------------- | |||||
| // Information (base) | |||||
| /*! | |||||
| * Get engine name. | |||||
| */ | |||||
| const char* getName() const; | |||||
| /*! | |||||
| * Get current sample rate. | |||||
| */ | |||||
| double getSampleRate() const; | |||||
| /*! | |||||
| * Get current buffer size. | |||||
| */ | |||||
| uint32_t getBufferSize() const; | |||||
| /*! | |||||
| * Get current Time information. | |||||
| */ | |||||
| const CarlaEngineTimeInfo* getTimeInfo() const; | |||||
| /*! | |||||
| * Tell the engine it's about to close.\n | |||||
| * This is used to prevent the engine thread from reactivating. | |||||
| */ | |||||
| void aboutToClose(); | |||||
| // ------------------------------------------------------------------- | |||||
| // Information (audio peaks) | |||||
| double getInputPeak(const unsigned short pluginId, const unsigned short id) const; | |||||
| double getOutputPeak(const unsigned short pluginId, const unsigned short id) const; | |||||
| void setInputPeak(const unsigned short pluginId, const unsigned short id, double value); | |||||
| void setOutputPeak(const unsigned short pluginId, const unsigned short id, double value); | |||||
| // ------------------------------------------------------------------- | |||||
| // Callback | |||||
| void callback(const CallbackType action, const unsigned short pluginId, const int value1, const int value2, const double value3, const char* const valueStr); | |||||
| void setCallback(const CallbackFunc func, void* const ptr); | |||||
| // ------------------------------------------------------------------- | |||||
| // Error handling | |||||
| /*! | |||||
| * Get last error. | |||||
| */ | |||||
| const char* getLastError() const; | |||||
| /*! | |||||
| * Set last error. | |||||
| */ | |||||
| void setLastError(const char* const error); | |||||
| // ------------------------------------------------------------------- | |||||
| // Options | |||||
| /*! | |||||
| * Get the engine options (read-only). | |||||
| */ | |||||
| const CarlaEngineOptions& getOptions() const | |||||
| { | |||||
| return options; | |||||
| } | |||||
| #ifndef BUILD_BRIDGE | |||||
| /*! | |||||
| * Get the engine options as process environment. | |||||
| */ | |||||
| const QProcessEnvironment& getOptionsAsProcessEnvironment() const | |||||
| { | |||||
| return m_procEnv; | |||||
| } | |||||
| /*! | |||||
| * Set the engine option \a option. | |||||
| */ | |||||
| void setOption(const OptionsType option, const int value, const char* const valueStr); | |||||
| #endif | |||||
| // ------------------------------------------------------------------- | |||||
| // Mutex locks | |||||
| /*! | |||||
| * Lock processing. | |||||
| */ | |||||
| void processLock(); | |||||
| /*! | |||||
| * Try Lock processing. | |||||
| */ | |||||
| void processTryLock(); | |||||
| /*! | |||||
| * Unlock processing. | |||||
| */ | |||||
| void processUnlock(); | |||||
| /*! | |||||
| * Lock MIDI. | |||||
| */ | |||||
| void midiLock(); | |||||
| /*! | |||||
| * Try Lock MIDI. | |||||
| */ | |||||
| void midiTryLock(); | |||||
| /*! | |||||
| * Unlock MIDI. | |||||
| */ | |||||
| void midiUnlock(); | |||||
| // ------------------------------------------------------------------- | |||||
| // OSC Stuff | |||||
| #ifndef BUILD_BRIDGE | |||||
| /*! | |||||
| * Check if OSC controller is registered. | |||||
| */ | |||||
| bool isOscControlRegistered() const; | |||||
| #else | |||||
| /*! | |||||
| * Check if OSC bridge is registered. | |||||
| */ | |||||
| bool isOscBridgeRegistered() const; | |||||
| #endif | |||||
| /*! | |||||
| * Idle OSC. | |||||
| */ | |||||
| void idleOsc(); | |||||
| /*! | |||||
| * Get OSC TCP server path. | |||||
| */ | |||||
| const char* getOscServerPathTCP() const; | |||||
| /*! | |||||
| * Get OSC UDP server path. | |||||
| */ | |||||
| const char* getOscServerPathUDP() const; | |||||
| #ifdef BUILD_BRIDGE | |||||
| /*! | |||||
| * Set OSC bridge data. | |||||
| */ | |||||
| void setOscBridgeData(const CarlaOscData* const oscData); | |||||
| #endif | |||||
| #ifdef BUILD_BRIDGE | |||||
| void osc_send_peaks(CarlaPlugin* const plugin); | |||||
| #else | |||||
| void osc_send_peaks(CarlaPlugin* const plugin, const unsigned short& id); | |||||
| #endif | |||||
| #ifdef BUILD_BRIDGE | |||||
| void osc_send_bridge_audio_count(const int32_t ins, const int32_t outs, const int32_t total); | |||||
| void osc_send_bridge_midi_count(const int32_t ins, const int32_t outs, const int32_t total); | |||||
| void osc_send_bridge_parameter_count(const int32_t ins, const int32_t outs, const int32_t total); | |||||
| void osc_send_bridge_program_count(const int32_t count); | |||||
| void osc_send_bridge_midi_program_count(const int32_t count); | |||||
| void osc_send_bridge_plugin_info(const int32_t category, const int32_t hints, const char* const name, const char* const label, const char* const maker, const char* const copyright, const int64_t uniqueId); | |||||
| void osc_send_bridge_parameter_info(const int32_t index, const char* const name, const char* const unit); | |||||
| void osc_send_bridge_parameter_data(const int32_t index, const int32_t type, const int32_t rindex, const int32_t hints, const int32_t midiChannel, const int32_t midiCC); | |||||
| void osc_send_bridge_parameter_ranges(const int32_t index, const double def, const double min, const double max, const double step, const double stepSmall, const double stepLarge); | |||||
| void osc_send_bridge_program_info(const int32_t index, const char* const name); | |||||
| void osc_send_bridge_midi_program_info(const int32_t index, const int32_t bank, const int32_t program, const char* const label); | |||||
| void osc_send_bridge_configure(const char* const key, const char* const value); | |||||
| void osc_send_bridge_set_parameter_value(const int32_t index, const double value); | |||||
| void osc_send_bridge_set_default_value(const int32_t index, const double value); | |||||
| void osc_send_bridge_set_program(const int32_t index); | |||||
| void osc_send_bridge_set_midi_program(const int32_t index); | |||||
| void osc_send_bridge_set_custom_data(const char* const type, const char* const key, const char* const value); | |||||
| void osc_send_bridge_set_chunk_data(const char* const chunkFile); | |||||
| void osc_send_bridge_set_inpeak(const int32_t portId); | |||||
| void osc_send_bridge_set_outpeak(const int32_t portId); | |||||
| #else | |||||
| void osc_send_control_add_plugin_start(const int32_t pluginId, const char* const pluginName); | |||||
| void osc_send_control_add_plugin_end(const int32_t pluginId); | |||||
| void osc_send_control_remove_plugin(const int32_t pluginId); | |||||
| void osc_send_control_set_plugin_data(const int32_t pluginId, const int32_t type, const int32_t category, const int32_t hints, const char* const realName, const char* const label, const char* const maker, const char* const copyright, const int64_t uniqueId); | |||||
| void osc_send_control_set_plugin_ports(const int32_t pluginId, const int32_t audioIns, const int32_t audioOuts, const int32_t midiIns, const int32_t midiOuts, const int32_t cIns, const int32_t cOuts, const int32_t cTotals); | |||||
| void osc_send_control_set_parameter_data(const int32_t pluginId, const int32_t index, const int32_t type, const int32_t hints, const char* const name, const char* const label, const double current); | |||||
| void osc_send_control_set_parameter_ranges(const int32_t pluginId, const int32_t index, const double min, const double max, const double def, const double step, const double stepSmall, const double stepLarge); | |||||
| void osc_send_control_set_parameter_midi_cc(const int32_t pluginId, const int32_t index, const int32_t cc); | |||||
| void osc_send_control_set_parameter_midi_channel(const int32_t pluginId, const int32_t index, const int32_t channel); | |||||
| void osc_send_control_set_parameter_value(const int32_t pluginId, const int32_t index, const double value); | |||||
| void osc_send_control_set_default_value(const int32_t pluginId, const int32_t index, const double value); | |||||
| void osc_send_control_set_program(const int32_t pluginId, const int32_t index); | |||||
| void osc_send_control_set_program_count(const int32_t pluginId, const int32_t count); | |||||
| void osc_send_control_set_program_name(const int32_t pluginId, const int32_t index, const char* const name); | |||||
| void osc_send_control_set_midi_program(const int32_t pluginId, const int32_t index); | |||||
| void osc_send_control_set_midi_program_count(const int32_t pluginId, const int32_t count); | |||||
| void osc_send_control_set_midi_program_data(const int32_t pluginId, const int32_t index, const int32_t bank, const int32_t program, const char* const name); | |||||
| void osc_send_control_note_on(const int32_t pluginId, const int32_t channel, const int32_t note, const int32_t velo); | |||||
| void osc_send_control_note_off(const int32_t pluginId, const int32_t channel, const int32_t note); | |||||
| void osc_send_control_set_input_peak_value(const int32_t pluginId, const int32_t portId); | |||||
| void osc_send_control_set_output_peak_value(const int32_t pluginId, const int32_t portId); | |||||
| void osc_send_control_exit(); | |||||
| #endif | |||||
| #ifndef BUILD_BRIDGE | |||||
| // ------------------------------------------------------------------- | |||||
| // Rack mode | |||||
| static const unsigned short MAX_CONTROL_EVENTS = 512; | |||||
| static const unsigned short MAX_MIDI_EVENTS = 512; | |||||
| CarlaEngineControlEvent rackControlEventsIn[MAX_CONTROL_EVENTS]; | |||||
| CarlaEngineControlEvent rackControlEventsOut[MAX_CONTROL_EVENTS]; | |||||
| CarlaEngineMidiEvent rackMidiEventsIn[MAX_MIDI_EVENTS]; | |||||
| CarlaEngineMidiEvent rackMidiEventsOut[MAX_MIDI_EVENTS]; | |||||
| #endif | |||||
| // ------------------------------------- | |||||
| /*! | |||||
| * \class ScopedLocker | |||||
| * | |||||
| * \brief Carla engine scoped locker | |||||
| * | |||||
| * This is a handy class that temporarily locks an engine during a function scope. | |||||
| */ | |||||
| class ScopedLocker | |||||
| { | |||||
| public: | |||||
| /*! | |||||
| * Lock the engine \a engine if \a lock is true. | |||||
| * The engine is unlocked in the deconstructor of this class if \a lock is true. | |||||
| * | |||||
| * \param engine The engine to lock | |||||
| * \param lock Wherever to lock the engine or not, true by default | |||||
| */ | |||||
| ScopedLocker(CarlaEngine* const engine, bool lock = true) | |||||
| : mutex(&engine->m_procLock), | |||||
| m_lock(lock) | |||||
| { | |||||
| if (m_lock) | |||||
| mutex->lock(); | |||||
| } | |||||
| ~ScopedLocker() | |||||
| { | |||||
| if (m_lock) | |||||
| mutex->unlock(); | |||||
| } | |||||
| private: | |||||
| QMutex* const mutex; | |||||
| const bool m_lock; | |||||
| }; | |||||
| // ------------------------------------- | |||||
| protected: | |||||
| /*! | |||||
| * The contructor, protected.\n | |||||
| * \note This only initializes engine data, it doesn't initialize the engine itself. | |||||
| */ | |||||
| CarlaEngine(); | |||||
| #ifndef BUILD_BRIDGE | |||||
| /*! | |||||
| * Proccess audio buffer in rack mode, protected. | |||||
| */ | |||||
| void processRack(float* inBuf[2], float* outBuf[2], const uint32_t frames); | |||||
| #endif | |||||
| CarlaEngineOptions options; | |||||
| CarlaString name; | |||||
| uint32_t bufferSize; | |||||
| double sampleRate; | |||||
| CarlaEngineTimeInfo timeInfo; | |||||
| void bufferSizeChanged(const uint32_t newBufferSize); | |||||
| private: | |||||
| CarlaEngineOsc m_osc; | |||||
| CarlaEngineThread m_thread; | |||||
| const CarlaOscData* m_oscData; | |||||
| CallbackFunc m_callback; | |||||
| void* m_callbackPtr; | |||||
| CarlaString m_lastError; | |||||
| #ifndef BUILD_BRIDGE | |||||
| QProcessEnvironment m_procEnv; | |||||
| #endif | |||||
| QMutex m_procLock; | |||||
| QMutex m_midiLock; | |||||
| CarlaPlugin* m_carlaPlugins[MAX_PLUGINS]; | |||||
| const char* m_uniqueNames[MAX_PLUGINS]; | |||||
| double m_insPeak[MAX_PLUGINS * MAX_PEAKS]; | |||||
| double m_outsPeak[MAX_PLUGINS * MAX_PEAKS]; | |||||
| bool m_aboutToClose; | |||||
| unsigned short m_maxPluginNumber; | |||||
| #ifdef CARLA_ENGINE_JACK | |||||
| static CarlaEngine* newJack(); | |||||
| #endif | |||||
| #ifdef CARLA_ENGINE_RTAUDIO | |||||
| enum RtAudioApi { | |||||
| RTAUDIO_DUMMY = 0, | |||||
| RTAUDIO_LINUX_ALSA = 1, | |||||
| RTAUDIO_LINUX_PULSE = 2, | |||||
| RTAUDIO_LINUX_OSS = 3, | |||||
| RTAUDIO_UNIX_JACK = 4, | |||||
| RTAUDIO_MACOSX_CORE = 5, | |||||
| RTAUDIO_WINDOWS_ASIO = 6, | |||||
| RTAUDIO_WINDOWS_DS = 7 | |||||
| }; | |||||
| static CarlaEngine* newRtAudio(RtAudioApi api); | |||||
| static unsigned int getRtAudioApiCount(); | |||||
| static const char* getRtAudioApiName(unsigned int index); | |||||
| #endif | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | |||||
| /**@}*/ | |||||
| CARLA_BACKEND_END_NAMESPACE | |||||
| #endif // CARLA_ENGINE_HPP | |||||
| @@ -0,0 +1,88 @@ | |||||
| #!/usr/bin/make -f | |||||
| # Makefile for carla-discovery # | |||||
| # ----------------------------------------- # | |||||
| # Created by falkTX | |||||
| # | |||||
| include ../Makefile.mk | |||||
| # -------------------------------------------------------------- | |||||
| BUILD_CXX_FLAGS += -I../backend -I../includes -I../utils | |||||
| BUILD_CXX_FLAGS += $(shell pkg-config --cflags QtCore) | |||||
| LINK_FLAGS += $(shell pkg-config --libs QtCore) | |||||
| ifeq ($(CARLA_PLUGIN_SUPPORT),true) | |||||
| BUILD_CXX_FLAGS += -DWANT_LADSPA -DWANT_DSSI -DWANT_LV2 -DWANT_VST | |||||
| endif | |||||
| ifeq ($(HAVE_FLUIDSYNTH),true) | |||||
| NATIVE_FLAGS += $(shell pkg-config --cflags --libs fluidsynth) -DWANT_FLUIDSYNTH | |||||
| endif | |||||
| ifeq ($(HAVE_LINUXSAMPLER),true) | |||||
| NATIVE_FLAGS += $(shell pkg-config --cflags --libs linuxsampler) -DWANT_LINUXSAMPLER | |||||
| endif | |||||
| # -------------------------------------------------------------- | |||||
| POSIX_BUILD_FLAGS = $(BUILD_CXX_FLAGS) | |||||
| POSIX_32BIT_FLAGS = $(32BIT_FLAGS) -L/usr/lib32 -L/usr/lib/i386-linux-gnu | |||||
| POSIX_64BIT_FLAGS = $(64BIT_FLAGS) -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu | |||||
| POSIX_LINK_FLAGS = $(LINK_FLAGS) -ldl | |||||
| #-lpthread | |||||
| WIN_BUILD_FLAGS = $(BUILD_CXX_FLAGS) | |||||
| WIN_32BIT_FLAGS = $(32BIT_FLAGS) | |||||
| WIN_64BIT_FLAGS = $(64BIT_FLAGS) | |||||
| WIN_LINK_FLAGS = $(LINK_FLAGS) -static -mwindows -lole32 -luuid -lws2_32 | |||||
| # -------------------------------------------------------------- | |||||
| all: carla-discovery-native | |||||
| posix32: carla-discovery-posix32 | |||||
| posix64: carla-discovery-posix64 | |||||
| win32: carla-discovery-win32.exe | |||||
| win64: carla-discovery-win64.exe | |||||
| # -------------------------------------------------------------- | |||||
| OBJS = carla-discovery.cpp | |||||
| carla-discovery-native: $(OBJS) ../libs/lilv.a | |||||
| $(CXX) $^ $(POSIX_BUILD_FLAGS) $(POSIX_LINK_FLAGS) $(NATIVE_FLAGS) -o $@ && $(STRIP) $@ | |||||
| carla-discovery-posix32: $(OBJS) ../libs/lilv_posix32.a | |||||
| $(CXX) $^ $(POSIX_BUILD_FLAGS) $(POSIX_32BIT_FLAGS) $(POSIX_LINK_FLAGS) -o $@ && $(STRIP) $@ | |||||
| carla-discovery-posix64: $(OBJS) ../libs/lilv_posix64.a | |||||
| $(CXX) $^ $(POSIX_BUILD_FLAGS) $(POSIX_64BIT_FLAGS) $(POSIX_LINK_FLAGS) -o $@ && $(STRIP) $@ | |||||
| carla-discovery-win32.exe: $(OBJS) ../libs/lilv_win32.a | |||||
| $(CXX) $^ $(WIN_BUILD_FLAGS) $(WIN_32BIT_FLAGS) $(WIN_LINK_FLAGS) -o $@ && $(STRIP) $@ | |||||
| carla-discovery-win64.exe: $(OBJS) ../libs/lilv_win64.a | |||||
| $(CXX) $^ $(WIN_BUILD_FLAGS) $(WIN_64BIT_FLAGS) $(WIN_LINK_FLAGS) -o $@ && $(STRIP) $@ | |||||
| # -------------------------------------------------------------- | |||||
| ../libs/lilv.a: | |||||
| $(MAKE) -C ../libs/lilv | |||||
| ../libs/lilv_posix32.a: | |||||
| $(MAKE) -C ../libs/lilv posix32 | |||||
| ../libs/lilv_posix64.a: | |||||
| $(MAKE) -C ../libs/lilv posix64 | |||||
| ../libs/lilv_win32.a: | |||||
| $(MAKE) -C ../libs/lilv win32 | |||||
| ../libs/lilv_win64.a: | |||||
| $(MAKE) -C ../libs/lilv win64 | |||||
| # -------------------------------------------------------------- | |||||
| clean: | |||||
| rm -f carla-discovery-* | |||||
| @@ -0,0 +1,51 @@ | |||||
| # QtCreator project file | |||||
| QT = core | |||||
| win { | |||||
| CONFIG = release | |||||
| } else { | |||||
| CONFIG = debug | |||||
| } | |||||
| CONFIG += link_pkgconfig qt warn_on | |||||
| DEFINES = DEBUG | |||||
| DEFINES += WANT_LADSPA WANT_DSSI WANT_LV2 WANT_VST | |||||
| DEFINES += WANT_FLUIDSYNTH WANT_LINUXSAMPLER | |||||
| PKGCONFIG = fluidsynth linuxsampler | |||||
| TARGET = carla-discovery-qtcreator | |||||
| TEMPLATE = app | |||||
| VERSION = 0.5.0 | |||||
| SOURCES = \ | |||||
| carla-discovery.cpp | |||||
| HEADERS = \ | |||||
| ../includes/carla_defines.hpp \ | |||||
| ../includes/carla_midi.h \ | |||||
| ../includes/ladspa_rdf.hpp \ | |||||
| ../includes/lv2_rdf.hpp \ | |||||
| ../backend/carla_backend.hpp \ | |||||
| ../utils/carla_utils.hpp \ | |||||
| ../utils/carla_lib_utils.hpp \ | |||||
| ../utils/carla_ladspa_utils.hpp \ | |||||
| ../utils/carla_lv2_utils.hpp \ | |||||
| ../utils/carla_vst_utils.hpp | |||||
| INCLUDEPATH = \ | |||||
| ../backend \ | |||||
| ../includes \ | |||||
| ../utils | |||||
| LIBS = \ | |||||
| ../libs/lilv.a | |||||
| unix { | |||||
| LIBS += -ldl | |||||
| } | |||||
| mingw { | |||||
| LIBS += -static -mwindows | |||||
| } | |||||
| QMAKE_CXXFLAGS *= -std=c++0x | |||||
| @@ -0,0 +1,192 @@ | |||||
| /* | |||||
| * Simple Queue, specially developed for Atom types | |||||
| * 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 __LV2_ATOM_QUEUE_HPP__ | |||||
| #define __LV2_ATOM_QUEUE_HPP__ | |||||
| #include "carla_utils.hpp" | |||||
| #include "lv2/atom.h" | |||||
| #include <cstring> // memcpy, memset | |||||
| #include <pthread.h> | |||||
| class Lv2AtomQueue | |||||
| { | |||||
| public: | |||||
| Lv2AtomQueue() | |||||
| : mutex(PTHREAD_MUTEX_INITIALIZER) | |||||
| { | |||||
| index = indexPool = 0; | |||||
| empty = true; | |||||
| full = false; | |||||
| ::memset(dataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE); | |||||
| } | |||||
| void copyDataFrom(Lv2AtomQueue* const queue) | |||||
| { | |||||
| // lock mutexes | |||||
| queue->lock(); | |||||
| lock(); | |||||
| // copy data from queue | |||||
| ::memcpy(data, queue->data, sizeof(datatype)*MAX_SIZE); | |||||
| ::memcpy(dataPool, queue->dataPool, sizeof(unsigned char)*MAX_POOL_SIZE); | |||||
| index = queue->index; | |||||
| indexPool = queue->indexPool; | |||||
| empty = queue->empty; | |||||
| full = queue->full; | |||||
| // unlock our mutex, no longer needed | |||||
| unlock(); | |||||
| // reset queque | |||||
| ::memset(queue->data, 0, sizeof(datatype)*MAX_SIZE); | |||||
| ::memset(queue->dataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE); | |||||
| queue->index = queue->indexPool = 0; | |||||
| queue->empty = true; | |||||
| queue->full = false; | |||||
| // unlock queque mutex | |||||
| queue->unlock(); | |||||
| } | |||||
| bool isEmpty() | |||||
| { | |||||
| return empty; | |||||
| } | |||||
| bool isFull() | |||||
| { | |||||
| return full; | |||||
| } | |||||
| bool lock() | |||||
| { | |||||
| return (pthread_mutex_lock(&mutex) == 0); | |||||
| } | |||||
| bool tryLock() | |||||
| { | |||||
| return (pthread_mutex_trylock(&mutex) == 0); | |||||
| } | |||||
| bool unlock() | |||||
| { | |||||
| return (pthread_mutex_unlock(&mutex) == 0); | |||||
| } | |||||
| void put(const uint32_t portIndex, const LV2_Atom* const atom) | |||||
| { | |||||
| CARLA_ASSERT(atom && atom->size > 0); | |||||
| CARLA_ASSERT(indexPool + atom->size < MAX_POOL_SIZE); // overflow | |||||
| if (full || atom->size == 0 || indexPool + atom->size >= MAX_POOL_SIZE) | |||||
| return; | |||||
| lock(); | |||||
| for (unsigned short i=0; i < MAX_SIZE; i++) | |||||
| { | |||||
| if (data[i].size == 0) | |||||
| { | |||||
| data[i].portIndex = portIndex; | |||||
| data[i].size = atom->size; | |||||
| data[i].type = atom->type; | |||||
| data[i].poolOffset = indexPool; | |||||
| ::memcpy(dataPool + indexPool, (const unsigned char*)LV2_ATOM_BODY_CONST(atom), atom->size); | |||||
| empty = false; | |||||
| full = (i == MAX_SIZE-1); | |||||
| indexPool += atom->size; | |||||
| break; | |||||
| } | |||||
| } | |||||
| unlock(); | |||||
| } | |||||
| bool get(uint32_t* const portIndex, const LV2_Atom** const atom) | |||||
| { | |||||
| CARLA_ASSERT(portIndex && atom); | |||||
| if (empty || ! (portIndex && atom)) | |||||
| return false; | |||||
| if (! tryLock()) | |||||
| return false; | |||||
| full = false; | |||||
| if (data[index].size == 0) | |||||
| { | |||||
| index = indexPool = 0; | |||||
| empty = true; | |||||
| unlock(); | |||||
| return false; | |||||
| } | |||||
| retAtom.atom.size = data[index].size; | |||||
| retAtom.atom.type = data[index].type; | |||||
| ::memcpy(retAtom.data, dataPool + data[index].poolOffset, data[index].size); | |||||
| *portIndex = data[index].portIndex; | |||||
| *atom = (LV2_Atom*)&retAtom; | |||||
| data[index].portIndex = 0; | |||||
| data[index].size = 0; | |||||
| data[index].type = 0; | |||||
| data[index].poolOffset = 0; | |||||
| index++; | |||||
| empty = false; | |||||
| unlock(); | |||||
| return true; | |||||
| } | |||||
| private: | |||||
| struct datatype { | |||||
| size_t size; | |||||
| uint32_t type; | |||||
| uint32_t portIndex; | |||||
| uint32_t poolOffset; | |||||
| datatype() | |||||
| : size(0), | |||||
| type(0), | |||||
| portIndex(0), | |||||
| poolOffset(0) {} | |||||
| }; | |||||
| static const unsigned short MAX_SIZE = 128; | |||||
| static const unsigned short MAX_POOL_SIZE = 8192; | |||||
| datatype data[MAX_SIZE]; | |||||
| unsigned char dataPool[MAX_POOL_SIZE]; | |||||
| struct { | |||||
| LV2_Atom atom; | |||||
| unsigned char data[MAX_POOL_SIZE]; | |||||
| } retAtom; | |||||
| unsigned short index, indexPool; | |||||
| bool empty, full; | |||||
| pthread_mutex_t mutex; | |||||
| }; | |||||
| #endif // __LV2_ATOM_QUEUE_HPP__ | |||||
| @@ -0,0 +1,567 @@ | |||||
| /* | |||||
| * Custom types to store LV2 information | |||||
| * Copyright (C) 2011-2013 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 LV2_RDF_INCLUDED | |||||
| #define LV2_RDF_INCLUDED | |||||
| #include <cstdint> | |||||
| #include <cstdlib> | |||||
| // Base Types | |||||
| typedef const char* LV2_URI; | |||||
| typedef uint32_t LV2_Property; | |||||
| struct LV2_Type { | |||||
| LV2_Property Value; | |||||
| LV2_URI URI; | |||||
| LV2_Type() | |||||
| : Value(0), | |||||
| URI(nullptr) {} | |||||
| ~LV2_Type() | |||||
| { | |||||
| if (URI) | |||||
| ::free((void*)URI); | |||||
| } | |||||
| }; | |||||
| // Port Midi Map Types | |||||
| #define LV2_PORT_MIDI_MAP_CC 0x1 | |||||
| #define LV2_PORT_MIDI_MAP_NRPN 0x2 | |||||
| #define LV2_IS_PORT_MIDI_MAP_CC(x) ((x) == LV2_PORT_MIDI_MAP_CC) | |||||
| #define LV2_IS_PORT_MIDI_MAP_NRPN(x) ((x) == LV2_PORT_MIDI_MAP_NRPN) | |||||
| // Port Point Hints | |||||
| #define LV2_PORT_POINT_DEFAULT 0x1 | |||||
| #define LV2_PORT_POINT_MINIMUM 0x2 | |||||
| #define LV2_PORT_POINT_MAXIMUM 0x4 | |||||
| #define LV2_HAVE_DEFAULT_PORT_POINT(x) ((x) & LV2_PORT_POINT_DEFAULT) | |||||
| #define LV2_HAVE_MINIMUM_PORT_POINT(x) ((x) & LV2_PORT_POINT_MINIMUM) | |||||
| #define LV2_HAVE_MAXIMUM_PORT_POINT(x) ((x) & LV2_PORT_POINT_MAXIMUM) | |||||
| // Port Unit Hints | |||||
| #define LV2_PORT_UNIT_NAME 0x1 | |||||
| #define LV2_PORT_UNIT_RENDER 0x2 | |||||
| #define LV2_PORT_UNIT_SYMBOL 0x4 | |||||
| #define LV2_PORT_UNIT_UNIT 0x8 | |||||
| #define LV2_HAVE_PORT_UNIT_NAME(x) ((x) & LV2_PORT_UNIT_NAME) | |||||
| #define LV2_HAVE_PORT_UNIT_RENDER(x) ((x) & LV2_PORT_UNIT_RENDER) | |||||
| #define LV2_HAVE_PORT_UNIT_SYMBOL(x) ((x) & LV2_PORT_UNIT_SYMBOL) | |||||
| #define LV2_HAVE_PORT_UNIT_UNIT(x) ((x) & LV2_PORT_UNIT_UNIT) | |||||
| // Port Unit Unit | |||||
| #define LV2_PORT_UNIT_BAR 0x01 | |||||
| #define LV2_PORT_UNIT_BEAT 0x02 | |||||
| #define LV2_PORT_UNIT_BPM 0x03 | |||||
| #define LV2_PORT_UNIT_CENT 0x04 | |||||
| #define LV2_PORT_UNIT_CM 0x05 | |||||
| #define LV2_PORT_UNIT_COEF 0x06 | |||||
| #define LV2_PORT_UNIT_DB 0x07 | |||||
| #define LV2_PORT_UNIT_DEGREE 0x08 | |||||
| #define LV2_PORT_UNIT_FRAME 0x09 | |||||
| #define LV2_PORT_UNIT_HZ 0x0A | |||||
| #define LV2_PORT_UNIT_INCH 0x0B | |||||
| #define LV2_PORT_UNIT_KHZ 0x0C | |||||
| #define LV2_PORT_UNIT_KM 0x0D | |||||
| #define LV2_PORT_UNIT_M 0x0E | |||||
| #define LV2_PORT_UNIT_MHZ 0x0F | |||||
| #define LV2_PORT_UNIT_MIDINOTE 0x10 | |||||
| #define LV2_PORT_UNIT_MILE 0x11 | |||||
| #define LV2_PORT_UNIT_MIN 0x12 | |||||
| #define LV2_PORT_UNIT_MM 0x13 | |||||
| #define LV2_PORT_UNIT_MS 0x14 | |||||
| #define LV2_PORT_UNIT_OCT 0x15 | |||||
| #define LV2_PORT_UNIT_PC 0x16 | |||||
| #define LV2_PORT_UNIT_S 0x17 | |||||
| #define LV2_PORT_UNIT_SEMITONE 0x18 | |||||
| #define LV2_IS_PORT_UNIT_BAR(x) ((x) == LV2_PORT_UNIT_BAR) | |||||
| #define LV2_IS_PORT_UNIT_BEAT(x) ((x) == LV2_PORT_UNIT_BEAT) | |||||
| #define LV2_IS_PORT_UNIT_BPM(x) ((x) == LV2_PORT_UNIT_BPM) | |||||
| #define LV2_IS_PORT_UNIT_CENT(x) ((x) == LV2_PORT_UNIT_CENT) | |||||
| #define LV2_IS_PORT_UNIT_CM(x) ((x) == LV2_PORT_UNIT_CM) | |||||
| #define LV2_IS_PORT_UNIT_COEF(x) ((x) == LV2_PORT_UNIT_COEF) | |||||
| #define LV2_IS_PORT_UNIT_DB(x) ((x) == LV2_PORT_UNIT_DB) | |||||
| #define LV2_IS_PORT_UNIT_DEGREE(x) ((x) == LV2_PORT_UNIT_DEGREE) | |||||
| #define LV2_IS_PORT_UNIT_FRAME(x) ((x) == LV2_PORT_UNIT_FRAME) | |||||
| #define LV2_IS_PORT_UNIT_HZ(x) ((x) == LV2_PORT_UNIT_HZ) | |||||
| #define LV2_IS_PORT_UNIT_INCH(x) ((x) == LV2_PORT_UNIT_INCH) | |||||
| #define LV2_IS_PORT_UNIT_KHZ(x) ((x) == LV2_PORT_UNIT_KHZ) | |||||
| #define LV2_IS_PORT_UNIT_KM(x) ((x) == LV2_PORT_UNIT_KM) | |||||
| #define LV2_IS_PORT_UNIT_M(x) ((x) == LV2_PORT_UNIT_M) | |||||
| #define LV2_IS_PORT_UNIT_MHZ(x) ((x) == LV2_PORT_UNIT_MHZ) | |||||
| #define LV2_IS_PORT_UNIT_MIDINOTE(x) ((x) == LV2_PORT_UNIT_MIDINOTE) | |||||
| #define LV2_IS_PORT_UNIT_MILE(x) ((x) == LV2_PORT_UNIT_MILE) | |||||
| #define LV2_IS_PORT_UNIT_MIN(x) ((x) == LV2_PORT_UNIT_MIN) | |||||
| #define LV2_IS_PORT_UNIT_MM(x) ((x) == LV2_PORT_UNIT_MM) | |||||
| #define LV2_IS_PORT_UNIT_MS(x) ((x) == LV2_PORT_UNIT_MS) | |||||
| #define LV2_IS_PORT_UNIT_OCT(x) ((x) == LV2_PORT_UNIT_OCT) | |||||
| #define LV2_IS_PORT_UNIT_PC(x) ((x) == LV2_PORT_UNIT_PC) | |||||
| #define LV2_IS_PORT_UNIT_S(x) ((x) == LV2_PORT_UNIT_S) | |||||
| #define LV2_IS_PORT_UNIT_SEMITONE(x) ((x) == LV2_PORT_UNIT_SEMITONE) | |||||
| // Port Types | |||||
| #define LV2_PORT_INPUT 0x01 | |||||
| #define LV2_PORT_OUTPUT 0x02 | |||||
| #define LV2_PORT_CONTROL 0x04 | |||||
| #define LV2_PORT_AUDIO 0x08 | |||||
| #define LV2_PORT_CV 0x10 | |||||
| #define LV2_PORT_ATOM 0x20 | |||||
| #define LV2_PORT_ATOM_SEQUENCE (0x40 | LV2_PORT_ATOM) | |||||
| #define LV2_PORT_EVENT 0x80 | |||||
| #define LV2_PORT_MIDI_LL 0x100 | |||||
| // Port Data Types | |||||
| #define LV2_PORT_DATA_MIDI_EVENT 0x1000 | |||||
| #define LV2_PORT_DATA_PATCH_MESSAGE 0x2000 | |||||
| #define LV2_IS_PORT_INPUT(x) ((x) & LV2_PORT_INPUT) | |||||
| #define LV2_IS_PORT_OUTPUT(x) ((x) & LV2_PORT_OUTPUT) | |||||
| #define LV2_IS_PORT_CONTROL(x) ((x) & LV2_PORT_CONTROL) | |||||
| #define LV2_IS_PORT_AUDIO(x) ((x) & LV2_PORT_AUDIO) | |||||
| #define LV2_IS_PORT_ATOM_SEQUENCE(x) ((x) & LV2_PORT_ATOM_SEQUENCE) | |||||
| #define LV2_IS_PORT_CV(x) ((x) & LV2_PORT_CV) | |||||
| #define LV2_IS_PORT_EVENT(x) ((x) & LV2_PORT_EVENT) | |||||
| #define LV2_IS_PORT_MIDI_LL(x) ((x) & LV2_PORT_MIDI_LL) | |||||
| #define LV2_PORT_SUPPORTS_MIDI_EVENT ((x) & LV2_PORT_DATA_MIDI_EVENT) | |||||
| #define LV2_PORT_SUPPORTS_PATCH_MESSAGE ((x) & LV2_PORT_DATA_PATCH_MESSAGE) | |||||
| // Port Properties | |||||
| #define LV2_PORT_OPTIONAL 0x0001 | |||||
| #define LV2_PORT_ENUMERATION 0x0002 | |||||
| #define LV2_PORT_INTEGER 0x0004 | |||||
| #define LV2_PORT_SAMPLE_RATE 0x0008 | |||||
| #define LV2_PORT_TOGGLED 0x0010 | |||||
| #define LV2_PORT_CAUSES_ARTIFACTS 0x0020 | |||||
| #define LV2_PORT_CONTINUOUS_CV 0x0040 | |||||
| #define LV2_PORT_DISCRETE_CV 0x0080 | |||||
| #define LV2_PORT_EXPENSIVE 0x0100 | |||||
| #define LV2_PORT_STRICT_BOUNDS 0x0200 | |||||
| #define LV2_PORT_LOGARITHMIC 0x0400 | |||||
| #define LV2_PORT_NOT_AUTOMATIC 0x0800 | |||||
| #define LV2_PORT_NOT_ON_GUI 0x1000 | |||||
| #define LV2_PORT_TRIGGER 0x2000 | |||||
| #define LV2_IS_PORT_OPTIONAL(x) ((x) & LV2_PORT_OPTIONAL) | |||||
| #define LV2_IS_PORT_ENUMERATION(x) ((x) & LV2_PORT_ENUMERATION) | |||||
| #define LV2_IS_PORT_INTEGER(x) ((x) & LV2_PORT_INTEGER) | |||||
| #define LV2_IS_PORT_SAMPLE_RATE(x) ((x) & LV2_PORT_SAMPLE_RATE) | |||||
| #define LV2_IS_PORT_TOGGLED(x) ((x) & LV2_PORT_TOGGLED) | |||||
| #define LV2_IS_PORT_CAUSES_ARTIFACTS(x) ((x) & LV2_PORT_CAUSES_ARTIFACTS) | |||||
| #define LV2_IS_PORT_CONTINUOUS_CV(x) ((x) & LV2_PORT_CONTINUOUS_CV) | |||||
| #define LV2_IS_PORT_DISCRETE_CV(x) ((x) & LV2_PORT_DISCRETE_CV) | |||||
| #define LV2_IS_PORT_EXPENSIVE(x) ((x) & LV2_PORT_EXPENSIVE) | |||||
| #define LV2_IS_PORT_STRICT_BOUNDS(x) ((x) & LV2_PORT_STRICT_BOUNDS) | |||||
| #define LV2_IS_PORT_LOGARITHMIC(x) ((x) & LV2_PORT_LOGARITHMIC) | |||||
| #define LV2_IS_PORT_NOT_AUTOMATIC(x) ((x) & LV2_PORT_NOT_AUTOMATIC) | |||||
| #define LV2_IS_PORT_NOT_ON_GUI(x) ((x) & LV2_PORT_NOT_ON_GUI) | |||||
| #define LV2_IS_PORT_TRIGGER(x) ((x) & LV2_PORT_TRIGGER) | |||||
| // Port Designation | |||||
| #define LV2_PORT_DESIGNATION_FREEWHEELING 0x1 | |||||
| #define LV2_PORT_DESIGNATION_LATENCY 0x2 | |||||
| #define LV2_PORT_DESIGNATION_SAMPLE_RATE 0x3 | |||||
| #define LV2_PORT_DESIGNATION_TIME_BAR 0x4 | |||||
| #define LV2_PORT_DESIGNATION_TIME_BAR_BEAT 0x5 | |||||
| #define LV2_PORT_DESIGNATION_TIME_BEAT 0x6 | |||||
| #define LV2_PORT_DESIGNATION_TIME_BEAT_UNIT 0x7 | |||||
| #define LV2_PORT_DESIGNATION_TIME_BEATS_PER_BAR 0x8 | |||||
| #define LV2_PORT_DESIGNATION_TIME_BEATS_PER_MINUTE 0x9 | |||||
| #define LV2_PORT_DESIGNATION_TIME_FRAME 0xA | |||||
| #define LV2_PORT_DESIGNATION_TIME_FRAMES_PER_SECOND 0xB | |||||
| #define LV2_PORT_DESIGNATION_TIME_POSITION 0xC | |||||
| #define LV2_PORT_DESIGNATION_TIME_SPEED 0xD | |||||
| #define LV2_IS_PORT_DESIGNATION_FREEWHEELING(x) ((x) == LV2_PORT_DESIGNATION_FREEWHEELING) | |||||
| #define LV2_IS_PORT_DESIGNATION_LATENCY(x) ((x) == LV2_PORT_DESIGNATION_LATENCY) | |||||
| #define LV2_IS_PORT_DESIGNATION_SAMPLE_RATE(x) ((x) == LV2_PORT_DESIGNATION_SAMPLE_RATE) | |||||
| #define LV2_IS_PORT_DESIGNATION_TIME_BAR(x) ((x) == LV2_PORT_DESIGNATION_TIME_BAR) | |||||
| #define LV2_IS_PORT_DESIGNATION_TIME_BAR_BEAT(x) ((x) == LV2_PORT_DESIGNATION_TIME_BAR_BEAT) | |||||
| #define LV2_IS_PORT_DESIGNATION_TIME_BEAT(x) ((x) == LV2_PORT_DESIGNATION_TIME_BEAT) | |||||
| #define LV2_IS_PORT_DESIGNATION_TIME_BEAT_UNIT(x) ((x) == LV2_PORT_DESIGNATION_TIME_BEAT_UNIT) | |||||
| #define LV2_IS_PORT_DESIGNATION_TIME_BEATS_PER_BAR(x) ((x) == LV2_PORT_DESIGNATION_TIME_BEATS_PER_BAR) | |||||
| #define LV2_IS_PORT_DESIGNATION_TIME_BEATS_PER_MINUTE(x) ((x) == LV2_PORT_DESIGNATION_TIME_BEATS_PER_MINUTE) | |||||
| #define LV2_IS_PORT_DESIGNATION_TIME_FRAME(x) ((x) == LV2_PORT_DESIGNATION_TIME_FRAME) | |||||
| #define LV2_IS_PORT_DESIGNATION_TIME_FRAMES_PER_SECOND(x) ((x) == LV2_PORT_DESIGNATION_TIME_FRAMES_PER_SECOND) | |||||
| #define LV2_IS_PORT_DESIGNATION_TIME_POSITION(x) ((x) == LV2_PORT_DESIGNATION_TIME_POSITION) | |||||
| #define LV2_IS_PORT_DESIGNATION_TIME_SPEED(x) ((x) == LV2_PORT_DESIGNATION_TIME_SPEED) | |||||
| #define LV2_IS_PORT_DESIGNATION_TIME(x) ((x) >= LV2_PORT_DESIGNATION_TIME_BAR && (x) <= LV2_PORT_DESIGNATION_TIME_SPEED) | |||||
| // Feature Types | |||||
| #define LV2_FEATURE_OPTIONAL 0x1 | |||||
| #define LV2_FEATURE_REQUIRED 0x2 | |||||
| #define LV2_IS_FEATURE_OPTIONAL(x) ((x) == LV2_FEATURE_OPTIONAL) | |||||
| #define LV2_IS_FEATURE_REQUIRED(x) ((x) == LV2_FEATURE_REQUIRED) | |||||
| // UI Types | |||||
| #define LV2_UI_GTK2 0x1 | |||||
| #define LV2_UI_GTK3 0x2 | |||||
| #define LV2_UI_QT4 0x3 | |||||
| #define LV2_UI_QT5 0x4 | |||||
| #define LV2_UI_COCOA 0x5 | |||||
| #define LV2_UI_WINDOWS 0x6 | |||||
| #define LV2_UI_X11 0x7 | |||||
| #define LV2_UI_EXTERNAL 0x8 | |||||
| #define LV2_UI_OLD_EXTERNAL 0x9 | |||||
| #define LV2_IS_UI_GTK2(x) ((x) == LV2_UI_GTK2) | |||||
| #define LV2_IS_UI_GTK3(x) ((x) == LV2_UI_GTK3) | |||||
| #define LV2_IS_UI_QT4(x) ((x) == LV2_UI_QT4) | |||||
| #define LV2_IS_UI_QT5(x) ((x) == LV2_UI_QT5) | |||||
| #define LV2_IS_UI_COCOA(x) ((x) == LV2_UI_COCOA) | |||||
| #define LV2_IS_UI_WINDOWS(x) ((x) == LV2_UI_WINDOWS) | |||||
| #define LV2_IS_UI_X11(x) ((x) == LV2_UI_X11) | |||||
| #define LV2_IS_UI_EXTERNAL(x) ((x) == LV2_UI_EXTERNAL) | |||||
| #define LV2_IS_UI_OLD_EXTERNAL(x) ((x) == LV2_UI_OLD_EXTERNAL) | |||||
| // Plugin Types | |||||
| #define LV2_PLUGIN_DELAY 0x000001 | |||||
| #define LV2_PLUGIN_REVERB 0x000002 | |||||
| #define LV2_PLUGIN_SIMULATOR 0x000004 | |||||
| #define LV2_PLUGIN_DISTORTION 0x000008 | |||||
| #define LV2_PLUGIN_WAVESHAPER 0x000010 | |||||
| #define LV2_PLUGIN_DYNAMICS 0x000020 | |||||
| #define LV2_PLUGIN_AMPLIFIER 0x000040 | |||||
| #define LV2_PLUGIN_COMPRESSOR 0x000080 | |||||
| #define LV2_PLUGIN_ENVELOPE 0x000100 | |||||
| #define LV2_PLUGIN_EXPANDER 0x000200 | |||||
| #define LV2_PLUGIN_GATE 0x000400 | |||||
| #define LV2_PLUGIN_LIMITER 0x000800 | |||||
| #define LV2_PLUGIN_EQ 0x001000 | |||||
| #define LV2_PLUGIN_MULTI_EQ 0x002000 | |||||
| #define LV2_PLUGIN_PARA_EQ 0x004000 | |||||
| #define LV2_PLUGIN_FILTER 0x008000 | |||||
| #define LV2_PLUGIN_ALLPASS 0x010000 | |||||
| #define LV2_PLUGIN_BANDPASS 0x020000 | |||||
| #define LV2_PLUGIN_COMB 0x040000 | |||||
| #define LV2_PLUGIN_HIGHPASS 0x080000 | |||||
| #define LV2_PLUGIN_LOWPASS 0x100000 | |||||
| #define LV2_PLUGIN_GENERATOR 0x000001 | |||||
| #define LV2_PLUGIN_CONSTANT 0x000002 | |||||
| #define LV2_PLUGIN_INSTRUMENT 0x000004 | |||||
| #define LV2_PLUGIN_OSCILLATOR 0x000008 | |||||
| #define LV2_PLUGIN_MODULATOR 0x000010 | |||||
| #define LV2_PLUGIN_CHORUS 0x000020 | |||||
| #define LV2_PLUGIN_FLANGER 0x000040 | |||||
| #define LV2_PLUGIN_PHASER 0x000080 | |||||
| #define LV2_PLUGIN_SPATIAL 0x000100 | |||||
| #define LV2_PLUGIN_SPECTRAL 0x000200 | |||||
| #define LV2_PLUGIN_PITCH 0x000400 | |||||
| #define LV2_PLUGIN_UTILITY 0x000800 | |||||
| #define LV2_PLUGIN_ANALYSER 0x001000 | |||||
| #define LV2_PLUGIN_CONVERTER 0x002000 | |||||
| #define LV2_PLUGIN_FUNCTION 0x008000 | |||||
| #define LV2_PLUGIN_MIXER 0x010000 | |||||
| #define LV2_GROUP_DELAY (LV2_PLUGIN_DELAY|LV2_PLUGIN_REVERB) | |||||
| #define LV2_GROUP_DISTORTION (LV2_PLUGIN_DISTORTION|LV2_PLUGIN_WAVESHAPER) | |||||
| #define LV2_GROUP_DYNAMICS (LV2_PLUGIN_DYNAMICS|LV2_PLUGIN_AMPLIFIER|LV2_PLUGIN_COMPRESSOR|LV2_PLUGIN_ENVELOPE|LV2_PLUGIN_EXPANDER|LV2_PLUGIN_GATE|LV2_PLUGIN_LIMITER) | |||||
| #define LV2_GROUP_EQ (LV2_PLUGIN_EQ|LV2_PLUGIN_MULTI_EQ|LV2_PLUGIN_PARA_EQ) | |||||
| #define LV2_GROUP_FILTER (LV2_PLUGIN_FILTER|LV2_PLUGIN_ALLPASS|LV2_PLUGIN_BANDPASS|LV2_PLUGIN_COMB|LV2_GROUP_EQ|LV2_PLUGIN_HIGHPASS|LV2_PLUGIN_LOWPASS) | |||||
| #define LV2_GROUP_GENERATOR (LV2_PLUGIN_GENERATOR|LV2_PLUGIN_CONSTANT|LV2_PLUGIN_INSTRUMENT|LV2_PLUGIN_OSCILLATOR) | |||||
| #define LV2_GROUP_MODULATOR (LV2_PLUGIN_MODULATOR|LV2_PLUGIN_CHORUS|LV2_PLUGIN_FLANGER|LV2_PLUGIN_PHASER) | |||||
| #define LV2_GROUP_REVERB (LV2_PLUGIN_REVERB) | |||||
| #define LV2_GROUP_SIMULATOR (LV2_PLUGIN_SIMULATOR|LV2_PLUGIN_REVERB) | |||||
| #define LV2_GROUP_SPATIAL (LV2_PLUGIN_SPATIAL) | |||||
| #define LV2_GROUP_SPECTRAL (LV2_PLUGIN_SPECTRAL|LV2_PLUGIN_PITCH) | |||||
| #define LV2_GROUP_UTILITY (LV2_PLUGIN_UTILITY|LV2_PLUGIN_ANALYSER|LV2_PLUGIN_CONVERTER|LV2_PLUGIN_FUNCTION|LV2_PLUGIN_MIXER) | |||||
| #define LV2_IS_DELAY(x, y) (((x) & LV2_GROUP_DELAY) || ((y) & LV2_GROUP_DELAY)) | |||||
| #define LV2_IS_DISTORTION(x, y) (((x) & LV2_GROUP_DISTORTION) || ((y) & LV2_GROUP_DISTORTION)) | |||||
| #define LV2_IS_DYNAMICS(x, y) (((x) & LV2_GROUP_DYNAMICS) || ((y) & LV2_GROUP_DYNAMICS)) | |||||
| #define LV2_IS_EQ(x, y) (((x) & LV2_GROUP_EQ) || ((y) & LV2_GROUP_EQ)) | |||||
| #define LV2_IS_FILTER(x, y) (((x) & LV2_GROUP_FILTER) || ((y) & LV2_GROUP_FILTER)) | |||||
| #define LV2_IS_GENERATOR(x, y) (((x) & LV2_GROUP_GENERATOR) || ((y) & LV2_GROUP_GENERATOR)) | |||||
| #define LV2_IS_MODULATOR(x, y) (((x) & LV2_GROUP_MODULATOR) || ((y) & LV2_GROUP_MODULATOR)) | |||||
| #define LV2_IS_REVERB(x, y) (((x) & LV2_GROUP_REVERB) || ((y) & LV2_GROUP_REVERB)) | |||||
| #define LV2_IS_SIMULATOR(x, y) (((x) & LV2_GROUP_SIMULATOR) || ((y) & LV2_GROUP_SIMULATOR)) | |||||
| #define LV2_IS_SPATIAL(x, y) (((x) & LV2_GROUP_SPATIAL) || ((y) & LV2_GROUP_SPATIAL)) | |||||
| #define LV2_IS_SPECTRAL(x, y) (((x) & LV2_GROUP_SPECTRAL) || ((y) & LV2_GROUP_SPECTRAL)) | |||||
| #define LV2_IS_UTILITY(x, y) (((x) & LV2_GROUP_UTILITY) || ((y) & LV2_GROUP_UTILITY)) | |||||
| // Port Midi Map | |||||
| struct LV2_RDF_PortMidiMap { | |||||
| LV2_Property Type; | |||||
| uint32_t Number; | |||||
| LV2_RDF_PortMidiMap() | |||||
| : Type(0), | |||||
| Number(0) {} | |||||
| }; | |||||
| // Port Points | |||||
| struct LV2_RDF_PortPoints { | |||||
| LV2_Property Hints; | |||||
| float Default; | |||||
| float Minimum; | |||||
| float Maximum; | |||||
| LV2_RDF_PortPoints() | |||||
| : Hints(0x0), | |||||
| Default(0.0f), | |||||
| Minimum(0.0f), | |||||
| Maximum(1.0f) {} | |||||
| }; | |||||
| // Port Unit | |||||
| struct LV2_RDF_PortUnit { | |||||
| LV2_Property Hints; | |||||
| const char* Name; | |||||
| const char* Render; | |||||
| const char* Symbol; | |||||
| LV2_Property Unit; | |||||
| LV2_RDF_PortUnit() | |||||
| : Hints(0x0), | |||||
| Name(nullptr), | |||||
| Render(nullptr), | |||||
| Symbol(nullptr), | |||||
| Unit(0) {} | |||||
| ~LV2_RDF_PortUnit() | |||||
| { | |||||
| if (Name) | |||||
| ::free((void*)Name); | |||||
| if (Render) | |||||
| ::free((void*)Render); | |||||
| if (Symbol) | |||||
| ::free((void*)Symbol); | |||||
| } | |||||
| }; | |||||
| // Port Scale Point | |||||
| struct LV2_RDF_PortScalePoint { | |||||
| const char* Label; | |||||
| float Value; | |||||
| LV2_RDF_PortScalePoint() | |||||
| : Label(nullptr), | |||||
| Value(0.0f) {} | |||||
| ~LV2_RDF_PortScalePoint() | |||||
| { | |||||
| if (Label) | |||||
| ::free((void*)Label); | |||||
| } | |||||
| }; | |||||
| // Port | |||||
| struct LV2_RDF_Port { | |||||
| LV2_Property Types; | |||||
| LV2_Property Properties; | |||||
| LV2_Property Designation; | |||||
| const char* Name; | |||||
| const char* Symbol; | |||||
| LV2_RDF_PortMidiMap MidiMap; | |||||
| LV2_RDF_PortPoints Points; | |||||
| LV2_RDF_PortUnit Unit; | |||||
| uint32_t ScalePointCount; | |||||
| LV2_RDF_PortScalePoint* ScalePoints; | |||||
| LV2_RDF_Port() | |||||
| : Types(0x0), | |||||
| Properties(0x0), | |||||
| Designation(0), | |||||
| Name(nullptr), | |||||
| Symbol(nullptr), | |||||
| ScalePointCount(0), | |||||
| ScalePoints(nullptr) {} | |||||
| ~LV2_RDF_Port() | |||||
| { | |||||
| if (Name) | |||||
| ::free((void*)Name); | |||||
| if (Symbol) | |||||
| ::free((void*)Symbol); | |||||
| if (ScalePoints) | |||||
| delete[] ScalePoints; | |||||
| } | |||||
| }; | |||||
| // Preset | |||||
| struct LV2_RDF_Preset { | |||||
| LV2_URI URI; | |||||
| const char* Label; | |||||
| LV2_RDF_Preset() | |||||
| : URI(nullptr), | |||||
| Label(nullptr) {} | |||||
| ~LV2_RDF_Preset() | |||||
| { | |||||
| if (URI) | |||||
| ::free((void*)URI); | |||||
| if (Label) | |||||
| ::free((void*)Label); | |||||
| } | |||||
| }; | |||||
| // Feature | |||||
| struct LV2_RDF_Feature { | |||||
| LV2_Property Type; | |||||
| LV2_URI URI; | |||||
| LV2_RDF_Feature() | |||||
| : Type(0), | |||||
| URI(nullptr) {} | |||||
| ~LV2_RDF_Feature() | |||||
| { | |||||
| if (URI) | |||||
| ::free((void*)URI); | |||||
| } | |||||
| }; | |||||
| // UI | |||||
| struct LV2_RDF_UI { | |||||
| LV2_Type Type; | |||||
| LV2_URI URI; | |||||
| const char* Binary; | |||||
| const char* Bundle; | |||||
| uint32_t FeatureCount; | |||||
| LV2_RDF_Feature* Features; | |||||
| uint32_t ExtensionCount; | |||||
| LV2_URI* Extensions; | |||||
| LV2_RDF_UI() | |||||
| : URI(nullptr), | |||||
| Binary(nullptr), | |||||
| Bundle(nullptr), | |||||
| FeatureCount(0), | |||||
| Features(nullptr), | |||||
| ExtensionCount(0), | |||||
| Extensions(nullptr) {} | |||||
| ~LV2_RDF_UI() | |||||
| { | |||||
| if (URI) | |||||
| ::free((void*)URI); | |||||
| if (Binary) | |||||
| ::free((void*)Binary); | |||||
| if (Bundle) | |||||
| ::free((void*)Bundle); | |||||
| if (Features) | |||||
| delete[] Features; | |||||
| if (Extensions) | |||||
| delete[] Extensions; | |||||
| } | |||||
| }; | |||||
| // Plugin | |||||
| struct LV2_RDF_Descriptor { | |||||
| LV2_Property Type[2]; | |||||
| LV2_URI URI; | |||||
| const char* Name; | |||||
| const char* Author; | |||||
| const char* License; | |||||
| const char* Binary; | |||||
| const char* Bundle; | |||||
| unsigned long UniqueID; | |||||
| uint32_t PortCount; | |||||
| LV2_RDF_Port* Ports; | |||||
| uint32_t PresetCount; | |||||
| LV2_RDF_Preset* Presets; | |||||
| uint32_t FeatureCount; | |||||
| LV2_RDF_Feature* Features; | |||||
| uint32_t ExtensionCount; | |||||
| LV2_URI* Extensions; | |||||
| uint32_t UICount; | |||||
| LV2_RDF_UI* UIs; | |||||
| LV2_RDF_Descriptor() | |||||
| : Type{0x0, 0x0}, // FIXME ? | |||||
| URI(nullptr), | |||||
| Name(nullptr), | |||||
| Author(nullptr), | |||||
| License(nullptr), | |||||
| Binary(nullptr), | |||||
| Bundle(nullptr), | |||||
| UniqueID(0), | |||||
| PortCount(0), | |||||
| Ports(nullptr), | |||||
| PresetCount(0), | |||||
| Presets(nullptr), | |||||
| FeatureCount(0), | |||||
| Features(nullptr), | |||||
| ExtensionCount(0), | |||||
| Extensions(nullptr), | |||||
| UICount(0), | |||||
| UIs(nullptr) {} | |||||
| ~LV2_RDF_Descriptor() | |||||
| { | |||||
| if (URI) | |||||
| ::free((void*)URI); | |||||
| if (Name) | |||||
| ::free((void*)Name); | |||||
| if (Author) | |||||
| ::free((void*)Author); | |||||
| if (License) | |||||
| ::free((void*)License); | |||||
| if (Binary) | |||||
| ::free((void*)Binary); | |||||
| if (Bundle) | |||||
| ::free((void*)Bundle); | |||||
| if (Ports) | |||||
| delete[] Ports; | |||||
| if (Presets) | |||||
| delete[] Presets; | |||||
| if (Features) | |||||
| delete[] Features; | |||||
| if (Extensions) | |||||
| delete[] Extensions; | |||||
| if (UIs) | |||||
| delete[] UIs; | |||||
| } | |||||
| }; | |||||
| #endif // LV2_RDF_INCLUDED | |||||
| @@ -0,0 +1,459 @@ | |||||
| /* | |||||
| * Carla Backend | |||||
| * Copyright (C) 2011-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_BACKEND_UTILS_HPP | |||||
| #define CARLA_BACKEND_UTILS_HPP | |||||
| #include "carla_backend.hpp" | |||||
| #include "carla_utils.hpp" | |||||
| CARLA_BACKEND_START_NAMESPACE | |||||
| /*! | |||||
| * @defgroup CarlaBackendUtils Carla Backend Utils | |||||
| * | |||||
| * Carla Backend Utils | |||||
| * | |||||
| * @{ | |||||
| */ | |||||
| static inline | |||||
| const char* BinaryType2Str(const BinaryType& type) | |||||
| { | |||||
| switch (type) | |||||
| { | |||||
| case BINARY_NONE: | |||||
| return "BINARY_NONE"; | |||||
| case BINARY_POSIX32: | |||||
| return "BINARY_POSIX32"; | |||||
| case BINARY_POSIX64: | |||||
| return "BINARY_POSIX64"; | |||||
| case BINARY_WIN32: | |||||
| return "BINARY_WIN32"; | |||||
| case BINARY_WIN64: | |||||
| return "BINARY_WIN64"; | |||||
| case BINARY_OTHER: | |||||
| return "BINARY_OTHER"; | |||||
| } | |||||
| qWarning("CarlaBackend::BinaryType2Str(%i) - invalid type", type); | |||||
| return nullptr; | |||||
| } | |||||
| static inline | |||||
| const char* PluginType2Str(const PluginType& type) | |||||
| { | |||||
| switch (type) | |||||
| { | |||||
| case PLUGIN_NONE: | |||||
| return "PLUGIN_NONE"; | |||||
| case PLUGIN_INTERNAL: | |||||
| return "PLUGIN_INTERNAL"; | |||||
| case PLUGIN_LADSPA: | |||||
| return "PLUGIN_LADSPA"; | |||||
| case PLUGIN_DSSI: | |||||
| return "PLUGIN_DSSI"; | |||||
| case PLUGIN_LV2: | |||||
| return "PLUGIN_LV2"; | |||||
| case PLUGIN_VST: | |||||
| return "PLUGIN_VST"; | |||||
| case PLUGIN_GIG: | |||||
| return "PLUGIN_GIG"; | |||||
| case PLUGIN_SF2: | |||||
| return "PLUGIN_SF2"; | |||||
| case PLUGIN_SFZ: | |||||
| return "PLUGIN_SFZ"; | |||||
| } | |||||
| qWarning("CarlaBackend::PluginType2Str(%i) - invalid type", type); | |||||
| return nullptr; | |||||
| } | |||||
| static inline | |||||
| const char* PluginCategory2Str(const PluginCategory& category) | |||||
| { | |||||
| switch (category) | |||||
| { | |||||
| case PLUGIN_CATEGORY_NONE: | |||||
| return "PLUGIN_CATEGORY_NONE"; | |||||
| case PLUGIN_CATEGORY_SYNTH: | |||||
| return "PLUGIN_CATEGORY_SYNTH"; | |||||
| case PLUGIN_CATEGORY_DELAY: | |||||
| return "PLUGIN_CATEGORY_DELAY"; | |||||
| case PLUGIN_CATEGORY_EQ: | |||||
| return "PLUGIN_CATEGORY_EQ"; | |||||
| case PLUGIN_CATEGORY_FILTER: | |||||
| return "PLUGIN_CATEGORY_FILTER"; | |||||
| case PLUGIN_CATEGORY_DYNAMICS: | |||||
| return "PLUGIN_CATEGORY_DYNAMICS"; | |||||
| case PLUGIN_CATEGORY_MODULATOR: | |||||
| return "PLUGIN_CATEGORY_MODULATOR"; | |||||
| case PLUGIN_CATEGORY_UTILITY: | |||||
| return "PLUGIN_CATEGORY_UTILITY"; | |||||
| case PLUGIN_CATEGORY_OTHER: | |||||
| return "PLUGIN_CATEGORY_OTHER"; | |||||
| } | |||||
| qWarning("CarlaBackend::PluginCategory2Str(%i) - invalid category", category); | |||||
| return nullptr; | |||||
| } | |||||
| static inline | |||||
| const char* ParameterType2Str(const ParameterType& type) | |||||
| { | |||||
| switch (type) | |||||
| { | |||||
| case PARAMETER_UNKNOWN: | |||||
| return "PARAMETER_UNKNOWN"; | |||||
| case PARAMETER_INPUT: | |||||
| return "PARAMETER_INPUT"; | |||||
| case PARAMETER_OUTPUT: | |||||
| return "PARAMETER_OUTPUT"; | |||||
| case PARAMETER_LATENCY: | |||||
| return "PARAMETER_LATENCY"; | |||||
| case PARAMETER_SAMPLE_RATE: | |||||
| return "PARAMETER_SAMPLE_RATE"; | |||||
| case PARAMETER_LV2_FREEWHEEL: | |||||
| return "PARAMETER_LV2_FREEWHEEL"; | |||||
| case PARAMETER_LV2_TIME: | |||||
| return "PARAMETER_LV2_TIME"; | |||||
| } | |||||
| qWarning("CarlaBackend::ParameterType2Str(%i) - invalid type", type); | |||||
| return nullptr; | |||||
| } | |||||
| static inline | |||||
| const char* InternalParametersIndex2Str(const InternalParametersIndex& index) | |||||
| { | |||||
| switch (index) | |||||
| { | |||||
| case PARAMETER_NULL: | |||||
| return "PARAMETER_NULL"; | |||||
| case PARAMETER_ACTIVE: | |||||
| return "PARAMETER_ACTIVE"; | |||||
| case PARAMETER_DRYWET: | |||||
| return "PARAMETER_DRYWET"; | |||||
| case PARAMETER_VOLUME: | |||||
| return "PARAMETER_VOLUME"; | |||||
| case PARAMETER_BALANCE_LEFT: | |||||
| return "PARAMETER_BALANCE_LEFT"; | |||||
| case PARAMETER_BALANCE_RIGHT: | |||||
| return "PARAMETER_BALANCE_RIGHT"; | |||||
| } | |||||
| qWarning("CarlaBackend::InternalParametersIndex2Str(%i) - invalid index", index); | |||||
| return nullptr; | |||||
| } | |||||
| static inline | |||||
| const char* GuiType2Str(const GuiType& type) | |||||
| { | |||||
| switch (type) | |||||
| { | |||||
| case GUI_NONE: | |||||
| return "GUI_NONE"; | |||||
| case GUI_INTERNAL_QT4: | |||||
| return "GUI_INTERNAL_QT4"; | |||||
| case GUI_INTERNAL_COCOA: | |||||
| return "GUI_INTERNAL_COCOA"; | |||||
| case GUI_INTERNAL_HWND: | |||||
| return "GUI_INTERNAL_HWND"; | |||||
| case GUI_INTERNAL_X11: | |||||
| return "GUI_INTERNAL_X11"; | |||||
| case GUI_EXTERNAL_LV2: | |||||
| return "GUI_EXTERNAL_LV2"; | |||||
| case GUI_EXTERNAL_SUIL: | |||||
| return "GUI_EXTERNAL_SUIL"; | |||||
| case GUI_EXTERNAL_OSC: | |||||
| return "GUI_EXTERNAL_OSC"; | |||||
| } | |||||
| qWarning("CarlaBackend::GuiType2Str(%i) - invalid type", type); | |||||
| return nullptr; | |||||
| } | |||||
| static inline | |||||
| const char* OptionsType2Str(const OptionsType& type) | |||||
| { | |||||
| switch (type) | |||||
| { | |||||
| case OPTION_PROCESS_NAME: | |||||
| return "OPTION_PROCESS_NAME"; | |||||
| case OPTION_PROCESS_MODE: | |||||
| return "OPTION_PROCESS_MODE"; | |||||
| case OPTION_PROCESS_HIGH_PRECISION: | |||||
| return "OPTION_PROCESS_HIGH_PRECISION"; | |||||
| case OPTION_MAX_PARAMETERS: | |||||
| return "OPTION_MAX_PARAMETERS"; | |||||
| case OPTION_PREFERRED_BUFFER_SIZE: | |||||
| return "OPTION_PREFERRED_BUFFER_SIZE"; | |||||
| case OPTION_PREFERRED_SAMPLE_RATE: | |||||
| return "OPTION_PREFERRED_SAMPLE_RATE"; | |||||
| case OPTION_FORCE_STEREO: | |||||
| return "OPTION_FORCE_STEREO"; | |||||
| case OPTION_USE_DSSI_VST_CHUNKS: | |||||
| return "OPTION_USE_DSSI_VST_CHUNKS"; | |||||
| case OPTION_PREFER_PLUGIN_BRIDGES: | |||||
| return "OPTION_PREFER_PLUGIN_BRIDGES"; | |||||
| case OPTION_PREFER_UI_BRIDGES: | |||||
| return "OPTION_PREFER_UI_BRIDGES"; | |||||
| case OPTION_OSC_UI_TIMEOUT: | |||||
| return "OPTION_OSC_UI_TIMEOUT"; | |||||
| case OPTION_PATH_BRIDGE_POSIX32: | |||||
| return "OPTION_PATH_BRIDGE_POSIX32"; | |||||
| case OPTION_PATH_BRIDGE_POSIX64: | |||||
| return "OPTION_PATH_BRIDGE_POSIX64"; | |||||
| case OPTION_PATH_BRIDGE_WIN32: | |||||
| return "OPTION_PATH_BRIDGE_WIN32"; | |||||
| case OPTION_PATH_BRIDGE_WIN64: | |||||
| return "OPTION_PATH_BRIDGE_WIN64"; | |||||
| case OPTION_PATH_BRIDGE_LV2_GTK2: | |||||
| return "OPTION_PATH_BRIDGE_LV2_GTK2"; | |||||
| case OPTION_PATH_BRIDGE_LV2_GTK3: | |||||
| return "OPTION_PATH_BRIDGE_LV2_GTK3"; | |||||
| case OPTION_PATH_BRIDGE_LV2_QT4: | |||||
| return "OPTION_PATH_BRIDGE_LV2_QT4"; | |||||
| case OPTION_PATH_BRIDGE_LV2_QT5: | |||||
| return "OPTION_PATH_BRIDGE_LV2_QT5"; | |||||
| case OPTION_PATH_BRIDGE_LV2_COCOA: | |||||
| return "OPTION_PATH_BRIDGE_LV2_COCOA"; | |||||
| case OPTION_PATH_BRIDGE_LV2_WINDOWS: | |||||
| return "OPTION_PATH_BRIDGE_LV2_WINDOWS"; | |||||
| case OPTION_PATH_BRIDGE_LV2_X11: | |||||
| return "OPTION_PATH_BRIDGE_LV2_X11"; | |||||
| case OPTION_PATH_BRIDGE_VST_COCOA: | |||||
| return "OPTION_PATH_BRIDGE_VST_COCOA"; | |||||
| case OPTION_PATH_BRIDGE_VST_HWND: | |||||
| return "OPTION_PATH_BRIDGE_VST_HWND"; | |||||
| case OPTION_PATH_BRIDGE_VST_X11: | |||||
| return "OPTION_PATH_BRIDGE_VST_X11"; | |||||
| } | |||||
| qWarning("CarlaBackend::OptionsType2Str(%i) - invalid type", type); | |||||
| return nullptr; | |||||
| } | |||||
| static inline | |||||
| const char* CallbackType2Str(const CallbackType& type) | |||||
| { | |||||
| switch (type) | |||||
| { | |||||
| case CALLBACK_DEBUG: | |||||
| return "CALLBACK_DEBUG"; | |||||
| case CALLBACK_PARAMETER_VALUE_CHANGED: | |||||
| return "CALLBACK_PARAMETER_VALUE_CHANGED"; | |||||
| case CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED: | |||||
| return "CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED"; | |||||
| case CALLBACK_PARAMETER_MIDI_CC_CHANGED: | |||||
| return "CALLBACK_PARAMETER_MIDI_CC_CHANGED"; | |||||
| case CALLBACK_PROGRAM_CHANGED: | |||||
| return "CALLBACK_PROGRAM_CHANGED"; | |||||
| case CALLBACK_MIDI_PROGRAM_CHANGED: | |||||
| return "CALLBACK_MIDI_PROGRAM_CHANGED"; | |||||
| case CALLBACK_NOTE_ON: | |||||
| return "CALLBACK_NOTE_ON"; | |||||
| case CALLBACK_NOTE_OFF: | |||||
| return "CALLBACK_NOTE_OFF"; | |||||
| case CALLBACK_SHOW_GUI: | |||||
| return "CALLBACK_SHOW_GUI"; | |||||
| case CALLBACK_RESIZE_GUI: | |||||
| return "CALLBACK_RESIZE_GUI"; | |||||
| case CALLBACK_UPDATE: | |||||
| return "CALLBACK_UPDATE"; | |||||
| case CALLBACK_RELOAD_INFO: | |||||
| return "CALLBACK_RELOAD_INFO"; | |||||
| case CALLBACK_RELOAD_PARAMETERS: | |||||
| return "CALLBACK_RELOAD_PARAMETERS"; | |||||
| case CALLBACK_RELOAD_PROGRAMS: | |||||
| return "CALLBACK_RELOAD_PROGRAMS"; | |||||
| case CALLBACK_RELOAD_ALL: | |||||
| return "CALLBACK_RELOAD_ALL"; | |||||
| case CALLBACK_NSM_ANNOUNCE: | |||||
| return "CALLBACK_NSM_ANNOUNCE"; | |||||
| case CALLBACK_NSM_OPEN1: | |||||
| return "CALLBACK_NSM_OPEN1"; | |||||
| case CALLBACK_NSM_OPEN2: | |||||
| return "CALLBACK_NSM_OPEN2"; | |||||
| case CALLBACK_NSM_SAVE: | |||||
| return "CALLBACK_NSM_SAVE"; | |||||
| case CALLBACK_ERROR: | |||||
| return "CALLBACK_ERROR"; | |||||
| case CALLBACK_QUIT: | |||||
| return "CALLBACK_QUIT"; | |||||
| } | |||||
| qWarning("CarlaBackend::CallbackType2Str(%i) - invalid type", type); | |||||
| return nullptr; | |||||
| } | |||||
| static inline | |||||
| const char* ProcessMode2Str(const ProcessMode& mode) | |||||
| { | |||||
| switch (mode) | |||||
| { | |||||
| case PROCESS_MODE_SINGLE_CLIENT: | |||||
| return "PROCESS_MODE_SINGLE_CLIENT"; | |||||
| case PROCESS_MODE_MULTIPLE_CLIENTS: | |||||
| return "PROCESS_MODE_MULTIPLE_CLIENTS"; | |||||
| case PROCESS_MODE_CONTINUOUS_RACK: | |||||
| return "PROCESS_MODE_CONTINUOUS_RACK"; | |||||
| case PROCESS_MODE_PATCHBAY: | |||||
| return "PROCESS_MODE_PATCHBAY"; | |||||
| } | |||||
| qWarning("CarlaBackend::ProcessModeType2Str(%i) - invalid type", mode); | |||||
| return nullptr; | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| static inline | |||||
| const char* getPluginTypeString(const PluginType& type) | |||||
| { | |||||
| qDebug("CarlaBackend::getPluginTypeString(%s)", PluginType2Str(type)); | |||||
| switch (type) | |||||
| { | |||||
| case PLUGIN_NONE: | |||||
| return "NONE"; | |||||
| case PLUGIN_INTERNAL: | |||||
| return "INTERNAL"; | |||||
| case PLUGIN_LADSPA: | |||||
| return "LADSPA"; | |||||
| case PLUGIN_DSSI: | |||||
| return "DSSI"; | |||||
| case PLUGIN_LV2: | |||||
| return "LV2"; | |||||
| case PLUGIN_VST: | |||||
| return "VST"; | |||||
| case PLUGIN_GIG: | |||||
| return "GIG"; | |||||
| case PLUGIN_SF2: | |||||
| return "SF2"; | |||||
| case PLUGIN_SFZ: | |||||
| return "SFZ"; | |||||
| } | |||||
| return "NONE"; | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| static inline | |||||
| uintptr_t getAddressFromPointer(void* const ptr) | |||||
| { | |||||
| qDebug("CarlaBackend::getAddressFromPointer(%p)", ptr); | |||||
| CARLA_ASSERT(ptr != nullptr); | |||||
| uintptr_t* addr = (uintptr_t*)&ptr; | |||||
| return *addr; | |||||
| } | |||||
| static inline | |||||
| void* getPointerFromAddress(const uintptr_t& addr) | |||||
| { | |||||
| CARLA_ASSERT(addr != 0); | |||||
| uintptr_t** const ptr = (uintptr_t**)&addr; | |||||
| return *ptr; | |||||
| } | |||||
| static inline | |||||
| PluginCategory getPluginCategoryFromName(const char* const name) | |||||
| { | |||||
| qDebug("CarlaBackend::getPluginCategoryFromName(\"%s\")", name); | |||||
| CARLA_ASSERT(name); | |||||
| if (! name) | |||||
| return PLUGIN_CATEGORY_NONE; | |||||
| CarlaString sname(name); | |||||
| if (sname.isEmpty()) | |||||
| return PLUGIN_CATEGORY_NONE; | |||||
| sname.toLower(); | |||||
| // generic tags first | |||||
| if (sname.contains("delay")) | |||||
| return PLUGIN_CATEGORY_DELAY; | |||||
| if (sname.contains("reverb")) | |||||
| return PLUGIN_CATEGORY_DELAY; | |||||
| // filter | |||||
| if (sname.contains("filter")) | |||||
| return PLUGIN_CATEGORY_FILTER; | |||||
| // dynamics | |||||
| if (sname.contains("dynamics")) | |||||
| return PLUGIN_CATEGORY_DYNAMICS; | |||||
| if (sname.contains("amplifier")) | |||||
| return PLUGIN_CATEGORY_DYNAMICS; | |||||
| if (sname.contains("compressor")) | |||||
| return PLUGIN_CATEGORY_DYNAMICS; | |||||
| if (sname.contains("enhancer")) | |||||
| return PLUGIN_CATEGORY_DYNAMICS; | |||||
| if (sname.contains("exciter")) | |||||
| return PLUGIN_CATEGORY_DYNAMICS; | |||||
| if (sname.contains("gate")) | |||||
| return PLUGIN_CATEGORY_DYNAMICS; | |||||
| if (sname.contains("limiter")) | |||||
| return PLUGIN_CATEGORY_DYNAMICS; | |||||
| // modulator | |||||
| if (sname.contains("modulator")) | |||||
| return PLUGIN_CATEGORY_MODULATOR; | |||||
| if (sname.contains("chorus")) | |||||
| return PLUGIN_CATEGORY_MODULATOR; | |||||
| if (sname.contains("flanger")) | |||||
| return PLUGIN_CATEGORY_MODULATOR; | |||||
| if (sname.contains("phaser")) | |||||
| return PLUGIN_CATEGORY_MODULATOR; | |||||
| if (sname.contains("saturator")) | |||||
| return PLUGIN_CATEGORY_MODULATOR; | |||||
| // utility | |||||
| if (sname.contains("utility")) | |||||
| return PLUGIN_CATEGORY_UTILITY; | |||||
| if (sname.contains("analyzer")) | |||||
| return PLUGIN_CATEGORY_UTILITY; | |||||
| if (sname.contains("converter")) | |||||
| return PLUGIN_CATEGORY_UTILITY; | |||||
| if (sname.contains("deesser")) | |||||
| return PLUGIN_CATEGORY_UTILITY; | |||||
| if (sname.contains("mixer")) | |||||
| return PLUGIN_CATEGORY_UTILITY; | |||||
| // common tags | |||||
| if (sname.contains("verb")) | |||||
| return PLUGIN_CATEGORY_DELAY; | |||||
| if (sname.contains("eq")) | |||||
| return PLUGIN_CATEGORY_EQ; | |||||
| if (sname.contains("tool")) | |||||
| return PLUGIN_CATEGORY_UTILITY; | |||||
| return PLUGIN_CATEGORY_NONE; | |||||
| } | |||||
| /**@}*/ | |||||
| CARLA_BACKEND_END_NAMESPACE | |||||
| #endif // CARLA_BACKEND_UTILS_HPP | |||||
| @@ -0,0 +1,212 @@ | |||||
| /* | |||||
| * Carla LADSPA utils | |||||
| * Copyright (C) 2011-2013 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_LADSPA_UTILS_HPP__ | |||||
| #define __CARLA_LADSPA_UTILS_HPP__ | |||||
| #include "carla_utils.hpp" | |||||
| #include "ladspa/ladspa.h" | |||||
| #include "ladspa_rdf.hpp" | |||||
| #include <cmath> | |||||
| #include <cstring> | |||||
| // ------------------------------------------------- | |||||
| // Copy RDF object | |||||
| static inline | |||||
| const LADSPA_RDF_Descriptor* ladspa_rdf_dup(const LADSPA_RDF_Descriptor* const oldDescriptor) | |||||
| { | |||||
| CARLA_ASSERT(oldDescriptor); | |||||
| if (! oldDescriptor) | |||||
| return nullptr; | |||||
| LADSPA_RDF_Descriptor* const newDescriptor = new LADSPA_RDF_Descriptor; | |||||
| newDescriptor->Type = oldDescriptor->Type; | |||||
| newDescriptor->UniqueID = oldDescriptor->UniqueID; | |||||
| newDescriptor->PortCount = oldDescriptor->PortCount; | |||||
| if (oldDescriptor->Title) | |||||
| newDescriptor->Title = strdup(oldDescriptor->Title); | |||||
| if (oldDescriptor->Creator) | |||||
| newDescriptor->Creator = strdup(oldDescriptor->Creator); | |||||
| if (newDescriptor->PortCount > 0) | |||||
| { | |||||
| newDescriptor->Ports = new LADSPA_RDF_Port[newDescriptor->PortCount]; | |||||
| for (unsigned long i=0; i < newDescriptor->PortCount; i++) | |||||
| { | |||||
| LADSPA_RDF_Port* const newPort = &newDescriptor->Ports[i]; | |||||
| newPort->Type = oldDescriptor->Ports[i].Type; | |||||
| newPort->Hints = oldDescriptor->Ports[i].Hints; | |||||
| newPort->Default = oldDescriptor->Ports[i].Default; | |||||
| newPort->Unit = oldDescriptor->Ports[i].Unit; | |||||
| newPort->ScalePointCount = oldDescriptor->Ports[i].ScalePointCount; | |||||
| if (oldDescriptor->Ports[i].Label) | |||||
| newPort->Label = strdup(oldDescriptor->Ports[i].Label); | |||||
| if (newPort->ScalePointCount > 0) | |||||
| { | |||||
| newPort->ScalePoints = new LADSPA_RDF_ScalePoint[newPort->ScalePointCount]; | |||||
| for (unsigned long j=0; j < newPort->ScalePointCount; j++) | |||||
| { | |||||
| LADSPA_RDF_ScalePoint* const newScalePoint = &newPort->ScalePoints[j]; | |||||
| newScalePoint->Value = oldDescriptor->Ports[i].ScalePoints[j].Value; | |||||
| if (oldDescriptor->Ports[i].ScalePoints[j].Label) | |||||
| newScalePoint->Label = strdup(oldDescriptor->Ports[i].ScalePoints[j].Label); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| return newDescriptor; | |||||
| } | |||||
| // ------------------------------------------------- | |||||
| // Check if 2 ports match types | |||||
| static inline | |||||
| bool is_ladspa_port_good(const LADSPA_PortDescriptor port1, const LADSPA_PortDescriptor port2) | |||||
| { | |||||
| if (LADSPA_IS_PORT_INPUT(port1) && ! LADSPA_IS_PORT_INPUT(port2)) | |||||
| return false; | |||||
| if (LADSPA_IS_PORT_OUTPUT(port1) && ! LADSPA_IS_PORT_OUTPUT(port2)) | |||||
| return false; | |||||
| if (LADSPA_IS_PORT_CONTROL(port1) && ! LADSPA_IS_PORT_CONTROL(port2)) | |||||
| return false; | |||||
| if (LADSPA_IS_PORT_AUDIO(port1) && ! LADSPA_IS_PORT_AUDIO(port2)) | |||||
| return false; | |||||
| return true; | |||||
| } | |||||
| // ------------------------------------------------- | |||||
| // Check if rdf data matches descriptor | |||||
| static inline | |||||
| bool is_ladspa_rdf_descriptor_valid(const LADSPA_RDF_Descriptor* const rdfDescriptor, const LADSPA_Descriptor* const descriptor) | |||||
| { | |||||
| CARLA_ASSERT(rdfDescriptor); | |||||
| CARLA_ASSERT(descriptor); | |||||
| if (! rdfDescriptor) | |||||
| return false; | |||||
| if (! descriptor) | |||||
| return false; | |||||
| if (rdfDescriptor->UniqueID != descriptor->UniqueID) | |||||
| { | |||||
| qWarning("WARNING - Plugin has wrong UniqueID: %li != %li", rdfDescriptor->UniqueID, descriptor->UniqueID); | |||||
| return false; | |||||
| } | |||||
| if (rdfDescriptor->PortCount > descriptor->PortCount) | |||||
| { | |||||
| qWarning("WARNING - Plugin has RDF data, but invalid PortCount: %li > %li", rdfDescriptor->PortCount, descriptor->PortCount); | |||||
| return false; | |||||
| } | |||||
| for (unsigned long i=0; i < rdfDescriptor->PortCount; i++) | |||||
| { | |||||
| if (! is_ladspa_port_good(rdfDescriptor->Ports[i].Type, descriptor->PortDescriptors[i])) | |||||
| { | |||||
| qWarning("WARNING - Plugin has RDF data, but invalid PortTypes: %i != %i", rdfDescriptor->Ports[i].Type, descriptor->PortDescriptors[i]); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| return true; | |||||
| } | |||||
| // ------------------------------------------------- | |||||
| // Get default control port value | |||||
| static inline | |||||
| LADSPA_Data get_default_ladspa_port_value(const LADSPA_PortRangeHintDescriptor hintDescriptor, const LADSPA_Data min, const LADSPA_Data max) | |||||
| { | |||||
| LADSPA_Data def; | |||||
| if (LADSPA_IS_HINT_HAS_DEFAULT(hintDescriptor)) | |||||
| { | |||||
| switch (hintDescriptor & LADSPA_HINT_DEFAULT_MASK) | |||||
| { | |||||
| case LADSPA_HINT_DEFAULT_MINIMUM: | |||||
| def = min; | |||||
| break; | |||||
| case LADSPA_HINT_DEFAULT_MAXIMUM: | |||||
| def = max; | |||||
| break; | |||||
| case LADSPA_HINT_DEFAULT_0: | |||||
| def = 0.0f; | |||||
| break; | |||||
| case LADSPA_HINT_DEFAULT_1: | |||||
| def = 1.0f; | |||||
| break; | |||||
| case LADSPA_HINT_DEFAULT_100: | |||||
| def = 100.0f; | |||||
| break; | |||||
| case LADSPA_HINT_DEFAULT_440: | |||||
| def = 440.0f; | |||||
| break; | |||||
| case LADSPA_HINT_DEFAULT_LOW: | |||||
| if (LADSPA_IS_HINT_LOGARITHMIC(hintDescriptor)) | |||||
| def = std::exp((std::log(min)*0.75f) + (std::log(max)*0.25f)); | |||||
| else | |||||
| def = (min*0.75f) + (max*0.25f); | |||||
| break; | |||||
| case LADSPA_HINT_DEFAULT_MIDDLE: | |||||
| if (LADSPA_IS_HINT_LOGARITHMIC(hintDescriptor)) | |||||
| def = std::sqrt(min*max); | |||||
| else | |||||
| def = (min+max)/2; | |||||
| break; | |||||
| case LADSPA_HINT_DEFAULT_HIGH: | |||||
| if (LADSPA_IS_HINT_LOGARITHMIC(hintDescriptor)) | |||||
| def = std::exp((std::log(min)*0.25f) + (std::log(max)*0.75f)); | |||||
| else | |||||
| def = (min*0.25f) + (max*0.75f); | |||||
| break; | |||||
| default: | |||||
| if (min < 0.0f && max > 0.0f) | |||||
| def = 0.0f; | |||||
| else | |||||
| def = min; | |||||
| break; | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| // no default value | |||||
| if (min < 0.0f && max > 0.0f) | |||||
| def = 0.0f; | |||||
| else | |||||
| def = min; | |||||
| } | |||||
| return def; | |||||
| } | |||||
| // ------------------------------------------------- | |||||
| #endif // __CARLA_LADSPA_UTILS_HPP__ | |||||
| @@ -0,0 +1,98 @@ | |||||
| /* | |||||
| * Carla library utils | |||||
| * Copyright (C) 2011-2013 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_LIB_UTILS_HPP__ | |||||
| #define __CARLA_LIB_UTILS_HPP__ | |||||
| #include "carla_utils.hpp" | |||||
| #ifndef Q_OS_WIN | |||||
| # include <dlfcn.h> | |||||
| #endif | |||||
| // ------------------------------------------------- | |||||
| // library related calls | |||||
| static inline | |||||
| void* lib_open(const char* const filename) | |||||
| { | |||||
| CARLA_ASSERT(filename); | |||||
| #ifdef Q_OS_WIN | |||||
| return LoadLibraryA(filename); | |||||
| #else | |||||
| return dlopen(filename, RTLD_NOW|RTLD_LOCAL); | |||||
| #endif | |||||
| } | |||||
| static inline | |||||
| bool lib_close(void* const lib) | |||||
| { | |||||
| CARLA_ASSERT(lib); | |||||
| if (! lib) | |||||
| return false; | |||||
| #ifdef Q_OS_WIN | |||||
| return FreeLibrary((HMODULE)lib); | |||||
| #else | |||||
| return (dlclose(lib) == 0); | |||||
| #endif | |||||
| } | |||||
| static inline | |||||
| void* lib_symbol(void* const lib, const char* const symbol) | |||||
| { | |||||
| CARLA_ASSERT(lib); | |||||
| CARLA_ASSERT(symbol); | |||||
| if (! (lib && symbol)) | |||||
| return nullptr; | |||||
| #ifdef Q_OS_WIN | |||||
| return (void*)GetProcAddress((HMODULE)lib, symbol); | |||||
| #else | |||||
| return dlsym(lib, symbol); | |||||
| #endif | |||||
| } | |||||
| static inline | |||||
| const char* lib_error(const char* const filename) | |||||
| { | |||||
| CARLA_ASSERT(filename); | |||||
| #ifdef Q_OS_WIN | |||||
| static char libError[2048]; | |||||
| memset(libError, 0, sizeof(char)*2048); | |||||
| LPVOID winErrorString; | |||||
| DWORD winErrorCode = GetLastError(); | |||||
| FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, winErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&winErrorString, 0, nullptr); | |||||
| snprintf(libError, 2048, "%s: error code %li: %s", filename, winErrorCode, (const char*)winErrorString); | |||||
| LocalFree(winErrorString); | |||||
| return libError; | |||||
| #else | |||||
| return dlerror(); | |||||
| Q_UNUSED(filename); | |||||
| #endif | |||||
| } | |||||
| // ------------------------------------------------- | |||||
| #endif // __CARLA_LIB_UTILS_HPP__ | |||||
| @@ -0,0 +1,348 @@ | |||||
| /* | |||||
| * Carla OSC utils | |||||
| * 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_OSC_UTILS_HPP | |||||
| #define CARLA_OSC_UTILS_HPP | |||||
| #include "carla_utils.hpp" | |||||
| #include <cstdint> | |||||
| #include <lo/lo.h> | |||||
| // ------------------------------------------------------------------------------------------------ | |||||
| struct CarlaOscData { | |||||
| const char* path; | |||||
| lo_address source; | |||||
| lo_address target; | |||||
| CarlaOscData() | |||||
| : path(nullptr), | |||||
| source(nullptr), | |||||
| target(nullptr) {} | |||||
| ~CarlaOscData() | |||||
| { | |||||
| free(); | |||||
| } | |||||
| void free() | |||||
| { | |||||
| if (path) | |||||
| ::free((void*)path); | |||||
| if (source) | |||||
| ::lo_address_free(source); | |||||
| if (target) | |||||
| ::lo_address_free(target); | |||||
| path = nullptr; | |||||
| source = nullptr; | |||||
| target = nullptr; | |||||
| } | |||||
| }; | |||||
| // ------------------------------------------------------------------------------------------------ | |||||
| static inline | |||||
| void osc_send_configure(const CarlaOscData* const oscData, const char* const key, const char* const value) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| CARLA_ASSERT(key); | |||||
| CARLA_ASSERT(value); | |||||
| qDebug("osc_send_configure(path:\"%s\", \"%s\", \"%s\")", oscData->path, key, value); | |||||
| if (oscData && oscData->path && oscData->target && key && value) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+11]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/configure"); | |||||
| lo_send(oscData->target, targetPath, "ss", key, value); | |||||
| } | |||||
| } | |||||
| static inline | |||||
| void osc_send_control(const CarlaOscData* const oscData, const int32_t index, const float value) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| CARLA_ASSERT(index != -1); // -1 == PARAMETER_NULL | |||||
| qDebug("osc_send_control(path:\"%s\", %i, %f)", oscData->path, index, value); | |||||
| if (oscData && oscData->path && oscData->target && index != -1) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+9]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/control"); | |||||
| lo_send(oscData->target, targetPath, "if", index, value); | |||||
| } | |||||
| } | |||||
| static inline | |||||
| void osc_send_program(const CarlaOscData* const oscData, const int32_t index) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| CARLA_ASSERT(index >= 0); | |||||
| qDebug("osc_send_program(path:\"%s\", %i)", oscData->path, index); | |||||
| if (oscData && oscData->path && oscData->target && index >= 0) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+9]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/program"); | |||||
| lo_send(oscData->target, targetPath, "i", index); | |||||
| } | |||||
| } | |||||
| static inline | |||||
| void osc_send_program(const CarlaOscData* const oscData, const int32_t bank, const int32_t program) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| CARLA_ASSERT(program >= 0); | |||||
| CARLA_ASSERT(bank >= 0); | |||||
| qDebug("osc_send_program(path:\"%s\", %i, %i)", oscData->path, bank, program); | |||||
| if (oscData && oscData->path && oscData->target && bank >= 0 && program >= 0) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+9]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/program"); | |||||
| lo_send(oscData->target, targetPath, "ii", bank, program); | |||||
| } | |||||
| } | |||||
| static inline | |||||
| void osc_send_midi_program(const CarlaOscData* const oscData, const int32_t index) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| CARLA_ASSERT(index >= 0); | |||||
| qDebug("osc_send_midi_program(path:\"%s\", %i)", oscData->path, index); | |||||
| if (oscData && oscData->path && oscData->target && index >= 0) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+14]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/midi_program"); | |||||
| lo_send(oscData->target, targetPath, "i", index); | |||||
| } | |||||
| } | |||||
| static inline | |||||
| void osc_send_midi_program(const CarlaOscData* const oscData, const int32_t bank, const int32_t program) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| CARLA_ASSERT(program >= 0); | |||||
| CARLA_ASSERT(bank >= 0); | |||||
| qDebug("osc_send_midi_program(path:\"%s\", %i, %i)", oscData->path, bank, program); | |||||
| if (oscData && oscData->path && oscData->target && bank >= 0 && program >= 0) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+14]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/midi_program"); | |||||
| lo_send(oscData->target, targetPath, "ii", bank, program); | |||||
| } | |||||
| } | |||||
| static inline | |||||
| void osc_send_midi(const CarlaOscData* const oscData, const uint8_t buf[4]) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| CARLA_ASSERT(buf[0] == 0); | |||||
| CARLA_ASSERT(buf[1] != 0); | |||||
| qDebug("osc_send_midi(path:\"%s\", 0x%X, %03u, %03u)", oscData->path, buf[1], buf[2], buf[3]); | |||||
| if (oscData && oscData->path && oscData->target && buf[0] == 0 && buf[1] != 0) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+6]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/midi"); | |||||
| lo_send(oscData->target, targetPath, "m", buf); | |||||
| } | |||||
| } | |||||
| static inline | |||||
| void osc_send_sample_rate(const CarlaOscData* const oscData, const float sampleRate) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| CARLA_ASSERT(sampleRate > 0.0f); | |||||
| qDebug("osc_send_sample_rate(path:\"%s\", %f)", oscData->path, sampleRate); | |||||
| if (oscData && oscData->path && oscData->target && sampleRate > 0.0f) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+13]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/sample-rate"); | |||||
| lo_send(oscData->target, targetPath, "f", sampleRate); | |||||
| } | |||||
| } | |||||
| #ifdef BUILD_BRIDGE | |||||
| static inline | |||||
| void osc_send_update(const CarlaOscData* const oscData, const char* const url) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| CARLA_ASSERT(url); | |||||
| qDebug("osc_send_update(path:\"%s\", \"%s\")", oscData->path, url); | |||||
| if (oscData && oscData->path && oscData->target && url) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+8]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/update"); | |||||
| lo_send(oscData->target, targetPath, "s", url); | |||||
| } | |||||
| } | |||||
| static inline | |||||
| void osc_send_exiting(const CarlaOscData* const oscData) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| qDebug("osc_send_exiting(path:\"%s\")", oscData->path); | |||||
| if (oscData && oscData->path && oscData->target) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+9]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/exiting"); | |||||
| lo_send(oscData->target, targetPath, ""); | |||||
| } | |||||
| } | |||||
| #endif | |||||
| static inline | |||||
| void osc_send_show(const CarlaOscData* const oscData) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| qDebug("osc_send_show(path:\"%s\")", oscData->path); | |||||
| if (oscData && oscData->path && oscData->target) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+6]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/show"); | |||||
| lo_send(oscData->target, targetPath, ""); | |||||
| } | |||||
| } | |||||
| static inline | |||||
| void osc_send_hide(const CarlaOscData* const oscData) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| qDebug("osc_send_hide(path:\"%s\")", oscData->path); | |||||
| if (oscData && oscData->path && oscData->target) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+6]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/hide"); | |||||
| lo_send(oscData->target, targetPath, ""); | |||||
| } | |||||
| } | |||||
| static inline | |||||
| void osc_send_quit(const CarlaOscData* const oscData) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| qDebug("osc_send_quit(path:\"%s\")", oscData->path); | |||||
| if (oscData && oscData->path && oscData->target) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+6]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/quit"); | |||||
| lo_send(oscData->target, targetPath, ""); | |||||
| } | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------ | |||||
| #ifdef BUILD_BRIDGE_PLUGIN | |||||
| static inline | |||||
| void osc_send_bridge_update(const CarlaOscData* const oscData, const char* const url) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| CARLA_ASSERT(url); | |||||
| qDebug("osc_send_bridge_update(path:\"%s\", \"%s\")", oscData->path, url); | |||||
| if (oscData && oscData->path && oscData->target && url) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+15]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/bridge_update"); | |||||
| lo_send(oscData->target, targetPath, "s", url); | |||||
| } | |||||
| } | |||||
| static inline | |||||
| void osc_send_bridge_error(const CarlaOscData* const oscData, const char* const error) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| CARLA_ASSERT(error); | |||||
| qDebug("osc_send_bridge_error(path:\"%s\", \"%s\")", oscData->path, error); | |||||
| if (oscData && oscData->path && oscData->target && error) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+14]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/bridge_error"); | |||||
| lo_send(oscData->target, targetPath, "s", error); | |||||
| } | |||||
| } | |||||
| #endif | |||||
| #if defined(BRIDGE_LV2) || defined(WANT_LV2) | |||||
| static inline | |||||
| void osc_send_lv2_transfer_atom(const CarlaOscData* const oscData, const int32_t portIndex, const char* const typeStr, const char* const atomBuf) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| CARLA_ASSERT(portIndex >= 0); | |||||
| CARLA_ASSERT(typeStr); | |||||
| CARLA_ASSERT(atomBuf); | |||||
| qDebug("osc_send_lv2_transfer_atom(path:\"%s\", %i, \"%s\", <atomBuf:%p>)", oscData->path, portIndex, typeStr, atomBuf); | |||||
| if (oscData && oscData->path && oscData->target && portIndex >= 0 && typeStr && atomBuf) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+19]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/lv2_atom_transfer"); | |||||
| lo_send(oscData->target, targetPath, "iss", portIndex, typeStr, atomBuf); | |||||
| } | |||||
| } | |||||
| static inline | |||||
| void osc_send_lv2_transfer_event(const CarlaOscData* const oscData, const int32_t portIndex, const char* const typeStr, const char* const atomBuf) | |||||
| { | |||||
| CARLA_ASSERT(oscData && oscData->path); | |||||
| CARLA_ASSERT(portIndex >= 0); | |||||
| CARLA_ASSERT(typeStr); | |||||
| CARLA_ASSERT(atomBuf); | |||||
| qDebug("osc_send_lv2_transfer_event(path:\"%s\", %i, \"%s\", <atomBuf:%p>)", oscData->path, portIndex, typeStr, atomBuf); | |||||
| if (oscData && oscData->path && oscData->target && portIndex >= 0 && typeStr && atomBuf) | |||||
| { | |||||
| char targetPath[strlen(oscData->path)+20]; | |||||
| strcpy(targetPath, oscData->path); | |||||
| strcat(targetPath, "/lv2_event_transfer"); | |||||
| lo_send(oscData->target, targetPath, "iss", portIndex, typeStr, atomBuf); | |||||
| } | |||||
| } | |||||
| #endif | |||||
| // ------------------------------------------------------------------------------------------------ | |||||
| #endif // CARLA_OSC_UTILS_HPP | |||||
| @@ -0,0 +1,471 @@ | |||||
| /* | |||||
| * Carla common utils | |||||
| * Copyright (C) 2011-2013 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_UTILS_HPP__ | |||||
| #define __CARLA_UTILS_HPP__ | |||||
| #include "carla_defines.hpp" | |||||
| #include <cstdio> | |||||
| #include <cstdlib> | |||||
| #include <cstring> | |||||
| #if defined(Q_OS_HAIKU) | |||||
| # include <kernel/OS.h> | |||||
| #elif defined(Q_OS_LINUX) | |||||
| # include <sys/prctl.h> | |||||
| # include <linux/prctl.h> | |||||
| #endif | |||||
| // ------------------------------------------------- | |||||
| // carla_assert* | |||||
| static inline | |||||
| void carla_assert(const char* const assertion, const char* const file, const int line) | |||||
| { | |||||
| qCritical("Carla assertion failure: \"%s\" in file %s, line %i", assertion, file, line); | |||||
| } | |||||
| static inline | |||||
| void carla_assert_int(const char* const assertion, const char* const file, const int line, const int value) | |||||
| { | |||||
| qCritical("Carla assertion failure: \"%s\" in file %s, line %i, value %i", assertion, file, line, value); | |||||
| } | |||||
| // ------------------------------------------------- | |||||
| // carla_*sleep (carla_usleep not possible in Windows) | |||||
| static inline | |||||
| void carla_sleep(const int secs) | |||||
| { | |||||
| CARLA_ASSERT(secs > 0); | |||||
| #ifdef Q_OS_WIN | |||||
| Sleep(secs * 1000); | |||||
| #else | |||||
| sleep(secs); | |||||
| #endif | |||||
| } | |||||
| static inline | |||||
| void carla_msleep(const int msecs) | |||||
| { | |||||
| CARLA_ASSERT(msecs > 0); | |||||
| #ifdef Q_OS_WIN | |||||
| Sleep(msecs); | |||||
| #else | |||||
| usleep(msecs * 1000); | |||||
| #endif | |||||
| } | |||||
| static inline | |||||
| void carla_usleep(const int usecs) | |||||
| { | |||||
| CARLA_ASSERT(usecs > 0); | |||||
| #ifdef Q_OS_WIN | |||||
| Sleep(usecs / 1000); | |||||
| #else | |||||
| usleep(usecs); | |||||
| #endif | |||||
| } | |||||
| // ------------------------------------------------- | |||||
| // carla_setenv | |||||
| static inline | |||||
| void carla_setenv(const char* const key, const char* const value) | |||||
| { | |||||
| CARLA_ASSERT(key); | |||||
| CARLA_ASSERT(value); | |||||
| #ifdef Q_OS_WIN | |||||
| SetEnvironmentVariableA(key, value); | |||||
| #else | |||||
| setenv(key, value, 1); | |||||
| #endif | |||||
| } | |||||
| // ------------------------------------------------- | |||||
| // carla_setprocname (not available on all platforms) | |||||
| static inline | |||||
| void carla_setprocname(const char* const name) | |||||
| { | |||||
| CARLA_ASSERT(name); | |||||
| #if defined(Q_OS_HAIKU) | |||||
| if ((thread_id this_thread = find_thread(nullptr)) != B_NAME_NOT_FOUND) | |||||
| rename_thread(this_thread, name); | |||||
| #elif defined(Q_OS_LINUX) | |||||
| prctl(PR_SET_NAME, name); | |||||
| #else | |||||
| qWarning("carla_setprocname(\"%s\") - unsupported on this platform", name); | |||||
| #endif | |||||
| } | |||||
| // ------------------------------------------------- | |||||
| // math functions | |||||
| template<typename T> | |||||
| static inline | |||||
| const T& carla_min(const T& v1, const T& v2, const T& min) | |||||
| { | |||||
| return ((v1 < min || v2 < min) ? min : (v1 < v2 ? v1 : v2)); | |||||
| } | |||||
| template<typename T> | |||||
| static inline | |||||
| void carla_fill(T* data, const unsigned int size, const T v) | |||||
| { | |||||
| CARLA_ASSERT(data); | |||||
| CARLA_ASSERT(size > 0); | |||||
| for (unsigned int i=0; i < size; i++) | |||||
| *data++ = v; | |||||
| } | |||||
| void carla_zeroDouble(double* data, const unsigned size) | |||||
| { | |||||
| carla_fill<double>(data, size, 0.0); | |||||
| } | |||||
| void carla_zeroFloat(float* data, const unsigned size) | |||||
| { | |||||
| carla_fill<float>(data, size, 0.0f); | |||||
| } | |||||
| // ------------------------------------------------- | |||||
| // other misc functions | |||||
| static inline | |||||
| const char* bool2str(const bool yesNo) | |||||
| { | |||||
| return yesNo ? "true" : "false"; | |||||
| } | |||||
| static inline | |||||
| void pass() {} | |||||
| // ------------------------------------------------- | |||||
| // CarlaString class | |||||
| class CarlaString | |||||
| { | |||||
| public: | |||||
| // --------------------------------------------- | |||||
| // constructors (no explicit conversions allowed) | |||||
| explicit CarlaString() | |||||
| { | |||||
| buffer = ::strdup(""); | |||||
| } | |||||
| explicit CarlaString(char* const strBuf) | |||||
| { | |||||
| buffer = ::strdup(strBuf ? strBuf : ""); | |||||
| } | |||||
| explicit CarlaString(const char* const strBuf) | |||||
| { | |||||
| buffer = ::strdup(strBuf ? strBuf : ""); | |||||
| } | |||||
| explicit CarlaString(const int value) | |||||
| { | |||||
| const size_t strBufSize = ::abs(value/10) + 3; | |||||
| char strBuf[strBufSize]; | |||||
| ::snprintf(strBuf, strBufSize, "%d", value); | |||||
| buffer = ::strdup(strBuf); | |||||
| } | |||||
| explicit CarlaString(const unsigned int value, const bool hexadecimal = false) | |||||
| { | |||||
| const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0); | |||||
| char strBuf[strBufSize]; | |||||
| ::snprintf(strBuf, strBufSize, hexadecimal ? "%u" : "0x%x", value); | |||||
| buffer = ::strdup(strBuf); | |||||
| } | |||||
| explicit CarlaString(const long int value) | |||||
| { | |||||
| const size_t strBufSize = ::labs(value/10) + 3; | |||||
| char strBuf[strBufSize]; | |||||
| ::snprintf(strBuf, strBufSize, "%ld", value); | |||||
| buffer = ::strdup(strBuf); | |||||
| } | |||||
| explicit CarlaString(const unsigned long int value, const bool hexadecimal = false) | |||||
| { | |||||
| const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0); | |||||
| char strBuf[strBufSize]; | |||||
| ::snprintf(strBuf, strBufSize, hexadecimal ? "%lu" : "0x%lx", value); | |||||
| buffer = ::strdup(strBuf); | |||||
| } | |||||
| explicit CarlaString(const float value) | |||||
| { | |||||
| char strBuf[0xff]; | |||||
| ::snprintf(strBuf, 0xff, "%f", value); | |||||
| buffer = ::strdup(strBuf); | |||||
| } | |||||
| explicit CarlaString(const double value) | |||||
| { | |||||
| char strBuf[0xff]; | |||||
| ::snprintf(strBuf, 0xff, "%g", value); | |||||
| buffer = ::strdup(strBuf); | |||||
| } | |||||
| // --------------------------------------------- | |||||
| // non-explicit constructor | |||||
| CarlaString(const CarlaString& str) | |||||
| { | |||||
| buffer = ::strdup(str.buffer); | |||||
| } | |||||
| // --------------------------------------------- | |||||
| // deconstructor | |||||
| ~CarlaString() | |||||
| { | |||||
| CARLA_ASSERT(buffer); | |||||
| ::free(buffer); | |||||
| } | |||||
| // --------------------------------------------- | |||||
| // public methods | |||||
| size_t length() const | |||||
| { | |||||
| return ::strlen(buffer); | |||||
| } | |||||
| bool isEmpty() const | |||||
| { | |||||
| return (*buffer == 0); | |||||
| } | |||||
| bool isNotEmpty() const | |||||
| { | |||||
| return (*buffer != 0); | |||||
| } | |||||
| bool contains(const char* const strBuf) const | |||||
| { | |||||
| if (! strBuf) | |||||
| return false; | |||||
| if (*strBuf == 0) | |||||
| return false; | |||||
| size_t thisLen = ::strlen(buffer); | |||||
| size_t thatLen = ::strlen(strBuf)-1; | |||||
| for (size_t i=0, j=0; i < thisLen; i++) | |||||
| { | |||||
| if (buffer[i] == strBuf[j]) | |||||
| j++; | |||||
| else | |||||
| j = 0; | |||||
| if (j == thatLen) | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| bool contains(const CarlaString& str) const | |||||
| { | |||||
| return contains(str.buffer); | |||||
| } | |||||
| bool isDigit(const size_t pos) const | |||||
| { | |||||
| if (pos >= length()) | |||||
| return false; | |||||
| return (buffer[pos] >= '0' && buffer[pos] <= '9'); | |||||
| } | |||||
| void clear() | |||||
| { | |||||
| truncate(0); | |||||
| } | |||||
| void replace(const char before, const char after) | |||||
| { | |||||
| for (size_t i=0, len = ::strlen(buffer); i < len; i++) | |||||
| { | |||||
| if (buffer[i] == before) | |||||
| buffer[i] = after; | |||||
| } | |||||
| } | |||||
| void truncate(const unsigned int n) | |||||
| { | |||||
| for (size_t i=n, len = ::strlen(buffer); i < len; i++) | |||||
| buffer[i] = 0; | |||||
| } | |||||
| void toBasic() | |||||
| { | |||||
| for (size_t i=0, len = ::strlen(buffer); i < len; i++) | |||||
| { | |||||
| if (buffer[i] >= '0' && buffer[i] <= '9') | |||||
| continue; | |||||
| if (buffer[i] >= 'A' && buffer[i] <= 'Z') | |||||
| continue; | |||||
| if (buffer[i] >= 'a' && buffer[i] <= 'z') | |||||
| continue; | |||||
| if (buffer[i] == '_') | |||||
| continue; | |||||
| buffer[i] = '_'; | |||||
| } | |||||
| } | |||||
| void toLower() | |||||
| { | |||||
| for (size_t i=0, len = ::strlen(buffer); i < len; i++) | |||||
| { | |||||
| if (buffer[i] >= 'A' && buffer[i] <= 'Z') | |||||
| buffer[i] += 32; | |||||
| } | |||||
| } | |||||
| void toUpper() | |||||
| { | |||||
| for (size_t i=0, len = ::strlen(buffer); i < len; i++) | |||||
| { | |||||
| if (buffer[i] >= 'a' && buffer[i] <= 'z') | |||||
| buffer[i] -= 32; | |||||
| } | |||||
| } | |||||
| // --------------------------------------------- | |||||
| // public operators | |||||
| operator const char*() const | |||||
| { | |||||
| return buffer; | |||||
| } | |||||
| char& operator[](const unsigned int pos) | |||||
| { | |||||
| return buffer[pos]; | |||||
| } | |||||
| bool operator==(const char* const strBuf) const | |||||
| { | |||||
| return (strBuf && ::strcmp(buffer, strBuf) == 0); | |||||
| } | |||||
| bool operator==(const CarlaString& str) const | |||||
| { | |||||
| return operator==(str.buffer); | |||||
| } | |||||
| bool operator!=(const char* const strBuf) const | |||||
| { | |||||
| return !operator==(strBuf); | |||||
| } | |||||
| bool operator!=(const CarlaString& str) const | |||||
| { | |||||
| return !operator==(str.buffer); | |||||
| } | |||||
| CarlaString& operator=(const char* const strBuf) | |||||
| { | |||||
| ::free(buffer); | |||||
| buffer = ::strdup(strBuf ? strBuf : ""); | |||||
| return *this; | |||||
| } | |||||
| CarlaString& operator=(const CarlaString& str) | |||||
| { | |||||
| return operator=(str.buffer); | |||||
| } | |||||
| CarlaString& operator+=(const char* const strBuf) | |||||
| { | |||||
| const size_t newBufSize = ::strlen(buffer) + (strBuf ? ::strlen(strBuf) : 0) + 1; | |||||
| char newBuf[newBufSize]; | |||||
| ::strcpy(newBuf, buffer); | |||||
| ::strcat(newBuf, strBuf); | |||||
| ::free(buffer); | |||||
| buffer = ::strdup(newBuf); | |||||
| return *this; | |||||
| } | |||||
| CarlaString& operator+=(const CarlaString& str) | |||||
| { | |||||
| return operator+=(str.buffer); | |||||
| } | |||||
| CarlaString operator+(const char* const strBuf) | |||||
| { | |||||
| const size_t newBufSize = ::strlen(buffer) + (strBuf ? ::strlen(strBuf) : 0) + 1; | |||||
| char newBuf[newBufSize]; | |||||
| ::strcpy(newBuf, buffer); | |||||
| ::strcat(newBuf, strBuf); | |||||
| return CarlaString(newBuf); | |||||
| } | |||||
| CarlaString operator+(const CarlaString& str) | |||||
| { | |||||
| return operator+(str.buffer); | |||||
| } | |||||
| // --------------------------------------------- | |||||
| private: | |||||
| char* buffer; | |||||
| }; | |||||
| static inline | |||||
| CarlaString operator+(const char* const strBufBefore, const CarlaString& strAfter) | |||||
| { | |||||
| const char* const strBufAfter = (const char*)strAfter; | |||||
| const size_t newBufSize = (strBufBefore ? ::strlen(strBufBefore) : 0) + ::strlen(strBufAfter) + 1; | |||||
| char newBuf[newBufSize]; | |||||
| ::strcpy(newBuf, strBufBefore); | |||||
| ::strcat(newBuf, strBufAfter); | |||||
| return CarlaString(newBuf); | |||||
| } | |||||
| // ------------------------------------------------- | |||||
| #endif // __CARLA_UTILS_HPP__ | |||||
| @@ -0,0 +1,454 @@ | |||||
| /* | |||||
| * Carla VST utils | |||||
| * Copyright (C) 2011-2013 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_VST_UTILS_HPP__ | |||||
| #define __CARLA_VST_UTILS_HPP__ | |||||
| // Disable deprecated VST features (NOT) | |||||
| #define VST_FORCE_DEPRECATED 0 | |||||
| #include "carla_utils.hpp" | |||||
| #include <cstdint> | |||||
| // ------------------------------------------------- | |||||
| // Include fixes | |||||
| #if VESTIGE_HEADER | |||||
| #include "vestige/aeffectx.h" | |||||
| #define audioMasterGetOutputSpeakerArrangement audioMasterGetSpeakerArrangement | |||||
| #define effFlagsProgramChunks (1 << 5) | |||||
| #define effSetProgramName 4 | |||||
| #define effGetParamLabel 6 | |||||
| #define effGetParamDisplay 7 | |||||
| #define effGetVu 9 | |||||
| #define effEditDraw 16 | |||||
| #define effEditMouse 17 | |||||
| #define effEditKey 18 | |||||
| #define effEditSleep 21 | |||||
| #define effIdentify 22 | |||||
| #define effGetChunk 23 | |||||
| #define effSetChunk 24 | |||||
| #define effCanBeAutomated 26 | |||||
| #define effString2Parameter 27 | |||||
| #define effGetNumProgramCategories 28 | |||||
| #define effGetProgramNameIndexed 29 | |||||
| #define effCopyProgram 30 | |||||
| #define effConnectInput 31 | |||||
| #define effConnectOutput 32 | |||||
| #define effGetInputProperties 33 | |||||
| #define effGetOutputProperties 34 | |||||
| #define effGetPlugCategory 35 | |||||
| #define effGetCurrentPosition 36 | |||||
| #define effGetDestinationBuffer 37 | |||||
| #define effOfflineNotify 38 | |||||
| #define effOfflinePrepare 39 | |||||
| #define effOfflineRun 40 | |||||
| #define effProcessVarIo 41 | |||||
| #define effSetSpeakerArrangement 42 | |||||
| #define effSetBlockSizeAndSampleRate 43 | |||||
| #define effSetBypass 44 | |||||
| #define effGetErrorText 46 | |||||
| #define effVendorSpecific 50 | |||||
| #define effGetTailSize 52 | |||||
| #define effIdle 53 | |||||
| #define effGetIcon 54 | |||||
| #define effSetViewPosition 55 | |||||
| #define effKeysRequired 57 | |||||
| #define effEditKeyDown 59 | |||||
| #define effEditKeyUp 60 | |||||
| #define effSetEditKnobMode 61 | |||||
| #define effGetMidiProgramName 62 | |||||
| #define effGetCurrentMidiProgram 63 | |||||
| #define effGetMidiProgramCategory 64 | |||||
| #define effHasMidiProgramsChanged 65 | |||||
| #define effGetMidiKeyName 66 | |||||
| #define effBeginSetProgram 67 | |||||
| #define effEndSetProgram 68 | |||||
| #define effGetSpeakerArrangement 69 | |||||
| #define effShellGetNextPlugin 70 | |||||
| #define effStartProcess 71 | |||||
| #define effStopProcess 72 | |||||
| #define effSetTotalSampleToProcess 73 | |||||
| #define effSetPanLaw 74 | |||||
| #define effBeginLoadBank 75 | |||||
| #define effBeginLoadProgram 76 | |||||
| #define effSetProcessPrecision 77 | |||||
| #define effGetNumMidiInputChannels 78 | |||||
| #define effGetNumMidiOutputChannels 79 | |||||
| #define kPlugCategSynth 2 | |||||
| #define kPlugCategAnalysis 3 | |||||
| #define kPlugCategMastering 4 | |||||
| #define kPlugCategRoomFx 6 | |||||
| #define kPlugCategRestoration 8 | |||||
| #define kPlugCategShell 10 | |||||
| #define kPlugCategGenerator 11 | |||||
| #define kVstAutomationOff 1 | |||||
| #define kVstAutomationReadWrite 4 | |||||
| #define kVstProcessLevelUnknown 0 | |||||
| #define kVstProcessLevelUser 1 | |||||
| #define kVstProcessLevelRealtime 2 | |||||
| #define kVstProcessLevelOffline 4 | |||||
| #define kVstProcessPrecision32 0 | |||||
| #define kVstTransportChanged 1 | |||||
| #define kVstVersion 2400 | |||||
| #define VSTCALLBACK | |||||
| struct ERect { | |||||
| int16_t top, left, bottom, right; | |||||
| }; | |||||
| struct VstTimeInfo_R { | |||||
| double samplePos, sampleRate, nanoSeconds, ppqPos, tempo, barStartPos, cycleStartPos, cycleEndPos; | |||||
| int32_t timeSigNumerator, timeSigDenominator, smpteOffset, smpteFrameRate, samplesToNextClock, flags; | |||||
| }; | |||||
| #else | |||||
| #include "vst/aeffectx.h" | |||||
| typedef VstTimeInfo VstTimeInfo_R; | |||||
| #endif | |||||
| // ------------------------------------------------- | |||||
| // Plugin callback | |||||
| typedef AEffect* (*VST_Function)(audioMasterCallback); | |||||
| // ------------------------------------------------- | |||||
| // Check if feature is supported by the plugin | |||||
| static inline | |||||
| bool vstPluginCanDo(AEffect* const effect, const char* const feature) | |||||
| { | |||||
| return (effect->dispatcher(effect, effCanDo, 0, 0, (void*)feature, 0.0f) == 1); | |||||
| } | |||||
| // ------------------------------------------------- | |||||
| // Convert Effect opcode to string | |||||
| static inline | |||||
| const char* vstEffectOpcode2str(const int32_t opcode) | |||||
| { | |||||
| switch (opcode) | |||||
| { | |||||
| case effOpen: | |||||
| return "effOpen"; | |||||
| case effClose: | |||||
| return "effClose"; | |||||
| case effSetProgram: | |||||
| return "effSetProgram"; | |||||
| case effGetProgram: | |||||
| return "effGetProgram"; | |||||
| case effSetProgramName: | |||||
| return "effSetProgramName"; | |||||
| case effGetProgramName: | |||||
| return "effGetProgramName"; | |||||
| case effGetParamLabel: | |||||
| return "effGetParamLabel"; | |||||
| case effGetParamDisplay: | |||||
| return "effGetParamDisplay"; | |||||
| case effGetParamName: | |||||
| return "effGetParamName"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case effGetVu: | |||||
| return "effGetVu"; | |||||
| #endif | |||||
| case effSetSampleRate: | |||||
| return "effSetSampleRate"; | |||||
| case effSetBlockSize: | |||||
| return "effSetBlockSize"; | |||||
| case effMainsChanged: | |||||
| return "effMainsChanged"; | |||||
| case effEditGetRect: | |||||
| return "effEditGetRect"; | |||||
| case effEditOpen: | |||||
| return "effEditOpen"; | |||||
| case effEditClose: | |||||
| return "effEditClose"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case effEditDraw: | |||||
| return "effEditDraw"; | |||||
| case effEditMouse: | |||||
| return "effEditMouse"; | |||||
| case effEditKey: | |||||
| return "effEditKey"; | |||||
| case effEditTop: | |||||
| return "effEditTop"; | |||||
| case effEditSleep: | |||||
| return "effEditSleep"; | |||||
| case effIdentify: | |||||
| return "effIdentify"; | |||||
| #endif | |||||
| case effGetChunk: | |||||
| return "effGetChunk"; | |||||
| case effSetChunk: | |||||
| return "effSetChunk"; | |||||
| case effProcessEvents: | |||||
| return "effProcessEvents"; | |||||
| case effCanBeAutomated: | |||||
| return "effCanBeAutomated"; | |||||
| case effString2Parameter: | |||||
| return "effString2Parameter"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case effGetNumProgramCategories: | |||||
| return "effGetNumProgramCategories"; | |||||
| #endif | |||||
| case effGetProgramNameIndexed: | |||||
| return "effGetProgramNameIndexed"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case effCopyProgram: | |||||
| return "effCopyProgram"; | |||||
| case effConnectInput: | |||||
| return "effConnectInput"; | |||||
| case effConnectOutput: | |||||
| return "effConnectOutput"; | |||||
| #endif | |||||
| case effGetInputProperties: | |||||
| return "effGetInputProperties"; | |||||
| case effGetOutputProperties: | |||||
| return "effGetOutputProperties"; | |||||
| case effGetPlugCategory: | |||||
| return "effGetPlugCategory"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case effGetCurrentPosition: | |||||
| return "effGetCurrentPosition"; | |||||
| case effGetDestinationBuffer: | |||||
| return "effGetDestinationBuffer"; | |||||
| #endif | |||||
| case effOfflineNotify: | |||||
| return "effOfflineNotify"; | |||||
| case effOfflinePrepare: | |||||
| return "effOfflinePrepare"; | |||||
| case effOfflineRun: | |||||
| return "effOfflineRun"; | |||||
| case effProcessVarIo: | |||||
| return "effProcessVarIo"; | |||||
| case effSetSpeakerArrangement: | |||||
| return "effSetSpeakerArrangement"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case effSetBlockSizeAndSampleRate: | |||||
| return "effSetBlockSizeAndSampleRate"; | |||||
| #endif | |||||
| case effSetBypass: | |||||
| return "effSetBypass"; | |||||
| case effGetEffectName: | |||||
| return "effGetEffectName"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case effGetErrorText: | |||||
| return "effGetErrorText"; | |||||
| #endif | |||||
| case effGetVendorString: | |||||
| return "effGetVendorString"; | |||||
| case effGetProductString: | |||||
| return "effGetProductString"; | |||||
| case effGetVendorVersion: | |||||
| return "effGetVendorVersion"; | |||||
| case effVendorSpecific: | |||||
| return "effVendorSpecific"; | |||||
| case effCanDo: | |||||
| return "effCanDo"; | |||||
| case effGetTailSize: | |||||
| return "effGetTailSize"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case effIdle: | |||||
| return "effIdle"; | |||||
| case effGetIcon: | |||||
| return "effGetIcon"; | |||||
| case effSetViewPosition: | |||||
| return "effSetViewPosition"; | |||||
| #endif | |||||
| case effGetParameterProperties: | |||||
| return "effGetParameterProperties"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case effKeysRequired: | |||||
| return "effKeysRequired"; | |||||
| #endif | |||||
| case effGetVstVersion: | |||||
| return "effGetVstVersion"; | |||||
| case effEditKeyDown: | |||||
| return "effEditKeyDown"; | |||||
| case effEditKeyUp: | |||||
| return "effEditKeyUp"; | |||||
| case effSetEditKnobMode: | |||||
| return "effSetEditKnobMode"; | |||||
| case effGetMidiProgramName: | |||||
| return "effGetMidiProgramName"; | |||||
| case effGetCurrentMidiProgram: | |||||
| return "effGetCurrentMidiProgram"; | |||||
| case effGetMidiProgramCategory: | |||||
| return "effGetMidiProgramCategory"; | |||||
| case effHasMidiProgramsChanged: | |||||
| return "effHasMidiProgramsChanged"; | |||||
| case effGetMidiKeyName: | |||||
| return "effGetMidiKeyName"; | |||||
| case effBeginSetProgram: | |||||
| return "effBeginSetProgram"; | |||||
| case effEndSetProgram: | |||||
| return "effEndSetProgram"; | |||||
| case effGetSpeakerArrangement: | |||||
| return "effGetSpeakerArrangement"; | |||||
| case effShellGetNextPlugin: | |||||
| return "effShellGetNextPlugin"; | |||||
| case effStartProcess: | |||||
| return "effStartProcess"; | |||||
| case effStopProcess: | |||||
| return "effStopProcess"; | |||||
| case effSetTotalSampleToProcess: | |||||
| return "effSetTotalSampleToProcess"; | |||||
| case effSetPanLaw: | |||||
| return "effSetPanLaw"; | |||||
| case effBeginLoadBank: | |||||
| return "effBeginLoadBank"; | |||||
| case effBeginLoadProgram: | |||||
| return "effBeginLoadProgram"; | |||||
| case effSetProcessPrecision: | |||||
| return "effSetProcessPrecision"; | |||||
| case effGetNumMidiInputChannels: | |||||
| return "effGetNumMidiInputChannels"; | |||||
| case effGetNumMidiOutputChannels: | |||||
| return "effGetNumMidiOutputChannels"; | |||||
| default: | |||||
| return "unknown"; | |||||
| } | |||||
| } | |||||
| // ------------------------------------------------- | |||||
| // Convert Host/Master opcode to string | |||||
| static inline | |||||
| const char* vstMasterOpcode2str(const int32_t opcode) | |||||
| { | |||||
| switch (opcode) | |||||
| { | |||||
| case audioMasterAutomate: | |||||
| return "audioMasterAutomate"; | |||||
| case audioMasterVersion: | |||||
| return "audioMasterVersion"; | |||||
| case audioMasterCurrentId: | |||||
| return "audioMasterCurrentId"; | |||||
| case audioMasterIdle: | |||||
| return "audioMasterIdle"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case audioMasterPinConnected: | |||||
| return "audioMasterPinConnected"; | |||||
| case audioMasterWantMidi: | |||||
| return "audioMasterWantMidi"; | |||||
| #endif | |||||
| case audioMasterGetTime: | |||||
| return "audioMasterGetTime"; | |||||
| case audioMasterProcessEvents: | |||||
| return "audioMasterProcessEvents"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case audioMasterSetTime: | |||||
| return "audioMasterSetTime"; | |||||
| case audioMasterTempoAt: | |||||
| return "audioMasterTempoAt"; | |||||
| case audioMasterGetNumAutomatableParameters: | |||||
| return "audioMasterGetNumAutomatableParameters"; | |||||
| case audioMasterGetParameterQuantization: | |||||
| return "audioMasterGetParameterQuantization"; | |||||
| #endif | |||||
| case audioMasterIOChanged: | |||||
| return "audioMasterIOChanged"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case audioMasterNeedIdle: | |||||
| return "audioMasterNeedIdle"; | |||||
| #endif | |||||
| case audioMasterSizeWindow: | |||||
| return "audioMasterSizeWindow"; | |||||
| case audioMasterGetSampleRate: | |||||
| return "audioMasterGetSampleRate"; | |||||
| case audioMasterGetBlockSize: | |||||
| return "audioMasterGetBlockSize"; | |||||
| case audioMasterGetInputLatency: | |||||
| return "audioMasterGetInputLatency"; | |||||
| case audioMasterGetOutputLatency: | |||||
| return "audioMasterGetOutputLatency"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case audioMasterGetPreviousPlug: | |||||
| return "audioMasterGetPreviousPlug"; | |||||
| case audioMasterGetNextPlug: | |||||
| return "audioMasterGetNextPlug"; | |||||
| case audioMasterWillReplaceOrAccumulate: | |||||
| return "audioMasterWillReplaceOrAccumulate"; | |||||
| #endif | |||||
| case audioMasterGetCurrentProcessLevel: | |||||
| return "audioMasterGetCurrentProcessLevel"; | |||||
| case audioMasterGetAutomationState: | |||||
| return "audioMasterGetAutomationState"; | |||||
| case audioMasterOfflineStart: | |||||
| return "audioMasterOfflineStart"; | |||||
| case audioMasterOfflineRead: | |||||
| return "audioMasterOfflineRead"; | |||||
| case audioMasterOfflineWrite: | |||||
| return "audioMasterOfflineWrite"; | |||||
| case audioMasterOfflineGetCurrentPass: | |||||
| return "audioMasterOfflineGetCurrentPass"; | |||||
| case audioMasterOfflineGetCurrentMetaPass: | |||||
| return "audioMasterOfflineGetCurrentMetaPass"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case audioMasterSetOutputSampleRate: | |||||
| return "audioMasterSetOutputSampleRate"; | |||||
| case audioMasterGetOutputSpeakerArrangement: | |||||
| return "audioMasterGetOutputSpeakerArrangement"; | |||||
| #endif | |||||
| case audioMasterGetVendorString: | |||||
| return "audioMasterGetVendorString"; | |||||
| case audioMasterGetProductString: | |||||
| return "audioMasterGetProductString"; | |||||
| case audioMasterGetVendorVersion: | |||||
| return "audioMasterGetVendorVersion"; | |||||
| case audioMasterVendorSpecific: | |||||
| return "audioMasterVendorSpecific"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case audioMasterSetIcon: | |||||
| return "audioMasterSetIcon"; | |||||
| #endif | |||||
| case audioMasterCanDo: | |||||
| return "audioMasterCanDo"; | |||||
| case audioMasterGetLanguage: | |||||
| return "audioMasterGetLanguage"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case audioMasterOpenWindow: | |||||
| return "audioMasterOpenWindow"; | |||||
| case audioMasterCloseWindow: | |||||
| return "audioMasterCloseWindow"; | |||||
| #endif | |||||
| case audioMasterGetDirectory: | |||||
| return "audioMasterGetDirectory"; | |||||
| case audioMasterUpdateDisplay: | |||||
| return "audioMasterUpdateDisplay"; | |||||
| case audioMasterBeginEdit: | |||||
| return "audioMasterBeginEdit"; | |||||
| case audioMasterEndEdit: | |||||
| return "audioMasterEndEdit"; | |||||
| case audioMasterOpenFileSelector: | |||||
| return "audioMasterOpenFileSelector"; | |||||
| case audioMasterCloseFileSelector: | |||||
| return "audioMasterCloseFileSelector"; | |||||
| #if ! VST_FORCE_DEPRECATED | |||||
| case audioMasterEditFile: | |||||
| return "audioMasterEditFile"; | |||||
| case audioMasterGetChunkFile: | |||||
| return "audioMasterGetChunkFile"; | |||||
| case audioMasterGetInputSpeakerArrangement: | |||||
| return "audioMasterGetInputSpeakerArrangement"; | |||||
| #endif | |||||
| default: | |||||
| return "unknown"; | |||||
| } | |||||
| } | |||||
| // ------------------------------------------------- | |||||
| #endif // __CARLA_VST_UTILS_HPP__ | |||||