@@ -2471,7 +2471,6 @@ void CarlaEngine::oscSend_bridge_set_chunk_data(const char* const chunkFile) con | |||
std::strcat(targetPath, "/bridge_set_chunk_data"); | |||
try_lo_send(pData->oscData->target, targetPath, "s", chunkFile); | |||
} | |||
#else | |||
void CarlaEngine::oscSend_control_add_plugin_start(const uint pluginId, const char* const pluginName) const noexcept | |||
{ | |||
@@ -277,7 +277,7 @@ public: | |||
} | |||
} | |||
while (fShmControl.isDataAvailable()) | |||
for (; fShmControl.isDataAvailable();) | |||
{ | |||
const PluginBridgeOpcode opcode(fShmControl.readOpcode()); | |||
@@ -416,8 +416,8 @@ public: | |||
} | |||
} | |||
if (jackbridge_sem_post(&fShmControl.data->runClient) != 0) | |||
pass(); //carla_stderr2("Could not post to semaphore"); | |||
if (! jackbridge_sem_post(&fShmControl.data->runClient)) | |||
carla_stderr2("Could not post to semaphore"); | |||
} | |||
fIsRunning = false; | |||
@@ -749,6 +749,7 @@ public: | |||
//jackbridge_set_latency_callback(client, carla_jack_latency_callback_plugin, plugin); | |||
jackbridge_set_process_callback(client, carla_jack_process_callback_plugin, plugin); | |||
jackbridge_on_shutdown(fClient, carla_jack_shutdown_callback_plugin, plugin); | |||
} | |||
#endif | |||
return new CarlaEngineJackClient(*this, client); | |||
@@ -810,6 +811,7 @@ public: | |||
jackbridge_set_process_callback(jclient, carla_jack_process_callback_plugin, plugin); | |||
//jackbridge_set_latency_callback(jclient, carla_jack_latency_callback_plugin, plugin); | |||
jackbridge_on_shutdown(jclient, carla_jack_shutdown_callback_plugin, plugin); | |||
client->fClient = jclient; | |||
} | |||
@@ -2058,6 +2060,19 @@ private: | |||
} | |||
} | |||
# endif | |||
static void carla_jack_shutdown_callback_plugin(void* arg) | |||
{ | |||
CarlaPlugin* const plugin((CarlaPlugin*)arg); | |||
if (plugin != nullptr) | |||
{ | |||
CarlaEngineJackClient* const engineClient((CarlaEngineJackClient*)plugin->getEngineClient()); | |||
CARLA_SAFE_ASSERT_RETURN(engineClient != nullptr,); | |||
engineClient->fClient = nullptr; | |||
} | |||
} | |||
#endif | |||
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJack) | |||
@@ -360,8 +360,8 @@ int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, cons | |||
return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeSetCustomData, argc, argv, types); | |||
if (std::strcmp(bmethod, "set_chunk_data") == 0) | |||
return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeSetChunkData, argc, argv, types); | |||
if (std::strcmp(bmethod, "update") == 0) | |||
return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeUpdate, argc, argv, types); | |||
if (std::strcmp(bmethod, "update_now") == 0) | |||
return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeUpdateNow, argc, argv, types); | |||
if (std::strcmp(bmethod, "error") == 0) | |||
return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeError, argc, argv, types); | |||
} | |||
@@ -204,13 +204,13 @@ struct BridgeControl : public RingBufferControl<StackPackedRingBuffer> { | |||
setRingBuffer(nullptr, false); | |||
} | |||
bool waitForServer() | |||
bool waitForServer(const int secs) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | |||
jackbridge_sem_post(&data->runServer); | |||
return jackbridge_sem_timedwait(&data->runClient, 5); | |||
return jackbridge_sem_timedwait(&data->runClient, secs); | |||
} | |||
void writeOpcode(const PluginBridgeOpcode opcode) noexcept | |||
@@ -243,6 +243,7 @@ public: | |||
fInitError(false), | |||
fSaved(false), | |||
fNeedsSemDestroy(false), | |||
fTimedOut(false), | |||
fParams(nullptr) | |||
{ | |||
carla_debug("BridgePlugin::BridgePlugin(%p, %i, %s, %s)", engine, id, BinaryType2Str(btype), PluginType2Str(ptype)); | |||
@@ -268,11 +269,11 @@ public: | |||
pData->active = false; | |||
} | |||
if (pData->osc.thread.isRunning()) | |||
if (pData->osc.thread.isRunning() && ! fTimedOut) | |||
{ | |||
fShmControl.writeOpcode(kPluginBridgeOpcodeQuit); | |||
fShmControl.commitWrite(); | |||
fShmControl.waitForServer(); | |||
fShmControl.waitForServer(3); | |||
} | |||
if (pData->osc.data.target != nullptr) | |||
@@ -282,7 +283,7 @@ public: | |||
} | |||
pData->osc.data.free(); | |||
pData->osc.thread.stop(6000); | |||
pData->osc.thread.stop(3000); | |||
if (fNeedsSemDestroy) | |||
{ | |||
@@ -708,9 +709,14 @@ public: | |||
fShmControl.writeFloat(1.0f); | |||
fShmControl.commitWrite(); | |||
bool timedOut = true; | |||
try { | |||
waitForServer(); | |||
timedOut = waitForServer(); | |||
} catch(...) {} | |||
if (! timedOut) | |||
fTimedOut = false; | |||
} | |||
void deactivate() noexcept override | |||
@@ -721,9 +727,14 @@ public: | |||
fShmControl.writeFloat(0.0f); | |||
fShmControl.commitWrite(); | |||
bool timedOut = true; | |||
try { | |||
waitForServer(); | |||
timedOut = waitForServer(); | |||
} catch(...) {} | |||
if (! timedOut) | |||
fTimedOut = false; | |||
} | |||
void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override | |||
@@ -731,7 +742,7 @@ public: | |||
// -------------------------------------------------------------------------------------------------------- | |||
// Check if active | |||
if (! pData->active) | |||
if (fTimedOut || ! pData->active) | |||
{ | |||
// disable any output sound | |||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | |||
@@ -1045,6 +1056,8 @@ public: | |||
// -------------------------------------------------------------------------------------------------------- | |||
// Reset audio buffers | |||
//std::memset(fShmAudioPool.data, 0, fShmAudioPool.size); | |||
for (uint32_t i=0; i < fInfo.aIns; ++i) | |||
FLOAT_COPY(fShmAudioPool.data + (i * frames), inBuffer[i], frames); | |||
@@ -1054,7 +1067,7 @@ public: | |||
fShmControl.writeOpcode(kPluginBridgeOpcodeProcess); | |||
fShmControl.commitWrite(); | |||
if (! waitForServer()) | |||
if (! waitForServer(2)) | |||
{ | |||
pData->singleMutex.unlock(); | |||
return true; | |||
@@ -1597,7 +1610,7 @@ public: | |||
break; | |||
} | |||
case kPluginBridgeUpdate: | |||
case kPluginBridgeUpdateNow: | |||
fInitiated = true; | |||
break; | |||
@@ -1796,6 +1809,7 @@ private: | |||
bool fInitError; | |||
bool fSaved; | |||
bool fNeedsSemDestroy; | |||
bool fTimedOut; | |||
CarlaString fBridgeBinary; | |||
@@ -1835,12 +1849,14 @@ private: | |||
waitForServer(); | |||
} | |||
bool waitForServer() | |||
bool waitForServer(const int secs = 5) | |||
{ | |||
if (! fShmControl.waitForServer()) | |||
CARLA_SAFE_ASSERT_RETURN(! fTimedOut, false); | |||
if (! fShmControl.waitForServer(secs)) | |||
{ | |||
carla_stderr("waitForServer() timeout"); | |||
pData->active = false; // TODO | |||
carla_stderr("waitForServer() timeout here"); | |||
fTimedOut = true; | |||
return false; | |||
} | |||
@@ -35,7 +35,7 @@ public: | |||
JucePlugin(CarlaEngine* const engine, const uint id) | |||
: CarlaPlugin(engine, id), | |||
fInstance(nullptr), | |||
fAudioBuffer(0, 0) | |||
fAudioBuffer(1, 0) | |||
{ | |||
carla_debug("JucePlugin::JucePlugin(%p, %i)", engine, id); | |||
@@ -457,7 +457,7 @@ public: | |||
// plugin hints | |||
pData->hints = 0x0; | |||
if (fDesc.category.compareIgnoreCase("synth")) | |||
if (fDesc.isInstrument) | |||
pData->hints |= PLUGIN_IS_SYNTH; | |||
if (fInstance->hasEditor()) | |||
@@ -668,24 +668,38 @@ public: | |||
return false; | |||
} | |||
#if 0 | |||
if (label == nullptr || label[0] == '\0') | |||
{ | |||
pData->engine->setLastError("null label"); | |||
return false; | |||
} | |||
#else | |||
(void)label; | |||
// --------------------------------------------------------------- | |||
// fix path for wine usage | |||
String jfilename(filename); | |||
#ifdef CARLA_OS_WIN | |||
if (jfilename.startsWith("/")) | |||
{ | |||
jfilename.replace("/", "\\"); | |||
jfilename = "Z:" + jfilename; | |||
} | |||
#endif | |||
//fDesc.name = fDesc.descriptiveName = label; | |||
//fDesc.pluginFormatName = "VST"; | |||
fDesc.uid = 0; | |||
fDesc.fileOrIdentifier = filename; | |||
fDesc.uid = 0; // TODO - set uid for shell plugins | |||
fDesc.fileOrIdentifier = jfilename; | |||
fInstance = fFormat.createInstanceFromDescription(fDesc, 44100, 512); | |||
// TODO - set uid for shell plugins | |||
if (fInstance == nullptr) | |||
{ | |||
pData->engine->setLastError("Plugin failed to initialize"); | |||
return false; | |||
} | |||
fInstance = fFormat.createInstanceFromDescription(fDesc, pData->engine->getSampleRate(), static_cast<int>(pData->engine->getBufferSize())); | |||
fInstance->fillInPluginDescription(fDesc); | |||
// --------------------------------------------------------------- | |||
@@ -443,7 +443,9 @@ endif | |||
ifeq ($(HAVE_JUCE),true) | |||
LIBS_NATIVE += \ | |||
../modules/juce_audio_basics.a \ | |||
../modules/juce_audio_processors.a \ | |||
../modules/juce_core.a \ | |||
../modules/juce_data_structures.a \ | |||
../modules/juce_events.a \ | |||
../modules/juce_data_structures.a \ | |||
../modules/juce_graphics.a \ | |||
@@ -503,6 +505,17 @@ LIBS_POSIX32 = \ | |||
../modules/lilv.posix32.a \ | |||
../modules/rtmempool.posix32.a | |||
ifeq ($(HAVE_JUCE),true) | |||
LIBS_POSIX32 += \ | |||
../modules/juce_audio_basics.posix32.a \ | |||
../modules/juce_audio_processors.posix32.a \ | |||
../modules/juce_core.posix32.a \ | |||
../modules/juce_data_structures.posix32.a \ | |||
../modules/juce_events.posix32.a \ | |||
../modules/juce_graphics.posix32.a \ | |||
../modules/juce_gui_basics.posix32.a | |||
endif | |||
carla-bridge-posix32: $(OBJS_POSIX32) $(LIBS_POSIX32) | |||
$(CXX) $(OBJS_POSIX32) -Wl,--start-group $(LIBS_POSIX32) -Wl,--end-group $(POSIX_LINK_FLAGS) $(POSIX_32BIT_FLAGS) -o $@ | |||
@@ -551,6 +564,17 @@ LIBS_POSIX64 = \ | |||
../modules/lilv.posix64.a \ | |||
../modules/rtmempool.posix64.a | |||
ifeq ($(HAVE_JUCE),true) | |||
LIBS_POSIX64 += \ | |||
../modules/juce_audio_basics.posix64.a \ | |||
../modules/juce_audio_processors.posix64.a \ | |||
../modules/juce_core.posix64.a \ | |||
../modules/juce_data_structures.posix64.a \ | |||
../modules/juce_events.posix64.a \ | |||
../modules/juce_graphics.posix64.a \ | |||
../modules/juce_gui_basics.posix64.a | |||
endif | |||
carla-bridge-posix64: $(OBJS_POSIX64) $(LIBS_POSIX64) | |||
$(CXX) $(OBJS_POSIX64) -Wl,--start-group $(LIBS_POSIX64) -Wl,--end-group $(POSIX_LINK_FLAGS) $(POSIX_64BIT_FLAGS) -o $@ | |||
@@ -658,8 +682,19 @@ LIBS_WIN64 = \ | |||
../modules/lilv.win64.a \ | |||
../modules/rtmempool.win64.a | |||
ifeq ($(HAVE_JUCE),true) | |||
LIBS_WIN64 += \ | |||
../modules/juce_audio_basics.win64.a \ | |||
../modules/juce_audio_processors.win64.a \ | |||
../modules/juce_core.win64.a \ | |||
../modules/juce_data_structures.win64.a \ | |||
../modules/juce_events.win64.a \ | |||
../modules/juce_graphics.win64.a \ | |||
../modules/juce_gui_basics.win64.a | |||
endif | |||
carla-bridge-win64.exe: $(OBJS_WIN64) $(LIBS_WIN64) ../modules/jackbridge-win64.dll | |||
$(CXX) $(OBJS_WIN64) -Wl,--start-group $(LIBS_WIN32) -Wl,--end-group $(WIN_LINK_FLAGS) $(WIN_64BIT_FLAGS) -ljackbridge-win64 -o $@ | |||
$(CXX) $(OBJS_WIN64) -Wl,--start-group $(LIBS_WIN64) -Wl,--end-group $(WIN_LINK_FLAGS) $(WIN_64BIT_FLAGS) -ljackbridge-win64 -o $@ | |||
%__win64.o: %.cpp | |||
$(CXX) $< $(WIN_BUILD_FLAGS) $(WIN_64BIT_FLAGS) -c -o $@ | |||
@@ -46,7 +46,7 @@ enum PluginBridgeInfoType { | |||
kPluginBridgeConfigure, // ss => key, value | |||
kPluginBridgeSetCustomData, // sss => type, key, value | |||
kPluginBridgeSetChunkData, // s => chunkFile | |||
kPluginBridgeUpdate, // | |||
kPluginBridgeUpdateNow, // | |||
kPluginBridgeError // | |||
}; | |||
@@ -138,8 +138,8 @@ const char* PluginBridgeInfoType2str(const PluginBridgeInfoType type) noexcept | |||
return "kPluginBridgeSetCustomData"; | |||
case kPluginBridgeSetChunkData: | |||
return "kPluginBridgeSetChunkData"; | |||
case kPluginBridgeUpdate: | |||
return "kPluginBridgeUpdate"; | |||
case kPluginBridgeUpdateNow: | |||
return "kPluginBridgeUpdateNow"; | |||
case kPluginBridgeError: | |||
return "kPluginBridgeError"; | |||
} | |||
@@ -259,9 +259,9 @@ void osc_send_bridge_update(const CarlaOscData& oscData, const char* const url) | |||
CARLA_SAFE_ASSERT_RETURN(url != nullptr && url[0] != '\0',); | |||
carla_debug("osc_send_bridge_update(path:\"%s\", \"%s\")", oscData.path, url); | |||
char targetPath[std::strlen(oscData.path)+15]; | |||
char targetPath[std::strlen(oscData.path)+19]; | |||
std::strcpy(targetPath, oscData.path); | |||
std::strcat(targetPath, "/bridge_update"); | |||
std::strcat(targetPath, "/bridge_update_now"); | |||
try_lo_send(oscData.target, targetPath, "s", url); | |||
} | |||