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