Browse Source

Misc stuff

tags/1.9.4
falkTX 11 years ago
parent
commit
d11d669174
16 changed files with 594 additions and 473 deletions
  1. +79
    -93
      source/backend/carla_backend.hpp
  2. +71
    -61
      source/backend/carla_engine.hpp
  3. +3
    -6
      source/backend/carla_plugin.hpp
  4. +60
    -36
      source/backend/engine/carla_engine.cpp
  5. +2
    -2
      source/backend/engine/carla_engine.pro
  6. +48
    -15
      source/backend/engine/carla_engine_internal.hpp
  7. +5
    -5
      source/backend/engine/carla_engine_osc.hpp
  8. +11
    -9
      source/backend/engine/carla_engine_thread.hpp
  9. +8
    -10
      source/backend/engine/jack.cpp
  10. +3
    -0
      source/backend/engine/rtaudio.cpp
  11. +203
    -136
      source/discovery/carla-discovery.cpp
  12. +4
    -2
      source/includes/carla_defines.hpp
  13. +47
    -80
      source/utils/carla_backend_utils.hpp
  14. +27
    -2
      source/utils/carla_lv2_utils.hpp
  15. +8
    -2
      source/utils/carla_utils.hpp
  16. +15
    -14
      source/utils/rt_list.hpp

+ 79
- 93
source/backend/carla_backend.hpp View File

@@ -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
*/


+ 71
- 61
source/backend/carla_engine.hpp View File

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


+ 3
- 6
source/backend/carla_plugin.hpp View File

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


+ 60
- 36
source/backend/engine/carla_engine.cpp View File

@@ -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()
{


+ 2
- 2
source/backend/engine/carla_engine.pro View File

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


+ 48
- 15
source/backend/engine/carla_engine_internal.hpp View File

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


+ 5
- 5
source/backend/engine/carla_engine_osc.hpp View File

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

+ 11
- 9
source/backend/engine/carla_engine_thread.hpp View File

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

+ 8
- 10
source/backend/engine/jack.cpp View File

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

// -----------------------------------------


+ 3
- 0
source/backend/engine/rtaudio.cpp View File

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



+ 203
- 136
source/discovery/carla-discovery.cpp View File

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


+ 4
- 2
source/includes/carla_defines.hpp View File

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


+ 47
- 80
source/utils/carla_backend_utils.hpp View File

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

+ 27
- 2
source/utils/carla_lv2_utils.hpp View File

@@ -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)
{


+ 8
- 2
source/utils/carla_utils.hpp View File

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


+ 15
- 14
source/utils/rt_list.hpp View File

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



Loading…
Cancel
Save