@@ -10,6 +10,6 @@ export CFLAGS="-DJACKBRIDGE_DIRECT=1 -DSTOAT_TEST_BUILD=1" | |||||
export CXXFLAGS=${CFLAGS} | export CXXFLAGS=${CFLAGS} | ||||
export LDFLAGS="-ljack" | export LDFLAGS="-ljack" | ||||
make -j 8 EXTERNAL_PLUGINS=false backend | |||||
make -j 8 EXTERNAL_PLUGINS=false backend && \ | |||||
stoat --recursive build/ -b data/stoat/blacklist.txt -w data/stoat/whitelist.txt | stoat --recursive build/ -b data/stoat/blacklist.txt -w data/stoat/whitelist.txt | ||||
# -G stoat-output.png | # -G stoat-output.png |
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla Plugin Host | * Carla Plugin Host | ||||
* Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -632,6 +632,12 @@ public: | |||||
*/ | */ | ||||
void setMidiProgramById(const uint32_t bank, const uint32_t program, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept; | void setMidiProgramById(const uint32_t bank, const uint32_t program, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept; | ||||
/*! | |||||
* Overloaded functions, to be called from within RT context only. | |||||
*/ | |||||
virtual void setProgramRT(const uint32_t index) noexcept; | |||||
virtual void setMidiProgramRT(const uint32_t index) noexcept; | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
// Plugin state | // Plugin state | ||||
@@ -1690,10 +1690,17 @@ void CarlaPlugin::setProgram(const int32_t index, const bool sendGui, const bool | |||||
if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0) | if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0) | ||||
uiProgramChange(static_cast<uint32_t>(index)); | uiProgramChange(static_cast<uint32_t>(index)); | ||||
if (getType() == PLUGIN_GIG || getType() == PLUGIN_SF2 || getType() == PLUGIN_SFZ) | |||||
return; | |||||
switch (getType()) | |||||
{ | |||||
case PLUGIN_GIG: | |||||
case PLUGIN_SF2: | |||||
case PLUGIN_SFZ: | |||||
break; | |||||
pData->updateParameterValues(this, reallySendOsc, sendCallback, true); | |||||
default: | |||||
pData->updateParameterValues(this, reallySendOsc, sendCallback, true); | |||||
break; | |||||
} | |||||
} | } | ||||
// may be unused | // may be unused | ||||
@@ -1718,15 +1725,23 @@ void CarlaPlugin::setMidiProgram(const int32_t index, const bool sendGui, const | |||||
if (sendCallback) | if (sendCallback) | ||||
pData->engine->callback(ENGINE_CALLBACK_MIDI_PROGRAM_CHANGED, pData->id, index, 0, 0.0f, nullptr); | pData->engine->callback(ENGINE_CALLBACK_MIDI_PROGRAM_CHANGED, pData->id, index, 0, 0.0f, nullptr); | ||||
// Change default parameter values | |||||
if (index >= 0) | if (index >= 0) | ||||
{ | { | ||||
if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0) | if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0) | ||||
uiMidiProgramChange(static_cast<uint32_t>(index)); | uiMidiProgramChange(static_cast<uint32_t>(index)); | ||||
if (getType() == PLUGIN_GIG || getType() == PLUGIN_SF2 || getType() == PLUGIN_SFZ) | |||||
return; | |||||
switch (getType()) | |||||
{ | |||||
case PLUGIN_GIG: | |||||
case PLUGIN_SF2: | |||||
case PLUGIN_SFZ: | |||||
break; | |||||
pData->updateParameterValues(this, reallySendOsc, sendCallback, true); | |||||
default: | |||||
pData->updateParameterValues(this, reallySendOsc, sendCallback, true); | |||||
break; | |||||
} | |||||
} | } | ||||
// may be unused | // may be unused | ||||
@@ -1742,6 +1757,52 @@ void CarlaPlugin::setMidiProgramById(const uint32_t bank, const uint32_t program | |||||
} | } | ||||
} | } | ||||
void CarlaPlugin::setProgramRT(const uint32_t uindex) noexcept | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(uindex < pData->prog.count,); | |||||
const int32_t index = static_cast<int32_t>(uindex); | |||||
pData->prog.current = index; | |||||
// Change default parameter values | |||||
switch (getType()) | |||||
{ | |||||
case PLUGIN_GIG: | |||||
case PLUGIN_SF2: | |||||
case PLUGIN_SFZ: | |||||
break; | |||||
default: | |||||
pData->updateDefaultParameterValues(this); | |||||
break; | |||||
} | |||||
pData->postponeRtEvent(kPluginPostRtEventProgramChange, index, 0, 0.0f); | |||||
} | |||||
void CarlaPlugin::setMidiProgramRT(const uint32_t uindex) noexcept | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(uindex < pData->midiprog.count,); | |||||
const int32_t index = static_cast<int32_t>(uindex); | |||||
pData->midiprog.current = index; | |||||
// Change default parameter values | |||||
switch (getType()) | |||||
{ | |||||
case PLUGIN_GIG: | |||||
case PLUGIN_SF2: | |||||
case PLUGIN_SFZ: | |||||
break; | |||||
default: | |||||
pData->updateDefaultParameterValues(this); | |||||
break; | |||||
} | |||||
pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, index, 0, 0.0f); | |||||
} | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
// Plugin state | // Plugin state | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla Plugin Bridge | * Carla Plugin Bridge | ||||
* Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -659,7 +659,7 @@ public: | |||||
void setCtrlChannel(const int8_t channel, const bool sendOsc, const bool sendCallback) noexcept override | void setCtrlChannel(const int8_t channel, const bool sendOsc, const bool sendCallback) noexcept override | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT | |||||
CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); | |||||
{ | { | ||||
const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex); | const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex); | ||||
@@ -677,8 +677,8 @@ public: | |||||
void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override | void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); // never call this from RT | |||||
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); | CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); | ||||
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); | |||||
const float fixedValue(pData->param.getFixedValue(parameterId, value)); | const float fixedValue(pData->param.getFixedValue(parameterId, value)); | ||||
fParams[parameterId].value = fixedValue; | fParams[parameterId].value = fixedValue; | ||||
@@ -698,9 +698,9 @@ public: | |||||
void setParameterMidiChannel(const uint32_t parameterId, const uint8_t channel, const bool sendOsc, const bool sendCallback) noexcept override | void setParameterMidiChannel(const uint32_t parameterId, const uint8_t channel, const bool sendOsc, const bool sendCallback) noexcept override | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT | |||||
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); | CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); | ||||
CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); | CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); | ||||
CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); | |||||
{ | { | ||||
const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex); | const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex); | ||||
@@ -716,9 +716,9 @@ public: | |||||
void setParameterMidiCC(const uint32_t parameterId, const int16_t cc, const bool sendOsc, const bool sendCallback) noexcept override | void setParameterMidiCC(const uint32_t parameterId, const int16_t cc, const bool sendOsc, const bool sendCallback) noexcept override | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT | |||||
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); | CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); | ||||
CARLA_SAFE_ASSERT_RETURN(cc >= -1 && cc < MAX_MIDI_CONTROL,); | CARLA_SAFE_ASSERT_RETURN(cc >= -1 && cc < MAX_MIDI_CONTROL,); | ||||
CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); | |||||
{ | { | ||||
const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex); | const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex); | ||||
@@ -734,8 +734,8 @@ public: | |||||
void setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override | void setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); // never call this from RT | |||||
CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),); | CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),); | ||||
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); | |||||
{ | { | ||||
const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex); | const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex); | ||||
@@ -750,8 +750,8 @@ public: | |||||
void setMidiProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override | void setMidiProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); // never call this from RT | |||||
CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),); | CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),); | ||||
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); | |||||
{ | { | ||||
const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex); | const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex); | ||||
@@ -764,6 +764,21 @@ public: | |||||
CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback); | CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback); | ||||
} | } | ||||
void setMidiProgramRT(const uint32_t uindex) noexcept override | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(uindex < pData->midiprog.count,); | |||||
{ | |||||
const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex); | |||||
fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetMidiProgram); | |||||
fShmNonRtClientControl.writeInt(static_cast<int32_t>(uindex)); | |||||
fShmNonRtClientControl.commitWrite(); | |||||
} | |||||
CarlaPlugin::setMidiProgramRT(uindex); | |||||
} | |||||
void setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui) override | void setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui) override | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(type != nullptr && type[0] != '\0',); | CARLA_SAFE_ASSERT_RETURN(type != nullptr && type[0] != '\0',); | ||||
@@ -1420,11 +1435,14 @@ public: | |||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Try lock, silence otherwise | // Try lock, silence otherwise | ||||
#ifndef STOAT_TEST_BUILD | |||||
if (pData->engine->isOffline()) | if (pData->engine->isOffline()) | ||||
{ | { | ||||
pData->singleMutex.lock(); | pData->singleMutex.lock(); | ||||
} | } | ||||
else if (! pData->singleMutex.tryLock()) | |||||
else | |||||
#endif | |||||
if (! pData->singleMutex.tryLock()) | |||||
{ | { | ||||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | for (uint32_t i=0; i < pData->audioOut.count; ++i) | ||||
carla_zeroFloats(audioOut[i], frames); | carla_zeroFloats(audioOut[i], frames); | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla Plugin, DSSI implementation | * Carla Plugin, DSSI implementation | ||||
* Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -645,28 +645,45 @@ public: | |||||
CARLA_SAFE_ASSERT_RETURN(fDssiDescriptor != nullptr,); | CARLA_SAFE_ASSERT_RETURN(fDssiDescriptor != nullptr,); | ||||
CARLA_SAFE_ASSERT_RETURN(fDssiDescriptor->select_program != nullptr,); | CARLA_SAFE_ASSERT_RETURN(fDssiDescriptor->select_program != nullptr,); | ||||
CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),); | CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),); | ||||
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); | |||||
if (index >= 0 && fHandles.count() > 0) | if (index >= 0 && fHandles.count() > 0) | ||||
{ | { | ||||
const uint32_t bank(pData->midiprog.data[index].bank); | |||||
const uint32_t program(pData->midiprog.data[index].program); | |||||
const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback)); | const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback)); | ||||
for (LinkedList<LADSPA_Handle>::Itenerator it = fHandles.begin2(); it.valid(); it.next()) | |||||
{ | |||||
LADSPA_Handle const handle(it.getValue(nullptr)); | |||||
CARLA_SAFE_ASSERT_CONTINUE(handle != nullptr); | |||||
try { | |||||
fDssiDescriptor->select_program(handle, bank, program); | |||||
} CARLA_SAFE_EXCEPTION("DSSI setMidiProgram") | |||||
} | |||||
setMidiProgramInDSSI(static_cast<uint32_t>(index)); | |||||
} | } | ||||
CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback); | CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback); | ||||
} | } | ||||
void setMidiProgramRT(const uint32_t uindex) noexcept override | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(fDssiDescriptor != nullptr,); | |||||
CARLA_SAFE_ASSERT_RETURN(fDssiDescriptor->select_program != nullptr,); | |||||
CARLA_SAFE_ASSERT_RETURN(uindex < pData->midiprog.count,); | |||||
setMidiProgramInDSSI(uindex); | |||||
CarlaPlugin::setMidiProgramRT(uindex); | |||||
} | |||||
void setMidiProgramInDSSI(const uint32_t uindex) noexcept | |||||
{ | |||||
const uint32_t bank(pData->midiprog.data[uindex].bank); | |||||
const uint32_t program(pData->midiprog.data[uindex].program); | |||||
for (LinkedList<LADSPA_Handle>::Itenerator it = fHandles.begin2(); it.valid(); it.next()) | |||||
{ | |||||
LADSPA_Handle const handle(it.getValue(nullptr)); | |||||
CARLA_SAFE_ASSERT_CONTINUE(handle != nullptr); | |||||
try { | |||||
fDssiDescriptor->select_program(handle, bank, program); | |||||
} CARLA_SAFE_EXCEPTION("DSSI setMidiProgram") | |||||
} | |||||
} | |||||
#ifdef HAVE_LIBLO | #ifdef HAVE_LIBLO | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
// Set ui stuff | // Set ui stuff | ||||
@@ -1542,9 +1559,7 @@ public: | |||||
{ | { | ||||
if (pData->midiprog.data[k].bank == nextBankId && pData->midiprog.data[k].program == nextProgramId) | if (pData->midiprog.data[k].bank == nextBankId && pData->midiprog.data[k].program == nextProgramId) | ||||
{ | { | ||||
const int32_t index(static_cast<int32_t>(k)); | |||||
setMidiProgram(index, false, false, false); | |||||
pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, index, 0, 0.0f); | |||||
setMidiProgramRT(k); | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
@@ -1756,11 +1771,14 @@ public: | |||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Try lock, silence otherwise | // Try lock, silence otherwise | ||||
#ifndef STOAT_TEST_BUILD | |||||
if (pData->engine->isOffline()) | if (pData->engine->isOffline()) | ||||
{ | { | ||||
pData->singleMutex.lock(); | pData->singleMutex.lock(); | ||||
} | } | ||||
else if (! pData->singleMutex.tryLock()) | |||||
else | |||||
#endif | |||||
if (! pData->singleMutex.tryLock()) | |||||
{ | { | ||||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | for (uint32_t i=0; i < pData->audioOut.count; ++i) | ||||
{ | { | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla FluidSynth Plugin | * Carla FluidSynth Plugin | ||||
* Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -387,6 +387,7 @@ public: | |||||
void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override | void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); | CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); | ||||
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); | |||||
float fixedValue; | float fixedValue; | ||||
@@ -530,17 +531,18 @@ public: | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(fSynth != nullptr,); | CARLA_SAFE_ASSERT_RETURN(fSynth != nullptr,); | ||||
CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),); | CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),); | ||||
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); | |||||
if (index >= 0 && pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS) | if (index >= 0 && pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS) | ||||
{ | { | ||||
const uint32_t bank = pData->midiprog.data[index].bank; | const uint32_t bank = pData->midiprog.data[index].bank; | ||||
const uint32_t program = pData->midiprog.data[index].program; | const uint32_t program = pData->midiprog.data[index].program; | ||||
//const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback)); | |||||
const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback)); | |||||
try { | try { | ||||
fluid_synth_program_select(fSynth, pData->ctrlChannel, fSynthId, bank, program); | fluid_synth_program_select(fSynth, pData->ctrlChannel, fSynthId, bank, program); | ||||
} catch(...) {} | |||||
} CARLA_SAFE_EXCEPTION("fluid_synth_program_select") | |||||
fCurMidiProgs[pData->ctrlChannel] = index; | fCurMidiProgs[pData->ctrlChannel] = index; | ||||
} | } | ||||
@@ -548,6 +550,26 @@ public: | |||||
CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback); | CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback); | ||||
} | } | ||||
void setMidiProgramRT(const uint32_t uindex) noexcept override | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(fSynth != nullptr,); | |||||
CARLA_SAFE_ASSERT_RETURN(uindex < pData->midiprog.count,); | |||||
if (pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS) | |||||
{ | |||||
const uint32_t bank = pData->midiprog.data[uindex].bank; | |||||
const uint32_t program = pData->midiprog.data[uindex].program; | |||||
try { | |||||
fluid_synth_program_select(fSynth, pData->ctrlChannel, fSynthId, bank, program); | |||||
} CARLA_SAFE_EXCEPTION("fluid_synth_program_select") | |||||
fCurMidiProgs[pData->ctrlChannel] = static_cast<int32_t>(uindex); | |||||
} | |||||
CarlaPlugin::setMidiProgramRT(uindex); | |||||
} | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
// Set ui stuff | // Set ui stuff | ||||
@@ -1403,11 +1425,14 @@ public: | |||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Try lock, silence otherwise | // Try lock, silence otherwise | ||||
#ifndef STOAT_TEST_BUILD | |||||
if (pData->engine->isOffline()) | if (pData->engine->isOffline()) | ||||
{ | { | ||||
pData->singleMutex.lock(); | pData->singleMutex.lock(); | ||||
} | } | ||||
else if (! pData->singleMutex.tryLock()) | |||||
else | |||||
#endif | |||||
if (! pData->singleMutex.tryLock()) | |||||
{ | { | ||||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | for (uint32_t i=0; i < pData->audioOut.count; ++i) | ||||
{ | { | ||||
@@ -819,6 +819,12 @@ void CarlaPlugin::ProtectedData::updateParameterValues(CarlaPlugin* const plugin | |||||
return; (void)sendOsc; | return; (void)sendOsc; | ||||
} | } | ||||
void CarlaPlugin::ProtectedData::updateDefaultParameterValues(CarlaPlugin* const plugin) noexcept | |||||
{ | |||||
for (uint32_t i=0; i < param.count; ++i) | |||||
param.ranges[i].def = param.ranges[i].getFixedValue(plugin->getParameterValue(i)); | |||||
} | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
CARLA_BACKEND_END_NAMESPACE | CARLA_BACKEND_END_NAMESPACE |
@@ -370,6 +370,7 @@ struct CarlaPlugin::ProtectedData { | |||||
void tryTransient() noexcept; | void tryTransient() noexcept; | ||||
#endif | #endif | ||||
void updateParameterValues(CarlaPlugin* const plugin, const bool sendOsc, const bool sendCallback, const bool useDefault) noexcept; | void updateParameterValues(CarlaPlugin* const plugin, const bool sendOsc, const bool sendCallback, const bool useDefault) noexcept; | ||||
void updateDefaultParameterValues(CarlaPlugin* const plugin) noexcept; | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -918,11 +918,14 @@ public: | |||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Try lock, silence otherwise | // Try lock, silence otherwise | ||||
#ifndef STOAT_TEST_BUILD | |||||
if (pData->engine->isOffline()) | if (pData->engine->isOffline()) | ||||
{ | { | ||||
pData->singleMutex.lock(); | pData->singleMutex.lock(); | ||||
} | } | ||||
else if (! pData->singleMutex.tryLock()) | |||||
else | |||||
#endif | |||||
if (! pData->singleMutex.tryLock()) | |||||
{ | { | ||||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | for (uint32_t i=0; i < pData->audioOut.count; ++i) | ||||
carla_zeroFloats(audioOut[i], frames); | carla_zeroFloats(audioOut[i], frames); | ||||
@@ -1120,11 +1120,14 @@ public: | |||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Try lock, silence otherwise | // Try lock, silence otherwise | ||||
#ifndef STOAT_TEST_BUILD | |||||
if (pData->engine->isOffline()) | if (pData->engine->isOffline()) | ||||
{ | { | ||||
pData->singleMutex.lock(); | pData->singleMutex.lock(); | ||||
} | } | ||||
else if (! pData->singleMutex.tryLock()) | |||||
else | |||||
#endif | |||||
if (! pData->singleMutex.tryLock()) | |||||
{ | { | ||||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | for (uint32_t i=0; i < pData->audioOut.count; ++i) | ||||
{ | { | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla LV2 Plugin | * Carla LV2 Plugin | ||||
* Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -1227,6 +1227,7 @@ public: | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,); | CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,); | ||||
CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),); | CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),); | ||||
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); | |||||
if (index >= 0 && index < static_cast<int32_t>(fRdfDescriptor->PresetCount)) | if (index >= 0 && index < static_cast<int32_t>(fRdfDescriptor->PresetCount)) | ||||
{ | { | ||||
@@ -1263,6 +1264,7 @@ public: | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,); | CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,); | ||||
CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),); | CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),); | ||||
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); | |||||
if (index >= 0 && fExt.programs != nullptr && fExt.programs->select_program != nullptr) | if (index >= 0 && fExt.programs != nullptr && fExt.programs->select_program != nullptr) | ||||
{ | { | ||||
@@ -1286,6 +1288,31 @@ public: | |||||
CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback); | CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback); | ||||
} | } | ||||
void setMidiProgramRT(const uint32_t uindex) noexcept override | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,); | |||||
CARLA_SAFE_ASSERT_RETURN(uindex < pData->midiprog.count,); | |||||
if (fExt.programs != nullptr && fExt.programs->select_program != nullptr) | |||||
{ | |||||
const uint32_t bank(pData->midiprog.data[uindex].bank); | |||||
const uint32_t program(pData->midiprog.data[uindex].program); | |||||
try { | |||||
fExt.programs->select_program(fHandle, bank, program); | |||||
} catch(...) {} | |||||
if (fHandle2 != nullptr) | |||||
{ | |||||
try { | |||||
fExt.programs->select_program(fHandle2, bank, program); | |||||
} catch(...) {} | |||||
} | |||||
} | |||||
CarlaPlugin::setMidiProgramRT(uindex); | |||||
} | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
// Set ui stuff | // Set ui stuff | ||||
@@ -2997,7 +3024,7 @@ public: | |||||
} | } | ||||
else if (! lv2_atom_buffer_write(&evInAtomIters[j], 0, 0, atom->type, atom->size, LV2_ATOM_BODY_CONST(atom))) | else if (! lv2_atom_buffer_write(&evInAtomIters[j], 0, 0, atom->type, atom->size, LV2_ATOM_BODY_CONST(atom))) | ||||
{ | { | ||||
carla_stdout("Event input buffer full, at least 1 message lost"); | |||||
carla_stderr2("Event input buffer full, at least 1 message lost"); | |||||
continue; | continue; | ||||
} | } | ||||
} | } | ||||
@@ -3279,9 +3306,7 @@ public: | |||||
{ | { | ||||
if (pData->midiprog.data[k].bank == nextBankId && pData->midiprog.data[k].program == nextProgramId) | if (pData->midiprog.data[k].bank == nextBankId && pData->midiprog.data[k].program == nextProgramId) | ||||
{ | { | ||||
const int32_t index(static_cast<int32_t>(k)); | |||||
setMidiProgram(index, false, false, false); | |||||
pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, index, 0, 0.0f); | |||||
setMidiProgramRT(k); | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
@@ -3597,11 +3622,14 @@ public: | |||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Try lock, silence otherwise | // Try lock, silence otherwise | ||||
#ifndef STOAT_TEST_BUILD | |||||
if (pData->engine->isOffline()) | if (pData->engine->isOffline()) | ||||
{ | { | ||||
pData->singleMutex.lock(); | pData->singleMutex.lock(); | ||||
} | } | ||||
else if (! pData->singleMutex.tryLock()) | |||||
else | |||||
#endif | |||||
if (! pData->singleMutex.tryLock()) | |||||
{ | { | ||||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | for (uint32_t i=0; i < pData->audioOut.count; ++i) | ||||
{ | { | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla LinuxSampler Plugin | * Carla LinuxSampler Plugin | ||||
* Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -488,7 +488,10 @@ public: | |||||
const int index(it->getIntValue()); | const int index(it->getIntValue()); | ||||
if (index >= 0) | if (index >= 0) | ||||
setProgramInternal(static_cast<uint>(index), channel, true, false); | |||||
{ | |||||
const ScopedSingleProcessLocker spl(this, true); | |||||
setProgramInternal(static_cast<uint>(index), channel); | |||||
} | |||||
if (++channel >= MAX_MIDI_CHANNELS) | if (++channel >= MAX_MIDI_CHANNELS) | ||||
break; | break; | ||||
@@ -502,57 +505,72 @@ public: | |||||
void setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override | void setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); // never call this from RT | |||||
CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),); | CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),); | ||||
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); | |||||
const int8_t channel(kIsGIG ? pData->ctrlChannel : int8_t(0)); | const int8_t channel(kIsGIG ? pData->ctrlChannel : int8_t(0)); | ||||
if (index >= 0 && channel >= 0) | if (index >= 0 && channel >= 0) | ||||
setProgramInternal(static_cast<uint>(index), static_cast<uint8_t>(channel), sendCallback, false); | |||||
{ | |||||
const uint32_t uindex = static_cast<uint32_t>(index); | |||||
bool internalSetOk; | |||||
{ | |||||
const ScopedSingleProcessLocker spl(this, sendGui || sendOsc || sendCallback); | |||||
internalSetOk = setProgramInternal(uindex, static_cast<uint8_t>(channel)); | |||||
} | |||||
if (internalSetOk && sendCallback) | |||||
pData->engine->callback(ENGINE_CALLBACK_PROGRAM_CHANGED, pData->id, index, 0, 0.0f, nullptr); | |||||
} | |||||
CarlaPlugin::setProgram(index, sendGui, sendOsc, sendCallback); | CarlaPlugin::setProgram(index, sendGui, sendOsc, sendCallback); | ||||
} | } | ||||
void setProgramInternal(const uint32_t index, const uint8_t channel, const bool sendCallback, const bool inRtContent) noexcept | |||||
void setProgramRT(const uint32_t uindex) noexcept override | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(index < pData->prog.count,); | |||||
CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); | |||||
CARLA_SAFE_ASSERT_RETURN(uindex < pData->prog.count,); | |||||
const int8_t channel(kIsGIG ? pData->ctrlChannel : int8_t(0)); | |||||
if (fCurProgs[channel] == index) | |||||
if (channel < 0) | |||||
return; | |||||
if (! setProgramInternal(uindex, static_cast<uint8_t>(channel))) | |||||
return; | return; | ||||
LinuxSampler::EngineChannel* const engineChannel(fEngineChannels[kIsGIG ? channel : 0]); | |||||
CARLA_SAFE_ASSERT_RETURN(engineChannel != nullptr,); | |||||
CarlaPlugin::setProgramRT(uindex); | |||||
} | |||||
const ScopedSingleProcessLocker spl(this, !inRtContent); | |||||
bool setProgramInternal(const uint32_t uindex, const uint8_t channel) noexcept | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); | |||||
if (fCurProgs[channel] == uindex) | |||||
return false; | |||||
LinuxSampler::EngineChannel* const engineChannel(fEngineChannels[kIsGIG ? channel : 0]); | |||||
CARLA_SAFE_ASSERT_RETURN(engineChannel != nullptr, false); | |||||
#ifndef STOAT_TEST_BUILD | |||||
if (pData->engine->isOffline()) | if (pData->engine->isOffline()) | ||||
{ | { | ||||
try { | try { | ||||
engineChannel->PrepareLoadInstrument(pData->filename, index); | |||||
engineChannel->PrepareLoadInstrument(pData->filename, uindex); | |||||
engineChannel->LoadInstrument(); | engineChannel->LoadInstrument(); | ||||
} CARLA_SAFE_EXCEPTION("LoadInstrument"); | } CARLA_SAFE_EXCEPTION("LoadInstrument"); | ||||
} | } | ||||
else | else | ||||
#endif | |||||
{ | { | ||||
try { | try { | ||||
LinuxSampler::InstrumentManager::LoadInstrumentInBackground(fInstrumentIds[index], engineChannel); | |||||
LinuxSampler::InstrumentManager::LoadInstrumentInBackground(fInstrumentIds[uindex], engineChannel); | |||||
} CARLA_SAFE_EXCEPTION("LoadInstrumentInBackground"); | } CARLA_SAFE_EXCEPTION("LoadInstrumentInBackground"); | ||||
} | } | ||||
fCurProgs[channel] = index; | |||||
if (pData->ctrlChannel == channel) | |||||
{ | |||||
const int32_t iindex(static_cast<int32_t>(index)); | |||||
pData->prog.current = iindex; | |||||
fCurProgs[channel] = uindex; | |||||
if (inRtContent) | |||||
pData->postponeRtEvent(kPluginPostRtEventProgramChange, iindex, 0, 0.0f); | |||||
else if (sendCallback) | |||||
pData->engine->callback(ENGINE_CALLBACK_PROGRAM_CHANGED, pData->id, iindex, 0, 0.0f, nullptr); | |||||
} | |||||
return (pData->ctrlChannel == channel); | |||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -1005,9 +1023,7 @@ public: | |||||
case kEngineControlEventTypeMidiProgram: | case kEngineControlEventTypeMidiProgram: | ||||
if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) | if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) | ||||
{ | |||||
setProgramInternal(ctrlEvent.param, event.channel, false, true); | |||||
} | |||||
setProgramInternal(ctrlEvent.param, event.channel); | |||||
break; | break; | ||||
case kEngineControlEventTypeAllSoundOff: | case kEngineControlEventTypeAllSoundOff: | ||||
@@ -1103,11 +1119,14 @@ public: | |||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Try lock, silence otherwise | // Try lock, silence otherwise | ||||
#ifndef STOAT_TEST_BUILD | |||||
if (pData->engine->isOffline()) | if (pData->engine->isOffline()) | ||||
{ | { | ||||
pData->singleMutex.lock(); | pData->singleMutex.lock(); | ||||
} | } | ||||
else if (! pData->singleMutex.tryLock()) | |||||
else | |||||
#endif | |||||
if (! pData->singleMutex.tryLock()) | |||||
{ | { | ||||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | for (uint32_t i=0; i < pData->audioOut.count; ++i) | ||||
{ | { | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla Native Plugin | * Carla Native Plugin | ||||
* Copyright (C) 2012-2017 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -716,6 +716,7 @@ public: | |||||
CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,); | CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,); | ||||
CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,); | CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,); | ||||
CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),); | CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),); | ||||
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); | |||||
// TODO, put into check below | // TODO, put into check below | ||||
if ((pData->hints & PLUGIN_IS_SYNTH) != 0 && (pData->ctrlChannel < 0 || pData->ctrlChannel >= MAX_MIDI_CHANNELS)) | if ((pData->hints & PLUGIN_IS_SYNTH) != 0 && (pData->ctrlChannel < 0 || pData->ctrlChannel >= MAX_MIDI_CHANNELS)) | ||||
@@ -746,6 +747,36 @@ public: | |||||
CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback); | CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback); | ||||
} | } | ||||
void setMidiProgramRT(const uint32_t index) noexcept override | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,); | |||||
CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,); | |||||
CARLA_SAFE_ASSERT_RETURN(index < pData->midiprog.count,); | |||||
// TODO, put into check below | |||||
if ((pData->hints & PLUGIN_IS_SYNTH) != 0 && (pData->ctrlChannel < 0 || pData->ctrlChannel >= MAX_MIDI_CHANNELS)) | |||||
return CarlaPlugin::setMidiProgramRT(index); | |||||
const uint8_t channel = uint8_t((pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS) ? pData->ctrlChannel : 0); | |||||
const uint32_t bank = pData->midiprog.data[index].bank; | |||||
const uint32_t program = pData->midiprog.data[index].program; | |||||
try { | |||||
fDescriptor->set_midi_program(fHandle, channel, bank, program); | |||||
} catch(...) {} | |||||
if (fHandle2 != nullptr) | |||||
{ | |||||
try { | |||||
fDescriptor->set_midi_program(fHandle2, channel, bank, program); | |||||
} catch(...) {} | |||||
} | |||||
fCurMidiProgs[channel] = index; | |||||
CarlaPlugin::setMidiProgramRT(index); | |||||
} | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
// Set ui stuff | // Set ui stuff | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla VST Plugin | * Carla VST Plugin | ||||
* Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -409,6 +409,7 @@ public: | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,); | CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,); | ||||
CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),); | CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),); | ||||
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); | |||||
if (index >= 0) | if (index >= 0) | ||||
{ | { | ||||
@@ -432,6 +433,26 @@ public: | |||||
CarlaPlugin::setProgram(index, sendGui, sendOsc, sendCallback); | CarlaPlugin::setProgram(index, sendGui, sendOsc, sendCallback); | ||||
} | } | ||||
void setProgramRT(const uint32_t uindex) noexcept override | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,); | |||||
CARLA_SAFE_ASSERT_RETURN(uindex < pData->prog.count,); | |||||
try { | |||||
dispatcher(effBeginSetProgram, 0, 0, nullptr, 0.0f); | |||||
} CARLA_SAFE_EXCEPTION_RETURN("effBeginSetProgram",); | |||||
try { | |||||
dispatcher(effSetProgram, 0, static_cast<intptr_t>(uindex), nullptr, 0.0f); | |||||
} CARLA_SAFE_EXCEPTION("effSetProgram"); | |||||
try { | |||||
dispatcher(effEndSetProgram, 0, 0, nullptr, 0.0f); | |||||
} CARLA_SAFE_EXCEPTION("effEndSetProgram"); | |||||
CarlaPlugin::setProgramRT(uindex); | |||||
} | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
// Set ui stuff | // Set ui stuff | ||||
@@ -1352,8 +1373,7 @@ public: | |||||
{ | { | ||||
if (ctrlEvent.param < pData->prog.count) | if (ctrlEvent.param < pData->prog.count) | ||||
{ | { | ||||
setProgram(ctrlEvent.param, false, false, false); | |||||
pData->postponeRtEvent(kPluginPostRtEventProgramChange, ctrlEvent.param, 0, 0.0f); | |||||
setProgramRT(ctrlEvent.param); | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
@@ -1523,11 +1543,14 @@ public: | |||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Try lock, silence otherwise | // Try lock, silence otherwise | ||||
#ifndef STOAT_TEST_BUILD | |||||
if (pData->engine->isOffline()) | if (pData->engine->isOffline()) | ||||
{ | { | ||||
pData->singleMutex.lock(); | pData->singleMutex.lock(); | ||||
} | } | ||||
else if (! pData->singleMutex.tryLock()) | |||||
else | |||||
#endif | |||||
if (! pData->singleMutex.tryLock()) | |||||
{ | { | ||||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | for (uint32_t i=0; i < pData->audioOut.count; ++i) | ||||
{ | { | ||||