Browse Source

More rt/non-rt function split, catch unwanted uses

tags/v1.9.9
falkTX 6 years ago
parent
commit
7de5812912
14 changed files with 321 additions and 79 deletions
  1. +1
    -1
      data/stoat/run-stoat.sh
  2. +7
    -1
      source/backend/CarlaPlugin.hpp
  3. +67
    -6
      source/backend/plugin/CarlaPlugin.cpp
  4. +26
    -8
      source/backend/plugin/CarlaPluginBridge.cpp
  5. +35
    -17
      source/backend/plugin/CarlaPluginDSSI.cpp
  6. +29
    -4
      source/backend/plugin/CarlaPluginFluidSynth.cpp
  7. +6
    -0
      source/backend/plugin/CarlaPluginInternal.cpp
  8. +1
    -0
      source/backend/plugin/CarlaPluginInternal.hpp
  9. +4
    -1
      source/backend/plugin/CarlaPluginJack.cpp
  10. +4
    -1
      source/backend/plugin/CarlaPluginLADSPA.cpp
  11. +34
    -6
      source/backend/plugin/CarlaPluginLV2.cpp
  12. +48
    -29
      source/backend/plugin/CarlaPluginLinuxSampler.cpp
  13. +32
    -1
      source/backend/plugin/CarlaPluginNative.cpp
  14. +27
    -4
      source/backend/plugin/CarlaPluginVST2.cpp

+ 1
- 1
data/stoat/run-stoat.sh View File

@@ -10,6 +10,6 @@ export CFLAGS="-DJACKBRIDGE_DIRECT=1 -DSTOAT_TEST_BUILD=1"
export CXXFLAGS=${CFLAGS}
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
# -G stoat-output.png

+ 7
- 1
source/backend/CarlaPlugin.hpp View File

