| @@ -9,7 +9,7 @@ | |||||
| * | * | ||||
| * This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | * GNU General Public License for more details. | ||||
| * | * | ||||
| * For a full copy of the GNU General Public License see the COPYING file | * For a full copy of the GNU General Public License see the COPYING file | ||||
| @@ -18,6 +18,8 @@ | |||||
| #ifndef __CARLA_BACKEND_HPP__ | #ifndef __CARLA_BACKEND_HPP__ | ||||
| #define __CARLA_BACKEND_HPP__ | #define __CARLA_BACKEND_HPP__ | ||||
| // TODO - remove ifdef's when Carla stabilizes | |||||
| #include "carla_defines.hpp" | #include "carla_defines.hpp" | ||||
| #include <cstdint> | #include <cstdint> | ||||
| @@ -39,12 +41,10 @@ CARLA_BACKEND_START_NAMESPACE | |||||
| * @{ | * @{ | ||||
| */ | */ | ||||
| #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 | |||||
| const unsigned int MAX_DEFAULT_PLUGINS = 99; //!< Maximum default number of loadable plugins | |||||
| const unsigned int MAX_RACK_PLUGINS = 16; //!< Maximum number of loadable plugins in rack mode | |||||
| const unsigned int MAX_PATCHBAY_PLUGINS = 999; //!< Maximum number of loadable plugins in patchbay mode | |||||
| const unsigned int MAX_DEFAULT_PARAMETERS = 200; //!< Maximum default number of parameters allowed.\see OPTION_MAX_PARAMETERS | |||||
| /*! | /*! | ||||
| * @defgroup PluginHints Plugin Hints | * @defgroup PluginHints Plugin Hints | ||||
| @@ -56,14 +56,17 @@ const unsigned int MAX_PARAMETERS = 200; //!< Default value for the maximum numb | |||||
| #ifndef BUILD_BRIDGE | #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. | 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 | #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 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. | |||||
| const unsigned int PLUGIN_IS_RTSAFE = 0x002; //!< Plugin is hard real-time safe. | |||||
| const unsigned int PLUGIN_IS_SYNTH = 0x004; //!< Plugin is a synthesizer (produces sound). | |||||
| const unsigned int PLUGIN_HAS_GUI = 0x010; //!< Plugin has its own custom GUI. | |||||
| const unsigned int PLUGIN_USES_CHUNKS = 0x020; //!< Plugin uses chunks to save internal data.\see CarlaPlugin::chunkData() | |||||
| #ifndef BUILD_BRIDGE | |||||
| const unsigned int PLUGIN_USES_SINGLE_THREAD = 0x040; //!< Plugin needs a single thread for both DSP and UI events. | |||||
| #endif | |||||
| const unsigned int PLUGIN_CAN_DRYWET = 0x100; //!< Plugin can make use of Dry/Wet controls. | |||||
| const unsigned int PLUGIN_CAN_VOLUME = 0x200; //!< Plugin can make use of Volume controls. | |||||
| const unsigned int PLUGIN_CAN_BALANCE = 0x400; //!< Plugin can make use of Left & Right Balance controls. | |||||
| const unsigned int PLUGIN_CAN_FORCE_STEREO = 0x800; //!< Plugin can be used in forced-stereo mode. | |||||
| /**@}*/ | /**@}*/ | ||||
| /*! | /*! | ||||
| @@ -73,16 +76,17 @@ const unsigned int PLUGIN_CAN_FORCE_STEREO = 0x100; //!< Plugin can be used in | |||||
| * \see CarlaPlugin::parameterData() | * \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_BOOLEAN = 0x01; //!< Parameter value is always a boolean (always at minimum or maximum range). | |||||
| const unsigned int PARAMETER_IS_INTEGER = 0x02; //!< Parameter value is always an integer. | |||||
| const unsigned int PARAMETER_IS_LOGARITHMIC = 0x04; //!< Parameter is logarithmic. | |||||
| 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_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_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_SAMPLERATE = 0x20; //!< Parameter needs sample rate to work (value and ranges are multiplied by SR, and must be 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_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() | const unsigned int PARAMETER_USES_CUSTOM_TEXT = 0x80; //!< Parameter uses custom text for displaying its value.\see CarlaPlugin::getParameterText() | ||||
| /**@}*/ | /**@}*/ | ||||
| #if 0 | |||||
| /*! | /*! | ||||
| * @defgroup CustomDataTypes Custom Data types | * @defgroup CustomDataTypes Custom Data types | ||||
| * | * | ||||
| @@ -95,7 +99,9 @@ const char* const CUSTOM_DATA_INVALID = nullptr; | |||||
| const char* const CUSTOM_DATA_CHUNK = "http://kxstudio.sf.net/ns/carla/chunk"; //!< Carla Chunk | 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 | const char* const CUSTOM_DATA_STRING = "http://kxstudio.sf.net/ns/carla/string"; //!< Carla String | ||||
| /**@}*/ | /**@}*/ | ||||
| #endif | |||||
| #if 0 | |||||
| /*! | /*! | ||||
| * @defgroup BridgeMessages Bridge Messages | * @defgroup BridgeMessages Bridge Messages | ||||
| * | * | ||||
| @@ -105,12 +111,13 @@ const char* const CUSTOM_DATA_STRING = "http://kxstudio.sf.net/ns/carla/string" | |||||
| * TODO: Review these, may not be needed anymore | * TODO: Review these, may not be needed anymore | ||||
| * @{ | * @{ | ||||
| */ | */ | ||||
| //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. | |||||
| 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. | |||||
| /**@}*/ | /**@}*/ | ||||
| #endif | |||||
| /*! | /*! | ||||
| * The binary type of a plugin. | * The binary type of a plugin. | ||||
| @@ -126,7 +133,7 @@ enum BinaryType { | |||||
| /*! | /*! | ||||
| * All the available plugin types, as provided by subclasses of CarlaPlugin.\n | * All the available plugin types, as provided by subclasses of CarlaPlugin.\n | ||||
| * \note Some plugin classes might provide more than 1 plugin type. | |||||
| * Some plugin classes might provide more than 1 plugin type. | |||||
| */ | */ | ||||
| enum PluginType { | enum PluginType { | ||||
| PLUGIN_NONE = 0, //!< Null plugin type. | PLUGIN_NONE = 0, //!< Null plugin type. | ||||
| @@ -184,34 +191,18 @@ enum InternalParametersIndex { | |||||
| PARAMETER_ACTIVE = -2, //!< Active parameter, can only be 'true' or 'false'; default is 'false'. | 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_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_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. | |||||
| PARAMETER_BALANCE_LEFT = -5, //!< Stereo Balance-Left parameter, range -1.0...1.0; default is -1.0. | |||||
| PARAMETER_BALANCE_RIGHT = -6, //!< Stereo Balance-Right parameter, range -1.0...1.0; default is 1.0. | |||||
| PARAMETER_PANNING = -7 //!< Mono Panning parameter, range -1.0...1.0; default is 0.0. | |||||
| }; | }; | ||||
| /*! | /*! | ||||
| * Plugin custom GUI type. | |||||
| * \see OPTION_PREFER_UI_BRIDGES | |||||
| * | |||||
| * TODO: these need to be handled all internally, only via showGui() backend-side | |||||
| */ | |||||
| //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(). | |||||
| * Options used in the CarlaEngine::setOption() and set_option() calls.\n | |||||
| * These options must be set before initiliazing or after closing the engine. | |||||
| */ | */ | ||||
| enum OptionsType { | enum OptionsType { | ||||
| /*! | /*! | ||||
| * Try to set the current process name.\n | |||||
| * Try to set the current process name. | |||||
| * \note Not available on all platforms. | * \note Not available on all platforms. | ||||
| */ | */ | ||||
| OPTION_PROCESS_NAME = 0, | OPTION_PROCESS_NAME = 0, | ||||
| @@ -232,54 +223,55 @@ enum OptionsType { | |||||
| OPTION_PROCESS_HIGH_PRECISION = 2, | OPTION_PROCESS_HIGH_PRECISION = 2, | ||||
| /*! | /*! | ||||
| * Maximum number of parameters allowed.\n | |||||
| * Default is MAX_PARAMETERS. | |||||
| */ | |||||
| OPTION_MAX_PARAMETERS = 3, | |||||
| /*! | |||||
| * Prefered buffer size. | |||||
| * Force mono plugins as stereo, by running 2 instances at the same time. | |||||
| * \note Not supported by all plugins. | |||||
| */ | */ | ||||
| OPTION_PREFERRED_BUFFER_SIZE = 4, | |||||
| OPTION_FORCE_STEREO = 3, | |||||
| /*! | /*! | ||||
| * Prefered sample rate. | |||||
| * Use plugin bridges whenever possible.\n | |||||
| * Default is no, and not recommended at this point!. | |||||
| * EXPERIMENTAL AND INCOMPLETE! | |||||
| */ | */ | ||||
| OPTION_PREFERRED_SAMPLE_RATE = 5, | |||||
| OPTION_PREFER_PLUGIN_BRIDGES = 4, | |||||
| /*! | /*! | ||||
| * Force mono plugins as stereo, by running 2 instances at the same time.\n | |||||
| * Not supported by all plugins. | |||||
| * Use OSC-UI bridges whenever possible, otherwise UIs will be handled in the main thread.\n | |||||
| * Default is yes. | |||||
| */ | */ | ||||
| OPTION_FORCE_STEREO = 6, | |||||
| OPTION_PREFER_UI_BRIDGES = 5, | |||||
| #ifdef WANT_DSSI | #ifdef WANT_DSSI | ||||
| /*! | /*! | ||||
| * Use (unofficial) dssi-vst chunks feature.\n | * Use (unofficial) dssi-vst chunks feature.\n | ||||
| * Default is no. | * Default is no. | ||||
| */ | */ | ||||
| OPTION_USE_DSSI_VST_CHUNKS = 7, | |||||
| OPTION_USE_DSSI_VST_CHUNKS = 6, | |||||
| #endif | #endif | ||||
| /*! | /*! | ||||
| * Use plugin bridges whenever possible.\n | |||||
| * Default is no, and not recommended at this point!. | |||||
| * EXPERIMENTAL AND INCOMPLETE! | |||||
| * Maximum number of parameters allowed.\n | |||||
| * Default is MAX_DEFAULT_PARAMETERS. | |||||
| */ | */ | ||||
| OPTION_PREFER_PLUGIN_BRIDGES = 8, | |||||
| OPTION_MAX_PARAMETERS = 7, | |||||
| /*! | /*! | ||||
| * Use OSC-UI bridges whenever possible, otherwise UIs will be handled in the main thread.\n | |||||
| * Default is yes. | |||||
| * Timeout value in ms for how much to wait for OSC-Bridges to respond.\n | |||||
| * Default is 4000 (4 secs). | |||||
| */ | */ | ||||
| OPTION_PREFER_UI_BRIDGES = 9, | |||||
| OPTION_OSC_UI_TIMEOUT = 8, | |||||
| /*! | /*! | ||||
| * Timeout value in ms for how much to wait for OSC-Bridges to respond.\n | |||||
| * Default is 4000 ms (4 secs). | |||||
| * Prefered buffer size. | |||||
| */ | */ | ||||
| OPTION_OSC_UI_TIMEOUT = 10, | |||||
| OPTION_PREFERRED_BUFFER_SIZE = 9, | |||||
| /*! | |||||
| * Prefered sample rate. | |||||
| */ | |||||
| OPTION_PREFERRED_SAMPLE_RATE = 10, | |||||
| #ifndef BUILD_BRIDGE | |||||
| /*! | /*! | ||||
| * Set path to the native plugin bridge executable.\n | * Set path to the native plugin bridge executable.\n | ||||
| * Default unset. | * Default unset. | ||||
| @@ -309,6 +301,7 @@ enum OptionsType { | |||||
| * Default unset. | * Default unset. | ||||
| */ | */ | ||||
| OPTION_PATH_BRIDGE_WIN64 = 15, | OPTION_PATH_BRIDGE_WIN64 = 15, | ||||
| #endif | |||||
| #ifdef WANT_LV2 | #ifdef WANT_LV2 | ||||
| /*! | /*! | ||||
| @@ -376,8 +369,9 @@ enum OptionsType { | |||||
| }; | }; | ||||
| /*! | /*! | ||||
| * Opcodes sent from the engine callback, as defined by CallbackFunc. | |||||
| * Opcodes sent from the engine callback to the GUI, as defined by CallbackFunc. | |||||
| * | * | ||||
| * \see CarlaEngine::setCallback() | |||||
| * \see set_callback_function() | * \see set_callback_function() | ||||
| */ | */ | ||||
| enum CallbackType { | enum CallbackType { | ||||
| @@ -449,72 +443,64 @@ enum CallbackType { | |||||
| * \param value1 State, as follows:.\n | * \param value1 State, as follows:.\n | ||||
| * 0: GUI has been closed or hidden\n | * 0: GUI has been closed or hidden\n | ||||
| * 1: GUI has been shown\n | * 1: GUI has been shown\n | ||||
| * -1: GUI has crashed and should not be shown again\n | |||||
| * -1: GUI has crashed and should not be shown again | |||||
| */ | */ | ||||
| CALLBACK_SHOW_GUI = 8, | 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. | * The plugin needs update. | ||||
| */ | */ | ||||
| CALLBACK_UPDATE = 10, | |||||
| CALLBACK_UPDATE = 9, | |||||
| /*! | /*! | ||||
| * The plugin's data/information has changed. | * The plugin's data/information has changed. | ||||
| */ | */ | ||||
| CALLBACK_RELOAD_INFO = 11, | |||||
| CALLBACK_RELOAD_INFO = 10, | |||||
| /*! | /*! | ||||
| * The plugin's parameters have changed. | * The plugin's parameters have changed. | ||||
| */ | */ | ||||
| CALLBACK_RELOAD_PARAMETERS = 12, | |||||
| CALLBACK_RELOAD_PARAMETERS = 11, | |||||
| /*! | /*! | ||||
| * The plugin's programs have changed. | * The plugin's programs have changed. | ||||
| */ | */ | ||||
| CALLBACK_RELOAD_PROGRAMS = 13, | |||||
| CALLBACK_RELOAD_PROGRAMS = 12, | |||||
| /*! | /*! | ||||
| * The plugin's state has changed. | * The plugin's state has changed. | ||||
| */ | */ | ||||
| CALLBACK_RELOAD_ALL = 14, | |||||
| CALLBACK_RELOAD_ALL = 13, | |||||
| /*! | /*! | ||||
| * Non-Session-Manager Announce message. | * Non-Session-Manager Announce message. | ||||
| */ | */ | ||||
| CALLBACK_NSM_ANNOUNCE = 15, | |||||
| CALLBACK_NSM_ANNOUNCE = 14, | |||||
| /*! | /*! | ||||
| * Non-Session-Manager Open message #1. | * Non-Session-Manager Open message #1. | ||||
| */ | */ | ||||
| CALLBACK_NSM_OPEN1 = 16, | |||||
| CALLBACK_NSM_OPEN1 = 15, | |||||
| /*! | /*! | ||||
| * Non-Session-Manager Open message #2. | * Non-Session-Manager Open message #2. | ||||
| */ | */ | ||||
| CALLBACK_NSM_OPEN2 = 17, | |||||
| CALLBACK_NSM_OPEN2 = 16, | |||||
| /*! | /*! | ||||
| * Non-Session-Manager Save message. | * Non-Session-Manager Save message. | ||||
| */ | */ | ||||
| CALLBACK_NSM_SAVE = 18, | |||||
| CALLBACK_NSM_SAVE = 17, | |||||
| /*! | /*! | ||||
| * An error occurred, show last error to user. | * An error occurred, show last error to user. | ||||
| */ | */ | ||||
| CALLBACK_ERROR = 19, | |||||
| CALLBACK_ERROR = 18, | |||||
| /*! | /*! | ||||
| * The engine has crashed or malfunctioned and will no longer work. | * The engine has crashed or malfunctioned and will no longer work. | ||||
| */ | */ | ||||
| CALLBACK_QUIT = 20 | |||||
| CALLBACK_QUIT = 19 | |||||
| }; | }; | ||||
| /*! | /*! | ||||
| @@ -598,7 +584,7 @@ struct MidiProgramData { | |||||
| /*! | /*! | ||||
| * Custom data, saving key:value 'dictionaries'. | * Custom data, saving key:value 'dictionaries'. | ||||
| * \a type is an URI. | |||||
| * \a type is an URI which defines the \a value type. | |||||
| * | * | ||||
| * \see CustomDataTypes | * \see CustomDataTypes | ||||
| */ | */ | ||||
| @@ -9,7 +9,7 @@ | |||||
| * | * | ||||
| * This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | * GNU General Public License for more details. | ||||
| * | * | ||||
| * For a full copy of the GNU General Public License see the COPYING file | * For a full copy of the GNU General Public License see the COPYING file | ||||
| @@ -172,50 +172,7 @@ struct CarlaEngineMidiEvent { | |||||
| } | } | ||||
| }; | }; | ||||
| /*! | |||||
| * Engine BBT Time information. | |||||
| */ | |||||
| struct CarlaEngineTimeInfoBBT { | |||||
| int32_t bar; //!< current bar | |||||
| int32_t beat; //!< current beat-within-bar | |||||
| int32_t tick; //!< current tick-within-beat | |||||
| double barStartTick; | |||||
| float beatsPerBar; //!< time signature "numerator" | |||||
| float beatType; //!< time signature "denominator" | |||||
| double ticksPerBeat; | |||||
| double beatsPerMinute; | |||||
| CarlaEngineTimeInfoBBT() | |||||
| : bar(0), | |||||
| beat(0), | |||||
| tick(0), | |||||
| barStartTick(0.0), | |||||
| beatsPerBar(0.0f), | |||||
| beatType(0.0f), | |||||
| ticksPerBeat(0.0), | |||||
| beatsPerMinute(0.0) {} | |||||
| }; | |||||
| /*! | |||||
| * Engine Time information. | |||||
| */ | |||||
| struct CarlaEngineTimeInfo { | |||||
| static const uint32_t ValidBBT = 0x1; | |||||
| bool playing; | |||||
| uint32_t frame; | |||||
| uint32_t time; | |||||
| uint32_t valid; | |||||
| CarlaEngineTimeInfoBBT bbt; | |||||
| CarlaEngineTimeInfo() | |||||
| : playing(false), | |||||
| frame(0), | |||||
| time(0), | |||||
| valid(0) {} | |||||
| }; | |||||
| // LATER - CarlaEngineExtendedMidiEvent | |||||
| /*! | /*! | ||||
| * Engine options. | * Engine options. | ||||
| @@ -236,11 +193,13 @@ struct CarlaEngineOptions { | |||||
| uint preferredBufferSize; | uint preferredBufferSize; | ||||
| uint preferredSampleRate; | uint preferredSampleRate; | ||||
| #ifndef BUILD_BRIDGE | |||||
| CarlaString bridge_native; | CarlaString bridge_native; | ||||
| CarlaString bridge_posix32; | CarlaString bridge_posix32; | ||||
| CarlaString bridge_posix64; | CarlaString bridge_posix64; | ||||
| CarlaString bridge_win32; | CarlaString bridge_win32; | ||||
| CarlaString bridge_win64; | CarlaString bridge_win64; | ||||
| #endif | |||||
| #ifdef WANT_LV2 | #ifdef WANT_LV2 | ||||
| CarlaString bridge_lv2gtk2; | CarlaString bridge_lv2gtk2; | ||||
| CarlaString bridge_lv2gtk3; | CarlaString bridge_lv2gtk3; | ||||
| @@ -257,7 +216,7 @@ struct CarlaEngineOptions { | |||||
| #endif | #endif | ||||
| CarlaEngineOptions() | CarlaEngineOptions() | ||||
| : processMode(PROCESS_MODE_PATCHBAY), | |||||
| : processMode(PROCESS_MODE_CONTINUOUS_RACK), | |||||
| processHighPrecision(false), | processHighPrecision(false), | ||||
| forceStereo(false), | forceStereo(false), | ||||
| preferPluginBridges(false), | preferPluginBridges(false), | ||||
| @@ -265,12 +224,57 @@ struct CarlaEngineOptions { | |||||
| #ifdef WANT_DSSI | #ifdef WANT_DSSI | ||||
| useDssiVstChunks(false), | useDssiVstChunks(false), | ||||
| #endif | #endif | ||||
| maxParameters(MAX_PARAMETERS), | |||||
| oscUiTimeout(4000/100), | |||||
| maxParameters(MAX_DEFAULT_PARAMETERS), | |||||
| oscUiTimeout(4000), | |||||
| preferredBufferSize(512), | preferredBufferSize(512), | ||||
| preferredSampleRate(44100) {} | preferredSampleRate(44100) {} | ||||
| }; | }; | ||||
| /*! | |||||
| * Engine BBT Time information. | |||||
| */ | |||||
| struct CarlaEngineTimeInfoBBT { | |||||
| int32_t bar; //!< current bar | |||||
| int32_t beat; //!< current beat-within-bar | |||||
| int32_t tick; //!< current tick-within-beat | |||||
| double barStartTick; | |||||
| float beatsPerBar; //!< time signature "numerator" | |||||
| float beatType; //!< time signature "denominator" | |||||
| double ticksPerBeat; | |||||
| double beatsPerMinute; | |||||
| CarlaEngineTimeInfoBBT() | |||||
| : bar(0), | |||||
| beat(0), | |||||
| tick(0), | |||||
| barStartTick(0.0), | |||||
| beatsPerBar(0.0f), | |||||
| beatType(0.0f), | |||||
| ticksPerBeat(0.0), | |||||
| beatsPerMinute(0.0) {} | |||||
| }; | |||||
| /*! | |||||
| * Engine Time information. | |||||
| */ | |||||
| struct CarlaEngineTimeInfo { | |||||
| static const uint32_t ValidBBT = 0x1; | |||||
| bool playing; | |||||
| uint32_t frame; | |||||
| uint32_t time; | |||||
| uint32_t valid; | |||||
| CarlaEngineTimeInfoBBT bbt; | |||||
| CarlaEngineTimeInfo() | |||||
| : playing(false), | |||||
| frame(0), | |||||
| time(0), | |||||
| valid(0x0) {} | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| /*! | /*! | ||||
| @@ -566,6 +570,7 @@ public: | |||||
| */ | */ | ||||
| static CarlaEngine* newDriverByName(const char* const driverName); | static CarlaEngine* newDriverByName(const char* const driverName); | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Maximum values | // Maximum values | ||||
| @@ -583,7 +588,7 @@ public: | |||||
| * Maximum number of loadable plugins. | * Maximum number of loadable plugins. | ||||
| * \note This function returns 0 if engine is not started. | * \note This function returns 0 if engine is not started. | ||||
| */ | */ | ||||
| unsigned short maxPluginNumber() const; | |||||
| unsigned int maxPluginNumber() const; | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Virtual, per-engine type calls | // Virtual, per-engine type calls | ||||
| @@ -626,8 +631,10 @@ public: | |||||
| * Get next available plugin id.\n | * Get next available plugin id.\n | ||||
| * Returns -1 if no more plugins can be loaded. | * Returns -1 if no more plugins can be loaded. | ||||
| */ | */ | ||||
| short getNewPluginId() const; | |||||
| int getNewPluginId() const; | |||||
| #if 0 | |||||
| #if 0 | |||||
| /*! | /*! | ||||
| * Get plugin with id \a id. | * Get plugin with id \a id. | ||||
| */ | */ | ||||
| @@ -637,6 +644,7 @@ public: | |||||
| * Get plugin with id \a id, faster unchecked version. | * Get plugin with id \a id, faster unchecked version. | ||||
| */ | */ | ||||
| CarlaPlugin* getPluginUnchecked(const unsigned short id) const; | CarlaPlugin* getPluginUnchecked(const unsigned short id) const; | ||||
| #endif | |||||
| /*! | /*! | ||||
| * Get a unique plugin name within the engine.\n | * Get a unique plugin name within the engine.\n | ||||
| @@ -692,6 +700,14 @@ public: | |||||
| return (const char*)name; | return (const char*)name; | ||||
| } | } | ||||
| /*! | |||||
| * Get current buffer size. | |||||
| */ | |||||
| uint32_t getBufferSize() const | |||||
| { | |||||
| return bufferSize; | |||||
| } | |||||
| /*! | /*! | ||||
| * Get current sample rate. | * Get current sample rate. | ||||
| */ | */ | ||||
| @@ -701,11 +717,11 @@ public: | |||||
| } | } | ||||
| /*! | /*! | ||||
| * Get current buffer size. | |||||
| * Get the engine options (read-only). | |||||
| */ | */ | ||||
| uint32_t getBufferSize() const | |||||
| const CarlaEngineOptions& getOptions() const | |||||
| { | { | ||||
| return bufferSize; | |||||
| return options; | |||||
| } | } | ||||
| /*! | /*! | ||||
| @@ -752,14 +768,6 @@ public: | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Options | // Options | ||||
| /*! | |||||
| * Get the engine options (read-only). | |||||
| */ | |||||
| const CarlaEngineOptions& getOptions() const | |||||
| { | |||||
| return options; | |||||
| } | |||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| /*! | /*! | ||||
| * Get the engine options as process environment. | * Get the engine options as process environment. | ||||
| @@ -842,6 +850,8 @@ public: | |||||
| void setOscBridgeData(const CarlaOscData* const oscData); | void setOscBridgeData(const CarlaOscData* const oscData); | ||||
| #endif | #endif | ||||
| #endif | |||||
| #ifdef BUILD_BRIDGE | #ifdef BUILD_BRIDGE | ||||
| void osc_send_peaks(CarlaPlugin* const plugin); | void osc_send_peaks(CarlaPlugin* const plugin); | ||||
| #else | #else | ||||
| @@ -93,8 +93,7 @@ enum PluginPostEventType { | |||||
| PluginPostEventProgramChange, // index | PluginPostEventProgramChange, // index | ||||
| PluginPostEventMidiProgramChange, // index | PluginPostEventMidiProgramChange, // index | ||||
| PluginPostEventNoteOn, // channel, note, velo | PluginPostEventNoteOn, // channel, note, velo | ||||
| PluginPostEventNoteOff, // channel, note | |||||
| PluginPostEventCustom | |||||
| PluginPostEventNoteOff // channel, note | |||||
| }; | }; | ||||
| struct PluginAudioData { | struct PluginAudioData { | ||||
| @@ -159,14 +158,12 @@ struct PluginPostEvent { | |||||
| int32_t value1; | int32_t value1; | ||||
| int32_t value2; | int32_t value2; | ||||
| double value3; | double value3; | ||||
| const void* cdata; | |||||
| PluginPostEvent() | PluginPostEvent() | ||||
| : type(PluginPostEventNull), | : type(PluginPostEventNull), | ||||
| value1(-1), | value1(-1), | ||||
| value2(-1), | value2(-1), | ||||
| value3(0.0), | |||||
| cdata(nullptr) {} | |||||
| value3(0.0) {} | |||||
| }; | }; | ||||
| struct ExternalMidiNote { | struct ExternalMidiNote { | ||||
| @@ -180,7 +177,7 @@ struct ExternalMidiNote { | |||||
| velo(0) {} | velo(0) {} | ||||
| }; | }; | ||||
| class CarlaPluginPrivateData; | |||||
| struct CarlaPluginPrivateData; | |||||
| /*! | /*! | ||||
| * \class CarlaPlugin | * \class CarlaPlugin | ||||
| @@ -80,7 +80,7 @@ void CarlaEngineAudioPort::initBuffer(CarlaEngine* const) | |||||
| CarlaEngineControlPort::CarlaEngineControlPort(const bool isInput, const ProcessMode processMode) | CarlaEngineControlPort::CarlaEngineControlPort(const bool isInput, const ProcessMode processMode) | ||||
| : CarlaEnginePort(isInput, processMode), | : CarlaEnginePort(isInput, processMode), | ||||
| m_maxEventCount(processMode == PROCESS_MODE_CONTINUOUS_RACK ? CarlaEngine::MAX_CONTROL_EVENTS : PATCHBAY_EVENT_COUNT) | |||||
| m_maxEventCount(/*processMode == PROCESS_MODE_CONTINUOUS_RACK ? CarlaEngine::MAX_CONTROL_EVENTS :*/ PATCHBAY_EVENT_COUNT) | |||||
| { | { | ||||
| qDebug("CarlaEngineControlPort::CarlaEngineControlPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode)); | qDebug("CarlaEngineControlPort::CarlaEngineControlPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode)); | ||||
| @@ -224,7 +224,7 @@ void CarlaEngineControlPort::writeEvent(const CarlaEngineControlEventType type, | |||||
| CarlaEngineMidiPort::CarlaEngineMidiPort(const bool isInput, const ProcessMode processMode) | CarlaEngineMidiPort::CarlaEngineMidiPort(const bool isInput, const ProcessMode processMode) | ||||
| : CarlaEnginePort(isInput, processMode), | : CarlaEnginePort(isInput, processMode), | ||||
| m_maxEventCount(processMode == PROCESS_MODE_CONTINUOUS_RACK ? CarlaEngine::MAX_MIDI_EVENTS : PATCHBAY_EVENT_COUNT) | |||||
| m_maxEventCount(/*processMode == PROCESS_MODE_CONTINUOUS_RACK ? CarlaEngine::MAX_MIDI_EVENTS :*/ PATCHBAY_EVENT_COUNT) | |||||
| { | { | ||||
| qDebug("CarlaEngineMidiPort::CarlaEngineMidiPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode)); | qDebug("CarlaEngineMidiPort::CarlaEngineMidiPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode)); | ||||
| @@ -416,7 +416,7 @@ void CarlaEngineClient::setLatency(const uint32_t samples) | |||||
| } | } | ||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| // Carla Engine Client | |||||
| // Carla Engine | |||||
| CarlaEngine::CarlaEngine() | CarlaEngine::CarlaEngine() | ||||
| : data(new CarlaEnginePrivateData(this)) | : data(new CarlaEnginePrivateData(this)) | ||||
| @@ -530,7 +530,7 @@ int CarlaEngine::maxPortNameSize() | |||||
| return STR_MAX; | return STR_MAX; | ||||
| } | } | ||||
| unsigned short CarlaEngine::maxPluginNumber() const | |||||
| unsigned int CarlaEngine::maxPluginNumber() const | |||||
| { | { | ||||
| return data->maxPluginNumber; | return data->maxPluginNumber; | ||||
| } | } | ||||
| @@ -546,6 +546,7 @@ bool CarlaEngine::init(const char* const clientName) | |||||
| data->aboutToClose = false; | data->aboutToClose = false; | ||||
| data->maxPluginNumber = 0; | data->maxPluginNumber = 0; | ||||
| data->nextPluginId = 0; | |||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| data->oscData = data->osc.getControlData(); | data->oscData = data->osc.getControlData(); | ||||
| @@ -558,6 +559,9 @@ bool CarlaEngine::init(const char* const clientName) | |||||
| carla_setprocname(clientName); | carla_setprocname(clientName); | ||||
| #endif | #endif | ||||
| //data->postEvents.resize(); | |||||
| //data->plugins.resize(); | |||||
| data->thread.startNow(); | data->thread.startNow(); | ||||
| return true; | return true; | ||||
| @@ -586,20 +590,17 @@ bool CarlaEngine::close() | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Plugin management | // Plugin management | ||||
| short CarlaEngine::getNewPluginId() const | |||||
| int CarlaEngine::getNewPluginId() const | |||||
| { | { | ||||
| qDebug("CarlaEngine::getNewPluginId()"); | qDebug("CarlaEngine::getNewPluginId()"); | ||||
| CARLA_ASSERT(data->maxPluginNumber > 0); | CARLA_ASSERT(data->maxPluginNumber > 0); | ||||
| for (unsigned short i=0; i < data->maxPluginNumber; i++) | |||||
| { | |||||
| if (! data->carlaPlugins[i]) | |||||
| return i; | |||||
| } | |||||
| return -1; | |||||
| return data->nextPluginId; | |||||
| } | } | ||||
| #if 0 | |||||
| #if 0 | |||||
| CarlaPlugin* CarlaEngine::getPlugin(const unsigned short id) const | CarlaPlugin* CarlaEngine::getPlugin(const unsigned short id) const | ||||
| { | { | ||||
| qDebug("CarlaEngine::getPlugin(%i) [max:%i]", id, data->maxPluginNumber); | qDebug("CarlaEngine::getPlugin(%i) [max:%i]", id, data->maxPluginNumber); | ||||
| @@ -616,6 +617,7 @@ CarlaPlugin* CarlaEngine::getPluginUnchecked(const unsigned short id) const | |||||
| { | { | ||||
| return data->carlaPlugins[id]; | return data->carlaPlugins[id]; | ||||
| } | } | ||||
| #endif | |||||
| const char* CarlaEngine::getUniquePluginName(const char* const name) | const char* CarlaEngine::getUniquePluginName(const char* const name) | ||||
| { | { | ||||
| @@ -631,6 +633,7 @@ const char* CarlaEngine::getUniquePluginName(const char* const name) | |||||
| sname.truncate(maxClientNameSize()-5-1); // 5 = strlen(" (10)") | sname.truncate(maxClientNameSize()-5-1); // 5 = strlen(" (10)") | ||||
| sname.replace(':', '.'); // ':' is used in JACK1 to split client/port names | sname.replace(':', '.'); // ':' is used in JACK1 to split client/port names | ||||
| #if 0 | |||||
| for (unsigned short i=0; i < data->maxPluginNumber; i++) | for (unsigned short i=0; i < data->maxPluginNumber; i++) | ||||
| { | { | ||||
| // Check if unique name doesn't exist | // Check if unique name doesn't exist | ||||
| @@ -683,6 +686,7 @@ const char* CarlaEngine::getUniquePluginName(const char* const name) | |||||
| // Modify string if not | // Modify string if not | ||||
| sname += " (2)"; | sname += " (2)"; | ||||
| } | } | ||||
| #endif | |||||
| return strdup(sname); | return strdup(sname); | ||||
| } | } | ||||
| @@ -695,12 +699,24 @@ short CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, con | |||||
| CARLA_ASSERT(filename); | CARLA_ASSERT(filename); | ||||
| CARLA_ASSERT(label); | CARLA_ASSERT(label); | ||||
| if (QThread::currentThread() != &data->thread) | |||||
| { | |||||
| EnginePostEvent postEvent; | |||||
| data->postEvents.append(postEvent); | |||||
| return; | |||||
| } | |||||
| if (data->maxPluginNumber == 0) | if (data->maxPluginNumber == 0) | ||||
| { | { | ||||
| #ifdef BUILD_BRIDGE | #ifdef BUILD_BRIDGE | ||||
| data->maxPluginNumber = MAX_PLUGINS; // which is 1 | data->maxPluginNumber = MAX_PLUGINS; // which is 1 | ||||
| #else | #else | ||||
| data->maxPluginNumber = (options.processMode == PROCESS_MODE_CONTINUOUS_RACK) ? 16 : MAX_PLUGINS; | |||||
| if (options.processMode == PROCESS_MODE_CONTINUOUS_RACK) | |||||
| data->maxPluginNumber = MAX_RACK_PLUGINS; | |||||
| else if (options.processMode == PROCESS_MODE_PATCHBAY) | |||||
| data->maxPluginNumber = MAX_PATCHBAY_PLUGINS; | |||||
| else | |||||
| data->maxPluginNumber = MAX_DEFAULT_PLUGINS; | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -781,8 +797,8 @@ short CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, con | |||||
| const short id = plugin->id(); | const short id = plugin->id(); | ||||
| data->carlaPlugins[id] = plugin; | |||||
| data->uniqueNames[id] = plugin->name(); | |||||
| EnginePluginData pluginData(plugin); | |||||
| data->plugins.append(pluginData); | |||||
| return id; | return id; | ||||
| } | } | ||||
| @@ -1170,6 +1186,8 @@ void CarlaEngine::setOscBridgeData(const CarlaOscData* const oscData) | |||||
| } | } | ||||
| #endif | #endif | ||||
| #endif | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // protected calls | // protected calls | ||||
| @@ -1184,6 +1202,7 @@ void CarlaEngine::processRack(float* inBuf[2], float* outBuf[2], const uint32_t | |||||
| bool processed = false; | bool processed = false; | ||||
| #if 0 | |||||
| // process plugins | // process plugins | ||||
| for (unsigned short i=0, max=maxPluginNumber(); i < max; i++) | for (unsigned short i=0, max=maxPluginNumber(); i < max; i++) | ||||
| { | { | ||||
| @@ -1274,6 +1293,7 @@ void CarlaEngine::processRack(float* inBuf[2], float* outBuf[2], const uint32_t | |||||
| processed = true; | processed = true; | ||||
| } | } | ||||
| #endif | |||||
| // if no plugins in the rack, copy inputs over outputs | // if no plugins in the rack, copy inputs over outputs | ||||
| if (! processed) | if (! processed) | ||||
| @@ -1298,11 +1318,13 @@ void CarlaEngine::bufferSizeChanged(const uint32_t newBufferSize) | |||||
| { | { | ||||
| qDebug("CarlaEngine::bufferSizeChanged(%i)", newBufferSize); | qDebug("CarlaEngine::bufferSizeChanged(%i)", newBufferSize); | ||||
| #if 0 | |||||
| for (unsigned short i=0; i < data->maxPluginNumber; i++) | for (unsigned short i=0; i < data->maxPluginNumber; i++) | ||||
| { | { | ||||
| if (data->carlaPlugins[i] && data->carlaPlugins[i]->enabled() /*&& ! data->carlaPlugins[i]->data->processHighPrecision*/) | if (data->carlaPlugins[i] && data->carlaPlugins[i]->enabled() /*&& ! data->carlaPlugins[i]->data->processHighPrecision*/) | ||||
| data->carlaPlugins[i]->bufferSizeChanged(newBufferSize); | data->carlaPlugins[i]->bufferSizeChanged(newBufferSize); | ||||
| } | } | ||||
| #endif | |||||
| } | } | ||||
| void CarlaEngine::sampleRateChanged(const double newSampleRate) | void CarlaEngine::sampleRateChanged(const double newSampleRate) | ||||
| @@ -1349,7 +1371,7 @@ void CarlaEngine::osc_send_control_add_plugin_start(const int32_t pluginId, cons | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_add_plugin_start(%i, \"%s\")", pluginId, pluginName); | qDebug("CarlaEngine::osc_send_control_add_plugin_start(%i, \"%s\")", pluginId, pluginName); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginName); | CARLA_ASSERT(pluginName); | ||||
| if (data->oscData && data->oscData->target) | if (data->oscData && data->oscData->target) | ||||
| @@ -1365,7 +1387,7 @@ void CarlaEngine::osc_send_control_add_plugin_end(const int32_t pluginId) | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_add_plugin_end(%i)", pluginId); | qDebug("CarlaEngine::osc_send_control_add_plugin_end(%i)", pluginId); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| if (data->oscData && data->oscData->target) | if (data->oscData && data->oscData->target) | ||||
| { | { | ||||
| @@ -1380,7 +1402,7 @@ void CarlaEngine::osc_send_control_remove_plugin(const int32_t pluginId) | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_remove_plugin(%i)", pluginId); | qDebug("CarlaEngine::osc_send_control_remove_plugin(%i)", pluginId); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| if (data->oscData && data->oscData->target) | if (data->oscData && data->oscData->target) | ||||
| { | { | ||||
| @@ -1395,7 +1417,7 @@ void CarlaEngine::osc_send_control_set_plugin_data(const int32_t pluginId, const | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_set_plugin_data(%i, %i, %i, %i, \"%s\", \"%s\", \"%s\", \"%s\", " P_INT64 ")", pluginId, type, category, hints, realName, label, maker, copyright, uniqueId); | qDebug("CarlaEngine::osc_send_control_set_plugin_data(%i, %i, %i, %i, \"%s\", \"%s\", \"%s\", \"%s\", " P_INT64 ")", pluginId, type, category, hints, realName, label, maker, copyright, uniqueId); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| CARLA_ASSERT(type != PLUGIN_NONE); | CARLA_ASSERT(type != PLUGIN_NONE); | ||||
| if (data->oscData && data->oscData->target) | if (data->oscData && data->oscData->target) | ||||
| @@ -1411,7 +1433,7 @@ void CarlaEngine::osc_send_control_set_plugin_ports(const int32_t pluginId, cons | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_set_plugin_ports(%i, %i, %i, %i, %i, %i, %i, %i)", pluginId, audioIns, audioOuts, midiIns, midiOuts, cIns, cOuts, cTotals); | qDebug("CarlaEngine::osc_send_control_set_plugin_ports(%i, %i, %i, %i, %i, %i, %i, %i)", pluginId, audioIns, audioOuts, midiIns, midiOuts, cIns, cOuts, cTotals); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| if (data->oscData && data->oscData->target) | if (data->oscData && data->oscData->target) | ||||
| { | { | ||||
| @@ -1426,7 +1448,7 @@ void CarlaEngine::osc_send_control_set_parameter_data(const int32_t pluginId, co | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_set_parameter_data(%i, %i, %i, %i, \"%s\", \"%s\", %g)", pluginId, index, type, hints, name, label, current); | qDebug("CarlaEngine::osc_send_control_set_parameter_data(%i, %i, %i, %i, \"%s\", \"%s\", %g)", pluginId, index, type, hints, name, label, current); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| CARLA_ASSERT(index >= 0); | CARLA_ASSERT(index >= 0); | ||||
| CARLA_ASSERT(type != PARAMETER_UNKNOWN); | CARLA_ASSERT(type != PARAMETER_UNKNOWN); | ||||
| @@ -1443,7 +1465,7 @@ void CarlaEngine::osc_send_control_set_parameter_ranges(const int32_t pluginId, | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_set_parameter_ranges(%i, %i, %g, %g, %g, %g, %g, %g)", pluginId, index, min, max, def, step, stepSmall, stepLarge); | qDebug("CarlaEngine::osc_send_control_set_parameter_ranges(%i, %i, %g, %g, %g, %g, %g, %g)", pluginId, index, min, max, def, step, stepSmall, stepLarge); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| CARLA_ASSERT(index >= 0); | CARLA_ASSERT(index >= 0); | ||||
| CARLA_ASSERT(min < max); | CARLA_ASSERT(min < max); | ||||
| @@ -1460,7 +1482,7 @@ void CarlaEngine::osc_send_control_set_parameter_midi_cc(const int32_t pluginId, | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_set_parameter_midi_cc(%i, %i, %i)", pluginId, index, cc); | qDebug("CarlaEngine::osc_send_control_set_parameter_midi_cc(%i, %i, %i)", pluginId, index, cc); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| CARLA_ASSERT(index >= 0); | CARLA_ASSERT(index >= 0); | ||||
| if (data->oscData && data->oscData->target) | if (data->oscData && data->oscData->target) | ||||
| @@ -1476,7 +1498,7 @@ void CarlaEngine::osc_send_control_set_parameter_midi_channel(const int32_t plug | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_set_parameter_midi_channel(%i, %i, %i)", pluginId, index, channel); | qDebug("CarlaEngine::osc_send_control_set_parameter_midi_channel(%i, %i, %i)", pluginId, index, channel); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| CARLA_ASSERT(index >= 0); | CARLA_ASSERT(index >= 0); | ||||
| CARLA_ASSERT(channel >= 0 && channel < 16); | CARLA_ASSERT(channel >= 0 && channel < 16); | ||||
| @@ -1498,7 +1520,7 @@ void CarlaEngine::osc_send_control_set_parameter_value(const int32_t pluginId, c | |||||
| qDebug("CarlaEngine::osc_send_control_set_parameter_value(%i, %i, %g)", pluginId, index, value); | qDebug("CarlaEngine::osc_send_control_set_parameter_value(%i, %i, %g)", pluginId, index, value); | ||||
| #endif | #endif | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| if (data->oscData && data->oscData->target) | if (data->oscData && data->oscData->target) | ||||
| { | { | ||||
| @@ -1513,7 +1535,7 @@ void CarlaEngine::osc_send_control_set_default_value(const int32_t pluginId, con | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_set_default_value(%i, %i, %g)", pluginId, index, value); | qDebug("CarlaEngine::osc_send_control_set_default_value(%i, %i, %g)", pluginId, index, value); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| CARLA_ASSERT(index >= 0); | CARLA_ASSERT(index >= 0); | ||||
| if (data->oscData && data->oscData->target) | if (data->oscData && data->oscData->target) | ||||
| @@ -1529,7 +1551,7 @@ void CarlaEngine::osc_send_control_set_program(const int32_t pluginId, const int | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_set_program(%i, %i)", pluginId, index); | qDebug("CarlaEngine::osc_send_control_set_program(%i, %i)", pluginId, index); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| if (data->oscData && data->oscData->target) | if (data->oscData && data->oscData->target) | ||||
| { | { | ||||
| @@ -1544,7 +1566,7 @@ void CarlaEngine::osc_send_control_set_program_count(const int32_t pluginId, con | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_set_program_count(%i, %i)", pluginId, count); | qDebug("CarlaEngine::osc_send_control_set_program_count(%i, %i)", pluginId, count); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| CARLA_ASSERT(count >= 0); | CARLA_ASSERT(count >= 0); | ||||
| if (data->oscData && data->oscData->target) | if (data->oscData && data->oscData->target) | ||||
| @@ -1560,7 +1582,7 @@ void CarlaEngine::osc_send_control_set_program_name(const int32_t pluginId, cons | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_set_program_name(%i, %i, \"%s\")", pluginId, index, name); | qDebug("CarlaEngine::osc_send_control_set_program_name(%i, %i, \"%s\")", pluginId, index, name); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| CARLA_ASSERT(index >= 0); | CARLA_ASSERT(index >= 0); | ||||
| CARLA_ASSERT(name); | CARLA_ASSERT(name); | ||||
| @@ -1577,7 +1599,7 @@ void CarlaEngine::osc_send_control_set_midi_program(const int32_t pluginId, cons | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_set_midi_program(%i, %i)", pluginId, index); | qDebug("CarlaEngine::osc_send_control_set_midi_program(%i, %i)", pluginId, index); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| if (data->oscData && data->oscData->target) | if (data->oscData && data->oscData->target) | ||||
| { | { | ||||
| @@ -1592,7 +1614,7 @@ void CarlaEngine::osc_send_control_set_midi_program_count(const int32_t pluginId | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_set_midi_program_count(%i, %i)", pluginId, count); | qDebug("CarlaEngine::osc_send_control_set_midi_program_count(%i, %i)", pluginId, count); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| CARLA_ASSERT(count >= 0); | CARLA_ASSERT(count >= 0); | ||||
| if (data->oscData && data->oscData->target) | if (data->oscData && data->oscData->target) | ||||
| @@ -1608,7 +1630,7 @@ void CarlaEngine::osc_send_control_set_midi_program_data(const int32_t pluginId, | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_set_midi_program_data(%i, %i, %i, %i, \"%s\")", pluginId, index, bank, program, name); | qDebug("CarlaEngine::osc_send_control_set_midi_program_data(%i, %i, %i, %i, \"%s\")", pluginId, index, bank, program, name); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| CARLA_ASSERT(index >= 0); | CARLA_ASSERT(index >= 0); | ||||
| CARLA_ASSERT(bank >= 0); | CARLA_ASSERT(bank >= 0); | ||||
| CARLA_ASSERT(program >= 0); | CARLA_ASSERT(program >= 0); | ||||
| @@ -1627,7 +1649,7 @@ void CarlaEngine::osc_send_control_note_on(const int32_t pluginId, const int32_t | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_note_on(%i, %i, %i, %i)", pluginId, channel, note, velo); | qDebug("CarlaEngine::osc_send_control_note_on(%i, %i, %i, %i)", pluginId, channel, note, velo); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| CARLA_ASSERT(channel >= 0 && channel < 16); | CARLA_ASSERT(channel >= 0 && channel < 16); | ||||
| CARLA_ASSERT(note >= 0 && note < 128); | CARLA_ASSERT(note >= 0 && note < 128); | ||||
| CARLA_ASSERT(velo > 0 && velo < 128); | CARLA_ASSERT(velo > 0 && velo < 128); | ||||
| @@ -1645,7 +1667,7 @@ void CarlaEngine::osc_send_control_note_off(const int32_t pluginId, const int32_ | |||||
| { | { | ||||
| qDebug("CarlaEngine::osc_send_control_note_off(%i, %i, %i)", pluginId, channel, note); | qDebug("CarlaEngine::osc_send_control_note_off(%i, %i, %i)", pluginId, channel, note); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| CARLA_ASSERT(channel >= 0 && channel < 16); | CARLA_ASSERT(channel >= 0 && channel < 16); | ||||
| CARLA_ASSERT(note >= 0 && note < 128); | CARLA_ASSERT(note >= 0 && note < 128); | ||||
| @@ -1658,11 +1680,12 @@ void CarlaEngine::osc_send_control_note_off(const int32_t pluginId, const int32_ | |||||
| } | } | ||||
| } | } | ||||
| #if 0 | |||||
| void CarlaEngine::osc_send_control_set_input_peak_value(const int32_t pluginId, const int32_t portId) | void CarlaEngine::osc_send_control_set_input_peak_value(const int32_t pluginId, const int32_t portId) | ||||
| { | { | ||||
| //qDebug("CarlaEngine::osc_send_control_set_input_peak_value(%i, %i)", pluginId, portId); | //qDebug("CarlaEngine::osc_send_control_set_input_peak_value(%i, %i)", pluginId, portId); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| CARLA_ASSERT(portId == 1 || portId == 2); | CARLA_ASSERT(portId == 1 || portId == 2); | ||||
| if (data->oscData && data->oscData->target) | if (data->oscData && data->oscData->target) | ||||
| @@ -1678,7 +1701,7 @@ void CarlaEngine::osc_send_control_set_output_peak_value(const int32_t pluginId, | |||||
| { | { | ||||
| //qDebug("CarlaEngine::osc_send_control_set_output_peak_value(%i, %i)", pluginId, portId); | //qDebug("CarlaEngine::osc_send_control_set_output_peak_value(%i, %i)", pluginId, portId); | ||||
| CARLA_ASSERT(data->oscData); | CARLA_ASSERT(data->oscData); | ||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||||
| CARLA_ASSERT(portId == 1 || portId == 2); | CARLA_ASSERT(portId == 1 || portId == 2); | ||||
| if (data->oscData && data->oscData->target) | if (data->oscData && data->oscData->target) | ||||
| @@ -1689,6 +1712,7 @@ void CarlaEngine::osc_send_control_set_output_peak_value(const int32_t pluginId, | |||||
| lo_send(data->oscData->target, target_path, "iid", pluginId, portId, data->outsPeak[pluginId*MAX_PEAKS + portId-1]); | lo_send(data->oscData->target, target_path, "iid", pluginId, portId, data->outsPeak[pluginId*MAX_PEAKS + portId-1]); | ||||
| } | } | ||||
| } | } | ||||
| #endif | |||||
| void CarlaEngine::osc_send_control_exit() | void CarlaEngine::osc_send_control_exit() | ||||
| { | { | ||||
| @@ -31,8 +31,8 @@ VERSION = 0.5.0 | |||||
| SOURCES = \ | SOURCES = \ | ||||
| carla_engine.cpp \ | carla_engine.cpp \ | ||||
| carla_engine_osc.cpp \ | |||||
| carla_engine_thread.cpp \ | |||||
| # carla_engine_osc.cpp \ | |||||
| # carla_engine_thread.cpp \ | |||||
| jack.cpp \ | jack.cpp \ | ||||
| plugin.cpp \ | plugin.cpp \ | ||||
| rtaudio.cpp | rtaudio.cpp | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * Carla Engine | * Carla Engine | ||||
| * Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * This program is free software; you can redistribute it and/or modify | * 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 | * it under the terms of the GNU General Public License as published by | ||||
| @@ -9,7 +9,7 @@ | |||||
| * | * | ||||
| * This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | * GNU General Public License for more details. | ||||
| * | * | ||||
| * For a full copy of the GNU General Public License see the COPYING file | * For a full copy of the GNU General Public License see the COPYING file | ||||
| @@ -24,6 +24,8 @@ | |||||
| #include "carla_plugin.hpp" | #include "carla_plugin.hpp" | ||||
| #include "rt_list.hpp" | |||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| # include <QtCore/QProcessEnvironment> | # include <QtCore/QProcessEnvironment> | ||||
| #endif | #endif | ||||
| @@ -104,6 +106,37 @@ const char* CarlaEngineControlEventType2Str(const CarlaEngineControlEventType ty | |||||
| const uint32_t PATCHBAY_BUFFER_SIZE = 128; | const uint32_t PATCHBAY_BUFFER_SIZE = 128; | ||||
| const unsigned short PATCHBAY_EVENT_COUNT = 256; | const unsigned short PATCHBAY_EVENT_COUNT = 256; | ||||
| enum EnginePostEventType { | |||||
| EnginePostEventNull, | |||||
| EnginePostEventDebug, | |||||
| PluginPostEventAddPlugin, // id, ptr | |||||
| PluginPostEventRemovePlugin // id | |||||
| }; | |||||
| struct EnginePostEvent { | |||||
| EnginePostEventType type; | |||||
| int32_t value1; | |||||
| void* valuePtr; | |||||
| EnginePostEvent() | |||||
| : type(EnginePostEventNull), | |||||
| value1(-1), | |||||
| valuePtr(nullptr) {} | |||||
| }; | |||||
| struct EnginePluginData { | |||||
| CarlaPlugin* const plugin; | |||||
| double insPeak[MAX_PEAKS]; | |||||
| double outsPeak[MAX_PEAKS]; | |||||
| EnginePluginData(CarlaPlugin* const plugin_) | |||||
| : plugin(plugin_), | |||||
| insPeak{0}, | |||||
| outsPeak{0} {} | |||||
| EnginePluginData() = delete; | |||||
| }; | |||||
| struct CarlaEnginePrivateData { | struct CarlaEnginePrivateData { | ||||
| CarlaEngineOsc osc; | CarlaEngineOsc osc; | ||||
| CarlaEngineThread thread; | CarlaEngineThread thread; | ||||
| @@ -112,24 +145,25 @@ struct CarlaEnginePrivateData { | |||||
| CallbackFunc callback; | CallbackFunc callback; | ||||
| void* callbackPtr; | void* callbackPtr; | ||||
| CarlaString lastError; | CarlaString lastError; | ||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| QProcessEnvironment procEnv; | QProcessEnvironment procEnv; | ||||
| #endif | #endif | ||||
| CarlaMutex procLock; | |||||
| CarlaMutex midiLock; | |||||
| // for postEvents | |||||
| CarlaMutex eventLock; | |||||
| // TODO - use ListHead for pointers, remove maximum static value | |||||
| CarlaPlugin* carlaPlugins[MAX_PLUGINS]; | |||||
| const char* uniqueNames[MAX_PLUGINS]; | |||||
| // for external midi input (GUI and OSC) | |||||
| CarlaMutex midiLock; | |||||
| double insPeak[MAX_PLUGINS * MAX_PEAKS]; | |||||
| double outsPeak[MAX_PLUGINS * MAX_PEAKS]; | |||||
| RtList<EnginePostEvent> postEvents; | |||||
| RtList<EnginePluginData> plugins; | |||||
| bool aboutToClose; | bool aboutToClose; | ||||
| unsigned short maxPluginNumber; | |||||
| unsigned int maxPluginNumber; | |||||
| unsigned int nextPluginId; | |||||
| CarlaEnginePrivateData(CarlaEngine* const engine) | CarlaEnginePrivateData(CarlaEngine* const engine) | ||||
| : osc(engine), | : osc(engine), | ||||
| @@ -137,12 +171,11 @@ struct CarlaEnginePrivateData { | |||||
| oscData(nullptr), | oscData(nullptr), | ||||
| callback(nullptr), | callback(nullptr), | ||||
| callbackPtr(nullptr), | callbackPtr(nullptr), | ||||
| carlaPlugins{nullptr}, | |||||
| uniqueNames{nullptr}, | |||||
| insPeak{0.0}, | |||||
| outsPeak{0.0}, | |||||
| postEvents(1, 1), | |||||
| plugins(1, 1), | |||||
| aboutToClose(false), | aboutToClose(false), | ||||
| maxPluginNumber(0) {} | |||||
| maxPluginNumber(0), | |||||
| nextPluginId(0) {} | |||||
| }; | }; | ||||
| CARLA_BACKEND_END_NAMESPACE | CARLA_BACKEND_END_NAMESPACE | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * Carla Engine OSC | * Carla Engine OSC | ||||
| * Copyright (C) 2012 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * This program is free software; you can redistribute it and/or modify | * 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 | * it under the terms of the GNU General Public License as published by | ||||
| @@ -9,14 +9,14 @@ | |||||
| * | * | ||||
| * This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | * GNU General Public License for more details. | ||||
| * | * | ||||
| * For a full copy of the GNU General Public License see the COPYING file | * For a full copy of the GNU General Public License see the COPYING file | ||||
| */ | */ | ||||
| #ifndef CARLA_ENGINE_OSC_HPP | |||||
| #define CARLA_ENGINE_OSC_HPP | |||||
| #ifndef __CARLA_ENGINE_OSC_HPP__ | |||||
| #define __CARLA_ENGINE_OSC_HPP__ | |||||
| #include "carla_backend.hpp" | #include "carla_backend.hpp" | ||||
| #include "carla_osc_utils.hpp" | #include "carla_osc_utils.hpp" | ||||
| @@ -166,4 +166,4 @@ private: | |||||
| CARLA_BACKEND_END_NAMESPACE | CARLA_BACKEND_END_NAMESPACE | ||||
| #endif // CARLA_ENGINE_OSC_HPP | |||||
| #endif // __CARLA_ENGINE_OSC_HPP__ | |||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * Carla Engine Thread | * Carla Engine Thread | ||||
| * Copyright (C) 2012 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * This program is free software; you can redistribute it and/or modify | * 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 | * it under the terms of the GNU General Public License as published by | ||||
| @@ -9,18 +9,18 @@ | |||||
| * | * | ||||
| * This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | * GNU General Public License for more details. | ||||
| * | * | ||||
| * For a full copy of the GNU General Public License see the COPYING file | * For a full copy of the GNU General Public License see the COPYING file | ||||
| */ | */ | ||||
| #ifndef CARLA_ENGINE_THREAD_HPP | |||||
| #define CARLA_ENGINE_THREAD_HPP | |||||
| #ifndef __CARLA_ENGINE_THREAD_HPP__ | |||||
| #define __CARLA_ENGINE_THREAD_HPP__ | |||||
| #include "carla_backend.hpp" | #include "carla_backend.hpp" | ||||
| #include "carla_utils.hpp" | |||||
| #include <QtCore/QMutex> | |||||
| #include <QtCore/QThread> | #include <QtCore/QThread> | ||||
| CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
| @@ -48,11 +48,12 @@ protected: | |||||
| private: | private: | ||||
| CarlaEngine* const engine; | CarlaEngine* const engine; | ||||
| QMutex m_mutex; | |||||
| bool m_stopNow; | |||||
| CarlaMutex m_mutex; | |||||
| bool m_stopNow; | |||||
| // ---------------------------------------------- | // ---------------------------------------------- | ||||
| #if 0 | |||||
| class ScopedLocker | class ScopedLocker | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -68,10 +69,11 @@ private: | |||||
| } | } | ||||
| private: | private: | ||||
| QMutex* const mutex; | |||||
| CarlaMutex* const mutex; | |||||
| }; | }; | ||||
| #endif | |||||
| }; | }; | ||||
| CARLA_BACKEND_END_NAMESPACE | CARLA_BACKEND_END_NAMESPACE | ||||
| #endif // CARLA_ENGINE_THREAD_HPP | |||||
| #endif // __CARLA_ENGINE_THREAD_HPP__ | |||||
| @@ -65,7 +65,7 @@ public: | |||||
| if (! m_port) | if (! m_port) | ||||
| return CarlaEngineAudioPort::initBuffer(engine); | return CarlaEngineAudioPort::initBuffer(engine); | ||||
| buffer = jackbridge_port_get_buffer(m_port, engine->getBufferSize()); | |||||
| //buffer = jackbridge_port_get_buffer(m_port, engine->getBufferSize()); | |||||
| } | } | ||||
| float* getBuffer() const | float* getBuffer() const | ||||
| @@ -118,7 +118,7 @@ public: | |||||
| if (! m_port) | if (! m_port) | ||||
| return CarlaEngineControlPort::initBuffer(engine); | return CarlaEngineControlPort::initBuffer(engine); | ||||
| buffer = jackbridge_port_get_buffer(m_port, engine->getBufferSize()); | |||||
| //buffer = jackbridge_port_get_buffer(m_port, engine->getBufferSize()); | |||||
| if (! isInput) | if (! isInput) | ||||
| jackbridge_midi_clear_buffer(buffer); | jackbridge_midi_clear_buffer(buffer); | ||||
| @@ -317,7 +317,7 @@ public: | |||||
| if (! m_port) | if (! m_port) | ||||
| return CarlaEngineMidiPort::initBuffer(engine); | return CarlaEngineMidiPort::initBuffer(engine); | ||||
| buffer = jackbridge_port_get_buffer(m_port, engine->getBufferSize()); | |||||
| //buffer = jackbridge_port_get_buffer(m_port, engine->getBufferSize()); | |||||
| if (! isInput) | if (! isInput) | ||||
| jackbridge_midi_clear_buffer(buffer); | jackbridge_midi_clear_buffer(buffer); | ||||
| @@ -515,9 +515,7 @@ public: | |||||
| CarlaEngineJack() | CarlaEngineJack() | ||||
| : CarlaEngine() | : CarlaEngine() | ||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| # ifdef Q_COMPILER_INITIALIZER_LISTS | |||||
| , m_rackPorts{nullptr} | , m_rackPorts{nullptr} | ||||
| # endif | |||||
| #endif | #endif | ||||
| { | { | ||||
| qDebug("CarlaEngineJack::CarlaEngineJack()"); | qDebug("CarlaEngineJack::CarlaEngineJack()"); | ||||
| @@ -530,11 +528,6 @@ public: | |||||
| #ifdef BUILD_BRIDGE | #ifdef BUILD_BRIDGE | ||||
| hasQuit = false; | hasQuit = false; | ||||
| #else | |||||
| # ifndef Q_COMPILER_INITIALIZER_LISTS | |||||
| for (int i=0; i < rackPortCount; i++) | |||||
| m_rackPorts[i] = nullptr; | |||||
| # endif | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -741,6 +734,8 @@ public: | |||||
| #endif | #endif | ||||
| } | } | ||||
| #if 0 | |||||
| // ------------------------------------- | // ------------------------------------- | ||||
| protected: | protected: | ||||
| @@ -1025,6 +1020,7 @@ protected: | |||||
| } | } | ||||
| // ------------------------------------- | // ------------------------------------- | ||||
| #endif | |||||
| private: | private: | ||||
| jack_client_t* m_client; | jack_client_t* m_client; | ||||
| @@ -1052,6 +1048,7 @@ private: | |||||
| jack_port_t* m_rackPorts[rackPortCount]; | jack_port_t* m_rackPorts[rackPortCount]; | ||||
| #endif | #endif | ||||
| #if 0 | |||||
| // ------------------------------------- | // ------------------------------------- | ||||
| static void processPlugin(CarlaPlugin* const p, const uint32_t nframes) | static void processPlugin(CarlaPlugin* const p, const uint32_t nframes) | ||||
| @@ -1192,6 +1189,7 @@ private: | |||||
| if (plugin && plugin->enabled()) | if (plugin && plugin->enabled()) | ||||
| latencyPlugin(plugin, mode); | latencyPlugin(plugin, mode); | ||||
| } | } | ||||
| #endif | |||||
| }; | }; | ||||
| // ----------------------------------------- | // ----------------------------------------- | ||||
| @@ -65,6 +65,8 @@ public: | |||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| // RtAudio Engine | // RtAudio Engine | ||||
| #if 0 | |||||
| class CarlaEngineRtAudio : public CarlaEngine | class CarlaEngineRtAudio : public CarlaEngine | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -433,6 +435,7 @@ const char* CarlaEngine::getRtAudioApiName(unsigned int index) | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| #endif | |||||
| CARLA_BACKEND_END_NAMESPACE | CARLA_BACKEND_END_NAMESPACE | ||||
| @@ -221,7 +221,7 @@ intptr_t VSTCALLBACK vstHostCallback(AEffect* const effect, const int32_t opcode | |||||
| case audioMasterGetVendorString: | case audioMasterGetVendorString: | ||||
| if (ptr) | if (ptr) | ||||
| { | { | ||||
| strcpy((char*)ptr, "Cadence"); | |||||
| strcpy((char*)ptr, "falkTX"); | |||||
| ret = 1; | ret = 1; | ||||
| } | } | ||||
| break; | break; | ||||
| @@ -274,7 +274,25 @@ void do_ladspa_check(void* const libHandle, const bool init) | |||||
| while ((descriptor = descFn(i++))) | while ((descriptor = descFn(i++))) | ||||
| { | { | ||||
| CARLA_ASSERT(descriptor->run); | |||||
| if (! descriptor->instantiate) | |||||
| { | |||||
| DISCOVERY_OUT("error", "Plugin '" << descriptor->Name << "' has no instantiate()"); | |||||
| continue; | |||||
| } | |||||
| if (! descriptor->cleanup) | |||||
| { | |||||
| DISCOVERY_OUT("error", "Plugin '" << descriptor->Name << "' has no cleanup()"); | |||||
| continue; | |||||
| } | |||||
| if (! descriptor->run) | |||||
| { | |||||
| DISCOVERY_OUT("error", "Plugin '" << descriptor->Name << "' has no run()"); | |||||
| continue; | |||||
| } | |||||
| if (! LADSPA_IS_HARD_RT_CAPABLE(descriptor->Properties)) | |||||
| { | |||||
| DISCOVERY_OUT("warning", "Plugin '" << descriptor->Name << "' is not hard real-time capable"); | |||||
| } | |||||
| int hints = 0; | int hints = 0; | ||||
| int audioIns = 0; | int audioIns = 0; | ||||
| @@ -284,6 +302,9 @@ void do_ladspa_check(void* const libHandle, const bool init) | |||||
| int parametersOuts = 0; | int parametersOuts = 0; | ||||
| int parametersTotal = 0; | int parametersTotal = 0; | ||||
| if (LADSPA_IS_HARD_RT_CAPABLE(descriptor->Properties)) | |||||
| hints |= PLUGIN_IS_RTSAFE; | |||||
| for (unsigned long j=0; j < descriptor->PortCount; j++) | for (unsigned long j=0; j < descriptor->PortCount; j++) | ||||
| { | { | ||||
| const LADSPA_PortDescriptor portDescriptor = descriptor->PortDescriptors[j]; | const LADSPA_PortDescriptor portDescriptor = descriptor->PortDescriptors[j]; | ||||
| @@ -294,14 +315,16 @@ void do_ladspa_check(void* const libHandle, const bool init) | |||||
| audioIns += 1; | audioIns += 1; | ||||
| else if (LADSPA_IS_PORT_OUTPUT(portDescriptor)) | else if (LADSPA_IS_PORT_OUTPUT(portDescriptor)) | ||||
| audioOuts += 1; | audioOuts += 1; | ||||
| audioTotal += 1; | audioTotal += 1; | ||||
| } | } | ||||
| else if (LADSPA_IS_PORT_CONTROL(portDescriptor)) | else if (LADSPA_IS_PORT_CONTROL(portDescriptor)) | ||||
| { | { | ||||
| if (LADSPA_IS_PORT_INPUT(portDescriptor)) | if (LADSPA_IS_PORT_INPUT(portDescriptor)) | ||||
| parametersIns += 1; | parametersIns += 1; | ||||
| else if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && strcmp(descriptor->PortNames[j], "latency") && strcmp(descriptor->PortNames[j], "_latency") && strcmp(descriptor->PortNames[j], "_sample-rate")) | |||||
| else if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && strcmp(descriptor->PortNames[j], "latency") && strcmp(descriptor->PortNames[j], "_latency")) | |||||
| parametersOuts += 1; | parametersOuts += 1; | ||||
| parametersTotal += 1; | parametersTotal += 1; | ||||
| } | } | ||||
| } | } | ||||
| @@ -323,81 +346,79 @@ void do_ladspa_check(void* const libHandle, const bool init) | |||||
| LADSPA_Data bufferParams[parametersTotal]; | LADSPA_Data bufferParams[parametersTotal]; | ||||
| LADSPA_Data min, max, def; | LADSPA_Data min, max, def; | ||||
| for (unsigned long j=0, iA=0, iP=0; j < descriptor->PortCount; j++) | |||||
| for (unsigned long j=0, iA=0, iC=0; j < descriptor->PortCount; j++) | |||||
| { | { | ||||
| const LADSPA_PortDescriptor portType = descriptor->PortDescriptors[j]; | |||||
| const LADSPA_PortRangeHint portHints = descriptor->PortRangeHints[j]; | |||||
| const LADSPA_PortDescriptor portDescriptor = descriptor->PortDescriptors[j]; | |||||
| const LADSPA_PortRangeHint portRangeHints = descriptor->PortRangeHints[j]; | |||||
| const char* const portName = descriptor->PortNames[j]; | |||||
| if (LADSPA_IS_PORT_AUDIO(portType)) | |||||
| if (LADSPA_IS_PORT_AUDIO(portDescriptor)) | |||||
| { | { | ||||
| carla_zeroFloat(bufferAudio[iA], bufferSize); | carla_zeroFloat(bufferAudio[iA], bufferSize); | ||||
| descriptor->connect_port(handle, j, bufferAudio[iA++]); | descriptor->connect_port(handle, j, bufferAudio[iA++]); | ||||
| } | } | ||||
| else if (LADSPA_IS_PORT_CONTROL(portType)) | |||||
| else if (LADSPA_IS_PORT_CONTROL(portDescriptor)) | |||||
| { | { | ||||
| // min value | // min value | ||||
| if (LADSPA_IS_HINT_BOUNDED_BELOW(portHints.HintDescriptor)) | |||||
| min = portHints.LowerBound; | |||||
| if (LADSPA_IS_HINT_BOUNDED_BELOW(portRangeHints.HintDescriptor)) | |||||
| min = portRangeHints.LowerBound; | |||||
| else | else | ||||
| min = 0.0f; | min = 0.0f; | ||||
| // max value | // max value | ||||
| if (LADSPA_IS_HINT_BOUNDED_ABOVE(portHints.HintDescriptor)) | |||||
| max = portHints.UpperBound; | |||||
| if (LADSPA_IS_HINT_BOUNDED_ABOVE(portRangeHints.HintDescriptor)) | |||||
| max = portRangeHints.UpperBound; | |||||
| else | else | ||||
| max = 1.0f; | max = 1.0f; | ||||
| if (min > max) | if (min > max) | ||||
| max = min; | |||||
| else if (max < min) | |||||
| min = max; | |||||
| if (max - min == 0.0f) | |||||
| { | { | ||||
| DISCOVERY_OUT("error", "Broken parameter '" << descriptor->PortNames[j] << "': max - min == 0"); | |||||
| DISCOVERY_OUT("warning", "Parameter '" << portName << "' is broken: min > max"); | |||||
| max = min + 0.1f; | |||||
| } | |||||
| else if (max - min == 0.0f) | |||||
| { | |||||
| DISCOVERY_OUT("warning", "Parameter '" << portName << "' is broken: max - min == 0"); | |||||
| max = min + 0.1f; | max = min + 0.1f; | ||||
| } | } | ||||
| // default value | // default value | ||||
| def = get_default_ladspa_port_value(portHints.HintDescriptor, min, max); | |||||
| def = get_default_ladspa_port_value(portRangeHints.HintDescriptor, min, max); | |||||
| if (LADSPA_IS_HINT_SAMPLE_RATE(portHints.HintDescriptor)) | |||||
| if (LADSPA_IS_HINT_SAMPLE_RATE(portRangeHints.HintDescriptor)) | |||||
| { | { | ||||
| min *= sampleRate; | min *= sampleRate; | ||||
| max *= sampleRate; | max *= sampleRate; | ||||
| def *= sampleRate; | def *= sampleRate; | ||||
| } | } | ||||
| if (LADSPA_IS_PORT_OUTPUT(portType) && (strcmp(descriptor->PortNames[j], "latency") == 0 || strcmp(descriptor->PortNames[j], "_latency") == 0)) | |||||
| if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && (strcmp(portName, "latency") == 0 || strcmp(portName, "_latency") == 0)) | |||||
| { | { | ||||
| // latency parameter | // latency parameter | ||||
| min = 0.0f; | |||||
| max = sampleRate; | |||||
| def = 0.0f; | def = 0.0f; | ||||
| } | } | ||||
| else | |||||
| { | |||||
| if (def < min) | |||||
| def = min; | |||||
| else if (def > max) | |||||
| def = max; | |||||
| } | |||||
| if (def < min) | |||||
| def = min; | |||||
| else if (def > max) | |||||
| def = max; | |||||
| bufferParams[iP] = def; | |||||
| descriptor->connect_port(handle, j, &bufferParams[iP++]); | |||||
| bufferParams[iC] = def; | |||||
| descriptor->connect_port(handle, j, &bufferParams[iC++]); | |||||
| } | } | ||||
| } | } | ||||
| if (descriptor->activate) | if (descriptor->activate) | ||||
| descriptor->activate(handle); | descriptor->activate(handle); | ||||
| if (descriptor->run) | |||||
| descriptor->run(handle, bufferSize); | |||||
| descriptor->run(handle, bufferSize); | |||||
| if (descriptor->deactivate) | if (descriptor->deactivate) | ||||
| descriptor->deactivate(handle); | descriptor->deactivate(handle); | ||||
| if (descriptor->cleanup) | |||||
| descriptor->cleanup(handle); | |||||
| descriptor->cleanup(handle); | |||||
| // end crash-free plugin test | // end crash-free plugin test | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -408,7 +429,7 @@ void do_ladspa_check(void* const libHandle, const bool init) | |||||
| DISCOVERY_OUT("label", descriptor->Label); | DISCOVERY_OUT("label", descriptor->Label); | ||||
| DISCOVERY_OUT("maker", descriptor->Maker); | DISCOVERY_OUT("maker", descriptor->Maker); | ||||
| DISCOVERY_OUT("copyright", descriptor->Copyright); | DISCOVERY_OUT("copyright", descriptor->Copyright); | ||||
| DISCOVERY_OUT("unique_id", descriptor->UniqueID); | |||||
| DISCOVERY_OUT("uniqueId", descriptor->UniqueID); | |||||
| DISCOVERY_OUT("hints", hints); | DISCOVERY_OUT("hints", hints); | ||||
| DISCOVERY_OUT("audio.ins", audioIns); | DISCOVERY_OUT("audio.ins", audioIns); | ||||
| DISCOVERY_OUT("audio.outs", audioOuts); | DISCOVERY_OUT("audio.outs", audioOuts); | ||||
| @@ -443,8 +464,31 @@ void do_dssi_check(void* const libHandle, const bool init) | |||||
| while ((descriptor = descFn(i++))) | while ((descriptor = descFn(i++))) | ||||
| { | { | ||||
| const LADSPA_Descriptor* const ldescriptor = descriptor->LADSPA_Plugin; | const LADSPA_Descriptor* const ldescriptor = descriptor->LADSPA_Plugin; | ||||
| CARLA_ASSERT(ldescriptor); | |||||
| CARLA_ASSERT(ldescriptor->run || descriptor->run_synth || descriptor->run_multiple_synths); | |||||
| if (! ldescriptor) | |||||
| { | |||||
| DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' has no LADSPA interface"); | |||||
| continue; | |||||
| } | |||||
| if (! ldescriptor->instantiate) | |||||
| { | |||||
| DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' has no instantiate()"); | |||||
| continue; | |||||
| } | |||||
| if (! ldescriptor->cleanup) | |||||
| { | |||||
| DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' has no cleanup()"); | |||||
| continue; | |||||
| } | |||||
| if (! (ldescriptor->run || descriptor->run_synth || descriptor->run_multiple_synths)) | |||||
| { | |||||
| DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' has no run(), run_synth() or run_multiple_synths()"); | |||||
| continue; | |||||
| } | |||||
| if (! LADSPA_IS_HARD_RT_CAPABLE(ldescriptor->Properties)) | |||||
| { | |||||
| DISCOVERY_OUT("warning", "Plugin '" << ldescriptor->Name << "' is not hard real-time capable"); | |||||
| } | |||||
| int hints = 0; | int hints = 0; | ||||
| int audioIns = 0; | int audioIns = 0; | ||||
| @@ -457,6 +501,9 @@ void do_dssi_check(void* const libHandle, const bool init) | |||||
| int parametersTotal = 0; | int parametersTotal = 0; | ||||
| int programsTotal = 0; | int programsTotal = 0; | ||||
| if (LADSPA_IS_HARD_RT_CAPABLE(ldescriptor->Properties)) | |||||
| hints |= PLUGIN_IS_RTSAFE; | |||||
| for (unsigned long j=0; j < ldescriptor->PortCount; j++) | for (unsigned long j=0; j < ldescriptor->PortCount; j++) | ||||
| { | { | ||||
| const LADSPA_PortDescriptor portDescriptor = ldescriptor->PortDescriptors[j]; | const LADSPA_PortDescriptor portDescriptor = ldescriptor->PortDescriptors[j]; | ||||
| @@ -467,14 +514,16 @@ void do_dssi_check(void* const libHandle, const bool init) | |||||
| audioIns += 1; | audioIns += 1; | ||||
| else if (LADSPA_IS_PORT_OUTPUT(portDescriptor)) | else if (LADSPA_IS_PORT_OUTPUT(portDescriptor)) | ||||
| audioOuts += 1; | audioOuts += 1; | ||||
| audioTotal += 1; | audioTotal += 1; | ||||
| } | } | ||||
| else if (LADSPA_IS_PORT_CONTROL(portDescriptor)) | else if (LADSPA_IS_PORT_CONTROL(portDescriptor)) | ||||
| { | { | ||||
| if (LADSPA_IS_PORT_INPUT(portDescriptor)) | if (LADSPA_IS_PORT_INPUT(portDescriptor)) | ||||
| parametersIns += 1; | parametersIns += 1; | ||||
| else if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && strcmp(ldescriptor->PortNames[j], "latency") && strcmp(ldescriptor->PortNames[j], "_latency") && strcmp(ldescriptor->PortNames[j], "_sample-rate")) | |||||
| else if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && strcmp(ldescriptor->PortNames[j], "latency") && strcmp(ldescriptor->PortNames[j], "_latency")) | |||||
| parametersOuts += 1; | parametersOuts += 1; | ||||
| parametersTotal += 1; | parametersTotal += 1; | ||||
| } | } | ||||
| } | } | ||||
| @@ -482,7 +531,7 @@ void do_dssi_check(void* const libHandle, const bool init) | |||||
| if (descriptor->run_synth || descriptor->run_multiple_synths) | if (descriptor->run_synth || descriptor->run_multiple_synths) | ||||
| midiIns = midiTotal = 1; | midiIns = midiTotal = 1; | ||||
| if (midiIns > 0 && audioOuts > 0) | |||||
| if (midiIns > 0 && audioIns == 0 && audioOuts > 0) | |||||
| hints |= PLUGIN_IS_SYNTH; | hints |= PLUGIN_IS_SYNTH; | ||||
| if (init) | if (init) | ||||
| @@ -498,10 +547,9 @@ void do_dssi_check(void* const libHandle, const bool init) | |||||
| continue; | continue; | ||||
| } | } | ||||
| // we can only get program info per-handle | |||||
| if (descriptor->get_program && descriptor->select_program) | if (descriptor->get_program && descriptor->select_program) | ||||
| { | { | ||||
| while ((descriptor->get_program(handle, programsTotal++))) | |||||
| while (descriptor->get_program(handle, programsTotal++)) | |||||
| continue; | continue; | ||||
| } | } | ||||
| @@ -509,77 +557,74 @@ void do_dssi_check(void* const libHandle, const bool init) | |||||
| LADSPA_Data bufferParams[parametersTotal]; | LADSPA_Data bufferParams[parametersTotal]; | ||||
| LADSPA_Data min, max, def; | LADSPA_Data min, max, def; | ||||
| for (unsigned long j=0, iA=0, iP=0; j < ldescriptor->PortCount; j++) | |||||
| for (unsigned long j=0, iA=0, iC=0; j < ldescriptor->PortCount; j++) | |||||
| { | { | ||||
| const LADSPA_PortDescriptor portType = ldescriptor->PortDescriptors[j]; | |||||
| const LADSPA_PortRangeHint portHints = ldescriptor->PortRangeHints[j]; | |||||
| const LADSPA_PortDescriptor portDescriptor = ldescriptor->PortDescriptors[j]; | |||||
| const LADSPA_PortRangeHint portRangeHints = ldescriptor->PortRangeHints[j]; | |||||
| const char* const portName = ldescriptor->PortNames[j]; | |||||
| if (LADSPA_IS_PORT_AUDIO(portType)) | |||||
| if (LADSPA_IS_PORT_AUDIO(portDescriptor)) | |||||
| { | { | ||||
| carla_zeroFloat(bufferAudio[iA], bufferSize); | carla_zeroFloat(bufferAudio[iA], bufferSize); | ||||
| ldescriptor->connect_port(handle, j, bufferAudio[iA++]); | ldescriptor->connect_port(handle, j, bufferAudio[iA++]); | ||||
| } | } | ||||
| else if (LADSPA_IS_PORT_CONTROL(portType)) | |||||
| else if (LADSPA_IS_PORT_CONTROL(portDescriptor)) | |||||
| { | { | ||||
| // min value | // min value | ||||
| if (LADSPA_IS_HINT_BOUNDED_BELOW(portHints.HintDescriptor)) | |||||
| min = portHints.LowerBound; | |||||
| if (LADSPA_IS_HINT_BOUNDED_BELOW(portRangeHints.HintDescriptor)) | |||||
| min = portRangeHints.LowerBound; | |||||
| else | else | ||||
| min = 0.0f; | min = 0.0f; | ||||
| // max value | // max value | ||||
| if (LADSPA_IS_HINT_BOUNDED_ABOVE(portHints.HintDescriptor)) | |||||
| max = portHints.UpperBound; | |||||
| if (LADSPA_IS_HINT_BOUNDED_ABOVE(portRangeHints.HintDescriptor)) | |||||
| max = portRangeHints.UpperBound; | |||||
| else | else | ||||
| max = 1.0f; | max = 1.0f; | ||||
| if (min > max) | if (min > max) | ||||
| max = min; | |||||
| else if (max < min) | |||||
| min = max; | |||||
| if (max - min == 0.0f) | |||||
| { | { | ||||
| DISCOVERY_OUT("error", "Broken parameter '" << ldescriptor->PortNames[j] << "': max - min == 0"); | |||||
| DISCOVERY_OUT("warning", "Parameter '" << portName << "' is broken: min > max"); | |||||
| max = min + 0.1f; | |||||
| } | |||||
| else if (max - min == 0.0f) | |||||
| { | |||||
| DISCOVERY_OUT("warning", "Parameter '" << portName << "' is broken: max - min == 0"); | |||||
| max = min + 0.1f; | max = min + 0.1f; | ||||
| } | } | ||||
| // default value | // default value | ||||
| def = get_default_ladspa_port_value(portHints.HintDescriptor, min, max); | |||||
| def = get_default_ladspa_port_value(portRangeHints.HintDescriptor, min, max); | |||||
| if (LADSPA_IS_HINT_SAMPLE_RATE(portHints.HintDescriptor)) | |||||
| if (LADSPA_IS_HINT_SAMPLE_RATE(portRangeHints.HintDescriptor)) | |||||
| { | { | ||||
| min *= sampleRate; | min *= sampleRate; | ||||
| max *= sampleRate; | max *= sampleRate; | ||||
| def *= sampleRate; | def *= sampleRate; | ||||
| } | } | ||||
| if (LADSPA_IS_PORT_OUTPUT(portType) && (strcmp(ldescriptor->PortNames[j], "latency") == 0 || strcmp(ldescriptor->PortNames[j], "_latency") == 0)) | |||||
| if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && (strcmp(portName, "latency") == 0 || strcmp(portName, "_latency") == 0)) | |||||
| { | { | ||||
| // latency parameter | // latency parameter | ||||
| min = 0.0f; | |||||
| max = sampleRate; | |||||
| def = 0.0f; | def = 0.0f; | ||||
| } | } | ||||
| else | |||||
| { | |||||
| if (def < min) | |||||
| def = min; | |||||
| else if (def > max) | |||||
| def = max; | |||||
| } | |||||
| if (def < min) | |||||
| def = min; | |||||
| else if (def > max) | |||||
| def = max; | |||||
| bufferParams[iP] = def; | |||||
| ldescriptor->connect_port(handle, j, &bufferParams[iP++]); | |||||
| bufferParams[iC] = def; | |||||
| ldescriptor->connect_port(handle, j, &bufferParams[iC++]); | |||||
| } | } | ||||
| } | } | ||||
| // select first midi-program if available | // select first midi-program if available | ||||
| if (programsTotal > 0) | if (programsTotal > 0) | ||||
| { | { | ||||
| const DSSI_Program_Descriptor* pDesc = descriptor->get_program(handle, 0); | |||||
| CARLA_ASSERT(pDesc); | |||||
| if (pDesc) | |||||
| if (const DSSI_Program_Descriptor* const pDesc = descriptor->get_program(handle, 0)) | |||||
| descriptor->select_program(handle, pDesc->Bank, pDesc->Program); | descriptor->select_program(handle, pDesc->Bank, pDesc->Program); | ||||
| } | } | ||||
| @@ -612,14 +657,13 @@ void do_dssi_check(void* const libHandle, const bool init) | |||||
| else | else | ||||
| descriptor->run_synth(handle, bufferSize, midiEvents, midiEventCount); | descriptor->run_synth(handle, bufferSize, midiEvents, midiEventCount); | ||||
| } | } | ||||
| else if (ldescriptor->run) | |||||
| else | |||||
| ldescriptor->run(handle, bufferSize); | ldescriptor->run(handle, bufferSize); | ||||
| if (ldescriptor->deactivate) | if (ldescriptor->deactivate) | ||||
| ldescriptor->deactivate(handle); | ldescriptor->deactivate(handle); | ||||
| if (ldescriptor->cleanup) | |||||
| ldescriptor->cleanup(handle); | |||||
| ldescriptor->cleanup(handle); | |||||
| // end crash-free plugin test | // end crash-free plugin test | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -672,7 +716,9 @@ void do_lv2_check(const char* const bundle, const bool init) | |||||
| LILV_FOREACH(plugins, i, lilvPlugins) | LILV_FOREACH(plugins, i, lilvPlugins) | ||||
| { | { | ||||
| Lilv::Plugin lilvPlugin(lilv_plugins_get(lilvPlugins, i)); | Lilv::Plugin lilvPlugin(lilv_plugins_get(lilvPlugins, i)); | ||||
| URIs.append(QString(lilvPlugin.get_uri().as_string())); | |||||
| if (const char* const uri = lilvPlugin.get_uri().as_string()) | |||||
| URIs.append(QString(uri)); | |||||
| } | } | ||||
| // Get & check every plugin-instance | // Get & check every plugin-instance | ||||
| @@ -689,80 +735,69 @@ void do_lv2_check(const char* const bundle, const bool init) | |||||
| if (init) | if (init) | ||||
| { | { | ||||
| // test if DLL is loadable | |||||
| // test if DLL is loadable, twice | |||||
| bool isLoadable = true; | |||||
| for (int j=0; j < 2; j++) | |||||
| { | { | ||||
| void* const libHandle = lib_open(rdfDescriptor->Binary); | void* const libHandle = lib_open(rdfDescriptor->Binary); | ||||
| if (! libHandle) | if (! libHandle) | ||||
| { | { | ||||
| isLoadable = false; | |||||
| print_lib_error(rdfDescriptor->Binary); | print_lib_error(rdfDescriptor->Binary); | ||||
| delete rdfDescriptor; | delete rdfDescriptor; | ||||
| continue; | |||||
| break; | |||||
| } | } | ||||
| lib_close(libHandle); | lib_close(libHandle); | ||||
| } | } | ||||
| // test if we support all required ports and features | |||||
| if (! isLoadable) | |||||
| continue; | |||||
| } | |||||
| // test if we support all required ports and features | |||||
| { | |||||
| bool supported = true; | |||||
| for (uint32_t j=0; j < rdfDescriptor->PortCount && supported; j++) | |||||
| { | { | ||||
| bool supported = true; | |||||
| const LV2_RDF_Port* const rdfPort = &rdfDescriptor->Ports[j]; | |||||
| for (uint32_t j=0; j < rdfDescriptor->PortCount; j++) | |||||
| if (is_lv2_port_supported(rdfPort->Types)) | |||||
| { | { | ||||
| const LV2_RDF_Port* const rdfPort = &rdfDescriptor->Ports[j]; | |||||
| if (LV2_IS_PORT_CONTROL(rdfPort->Types)) | |||||
| { | |||||
| pass(); | |||||
| } | |||||
| else if (LV2_IS_PORT_AUDIO(rdfPort->Types)) | |||||
| { | |||||
| pass(); | |||||
| } | |||||
| else if (LV2_IS_PORT_ATOM_SEQUENCE(rdfPort->Types)) | |||||
| { | |||||
| pass(); | |||||
| } | |||||
| //else if (LV2_IS_PORT_CV(rdfPort->Types)) | |||||
| // pass(); | |||||
| else if (LV2_IS_PORT_EVENT(rdfPort->Types)) | |||||
| { | |||||
| pass(); | |||||
| } | |||||
| else if (LV2_IS_PORT_MIDI_LL(rdfPort->Types)) | |||||
| { | |||||
| pass(); | |||||
| } | |||||
| else if (! LV2_IS_PORT_OPTIONAL(rdfPort->Properties)) | |||||
| { | |||||
| DISCOVERY_OUT("error", "plugin requires a non-supported port type, port-name: " << rdfPort->Name); | |||||
| supported = false; | |||||
| break; | |||||
| } | |||||
| pass(); | |||||
| } | } | ||||
| for (uint32_t j=0; j < rdfDescriptor->FeatureCount && supported; j++) | |||||
| else if (! LV2_IS_PORT_OPTIONAL(rdfPort->Properties)) | |||||
| { | { | ||||
| const LV2_RDF_Feature* const rdfFeature = &rdfDescriptor->Features[j]; | |||||
| if (is_lv2_feature_supported(rdfFeature->URI)) | |||||
| { | |||||
| pass(); | |||||
| } | |||||
| else if (LV2_IS_FEATURE_REQUIRED(rdfFeature->Type)) | |||||
| { | |||||
| DISCOVERY_OUT("error", "plugin requires a non-supported feature " << rdfFeature->URI); | |||||
| supported = false; | |||||
| break; | |||||
| } | |||||
| DISCOVERY_OUT("error", "Plugin '" << rdfDescriptor->URI << "' requires a non-supported port type (portName: '" << rdfPort->Name << "')"); | |||||
| supported = false; | |||||
| break; | |||||
| } | } | ||||
| } | |||||
| if (! supported) | |||||
| for (uint32_t j=0; j < rdfDescriptor->FeatureCount && supported; j++) | |||||
| { | |||||
| const LV2_RDF_Feature* const rdfFeature = &rdfDescriptor->Features[j]; | |||||
| if (is_lv2_feature_supported(rdfFeature->URI)) | |||||
| { | { | ||||
| delete rdfDescriptor; | |||||
| continue; | |||||
| pass(); | |||||
| } | |||||
| else if (LV2_IS_FEATURE_REQUIRED(rdfFeature->Type)) | |||||
| { | |||||
| DISCOVERY_OUT("error", "Plugin '" << rdfDescriptor->URI << "' requires a non-supported feature '" << rdfFeature->URI << "'"); | |||||
| supported = false; | |||||
| break; | |||||
| } | } | ||||
| } | } | ||||
| if (! supported) | |||||
| { | |||||
| delete rdfDescriptor; | |||||
| continue; | |||||
| } | |||||
| } | } | ||||
| int hints = 0; | int hints = 0; | ||||
| @@ -777,6 +812,14 @@ void do_lv2_check(const char* const bundle, const bool init) | |||||
| int parametersTotal = 0; | int parametersTotal = 0; | ||||
| int programsTotal = rdfDescriptor->PresetCount; | int programsTotal = rdfDescriptor->PresetCount; | ||||
| for (uint32_t j=0; j < rdfDescriptor->FeatureCount; j++) | |||||
| { | |||||
| const LV2_RDF_Feature* const rdfFeature = &rdfDescriptor->Features[j]; | |||||
| if (strcmp(rdfFeature->URI, LV2_CORE__hardRTCapable) == 0) | |||||
| hints |= PLUGIN_IS_RTSAFE; | |||||
| } | |||||
| for (uint32_t j=0; j < rdfDescriptor->PortCount; j++) | for (uint32_t j=0; j < rdfDescriptor->PortCount; j++) | ||||
| { | { | ||||
| const LV2_RDF_Port* const rdfPort = &rdfDescriptor->Ports[j]; | const LV2_RDF_Port* const rdfPort = &rdfDescriptor->Ports[j]; | ||||
| @@ -787,6 +830,7 @@ void do_lv2_check(const char* const bundle, const bool init) | |||||
| audioIns += 1; | audioIns += 1; | ||||
| else if (LV2_IS_PORT_OUTPUT(rdfPort->Types)) | else if (LV2_IS_PORT_OUTPUT(rdfPort->Types)) | ||||
| audioOuts += 1; | audioOuts += 1; | ||||
| audioTotal += 1; | audioTotal += 1; | ||||
| } | } | ||||
| else if (LV2_IS_PORT_CONTROL(rdfPort->Types)) | else if (LV2_IS_PORT_CONTROL(rdfPort->Types)) | ||||
| @@ -813,6 +857,7 @@ void do_lv2_check(const char* const bundle, const bool init) | |||||
| parametersIns += 1; | parametersIns += 1; | ||||
| else if (LV2_IS_PORT_OUTPUT(rdfPort->Types)) | else if (LV2_IS_PORT_OUTPUT(rdfPort->Types)) | ||||
| parametersOuts += 1; | parametersOuts += 1; | ||||
| parametersTotal += 1; | parametersTotal += 1; | ||||
| } | } | ||||
| } | } | ||||
| @@ -822,6 +867,7 @@ void do_lv2_check(const char* const bundle, const bool init) | |||||
| midiIns += 1; | midiIns += 1; | ||||
| else if (LV2_IS_PORT_OUTPUT(rdfPort->Types)) | else if (LV2_IS_PORT_OUTPUT(rdfPort->Types)) | ||||
| midiOuts += 1; | midiOuts += 1; | ||||
| midiTotal += 1; | midiTotal += 1; | ||||
| } | } | ||||
| } | } | ||||
| @@ -870,12 +916,14 @@ void do_vst_check(void* const libHandle, const bool init) | |||||
| VST_Function vstFn = (VST_Function)lib_symbol(libHandle, "VSTPluginMain"); | VST_Function vstFn = (VST_Function)lib_symbol(libHandle, "VSTPluginMain"); | ||||
| if (! vstFn) | if (! vstFn) | ||||
| { | |||||
| vstFn = (VST_Function)lib_symbol(libHandle, "main"); | vstFn = (VST_Function)lib_symbol(libHandle, "main"); | ||||
| if (! vstFn) | |||||
| { | |||||
| DISCOVERY_OUT("error", "Not a VST plugin"); | |||||
| return; | |||||
| if (! vstFn) | |||||
| { | |||||
| DISCOVERY_OUT("error", "Not a VST plugin"); | |||||
| return; | |||||
| } | |||||
| } | } | ||||
| AEffect* const effect = vstFn(vstHostCallback); | AEffect* const effect = vstFn(vstHostCallback); | ||||
| @@ -895,7 +943,7 @@ void do_vst_check(void* const libHandle, const bool init) | |||||
| intptr_t vstCategory = effect->dispatcher(effect, effGetPlugCategory, 0, 0, nullptr, 0.0f); | intptr_t vstCategory = effect->dispatcher(effect, effGetPlugCategory, 0, 0, nullptr, 0.0f); | ||||
| if (vstCategory == kPlugCategShell) | |||||
| if (vstCategory == kPlugCategShell && effect->uniqueID == 0) | |||||
| { | { | ||||
| if ((vstCurrentUniqueId = effect->dispatcher(effect, effShellGetNextPlugin, 0, 0, strBuf, 0.0f)) != 0) | if ((vstCurrentUniqueId = effect->dispatcher(effect, effShellGetNextPlugin, 0, 0, strBuf, 0.0f)) != 0) | ||||
| cName = strBuf; | cName = strBuf; | ||||
| @@ -1409,6 +1457,25 @@ int main(int argc, char* argv[]) | |||||
| if (doInit && getenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS")) | if (doInit && getenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS")) | ||||
| doInit = false; | doInit = false; | ||||
| if (doInit && handle) | |||||
| { | |||||
| // test fast loading & unloading DLL without initializing the plugin(s) | |||||
| if (! lib_close(handle)) | |||||
| { | |||||
| print_lib_error(filename); | |||||
| return 1; | |||||
| } | |||||
| handle = lib_open(filename); | |||||
| if (! handle) | |||||
| { | |||||
| print_lib_error(filename); | |||||
| return 1; | |||||
| } | |||||
| } | |||||
| switch (type) | switch (type) | ||||
| { | { | ||||
| case PLUGIN_LADSPA: | case PLUGIN_LADSPA: | ||||
| @@ -1436,7 +1503,7 @@ int main(int argc, char* argv[]) | |||||
| break; | break; | ||||
| } | } | ||||
| if (openLib) | |||||
| if (openLib && handle) | |||||
| lib_close(handle); | lib_close(handle); | ||||
| return 0; | return 0; | ||||
| @@ -9,7 +9,7 @@ | |||||
| * | * | ||||
| * This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | * GNU General Public License for more details. | ||||
| * | * | ||||
| * For a full copy of the GNU General Public License see the COPYING file | * For a full copy of the GNU General Public License see the COPYING file | ||||
| @@ -81,9 +81,11 @@ | |||||
| #ifdef NDEBUG | #ifdef NDEBUG | ||||
| # define CARLA_ASSERT(cond) ((!(cond)) ? carla_assert(#cond, __FILE__, __LINE__) : qt_noop()) | # define CARLA_ASSERT(cond) ((!(cond)) ? carla_assert(#cond, __FILE__, __LINE__) : qt_noop()) | ||||
| # define CARLA_ASSERT_INT(cond, value) ((!(cond)) ? carla_assert_int(#cond, __FILE__, __LINE__, value) : qt_noop()) | # define CARLA_ASSERT_INT(cond, value) ((!(cond)) ? carla_assert_int(#cond, __FILE__, __LINE__, value) : qt_noop()) | ||||
| # define CARLA_ASSERT_INT2(cond, v1, v2) ((!(cond)) ? carla_assert_int2(#cond, __FILE__, __LINE__, v1, v2) : qt_noop()) | |||||
| #else | #else | ||||
| # define CARLA_ASSERT Q_ASSERT | |||||
| # define CARLA_ASSERT(cond) Q_ASSERT(cond) | |||||
| # define CARLA_ASSERT_INT(cond, value) Q_ASSERT(cond) | # define CARLA_ASSERT_INT(cond, value) Q_ASSERT(cond) | ||||
| # define CARLA_ASSERT_INT2(cond, v1, v2) Q_ASSERT(cond) | |||||
| #endif | #endif | ||||
| // Define CARLA_EXPORT | // Define CARLA_EXPORT | ||||
| @@ -1,5 +1,5 @@ | |||||
| /* | /* | ||||
| * Carla Backend | |||||
| * Carla Backend utils | |||||
| * Copyright (C) 2011-2012 Filipe Coelho <falktx@falktx.com> | * Copyright (C) 2011-2012 Filipe Coelho <falktx@falktx.com> | ||||
| * | * | ||||
| * This program is free software; you can redistribute it and/or modify | * This program is free software; you can redistribute it and/or modify | ||||
| @@ -9,29 +9,21 @@ | |||||
| * | * | ||||
| * This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | * GNU General Public License for more details. | ||||
| * | * | ||||
| * For a full copy of the GNU General Public License see the COPYING file | * For a full copy of the GNU General Public License see the COPYING file | ||||
| */ | */ | ||||
| #ifndef CARLA_BACKEND_UTILS_HPP | |||||
| #define CARLA_BACKEND_UTILS_HPP | |||||
| #ifndef __CARLA_BACKEND_UTILS_HPP__ | |||||
| #define __CARLA_BACKEND_UTILS_HPP__ | |||||
| #include "carla_backend.hpp" | #include "carla_backend.hpp" | ||||
| #include "carla_utils.hpp" | #include "carla_utils.hpp" | ||||
| CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
| /*! | |||||
| * @defgroup CarlaBackendUtils Carla Backend Utils | |||||
| * | |||||
| * Carla Backend Utils | |||||
| * | |||||
| * @{ | |||||
| */ | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| // ------------------------------------------------- | |||||
| static inline | static inline | ||||
| const char* BinaryType2Str(const BinaryType& type) | const char* BinaryType2Str(const BinaryType& type) | ||||
| @@ -156,41 +148,14 @@ const char* InternalParametersIndex2Str(const InternalParametersIndex& index) | |||||
| return "PARAMETER_BALANCE_LEFT"; | return "PARAMETER_BALANCE_LEFT"; | ||||
| case PARAMETER_BALANCE_RIGHT: | case PARAMETER_BALANCE_RIGHT: | ||||
| return "PARAMETER_BALANCE_RIGHT"; | return "PARAMETER_BALANCE_RIGHT"; | ||||
| case PARAMETER_PANNING: | |||||
| return "PARAMETER_PANNING"; | |||||
| } | } | ||||
| qWarning("CarlaBackend::InternalParametersIndex2Str(%i) - invalid index", index); | qWarning("CarlaBackend::InternalParametersIndex2Str(%i) - invalid index", index); | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| #if 0 | |||||
| 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; | |||||
| } | |||||
| #endif | |||||
| static inline | static inline | ||||
| const char* OptionsType2Str(const OptionsType& type) | const char* OptionsType2Str(const OptionsType& type) | ||||
| { | { | ||||
| @@ -202,24 +167,25 @@ const char* OptionsType2Str(const OptionsType& type) | |||||
| return "OPTION_PROCESS_MODE"; | return "OPTION_PROCESS_MODE"; | ||||
| case OPTION_PROCESS_HIGH_PRECISION: | case OPTION_PROCESS_HIGH_PRECISION: | ||||
| return "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: | case OPTION_FORCE_STEREO: | ||||
| return "OPTION_FORCE_STEREO"; | return "OPTION_FORCE_STEREO"; | ||||
| #ifdef WANT_DSSI | |||||
| case OPTION_USE_DSSI_VST_CHUNKS: | |||||
| return "OPTION_USE_DSSI_VST_CHUNKS"; | |||||
| #endif | |||||
| case OPTION_PREFER_PLUGIN_BRIDGES: | case OPTION_PREFER_PLUGIN_BRIDGES: | ||||
| return "OPTION_PREFER_PLUGIN_BRIDGES"; | return "OPTION_PREFER_PLUGIN_BRIDGES"; | ||||
| case OPTION_PREFER_UI_BRIDGES: | case OPTION_PREFER_UI_BRIDGES: | ||||
| return "OPTION_PREFER_UI_BRIDGES"; | return "OPTION_PREFER_UI_BRIDGES"; | ||||
| #ifdef WANT_DSSI | |||||
| case OPTION_USE_DSSI_VST_CHUNKS: | |||||
| return "OPTION_USE_DSSI_VST_CHUNKS"; | |||||
| #endif | |||||
| case OPTION_MAX_PARAMETERS: | |||||
| return "OPTION_MAX_PARAMETERS"; | |||||
| case OPTION_OSC_UI_TIMEOUT: | case OPTION_OSC_UI_TIMEOUT: | ||||
| return "OPTION_OSC_UI_TIMEOUT"; | return "OPTION_OSC_UI_TIMEOUT"; | ||||
| case OPTION_PREFERRED_BUFFER_SIZE: | |||||
| return "OPTION_PREFERRED_BUFFER_SIZE"; | |||||
| case OPTION_PREFERRED_SAMPLE_RATE: | |||||
| return "OPTION_PREFERRED_SAMPLE_RATE"; | |||||
| #ifndef BUILD_BRIDGE | |||||
| case OPTION_PATH_BRIDGE_NATIVE: | case OPTION_PATH_BRIDGE_NATIVE: | ||||
| return "OPTION_PATH_BRIDGE_NATIVE"; | return "OPTION_PATH_BRIDGE_NATIVE"; | ||||
| case OPTION_PATH_BRIDGE_POSIX32: | case OPTION_PATH_BRIDGE_POSIX32: | ||||
| @@ -230,6 +196,7 @@ const char* OptionsType2Str(const OptionsType& type) | |||||
| return "OPTION_PATH_BRIDGE_WIN32"; | return "OPTION_PATH_BRIDGE_WIN32"; | ||||
| case OPTION_PATH_BRIDGE_WIN64: | case OPTION_PATH_BRIDGE_WIN64: | ||||
| return "OPTION_PATH_BRIDGE_WIN64"; | return "OPTION_PATH_BRIDGE_WIN64"; | ||||
| #endif | |||||
| #ifdef WANT_LV2 | #ifdef WANT_LV2 | ||||
| case OPTION_PATH_BRIDGE_LV2_GTK2: | case OPTION_PATH_BRIDGE_LV2_GTK2: | ||||
| return "OPTION_PATH_BRIDGE_LV2_GTK2"; | return "OPTION_PATH_BRIDGE_LV2_GTK2"; | ||||
| @@ -283,8 +250,6 @@ const char* CallbackType2Str(const CallbackType& type) | |||||
| return "CALLBACK_NOTE_OFF"; | return "CALLBACK_NOTE_OFF"; | ||||
| case CALLBACK_SHOW_GUI: | case CALLBACK_SHOW_GUI: | ||||
| return "CALLBACK_SHOW_GUI"; | return "CALLBACK_SHOW_GUI"; | ||||
| case CALLBACK_RESIZE_GUI: | |||||
| return "CALLBACK_RESIZE_GUI"; | |||||
| case CALLBACK_UPDATE: | case CALLBACK_UPDATE: | ||||
| return "CALLBACK_UPDATE"; | return "CALLBACK_UPDATE"; | ||||
| case CALLBACK_RELOAD_INFO: | case CALLBACK_RELOAD_INFO: | ||||
| @@ -332,7 +297,28 @@ const char* ProcessMode2Str(const ProcessMode& mode) | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| // ------------------------------------------------- | |||||
| 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 | static inline | ||||
| const char* getPluginTypeString(const PluginType& type) | const char* getPluginTypeString(const PluginType& type) | ||||
| @@ -343,8 +329,10 @@ const char* getPluginTypeString(const PluginType& type) | |||||
| { | { | ||||
| case PLUGIN_NONE: | case PLUGIN_NONE: | ||||
| return "NONE"; | return "NONE"; | ||||
| #ifndef BUILD_BRIDGE | |||||
| case PLUGIN_INTERNAL: | case PLUGIN_INTERNAL: | ||||
| return "INTERNAL"; | return "INTERNAL"; | ||||
| #endif | |||||
| case PLUGIN_LADSPA: | case PLUGIN_LADSPA: | ||||
| return "LADSPA"; | return "LADSPA"; | ||||
| case PLUGIN_DSSI: | case PLUGIN_DSSI: | ||||
| @@ -353,39 +341,20 @@ const char* getPluginTypeString(const PluginType& type) | |||||
| return "LV2"; | return "LV2"; | ||||
| case PLUGIN_VST: | case PLUGIN_VST: | ||||
| return "VST"; | return "VST"; | ||||
| #ifndef BUILD_BRIDGE | |||||
| case PLUGIN_GIG: | case PLUGIN_GIG: | ||||
| return "GIG"; | return "GIG"; | ||||
| case PLUGIN_SF2: | case PLUGIN_SF2: | ||||
| return "SF2"; | return "SF2"; | ||||
| case PLUGIN_SFZ: | case PLUGIN_SFZ: | ||||
| return "SFZ"; | return "SFZ"; | ||||
| #endif | |||||
| } | } | ||||
| return "NONE"; | 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 | static inline | ||||
| PluginCategory getPluginCategoryFromName(const char* const name) | PluginCategory getPluginCategoryFromName(const char* const name) | ||||
| @@ -466,8 +435,6 @@ PluginCategory getPluginCategoryFromName(const char* const name) | |||||
| return PLUGIN_CATEGORY_NONE; | return PLUGIN_CATEGORY_NONE; | ||||
| } | } | ||||
| /**@}*/ | |||||
| CARLA_BACKEND_END_NAMESPACE | CARLA_BACKEND_END_NAMESPACE | ||||
| #endif // CARLA_BACKEND_UTILS_HPP | |||||
| #endif // __CARLA_BACKEND_UTILS_HPP__ | |||||
| @@ -1124,10 +1124,30 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri) | |||||
| return rdfDescriptor; | return rdfDescriptor; | ||||
| } | } | ||||
| // ------------------------------------------------- | |||||
| // Check if we support a plugin port | |||||
| static inline | |||||
| bool is_lv2_port_supported(const LV2_Property types) | |||||
| { | |||||
| if (LV2_IS_PORT_CONTROL(types)) | |||||
| return true; | |||||
| if (LV2_IS_PORT_AUDIO(types)) | |||||
| return true; | |||||
| if (LV2_IS_PORT_ATOM_SEQUENCE(types)) | |||||
| return true; | |||||
| if (LV2_IS_PORT_CV(types)) | |||||
| return true; // TODO | |||||
| if (LV2_IS_PORT_EVENT(types)) | |||||
| return true; | |||||
| if (LV2_IS_PORT_MIDI_LL(types)) | |||||
| return true; | |||||
| return false; | |||||
| } | |||||
| // ------------------------------------------------- | // ------------------------------------------------- | ||||
| // Check if we support a plugin feature | // Check if we support a plugin feature | ||||
| // TODO - review these | |||||
| static inline | static inline | ||||
| bool is_lv2_feature_supported(const LV2_URI uri) | bool is_lv2_feature_supported(const LV2_URI uri) | ||||
| { | { | ||||
| @@ -1137,6 +1157,12 @@ bool is_lv2_feature_supported(const LV2_URI uri) | |||||
| return true; | return true; | ||||
| if (strcmp(uri, LV2_CORE__isLive) == 0) | if (strcmp(uri, LV2_CORE__isLive) == 0) | ||||
| return true; | return true; | ||||
| if (strcmp(uri, LV2_BUF_SIZE__boundedBlockLength) == 0) | |||||
| return true; | |||||
| if (strcmp(uri, LV2_BUF_SIZE__fixedBlockLength) == 0) | |||||
| return true; | |||||
| if (strcmp(uri, LV2_BUF_SIZE__powerOf2BlockLength) == 0) | |||||
| return true; | |||||
| if (strcmp(uri, LV2_EVENT_URI) == 0) | if (strcmp(uri, LV2_EVENT_URI) == 0) | ||||
| return true; | return true; | ||||
| if (strcmp(uri, LV2_LOG__log) == 0) | if (strcmp(uri, LV2_LOG__log) == 0) | ||||
| @@ -1167,7 +1193,6 @@ bool is_lv2_feature_supported(const LV2_URI uri) | |||||
| // ------------------------------------------------- | // ------------------------------------------------- | ||||
| // Check if we support a plugin or UI feature | // Check if we support a plugin or UI feature | ||||
| // TODO - review these | |||||
| static inline | static inline | ||||
| bool is_lv2_ui_feature_supported(const LV2_URI uri) | bool is_lv2_ui_feature_supported(const LV2_URI uri) | ||||
| { | { | ||||
| @@ -9,7 +9,7 @@ | |||||
| * | * | ||||
| * This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | * GNU General Public License for more details. | ||||
| * | * | ||||
| * For a full copy of the GNU General Public License see the COPYING file | * For a full copy of the GNU General Public License see the COPYING file | ||||
| @@ -47,8 +47,14 @@ void carla_assert_int(const char* const assertion, const char* const file, const | |||||
| qCritical("Carla assertion failure: \"%s\" in file %s, line %i, value %i", assertion, file, line, value); | qCritical("Carla assertion failure: \"%s\" in file %s, line %i, value %i", assertion, file, line, value); | ||||
| } | } | ||||
| static inline | |||||
| void carla_assert_int2(const char* const assertion, const char* const file, const int line, const int v1, const int v2) | |||||
| { | |||||
| qCritical("Carla assertion failure: \"%s\" in file %s, line %i, v1 %i, v2 %i", assertion, file, line, v1, v2); | |||||
| } | |||||
| // ------------------------------------------------- | // ------------------------------------------------- | ||||
| // carla_*sleep (carla_usleep not possible in Windows) | |||||
| // carla_*sleep | |||||
| static inline | static inline | ||||
| void carla_sleep(const unsigned int secs) | void carla_sleep(const unsigned int secs) | ||||
| @@ -36,7 +36,7 @@ public: | |||||
| qcount = 0; | qcount = 0; | ||||
| INIT_LIST_HEAD(&queue); | INIT_LIST_HEAD(&queue); | ||||
| rtsafe_memory_pool_create(&mempool, nullptr, sizeof(ListHeadData), minPreallocated, maxPreallocated); | |||||
| rtsafe_memory_pool_create(&mempool, nullptr, sizeof(RtListData), minPreallocated, maxPreallocated); | |||||
| assert(mempool); | assert(mempool); | ||||
| } | } | ||||
| @@ -53,7 +53,7 @@ public: | |||||
| clear(); | clear(); | ||||
| rtsafe_memory_pool_destroy(mempool); | rtsafe_memory_pool_destroy(mempool); | ||||
| rtsafe_memory_pool_create(&mempool, nullptr, sizeof(ListHeadData), minPreallocated, maxPreallocated); | |||||
| rtsafe_memory_pool_create(&mempool, nullptr, sizeof(RtListData), minPreallocated, maxPreallocated); | |||||
| assert(mempool); | assert(mempool); | ||||
| } | } | ||||
| @@ -62,12 +62,12 @@ public: | |||||
| { | { | ||||
| if (! isEmpty()) | if (! isEmpty()) | ||||
| { | { | ||||
| ListHeadData* data; | |||||
| RtListData* data; | |||||
| k_list_head* entry; | k_list_head* entry; | ||||
| list_for_each(entry, &queue) | list_for_each(entry, &queue) | ||||
| { | { | ||||
| data = list_entry(entry, ListHeadData, siblings); | |||||
| data = list_entry(entry, RtListData, siblings); | |||||
| rtsafe_memory_pool_deallocate(mempool, data); | rtsafe_memory_pool_deallocate(mempool, data); | ||||
| } | } | ||||
| } | } | ||||
| @@ -83,17 +83,18 @@ public: | |||||
| bool isEmpty() const | bool isEmpty() const | ||||
| { | { | ||||
| return (list_empty(&queue) != 0); | |||||
| return (qcount == 0); | |||||
| //return (list_empty(&queue) != 0); | |||||
| } | } | ||||
| void append(const T& value, const bool sleepy = false) | void append(const T& value, const bool sleepy = false) | ||||
| { | { | ||||
| ListHeadData* data; | |||||
| RtListData* data; | |||||
| if (sleepy) | if (sleepy) | ||||
| data = (ListHeadData*)rtsafe_memory_pool_allocate_sleepy(mempool); | |||||
| data = (RtListData*)rtsafe_memory_pool_allocate_sleepy(mempool); | |||||
| else | else | ||||
| data = (ListHeadData*)rtsafe_memory_pool_allocate_atomic(mempool); | |||||
| data = (RtListData*)rtsafe_memory_pool_allocate_atomic(mempool); | |||||
| if (data) | if (data) | ||||
| { | { | ||||
| @@ -126,12 +127,12 @@ public: | |||||
| bool removeOne(const T& value) | bool removeOne(const T& value) | ||||
| { | { | ||||
| ListHeadData* data; | |||||
| RtListData* data; | |||||
| k_list_head* entry; | k_list_head* entry; | ||||
| list_for_each(entry, &queue) | list_for_each(entry, &queue) | ||||
| { | { | ||||
| data = list_entry(entry, ListHeadData, siblings); | |||||
| data = list_entry(entry, RtListData, siblings); | |||||
| if (data->value == value) | if (data->value == value) | ||||
| { | { | ||||
| @@ -147,13 +148,13 @@ public: | |||||
| void removeAll(const T& value) | void removeAll(const T& value) | ||||
| { | { | ||||
| ListHeadData* data; | |||||
| RtListData* data; | |||||
| k_list_head* entry; | k_list_head* entry; | ||||
| k_list_head* tmp; | k_list_head* tmp; | ||||
| list_for_each_safe(entry, tmp, &queue) | list_for_each_safe(entry, tmp, &queue) | ||||
| { | { | ||||
| data = list_entry(entry, ListHeadData, siblings); | |||||
| data = list_entry(entry, RtListData, siblings); | |||||
| if (data->value == value) | if (data->value == value) | ||||
| { | { | ||||
| @@ -169,7 +170,7 @@ private: | |||||
| k_list_head queue; | k_list_head queue; | ||||
| RtMemPool_Handle mempool; | RtMemPool_Handle mempool; | ||||
| struct ListHeadData { | |||||
| struct RtListData { | |||||
| T value; | T value; | ||||
| k_list_head siblings; | k_list_head siblings; | ||||
| }; | }; | ||||
| @@ -192,7 +193,7 @@ private: | |||||
| } | } | ||||
| k_list_head* entry = first ? queue.next : queue.prev; | k_list_head* entry = first ? queue.next : queue.prev; | ||||
| ListHeadData* data = list_entry(entry, ListHeadData, siblings); | |||||
| RtListData* data = list_entry(entry, RtListData, siblings); | |||||
| T& ret = data->value; | T& ret = data->value; | ||||