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