@@ -314,8 +314,7 @@ void CarlaEngine::removeAllPlugins() | |||
{ | |||
qDebug("CarlaEngine::removeAllPlugins()"); | |||
if (m_checkThread.isRunning()) | |||
m_checkThread.stopNow(); | |||
const CarlaCheckThread::ScopedLocker m(&m_checkThread); | |||
for (unsigned short i=0; i < MAX_PLUGINS; i++) | |||
{ | |||
@@ -333,9 +332,6 @@ void CarlaEngine::removeAllPlugins() | |||
m_uniqueNames[i] = nullptr; | |||
} | |||
} | |||
if (isRunning()) | |||
m_checkThread.start(QThread::HighPriority); | |||
} | |||
void CarlaEngine::idlePluginGuis() | |||
@@ -391,6 +391,42 @@ public: | |||
// ------------------------------------- | |||
/*! | |||
* \class CarlaEngineScopedLocker | |||
* | |||
* \brief Carla engine scoped locker | |||
* | |||
* This is a handy class that temporarily locks an engine during a function scope. | |||
*/ | |||
class ScopedLocker | |||
{ | |||
public: | |||
/*! | |||
* Lock the engine \a engine if \a lock is true. | |||
* The engine is unlocked in the deconstructor of this class if \a lock is true. | |||
* | |||
* \param engine The engine to lock | |||
* \param lock Wherever to lock the engine or not, true by default | |||
*/ | |||
ScopedLocker(CarlaEngine* const engine, bool lock = true) : | |||
m_engine(engine), | |||
m_lock(lock) | |||
{ | |||
if (m_lock) | |||
m_engine->processLock(); | |||
} | |||
~ScopedLocker() | |||
{ | |||
if (m_lock) | |||
m_engine->processUnlock(); | |||
} | |||
private: | |||
CarlaEngine* const m_engine; | |||
const bool m_lock; | |||
}; | |||
protected: | |||
CarlaEngineType type; | |||
const char* name; | |||
@@ -420,42 +456,6 @@ private: | |||
double m_outsPeak[MAX_PLUGINS * MAX_PEAKS]; | |||
}; | |||
/*! | |||
* \class CarlaEngineScopedLocker | |||
* | |||
* \brief Carla engine scoped locker | |||
* | |||
* This is a handy class that temporarily locks an engine during a function scope. | |||
*/ | |||
class CarlaEngineScopedLocker | |||
{ | |||
public: | |||
/*! | |||
* Lock the engine \a engine if \a lock is true. | |||
* The engine is unlocked in the deconstructor of this class if \a lock is true. | |||
* | |||
* \param engine The engine to lock | |||
* \param lock Wherever to lock the engine or not, true by default | |||
*/ | |||
CarlaEngineScopedLocker(CarlaEngine* const engine, bool lock = true) : | |||
m_engine(engine), | |||
m_lock(lock) | |||
{ | |||
if (m_lock) | |||
m_engine->processLock(); | |||
} | |||
~CarlaEngineScopedLocker() | |||
{ | |||
if (m_lock) | |||
m_engine->processUnlock(); | |||
} | |||
private: | |||
CarlaEngine* const m_engine; | |||
const bool m_lock; | |||
}; | |||
// ----------------------------------------------------------------------- | |||
class CarlaEngineClient | |||
@@ -2033,6 +2033,57 @@ public: | |||
// ------------------------------------------------------------------- | |||
/*! | |||
* \class CarlaPluginScopedDisabler | |||
* | |||
* \brief Carla plugin scoped disabler | |||
* | |||
* This is a handy class that temporarily disables a plugin during a function scope.\n | |||
* It should be used when the plugin needs reload or state change, something like this: | |||
* \code | |||
* { | |||
* const CarlaPluginScopedDisabler m(plugin); | |||
* plugin->setChunkData(data); | |||
* } | |||
* \endcode | |||
*/ | |||
class ScopedDisabler | |||
{ | |||
public: | |||
/*! | |||
* Disable plugin \a plugin if \a disable is true. | |||
* The plugin is re-enabled in the deconstructor of this class if \a disable is true. | |||
* | |||
* \param plugin The plugin to disable | |||
* \param disable Wherever to disable the plugin or not, true by default | |||
*/ | |||
ScopedDisabler(CarlaPlugin* const plugin, bool disable = true) : | |||
m_plugin(plugin), | |||
m_disable(disable) | |||
{ | |||
if (m_disable) | |||
{ | |||
m_plugin->engineProcessLock(); | |||
m_plugin->setEnabled(false); | |||
m_plugin->engineProcessUnlock(); | |||
} | |||
} | |||
~ScopedDisabler() | |||
{ | |||
if (m_disable) | |||
{ | |||
m_plugin->engineProcessLock(); | |||
m_plugin->setEnabled(true); | |||
m_plugin->engineProcessUnlock(); | |||
} | |||
} | |||
private: | |||
CarlaPlugin* const m_plugin; | |||
const bool m_disable; | |||
}; | |||
protected: | |||
unsigned short m_id; | |||
CarlaEngine* const x_engine; | |||
@@ -2108,57 +2159,6 @@ protected: | |||
} | |||
}; | |||
/*! | |||
* \class CarlaPluginScopedDisabler | |||
* | |||
* \brief Carla plugin scoped disabler | |||
* | |||
* This is a handy class that temporarily disables a plugin during a function scope.\n | |||
* It should be used when the plugin needs reload or state change, something like this: | |||
* \code | |||
* { | |||
* const CarlaPluginScopedDisabler m(plugin); | |||
* plugin->setChunkData(data); | |||
* } | |||
* \endcode | |||
*/ | |||
class CarlaPluginScopedDisabler | |||
{ | |||
public: | |||
/*! | |||
* Disable plugin \a plugin if \a disable is true. | |||
* The plugin is re-enabled in the deconstructor of this class if \a disable is true. | |||
* | |||
* \param plugin The plugin to disable | |||
* \param disable Wherever to disable the plugin or not, true by default | |||
*/ | |||
CarlaPluginScopedDisabler(CarlaPlugin* const plugin, bool disable = true) : | |||
m_plugin(plugin), | |||
m_disable(disable) | |||
{ | |||
if (m_disable) | |||
{ | |||
m_plugin->engineProcessLock(); | |||
m_plugin->setEnabled(false); | |||
m_plugin->engineProcessUnlock(); | |||
} | |||
} | |||
~CarlaPluginScopedDisabler() | |||
{ | |||
if (m_disable) | |||
{ | |||
m_plugin->engineProcessLock(); | |||
m_plugin->setEnabled(true); | |||
m_plugin->engineProcessUnlock(); | |||
} | |||
} | |||
private: | |||
CarlaPlugin* const m_plugin; | |||
const bool m_disable; | |||
}; | |||
/**@}*/ | |||
CARLA_BACKEND_END_NAMESPACE | |||
@@ -64,7 +64,7 @@ void CarlaCheckThread::run() | |||
while (engine->isRunning() && ! m_stopNow) | |||
{ | |||
QMutexLocker(&this->mutex); // FIXME | |||
const ScopedLocker m(this); | |||
oscControllerRegisted = engine->isOscControllerRegisted(); | |||
for (unsigned short i=0; i < CarlaBackend::MAX_PLUGINS; i++) | |||
@@ -23,8 +23,6 @@ | |||
#include <QtCore/QMutex> | |||
#include <QtCore/QThread> | |||
class QProcess; | |||
// -------------------------------------------------------------------------------------------------------- | |||
// CarlaCheckThread | |||
@@ -36,15 +34,23 @@ public: | |||
void stopNow(); | |||
void lock() | |||
{ | |||
mutex.lock(); | |||
} | |||
void unlock() | |||
class ScopedLocker | |||
{ | |||
mutex.unlock(); | |||
} | |||
public: | |||
ScopedLocker(CarlaCheckThread* const thread) | |||
: m_thread(thread) | |||
{ | |||
m_thread->mutex.lock(); | |||
} | |||
~ScopedLocker() | |||
{ | |||
m_thread->mutex.unlock(); | |||
} | |||
private: | |||
CarlaCheckThread* const m_thread; | |||
}; | |||
protected: | |||
void run(); | |||
@@ -58,6 +64,8 @@ private: | |||
// -------------------------------------------------------------------------------------------------------- | |||
// CarlaPluginThread | |||
class QProcess; | |||
class CarlaPluginThread : public QThread | |||
{ | |||
public: | |||
@@ -226,7 +226,7 @@ public: | |||
if (strcmp(key, "reloadprograms") == 0 || strcmp(key, "load") == 0 || strncmp(key, "patches", 7) == 0) | |||
{ | |||
const CarlaPluginScopedDisabler m(this); | |||
const ScopedDisabler m(this); | |||
reloadPrograms(false); | |||
} | |||
@@ -242,13 +242,12 @@ public: | |||
if (x_engine->isOffline()) | |||
{ | |||
engineProcessLock(); | |||
const CarlaEngine::ScopedLocker m(x_engine); | |||
descriptor->set_custom_data(handle, chunk.data(), chunk.size()); | |||
engineProcessUnlock(); | |||
} | |||
else | |||
{ | |||
const CarlaPluginScopedDisabler m(this); | |||
const ScopedDisabler m(this); | |||
descriptor->set_custom_data(handle, chunk.data(), chunk.size()); | |||
} | |||
} | |||
@@ -261,13 +260,12 @@ public: | |||
{ | |||
if (x_engine->isOffline()) | |||
{ | |||
if (block) engineProcessLock(); | |||
const CarlaEngine::ScopedLocker m(x_engine, block); | |||
descriptor->select_program(handle, midiprog.data[index].bank, midiprog.data[index].program); | |||
if (block) engineProcessUnlock(); | |||
} | |||
else | |||
{ | |||
const CarlaPluginScopedDisabler m(this, block); | |||
const ScopedDisabler m(this, block); | |||
descriptor->select_program(handle, midiprog.data[index].bank, midiprog.data[index].program); | |||
} | |||
@@ -316,7 +314,7 @@ public: | |||
qDebug("DssiPlugin::reload() - start"); | |||
// Safely disable plugin for reload | |||
const CarlaPluginScopedDisabler m(this); | |||
const ScopedDisabler m(this); | |||
if (x_client->isActive()) | |||
x_client->deactivate(); | |||
@@ -316,7 +316,7 @@ public: | |||
case FluidSynthChorusOnOff: | |||
{ | |||
const CarlaPluginScopedDisabler m(this, ! x_engine->isOffline()); | |||
const ScopedDisabler m(this, ! x_engine->isOffline()); | |||
value = value > 0.5 ? 1 : 0; | |||
fluid_synth_set_chorus_on(f_synth, value); | |||
break; | |||
@@ -328,21 +328,21 @@ public: | |||
case FluidSynthChorusDepthMs: | |||
case FluidSynthChorusType: | |||
{ | |||
const CarlaPluginScopedDisabler m(this, ! x_engine->isOffline()); | |||
const ScopedDisabler m(this, ! x_engine->isOffline()); | |||
fluid_synth_set_chorus(f_synth, rint(param_buffers[FluidSynthChorusNr]), param_buffers[FluidSynthChorusLevel], param_buffers[FluidSynthChorusSpeedHz], param_buffers[FluidSynthChorusDepthMs], rint(param_buffers[FluidSynthChorusType])); | |||
break; | |||
} | |||
case FluidSynthPolyphony: | |||
{ | |||
const CarlaPluginScopedDisabler m(this, ! x_engine->isOffline()); | |||
const ScopedDisabler m(this, ! x_engine->isOffline()); | |||
fluid_synth_set_polyphony(f_synth, rint(value)); | |||
break; | |||
} | |||
case FluidSynthInterpolation: | |||
{ | |||
const CarlaPluginScopedDisabler m(this, ! x_engine->isOffline()); | |||
const ScopedDisabler m(this, ! x_engine->isOffline()); | |||
for (int i=0; i < 16; i++) | |||
fluid_synth_set_interp_method(f_synth, i, rint(value)); | |||
break; | |||
@@ -366,13 +366,12 @@ public: | |||
{ | |||
if (x_engine->isOffline()) | |||
{ | |||
if (block) engineProcessLock(); | |||
const CarlaEngine::ScopedLocker m(x_engine, block); | |||
fluid_synth_program_select(f_synth, cin_channel, f_id, midiprog.data[index].bank, midiprog.data[index].program); | |||
if (block) engineProcessUnlock(); | |||
} | |||
else | |||
{ | |||
const CarlaPluginScopedDisabler m(this, block); | |||
const ScopedDisabler m(this, block); | |||
fluid_synth_program_select(f_synth, cin_channel, f_id, midiprog.data[index].bank, midiprog.data[index].program); | |||
} | |||
} | |||
@@ -388,7 +387,7 @@ public: | |||
qDebug("FluidSynthPlugin::reload() - start"); | |||
// Safely disable plugin for reload | |||
const CarlaPluginScopedDisabler m(this); | |||
const ScopedDisabler m(this); | |||
if (x_client->isActive()) | |||
x_client->deactivate(); | |||
@@ -300,7 +300,7 @@ public: | |||
qDebug("LadspaPlugin::reload() - start"); | |||
// Safely disable plugin for reload | |||
const CarlaPluginScopedDisabler m(this); | |||
const ScopedDisabler m(this); | |||
if (x_client->isActive()) | |||
x_client->deactivate(); | |||
@@ -136,7 +136,7 @@ public: | |||
qDebug("LinuxSamplerPlugin::reload() - start"); | |||
// Safely disable plugin for reload | |||
const CarlaPluginScopedDisabler m(this); | |||
const ScopedDisabler m(this); | |||
if (x_client->isActive()) | |||
x_client->deactivate(); | |||
@@ -714,13 +714,12 @@ public: | |||
if (x_engine->isOffline()) | |||
{ | |||
engineProcessLock(); | |||
const CarlaEngine::ScopedLocker m(x_engine); | |||
status = ext.state->restore(handle, carla_lv2_state_retrieve, this, 0, features); | |||
engineProcessUnlock(); | |||
} | |||
else | |||
{ | |||
const CarlaPluginScopedDisabler m(this); | |||
const ScopedDisabler m(this); | |||
status = ext.state->restore(handle, carla_lv2_state_retrieve, this, 0, features); | |||
} | |||
@@ -756,13 +755,12 @@ public: | |||
{ | |||
if (x_engine->isOffline()) | |||
{ | |||
if (block) engineProcessLock(); | |||
const CarlaEngine::ScopedLocker m(x_engine, block); | |||
ext.programs->select_program(handle, midiprog.data[index].bank, midiprog.data[index].program); | |||
if (block) engineProcessUnlock(); | |||
} | |||
else | |||
{ | |||
const CarlaPluginScopedDisabler m(this, block); | |||
const ScopedDisabler m(this, block); | |||
ext.programs->select_program(handle, midiprog.data[index].bank, midiprog.data[index].program); | |||
} | |||
@@ -922,7 +920,7 @@ public: | |||
qDebug("Lv2Plugin::reload() - start"); | |||
// Safely disable plugin for reload | |||
const CarlaPluginScopedDisabler m(this); | |||
const ScopedDisabler m(this); | |||
if (x_client->isActive()) | |||
x_client->deactivate(); | |||
@@ -2539,7 +2537,7 @@ public: | |||
{ | |||
if (index == -1) | |||
{ | |||
const CarlaPluginScopedDisabler m(this); | |||
const ScopedDisabler m(this); | |||
reloadPrograms(false); | |||
} | |||
else | |||
@@ -223,13 +223,12 @@ public: | |||
if (x_engine->isOffline()) | |||
{ | |||
engineProcessLock(); | |||
const CarlaEngine::ScopedLocker m(x_engine); | |||
effect->dispatcher(effect, effSetChunk, 0 /* bank */, chunk.size(), chunk.data(), 0.0f); | |||
engineProcessUnlock(); | |||
} | |||
else | |||
{ | |||
const CarlaPluginScopedDisabler m(this); | |||
const ScopedDisabler m(this); | |||
effect->dispatcher(effect, effSetChunk, 0 /* bank */, chunk.size(), chunk.data(), 0.0f); | |||
} | |||
} | |||
@@ -242,13 +241,12 @@ public: | |||
{ | |||
if (x_engine->isOffline()) | |||
{ | |||
if (block) engineProcessLock(); | |||
const CarlaEngine::ScopedLocker m(x_engine, block); | |||
effect->dispatcher(effect, effSetProgram, 0, index, nullptr, 0.0f); | |||
if (block) engineProcessUnlock(); | |||
} | |||
else | |||
{ | |||
const CarlaPluginScopedDisabler m(this, block); | |||
const ScopedDisabler m(this, block); | |||
effect->dispatcher(effect, effSetProgram, 0, index, nullptr, 0.0f); | |||
} | |||
} | |||
@@ -324,7 +322,7 @@ public: | |||
qDebug("VstPlugin::reload() - start"); | |||
// Safely disable plugin for reload | |||
const CarlaPluginScopedDisabler m(this); | |||
const ScopedDisabler m(this); | |||
if (x_client->isActive()) | |||
x_client->deactivate(); | |||