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