@@ -546,7 +546,7 @@ enum ProcessMode { | |||||
* | * | ||||
* \see CallbackType and set_callback_function() | * \see CallbackType and set_callback_function() | ||||
*/ | */ | ||||
typedef void (*CallbackFunc)(void* ptr, CallbackType action, unsigned int pluginId, int value1, int value2, double value3, const char* valueStr); | |||||
typedef void (*CallbackFunc)(void* ptr, CallbackType action, unsigned int pluginId, int value1, int value2, float value3, const char* valueStr); | |||||
/*! | /*! | ||||
* Parameter data | * Parameter data | ||||
@@ -599,6 +599,15 @@ struct ParameterRanges { | |||||
else if (value > max) | else if (value > max) | ||||
value = max; | value = max; | ||||
} | } | ||||
float fixValue(const float& value) const | |||||
{ | |||||
if (value < min) | |||||
return min; | |||||
else if (value > max) | |||||
return max; | |||||
return value; | |||||
} | |||||
}; | }; | ||||
/*! | /*! | ||||
@@ -216,7 +216,6 @@ struct EngineEvent { | |||||
*/ | */ | ||||
struct EngineOptions { | struct EngineOptions { | ||||
ProcessMode processMode; | ProcessMode processMode; | ||||
bool processHighPrecision; | |||||
bool forceStereo; | bool forceStereo; | ||||
bool preferPluginBridges; | bool preferPluginBridges; | ||||
@@ -254,7 +253,6 @@ struct EngineOptions { | |||||
EngineOptions() | EngineOptions() | ||||
: processMode(PROCESS_MODE_CONTINUOUS_RACK), | : processMode(PROCESS_MODE_CONTINUOUS_RACK), | ||||
processHighPrecision(false), | |||||
forceStereo(false), | forceStereo(false), | ||||
preferPluginBridges(false), | preferPluginBridges(false), | ||||
preferUiBridges(true), | preferUiBridges(true), | ||||
@@ -535,7 +533,7 @@ private: | |||||
* Private data used in CarlaEngine. | * Private data used in CarlaEngine. | ||||
* No other than CarlaEngine must have direct access to this. | * No other than CarlaEngine must have direct access to this. | ||||
*/ | */ | ||||
struct CarlaEngineProtectedData; | |||||
struct CarlaEnginePrivateData; | |||||
/*! | /*! | ||||
* Carla Engine. | * Carla Engine. | ||||
@@ -665,13 +663,13 @@ public: | |||||
* Add new plugin.\n | * Add new plugin.\n | ||||
* Returns the id of the plugin, or -1 if the operation failed. | * Returns the id of the plugin, or -1 if the operation failed. | ||||
*/ | */ | ||||
bool addPlugin(const BinaryType btype, const PluginType ptype, const char* const filename, const char* const name, const char* const label, void* const extra = nullptr); | |||||
bool addPlugin(const BinaryType btype, const PluginType ptype, const char* const filename, const char* const name, const char* const label, const void* const extra = nullptr); | |||||
/*! | /*! | ||||
* Add new plugin, using native binary type.\n | * Add new plugin, using native binary type.\n | ||||
* Returns the id of the plugin, or -1 if the operation failed. | * Returns the id of the plugin, or -1 if the operation failed. | ||||
*/ | */ | ||||
bool addPlugin(const PluginType ptype, const char* const filename, const char* const name, const char* const label, void* const extra = nullptr) | |||||
bool addPlugin(const PluginType ptype, const char* const filename, const char* const name, const char* const label, const void* const extra = nullptr) | |||||
{ | { | ||||
return addPlugin(BINARY_NATIVE, ptype, filename, name, label, extra); | return addPlugin(BINARY_NATIVE, ptype, filename, name, label, extra); | ||||
} | } | ||||
@@ -733,6 +731,11 @@ public: | |||||
return fOptions; | return fOptions; | ||||
} | } | ||||
ProcessMode getProccessMode() const | |||||
{ | |||||
return fOptions.processMode; | |||||
} | |||||
/*! | /*! | ||||
* Get current Time information (read-only). | * Get current Time information (read-only). | ||||
*/ | */ | ||||
@@ -763,7 +766,7 @@ public: | |||||
/*! | /*! | ||||
* TODO. | * TODO. | ||||
*/ | */ | ||||
void callback(const CallbackType action, const unsigned short pluginId, const int value1, const int value2, const double value3, const char* const valueStr); | |||||
void callback(const CallbackType action, const unsigned short pluginId, const int value1, const int value2, const float value3, const char* const valueStr); | |||||
/*! | /*! | ||||
* TODO. | * TODO. | ||||
@@ -846,8 +849,6 @@ protected: | |||||
EngineOptions fOptions; | EngineOptions fOptions; | ||||
EngineTimeInfo fTimeInfo; | EngineTimeInfo fTimeInfo; | ||||
ScopedPointer<CarlaEngineProtectedData> const fData; | |||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
// Rack mode data | // Rack mode data | ||||
EngineEvent* getRackEventBuffer(const bool isInput); | EngineEvent* getRackEventBuffer(const bool isInput); | ||||
@@ -868,6 +869,11 @@ protected: | |||||
void processPatchbay(float** inBuf, float** outBuf, const uint32_t bufCount[2], const uint32_t frames); | void processPatchbay(float** inBuf, float** outBuf, const uint32_t bufCount[2], const uint32_t frames); | ||||
#endif | #endif | ||||
/*! | |||||
* TODO. | |||||
*/ | |||||
void proccessPendingEvents(); | |||||
/*! | /*! | ||||
* Report to all plugins about buffer size change. | * Report to all plugins about buffer size change. | ||||
*/ | */ | ||||
@@ -881,6 +887,8 @@ protected: | |||||
void sampleRateChanged(const double newSampleRate); | void sampleRateChanged(const double newSampleRate); | ||||
private: | private: | ||||
ScopedPointer<CarlaEnginePrivateData> const fData; | |||||
#ifdef WANT_JACK | #ifdef WANT_JACK | ||||
static CarlaEngine* newJack(); | static CarlaEngine* newJack(); | ||||
#endif | #endif | ||||
@@ -94,7 +94,7 @@ public: | |||||
* \param engine The engine which this plugin belongs to, must not be null | * \param engine The engine which this plugin belongs to, must not be null | ||||
* \param id The 'id' of this plugin, must be between 0 and CarlaEngine::maxPluginNumber() | * \param id The 'id' of this plugin, must be between 0 and CarlaEngine::maxPluginNumber() | ||||
*/ | */ | ||||
CarlaPlugin(CarlaEngine* const engine, const int id); | |||||
CarlaPlugin(CarlaEngine* const engine, const unsigned int id); | |||||
/*! | /*! | ||||
* This is the destructor of the base plugin class. | * This is the destructor of the base plugin class. | ||||
@@ -124,7 +124,7 @@ public: | |||||
* | * | ||||
* \see setId() | * \see setId() | ||||
*/ | */ | ||||
unsigned short id() const; | |||||
unsigned int id() const; | |||||
/*! | /*! | ||||
* Get the plugin's hints. | * Get the plugin's hints. | ||||
@@ -291,12 +291,12 @@ public: | |||||
/*! | /*! | ||||
* Get the current parameter value of \a parameterId. | * Get the current parameter value of \a parameterId. | ||||
*/ | */ | ||||
virtual double getParameterValue(const uint32_t parameterId); | |||||
virtual float getParameterValue(const uint32_t parameterId); | |||||
/*! | /*! | ||||
* Get the scalepoint \a scalePointId value of the parameter \a parameterId. | * Get the scalepoint \a scalePointId value of the parameter \a parameterId. | ||||
*/ | */ | ||||
virtual double getParameterScalePointValue(const uint32_t parameterId, const uint32_t scalePointId); | |||||
virtual float getParameterScalePointValue(const uint32_t parameterId, const uint32_t scalePointId); | |||||
/*! | /*! | ||||
* Get the plugin's label (URI for PLUGIN_LV2). | * Get the plugin's label (URI for PLUGIN_LV2). | ||||
@@ -402,7 +402,7 @@ public: | |||||
* \param sendOsc Send message change over OSC | * \param sendOsc Send message change over OSC | ||||
* \param sendCallback Send message change to registered callback | * \param sendCallback Send message change to registered callback | ||||
*/ | */ | ||||
void setDryWet(double value, const bool sendOsc, const bool sendCallback); | |||||
void setDryWet(const float value, const bool sendOsc, const bool sendCallback); | |||||
/*! | /*! | ||||
* Set the plugin's output volume to \a value.\n | * Set the plugin's output volume to \a value.\n | ||||
@@ -411,7 +411,7 @@ public: | |||||
* \param sendOsc Send message change over OSC | * \param sendOsc Send message change over OSC | ||||
* \param sendCallback Send message change to registered callback | * \param sendCallback Send message change to registered callback | ||||
*/ | */ | ||||
void setVolume(double value, const bool sendOsc, const bool sendCallback); | |||||
void setVolume(const float value, const bool sendOsc, const bool sendCallback); | |||||
/*! | /*! | ||||
* Set the plugin's output left balance value to \a value.\n | * Set the plugin's output left balance value to \a value.\n | ||||
@@ -422,7 +422,7 @@ public: | |||||
* | * | ||||
* \note Pure-Stereo plugins only! | * \note Pure-Stereo plugins only! | ||||
*/ | */ | ||||
void setBalanceLeft(double value, const bool sendOsc, const bool sendCallback); | |||||
void setBalanceLeft(const float value, const bool sendOsc, const bool sendCallback); | |||||
/*! | /*! | ||||
* Set the plugin's output right balance value to \a value.\n | * Set the plugin's output right balance value to \a value.\n | ||||
@@ -433,7 +433,7 @@ public: | |||||
* | * | ||||
* \note Pure-Stereo plugins only! | * \note Pure-Stereo plugins only! | ||||
*/ | */ | ||||
void setBalanceRight(double value, const bool sendOsc, const bool sendCallback); | |||||
void setBalanceRight(const float value, const bool sendOsc, const bool sendCallback); | |||||
/*! | /*! | ||||
* Set the plugin's output panning value to \a value.\n | * Set the plugin's output panning value to \a value.\n | ||||
@@ -444,7 +444,7 @@ public: | |||||
* | * | ||||
* \note Force-Stereo plugins only! | * \note Force-Stereo plugins only! | ||||
*/ | */ | ||||
void setPanning(double value, const bool sendOsc, const bool sendCallback); | |||||
void setPanning(const float value, const bool sendOsc, const bool sendCallback); | |||||
#if 0 //ndef BUILD_BRIDGE | #if 0 //ndef BUILD_BRIDGE | ||||
/*! | /*! | ||||
@@ -467,7 +467,7 @@ public: | |||||
* | * | ||||
* \see getParameterValue() | * \see getParameterValue() | ||||
*/ | */ | ||||
virtual void setParameterValue(const uint32_t parameterId, double value, const bool sendGui, const bool sendOsc, const bool sendCallback); | |||||
virtual void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback); | |||||
/*! | /*! | ||||
* Set a plugin's parameter value, including internal parameters.\n | * Set a plugin's parameter value, including internal parameters.\n | ||||
@@ -480,7 +480,7 @@ public: | |||||
* \see setBalanceLeft() | * \see setBalanceLeft() | ||||
* \see setBalanceRight() | * \see setBalanceRight() | ||||
*/ | */ | ||||
void setParameterValueByRIndex(const int32_t rindex, const double value, const bool sendGui, const bool sendOsc, const bool sendCallback); | |||||
void setParameterValueByRIndex(const int32_t rindex, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback); | |||||
/*! | /*! | ||||
* Set parameter's \a parameterId MIDI channel to \a channel.\n | * Set parameter's \a parameterId MIDI channel to \a channel.\n | ||||
@@ -529,7 +529,7 @@ public: | |||||
* \param sendCallback Send message change to registered callback | * \param sendCallback Send message change to registered callback | ||||
* \param block Block the audio callback | * \param block Block the audio callback | ||||
*/ | */ | ||||
virtual void setProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block); | |||||
virtual void setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block); | |||||
/*! | /*! | ||||
* Change the current MIDI plugin program to \a index. | * Change the current MIDI plugin program to \a index. | ||||
@@ -543,7 +543,7 @@ public: | |||||
* \param sendCallback Send message change to registered callback | * \param sendCallback Send message change to registered callback | ||||
* \param block Block the audio callback | * \param block Block the audio callback | ||||
*/ | */ | ||||
virtual void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block); | |||||
virtual void setMidiProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block); | |||||
/*! | /*! | ||||
* This is an overloaded call to setMidiProgram().\n | * This is an overloaded call to setMidiProgram().\n | ||||
@@ -641,6 +641,7 @@ public: | |||||
/*! | /*! | ||||
* Send a single midi note to be processed in the next audio callback.\n | * Send a single midi note to be processed in the next audio callback.\n | ||||
* A note with 0 velocity means note-off. | * A note with 0 velocity means note-off. | ||||
* \note Non-RT call | |||||
*/ | */ | ||||
void sendMidiSingleNote(const uint8_t channel, const uint8_t note, const uint8_t velo, const bool sendGui, const bool sendOsc, const bool sendCallback); | void sendMidiSingleNote(const uint8_t channel, const uint8_t note, const uint8_t velo, const bool sendGui, const bool sendOsc, const bool sendCallback); | ||||
@@ -736,6 +737,7 @@ public: | |||||
struct Initializer { | struct Initializer { | ||||
CarlaEngine* const engine; | CarlaEngine* const engine; | ||||
const unsigned int id; | |||||
const char* const filename; | const char* const filename; | ||||
const char* const name; | const char* const name; | ||||
const char* const label; | const char* const label; | ||||
@@ -1,18 +1,18 @@ | |||||
/* | /* | ||||
* Carla Engine | * Carla Engine | ||||
* 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 | |||||
* the Free Software Foundation; either version 2 of the License, or | |||||
* any later version. | |||||
* 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 the Free Software Foundation; either version 2 of | |||||
* the License, or any later version. | |||||
* | * | ||||
* This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | * GNU General Public License for more details. | ||||
* | * | ||||
* For a full copy of the GNU General Public License see the COPYING file | |||||
* For a full copy of the GNU General Public License see the GPL.txt file | |||||
*/ | */ | ||||
#include "carla_engine_internal.hpp" | #include "carla_engine_internal.hpp" | ||||
@@ -40,16 +40,15 @@ CarlaEnginePort::~CarlaEnginePort() | |||||
// Carla Engine Audio port | // Carla Engine Audio port | ||||
CarlaEngineAudioPort::CarlaEngineAudioPort(const bool isInput, const ProcessMode processMode) | CarlaEngineAudioPort::CarlaEngineAudioPort(const bool isInput, const ProcessMode processMode) | ||||
: CarlaEnginePort(isInput, processMode) | |||||
: CarlaEnginePort(isInput, processMode), | |||||
fBuffer(nullptr) | |||||
{ | { | ||||
qDebug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode)); | qDebug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode)); | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (kProcessMode == PROCESS_MODE_PATCHBAY) | if (kProcessMode == PROCESS_MODE_PATCHBAY) | ||||
fBuffer = new float[PATCHBAY_BUFFER_SIZE]; | fBuffer = new float[PATCHBAY_BUFFER_SIZE]; | ||||
else | |||||
#endif | #endif | ||||
fBuffer = nullptr; | |||||
} | } | ||||
CarlaEngineAudioPort::~CarlaEngineAudioPort() | CarlaEngineAudioPort::~CarlaEngineAudioPort() | ||||
@@ -62,7 +61,7 @@ CarlaEngineAudioPort::~CarlaEngineAudioPort() | |||||
CARLA_ASSERT(fBuffer); | CARLA_ASSERT(fBuffer); | ||||
if (fBuffer) | if (fBuffer) | ||||
delete[] (float*)fBuffer; | |||||
delete[] fBuffer; | |||||
} | } | ||||
#endif | #endif | ||||
} | } | ||||
@@ -70,9 +69,7 @@ CarlaEngineAudioPort::~CarlaEngineAudioPort() | |||||
void CarlaEngineAudioPort::initBuffer(CarlaEngine* const) | void CarlaEngineAudioPort::initBuffer(CarlaEngine* const) | ||||
{ | { | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (kProcessMode != PROCESS_MODE_PATCHBAY) | |||||
fBuffer = nullptr; | |||||
else if (! kIsInput) | |||||
if (kProcessMode == PROCESS_MODE_PATCHBAY && ! kIsInput) | |||||
carla_zeroFloat(fBuffer, PATCHBAY_BUFFER_SIZE); | carla_zeroFloat(fBuffer, PATCHBAY_BUFFER_SIZE); | ||||
#endif | #endif | ||||
} | } | ||||
@@ -82,16 +79,15 @@ void CarlaEngineAudioPort::initBuffer(CarlaEngine* const) | |||||
CarlaEngineEventPort::CarlaEngineEventPort(const bool isInput, const ProcessMode processMode) | CarlaEngineEventPort::CarlaEngineEventPort(const bool isInput, const ProcessMode processMode) | ||||
: CarlaEnginePort(isInput, processMode), | : CarlaEnginePort(isInput, processMode), | ||||
kMaxEventCount(processMode == PROCESS_MODE_CONTINUOUS_RACK ? RACK_EVENT_COUNT : PATCHBAY_EVENT_COUNT) | |||||
kMaxEventCount(processMode == PROCESS_MODE_CONTINUOUS_RACK ? RACK_EVENT_COUNT : PATCHBAY_EVENT_COUNT), | |||||
fBuffer(nullptr) | |||||
{ | { | ||||
qDebug("CarlaEngineEventPort::CarlaEngineEventPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode)); | qDebug("CarlaEngineEventPort::CarlaEngineEventPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode)); | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (kProcessMode == PROCESS_MODE_PATCHBAY) | if (kProcessMode == PROCESS_MODE_PATCHBAY) | ||||
fBuffer = new EngineEvent[PATCHBAY_EVENT_COUNT]; | fBuffer = new EngineEvent[PATCHBAY_EVENT_COUNT]; | ||||
else | |||||
#endif | #endif | ||||
fBuffer = nullptr; | |||||
} | } | ||||
CarlaEngineEventPort::~CarlaEngineEventPort() | CarlaEngineEventPort::~CarlaEngineEventPort() | ||||
@@ -235,14 +231,16 @@ void CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t cha | |||||
CARLA_ASSERT(fBuffer != nullptr); | CARLA_ASSERT(fBuffer != nullptr); | ||||
CARLA_ASSERT(channel < MAX_MIDI_CHANNELS); | CARLA_ASSERT(channel < MAX_MIDI_CHANNELS); | ||||
CARLA_ASSERT(data); | |||||
CARLA_ASSERT(data != nullptr); | |||||
CARLA_ASSERT(size > 0); | CARLA_ASSERT(size > 0); | ||||
if (fBuffer == nullptr) | if (fBuffer == nullptr) | ||||
return; | return; | ||||
if (channel >= MAX_MIDI_CHANNELS) | if (channel >= MAX_MIDI_CHANNELS) | ||||
return; | return; | ||||
if (! (data && size > 0)) | |||||
if (data == nullptr) | |||||
return; | |||||
if (size == 0) | |||||
return; | return; | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
@@ -282,13 +280,12 @@ void CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t cha | |||||
CarlaEngineClient::CarlaEngineClient(const EngineType engineType, const ProcessMode processMode) | CarlaEngineClient::CarlaEngineClient(const EngineType engineType, const ProcessMode processMode) | ||||
: kEngineType(engineType), | : kEngineType(engineType), | ||||
kProcessMode(processMode) | |||||
kProcessMode(processMode), | |||||
fActive(false), | |||||
fLatency(0) | |||||
{ | { | ||||
qDebug("CarlaEngineClient::CarlaEngineClient(%s, %s)", EngineType2Str(engineType), ProcessMode2Str(processMode)); | qDebug("CarlaEngineClient::CarlaEngineClient(%s, %s)", EngineType2Str(engineType), ProcessMode2Str(processMode)); | ||||
CARLA_ASSERT(engineType != kEngineTypeNull); | CARLA_ASSERT(engineType != kEngineTypeNull); | ||||
fActive = false; | |||||
fLatency = 0; | |||||
} | } | ||||
CarlaEngineClient::~CarlaEngineClient() | CarlaEngineClient::~CarlaEngineClient() | ||||
@@ -341,12 +338,11 @@ void CarlaEngineClient::setLatency(const uint32_t samples) | |||||
// Carla Engine | // Carla Engine | ||||
CarlaEngine::CarlaEngine() | CarlaEngine::CarlaEngine() | ||||
: fData(new CarlaEngineProtectedData(this)) | |||||
: fBufferSize(0), | |||||
fSampleRate(0.0), | |||||
fData(new CarlaEnginePrivateData(this)) | |||||
{ | { | ||||
qDebug("CarlaEngine::CarlaEngine()"); | qDebug("CarlaEngine::CarlaEngine()"); | ||||
fBufferSize = 0; | |||||
fSampleRate = 0.0; | |||||
} | } | ||||
CarlaEngine::~CarlaEngine() | CarlaEngine::~CarlaEngine() | ||||
@@ -356,6 +352,46 @@ CarlaEngine::~CarlaEngine() | |||||
//data = nullptr; | //data = nullptr; | ||||
} | } | ||||
// ----------------------------------------------------------------------- | |||||
// Helpers | |||||
void doPluginRemove(CarlaEnginePrivateData* const fData, const bool unlock) | |||||
{ | |||||
CARLA_ASSERT(fData->curPluginCount > 0); | |||||
fData->curPluginCount--; | |||||
const unsigned int id = fData->nextAction.pluginId; | |||||
// reset current plugin | |||||
fData->plugins[id].plugin = nullptr; | |||||
CarlaPlugin* plugin; | |||||
// move all plugins 1 spot backwards | |||||
for (unsigned int i=id; i < fData->curPluginCount; i++) | |||||
{ | |||||
plugin = fData->plugins[i+1].plugin; | |||||
CARLA_ASSERT(plugin); | |||||
if (plugin == nullptr) | |||||
break; | |||||
plugin->setId(i); | |||||
fData->plugins[i].plugin = plugin; | |||||
fData->plugins[i].insPeak[0] = 0.0f; | |||||
fData->plugins[i].insPeak[1] = 0.0f; | |||||
fData->plugins[i].outsPeak[0] = 0.0f; | |||||
fData->plugins[i].outsPeak[1] = 0.0f; | |||||
} | |||||
fData->nextAction.opcode = EnginePostActionNull; | |||||
if (unlock) | |||||
fData->nextAction.mutex.unlock(); | |||||
} | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Static values and calls | // Static values and calls | ||||
@@ -364,12 +400,14 @@ unsigned int CarlaEngine::getDriverCount() | |||||
qDebug("CarlaEngine::getDriverCount()"); | qDebug("CarlaEngine::getDriverCount()"); | ||||
unsigned int count = 0; | unsigned int count = 0; | ||||
#ifdef WANT_JACK | #ifdef WANT_JACK | ||||
count += 1; | count += 1; | ||||
#endif | #endif | ||||
#ifdef WANT_RTAUDIO | #ifdef WANT_RTAUDIO | ||||
count += getRtAudioApiCount(); | count += getRtAudioApiCount(); | ||||
#endif | #endif | ||||
return count; | return count; | ||||
} | } | ||||
@@ -470,9 +508,11 @@ bool CarlaEngine::init(const char* const clientName) | |||||
qDebug("CarlaEngine::init(\"%s\")", clientName); | qDebug("CarlaEngine::init(\"%s\")", clientName); | ||||
CARLA_ASSERT(fData->plugins == nullptr); | CARLA_ASSERT(fData->plugins == nullptr); | ||||
fName = clientName; | |||||
fName.toBasic(); | |||||
fData->aboutToClose = false; | fData->aboutToClose = false; | ||||
fData->curPluginCount = 0; | fData->curPluginCount = 0; | ||||
fData->maxPluginNumber = 0; | |||||
switch (fOptions.processMode) | switch (fOptions.processMode) | ||||
{ | { | ||||
@@ -482,6 +522,9 @@ bool CarlaEngine::init(const char* const clientName) | |||||
case PROCESS_MODE_PATCHBAY: | case PROCESS_MODE_PATCHBAY: | ||||
fData->maxPluginNumber = MAX_PATCHBAY_PLUGINS; | fData->maxPluginNumber = MAX_PATCHBAY_PLUGINS; | ||||
break; | break; | ||||
case PROCESS_MODE_BRIDGE: | |||||
fData->maxPluginNumber = 1; | |||||
break; | |||||
default: | default: | ||||
fData->maxPluginNumber = MAX_DEFAULT_PLUGINS; | fData->maxPluginNumber = MAX_DEFAULT_PLUGINS; | ||||
break; | break; | ||||
@@ -494,7 +537,7 @@ bool CarlaEngine::init(const char* const clientName) | |||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
fData->oscData = fData->osc.getControlData(); | fData->oscData = fData->osc.getControlData(); | ||||
#else | #else | ||||
fData->oscData = nullptr; // set in setOscBridgeData() | |||||
fData->oscData = nullptr; // set later in setOscBridgeData() | |||||
#endif | #endif | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
@@ -502,6 +545,7 @@ bool CarlaEngine::init(const char* const clientName) | |||||
carla_setprocname(clientName); | carla_setprocname(clientName); | ||||
#endif | #endif | ||||
fData->nextAction.ready(); | |||||
fData->thread.startNow(); | fData->thread.startNow(); | ||||
return true; | return true; | ||||
@@ -512,6 +556,7 @@ bool CarlaEngine::close() | |||||
qDebug("CarlaEngine::close()"); | qDebug("CarlaEngine::close()"); | ||||
CARLA_ASSERT(fData->plugins != nullptr); | CARLA_ASSERT(fData->plugins != nullptr); | ||||
fData->nextAction.ready(); | |||||
fData->thread.stopNow(); | fData->thread.stopNow(); | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
@@ -539,16 +584,6 @@ bool CarlaEngine::close() | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Plugin management | // Plugin management | ||||
#if 0 | |||||
int CarlaEngine::getNewPluginId() const | |||||
{ | |||||
qDebug("CarlaEngine::getNewPluginId()"); | |||||
CARLA_ASSERT(data->maxPluginNumber > 0); | |||||
return data->nextPluginId; | |||||
} | |||||
#endif | |||||
CarlaPlugin* CarlaEngine::getPlugin(const unsigned int id) const | CarlaPlugin* CarlaEngine::getPlugin(const unsigned int id) const | ||||
{ | { | ||||
qDebug("CarlaEngine::getPlugin(%i) [count:%i]", id, fData->curPluginCount); | qDebug("CarlaEngine::getPlugin(%i) [count:%i]", id, fData->curPluginCount); | ||||
@@ -556,7 +591,7 @@ CarlaPlugin* CarlaEngine::getPlugin(const unsigned int id) const | |||||
CARLA_ASSERT(id < fData->curPluginCount); | CARLA_ASSERT(id < fData->curPluginCount); | ||||
CARLA_ASSERT(fData->plugins != nullptr); | CARLA_ASSERT(fData->plugins != nullptr); | ||||
if (id < fData->curPluginCount && fData->plugins) | |||||
if (id < fData->curPluginCount && fData->plugins != nullptr) | |||||
return fData->plugins[id].plugin; | return fData->plugins[id].plugin; | ||||
return nullptr; | return nullptr; | ||||
@@ -572,7 +607,7 @@ const char* CarlaEngine::getNewUniquePluginName(const char* const name) | |||||
qDebug("CarlaEngine::getNewUniquePluginName(\"%s\")", name); | qDebug("CarlaEngine::getNewUniquePluginName(\"%s\")", name); | ||||
CARLA_ASSERT(fData->curPluginCount > 0); | CARLA_ASSERT(fData->curPluginCount > 0); | ||||
CARLA_ASSERT(fData->plugins != nullptr); | CARLA_ASSERT(fData->plugins != nullptr); | ||||
CARLA_ASSERT(name); | |||||
CARLA_ASSERT(name != nullptr); | |||||
CarlaString sname(name); | CarlaString sname(name); | ||||
@@ -584,14 +619,14 @@ const char* CarlaEngine::getNewUniquePluginName(const char* const name) | |||||
for (unsigned short i=0; i < fData->curPluginCount; i++) | for (unsigned short i=0; i < fData->curPluginCount; i++) | ||||
{ | { | ||||
#if 0 | |||||
CARLA_ASSERT(fData->plugins[i].plugin); | |||||
// Check if unique name doesn't exist | // Check if unique name doesn't exist | ||||
if (const char* const pluginName = fData->plugins[i].plugin->name()) | if (const char* const pluginName = fData->plugins[i].plugin->name()) | ||||
{ | { | ||||
if (sname != pluginName) | if (sname != pluginName) | ||||
continue; | continue; | ||||
} | } | ||||
#endif | |||||
// Check if string has already been modified | // Check if string has already been modified | ||||
{ | { | ||||
@@ -643,7 +678,7 @@ const char* CarlaEngine::getNewUniquePluginName(const char* const name) | |||||
return strdup(sname); | return strdup(sname); | ||||
} | } | ||||
bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, const char* const filename, const char* const name, const char* const label, void* const extra) | |||||
bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, const char* const filename, const char* const name, const char* const label, const void* const extra) | |||||
{ | { | ||||
qDebug("CarlaEngine::addPlugin(%s, %s, \"%s\", \"%s\", \"%s\", %p)", BinaryType2Str(btype), PluginType2Str(ptype), filename, name, label, extra); | qDebug("CarlaEngine::addPlugin(%s, %s, \"%s\", \"%s\", \"%s\", %p)", BinaryType2Str(btype), PluginType2Str(ptype), filename, name, label, extra); | ||||
CARLA_ASSERT(btype != BINARY_NONE); | CARLA_ASSERT(btype != BINARY_NONE); | ||||
@@ -651,12 +686,19 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, cons | |||||
CARLA_ASSERT(filename); | CARLA_ASSERT(filename); | ||||
CARLA_ASSERT(label); | CARLA_ASSERT(label); | ||||
//CarlaPlugin::Initializer init = { | |||||
// this, | |||||
// filename, | |||||
// name, | |||||
// label | |||||
//}; | |||||
if (fData->curPluginCount == fData->maxPluginNumber) | |||||
{ | |||||
setLastError("Maximum number of plugins reached"); | |||||
return false; | |||||
} | |||||
CarlaPlugin::Initializer init = { | |||||
this, | |||||
fData->curPluginCount, | |||||
filename, | |||||
name, | |||||
label | |||||
}; | |||||
CarlaPlugin* plugin = nullptr; | CarlaPlugin* plugin = nullptr; | ||||
@@ -710,23 +752,24 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, cons | |||||
else | else | ||||
#endif // BUILD_BRIDGE | #endif // BUILD_BRIDGE | ||||
{ | { | ||||
#if 0 | |||||
switch (ptype) | switch (ptype) | ||||
{ | { | ||||
case PLUGIN_NONE: | case PLUGIN_NONE: | ||||
break; | break; | ||||
case PLUGIN_INTERNAL: | |||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
case PLUGIN_INTERNAL: | |||||
plugin = CarlaPlugin::newNative(init); | plugin = CarlaPlugin::newNative(init); | ||||
#endif | |||||
break; | break; | ||||
#endif | |||||
case PLUGIN_LADSPA: | case PLUGIN_LADSPA: | ||||
#ifdef WANT_LADSPA | #ifdef WANT_LADSPA | ||||
plugin = CarlaPlugin::newLADSPA(init, extra); | |||||
plugin = CarlaPlugin::newLADSPA(init, (const LADSPA_RDF_Descriptor*)extra); | |||||
#endif | #endif | ||||
break; | break; | ||||
#if 0 | |||||
case PLUGIN_DSSI: | case PLUGIN_DSSI: | ||||
#ifdef WANT_DSSI | #ifdef WANT_DSSI | ||||
plugin = CarlaPlugin::newDSSI(init, extra); | plugin = CarlaPlugin::newDSSI(init, extra); | ||||
@@ -762,20 +805,20 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, cons | |||||
plugin = CarlaPlugin::newSFZ(init); | plugin = CarlaPlugin::newSFZ(init); | ||||
#endif | #endif | ||||
break; | break; | ||||
} | |||||
#else | |||||
default: | |||||
break; | |||||
#endif | #endif | ||||
} | |||||
} | } | ||||
if (plugin == nullptr) | if (plugin == nullptr) | ||||
return false; | return false; | ||||
//const int id = fData->curPluginCount++; | |||||
fData->curPluginCount++; | |||||
#if 0 | |||||
plugin->setId(id); | |||||
#endif | |||||
callback(CALLBACK_PLUGIN_ADDED, init.id, 0, 0, 0.0f, nullptr); | |||||
//return id; | |||||
return true; | return true; | ||||
} | } | ||||
@@ -788,70 +831,46 @@ bool CarlaEngine::removePlugin(const unsigned int id) | |||||
if (fData->plugins == nullptr) | if (fData->plugins == nullptr) | ||||
{ | { | ||||
// TODO - warning | |||||
setLastError("Critical error: no plugins are currently loaded!"); | |||||
return false; | return false; | ||||
} | } | ||||
CarlaPlugin* plugin = fData->plugins[id].plugin; | |||||
CarlaPlugin* const plugin = fData->plugins[id].plugin; | |||||
CARLA_ASSERT(plugin); | CARLA_ASSERT(plugin); | ||||
if (plugin /*&& plugin->id() == id*/) | |||||
if (plugin) | |||||
{ | { | ||||
#if 0 | |||||
CARLA_ASSERT(plugin->id() == id); | CARLA_ASSERT(plugin->id() == id); | ||||
#endif | |||||
fData->thread.stopNow(); | fData->thread.stopNow(); | ||||
// wait for processing to stop for this plugin | |||||
// TODO | |||||
// clear this plugin | |||||
fData->plugins[id].plugin = nullptr; | |||||
fData->plugins[id].insPeak[0] = 0.0; | |||||
fData->plugins[id].insPeak[1] = 0.0; | |||||
fData->plugins[id].outsPeak[0] = 0.0; | |||||
fData->plugins[id].outsPeak[1] = 0.0; | |||||
// wait for processing to stop for this plugin | |||||
// TODO | |||||
//processLock(); | |||||
//plugin->setEnabled(false); | |||||
//data->carlaPlugins[id] = nullptr; | |||||
//data->uniqueNames[id] = nullptr; | |||||
//processUnlock(); | |||||
delete plugin; | |||||
fData->nextAction.pluginId = id; | |||||
fData->nextAction.opcode = EnginePostActionRemovePlugin; | |||||
#ifndef BUILD_BRIDGE | |||||
osc_send_control_remove_plugin(static_cast<int32_t>(id)); | |||||
fData->nextAction.mutex.lock(); | |||||
// move all plugins 1 spot backwards | |||||
for (unsigned int i=id; i < fData->curPluginCount-1; i++) | |||||
if (isRunning()) | |||||
{ | { | ||||
plugin = fData->plugins[i+1].plugin; | |||||
CARLA_ASSERT(plugin); | |||||
// block wait for unlock on proccessing side | |||||
fData->nextAction.mutex.lock(); | |||||
} | |||||
else | |||||
{ | |||||
doPluginRemove(fData, false); | |||||
} | |||||
#if 0 | |||||
if (plugin) | |||||
plugin->setId(i); | |||||
#ifndef BUILD_BRIDGE | |||||
if (isOscControlRegistered()) | |||||
osc_send_control_remove_plugin(id); | |||||
#endif | #endif | ||||
fData->plugins[i].plugin = plugin; | |||||
fData->plugins[i].insPeak[0] = 0.0; | |||||
fData->plugins[i].insPeak[1] = 0.0; | |||||
fData->plugins[i].outsPeak[0] = 0.0; | |||||
fData->plugins[i].outsPeak[1] = 0.0; | |||||
} | |||||
delete plugin; | |||||
fData->curPluginCount--; | |||||
fData->nextAction.mutex.unlock(); | |||||
if (isRunning() && ! fData->aboutToClose) | if (isRunning() && ! fData->aboutToClose) | ||||
fData->thread.startNow(); | fData->thread.startNow(); | ||||
#endif | |||||
return true; | return true; | ||||
} | } | ||||
@@ -965,7 +984,7 @@ void CarlaEngine::setOutputPeak(const unsigned short pluginId, const unsigned sh | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Callback | // Callback | ||||
void CarlaEngine::callback(const CallbackType action, const unsigned short pluginId, const int value1, const int value2, const double value3, const char* const valueStr) | |||||
void CarlaEngine::callback(const CallbackType action, const unsigned short pluginId, const int value1, const int value2, const float value3, const char* const valueStr) | |||||
{ | { | ||||
qDebug("CarlaEngine::callback(%s, %i, %i, %i, %f, \"%s\")", CallbackType2Str(action), pluginId, value1, value2, value3, valueStr); | qDebug("CarlaEngine::callback(%s, %i, %i, %i, %f, \"%s\")", CallbackType2Str(action), pluginId, value1, value2, value3, valueStr); | ||||
@@ -1297,6 +1316,18 @@ void CarlaEngine::processPatchbay(float** inBuf, float** outBuf, const uint32_t | |||||
} | } | ||||
#endif | #endif | ||||
void CarlaEngine::proccessPendingEvents() | |||||
{ | |||||
switch (fData->nextAction.opcode) | |||||
{ | |||||
case EnginePostActionNull: | |||||
break; | |||||
case EnginePostActionRemovePlugin: | |||||
doPluginRemove(fData, true); | |||||
break; | |||||
} | |||||
} | |||||
void CarlaEngine::bufferSizeChanged(const uint32_t newBufferSize) | void CarlaEngine::bufferSizeChanged(const uint32_t newBufferSize) | ||||
{ | { | ||||
qDebug("CarlaEngine::bufferSizeChanged(%i)", newBufferSize); | qDebug("CarlaEngine::bufferSizeChanged(%i)", newBufferSize); | ||||
@@ -1321,7 +1352,7 @@ void CarlaEngine::sampleRateChanged(const double newSampleRate) | |||||
// Carla Engine OSC stuff | // Carla Engine OSC stuff | ||||
#ifdef BUILD_BRIDGE | #ifdef BUILD_BRIDGE | ||||
void CarlaEngine::osc_send_peaks(CarlaPlugin* const plugin) | |||||
void CarlaEngine::osc_send_peaks(CarlaPlugin* const /*plugin*/) | |||||
#else | #else | ||||
void CarlaEngine::osc_send_peaks(CarlaPlugin* const plugin, const unsigned short& id) | void CarlaEngine::osc_send_peaks(CarlaPlugin* const plugin, const unsigned short& id) | ||||
#endif | #endif | ||||
@@ -98,20 +98,13 @@ const char* EngineControlEventType2Str(const EngineControlEventType type) | |||||
* \note There are both input and output peaks. | * \note There are both input and output peaks. | ||||
*/ | */ | ||||
/*static*/ | /*static*/ | ||||
const unsigned short MAX_PEAKS = 2; | |||||
const unsigned short MAX_PEAKS = 2; | |||||
const uint32_t PATCHBAY_BUFFER_SIZE = 128; | const uint32_t PATCHBAY_BUFFER_SIZE = 128; | ||||
const unsigned short PATCHBAY_EVENT_COUNT = 512; | const unsigned short PATCHBAY_EVENT_COUNT = 512; | ||||
const unsigned short RACK_EVENT_COUNT = 1024; | const unsigned short RACK_EVENT_COUNT = 1024; | ||||
#if 0 | #if 0 | ||||
enum EnginePostEventType { | |||||
EnginePostEventNull, | |||||
EnginePostEventDebug, | |||||
EnginePostEventAddPlugin, // id, ptr | |||||
EnginePostEventRemovePlugin // id | |||||
}; | |||||
struct EnginePostEvent { | struct EnginePostEvent { | ||||
EnginePostEventType type; | EnginePostEventType type; | ||||
int32_t value1; | int32_t value1; | ||||
@@ -124,18 +117,25 @@ struct EnginePostEvent { | |||||
}; | }; | ||||
#endif | #endif | ||||
enum EnginePostAction { | |||||
EnginePostActionNull, | |||||
EnginePostActionRemovePlugin | |||||
}; | |||||
struct EnginePluginData { | struct EnginePluginData { | ||||
CarlaPlugin* plugin; | CarlaPlugin* plugin; | ||||
double insPeak[MAX_PEAKS]; | |||||
double outsPeak[MAX_PEAKS]; | |||||
float insPeak[MAX_PEAKS]; | |||||
float outsPeak[MAX_PEAKS]; | |||||
EnginePluginData() | EnginePluginData() | ||||
: plugin(nullptr), | : plugin(nullptr), | ||||
insPeak{0}, | |||||
outsPeak{0} {} | |||||
insPeak{ 0.0f }, | |||||
outsPeak{ 0.0f } {} | |||||
}; | }; | ||||
struct CarlaEngineProtectedData { | |||||
// ------------------------------------------------------------------------------------------------------------------- | |||||
struct CarlaEnginePrivateData { | |||||
CarlaEngineOsc osc; | CarlaEngineOsc osc; | ||||
CarlaEngineThread thread; | CarlaEngineThread thread; | ||||
@@ -154,9 +154,25 @@ struct CarlaEngineProtectedData { | |||||
unsigned int curPluginCount; // number of plugins loaded (0...max) | unsigned int curPluginCount; // number of plugins loaded (0...max) | ||||
unsigned int maxPluginNumber; // number of plugins allowed (0, 16, 99 or 999) | unsigned int maxPluginNumber; // number of plugins allowed (0, 16, 99 or 999) | ||||
struct NextAction { | |||||
EnginePostAction opcode; | |||||
unsigned int pluginId; | |||||
CarlaMutex mutex; | |||||
NextAction() | |||||
: opcode(EnginePostActionNull), | |||||
pluginId(0) {} | |||||
void ready() | |||||
{ | |||||
mutex.lock(); | |||||
mutex.unlock(); | |||||
} | |||||
} nextAction; | |||||
EnginePluginData* plugins; | EnginePluginData* plugins; | ||||
CarlaEngineProtectedData(CarlaEngine* const engine) | |||||
CarlaEnginePrivateData(CarlaEngine* const engine) | |||||
: osc(engine), | : osc(engine), | ||||
thread(engine), | thread(engine), | ||||
oscData(nullptr), | oscData(nullptr), | ||||
@@ -167,9 +183,9 @@ struct CarlaEngineProtectedData { | |||||
maxPluginNumber(0), | maxPluginNumber(0), | ||||
plugins(nullptr) {} | plugins(nullptr) {} | ||||
CarlaEngineProtectedData() = delete; | |||||
CarlaEnginePrivateData() = delete; | |||||
CARLA_LEAK_DETECTOR(CarlaEngineProtectedData) | |||||
CARLA_LEAK_DETECTOR(CarlaEnginePrivateData) | |||||
}; | }; | ||||
CARLA_BACKEND_END_NAMESPACE | CARLA_BACKEND_END_NAMESPACE | ||||
@@ -528,7 +528,7 @@ int CarlaEngineOsc::handleMsgExiting(CARLA_ENGINE_OSC_HANDLE_ARGS1) | |||||
qDebug("CarlaEngineOsc::handleMsgExiting()"); | qDebug("CarlaEngineOsc::handleMsgExiting()"); | ||||
// TODO - check for non-UIs (dssi-vst) and set to -1 instead | // TODO - check for non-UIs (dssi-vst) and set to -1 instead | ||||
kEngine->callback(CALLBACK_SHOW_GUI, plugin->id(), 0, 0, 0.0, nullptr); | |||||
kEngine->callback(CALLBACK_SHOW_GUI, plugin->id(), 0, 0, 0.0f, nullptr); | |||||
plugin->freeOscData(); | plugin->freeOscData(); | ||||
@@ -1,18 +1,18 @@ | |||||
/* | /* | ||||
* Carla Engine Thread | * Carla Engine Thread | ||||
* Copyright (C) 2012 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or modify | |||||
* it under the terms of the GNU General Public License as published by | |||||
* the Free Software Foundation; either version 2 of the License, or | |||||
* any later version. | |||||
* 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 the Free Software Foundation; either version 2 of | |||||
* the License, or any later version. | |||||
* | * | ||||
* This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | * GNU General Public License for more details. | ||||
* | * | ||||
* For a full copy of the GNU General Public License see the COPYING file | |||||
* For a full copy of the GNU General Public License see the GPL.txt file | |||||
*/ | */ | ||||
#include "carla_engine.hpp" | #include "carla_engine.hpp" | ||||
@@ -1,18 +1,18 @@ | |||||
/* | /* | ||||
* Carla JACK Engine | * Carla JACK Engine | ||||
* Copyright (C) 2011-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 | |||||
* the Free Software Foundation; either version 2 of the License, or | |||||
* any later version. | |||||
* 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 the Free Software Foundation; either version 2 of | |||||
* the License, or any later version. | |||||
* | * | ||||
* This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | * GNU General Public License for more details. | ||||
* | * | ||||
* For a full copy of the GNU General Public License see the COPYING file | |||||
* For a full copy of the GNU General Public License see the GPL.txt file | |||||
*/ | */ | ||||
#ifdef WANT_JACK | #ifdef WANT_JACK | ||||
@@ -499,7 +499,7 @@ public: | |||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (fOptions.processMode == PROCESS_MODE_SINGLE_CLIENT || fOptions.processMode == PROCESS_MODE_MULTIPLE_CLIENTS) | if (fOptions.processMode == PROCESS_MODE_SINGLE_CLIENT || fOptions.processMode == PROCESS_MODE_MULTIPLE_CLIENTS) | ||||
#endif | #endif | ||||
return (unsigned int)jackbridge_client_name_size() - 3; // reserve space for "_2" forced-stereo ports | |||||
return static_cast<unsigned int>(jackbridge_client_name_size()); | |||||
return CarlaEngine::maxClientNameSize(); | return CarlaEngine::maxClientNameSize(); | ||||
} | } | ||||
@@ -509,7 +509,7 @@ public: | |||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
if (fOptions.processMode == PROCESS_MODE_SINGLE_CLIENT || fOptions.processMode == PROCESS_MODE_MULTIPLE_CLIENTS) | if (fOptions.processMode == PROCESS_MODE_SINGLE_CLIENT || fOptions.processMode == PROCESS_MODE_MULTIPLE_CLIENTS) | ||||
#endif | #endif | ||||
return (unsigned int)jackbridge_port_name_size(); | |||||
return static_cast<unsigned int>(jackbridge_port_name_size()); | |||||
return CarlaEngine::maxPortNameSize(); | return CarlaEngine::maxPortNameSize(); | ||||
} | } | ||||
@@ -970,7 +970,7 @@ protected: | |||||
} | } | ||||
m_client = nullptr; | m_client = nullptr; | ||||
callback(CALLBACK_QUIT, 0, 0, 0, 0.0, nullptr); | |||||
callback(CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr); | |||||
} | } | ||||
// ------------------------------------- | // ------------------------------------- | ||||
@@ -22,15 +22,14 @@ | |||||
#include "carla_plugin_thread.hpp" | #include "carla_plugin_thread.hpp" | ||||
#include "carla_engine.hpp" | #include "carla_engine.hpp" | ||||
#include "carla_osc_utils.hpp" | |||||
#ifdef BUILD_BRIDGE | |||||
# include "carla_bridge_osc.hpp" | |||||
#else | |||||
# include "carla_osc_utils.hpp" | |||||
#endif | |||||
//#include "carla_bridge_osc.hpp" | |||||
#include "rt_list.hpp" | #include "rt_list.hpp" | ||||
#include <QtGui/QMainWindow> | |||||
#define CARLA_DECLARE_NON_COPY_STRUCT(structName) \ | #define CARLA_DECLARE_NON_COPY_STRUCT(structName) \ | ||||
structName(const structName&) = delete; | structName(const structName&) = delete; | ||||
@@ -81,15 +80,38 @@ struct PluginAudioData { | |||||
ports = new PluginAudioPort[count]; | ports = new PluginAudioPort[count]; | ||||
} | } | ||||
void free() | |||||
void freePorts() | |||||
{ | |||||
for (uint32_t i=0; i < count; i++) | |||||
{ | |||||
if (ports[i].port != nullptr) | |||||
{ | |||||
delete ports[i].port; | |||||
ports[i].port = nullptr; | |||||
} | |||||
} | |||||
} | |||||
void clear() | |||||
{ | { | ||||
CARLA_ASSERT(ports != nullptr); | |||||
freePorts(); | |||||
if (ports != nullptr) | if (ports != nullptr) | ||||
{ | { | ||||
delete[] ports; | delete[] ports; | ||||
ports = nullptr; | ports = nullptr; | ||||
} | } | ||||
count = 0; | |||||
} | |||||
void initBuffers(CarlaEngine* const engine) | |||||
{ | |||||
for (uint32_t i=0; i < count; i++) | |||||
{ | |||||
if (ports[i].port != nullptr) | |||||
ports[i].port->initBuffer(engine); | |||||
} | |||||
} | } | ||||
CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginAudioData) | CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginAudioData) | ||||
@@ -111,6 +133,35 @@ struct PluginEventData { | |||||
CARLA_ASSERT(portOut == nullptr); | CARLA_ASSERT(portOut == nullptr); | ||||
} | } | ||||
void freePorts() | |||||
{ | |||||
if (portIn != nullptr) | |||||
{ | |||||
delete portIn; | |||||
portIn = nullptr; | |||||
} | |||||
if (portOut != nullptr) | |||||
{ | |||||
delete portOut; | |||||
portOut = nullptr; | |||||
} | |||||
} | |||||
void clear() | |||||
{ | |||||
freePorts(); | |||||
} | |||||
void initBuffers(CarlaEngine* const engine) | |||||
{ | |||||
if (portIn != nullptr) | |||||
portIn->initBuffer(engine); | |||||
if (portOut != nullptr) | |||||
portOut->initBuffer(engine); | |||||
} | |||||
CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginEventData) | CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginEventData) | ||||
}; | }; | ||||
@@ -144,11 +195,8 @@ struct PluginParameterData { | |||||
ranges = new ParameterRanges[count]; | ranges = new ParameterRanges[count]; | ||||
} | } | ||||
void free() | |||||
void clear() | |||||
{ | { | ||||
CARLA_ASSERT(data != nullptr); | |||||
CARLA_ASSERT(ranges != nullptr); | |||||
if (data != nullptr) | if (data != nullptr) | ||||
{ | { | ||||
delete[] data; | delete[] data; | ||||
@@ -160,6 +208,8 @@ struct PluginParameterData { | |||||
delete[] ranges; | delete[] ranges; | ||||
ranges = nullptr; | ranges = nullptr; | ||||
} | } | ||||
count = 0; | |||||
} | } | ||||
CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginParameterData) | CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginParameterData) | ||||
@@ -184,28 +234,39 @@ struct PluginProgramData { | |||||
CARLA_ASSERT(names == nullptr); | CARLA_ASSERT(names == nullptr); | ||||
} | } | ||||
void createNew(const size_t count) | |||||
void createNew(const uint32_t count) | |||||
{ | { | ||||
CARLA_ASSERT(names == nullptr); | CARLA_ASSERT(names == nullptr); | ||||
if (names == nullptr) | if (names == nullptr) | ||||
names = new ProgramName[count]; | names = new ProgramName[count]; | ||||
for (uint32_t i=0; i < count; i++) | |||||
names[i] = nullptr; | |||||
this->count = count; | |||||
} | } | ||||
void free() | |||||
void clear() | |||||
{ | { | ||||
CARLA_ASSERT(names != nullptr); | |||||
if (names != nullptr) | if (names != nullptr) | ||||
{ | { | ||||
for (uint32_t i=0; i < count; i++) | |||||
std::free((void*)names[i]); | |||||
delete[] names; | delete[] names; | ||||
names = nullptr; | names = nullptr; | ||||
} | } | ||||
count = 0; | |||||
current = -1; | |||||
} | } | ||||
CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginProgramData) | CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginProgramData) | ||||
}; | }; | ||||
// ----------------------------------------------------------------------- | |||||
struct PluginMidiProgramData { | struct PluginMidiProgramData { | ||||
uint32_t count; | uint32_t count; | ||||
int32_t current; | int32_t current; | ||||
@@ -221,27 +282,31 @@ struct PluginMidiProgramData { | |||||
CARLA_ASSERT(data == nullptr); | CARLA_ASSERT(data == nullptr); | ||||
} | } | ||||
void createNew(const size_t count) | |||||
void createNew(const uint32_t count) | |||||
{ | { | ||||
CARLA_ASSERT(data == nullptr); | CARLA_ASSERT(data == nullptr); | ||||
if (data == nullptr) | if (data == nullptr) | ||||
data = new MidiProgramData[count]; | data = new MidiProgramData[count]; | ||||
this->count = count; | |||||
} | } | ||||
void free() | |||||
void clear() | |||||
{ | { | ||||
CARLA_ASSERT(data != nullptr); | |||||
if (data != nullptr) | if (data != nullptr) | ||||
{ | { | ||||
delete[] data; | delete[] data; | ||||
data = nullptr; | data = nullptr; | ||||
} | } | ||||
count = 0; | |||||
current = -1; | |||||
} | } | ||||
const MidiProgramData& getCurrent() | |||||
const MidiProgramData& getCurrent() const | |||||
{ | { | ||||
CARLA_ASSERT(current >= 0 && current < static_cast<int32_t>(count)); | |||||
return data[current]; | return data[current]; | ||||
} | } | ||||
@@ -282,14 +347,33 @@ struct ExternalMidiNote { | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
class CarlaPluginGUI : public QMainWindow | |||||
{ | |||||
public: | |||||
CarlaPluginGUI(QWidget* const parent = nullptr); | |||||
~CarlaPluginGUI(); | |||||
private: | |||||
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginGUI) | |||||
}; | |||||
// ----------------------------------------------------------------------- | |||||
const unsigned short MIN_RT_EVENTS = 152; | |||||
const unsigned short MAX_RT_EVENTS = 512; | |||||
const unsigned int PLUGIN_OPTION2_HAS_MIDI_IN = 0x1; | const unsigned int PLUGIN_OPTION2_HAS_MIDI_IN = 0x1; | ||||
const unsigned int PLUGIN_OPTION2_HAS_MIDI_OUT = 0x2; | const unsigned int PLUGIN_OPTION2_HAS_MIDI_OUT = 0x2; | ||||
// ----------------------------------------------------------------------- | |||||
struct CarlaPluginProtectedData { | struct CarlaPluginProtectedData { | ||||
int id; | |||||
unsigned int id; | |||||
CarlaEngine* const engine; | CarlaEngine* const engine; | ||||
CarlaEngineClient* client; | CarlaEngineClient* client; | ||||
CarlaPluginGUI* gui; | |||||
unsigned int hints; | unsigned int hints; | ||||
unsigned int options; | unsigned int options; | ||||
@@ -300,13 +384,16 @@ struct CarlaPluginProtectedData { | |||||
bool enabled; | bool enabled; | ||||
void* lib; | void* lib; | ||||
const char* name; | |||||
const char* filename; | |||||
CarlaString name; | |||||
CarlaString filename; | |||||
// misc | // misc | ||||
int8_t ctrlInChannel; | |||||
int8_t ctrlInChannel; | |||||
#if 0 | |||||
uint32_t latency; | uint32_t latency; | ||||
float** latencyBuffers; | float** latencyBuffers; | ||||
#endif | |||||
// data | // data | ||||
PluginAudioData audioIn; | PluginAudioData audioIn; | ||||
@@ -315,7 +402,7 @@ struct CarlaPluginProtectedData { | |||||
PluginParameterData param; | PluginParameterData param; | ||||
PluginProgramData prog; | PluginProgramData prog; | ||||
PluginMidiProgramData midiprog; | PluginMidiProgramData midiprog; | ||||
NonRtList<CustomData> custom; | |||||
NonRtListNew<CustomData> custom; | |||||
struct ExternalNotes { | struct ExternalNotes { | ||||
CarlaMutex mutex; | CarlaMutex mutex; | ||||
@@ -323,6 +410,12 @@ struct CarlaPluginProtectedData { | |||||
ExternalNotes() | ExternalNotes() | ||||
: data(32, 512) {} | : data(32, 512) {} | ||||
void append(const ExternalMidiNote& note) | |||||
{ | |||||
data.append_sleepy(note); | |||||
} | |||||
} extNotes; | } extNotes; | ||||
struct PostRtEvents { | struct PostRtEvents { | ||||
@@ -331,8 +424,8 @@ struct CarlaPluginProtectedData { | |||||
RtList<PluginPostRtEvent> dataPendingRT; | RtList<PluginPostRtEvent> dataPendingRT; | ||||
PostRtEvents() | PostRtEvents() | ||||
: data(152, 512), | |||||
dataPendingRT(152, 256) {} | |||||
: data(MIN_RT_EVENTS, MAX_RT_EVENTS), | |||||
dataPendingRT(MIN_RT_EVENTS, MAX_RT_EVENTS) {} | |||||
void appendRT(const PluginPostRtEvent& event) | void appendRT(const PluginPostRtEvent& event) | ||||
{ | { | ||||
@@ -345,21 +438,26 @@ struct CarlaPluginProtectedData { | |||||
} | } | ||||
} | } | ||||
//void appendNonRT(const PluginPostRtEvent& event) | |||||
//{ | |||||
// data.append_sleepy(event); | |||||
//} | |||||
} postRtEvents; | } postRtEvents; | ||||
struct PostProc { | struct PostProc { | ||||
double dryWet; | |||||
double volume; | |||||
double balanceLeft; | |||||
double balanceRight; | |||||
double panning; | |||||
float dryWet; | |||||
float volume; | |||||
float balanceLeft; | |||||
float balanceRight; | |||||
float panning; | |||||
PostProc() | PostProc() | ||||
: dryWet(1.0), | |||||
volume(1.0), | |||||
balanceLeft(-1.0), | |||||
balanceRight(1.0), | |||||
panning(0.0) {} | |||||
: dryWet(1.0f), | |||||
volume(1.0f), | |||||
balanceLeft(-1.0f), | |||||
balanceRight(1.0f), | |||||
panning(0.0f) {} | |||||
} postProc; | } postProc; | ||||
struct OSC { | struct OSC { | ||||
@@ -374,6 +472,7 @@ struct CarlaPluginProtectedData { | |||||
: id(id_), | : id(id_), | ||||
engine(engine_), | engine(engine_), | ||||
client(nullptr), | client(nullptr), | ||||
gui(nullptr), | |||||
hints(0x0), | hints(0x0), | ||||
options(0x0), | options(0x0), | ||||
options2(0x0), | options2(0x0), | ||||
@@ -381,11 +480,11 @@ struct CarlaPluginProtectedData { | |||||
activeBefore(false), | activeBefore(false), | ||||
enabled(false), | enabled(false), | ||||
lib(nullptr), | lib(nullptr), | ||||
name(nullptr), | |||||
filename(nullptr), | |||||
ctrlInChannel(-1), | |||||
ctrlInChannel(-1) {} | |||||
#if 0 | |||||
latency(0), | latency(0), | ||||
latencyBuffers(nullptr) {} | latencyBuffers(nullptr) {} | ||||
#endif | |||||
CarlaPluginProtectedData() = delete; | CarlaPluginProtectedData() = delete; | ||||
@@ -59,7 +59,7 @@ public: | |||||
// --------------------------------------------------------------------- | // --------------------------------------------------------------------- | ||||
// processing | // processing | ||||
virtual void setParameter(const int32_t rindex, const double value) = 0; | |||||
virtual void setParameter(const int32_t rindex, const float value) = 0; | |||||
virtual void setProgram(const uint32_t index) = 0; | virtual void setProgram(const uint32_t index) = 0; | ||||
#ifdef BUILD_BRIDGE_PLUGIN | #ifdef BUILD_BRIDGE_PLUGIN | ||||
virtual void setMidiProgram(const uint32_t index) = 0; | virtual void setMidiProgram(const uint32_t index) = 0; | ||||
@@ -628,7 +628,7 @@ public: | |||||
// --------------------------------------------------------------------- | // --------------------------------------------------------------------- | ||||
// processing | // processing | ||||
void setParameter(const int32_t rindex, const double value) | |||||
void setParameter(const int32_t rindex, const float value) | |||||
{ | { | ||||
qDebug("CarlaPluginClient::setParameter(%i, %g)", rindex, value); | qDebug("CarlaPluginClient::setParameter(%i, %g)", rindex, value); | ||||
CARLA_ASSERT(plugin); | CARLA_ASSERT(plugin); | ||||
@@ -799,7 +799,7 @@ public: | |||||
// --------------------------------------------------------------------- | // --------------------------------------------------------------------- | ||||
// callback | // callback | ||||
static void callback(void* const ptr, CarlaBackend::CallbackType const action, const unsigned int, const int value1, const int value2, const double value3, const char* const valueStr) | |||||
static void callback(void* ptr, CarlaBackend::CallbackType action, unsigned int, int value1, int value2, float value3, const char* valueStr) | |||||
{ | { | ||||
CARLA_ASSERT(ptr); | CARLA_ASSERT(ptr); | ||||
@@ -34,9 +34,10 @@ SOURCES += \ | |||||
# carla-plugin | # carla-plugin | ||||
SOURCES += \ | SOURCES += \ | ||||
../../backend/plugin/carla_plugin.cpp | |||||
../../backend/plugin/carla_plugin.cpp \ | |||||
../../backend/plugin/ladspa.cpp | |||||
# ../../backend/plugin/carla_plugin_thread.cpp \ | # ../../backend/plugin/carla_plugin_thread.cpp \ | ||||
# ../../backend/plugin/ladspa.cpp \ | |||||
# ../../backend/plugin/dssi.cpp \ | # ../../backend/plugin/dssi.cpp \ | ||||
# ../../backend/plugin/lv2.cpp \ | # ../../backend/plugin/lv2.cpp \ | ||||
# ../../backend/plugin/vst.cpp | # ../../backend/plugin/vst.cpp | ||||
@@ -141,6 +141,17 @@ const T& carla_min(const T& v1, const T& v2, const T& min) | |||||
return ((v1 < min || v2 < min) ? min : (v1 < v2 ? v1 : v2)); | return ((v1 < min || v2 < min) ? min : (v1 < v2 ? v1 : v2)); | ||||
} | } | ||||
template<typename T> | |||||
static inline | |||||
const T& carla_fixValue(const T& min, const T& max, const T& value) | |||||
{ | |||||
if (value < min) | |||||
return min; | |||||
if (value > max) | |||||
return max; | |||||
return value; | |||||
} | |||||
template<typename T> | template<typename T> | ||||
static inline | static inline | ||||
void carla_fill(T* data, const unsigned int size, const T v) | void carla_fill(T* data, const unsigned int size, const T v) | ||||
@@ -29,9 +29,11 @@ extern "C" { | |||||
// Declare non copyable and prevent heap allocation | // Declare non copyable and prevent heap allocation | ||||
#define LIST_DECLARATIONS(className) \ | #define LIST_DECLARATIONS(className) \ | ||||
className(const className&); \ | className(const className&); \ | ||||
className& operator= (const className&); \ | |||||
static void* operator new (size_t); \ | |||||
static void operator delete (void*); \ | |||||
className& operator= (const className&); | |||||
// FIXME | |||||
//static void* operator new (size_t); | |||||
//static void operator delete (void*); | |||||
typedef struct list_head k_list_head; | typedef struct list_head k_list_head; | ||||
@@ -303,7 +305,7 @@ private: | |||||
rtsafe_memory_pool_deallocate(fMemPool, dataPtr); | rtsafe_memory_pool_deallocate(fMemPool, dataPtr); | ||||
} | } | ||||
//LIST_DECLARATIONS(RtList) | |||||
LIST_DECLARATIONS(RtList) | |||||
}; | }; | ||||
template<typename T> | template<typename T> | ||||
@@ -329,7 +331,7 @@ private: | |||||
free(dataPtr); | free(dataPtr); | ||||
} | } | ||||
//LIST_DECLARATIONS(NonRtList) | |||||
LIST_DECLARATIONS(NonRtList) | |||||
}; | }; | ||||
template<typename T> | template<typename T> | ||||
@@ -355,7 +357,7 @@ private: | |||||
delete dataPtr; | delete dataPtr; | ||||
} | } | ||||
//LIST_DECLARATIONS(NonRtListNew) | |||||
LIST_DECLARATIONS(NonRtListNew) | |||||
}; | }; | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||