Browse Source

More cleanup, add ScopedProcessLocker class

tags/1.9.4
falkTX 12 years ago
parent
commit
305f6c6caa
13 changed files with 249 additions and 230 deletions
  1. +7
    -4
      source/backend/CarlaPlugin.hpp
  2. +4
    -3
      source/backend/engine/CarlaEngine.cpp
  3. +4
    -4
      source/backend/engine/CarlaEngineOsc.cpp
  4. +24
    -9
      source/backend/plugin/CarlaPlugin.cpp
  5. +9
    -9
      source/backend/plugin/DssiPlugin.cpp
  6. +151
    -146
      source/backend/plugin/FluidSynthPlugin.cpp
  7. +1
    -1
      source/backend/plugin/LadspaPlugin.cpp
  8. +33
    -11
      source/backend/plugin/LinuxSamplerPlugin.cpp
  9. +0
    -5
      source/backend/plugin/Lv2Plugin.cpp
  10. +12
    -29
      source/backend/plugin/NativePlugin.cpp
  11. +0
    -5
      source/backend/plugin/VstPlugin.cpp
  12. +2
    -2
      source/backend/standalone/CarlaStandalone.cpp
  13. +2
    -2
      source/bridges/CarlaBridgePlugin.cpp

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

@@ -597,7 +597,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(const 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);


/*! /*!
* Change the current MIDI plugin program to \a index. * Change the current MIDI plugin program to \a index.
@@ -611,13 +611,13 @@ 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(const 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);


/*! /*!
* This is an overloaded call to setMidiProgram().\n * This is an overloaded call to setMidiProgram().\n
* It changes the current MIDI program using \a bank and \a program values instead of index. * It changes the current MIDI program using \a bank and \a program values instead of index.
*/ */
void setMidiProgramById(const uint32_t bank, const uint32_t program, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block);
void setMidiProgramById(const uint32_t bank, const uint32_t program, const bool sendGui, const bool sendOsc, const bool sendCallback);


// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Set gui stuff // Set gui stuff
@@ -847,6 +847,7 @@ protected:
private: private:
CarlaPlugin* const kPlugin; CarlaPlugin* const kPlugin;


CARLA_PREVENT_HEAP_ALLOCATION
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ScopedDisabler) CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ScopedDisabler)
}; };


@@ -856,12 +857,14 @@ protected:
class ScopedProcessLocker class ScopedProcessLocker
{ {
public: public:
ScopedProcessLocker(CarlaPlugin* const plugin);
ScopedProcessLocker(CarlaPlugin* const plugin, const bool block);
~ScopedProcessLocker(); ~ScopedProcessLocker();


private: private:
CarlaPlugin* const kPlugin; CarlaPlugin* const kPlugin;
const bool kBlock;


CARLA_PREVENT_HEAP_ALLOCATION
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ScopedProcessLocker) CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ScopedProcessLocker)
}; };




+ 4
- 3
source/backend/engine/CarlaEngine.cpp View File

@@ -1456,9 +1456,10 @@ void CarlaEngine::processRack(float* inBuf[2], float* outBuf[2], const uint32_t
// if no plugins in the rack, copy inputs over outputs // if no plugins in the rack, copy inputs over outputs
if (! processed) if (! processed)
{ {
carla_copyFloat(outBuf[0], inBuf[0], frames);
carla_copyFloat(outBuf[1], inBuf[1], frames);
std::memcpy(kData->rack.out, kData->rack.in, sizeof(EngineEvent)*RACK_EVENT_COUNT);
// FIXME
//carla_copyFloat(outBuf[0], inBuf[0], frames);
//carla_copyFloat(outBuf[1], inBuf[1], frames);
//std::memcpy(kData->rack.out, kData->rack.in, sizeof(EngineEvent)*RACK_EVENT_COUNT);
} }
} }




+ 4
- 4
source/backend/engine/CarlaEngineOsc.cpp View File

@@ -499,7 +499,7 @@ int CarlaEngineOsc::handleMsgProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2)
if (program < 0) if (program < 0)
return 1; return 1;


plugin->setMidiProgramById(static_cast<uint32_t>(bank), static_cast<uint32_t>(program), false, true, true, true);
plugin->setMidiProgramById(static_cast<uint32_t>(bank), static_cast<uint32_t>(program), false, true, true);


return 0; return 0;
} }
@@ -516,7 +516,7 @@ int CarlaEngineOsc::handleMsgProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2)


if (program < static_cast<int32_t>(plugin->programCount())) if (program < static_cast<int32_t>(plugin->programCount()))
{ {
plugin->setProgram(program, false, true, true, true);
plugin->setProgram(program, false, true, true);
return 0; return 0;
} }


@@ -728,7 +728,7 @@ int CarlaEngineOsc::handleMsgSetProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2)


const int32_t index = argv[0]->i; const int32_t index = argv[0]->i;


plugin->setProgram(index, true, false, true, true);
plugin->setProgram(index, true, false, true);


return 0; return 0;
} }
@@ -740,7 +740,7 @@ int CarlaEngineOsc::handleMsgSetMidiProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2)


const int32_t index = argv[0]->i; const int32_t index = argv[0]->i;


plugin->setMidiProgram(index, true, false, true, true);
plugin->setMidiProgram(index, true, false, true);


return 0; return 0;
} }


+ 24
- 9
source/backend/plugin/CarlaPlugin.cpp View File

@@ -762,7 +762,7 @@ void CarlaPlugin::setChunkData(const char* const stringData)
(void)stringData; (void)stringData;
} }


