diff --git a/source/backend/CarlaPlugin.hpp b/source/backend/CarlaPlugin.hpp index bed67c827..bd4006097 100644 --- a/source/backend/CarlaPlugin.hpp +++ b/source/backend/CarlaPlugin.hpp @@ -597,7 +597,7 @@ public: * \param sendCallback Send message change to registered 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. @@ -611,13 +611,13 @@ public: * \param sendCallback Send message change to registered 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 * 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 @@ -847,6 +847,7 @@ protected: private: CarlaPlugin* const kPlugin; + CARLA_PREVENT_HEAP_ALLOCATION CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ScopedDisabler) }; @@ -856,12 +857,14 @@ protected: class ScopedProcessLocker { public: - ScopedProcessLocker(CarlaPlugin* const plugin); + ScopedProcessLocker(CarlaPlugin* const plugin, const bool block); ~ScopedProcessLocker(); private: CarlaPlugin* const kPlugin; + const bool kBlock; + CARLA_PREVENT_HEAP_ALLOCATION CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ScopedProcessLocker) }; diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index 829296aeb..529fb5f25 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -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 (! 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); } } diff --git a/source/backend/engine/CarlaEngineOsc.cpp b/source/backend/engine/CarlaEngineOsc.cpp index 308f94cd8..5e3f01435 100644 --- a/source/backend/engine/CarlaEngineOsc.cpp +++ b/source/backend/engine/CarlaEngineOsc.cpp @@ -499,7 +499,7 @@ int CarlaEngineOsc::handleMsgProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2) if (program < 0) return 1; - plugin->setMidiProgramById(static_cast(bank), static_cast(program), false, true, true, true); + plugin->setMidiProgramById(static_cast(bank), static_cast(program), false, true, true); return 0; } @@ -516,7 +516,7 @@ int CarlaEngineOsc::handleMsgProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2) if (program < static_cast(plugin->programCount())) { - plugin->setProgram(program, false, true, true, true); + plugin->setProgram(program, false, true, true); return 0; } @@ -728,7 +728,7 @@ int CarlaEngineOsc::handleMsgSetProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2) const int32_t index = argv[0]->i; - plugin->setProgram(index, true, false, true, true); + plugin->setProgram(index, true, false, true); return 0; } @@ -740,7 +740,7 @@ int CarlaEngineOsc::handleMsgSetMidiProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2) const int32_t index = argv[0]->i; - plugin->setMidiProgram(index, true, false, true, true); + plugin->setMidiProgram(index, true, false, true); return 0; } diff --git a/source/backend/plugin/CarlaPlugin.cpp b/source/backend/plugin/CarlaPlugin.cpp index 169d07603..6351d2b38 100644 --- a/source/backend/plugin/CarlaPlugin.cpp +++ b/source/backend/plugin/CarlaPlugin.cpp @@ -762,7 +762,7 @@ void CarlaPlugin::setChunkData(const char* const 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(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); } -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(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); } -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++) { 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) : kPlugin(plugin) { + carla_debug("CarlaPlugin::ScopedDisabler(%p)", plugin); + CARLA_ASSERT(plugin != nullptr); + if (plugin->fEnabled) { plugin->fEnabled = false; @@ -1476,6 +1479,8 @@ CarlaPlugin::ScopedDisabler::ScopedDisabler(CarlaPlugin* const plugin) CarlaPlugin::ScopedDisabler::~ScopedDisabler() { + carla_debug("CarlaPlugin::~ScopedDisabler()"); + kPlugin->fEnabled = true; kPlugin->kData->client->activate(); } @@ -1483,16 +1488,26 @@ CarlaPlugin::ScopedDisabler::~ScopedDisabler() // ------------------------------------------------------------------- // 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() { - kPlugin->kData->needsReset = true; - kPlugin->kData->mutex.unlock(); + carla_debug("CarlaPlugin::~ScopedProcessLocker()"); + + if (kBlock) + { + kPlugin->kData->needsReset = true; + kPlugin->kData->mutex.unlock(); + } } // ------------------------------------------------------------------- diff --git a/source/backend/plugin/DssiPlugin.cpp b/source/backend/plugin/DssiPlugin.cpp index fb11a6637..515b3a5ed 100644 --- a/source/backend/plugin/DssiPlugin.cpp +++ b/source/backend/plugin/DssiPlugin.cpp @@ -233,7 +233,7 @@ public: if (fDssiDescriptor->configure != nullptr) { - const ScopedProcessLocker spl(this); + const ScopedProcessLocker spl(this, true); fDssiDescriptor->configure(fHandle, key, value); @@ -269,11 +269,11 @@ public: fChunk = QByteArray::fromBase64(QByteArray(stringData)); //fChunk.toBase64(); - const ScopedProcessLocker spl(this); + const ScopedProcessLocker spl(this, true); 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(fHandle != nullptr); @@ -289,7 +289,7 @@ public: const uint32_t bank = kData->midiprog.data[index].bank; 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); @@ -297,7 +297,7 @@ public: 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 (kData->midiprog.count > 0) - setMidiProgram(0, false, false, false, true); + setMidiProgram(0, false, false, false); } else { @@ -853,7 +853,7 @@ public: } 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) { - 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 { @@ -1127,7 +1127,7 @@ public: { 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); break; } diff --git a/source/backend/plugin/FluidSynthPlugin.cpp b/source/backend/plugin/FluidSynthPlugin.cpp index c77e39929..a27255ea1 100644 --- a/source/backend/plugin/FluidSynthPlugin.cpp +++ b/source/backend/plugin/FluidSynthPlugin.cpp @@ -297,67 +297,54 @@ public: const float fixedValue = kData->param.fixValue(parameterId, value); 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); } - 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(kData->midiprog.count)); if (index < -1) @@ -368,25 +355,16 @@ public: if (kData->ctrlChannel < 0 || kData->ctrlChannel >= 16) return; - // FIXME if (index >= 0) { const uint32_t bank = kData->midiprog.data[index].bank; 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 const ScopedDisabler sd(this); - if (kData->client->isActive()) - kData->client->deactivate(); - deleteBuffers(); uint32_t aOuts, params, j; @@ -771,8 +746,6 @@ public: bufferSizeChanged(kData->engine->getBufferSize()); reloadPrograms(true); - kData->client->activate(); - carla_debug("FluidSynthPlugin::reload() - end"); } @@ -862,7 +835,7 @@ public: #endif } - setMidiProgram(0, false, false, false, true); + setMidiProgram(0, false, false, false); } else { @@ -891,7 +864,7 @@ public: } // -------------------------------------------------------------------------------------------------------- - // Check if active before + // Check if not active before if (kData->needsReset || ! kData->activeBefore) { @@ -941,6 +914,7 @@ public: bool allNotesOffSent = false; uint32_t time, nEvents = kData->event.portIn->getEventCount(); + uint32_t startTime = 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 }; @@ -961,12 +935,15 @@ public: 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 @@ -989,7 +966,7 @@ public: // Control backend stuff if (event.channel == kData->ctrlChannel) { - double value; + float value; 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) { - value = ctrlEvent.value*127/100; + value = ctrlEvent.value*127.0f/100.0f; setVolume(value, false, false); postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value); continue; @@ -1009,23 +986,23 @@ public: 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 { - left = -1.0; - right = 1.0; + left = -1.0f; + right = 1.0f; } setBalanceLeft(left, false, false); @@ -1048,23 +1025,22 @@ public: if ((kData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0) continue; - double value; + float value; 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 { - // 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) value = std::rint(value); } setParameterValue(k, value, false, false, false); - postponeRtEvent(kPluginPostRtEventParameterChange, k, 0, value); + postponeRtEvent(kPluginPostRtEventParameterChange, static_cast(k), 0, value); } break; @@ -1087,7 +1063,7 @@ public: { if (event.channel == kData->ctrlChannel) { - setMidiProgram(k, false, false, false, false); + setMidiProgram(k, false, false, false); postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0); } else @@ -1109,6 +1085,12 @@ public: postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 1.0); 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; @@ -1119,6 +1101,12 @@ public: sendMidiAllNotesOff(); 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; } @@ -1156,15 +1144,10 @@ public: } 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) { @@ -1186,8 +1169,6 @@ public: fluid_synth_pitch_bend(fSynth, channel, (msb << 7) | lsb); } - else - continue; break; } @@ -1197,21 +1178,73 @@ public: kData->postRtEvents.trySplice(); 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 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) { + // 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 doBalance = (fHints & PLUGIN_CAN_BALANCE) > 0 && (kData->postProc.balanceLeft != -1.0f || kData->postProc.balanceRight != 1.0f); @@ -1246,7 +1279,12 @@ public: } // 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++) outBuffer[i][k] *= kData->postProc.volume; @@ -1255,41 +1293,10 @@ public: } // 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) @@ -1407,8 +1414,6 @@ private: double fParamBuffers[FluidSynthParametersMax]; }; -/**@}*/ - CARLA_BACKEND_END_NAMESPACE #else // WANT_FLUIDSYNTH diff --git a/source/backend/plugin/LadspaPlugin.cpp b/source/backend/plugin/LadspaPlugin.cpp index 6582d47d7..303f1fcb4 100644 --- a/source/backend/plugin/LadspaPlugin.cpp +++ b/source/backend/plugin/LadspaPlugin.cpp @@ -926,7 +926,7 @@ public: 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 { diff --git a/source/backend/plugin/LinuxSamplerPlugin.cpp b/source/backend/plugin/LinuxSamplerPlugin.cpp index 8ce16a871..1dcdd80ad 100644 --- a/source/backend/plugin/LinuxSamplerPlugin.cpp +++ b/source/backend/plugin/LinuxSamplerPlugin.cpp @@ -248,6 +248,34 @@ public: 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(kData->midiprog.count)); + + if (index < -1) + index = -1; + else if (index > static_cast(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 @@ -262,9 +290,6 @@ public: // Safely disable plugin for reload const ScopedDisabler sd(this); - if (kData->client->isActive()) - kData->client->deactivate(); - deleteBuffers(); uint32_t aOuts; @@ -350,8 +375,6 @@ public: bufferSizeChanged(kData->engine->getBufferSize()); reloadPrograms(true); - kData->client->activate(); - carla_debug("LinuxSamplerPlugin::reload() - end"); } @@ -396,7 +419,7 @@ public: if (init) { - setMidiProgram(0, false, false, false, true); + setMidiProgram(0, false, false, false); } else { @@ -598,19 +621,18 @@ public: 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 { - // 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) value = std::rint(value); } setParameterValue(k, value, false, false, false); - postponeRtEvent(kPluginPostRtEventParameterChange, k, 0, value); + postponeRtEvent(kPluginPostRtEventParameterChange, static_cast(k), 0, value); } break; @@ -630,7 +652,7 @@ public: { 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); break; } diff --git a/source/backend/plugin/Lv2Plugin.cpp b/source/backend/plugin/Lv2Plugin.cpp index 0f50d78ea..6664733e8 100644 --- a/source/backend/plugin/Lv2Plugin.cpp +++ b/source/backend/plugin/Lv2Plugin.cpp @@ -1128,9 +1128,6 @@ public: // Safely disable plugin for reload const ScopedDisabler m(this); - if (x_client->isActive()) - x_client->deactivate(); - // Remove client ports removeClientPorts(); @@ -1822,8 +1819,6 @@ public: reloadPrograms(true); - x_client->activate(); - carla_debug("Lv2Plugin::reload() - end"); } diff --git a/source/backend/plugin/NativePlugin.cpp b/source/backend/plugin/NativePlugin.cpp index 8adca370f..f164f77dd 100644 --- a/source/backend/plugin/NativePlugin.cpp +++ b/source/backend/plugin/NativePlugin.cpp @@ -414,7 +414,7 @@ public: 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(fHandle != nullptr); @@ -425,31 +425,20 @@ public: else if (index > static_cast(kData->midiprog.count)) return; - // FIXME if (fDescriptor != nullptr && fHandle != nullptr && index >= 0) { const uint32_t bank = kData->midiprog.data[index].bank; 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 const ScopedDisabler sd(this); - if (kData->client->isActive()) - kData->client->deactivate(); - deleteBuffers(); const double sampleRate = kData->engine->getSampleRate(); @@ -865,8 +851,6 @@ public: bufferSizeChanged(kData->engine->getBufferSize()); reloadPrograms(true); - kData->client->activate(); - carla_debug("NativePlugin::reload() - end"); } @@ -912,7 +896,7 @@ public: if (init) { if (kData->midiprog.count > 0) - setMidiProgram(0, false, false, false, true); + setMidiProgram(0, false, false, false); } else { @@ -947,7 +931,7 @@ public: } 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) { - 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 { - // 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) value = std::rint(value); } setParameterValue(k, value, false, false, false); - postponeRtEvent(kPluginPostRtEventParameterChange, k, 0, value); + postponeRtEvent(kPluginPostRtEventParameterChange, static_cast(k), 0, value); } break; @@ -1227,7 +1210,7 @@ public: { 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); break; } diff --git a/source/backend/plugin/VstPlugin.cpp b/source/backend/plugin/VstPlugin.cpp index c071f106e..ccf5c25d5 100644 --- a/source/backend/plugin/VstPlugin.cpp +++ b/source/backend/plugin/VstPlugin.cpp @@ -480,9 +480,6 @@ public: // Safely disable plugin for reload const ScopedDisabler m(this); - if (x_client->isActive()) - x_client->deactivate(); - // Remove client ports removeClientPorts(); @@ -788,8 +785,6 @@ public: reloadPrograms(true); - x_client->activate(); - carla_debug("VstPlugin::reload() - end"); } diff --git a/source/backend/standalone/CarlaStandalone.cpp b/source/backend/standalone/CarlaStandalone.cpp index e91e77b92..d23c46071 100644 --- a/source/backend/standalone/CarlaStandalone.cpp +++ b/source/backend/standalone/CarlaStandalone.cpp @@ -1429,7 +1429,7 @@ void carla_set_program(unsigned int pluginId, uint32_t programId) if (CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId)) { if (programId < plugin->programCount()) - return plugin->setProgram(static_cast(programId), true, true, false, true); + return plugin->setProgram(static_cast(programId), true, true, false); carla_stderr2("carla_set_program(%i, %i) - programId out of bounds", pluginId, programId); 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 (midiProgramId < plugin->midiProgramCount()) - return plugin->setMidiProgram(static_cast(midiProgramId), true, true, false, true); + return plugin->setMidiProgram(static_cast(midiProgramId), true, true, false); carla_stderr2("carla_set_midi_program(%i, %i) - midiProgramId out of bounds", pluginId, midiProgramId); return; diff --git a/source/bridges/CarlaBridgePlugin.cpp b/source/bridges/CarlaBridgePlugin.cpp index bae6f1e4a..6cb7fa8e6 100644 --- a/source/bridges/CarlaBridgePlugin.cpp +++ b/source/bridges/CarlaBridgePlugin.cpp @@ -320,7 +320,7 @@ public: CARLA_ASSERT(fPlugin != nullptr); if (fPlugin != nullptr) - fPlugin->setProgram(index, true, true, false, true); + fPlugin->setProgram(index, true, true, false); } void setMidiProgram(const uint32_t index) @@ -329,7 +329,7 @@ public: CARLA_ASSERT(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)