@@ -1,6 +1,6 @@
/*
* 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
* 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;

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



+ 67
- 6
source/backend/plugin/CarlaPlugin.cpp View File

@@ -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)
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
@@ -1718,15 +1725,23 @@ void CarlaPlugin::setMidiProgram(const int32_t index, const bool sendGui, const
if (sendCallback)
pData->engine->callback(ENGINE_CALLBACK_MIDI_PROGRAM_CHANGED, pData->id, index, 0, 0.0f, nullptr);

// Change default parameter values
if (index >= 0)
{
if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0)
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
@@ -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



+ 26
- 8
source/backend/plugin/CarlaPluginBridge.cpp View File

@@ -1,6 +1,6 @@
/*
* 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
* 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
{
CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,);

{
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
{
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); // never call this from RT
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,);

const float fixedValue(pData->param.getFixedValue(parameterId, value));
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
{
CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,);

{
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
{
CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
CARLA_SAFE_ASSERT_RETURN(cc >= -1 && cc < MAX_MIDI_CONTROL,);
CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,);

{
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
{
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(sendGui || sendOsc || sendCallback,);

{
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
{
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(sendGui || sendOsc || sendCallback,);

{
const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
@@ -764,6 +764,21 @@ public:
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
{
CARLA_SAFE_ASSERT_RETURN(type != nullptr && type[0] != '\0',);
@@ -1420,11 +1435,14 @@ public:
// --------------------------------------------------------------------------------------------------------
// Try lock, silence otherwise

#ifndef STOAT_TEST_BUILD
if (pData->engine->isOffline())
{
pData->singleMutex.lock();
}
else if (! pData->singleMutex.tryLock())
else
#endif
if (! pData->singleMutex.tryLock())
{
for (uint32_t i=0; i < pData->audioOut.count; ++i)
carla_zeroFloats(audioOut[i], frames);


+ 35
- 17
source/backend/plugin/CarlaPluginDSSI.cpp View File

@@ -1,6 +1,6 @@
/*
* 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
* 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->select_program != nullptr,);
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)
{
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));

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

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
// -------------------------------------------------------------------
// Set ui stuff
@@ -1542,9 +1559,7 @@ public:
{
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;
}
}
@@ -1756,11 +1771,14 @@ public:
// --------------------------------------------------------------------------------------------------------
// Try lock, silence otherwise

#ifndef STOAT_TEST_BUILD
if (pData->engine->isOffline())
{
pData->singleMutex.lock();
}
else if (! pData->singleMutex.tryLock())
else
#endif
if (! pData->singleMutex.tryLock())
{
for (uint32_t i=0; i < pData->audioOut.count; ++i)
{


+ 29
- 4
source/backend/plugin/CarlaPluginFluidSynth.cpp View File

@@ -1,6 +1,6 @@
/*
* 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
* 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
{
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,);

float fixedValue;

@@ -530,17 +531,18 @@ public:
{
CARLA_SAFE_ASSERT_RETURN(fSynth != nullptr,);
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)
{
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));

try {
fluid_synth_program_select(fSynth, pData->ctrlChannel, fSynthId, bank, program);
} catch(...) {}
} CARLA_SAFE_EXCEPTION("fluid_synth_program_select")

fCurMidiProgs[pData->ctrlChannel] = index;
}
@@ -548,6 +550,26 @@ public:
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

@@ -1403,11 +1425,14 @@ public:
// --------------------------------------------------------------------------------------------------------
// Try lock, silence otherwise

#ifndef STOAT_TEST_BUILD
if (pData->engine->isOffline())
{
pData->singleMutex.lock();
}
else if (! pData->singleMutex.tryLock())
else
#endif
if (! pData->singleMutex.tryLock())
{
for (uint32_t i=0; i < pData->audioOut.count; ++i)
{


+ 6
- 0
source/backend/plugin/CarlaPluginInternal.cpp View File

@@ -819,6 +819,12 @@ void CarlaPlugin::ProtectedData::updateParameterValues(CarlaPlugin* const plugin
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

+ 1
- 0
source/backend/plugin/CarlaPluginInternal.hpp View File

@@ -370,6 +370,7 @@ struct CarlaPlugin::ProtectedData {
void tryTransient() noexcept;
#endif
void updateParameterValues(CarlaPlugin* const plugin, const bool sendOsc, const bool sendCallback, const bool useDefault) noexcept;
void updateDefaultParameterValues(CarlaPlugin* const plugin) noexcept;

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



+ 4
- 1
source/backend/plugin/CarlaPluginJack.cpp View File

@@ -918,11 +918,14 @@ public:
// --------------------------------------------------------------------------------------------------------
// Try lock, silence otherwise

#ifndef STOAT_TEST_BUILD
if (pData->engine->isOffline())
{
pData->singleMutex.lock();
}
else if (! pData->singleMutex.tryLock())
else
#endif
if (! pData->singleMutex.tryLock())
{
for (uint32_t i=0; i < pData->audioOut.count; ++i)
carla_zeroFloats(audioOut[i], frames);


+ 4
- 1
source/backend/plugin/CarlaPluginLADSPA.cpp View File

@@ -1120,11 +1120,14 @@ public:
// --------------------------------------------------------------------------------------------------------
// Try lock, silence otherwise

#ifndef STOAT_TEST_BUILD
if (pData->engine->isOffline())
{
pData->singleMutex.lock();
}
else if (! pData->singleMutex.tryLock())
else
#endif
if (! pData->singleMutex.tryLock())
{
for (uint32_t i=0; i < pData->audioOut.count; ++i)
{


+ 34
- 6
source/backend/plugin/CarlaPluginLV2.cpp View File

@@ -1,6 +1,6 @@
/*
* 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
* 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(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))
{
@@ -1263,6 +1264,7 @@ public:
{
CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
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)
{
@@ -1286,6 +1288,31 @@ public:
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

@@ -2997,7 +3024,7 @@ public:
}
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;
}
}
@@ -3279,9 +3306,7 @@ public:
{
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;
}
}
@@ -3597,11 +3622,14 @@ public:
// --------------------------------------------------------------------------------------------------------
// Try lock, silence otherwise

#ifndef STOAT_TEST_BUILD
if (pData->engine->isOffline())
{
pData->singleMutex.lock();
}
else if (! pData->singleMutex.tryLock())
else
#endif
if (! pData->singleMutex.tryLock())
{
for (uint32_t i=0; i < pData->audioOut.count; ++i)
{


+ 48
- 29
source/backend/plugin/CarlaPluginLinuxSampler.cpp View File

@@ -1,6 +1,6 @@
/*
* 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
* modify it under the terms of the GNU General Public License as
@@ -488,7 +488,10 @@ public:
const int index(it->getIntValue());

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)
break;
@@ -502,57 +505,72 @@ public:

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(sendGui || sendOsc || sendCallback,);

const int8_t channel(kIsGIG ? pData->ctrlChannel : int8_t(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);
}

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;

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())
{
try {
engineChannel->PrepareLoadInstrument(pData->filename, index);
engineChannel->PrepareLoadInstrument(pData->filename, uindex);
engineChannel->LoadInstrument();
} CARLA_SAFE_EXCEPTION("LoadInstrument");
}
else
#endif
{
try {
LinuxSampler::InstrumentManager::LoadInstrumentInBackground(fInstrumentIds[index], engineChannel);
LinuxSampler::InstrumentManager::LoadInstrumentInBackground(fInstrumentIds[uindex], engineChannel);
} 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:
if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES)
{
setProgramInternal(ctrlEvent.param, event.channel, false, true);
}
setProgramInternal(ctrlEvent.param, event.channel);
break;

case kEngineControlEventTypeAllSoundOff:
@@ -1103,11 +1119,14 @@ public:
// --------------------------------------------------------------------------------------------------------
// Try lock, silence otherwise

#ifndef STOAT_TEST_BUILD
if (pData->engine->isOffline())
{
pData->singleMutex.lock();
}
else if (! pData->singleMutex.tryLock())
else
#endif
if (! pData->singleMutex.tryLock())
{
for (uint32_t i=0; i < pData->audioOut.count; ++i)
{


+ 32
- 1
source/backend/plugin/CarlaPluginNative.cpp View File

@@ -1,6 +1,6 @@
/*
* 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
* 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(fHandle != nullptr,);
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
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);
}

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



+ 27
- 4
source/backend/plugin/CarlaPluginVST2.cpp View File

@@ -1,6 +1,6 @@
/*
* 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
* 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(index >= -1 && index < static_cast<int32_t>(pData->prog.count),);
CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,);

if (index >= 0)
{
@@ -432,6 +433,26 @@ public:
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

@@ -1352,8 +1373,7 @@ public:
{
if (ctrlEvent.param < pData->prog.count)
{
setProgram(ctrlEvent.param, false, false, false);
pData->postponeRtEvent(kPluginPostRtEventProgramChange, ctrlEvent.param, 0, 0.0f);
setProgramRT(ctrlEvent.param);
break;
}
}
@@ -1523,11 +1543,14 @@ public:
// --------------------------------------------------------------------------------------------------------
// Try lock, silence otherwise

#ifndef STOAT_TEST_BUILD
if (pData->engine->isOffline())
{
pData->singleMutex.lock();
}
else if (! pData->singleMutex.tryLock())
else
#endif
if (! pData->singleMutex.tryLock())
{
for (uint32_t i=0; i < pData->audioOut.count; ++i)
{


Loading…
Cancel
Save