void CarlaPlugin::setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool)
void CarlaPlugin::setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback)
{ {
CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(kData->prog.count)); CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(kData->prog.count));


@@ -804,7 +804,7 @@ void CarlaPlugin::setProgram(const int32_t index, const bool sendGui, const bool
kData->engine->callback(CALLBACK_PROGRAM_CHANGED, fId, fixedIndex, 0, 0.0f, nullptr); kData->engine->callback(CALLBACK_PROGRAM_CHANGED, fId, fixedIndex, 0, 0.0f, nullptr);
} }


void CarlaPlugin::setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool)
void CarlaPlugin::setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback)
{ {
CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(kData->midiprog.count)); CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(kData->midiprog.count));


@@ -851,12 +851,12 @@ void CarlaPlugin::setMidiProgram(int32_t index, const bool sendGui, const bool s
kData->engine->callback(CALLBACK_MIDI_PROGRAM_CHANGED, fId, fixedIndex, 0, 0.0f, nullptr); kData->engine->callback(CALLBACK_MIDI_PROGRAM_CHANGED, fId, fixedIndex, 0, 0.0f, nullptr);
} }


void CarlaPlugin::setMidiProgramById(const uint32_t bank, const uint32_t program, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block)
void CarlaPlugin::setMidiProgramById(const uint32_t bank, const uint32_t program, const bool sendGui, const bool sendOsc, const bool sendCallback)
{ {
for (uint32_t i=0; i < kData->midiprog.count; i++) for (uint32_t i=0; i < kData->midiprog.count; i++)
{ {
if (kData->midiprog.data[i].bank == bank && kData->midiprog.data[i].program == program) if (kData->midiprog.data[i].bank == bank && kData->midiprog.data[i].program == program)
return setMidiProgram(i, sendGui, sendOsc, sendCallback, block);
return setMidiProgram(i, sendGui, sendOsc, sendCallback);
} }
} }


@@ -1464,6 +1464,9 @@ const char* CarlaPlugin::libError(const char* const filename)
CarlaPlugin::ScopedDisabler::ScopedDisabler(CarlaPlugin* const plugin) CarlaPlugin::ScopedDisabler::ScopedDisabler(CarlaPlugin* const plugin)
: kPlugin(plugin) : kPlugin(plugin)
{ {
carla_debug("CarlaPlugin::ScopedDisabler(%p)", plugin);
CARLA_ASSERT(plugin != nullptr);

if (plugin->fEnabled) if (plugin->fEnabled)
{ {
plugin->fEnabled = false; plugin->fEnabled = false;
@@ -1476,6 +1479,8 @@ CarlaPlugin::ScopedDisabler::ScopedDisabler(CarlaPlugin* const plugin)


CarlaPlugin::ScopedDisabler::~ScopedDisabler() CarlaPlugin::ScopedDisabler::~ScopedDisabler()
{ {
carla_debug("CarlaPlugin::~ScopedDisabler()");

kPlugin->fEnabled = true; kPlugin->fEnabled = true;
kPlugin->kData->client->activate(); kPlugin->kData->client->activate();
} }
@@ -1483,16 +1488,26 @@ CarlaPlugin::ScopedDisabler::~ScopedDisabler()
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Scoped Process Locker // Scoped Process Locker


CarlaPlugin::ScopedProcessLocker::ScopedProcessLocker(CarlaPlugin* const plugin)
: kPlugin(plugin)
CarlaPlugin::ScopedProcessLocker::ScopedProcessLocker(CarlaPlugin* const plugin, const bool block)
: kPlugin(plugin),
kBlock(block)
{ {
plugin->kData->mutex.lock();
carla_debug("CarlaPlugin::ScopedProcessLocker(%p, %s)", plugin, bool2str(block));
CARLA_ASSERT(plugin != nullptr);

if (block)
plugin->kData->mutex.lock();
} }


CarlaPlugin::ScopedProcessLocker::~ScopedProcessLocker() CarlaPlugin::ScopedProcessLocker::~ScopedProcessLocker()
{ {
kPlugin->kData->needsReset = true;
kPlugin->kData->mutex.unlock();
carla_debug("CarlaPlugin::~ScopedProcessLocker()");

if (kBlock)
{
kPlugin->kData->needsReset = true;
kPlugin->kData->mutex.unlock();
}
} }


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


+ 9
- 9
source/backend/plugin/DssiPlugin.cpp View File

@@ -233,7 +233,7 @@ public:


if (fDssiDescriptor->configure != nullptr) if (fDssiDescriptor->configure != nullptr)
{ {
const ScopedProcessLocker spl(this);
const ScopedProcessLocker spl(this, true);


fDssiDescriptor->configure(fHandle, key, value); fDssiDescriptor->configure(fHandle, key, value);


@@ -269,11 +269,11 @@ public:
fChunk = QByteArray::fromBase64(QByteArray(stringData)); fChunk = QByteArray::fromBase64(QByteArray(stringData));
//fChunk.toBase64(); //fChunk.toBase64();


const ScopedProcessLocker spl(this);
const ScopedProcessLocker spl(this, true);
fDssiDescriptor->set_custom_data(fHandle, fChunk.data(), (unsigned long)fChunk.size()); fDssiDescriptor->set_custom_data(fHandle, fChunk.data(), (unsigned long)fChunk.size());
} }


void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block)
void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback)
{ {
CARLA_ASSERT(fDssiDescriptor != nullptr); CARLA_ASSERT(fDssiDescriptor != nullptr);
CARLA_ASSERT(fHandle != nullptr); CARLA_ASSERT(fHandle != nullptr);
@@ -289,7 +289,7 @@ public:
const uint32_t bank = kData->midiprog.data[index].bank; const uint32_t bank = kData->midiprog.data[index].bank;
const uint32_t program = kData->midiprog.data[index].program; const uint32_t program = kData->midiprog.data[index].program;


const ScopedProcessLocker spl(this);
const ScopedProcessLocker spl(this, (sendGui || sendOsc || sendCallback));


fDssiDescriptor->select_program(fHandle, bank, program); fDssiDescriptor->select_program(fHandle, bank, program);


@@ -297,7 +297,7 @@ public:
fDssiDescriptor->select_program(fHandle2, bank, program); fDssiDescriptor->select_program(fHandle2, bank, program);
} }


CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback, block);
CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback);
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -818,7 +818,7 @@ public:
if (init) if (init)
{ {
if (kData->midiprog.count > 0) if (kData->midiprog.count > 0)
setMidiProgram(0, false, false, false, true);
setMidiProgram(0, false, false, false);
} }
else else
{ {
@@ -853,7 +853,7 @@ public:
} }


