@@ -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__ |