| @@ -1775,7 +1775,7 @@ void CarlaEngine::saveProjectInternal(juce::MemoryOutputStream& outStream) const | |||
| // if we're running inside some session-manager (and using JACK), let them handle the connections | |||
| bool saveExternalConnections; | |||
| /**/ if (std::strcmp(getCurrentDriverName(), "Plugin") == 0) | |||
| /**/ if (isPlugin) | |||
| saveExternalConnections = false; | |||
| else if (std::strcmp(getCurrentDriverName(), "JACK") != 0) | |||
| saveExternalConnections = true; | |||
| @@ -1966,15 +1966,15 @@ bool CarlaEngine::loadProjectInternal(juce::XmlDocument& xmlDoc) | |||
| const void* extraStuff = nullptr; | |||
| // check if using GIG or SF2 16outs | |||
| static const char kTrue[] = "true"; | |||
| static const char kUse16OutsSuffix[] = " (16 outs)"; | |||
| const BinaryType btype(getBinaryTypeFromFile(stateSave.binary)); | |||
| const PluginType ptype(getPluginTypeFromString(stateSave.type)); | |||
| if (CarlaString(stateSave.label).endsWith(kUse16OutsSuffix)) | |||
| if ((ptype == PLUGIN_GIG || ptype == PLUGIN_SF2) && CarlaString(stateSave.label).endsWith(kUse16OutsSuffix)) | |||
| { | |||
| if (ptype == PLUGIN_GIG || ptype == PLUGIN_SF2) | |||
| extraStuff = "true"; | |||
| extraStuff = kTrue; | |||
| } | |||
| // TODO - proper find&load plugins | |||
| @@ -1983,6 +1983,8 @@ bool CarlaEngine::loadProjectInternal(juce::XmlDocument& xmlDoc) | |||
| { | |||
| if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1)) | |||
| { | |||
| callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr); | |||
| #ifndef BUILD_BRIDGE | |||
| // deactivate bridge client-side ping check, since some plugins block during load | |||
| if ((plugin->getHints() & PLUGIN_IS_BRIDGE) != 0 && ! isPreset) | |||
| @@ -2053,14 +2055,14 @@ bool CarlaEngine::loadProjectInternal(juce::XmlDocument& xmlDoc) | |||
| } | |||
| break; | |||
| } | |||
| } | |||
| callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr); | |||
| callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr); | |||
| } | |||
| // if we're running inside some session-manager (and using JACK), let them handle the external connections | |||
| bool loadExternalConnections; | |||
| /**/ if (std::strcmp(getCurrentDriverName(), "Plugin") == 0) | |||
| /**/ if (isPlugin) | |||
| loadExternalConnections = false; | |||
| else if (std::strcmp(getCurrentDriverName(), "JACK") != 0) | |||
| loadExternalConnections = true; | |||
| @@ -1235,6 +1235,11 @@ protected: | |||
| break; | |||
| case kPluginBridgeRtClientSetAudioPool: { | |||
| if (fShmAudioPool.data != nullptr) | |||
| { | |||
| jackbridge_shm_unmap(fShmAudioPool.shm, fShmAudioPool.data); | |||
| fShmAudioPool.data = nullptr; | |||
| } | |||
| const uint64_t poolSize(fShmRtClientControl.readULong()); | |||
| CARLA_SAFE_ASSERT_BREAK(poolSize > 0); | |||
| fShmAudioPool.data = (float*)jackbridge_shm_map(fShmAudioPool.shm, static_cast<size_t>(poolSize)); | |||
| @@ -1169,6 +1169,16 @@ public: | |||
| return nullptr; | |||
| } | |||
| // before we stop the engine thread we might need to get the plugin data | |||
| const bool needsReinit = (pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS); | |||
| const CarlaStateSave* saveStatePtr = nullptr; | |||
| if (needsReinit) | |||
| { | |||
| const CarlaStateSave& saveState(plugin->getStateSave()); | |||
| saveStatePtr = &saveState; | |||
| } | |||
| const ScopedThreadStopper sts(this); | |||
| CARLA_SAFE_ASSERT(plugin->getId() == id); | |||
| @@ -1187,8 +1197,6 @@ public: | |||
| return nullptr; | |||
| } | |||
| bool needsReinit = false; | |||
| // rename on client client mode, just rename the ports | |||
| if (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT) | |||
| { | |||
| @@ -1222,8 +1230,6 @@ public: | |||
| jackbridge_set_latency_callback(jackClient, carla_jack_latency_callback_plugin, plugin); | |||
| jackbridge_set_process_callback(jackClient, carla_jack_process_callback_plugin, plugin); | |||
| jackbridge_on_shutdown(jackClient, carla_jack_shutdown_callback_plugin, plugin); | |||
| needsReinit = true; | |||
| } | |||
| else | |||
| { | |||
| @@ -1238,9 +1244,8 @@ public: | |||
| if (needsReinit) | |||
| { | |||
| // reload plugin to recreate its ports | |||
| const CarlaStateSave& saveState(plugin->getStateSave()); | |||
| plugin->reload(); | |||
| plugin->loadStateSave(saveState); | |||
| plugin->loadStateSave(*saveStatePtr); | |||
| } | |||
| return plugin->getName(); | |||
| @@ -1223,6 +1223,13 @@ public: | |||
| // Safely disable plugin for reload | |||
| const ScopedDisabler sd(this); | |||
| // cleanup of previous data | |||
| pData->audioIn.clear(); | |||
| pData->audioOut.clear(); | |||
| pData->cvIn.clear(); | |||
| pData->cvOut.clear(); | |||
| pData->event.clear(); | |||
| bool needsCtrlIn, needsCtrlOut; | |||
| needsCtrlIn = needsCtrlOut = false; | |||
| @@ -840,8 +840,6 @@ public: | |||
| #ifndef BUILD_BRIDGE | |||
| bool allNotesOffSent = false; | |||
| #endif | |||
| bool sampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFERS) == 0; | |||
| uint32_t startTime = 0; | |||
| uint32_t timeOffset = 0; | |||
| @@ -852,7 +850,7 @@ public: | |||
| CARLA_SAFE_ASSERT_CONTINUE(event.time < frames); | |||
| CARLA_SAFE_ASSERT_BREAK(event.time >= timeOffset); | |||
| if (event.time > timeOffset && sampleAccurate) | |||
| if (event.time > timeOffset) | |||
| { | |||
| if (processSingle(audioOut, event.time - timeOffset, timeOffset)) | |||
| { | |||
| @@ -960,7 +958,7 @@ public: | |||
| if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param < MAX_MIDI_CONTROL) | |||
| { | |||
| fMidiInputPort->DispatchControlChange(uint8_t(ctrlEvent.param), uint8_t(ctrlEvent.value*127.0f), event.channel, static_cast<int32_t>(sampleAccurate ? startTime : event.time)); | |||
| fMidiInputPort->DispatchControlChange(uint8_t(ctrlEvent.param), uint8_t(ctrlEvent.value*127.0f), event.channel, static_cast<int32_t>(startTime)); | |||
| } | |||
| break; | |||
| @@ -979,7 +977,7 @@ public: | |||
| case kEngineControlEventTypeAllSoundOff: | |||
| if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF) | |||
| { | |||
| fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_SOUND_OFF, 0, event.channel, static_cast<int32_t>(sampleAccurate ? startTime : event.time)); | |||
| fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_SOUND_OFF, 0, event.channel, static_cast<int32_t>(startTime)); | |||
| } | |||
| break; | |||
| @@ -994,7 +992,7 @@ public: | |||
| } | |||
| #endif | |||
| fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_NOTES_OFF, 0, event.channel, static_cast<int32_t>(sampleAccurate ? startTime : event.time)); | |||
| fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_NOTES_OFF, 0, event.channel, static_cast<int32_t>(startTime)); | |||
| } | |||
| break; | |||
| } | |||
| @@ -1026,7 +1024,7 @@ public: | |||
| midiData2[0] = uint8_t(status | (event.channel & MIDI_CHANNEL_BIT)); | |||
| std::memcpy(midiData2+1, midiData+1, static_cast<std::size_t>(midiEvent.size-1)); | |||
| fMidiInputPort->DispatchRaw(midiData2, static_cast<int32_t>(sampleAccurate ? startTime : event.time)); | |||
| fMidiInputPort->DispatchRaw(midiData2, static_cast<int32_t>(startTime)); | |||
| if (status == MIDI_STATUS_NOTE_ON) | |||
| pData->postponeRtEvent(kPluginPostRtEventNoteOn, event.channel, midiData[1], midiData[2]); | |||
| @@ -404,5 +404,6 @@ JACKBRIDGE_API void jackbridge_shm_init(void* shm) noexcept; | |||
| JACKBRIDGE_API void jackbridge_shm_attach(void* shm, const char* name) noexcept; | |||
| JACKBRIDGE_API void jackbridge_shm_close(void* shm) noexcept; | |||
| JACKBRIDGE_API void* jackbridge_shm_map(void* shm, uint64_t size) noexcept; | |||
| JACKBRIDGE_API void jackbridge_shm_unmap(void* shm, void* ptr) noexcept; | |||
| #endif // JACKBRIDGE_HPP_INCLUDED | |||
| @@ -114,4 +114,13 @@ void* jackbridge_shm_map(void* shm, uint64_t size) noexcept | |||
| #endif | |||
| } | |||
| void jackbridge_shm_unmap(void* shm, void* ptr) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(shm != nullptr,); | |||
| #ifndef JACKBRIDGE_DUMMY | |||
| return carla_shm_unmap(*(carla_shm_t*)shm, ptr); | |||
| #endif | |||
| } | |||
| // ----------------------------------------------------------------------------- | |||
| @@ -135,6 +135,7 @@ const JackBridgeExportedFunctions* JACKBRIDGE_API jackbridge_get_exported_functi | |||
| funcs.shm_attach_ptr = jackbridge_shm_attach; | |||
| funcs.shm_close_ptr = jackbridge_shm_close; | |||
| funcs.shm_map_ptr = jackbridge_shm_map; | |||
| funcs.shm_unmap_ptr = jackbridge_shm_unmap; | |||
| funcs.unique1 = funcs.unique2 = funcs.unique3 = 0xdeadf00d; | |||
| @@ -578,4 +578,9 @@ void* jackbridge_shm_map(void* shm, uint64_t size) noexcept | |||
| return getBridgeInstance().shm_map_ptr(shm, size); | |||
| } | |||
| void jackbridge_shm_unmap(void* shm, void* ptr) noexcept | |||
| { | |||
| return getBridgeInstance().shm_unmap_ptr(shm, ptr); | |||
| } | |||
| // ----------------------------------------------------------------------------- | |||
| @@ -118,6 +118,7 @@ typedef void (JACKBRIDGE_API *jackbridgesym_shm_init)(void*); | |||
| typedef void (JACKBRIDGE_API *jackbridgesym_shm_attach)(void*, const char*); | |||
| typedef void (JACKBRIDGE_API *jackbridgesym_shm_close)(void*); | |||
| typedef void* (JACKBRIDGE_API *jackbridgesym_shm_map)(void*, uint64_t); | |||
| typedef void (JACKBRIDGE_API *jackbridgesym_shm_unmap)(void*, void*); | |||
| // ----------------------------------------------------------------------------- | |||
| @@ -222,6 +223,7 @@ struct _JackBridgeExportedFunctions { | |||
| jackbridgesym_shm_attach shm_attach_ptr; | |||
| jackbridgesym_shm_close shm_close_ptr; | |||
| jackbridgesym_shm_map shm_map_ptr; | |||
| jackbridgesym_shm_unmap shm_unmap_ptr; | |||
| ulong unique3; | |||
| }; | |||