if (programChanged) if (programChanged)
setMidiProgram(kData->midiprog.current, true, true, true, true);
setMidiProgram(kData->midiprog.current, true, true, true);
} }
} }


@@ -1096,7 +1096,7 @@ public:


if (kData->param.data[k].hints & PARAMETER_IS_BOOLEAN) if (kData->param.data[k].hints & PARAMETER_IS_BOOLEAN)
{ {
value = (ctrlEvent.value < 0.5) ? kData->param.ranges[k].min : kData->param.ranges[k].max;
value = (ctrlEvent.value < 0.5f) ? kData->param.ranges[k].min : kData->param.ranges[k].max;
} }
else else
{ {
@@ -1127,7 +1127,7 @@ public:
{ {
if (kData->midiprog.data[k].bank == nextBankId && kData->midiprog.data[k].program == nextProgramId) if (kData->midiprog.data[k].bank == nextBankId && kData->midiprog.data[k].program == nextProgramId)
{ {
setMidiProgram(k, false, false, false, false);
setMidiProgram(k, false, false, false);
postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0); postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0);
break; break;
} }


+ 151
- 146
source/backend/plugin/FluidSynthPlugin.cpp View File

@@ -297,67 +297,54 @@ public:
const float fixedValue = kData->param.fixValue(parameterId, value); const float fixedValue = kData->param.fixValue(parameterId, value);
fParamBuffers[parameterId] = fixedValue; fParamBuffers[parameterId] = fixedValue;


switch (parameterId)
{
case FluidSynthReverbOnOff:
fluid_synth_set_reverb_on(fSynth, (fixedValue > 0.5f) ? 1 : 0);
break;

case FluidSynthReverbRoomSize:
case FluidSynthReverbDamp:
case FluidSynthReverbLevel:
case FluidSynthReverbWidth:
fluid_synth_set_reverb(fSynth, fParamBuffers[FluidSynthReverbRoomSize], fParamBuffers[FluidSynthReverbDamp], fParamBuffers[FluidSynthReverbWidth], fParamBuffers[FluidSynthReverbLevel]);
break;

case FluidSynthChorusOnOff:
{
// FIXME
//const ScopedDisabler m(this, ! kData->engine->isOffline());
fluid_synth_set_chorus_on(fSynth, (value > 0.5f) ? 1 : 0);
break;
}

case FluidSynthChorusNr:
case FluidSynthChorusLevel:
case FluidSynthChorusSpeedHz:
case FluidSynthChorusDepthMs:
case FluidSynthChorusType:
{
//FIXME
//const ScopedDisabler m(this, ! kData->engine->isOffline());
fluid_synth_set_chorus(fSynth, fParamBuffers[FluidSynthChorusNr], fParamBuffers[FluidSynthChorusLevel], fParamBuffers[FluidSynthChorusSpeedHz], fParamBuffers[FluidSynthChorusDepthMs], fParamBuffers[FluidSynthChorusType]);
break;
}

case FluidSynthPolyphony:
{
//FIXME
//const ScopedDisabler m(this, ! kData->engine->isOffline());
fluid_synth_set_polyphony(fSynth, value);
break;
}

case FluidSynthInterpolation:
{ {
//FIXME
//const ScopedDisabler m(this, ! kData->engine->isOffline());

for (int i=0; i < 16; i++)
fluid_synth_set_interp_method(fSynth, i, value);
const ScopedProcessLocker spl(this, (sendGui || sendOsc || sendCallback));


break;
}
switch (parameterId)
{
case FluidSynthReverbOnOff:
fluid_synth_set_reverb_on(fSynth, (fixedValue > 0.5f) ? 1 : 0);
break;

case FluidSynthReverbRoomSize:
case FluidSynthReverbDamp:
case FluidSynthReverbLevel:
case FluidSynthReverbWidth:
fluid_synth_set_reverb(fSynth, fParamBuffers[FluidSynthReverbRoomSize], fParamBuffers[FluidSynthReverbDamp], fParamBuffers[FluidSynthReverbWidth], fParamBuffers[FluidSynthReverbLevel]);
break;

case FluidSynthChorusOnOff:
fluid_synth_set_chorus_on(fSynth, (value > 0.5f) ? 1 : 0);
break;

case FluidSynthChorusNr:
case FluidSynthChorusLevel:
case FluidSynthChorusSpeedHz:
case FluidSynthChorusDepthMs:
case FluidSynthChorusType:
fluid_synth_set_chorus(fSynth, fParamBuffers[FluidSynthChorusNr], fParamBuffers[FluidSynthChorusLevel], fParamBuffers[FluidSynthChorusSpeedHz], fParamBuffers[FluidSynthChorusDepthMs], fParamBuffers[FluidSynthChorusType]);
break;

case FluidSynthPolyphony:
fluid_synth_set_polyphony(fSynth, value);
break;

case FluidSynthInterpolation:
for (int i=0; i < 16; i++)
fluid_synth_set_interp_method(fSynth, i, value);
break;


default:
break;
default:
break;
}
} }


CarlaPlugin::setParameterValue(parameterId, value, sendGui, sendOsc, sendCallback); CarlaPlugin::setParameterValue(parameterId, value, sendGui, sendOsc, sendCallback);
} }


