| @@ -9,7 +9,7 @@ | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| @@ -18,6 +18,8 @@ | |||
| #ifndef __CARLA_BACKEND_HPP__ | |||
| #define __CARLA_BACKEND_HPP__ | |||
| // TODO - remove ifdef's when Carla stabilizes | |||
| #include "carla_defines.hpp" | |||
| #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 | |||
| @@ -56,14 +56,17 @@ const unsigned int MAX_PARAMETERS = 200; //!< Default value for the maximum numb | |||
| #ifndef BUILD_BRIDGE | |||
| const unsigned int PLUGIN_IS_BRIDGE = 0x001; //!< Plugin is a bridge (ie, BridgePlugin). This hint is required because "bridge" itself is not a plugin type. | |||
| #endif | |||
| const unsigned int PLUGIN_IS_SYNTH = 0x002; //!< Plugin is a synthesizer (produces sound). | |||
| const unsigned int PLUGIN_HAS_GUI = 0x004; //!< Plugin has its own custom GUI. | |||
| const unsigned int PLUGIN_USES_CHUNKS = 0x008; //!< Plugin uses chunks to save internal data.\see CarlaPlugin::chunkData() | |||
| const unsigned int PLUGIN_USES_SINGLE_THREAD = 0x010; //!< Plugin needs a single thread for both DSP 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() | |||
| * @{ | |||
| */ | |||
| 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_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_CUSTOM_TEXT = 0x80; //!< Parameter uses custom text for displaying its value.\see CarlaPlugin::getParameterText() | |||
| /**@}*/ | |||
| #if 0 | |||
| /*! | |||
| * @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_STRING = "http://kxstudio.sf.net/ns/carla/string"; //!< Carla String | |||
| /**@}*/ | |||
| #endif | |||
| #if 0 | |||
| /*! | |||
| * @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 | |||
| * @{ | |||
| */ | |||
| //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. | |||
| @@ -126,7 +133,7 @@ enum BinaryType { | |||
| /*! | |||
| * 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 { | |||
| 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_DRYWET = -3, //!< Dry/Wet parameter, range 0.0...1.0; default is 1.0. | |||
| PARAMETER_VOLUME = -4, //!< Volume parameter, range 0.0...1.27; default is 1.0. | |||
| PARAMETER_BALANCE_LEFT = -5, //!< Balance-Left parameter, range -1.0...1.0; default is -1.0. | |||
| PARAMETER_BALANCE_RIGHT = -6 //!< Balance-Right parameter, range -1.0...1.0; default is 1.0. | |||
| 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 { | |||
| /*! | |||
| * Try to set the current process name.\n | |||
| * Try to set the current process name. | |||
| * \note Not available on all platforms. | |||
| */ | |||
| OPTION_PROCESS_NAME = 0, | |||
| @@ -232,54 +223,55 @@ enum OptionsType { | |||
| 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 | |||
| /*! | |||
| * Use (unofficial) dssi-vst chunks feature.\n | |||
| * Default is no. | |||
| */ | |||
| OPTION_USE_DSSI_VST_CHUNKS = 7, | |||
| OPTION_USE_DSSI_VST_CHUNKS = 6, | |||
| #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 | |||
| * Default unset. | |||
| @@ -309,6 +301,7 @@ enum OptionsType { | |||
| * Default unset. | |||
| */ | |||
| OPTION_PATH_BRIDGE_WIN64 = 15, | |||
| #endif | |||
| #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() | |||
| */ | |||
| enum CallbackType { | |||
| @@ -449,72 +443,64 @@ enum CallbackType { | |||
| * \param value1 State, as follows:.\n | |||
| * 0: GUI has been closed or hidden\n | |||
| * 1: GUI has been shown\n | |||
| * -1: GUI has crashed and should not be shown again\n | |||
| * -1: GUI has crashed and should not be shown again | |||
| */ | |||
| CALLBACK_SHOW_GUI = 8, | |||
| /*! | |||
| * The plugin's custom GUI has been resized. | |||
| * | |||
| * \param value1 Width | |||
| * \param value2 Height | |||
| */ | |||
| CALLBACK_RESIZE_GUI = 9, | |||
| /*! | |||
| * The plugin needs update. | |||
| */ | |||
| CALLBACK_UPDATE = 10, | |||
| CALLBACK_UPDATE = 9, | |||
| /*! | |||
| * The plugin's data/information has changed. | |||
| */ | |||
| CALLBACK_RELOAD_INFO = 11, | |||
| CALLBACK_RELOAD_INFO = 10, | |||
| /*! | |||
| * The plugin's parameters have changed. | |||
| */ | |||
| CALLBACK_RELOAD_PARAMETERS = 12, | |||
| CALLBACK_RELOAD_PARAMETERS = 11, | |||
| /*! | |||
| * The plugin's programs have changed. | |||
| */ | |||
| CALLBACK_RELOAD_PROGRAMS = 13, | |||
| CALLBACK_RELOAD_PROGRAMS = 12, | |||
| /*! | |||
| * The plugin's state has changed. | |||
| */ | |||
| CALLBACK_RELOAD_ALL = 14, | |||
| CALLBACK_RELOAD_ALL = 13, | |||
| /*! | |||
| * Non-Session-Manager Announce message. | |||
| */ | |||
| CALLBACK_NSM_ANNOUNCE = 15, | |||
| CALLBACK_NSM_ANNOUNCE = 14, | |||
| /*! | |||
| * Non-Session-Manager Open message #1. | |||
| */ | |||
| CALLBACK_NSM_OPEN1 = 16, | |||
| CALLBACK_NSM_OPEN1 = 15, | |||
| /*! | |||
| * Non-Session-Manager Open message #2. | |||
| */ | |||
| CALLBACK_NSM_OPEN2 = 17, | |||
| CALLBACK_NSM_OPEN2 = 16, | |||
| /*! | |||
| * Non-Session-Manager Save message. | |||
| */ | |||
| CALLBACK_NSM_SAVE = 18, | |||
| CALLBACK_NSM_SAVE = 17, | |||
| /*! | |||
| * 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. | |||
| */ | |||
| CALLBACK_QUIT = 20 | |||
| CALLBACK_QUIT = 19 | |||
| }; | |||
| /*! | |||
| @@ -598,7 +584,7 @@ struct MidiProgramData { | |||
| /*! | |||
| * Custom data, saving key:value 'dictionaries'. | |||
| * \a type is an URI. | |||
| * \a type is an URI which defines the \a value type. | |||
| * | |||
| * \see CustomDataTypes | |||
| */ | |||
| @@ -9,7 +9,7 @@ | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| @@ -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. | |||
| @@ -236,11 +193,13 @@ struct CarlaEngineOptions { | |||
| uint preferredBufferSize; | |||
| uint preferredSampleRate; | |||
| #ifndef BUILD_BRIDGE | |||
| CarlaString bridge_native; | |||
| CarlaString bridge_posix32; | |||
| CarlaString bridge_posix64; | |||
| CarlaString bridge_win32; | |||
| CarlaString bridge_win64; | |||
| #endif | |||
| #ifdef WANT_LV2 | |||
| CarlaString bridge_lv2gtk2; | |||
| CarlaString bridge_lv2gtk3; | |||
| @@ -257,7 +216,7 @@ struct CarlaEngineOptions { | |||
| #endif | |||
| CarlaEngineOptions() | |||
| : processMode(PROCESS_MODE_PATCHBAY), | |||
| : processMode(PROCESS_MODE_CONTINUOUS_RACK), | |||
| processHighPrecision(false), | |||
| forceStereo(false), | |||
| preferPluginBridges(false), | |||
| @@ -265,12 +224,57 @@ struct CarlaEngineOptions { | |||
| #ifdef WANT_DSSI | |||
| useDssiVstChunks(false), | |||
| #endif | |||
| maxParameters(MAX_PARAMETERS), | |||
| oscUiTimeout(4000/100), | |||
| maxParameters(MAX_DEFAULT_PARAMETERS), | |||
| oscUiTimeout(4000), | |||
| preferredBufferSize(512), | |||
| 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); | |||
| // ------------------------------------------------------------------- | |||
| // Maximum values | |||
| @@ -583,7 +588,7 @@ public: | |||
| * Maximum number of loadable plugins. | |||
| * \note This function returns 0 if engine is not started. | |||
| */ | |||
| unsigned short maxPluginNumber() const; | |||
| unsigned int maxPluginNumber() const; | |||
| // ------------------------------------------------------------------- | |||
| // Virtual, per-engine type calls | |||
| @@ -626,8 +631,10 @@ public: | |||
| * Get next available plugin id.\n | |||
| * 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. | |||
| */ | |||
| @@ -637,6 +644,7 @@ public: | |||
| * Get plugin with id \a id, faster unchecked version. | |||
| */ | |||
| CarlaPlugin* getPluginUnchecked(const unsigned short id) const; | |||
| #endif | |||
| /*! | |||
| * Get a unique plugin name within the engine.\n | |||
| @@ -692,6 +700,14 @@ public: | |||
| return (const char*)name; | |||
| } | |||
| /*! | |||
| * Get current buffer size. | |||
| */ | |||
| uint32_t getBufferSize() const | |||
| { | |||
| return bufferSize; | |||
| } | |||
| /*! | |||
| * 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 | |||
| /*! | |||
| * Get the engine options (read-only). | |||
| */ | |||
| const CarlaEngineOptions& getOptions() const | |||
| { | |||
| return options; | |||
| } | |||
| #ifndef BUILD_BRIDGE | |||
| /*! | |||
| * Get the engine options as process environment. | |||
| @@ -842,6 +850,8 @@ public: | |||
| void setOscBridgeData(const CarlaOscData* const oscData); | |||
| #endif | |||
| #endif | |||
| #ifdef BUILD_BRIDGE | |||
| void osc_send_peaks(CarlaPlugin* const plugin); | |||
| #else | |||
| @@ -93,8 +93,7 @@ enum PluginPostEventType { | |||
| PluginPostEventProgramChange, // index | |||
| PluginPostEventMidiProgramChange, // index | |||
| PluginPostEventNoteOn, // channel, note, velo | |||
| PluginPostEventNoteOff, // channel, note | |||
| PluginPostEventCustom | |||
| PluginPostEventNoteOff // channel, note | |||
| }; | |||
| struct PluginAudioData { | |||
| @@ -159,14 +158,12 @@ struct PluginPostEvent { | |||
| int32_t value1; | |||
| int32_t value2; | |||
| double value3; | |||
| const void* cdata; | |||
| PluginPostEvent() | |||
| : type(PluginPostEventNull), | |||
| value1(-1), | |||
| value2(-1), | |||
| value3(0.0), | |||
| cdata(nullptr) {} | |||
| value3(0.0) {} | |||
| }; | |||
| struct ExternalMidiNote { | |||
| @@ -180,7 +177,7 @@ struct ExternalMidiNote { | |||
| velo(0) {} | |||
| }; | |||
| class CarlaPluginPrivateData; | |||
| struct CarlaPluginPrivateData; | |||
| /*! | |||
| * \class CarlaPlugin | |||
| @@ -80,7 +80,7 @@ void CarlaEngineAudioPort::initBuffer(CarlaEngine* const) | |||
| CarlaEngineControlPort::CarlaEngineControlPort(const bool isInput, const ProcessMode 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)); | |||
| @@ -224,7 +224,7 @@ void CarlaEngineControlPort::writeEvent(const CarlaEngineControlEventType type, | |||
| CarlaEngineMidiPort::CarlaEngineMidiPort(const bool isInput, const ProcessMode 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)); | |||
| @@ -416,7 +416,7 @@ void CarlaEngineClient::setLatency(const uint32_t samples) | |||
| } | |||
| // ------------------------------------------------------------------------------------------------------------------- | |||
| // Carla Engine Client | |||
| // Carla Engine | |||
| CarlaEngine::CarlaEngine() | |||
| : data(new CarlaEnginePrivateData(this)) | |||
| @@ -530,7 +530,7 @@ int CarlaEngine::maxPortNameSize() | |||
| return STR_MAX; | |||
| } | |||
| unsigned short CarlaEngine::maxPluginNumber() const | |||
| unsigned int CarlaEngine::maxPluginNumber() const | |||
| { | |||
| return data->maxPluginNumber; | |||
| } | |||
| @@ -546,6 +546,7 @@ bool CarlaEngine::init(const char* const clientName) | |||
| data->aboutToClose = false; | |||
| data->maxPluginNumber = 0; | |||
| data->nextPluginId = 0; | |||
| #ifndef BUILD_BRIDGE | |||
| data->oscData = data->osc.getControlData(); | |||
| @@ -558,6 +559,9 @@ bool CarlaEngine::init(const char* const clientName) | |||
| carla_setprocname(clientName); | |||
| #endif | |||
| //data->postEvents.resize(); | |||
| //data->plugins.resize(); | |||
| data->thread.startNow(); | |||
| return true; | |||
| @@ -586,20 +590,17 @@ bool CarlaEngine::close() | |||
| // ----------------------------------------------------------------------- | |||
| // Plugin management | |||
| short CarlaEngine::getNewPluginId() const | |||
| int CarlaEngine::getNewPluginId() const | |||
| { | |||
| qDebug("CarlaEngine::getNewPluginId()"); | |||
| 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 | |||
| { | |||
| 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]; | |||
| } | |||
| #endif | |||
| 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.replace(':', '.'); // ':' is used in JACK1 to split client/port names | |||
| #if 0 | |||
| for (unsigned short i=0; i < data->maxPluginNumber; i++) | |||
| { | |||
| // Check if unique name doesn't exist | |||
| @@ -683,6 +686,7 @@ const char* CarlaEngine::getUniquePluginName(const char* const name) | |||
| // Modify string if not | |||
| sname += " (2)"; | |||
| } | |||
| #endif | |||
| return strdup(sname); | |||
| } | |||
| @@ -695,12 +699,24 @@ short CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, con | |||
| CARLA_ASSERT(filename); | |||
| CARLA_ASSERT(label); | |||
| if (QThread::currentThread() != &data->thread) | |||
| { | |||
| EnginePostEvent postEvent; | |||
| data->postEvents.append(postEvent); | |||
| return; | |||
| } | |||
| if (data->maxPluginNumber == 0) | |||
| { | |||
| #ifdef BUILD_BRIDGE | |||
| data->maxPluginNumber = MAX_PLUGINS; // which is 1 | |||
| #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 | |||
| } | |||
| @@ -781,8 +797,8 @@ short CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, con | |||
| const short id = plugin->id(); | |||
| data->carlaPlugins[id] = plugin; | |||
| data->uniqueNames[id] = plugin->name(); | |||
| EnginePluginData pluginData(plugin); | |||
| data->plugins.append(pluginData); | |||
| return id; | |||
| } | |||
| @@ -1170,6 +1186,8 @@ void CarlaEngine::setOscBridgeData(const CarlaOscData* const oscData) | |||
| } | |||
| #endif | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| // protected calls | |||
| @@ -1184,6 +1202,7 @@ void CarlaEngine::processRack(float* inBuf[2], float* outBuf[2], const uint32_t | |||
| bool processed = false; | |||
| #if 0 | |||
| // process plugins | |||
| 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; | |||
| } | |||
| #endif | |||
| // if no plugins in the rack, copy inputs over outputs | |||
| if (! processed) | |||
| @@ -1298,11 +1318,13 @@ void CarlaEngine::bufferSizeChanged(const uint32_t newBufferSize) | |||
| { | |||
| qDebug("CarlaEngine::bufferSizeChanged(%i)", newBufferSize); | |||
| #if 0 | |||
| for (unsigned short i=0; i < data->maxPluginNumber; i++) | |||
| { | |||
| if (data->carlaPlugins[i] && data->carlaPlugins[i]->enabled() /*&& ! data->carlaPlugins[i]->data->processHighPrecision*/) | |||
| data->carlaPlugins[i]->bufferSizeChanged(newBufferSize); | |||
| } | |||
| #endif | |||
| } | |||
| 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); | |||
| CARLA_ASSERT(data->oscData); | |||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||
| CARLA_ASSERT(pluginName); | |||
| 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); | |||
| 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) | |||
| { | |||
| @@ -1380,7 +1402,7 @@ void CarlaEngine::osc_send_control_remove_plugin(const int32_t pluginId) | |||
| { | |||
| qDebug("CarlaEngine::osc_send_control_remove_plugin(%i)", pluginId); | |||
| 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) | |||
| { | |||
| @@ -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); | |||
| 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); | |||
| 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); | |||
| 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) | |||
| { | |||
| @@ -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); | |||
| 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(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); | |||
| 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(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); | |||
| CARLA_ASSERT(data->oscData); | |||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||
| CARLA_ASSERT(index >= 0); | |||
| 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); | |||
| 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(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); | |||
| #endif | |||
| 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) | |||
| { | |||
| @@ -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); | |||
| CARLA_ASSERT(data->oscData); | |||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||
| CARLA_ASSERT(index >= 0); | |||
| 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); | |||
| 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) | |||
| { | |||
| @@ -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); | |||
| CARLA_ASSERT(data->oscData); | |||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||
| CARLA_ASSERT(count >= 0); | |||
| 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); | |||
| 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(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); | |||
| 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) | |||
| { | |||
| @@ -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); | |||
| CARLA_ASSERT(data->oscData); | |||
| CARLA_ASSERT(pluginId >= 0 && pluginId < data->maxPluginNumber); | |||
| CARLA_ASSERT(pluginId >= 0 && pluginId < (int32_t)data->maxPluginNumber); | |||
| CARLA_ASSERT(count >= 0); | |||
| 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); | |||
| 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(bank >= 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); | |||
| 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(note >= 0 && note < 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); | |||
| 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(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) | |||
| { | |||
| //qDebug("CarlaEngine::osc_send_control_set_input_peak_value(%i, %i)", pluginId, portId); | |||
| 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); | |||
| 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); | |||
| 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); | |||
| 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]); | |||
| } | |||
| } | |||
| #endif | |||
| void CarlaEngine::osc_send_control_exit() | |||
| { | |||
| @@ -31,8 +31,8 @@ VERSION = 0.5.0 | |||
| SOURCES = \ | |||
| carla_engine.cpp \ | |||
| carla_engine_osc.cpp \ | |||
| carla_engine_thread.cpp \ | |||
| # carla_engine_osc.cpp \ | |||
| # carla_engine_thread.cpp \ | |||
| jack.cpp \ | |||
| plugin.cpp \ | |||
| rtaudio.cpp | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * 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 | |||
| * 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, | |||
| * 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. | |||
| * | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| @@ -24,6 +24,8 @@ | |||
| #include "carla_plugin.hpp" | |||
| #include "rt_list.hpp" | |||
| #ifndef BUILD_BRIDGE | |||
| # include <QtCore/QProcessEnvironment> | |||
| #endif | |||
| @@ -104,6 +106,37 @@ const char* CarlaEngineControlEventType2Str(const CarlaEngineControlEventType ty | |||
| const uint32_t PATCHBAY_BUFFER_SIZE = 128; | |||
| 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 { | |||
| CarlaEngineOsc osc; | |||
| CarlaEngineThread thread; | |||
| @@ -112,24 +145,25 @@ struct CarlaEnginePrivateData { | |||
| CallbackFunc callback; | |||
| void* callbackPtr; | |||
| CarlaString lastError; | |||
| #ifndef BUILD_BRIDGE | |||
| QProcessEnvironment procEnv; | |||
| #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; | |||
| unsigned short maxPluginNumber; | |||
| unsigned int maxPluginNumber; | |||
| unsigned int nextPluginId; | |||
| CarlaEnginePrivateData(CarlaEngine* const engine) | |||
| : osc(engine), | |||
| @@ -137,12 +171,11 @@ struct CarlaEnginePrivateData { | |||
| oscData(nullptr), | |||
| callback(nullptr), | |||
| callbackPtr(nullptr), | |||
| carlaPlugins{nullptr}, | |||
| uniqueNames{nullptr}, | |||
| insPeak{0.0}, | |||
| outsPeak{0.0}, | |||
| postEvents(1, 1), | |||
| plugins(1, 1), | |||
| aboutToClose(false), | |||
| maxPluginNumber(0) {} | |||
| maxPluginNumber(0), | |||
| nextPluginId(0) {} | |||
| }; | |||
| CARLA_BACKEND_END_NAMESPACE | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * 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 | |||
| * 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, | |||
| * 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. | |||
| * | |||
| * 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_osc_utils.hpp" | |||
| @@ -166,4 +166,4 @@ private: | |||
| CARLA_BACKEND_END_NAMESPACE | |||
| #endif // CARLA_ENGINE_OSC_HPP | |||
| #endif // __CARLA_ENGINE_OSC_HPP__ | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * 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 | |||
| * 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, | |||
| * 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. | |||
| * | |||
| * 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_utils.hpp" | |||
| #include <QtCore/QMutex> | |||
| #include <QtCore/QThread> | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| @@ -48,11 +48,12 @@ protected: | |||
| private: | |||
| CarlaEngine* const engine; | |||
| QMutex m_mutex; | |||
| bool m_stopNow; | |||
| CarlaMutex m_mutex; | |||
| bool m_stopNow; | |||
| // ---------------------------------------------- | |||
| #if 0 | |||
| class ScopedLocker | |||
| { | |||
| public: | |||
| @@ -68,10 +69,11 @@ private: | |||
| } | |||
| private: | |||
| QMutex* const mutex; | |||
| CarlaMutex* const mutex; | |||
| }; | |||
| #endif | |||
| }; | |||
| CARLA_BACKEND_END_NAMESPACE | |||
| #endif // CARLA_ENGINE_THREAD_HPP | |||
| #endif // __CARLA_ENGINE_THREAD_HPP__ | |||
| @@ -65,7 +65,7 @@ public: | |||
| if (! m_port) | |||
| 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 | |||
| @@ -118,7 +118,7 @@ public: | |||
| if (! m_port) | |||
| return CarlaEngineControlPort::initBuffer(engine); | |||
| buffer = jackbridge_port_get_buffer(m_port, engine->getBufferSize()); | |||
| //buffer = jackbridge_port_get_buffer(m_port, engine->getBufferSize()); | |||
| if (! isInput) | |||
| jackbridge_midi_clear_buffer(buffer); | |||
| @@ -317,7 +317,7 @@ public: | |||
| if (! m_port) | |||
| return CarlaEngineMidiPort::initBuffer(engine); | |||
| buffer = jackbridge_port_get_buffer(m_port, engine->getBufferSize()); | |||
| //buffer = jackbridge_port_get_buffer(m_port, engine->getBufferSize()); | |||
| if (! isInput) | |||
| jackbridge_midi_clear_buffer(buffer); | |||
| @@ -515,9 +515,7 @@ public: | |||
| CarlaEngineJack() | |||
| : CarlaEngine() | |||
| #ifndef BUILD_BRIDGE | |||
| # ifdef Q_COMPILER_INITIALIZER_LISTS | |||
| , m_rackPorts{nullptr} | |||
| # endif | |||
| #endif | |||
| { | |||
| qDebug("CarlaEngineJack::CarlaEngineJack()"); | |||
| @@ -530,11 +528,6 @@ public: | |||
| #ifdef BUILD_BRIDGE | |||
| hasQuit = false; | |||
| #else | |||
| # ifndef Q_COMPILER_INITIALIZER_LISTS | |||
| for (int i=0; i < rackPortCount; i++) | |||
| m_rackPorts[i] = nullptr; | |||
| # endif | |||
| #endif | |||
| } | |||
| @@ -741,6 +734,8 @@ public: | |||
| #endif | |||
| } | |||
| #if 0 | |||
| // ------------------------------------- | |||
| protected: | |||
| @@ -1025,6 +1020,7 @@ protected: | |||
| } | |||
| // ------------------------------------- | |||
| #endif | |||
| private: | |||
| jack_client_t* m_client; | |||
| @@ -1052,6 +1048,7 @@ private: | |||
| jack_port_t* m_rackPorts[rackPortCount]; | |||
| #endif | |||
| #if 0 | |||
| // ------------------------------------- | |||
| static void processPlugin(CarlaPlugin* const p, const uint32_t nframes) | |||
| @@ -1192,6 +1189,7 @@ private: | |||
| if (plugin && plugin->enabled()) | |||
| latencyPlugin(plugin, mode); | |||
| } | |||
| #endif | |||
| }; | |||
| // ----------------------------------------- | |||
| @@ -65,6 +65,8 @@ public: | |||
| // ------------------------------------------------------------------------------------------------------------------- | |||
| // RtAudio Engine | |||
| #if 0 | |||
| class CarlaEngineRtAudio : public CarlaEngine | |||
| { | |||
| public: | |||
| @@ -433,6 +435,7 @@ const char* CarlaEngine::getRtAudioApiName(unsigned int index) | |||
| return nullptr; | |||
| } | |||
| #endif | |||
| CARLA_BACKEND_END_NAMESPACE | |||
| @@ -221,7 +221,7 @@ intptr_t VSTCALLBACK vstHostCallback(AEffect* const effect, const int32_t opcode | |||
| case audioMasterGetVendorString: | |||
| if (ptr) | |||
| { | |||
| strcpy((char*)ptr, "Cadence"); | |||
| strcpy((char*)ptr, "falkTX"); | |||
| ret = 1; | |||
| } | |||
| break; | |||
| @@ -274,7 +274,25 @@ void do_ladspa_check(void* const libHandle, const bool init) | |||
| 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 audioIns = 0; | |||
| @@ -284,6 +302,9 @@ void do_ladspa_check(void* const libHandle, const bool init) | |||
| int parametersOuts = 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++) | |||
| { | |||
| const LADSPA_PortDescriptor portDescriptor = descriptor->PortDescriptors[j]; | |||
| @@ -294,14 +315,16 @@ void do_ladspa_check(void* const libHandle, const bool init) | |||
| audioIns += 1; | |||
| else if (LADSPA_IS_PORT_OUTPUT(portDescriptor)) | |||
| audioOuts += 1; | |||
| audioTotal += 1; | |||
| } | |||
| else if (LADSPA_IS_PORT_CONTROL(portDescriptor)) | |||
| { | |||
| if (LADSPA_IS_PORT_INPUT(portDescriptor)) | |||
| 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; | |||
| parametersTotal += 1; | |||
| } | |||
| } | |||
| @@ -323,81 +346,79 @@ void do_ladspa_check(void* const libHandle, const bool init) | |||
| LADSPA_Data bufferParams[parametersTotal]; | |||
| 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); | |||
| descriptor->connect_port(handle, j, bufferAudio[iA++]); | |||
| } | |||
| else if (LADSPA_IS_PORT_CONTROL(portType)) | |||
| else if (LADSPA_IS_PORT_CONTROL(portDescriptor)) | |||
| { | |||
| // 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 | |||
| min = 0.0f; | |||
| // 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 | |||
| max = 1.0f; | |||
| 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; | |||
| } | |||
| // 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; | |||
| max *= 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 | |||
| min = 0.0f; | |||
| max = sampleRate; | |||
| 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) | |||
| descriptor->activate(handle); | |||
| if (descriptor->run) | |||
| descriptor->run(handle, bufferSize); | |||
| descriptor->run(handle, bufferSize); | |||
| if (descriptor->deactivate) | |||
| descriptor->deactivate(handle); | |||
| if (descriptor->cleanup) | |||
| descriptor->cleanup(handle); | |||
| descriptor->cleanup(handle); | |||
| // 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("maker", descriptor->Maker); | |||
| DISCOVERY_OUT("copyright", descriptor->Copyright); | |||
| DISCOVERY_OUT("unique_id", descriptor->UniqueID); | |||
| DISCOVERY_OUT("uniqueId", descriptor->UniqueID); | |||
| DISCOVERY_OUT("hints", hints); | |||
| DISCOVERY_OUT("audio.ins", audioIns); | |||
| DISCOVERY_OUT("audio.outs", audioOuts); | |||
| @@ -443,8 +464,31 @@ void do_dssi_check(void* const libHandle, const bool init) | |||
| while ((descriptor = descFn(i++))) | |||
| { | |||
| 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 audioIns = 0; | |||
| @@ -457,6 +501,9 @@ void do_dssi_check(void* const libHandle, const bool init) | |||
| int parametersTotal = 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++) | |||
| { | |||
| const LADSPA_PortDescriptor portDescriptor = ldescriptor->PortDescriptors[j]; | |||
| @@ -467,14 +514,16 @@ void do_dssi_check(void* const libHandle, const bool init) | |||
| audioIns += 1; | |||
| else if (LADSPA_IS_PORT_OUTPUT(portDescriptor)) | |||
| audioOuts += 1; | |||
| audioTotal += 1; | |||
| } | |||
| else if (LADSPA_IS_PORT_CONTROL(portDescriptor)) | |||
| { | |||
| if (LADSPA_IS_PORT_INPUT(portDescriptor)) | |||
| 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; | |||
| parametersTotal += 1; | |||
| } | |||
| } | |||
| @@ -482,7 +531,7 @@ void do_dssi_check(void* const libHandle, const bool init) | |||
| if (descriptor->run_synth || descriptor->run_multiple_synths) | |||
| midiIns = midiTotal = 1; | |||
| if (midiIns > 0 && audioOuts > 0) | |||
| if (midiIns > 0 && audioIns == 0 && audioOuts > 0) | |||
| hints |= PLUGIN_IS_SYNTH; | |||
| if (init) | |||
| @@ -498,10 +547,9 @@ void do_dssi_check(void* const libHandle, const bool init) | |||
| continue; | |||
| } | |||
| // we can only get program info per-handle | |||
| if (descriptor->get_program && descriptor->select_program) | |||
| { | |||
| while ((descriptor->get_program(handle, programsTotal++))) | |||
| while (descriptor->get_program(handle, programsTotal++)) | |||
| continue; | |||
| } | |||
| @@ -509,77 +557,74 @@ void do_dssi_check(void* const libHandle, const bool init) | |||
| LADSPA_Data bufferParams[parametersTotal]; | |||
| 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); | |||
| ldescriptor->connect_port(handle, j, bufferAudio[iA++]); | |||
| } | |||
| else if (LADSPA_IS_PORT_CONTROL(portType)) | |||
| else if (LADSPA_IS_PORT_CONTROL(portDescriptor)) | |||
| { | |||
| // 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 | |||
| min = 0.0f; | |||
| // 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 | |||
| max = 1.0f; | |||
| 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; | |||
| } | |||
| // 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; | |||
| max *= 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 | |||
| min = 0.0f; | |||
| max = sampleRate; | |||
| 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 | |||
| 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); | |||
| } | |||
| @@ -612,14 +657,13 @@ void do_dssi_check(void* const libHandle, const bool init) | |||
| else | |||
| descriptor->run_synth(handle, bufferSize, midiEvents, midiEventCount); | |||
| } | |||
| else if (ldescriptor->run) | |||
| else | |||
| ldescriptor->run(handle, bufferSize); | |||
| if (ldescriptor->deactivate) | |||
| ldescriptor->deactivate(handle); | |||
| if (ldescriptor->cleanup) | |||
| ldescriptor->cleanup(handle); | |||
| ldescriptor->cleanup(handle); | |||
| // 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::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 | |||
| @@ -689,80 +735,69 @@ void do_lv2_check(const char* const bundle, const bool 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); | |||
| if (! libHandle) | |||
| { | |||
| isLoadable = false; | |||
| print_lib_error(rdfDescriptor->Binary); | |||
| delete rdfDescriptor; | |||
| continue; | |||
| break; | |||
| } | |||
| 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; | |||
| @@ -777,6 +812,14 @@ void do_lv2_check(const char* const bundle, const bool init) | |||
| int parametersTotal = 0; | |||
| 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++) | |||
| { | |||
| 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; | |||
| else if (LV2_IS_PORT_OUTPUT(rdfPort->Types)) | |||
| audioOuts += 1; | |||
| audioTotal += 1; | |||
| } | |||
| 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; | |||
| else if (LV2_IS_PORT_OUTPUT(rdfPort->Types)) | |||
| parametersOuts += 1; | |||
| parametersTotal += 1; | |||
| } | |||
| } | |||
| @@ -822,6 +867,7 @@ void do_lv2_check(const char* const bundle, const bool init) | |||
| midiIns += 1; | |||
| else if (LV2_IS_PORT_OUTPUT(rdfPort->Types)) | |||
| midiOuts += 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"); | |||
| if (! vstFn) | |||
| { | |||
| 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); | |||
| @@ -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); | |||
| if (vstCategory == kPlugCategShell) | |||
| if (vstCategory == kPlugCategShell && effect->uniqueID == 0) | |||
| { | |||
| if ((vstCurrentUniqueId = effect->dispatcher(effect, effShellGetNextPlugin, 0, 0, strBuf, 0.0f)) != 0) | |||
| cName = strBuf; | |||
| @@ -1409,6 +1457,25 @@ int main(int argc, char* argv[]) | |||
| if (doInit && getenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS")) | |||
| 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) | |||
| { | |||
| case PLUGIN_LADSPA: | |||
| @@ -1436,7 +1503,7 @@ int main(int argc, char* argv[]) | |||
| break; | |||
| } | |||
| if (openLib) | |||
| if (openLib && handle) | |||
| lib_close(handle); | |||
| return 0; | |||
| @@ -9,7 +9,7 @@ | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| @@ -81,9 +81,11 @@ | |||
| #ifdef NDEBUG | |||
| # 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_INT2(cond, v1, v2) ((!(cond)) ? carla_assert_int2(#cond, __FILE__, __LINE__, v1, v2) : qt_noop()) | |||
| #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_INT2(cond, v1, v2) Q_ASSERT(cond) | |||
| #endif | |||
| // Define CARLA_EXPORT | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| * Carla Backend | |||
| * Carla Backend utils | |||
| * Copyright (C) 2011-2012 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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, | |||
| * 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. | |||
| * | |||
| * 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_utils.hpp" | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| /*! | |||
| * @defgroup CarlaBackendUtils Carla Backend Utils | |||
| * | |||
| * Carla Backend Utils | |||
| * | |||
| * @{ | |||
| */ | |||
| // ------------------------------------------------------------------------------------------------------------------- | |||
| // ------------------------------------------------- | |||
| static inline | |||
| const char* BinaryType2Str(const BinaryType& type) | |||
| @@ -156,41 +148,14 @@ const char* InternalParametersIndex2Str(const InternalParametersIndex& index) | |||
| return "PARAMETER_BALANCE_LEFT"; | |||
| case PARAMETER_BALANCE_RIGHT: | |||
| return "PARAMETER_BALANCE_RIGHT"; | |||
| case PARAMETER_PANNING: | |||
| return "PARAMETER_PANNING"; | |||
| } | |||
| qWarning("CarlaBackend::InternalParametersIndex2Str(%i) - invalid index", index); | |||
| 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 | |||
| const char* OptionsType2Str(const OptionsType& type) | |||
| { | |||
| @@ -202,24 +167,25 @@ const char* OptionsType2Str(const OptionsType& type) | |||
| return "OPTION_PROCESS_MODE"; | |||
| case OPTION_PROCESS_HIGH_PRECISION: | |||
| return "OPTION_PROCESS_HIGH_PRECISION"; | |||
| case OPTION_MAX_PARAMETERS: | |||
| return "OPTION_MAX_PARAMETERS"; | |||
| case OPTION_PREFERRED_BUFFER_SIZE: | |||
| return "OPTION_PREFERRED_BUFFER_SIZE"; | |||
| case OPTION_PREFERRED_SAMPLE_RATE: | |||
| return "OPTION_PREFERRED_SAMPLE_RATE"; | |||
| case OPTION_FORCE_STEREO: | |||
| return "OPTION_FORCE_STEREO"; | |||
| #ifdef WANT_DSSI | |||
| case OPTION_USE_DSSI_VST_CHUNKS: | |||
| return "OPTION_USE_DSSI_VST_CHUNKS"; | |||
| #endif | |||
| case OPTION_PREFER_PLUGIN_BRIDGES: | |||
| return "OPTION_PREFER_PLUGIN_BRIDGES"; | |||
| case 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: | |||
| 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: | |||
| return "OPTION_PATH_BRIDGE_NATIVE"; | |||
| case OPTION_PATH_BRIDGE_POSIX32: | |||
| @@ -230,6 +196,7 @@ const char* OptionsType2Str(const OptionsType& type) | |||
| return "OPTION_PATH_BRIDGE_WIN32"; | |||
| case OPTION_PATH_BRIDGE_WIN64: | |||
| return "OPTION_PATH_BRIDGE_WIN64"; | |||
| #endif | |||
| #ifdef WANT_LV2 | |||
| case 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"; | |||
| case CALLBACK_SHOW_GUI: | |||
| return "CALLBACK_SHOW_GUI"; | |||
| case CALLBACK_RESIZE_GUI: | |||
| return "CALLBACK_RESIZE_GUI"; | |||
| case CALLBACK_UPDATE: | |||
| return "CALLBACK_UPDATE"; | |||
| case CALLBACK_RELOAD_INFO: | |||
| @@ -332,7 +297,28 @@ const char* ProcessMode2Str(const ProcessMode& mode) | |||
| 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 | |||
| const char* getPluginTypeString(const PluginType& type) | |||
| @@ -343,8 +329,10 @@ const char* getPluginTypeString(const PluginType& type) | |||
| { | |||
| case PLUGIN_NONE: | |||
| return "NONE"; | |||
| #ifndef BUILD_BRIDGE | |||
| case PLUGIN_INTERNAL: | |||
| return "INTERNAL"; | |||
| #endif | |||
| case PLUGIN_LADSPA: | |||
| return "LADSPA"; | |||
| case PLUGIN_DSSI: | |||
| @@ -353,39 +341,20 @@ const char* getPluginTypeString(const PluginType& type) | |||
| return "LV2"; | |||
| case PLUGIN_VST: | |||
| return "VST"; | |||
| #ifndef BUILD_BRIDGE | |||
| case PLUGIN_GIG: | |||
| return "GIG"; | |||
| case PLUGIN_SF2: | |||
| return "SF2"; | |||
| case PLUGIN_SFZ: | |||
| return "SFZ"; | |||
| #endif | |||
| } | |||
| return "NONE"; | |||
| } | |||
| // ------------------------------------------------------------------------------------------------------------------- | |||
| static inline | |||
| uintptr_t getAddressFromPointer(void* const ptr) | |||
| { | |||
| qDebug("CarlaBackend::getAddressFromPointer(%p)", ptr); | |||
| CARLA_ASSERT(ptr != nullptr); | |||
| uintptr_t* addr = (uintptr_t*)&ptr; | |||
| return *addr; | |||
| } | |||
| static inline | |||
| void* getPointerFromAddress(const uintptr_t& addr) | |||
| { | |||
| CARLA_ASSERT(addr != 0); | |||
| uintptr_t** const ptr = (uintptr_t**)&addr; | |||
| return *ptr; | |||
| } | |||
| // ------------------------------------------------------------------------------------------------------------------- | |||
| // ------------------------------------------------- | |||
| static inline | |||
| PluginCategory getPluginCategoryFromName(const char* const name) | |||
| @@ -466,8 +435,6 @@ PluginCategory getPluginCategoryFromName(const char* const name) | |||
| return PLUGIN_CATEGORY_NONE; | |||
| } | |||
| /**@}*/ | |||
| 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; | |||
| } | |||
| // ------------------------------------------------- | |||
| // 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 | |||
| // TODO - review these | |||
| static inline | |||
| bool is_lv2_feature_supported(const LV2_URI uri) | |||
| { | |||
| @@ -1137,6 +1157,12 @@ bool is_lv2_feature_supported(const LV2_URI uri) | |||
| return true; | |||
| if (strcmp(uri, LV2_CORE__isLive) == 0) | |||
| 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) | |||
| return true; | |||
| 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 | |||
| // TODO - review these | |||
| static inline | |||
| 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, | |||
| * 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. | |||
| * | |||
| * 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); | |||
| } | |||
| 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 | |||
| void carla_sleep(const unsigned int secs) | |||
| @@ -36,7 +36,7 @@ public: | |||
| qcount = 0; | |||
| 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); | |||
| } | |||
| @@ -53,7 +53,7 @@ public: | |||
| clear(); | |||
| 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); | |||
| } | |||
| @@ -62,12 +62,12 @@ public: | |||
| { | |||
| if (! isEmpty()) | |||
| { | |||
| ListHeadData* data; | |||
| RtListData* data; | |||
| k_list_head* entry; | |||
| list_for_each(entry, &queue) | |||
| { | |||
| data = list_entry(entry, ListHeadData, siblings); | |||
| data = list_entry(entry, RtListData, siblings); | |||
| rtsafe_memory_pool_deallocate(mempool, data); | |||
| } | |||
| } | |||
| @@ -83,17 +83,18 @@ public: | |||
| 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) | |||
| { | |||
| ListHeadData* data; | |||
| RtListData* data; | |||
| if (sleepy) | |||
| data = (ListHeadData*)rtsafe_memory_pool_allocate_sleepy(mempool); | |||
| data = (RtListData*)rtsafe_memory_pool_allocate_sleepy(mempool); | |||
| else | |||
| data = (ListHeadData*)rtsafe_memory_pool_allocate_atomic(mempool); | |||
| data = (RtListData*)rtsafe_memory_pool_allocate_atomic(mempool); | |||
| if (data) | |||
| { | |||
| @@ -126,12 +127,12 @@ public: | |||
| bool removeOne(const T& value) | |||
| { | |||
| ListHeadData* data; | |||
| RtListData* data; | |||
| k_list_head* entry; | |||
| list_for_each(entry, &queue) | |||
| { | |||
| data = list_entry(entry, ListHeadData, siblings); | |||
| data = list_entry(entry, RtListData, siblings); | |||
| if (data->value == value) | |||
| { | |||
| @@ -147,13 +148,13 @@ public: | |||
| void removeAll(const T& value) | |||
| { | |||
| ListHeadData* data; | |||
| RtListData* data; | |||
| k_list_head* entry; | |||
| k_list_head* tmp; | |||
| list_for_each_safe(entry, tmp, &queue) | |||
| { | |||
| data = list_entry(entry, ListHeadData, siblings); | |||
| data = list_entry(entry, RtListData, siblings); | |||
| if (data->value == value) | |||
| { | |||
| @@ -169,7 +170,7 @@ private: | |||
| k_list_head queue; | |||
| RtMemPool_Handle mempool; | |||
| struct ListHeadData { | |||
| struct RtListData { | |||
| T value; | |||
| k_list_head siblings; | |||
| }; | |||
| @@ -192,7 +193,7 @@ private: | |||
| } | |||
| 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; | |||