void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block)
void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback)
{ {
CARLA_ASSERT(fSynth != nullptr);
CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(kData->midiprog.count)); CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(kData->midiprog.count));


if (index < -1) if (index < -1)
@@ -368,25 +355,16 @@ public:
if (kData->ctrlChannel < 0 || kData->ctrlChannel >= 16) if (kData->ctrlChannel < 0 || kData->ctrlChannel >= 16)
return; return;


// FIXME
if (index >= 0) if (index >= 0)
{ {
const uint32_t bank = kData->midiprog.data[index].bank; const uint32_t bank = kData->midiprog.data[index].bank;
const uint32_t program = kData->midiprog.data[index].program; const uint32_t program = kData->midiprog.data[index].program;


if (kData->engine->isOffline())
{
//const CarlaEngine::ScopedLocker m(x_engine, block);
fluid_synth_program_select(fSynth, kData->ctrlChannel, fSynthId, bank, program);
}
else
{
//const ScopedDisabler m(this, block);
fluid_synth_program_select(fSynth, kData->ctrlChannel, fSynthId, bank, program);
}
const ScopedProcessLocker spl(this, (sendGui || sendOsc || sendCallback));
fluid_synth_program_select(fSynth, kData->ctrlChannel, fSynthId, bank, program);
} }


CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback, block);
CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback);
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -403,9 +381,6 @@ public:
// Safely disable plugin for reload // Safely disable plugin for reload
const ScopedDisabler sd(this); const ScopedDisabler sd(this);


if (kData->client->isActive())
kData->client->deactivate();

deleteBuffers(); deleteBuffers();


uint32_t aOuts, params, j; uint32_t aOuts, params, j;
@@ -771,8 +746,6 @@ public:
bufferSizeChanged(kData->engine->getBufferSize()); bufferSizeChanged(kData->engine->getBufferSize());
reloadPrograms(true); reloadPrograms(true);


kData->client->activate();

carla_debug("FluidSynthPlugin::reload() - end"); carla_debug("FluidSynthPlugin::reload() - end");
} }


@@ -862,7 +835,7 @@ public:
#endif #endif
} }


setMidiProgram(0, false, false, false, true);
setMidiProgram(0, false, false, false);
} }
else else
{ {
@@ -891,7 +864,7 @@ public:
} }


// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Check if active before
// Check if not active before


if (kData->needsReset || ! kData->activeBefore) if (kData->needsReset || ! kData->activeBefore)
{ {
@@ -941,6 +914,7 @@ public:
bool allNotesOffSent = false; bool allNotesOffSent = false;


uint32_t time, nEvents = kData->event.portIn->getEventCount(); uint32_t time, nEvents = kData->event.portIn->getEventCount();
uint32_t startTime = 0;
uint32_t timeOffset = 0; uint32_t timeOffset = 0;


uint32_t nextBankIds[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0 }; uint32_t nextBankIds[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0 };
@@ -961,12 +935,15 @@ public:


if (time > timeOffset) if (time > timeOffset)
{ {
if (kUses16Outs)
processSingle(outBuffer, time - timeOffset, timeOffset);
else
fluid_synth_write_float(fSynth, time - timeOffset, outBuffer[0] + timeOffset, 0, 1, outBuffer[1] + timeOffset, 0, 1);
if (processSingle(outBuffer, time - timeOffset, timeOffset))
{
timeOffset = time;


timeOffset = time;
if (kData->midiprog.current >= 0 && kData->midiprog.count > 0 && kData->ctrlChannel >= 0 && kData->ctrlChannel < 16)
nextBankIds[kData->ctrlChannel] = kData->midiprog.data[kData->midiprog.current].bank;
}
else
startTime += timeOffset;
} }


// Control change // Control change
@@ -989,7 +966,7 @@ public:
// Control backend stuff // Control backend stuff
if (event.channel == kData->ctrlChannel) if (event.channel == kData->ctrlChannel)
{ {
double value;
float value;


if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (fHints & PLUGIN_CAN_DRYWET) > 0) if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (fHints & PLUGIN_CAN_DRYWET) > 0)
{ {
@@ -1001,7 +978,7 @@ public:


if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (fHints & PLUGIN_CAN_VOLUME) > 0) if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (fHints & PLUGIN_CAN_VOLUME) > 0)
{ {
value = ctrlEvent.value*127/100;
value = ctrlEvent.value*127.0f/100.0f;
setVolume(value, false, false); setVolume(value, false, false);
postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value); postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value);
continue; continue;
@@ -1009,23 +986,23 @@ public:


if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (fHints & PLUGIN_CAN_BALANCE) > 0) if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (fHints & PLUGIN_CAN_BALANCE) > 0)
{ {
double left, right;
value = ctrlEvent.value/0.5 - 1.0;
float left, right;
value = ctrlEvent.value/0.5f - 1.0f;


if (value < 0.0)
if (value < 0.0f)
{ {
left = -1.0;
right = (value*2)+1.0;
left = -1.0f;
right = (value*2.0f)+1.0f;
} }
else if (value > 0.0)
else if (value > 0.0f)
{ {
left = (value*2)-1.0;
right = 1.0;
left = (value*2.0f)-1.0f;
right = 1.0f;
} }
else else
{ {
left = -1.0;
right = 1.0;
left = -1.0f;
right = 1.0f;
} }


setBalanceLeft(left, false, false); setBalanceLeft(left, false, false);
@@ -1048,23 +1025,22 @@ public:
if ((kData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0) if ((kData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0)
continue; continue;


double value;
float value;


if (kData->param.data[k].hints & PARAMETER_IS_BOOLEAN) if (kData->param.data[k].hints & PARAMETER_IS_BOOLEAN)
{ {
value = (ctrlEvent.value < 0.5) ? kData->param.ranges[k].min : kData->param.ranges[k].max;
value = (ctrlEvent.value < 0.5f) ? kData->param.ranges[k].min : kData->param.ranges[k].max;
} }
else else
{ {
// FIXME - ranges call for this
value = ctrlEvent.value * (kData->param.ranges[k].max - kData->param.ranges[k].min) + kData->param.ranges[k].min;
value = kData->param.ranges[i].unnormalizeValue(ctrlEvent.value);


if (kData->param.data[k].hints & PARAMETER_IS_INTEGER) if (kData->param.data[k].hints & PARAMETER_IS_INTEGER)
value = std::rint(value); value = std::rint(value);
} }


setParameterValue(k, value, false, false, false); setParameterValue(k, value, false, false, false);
postponeRtEvent(kPluginPostRtEventParameterChange, k, 0, value);
postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value);
} }


break; break;
@@ -1087,7 +1063,7 @@ public:
{ {
if (event.channel == kData->ctrlChannel) if (event.channel == kData->ctrlChannel)
{ {
setMidiProgram(k, false, false, false, false);
setMidiProgram(k, false, false, false);
postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0); postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0);
} }
else else
@@ -1109,6 +1085,12 @@ public:
postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 1.0); postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 1.0);


allNotesOffSent = true; allNotesOffSent = true;

#ifdef FLUIDSYNTH_VERSION_NEW_API
fluid_synth_all_sounds_off(fSynth, event.channel);
#else
fluid_synth_cc(f_synth, event.channel, MIDI_CONTROL_ALL_SOUND_OFF, 0);
#endif
} }
break; break;


@@ -1119,6 +1101,12 @@ public:
sendMidiAllNotesOff(); sendMidiAllNotesOff();


allNotesOffSent = true; allNotesOffSent = true;

#ifdef FLUIDSYNTH_VERSION_NEW_API
fluid_synth_all_notes_off(fSynth, event.channel);
#else
fluid_synth_cc(f_synth, event.channel, MIDI_CONTROL_ALL_NOTES_OFF, 0);
#endif
} }
break; break;
} }
@@ -1156,15 +1144,10 @@ public:
} }
else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status)) else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status))
{ {
const uint8_t note = midiEvent.data[1];
const uint8_t pressure = midiEvent.data[2];
//const uint8_t note = midiEvent.data[1];
//const uint8_t pressure = midiEvent.data[2];


// TODO, not in fluidsynth API?
continue;

// unused
(void)note;
(void)pressure;
// TODO, not in fluidsynth API
} }
else if (MIDI_IS_STATUS_CONTROL_CHANGE(status) && (fHints & PLUGIN_OPTION_SELF_AUTOMATION) != 0) else if (MIDI_IS_STATUS_CONTROL_CHANGE(status) && (fHints & PLUGIN_OPTION_SELF_AUTOMATION) != 0)
{ {
@@ -1186,8 +1169,6 @@ public:


fluid_synth_pitch_bend(fSynth, channel, (msb << 7) | lsb); fluid_synth_pitch_bend(fSynth, channel, (msb << 7) | lsb);
} }
else
continue;


break; break;
} }
@@ -1197,21 +1178,73 @@ public:
kData->postRtEvents.trySplice(); kData->postRtEvents.trySplice();


if (frames > timeOffset) if (frames > timeOffset)
{
if (kUses16Outs)
processSingle(outBuffer, frames - timeOffset, timeOffset);
else
fluid_synth_write_float(fSynth, frames - timeOffset, outBuffer[0] + timeOffset, 0, 1, outBuffer[1] + timeOffset, 0, 1);
}
processSingle(outBuffer, frames - timeOffset, timeOffset);


} // End of Event Input and Processing } // End of Event Input and Processing


CARLA_PROCESS_CONTINUE_CHECK; CARLA_PROCESS_CONTINUE_CHECK;


// --------------------------------------------------------------------------------------------------------
// Control Output

{
k = FluidSynthVoiceCount;
fParamBuffers[k] = fluid_synth_get_active_voice_count(fSynth);
kData->param.ranges[k].fixValue(fParamBuffers[k]);

if (kData->param.data[k].midiCC > 0)
{
double value = kData->param.ranges[k].normalizeValue(fParamBuffers[k]);
kData->event.portOut->writeControlEvent(0, kData->param.data[k].midiChannel, kEngineControlEventTypeParameter, kData->param.data[k].midiCC, value);
}

} // End of Control Output

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

kData->activeBefore = kData->active;
}

bool processSingle(float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)
{
uint32_t i, k;

// --------------------------------------------------------------------------------------------------------
// Try lock, silence otherwise

if (kData->engine->isOffline())
{
kData->mutex.lock();
}
else if (! kData->mutex.tryLock())
{
for (i=0; i < kData->audioOut.count; i++)
{
for (k=0; k < frames; k++)
outBuffer[i][k+timeOffset] = 0.0f;
}

return false;
}

// --------------------------------------------------------------------------------------------------------
// Fill plugin buffers and Run plugin

if (kUses16Outs)
{
for (i=0; i < kData->audioOut.count; i++)
carla_zeroFloat(fAudio16Buffers[i], frames);

fluid_synth_process(fSynth, frames, 0, nullptr, kData->audioOut.count, fAudio16Buffers);
}
else
fluid_synth_write_float(fSynth, frames, outBuffer[0] + timeOffset, 0, 1, outBuffer[1] + timeOffset, 0, 1);

// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Post-processing (volume and balance) // Post-processing (volume and balance)


{ {
// note - balance not possible with kUses16Outs, so we can safely skip fAudioOutBuffers
const bool doVolume = (fHints & PLUGIN_CAN_VOLUME) > 0 && kData->postProc.volume != 1.0f; const bool doVolume = (fHints & PLUGIN_CAN_VOLUME) > 0 && kData->postProc.volume != 1.0f;
const bool doBalance = (fHints & PLUGIN_CAN_BALANCE) > 0 && (kData->postProc.balanceLeft != -1.0f || kData->postProc.balanceRight != 1.0f); const bool doBalance = (fHints & PLUGIN_CAN_BALANCE) > 0 && (kData->postProc.balanceLeft != -1.0f || kData->postProc.balanceRight != 1.0f);


@@ -1246,7 +1279,12 @@ public:
} }


// Volume // Volume
if (doVolume)
if (kUses16Outs)
{
for (k=0; k < frames; k++)
outBuffer[i][k+timeOffset] = fAudio16Buffers[i][k] * kData->postProc.volume;
}
else if (doVolume)
{ {
for (k=0; k < frames; k++) for (k=0; k < frames; k++)
outBuffer[i][k] *= kData->postProc.volume; outBuffer[i][k] *= kData->postProc.volume;
@@ -1255,41 +1293,10 @@ public:


} // End of Post-processing } // End of Post-processing


CARLA_PROCESS_CONTINUE_CHECK;

// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Control Output


{
k = FluidSynthVoiceCount;
fParamBuffers[k] = fluid_synth_get_active_voice_count(fSynth);
kData->param.ranges[k].fixValue(fParamBuffers[k]);

if (kData->param.data[k].midiCC > 0)
{
double value = kData->param.ranges[k].normalizeValue(fParamBuffers[k]);
kData->event.portOut->writeControlEvent(0, kData->param.data[k].midiChannel, kEngineControlEventTypeParameter, kData->param.data[k].midiCC, value);
}

} // End of Control Output

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

kData->activeBefore = kData->active;
}

void processSingle(float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)
{
for (uint32_t i=0; i < kData->audioOut.count; i++)
carla_zeroFloat(fAudio16Buffers[i], frames);

fluid_synth_process(fSynth, frames, 0, nullptr, kData->audioOut.count, fAudio16Buffers);

for (uint32_t i=0, k; i < kData->audioOut.count; i++)
{
for (k=0; k < frames; k++)
outBuffer[i][k+timeOffset] = fAudio16Buffers[i][k];
}
kData->mutex.unlock();
return true;
} }


void bufferSizeChanged(const uint32_t newBufferSize) void bufferSizeChanged(const uint32_t newBufferSize)
@@ -1407,8 +1414,6 @@ private:
double fParamBuffers[FluidSynthParametersMax]; double fParamBuffers[FluidSynthParametersMax];
}; };


/**@}*/

CARLA_BACKEND_END_NAMESPACE CARLA_BACKEND_END_NAMESPACE


#else // WANT_FLUIDSYNTH #else // WANT_FLUIDSYNTH


+ 1
- 1
source/backend/plugin/LadspaPlugin.cpp View File

@@ -926,7 +926,7 @@ public:


if (kData->param.data[k].hints & PARAMETER_IS_BOOLEAN) if (kData->param.data[k].hints & PARAMETER_IS_BOOLEAN)
{ {
value = (ctrlEvent.value < 0.5) ? kData->param.ranges[k].min : kData->param.ranges[k].max;
value = (ctrlEvent.value < 0.5f) ? kData->param.ranges[k].min : kData->param.ranges[k].max;
} }
else else
{ {


+ 33
- 11
source/backend/plugin/LinuxSamplerPlugin.cpp View File

@@ -248,6 +248,34 @@ public:
std::strncpy(strBuf, (const char*)fRealName, STR_MAX); std::strncpy(strBuf, (const char*)fRealName, STR_MAX);
} }


// -------------------------------------------------------------------
// Set data (plugin-specific stuff)

void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback)
{
CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(kData->midiprog.count));

if (index < -1)
index = -1;
else if (index > static_cast<int32_t>(kData->midiprog.count))
return;

if (kData->ctrlChannel < 0 || kData->ctrlChannel >= 16)
return;

if (index >= 0)
{
// TODO
//const uint32_t bank = kData->midiprog.data[index].bank;
//const uint32_t program = kData->midiprog.data[index].program;

//const ScopedProcessLocker spl(this);
//fluid_synth_program_select(fSynth, kData->ctrlChannel, fSynthId, bank, program);
}

CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback);
}

// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Plugin state // Plugin state


@@ -262,9 +290,6 @@ public:
// Safely disable plugin for reload // Safely disable plugin for reload
const ScopedDisabler sd(this); const ScopedDisabler sd(this);


if (kData->client->isActive())
kData->client->deactivate();

deleteBuffers(); deleteBuffers();


uint32_t aOuts; uint32_t aOuts;
@@ -350,8 +375,6 @@ public:
bufferSizeChanged(kData->engine->getBufferSize()); bufferSizeChanged(kData->engine->getBufferSize());
reloadPrograms(true); reloadPrograms(true);


kData->client->activate();

carla_debug("LinuxSamplerPlugin::reload() - end"); carla_debug("LinuxSamplerPlugin::reload() - end");
} }


@@ -396,7 +419,7 @@ public:


if (init) if (init)
{ {
setMidiProgram(0, false, false, false, true);
setMidiProgram(0, false, false, false);
} }
else else
{ {
@@ -598,19 +621,18 @@ public:


if (kData->param.data[k].hints & PARAMETER_IS_BOOLEAN) if (kData->param.data[k].hints & PARAMETER_IS_BOOLEAN)
{ {
value = (ctrlEvent.value < 0.5) ? kData->param.ranges[k].min : kData->param.ranges[k].max;
value = (ctrlEvent.value < 0.5f) ? kData->param.ranges[k].min : kData->param.ranges[k].max;
} }
else else
{ {
// FIXME - ranges call for this
value = ctrlEvent.value * (kData->param.ranges[k].max - kData->param.ranges[k].min) + kData->param.ranges[k].min;
value = kData->param.ranges[i].unnormalizeValue(ctrlEvent.value);


if (kData->param.data[k].hints & PARAMETER_IS_INTEGER) if (kData->param.data[k].hints & PARAMETER_IS_INTEGER)
value = std::rint(value); value = std::rint(value);
} }


setParameterValue(k, value, false, false, false); setParameterValue(k, value, false, false, false);
postponeRtEvent(kPluginPostRtEventParameterChange, k, 0, value);
postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value);
} }


break; break;
@@ -630,7 +652,7 @@ public:
{ {
if (kData->midiprog.data[k].bank == nextBankId && kData->midiprog.data[k].program == nextProgramId) if (kData->midiprog.data[k].bank == nextBankId && kData->midiprog.data[k].program == nextProgramId)
{ {
setMidiProgram(k, false, false, false, false);
setMidiProgram(k, false, false, false);
postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0); postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0);
break; break;
} }


+ 0
- 5
source/backend/plugin/Lv2Plugin.cpp View File

@@ -1128,9 +1128,6 @@ public:
// Safely disable plugin for reload // Safely disable plugin for reload
const ScopedDisabler m(this); const ScopedDisabler m(this);


if (x_client->isActive())
x_client->deactivate();

// Remove client ports // Remove client ports
removeClientPorts(); removeClientPorts();


@@ -1822,8 +1819,6 @@ public:


reloadPrograms(true); reloadPrograms(true);


x_client->activate();

carla_debug("Lv2Plugin::reload() - end"); carla_debug("Lv2Plugin::reload() - end");
} }




+ 12
- 29
source/backend/plugin/NativePlugin.cpp View File

@@ -414,7 +414,7 @@ public:
CarlaPlugin::setCustomData(type, key, value, sendGui); CarlaPlugin::setCustomData(type, key, value, sendGui);
} }


void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block)
void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback)
{ {
CARLA_ASSERT(fDescriptor != nullptr); CARLA_ASSERT(fDescriptor != nullptr);
CARLA_ASSERT(fHandle != nullptr); CARLA_ASSERT(fHandle != nullptr);
@@ -425,31 +425,20 @@ public:
else if (index > static_cast<int32_t>(kData->midiprog.count)) else if (index > static_cast<int32_t>(kData->midiprog.count))
return; return;


// FIXME
if (fDescriptor != nullptr && fHandle != nullptr && index >= 0) if (fDescriptor != nullptr && fHandle != nullptr && index >= 0)
{ {
const uint32_t bank = kData->midiprog.data[index].bank; const uint32_t bank = kData->midiprog.data[index].bank;
const uint32_t program = kData->midiprog.data[index].program; const uint32_t program = kData->midiprog.data[index].program;


if (kData->engine->isOffline())
{
//const CarlaEngine::ScopedLocker m(x_engine, block);
fDescriptor->set_midi_program(fHandle, bank, program);
const ScopedProcessLocker spl(this, (sendGui || sendOsc || sendCallback));


if (fHandle2 != nullptr)
fDescriptor->set_midi_program(fHandle2, bank, program);
}
else
{
//const ScopedDisabler m(this, block);
fDescriptor->set_midi_program(fHandle, bank, program);
fDescriptor->set_midi_program(fHandle, bank, program);


if (fHandle2 != nullptr)
fDescriptor->set_midi_program(fHandle2, bank, program);
}
if (fHandle2 != nullptr)
fDescriptor->set_midi_program(fHandle2, bank, program);
} }


CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback, block);
CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback);
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -500,9 +489,6 @@ public:
// Safely disable plugin for reload // Safely disable plugin for reload
const ScopedDisabler sd(this); const ScopedDisabler sd(this);


if (kData->client->isActive())
kData->client->deactivate();

deleteBuffers(); deleteBuffers();


const double sampleRate = kData->engine->getSampleRate(); const double sampleRate = kData->engine->getSampleRate();
@@ -865,8 +851,6 @@ public:
bufferSizeChanged(kData->engine->getBufferSize()); bufferSizeChanged(kData->engine->getBufferSize());
reloadPrograms(true); reloadPrograms(true);


kData->client->activate();

carla_debug("NativePlugin::reload() - end"); carla_debug("NativePlugin::reload() - end");
} }


@@ -912,7 +896,7 @@ public:
if (init) if (init)
{ {
if (kData->midiprog.count > 0) if (kData->midiprog.count > 0)
setMidiProgram(0, false, false, false, true);
setMidiProgram(0, false, false, false);
} }
else else
{ {
@@ -947,7 +931,7 @@ public:
} }


if (programChanged) if (programChanged)
setMidiProgram(kData->midiprog.current, true, true, true, true);
setMidiProgram(kData->midiprog.current, true, true, true);
} }
} }


@@ -1195,19 +1179,18 @@ public:


if (kData->param.data[k].hints & PARAMETER_IS_BOOLEAN) if (kData->param.data[k].hints & PARAMETER_IS_BOOLEAN)
{ {
value = (ctrlEvent.value < 0.5) ? kData->param.ranges[k].min : kData->param.ranges[k].max;
value = (ctrlEvent.value < 0.5f) ? kData->param.ranges[k].min : kData->param.ranges[k].max;
} }
else else
{ {
// FIXME - ranges call for this
value = ctrlEvent.value * (kData->param.ranges[k].max - kData->param.ranges[k].min) + kData->param.ranges[k].min;
value = kData->param.ranges[i].unnormalizeValue(ctrlEvent.value);


if (kData->param.data[k].hints & PARAMETER_IS_INTEGER) if (kData->param.data[k].hints & PARAMETER_IS_INTEGER)
value = std::rint(value); value = std::rint(value);
} }


setParameterValue(k, value, false, false, false); setParameterValue(k, value, false, false, false);
postponeRtEvent(kPluginPostRtEventParameterChange, k, 0, value);
postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value);
} }


break; break;
@@ -1227,7 +1210,7 @@ public:
{ {
if (kData->midiprog.data[k].bank == nextBankId && kData->midiprog.data[k].program == nextProgramId) if (kData->midiprog.data[k].bank == nextBankId && kData->midiprog.data[k].program == nextProgramId)
{ {
setMidiProgram(k, false, false, false, false);
setMidiProgram(k, false, false, false);
postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0); postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0);
break; break;
} }


+ 0
- 5
source/backend/plugin/VstPlugin.cpp View File

@@ -480,9 +480,6 @@ public:
// Safely disable plugin for reload // Safely disable plugin for reload
const ScopedDisabler m(this); const ScopedDisabler m(this);


if (x_client->isActive())
x_client->deactivate();

// Remove client ports // Remove client ports
removeClientPorts(); removeClientPorts();


@@ -788,8 +785,6 @@ public:


reloadPrograms(true); reloadPrograms(true);


x_client->activate();

carla_debug("VstPlugin::reload() - end"); carla_debug("VstPlugin::reload() - end");
} }




+ 2
- 2
source/backend/standalone/CarlaStandalone.cpp View File

@@ -1429,7 +1429,7 @@ void carla_set_program(unsigned int pluginId, uint32_t programId)
if (CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId)) if (CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId))
{ {
if (programId < plugin->programCount()) if (programId < plugin->programCount())
return plugin->setProgram(static_cast<int32_t>(programId), true, true, false, true);
return plugin->setProgram(static_cast<int32_t>(programId), true, true, false);


carla_stderr2("carla_set_program(%i, %i) - programId out of bounds", pluginId, programId); carla_stderr2("carla_set_program(%i, %i) - programId out of bounds", pluginId, programId);
return; return;
@@ -1449,7 +1449,7 @@ void carla_set_midi_program(unsigned int pluginId, uint32_t midiProgramId)
if (CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId)) if (CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId))
{ {
if (midiProgramId < plugin->midiProgramCount()) if (midiProgramId < plugin->midiProgramCount())
return plugin->setMidiProgram(static_cast<int32_t>(midiProgramId), true, true, false, true);
return plugin->setMidiProgram(static_cast<int32_t>(midiProgramId), true, true, false);


carla_stderr2("carla_set_midi_program(%i, %i) - midiProgramId out of bounds", pluginId, midiProgramId); carla_stderr2("carla_set_midi_program(%i, %i) - midiProgramId out of bounds", pluginId, midiProgramId);
return; return;


+ 2
- 2
source/bridges/CarlaBridgePlugin.cpp View File

@@ -320,7 +320,7 @@ public:
CARLA_ASSERT(fPlugin != nullptr); CARLA_ASSERT(fPlugin != nullptr);


if (fPlugin != nullptr) if (fPlugin != nullptr)
fPlugin->setProgram(index, true, true, false, true);
fPlugin->setProgram(index, true, true, false);
} }


void setMidiProgram(const uint32_t index) void setMidiProgram(const uint32_t index)
@@ -329,7 +329,7 @@ public:
CARLA_ASSERT(fPlugin != nullptr); CARLA_ASSERT(fPlugin != nullptr);


if (fPlugin != nullptr) if (fPlugin != nullptr)
fPlugin->setMidiProgram(index, true, true, false, true);
fPlugin->setMidiProgram(index, true, true, false);
} }


void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo)


Loading…
Cancel
Save