Browse Source

Make some plugin OSC stuff DSSI specific; Cleanup

tags/1.9.6
falkTX 10 years ago
parent
commit
ee4bfb73f1
5 changed files with 217 additions and 265 deletions
  1. +2
    -19
      source/backend/CarlaPlugin.hpp
  2. +4
    -0
      source/backend/engine/CarlaEngine.cpp
  3. +4
    -112
      source/backend/plugin/CarlaPlugin.cpp
  4. +207
    -120
      source/backend/plugin/CarlaPluginDSSI.cpp
  5. +0
    -14
      source/utils/CarlaOscUtils.hpp

+ 2
- 19
source/backend/CarlaPlugin.hpp View File

@@ -718,26 +718,9 @@ public:
/*!
* Update the plugin's internal OSC data according to @a source and @a url.
* This is used for OSC-GUI bridges.
* TODO remove
*/
void updateOscData(const lo_address& source, const char* const url);

/*!
* Update the plugin's extra OSC data, called from the start of updateOscData().
* The default implementation does nothing.
*/
virtual bool updateOscDataExtra();

/*!
* Update the plugin's OSC URL used in UI bridges.
* This is called when removing or switching plugins.
*/
virtual void updateOscURL();

/*!
* Show the plugin's OSC based GUI.
* This is a handy function that waits for the GUI to respond and automatically asks it to show itself.
*/
bool waitForOscGuiShow();
virtual void updateOscData(const lo_address& source, const char* const url);

#ifndef BUILD_BRIDGE
// -------------------------------------------------------------------


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

@@ -593,12 +593,14 @@ bool CarlaEngine::removePlugin(const uint id)
const bool lockWait(isRunning() /*&& pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS*/);
const ScopedActionLock sal(pData, kEnginePostActionRemovePlugin, id, 0, lockWait);

/*
for (uint i=id; i < pData->curPluginCount; ++i)
{
CarlaPlugin* const plugin2(pData->plugins[i].plugin);
CARLA_SAFE_ASSERT_BREAK(plugin2 != nullptr);
plugin2->updateOscURL();
}
*/

if (isOscControlRegistered())
oscSend_control_remove_plugin(id);
@@ -778,6 +780,7 @@ bool CarlaEngine::switchPlugins(const uint idA, const uint idB) noexcept
const bool lockWait(isRunning() /*&& pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS*/);
const ScopedActionLock sal(pData, kEnginePostActionSwitchPlugins, idA, idB, lockWait);

/*
CarlaPlugin* const pluginA(pData->plugins[idA].plugin);
CarlaPlugin* const pluginB(pData->plugins[idB].plugin);

@@ -786,6 +789,7 @@ bool CarlaEngine::switchPlugins(const uint idA, const uint idB) noexcept
pluginA->updateOscURL();
pluginB->updateOscURL();
}
*/

// TODO
//if (isOscControlRegistered())


+ 4
- 112
source/backend/plugin/CarlaPlugin.cpp View File

@@ -1361,13 +1361,9 @@ void CarlaPlugin::idle()
pData->transientTryCounter = 0;
}

void CarlaPlugin::showCustomUI(const bool yesNo)
void CarlaPlugin::showCustomUI(const bool)
{
CARLA_SAFE_ASSERT(false);
return;

// unused
(void)yesNo;
}

// -------------------------------------------------------------------
@@ -1586,114 +1582,10 @@ void CarlaPlugin::registerToOscClient() noexcept
#endif
}

void CarlaPlugin::updateOscData(const lo_address& source, const char* const url)
void CarlaPlugin::updateOscData(const lo_address&, const char* const)
{
// FIXME - remove debug prints later
carla_stdout("CarlaPlugin::updateOscData(%p, \"%s\")", source, url);

pData->oscData.clear();

const int proto = lo_address_get_protocol(source);

{
const char* host = lo_address_get_hostname(source);
const char* port = lo_address_get_port(source);
pData->oscData.source = lo_address_new_with_proto(proto, host, port);

carla_stdout("CarlaPlugin::updateOscData() - source: host \"%s\", port \"%s\"", host, port);
}

{
char* host = lo_url_get_hostname(url);
char* port = lo_url_get_port(url);
pData->oscData.path = carla_strdup_free(lo_url_get_path(url));
pData->oscData.target = lo_address_new_with_proto(proto, host, port);
carla_stdout("CarlaPlugin::updateOscData() - target: host \"%s\", port \"%s\", path \"%s\"", host, port, pData->oscData.path);

std::free(host);
std::free(port);
}

#ifndef BUILD_BRIDGE
if (pData->hints & PLUGIN_IS_BRIDGE)
{
carla_stdout("CarlaPlugin::updateOscData() - done");
return;
}
#endif

// send possible extra data first
if (updateOscDataExtra())
pData->engine->idleOsc();

osc_send_sample_rate(pData->oscData, static_cast<float>(pData->engine->getSampleRate()));

for (LinkedList<CustomData>::Itenerator it = pData->custom.begin(); it.valid(); it.next())
{
const CustomData& customData(it.getValue(kCustomDataFallback));
CARLA_SAFE_ASSERT_CONTINUE(customData.isValid());

if (std::strcmp(customData.type, CUSTOM_DATA_TYPE_STRING) == 0)
osc_send_configure(pData->oscData, customData.key, customData.value);
}

if (pData->prog.current >= 0)
osc_send_program(pData->oscData, static_cast<uint32_t>(pData->prog.current));

if (pData->midiprog.current >= 0)
{
const MidiProgramData& curMidiProg(pData->midiprog.getCurrent());

if (getType() == PLUGIN_DSSI)
osc_send_program(pData->oscData, curMidiProg.bank, curMidiProg.program);
else
osc_send_midi_program(pData->oscData, curMidiProg.bank, curMidiProg.program);
}

for (uint32_t i=0; i < pData->param.count; ++i)
osc_send_control(pData->oscData, pData->param.data[i].rindex, getParameterValue(i));

if ((pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0 && pData->engine->getOptions().frontendWinId != 0)
pData->transientTryCounter = 1;

carla_stdout("CarlaPlugin::updateOscData() - done");
}

bool CarlaPlugin::updateOscDataExtra()
{
return false;
}

void CarlaPlugin::updateOscURL()
{
const String newURL(String(pData->engine->getOscServerPathUDP()) + String("/") + String(pData->id));

osc_send_update_url(pData->oscData, newURL.toRawUTF8());
}

bool CarlaPlugin::waitForOscGuiShow()
{
carla_stdout("CarlaPlugin::waitForOscGuiShow()");
uint i=0, oscUiTimeout = pData->engine->getOptions().uiBridgesTimeout;

// wait for UI 'update' call
for (; i < oscUiTimeout/100; ++i)
{
if (pData->oscData.target != nullptr)
{
carla_stdout("CarlaPlugin::waitForOscGuiShow() - got response, asking UI to show itself now");
osc_send_show(pData->oscData);
return true;
}

if (pData->childProcess != nullptr && pData->childProcess->isRunning())
carla_msleep(100);
else
return false;
}

carla_stdout("CarlaPlugin::waitForOscGuiShow() - Timeout while waiting for UI to respond (waited %u msecs)", oscUiTimeout);
return false;
// should not happen
CARLA_SAFE_ASSERT(false);
}

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


+ 207
- 120
source/backend/plugin/CarlaPluginDSSI.cpp View File

@@ -30,12 +30,19 @@ using juce::StringArray;

CARLA_BACKEND_START_NAMESPACE

// -----------------------------------------------------
class CarlaPluginDSSI;

// -------------------------------------------------------------------
// Fallback data

static const CustomData kCustomDataFallback = { nullptr, nullptr, nullptr };

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

class CarlaThreadDSSIUI : public CarlaThread
{
public:
CarlaThreadDSSIUI(CarlaEngine* const engine, CarlaPlugin* const plugin, ScopedPointer<ChildProcess>& childProcess) noexcept
CarlaThreadDSSIUI(CarlaEngine* const engine, CarlaPluginDSSI* const plugin, ScopedPointer<ChildProcess>& childProcess) noexcept
: CarlaThread("CarlaThreadDSSIUI"),
kEngine(engine),
kPlugin(plugin),
@@ -64,113 +71,11 @@ public:
return (uintptr_t)fProcess->getPID();
}

void run()
{
if (fProcess == nullptr)
{
fProcess = new ChildProcess();
}
else if (fProcess->isRunning())
{
carla_stderr("CarlaThreadDSSI::run() - already running, giving up...");

kEngine->callback(CarlaBackend::ENGINE_CALLBACK_UI_STATE_CHANGED, kPlugin->getId(), 0, 0, 0.0f, nullptr);
fProcess->kill();
fProcess = nullptr;
return;
}

#if 0 //def CARLA_OS_LINUX
const char* const oldPreload(std::getenv("LD_PRELOAD"));
::unsetenv("LD_PRELOAD");

if (oldPreload != nullptr)
::setenv("LD_PRELOAD", oldPreload, 1);
#endif

String name(kPlugin->getName());
String filename(kPlugin->getFilename());

if (name.isEmpty())
name = "(none)";

if (filename.isEmpty())
filename = "\"\"";

StringArray arguments;

#ifndef CARLA_OS_WIN
// start with "wine" if needed
if (fBinary.endsWith(".exe"))
arguments.add("wine");
#endif

// binary
arguments.add(fBinary.buffer());

// osc-url
arguments.add(String(kEngine->getOscServerPathUDP()) + String("/") + String(kPlugin->getId()));

// filename
arguments.add(filename);

// label
arguments.add(fLabel.buffer());

// ui-title
arguments.add(name + String(" (GUI)"));

carla_stdout("starting DSSI UI...");

if (! fProcess->start(arguments))
{
carla_stdout("failed!");
fProcess = nullptr;
return;
}

if (kPlugin->waitForOscGuiShow())
{
for (; fProcess->isRunning() && ! shouldThreadExit();)
carla_sleep(1);

// we only get here if UI was closed or thread asked to exit
if (fProcess->isRunning() && shouldThreadExit())
{
fProcess->waitForProcessToFinish(static_cast<int>(kEngine->getOptions().uiBridgesTimeout));

if (fProcess->isRunning())
{
carla_stdout("CarlaThreadDSSIUI::run() - UI refused to close, force kill now");
fProcess->kill();
}
else
{
carla_stdout("CarlaThreadDSSIUI::run() - UI auto-closed successfully");
}
}
else if (fProcess->getExitCode() != 0 /*|| fProcess->exitStatus() == QProcess::CrashExit*/)
carla_stderr("CarlaThreadDSSIUI::run() - UI crashed while running");
else
carla_stdout("CarlaThreadDSSIUI::run() - UI closed cleanly");

kEngine->callback(CarlaBackend::ENGINE_CALLBACK_UI_STATE_CHANGED, kPlugin->getId(), 0, 0, 0.0f, nullptr);
}
else
{
fProcess->kill();

carla_stdout("CarlaThreadDSSIUI::run() - GUI timeout");
kEngine->callback(CarlaBackend::ENGINE_CALLBACK_UI_STATE_CHANGED, kPlugin->getId(), 0, 0, 0.0f, nullptr);
}

carla_stdout("DSSI UI finished");
fProcess = nullptr;
}
void run();

private:
CarlaEngine* const kEngine;
CarlaPlugin* const kPlugin;
CarlaEngine* const kEngine;
CarlaPluginDSSI* const kPlugin;

CarlaString fBinary;
CarlaString fLabel;
@@ -2047,19 +1952,6 @@ public:
carla_debug("CarlaPluginDSSI::clearBuffers() - end");
}

// -------------------------------------------------------------------
// OSC stuff

void updateOscURL() override
{
// DSSI does not support this
if (! fThreadUI.isThreadRunning())
return;

showCustomUI(false);
//showCustomUI(true);
}

// -------------------------------------------------------------------
// Post-poned UI Stuff

@@ -2141,6 +2033,94 @@ public:

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

void updateOscData(const lo_address& source, const char* const url) override
{
// FIXME - remove debug prints later
carla_stdout("CarlaPluginDSSI::updateOscData(%p, \"%s\")", source, url);

pData->oscData.clear();

const int proto = lo_address_get_protocol(source);

{
const char* host = lo_address_get_hostname(source);
const char* port = lo_address_get_port(source);
pData->oscData.source = lo_address_new_with_proto(proto, host, port);

carla_stdout("CarlaPlugin::updateOscData() - source: host \"%s\", port \"%s\"", host, port);
}

{
char* host = lo_url_get_hostname(url);
char* port = lo_url_get_port(url);
pData->oscData.path = carla_strdup_free(lo_url_get_path(url));
pData->oscData.target = lo_address_new_with_proto(proto, host, port);
carla_stdout("CarlaPlugin::updateOscData() - target: host \"%s\", port \"%s\", path \"%s\"", host, port, pData->oscData.path);

std::free(host);
std::free(port);
}

osc_send_sample_rate(pData->oscData, static_cast<float>(pData->engine->getSampleRate()));

for (LinkedList<CustomData>::Itenerator it = pData->custom.begin(); it.valid(); it.next())
{
const CustomData& customData(it.getValue(kCustomDataFallback));
CARLA_SAFE_ASSERT_CONTINUE(customData.isValid());

if (std::strcmp(customData.type, CUSTOM_DATA_TYPE_STRING) == 0)
osc_send_configure(pData->oscData, customData.key, customData.value);
}

if (pData->prog.current >= 0)
osc_send_program(pData->oscData, static_cast<uint32_t>(pData->prog.current));

if (pData->midiprog.current >= 0)
{
const MidiProgramData& curMidiProg(pData->midiprog.getCurrent());

if (getType() == PLUGIN_DSSI)
osc_send_program(pData->oscData, curMidiProg.bank, curMidiProg.program);
else
osc_send_midi_program(pData->oscData, curMidiProg.bank, curMidiProg.program);
}

for (uint32_t i=0; i < pData->param.count; ++i)
osc_send_control(pData->oscData, pData->param.data[i].rindex, getParameterValue(i));

if ((pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0 && pData->engine->getOptions().frontendWinId != 0)
pData->transientTryCounter = 1;

carla_stdout("CarlaPluginDSSI::updateOscData() - done");
}

bool waitForOscGuiShow()
{
carla_stdout("CarlaPluginDSSI::waitForOscGuiShow()");
uint i=0, oscUiTimeout = pData->engine->getOptions().uiBridgesTimeout;

// wait for UI 'update' call
for (; i < oscUiTimeout/100; ++i)
{
if (pData->oscData.target != nullptr)
{
carla_stdout("CarlaPluginDSSI::waitForOscGuiShow() - got response, asking UI to show itself now");
osc_send_show(pData->oscData);
return true;
}

if (pData->childProcess != nullptr && pData->childProcess->isRunning())
carla_msleep(100);
else
return false;
}

carla_stdout("CarlaPluginDSSI::waitForOscGuiShow() - Timeout while waiting for UI to respond (waited %u msecs)", oscUiTimeout);
return false;
}

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

bool init(const char* const filename, const char* const name, const char* const label)
{
CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
@@ -2481,6 +2461,113 @@ private:

LinkedList<const char*> CarlaPluginDSSI::sMultiSynthList;


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

void CarlaThreadDSSIUI::run()
{
if (fProcess == nullptr)
{
fProcess = new ChildProcess();
}
else if (fProcess->isRunning())
{
carla_stderr("CarlaThreadDSSI::run() - already running, giving up...");

kEngine->callback(CarlaBackend::ENGINE_CALLBACK_UI_STATE_CHANGED, kPlugin->getId(), 0, 0, 0.0f, nullptr);
fProcess->kill();
fProcess = nullptr;
return;
}

#if 0 //def CARLA_OS_LINUX
const char* const oldPreload(std::getenv("LD_PRELOAD"));
::unsetenv("LD_PRELOAD");

if (oldPreload != nullptr)
::setenv("LD_PRELOAD", oldPreload, 1);
#endif

String name(kPlugin->getName());
String filename(kPlugin->getFilename());

if (name.isEmpty())
name = "(none)";

if (filename.isEmpty())
filename = "\"\"";

StringArray arguments;

#ifndef CARLA_OS_WIN
// start with "wine" if needed
if (fBinary.endsWith(".exe"))
arguments.add("wine");
#endif

// binary
arguments.add(fBinary.buffer());

// osc-url
arguments.add(String(kEngine->getOscServerPathUDP()) + String("/") + String(kPlugin->getId()));

// filename
arguments.add(filename);

// label
arguments.add(fLabel.buffer());

// ui-title
arguments.add(name + String(" (GUI)"));

carla_stdout("starting DSSI UI...");

if (! fProcess->start(arguments))
{
carla_stdout("failed!");
fProcess = nullptr;
return;
}

if (kPlugin->waitForOscGuiShow())
{
for (; fProcess->isRunning() && ! shouldThreadExit();)
carla_sleep(1);

// we only get here if UI was closed or thread asked to exit
if (fProcess->isRunning() && shouldThreadExit())
{
fProcess->waitForProcessToFinish(static_cast<int>(kEngine->getOptions().uiBridgesTimeout));

if (fProcess->isRunning())
{
carla_stdout("CarlaThreadDSSIUI::run() - UI refused to close, force kill now");
fProcess->kill();
}
else
{
carla_stdout("CarlaThreadDSSIUI::run() - UI auto-closed successfully");
}
}
else if (fProcess->getExitCode() != 0 /*|| fProcess->exitStatus() == QProcess::CrashExit*/)
carla_stderr("CarlaThreadDSSIUI::run() - UI crashed while running");
else
carla_stdout("CarlaThreadDSSIUI::run() - UI closed cleanly");

kEngine->callback(CarlaBackend::ENGINE_CALLBACK_UI_STATE_CHANGED, kPlugin->getId(), 0, 0, 0.0f, nullptr);
}
else
{
fProcess->kill();

carla_stdout("CarlaThreadDSSIUI::run() - GUI timeout");
kEngine->callback(CarlaBackend::ENGINE_CALLBACK_UI_STATE_CHANGED, kPlugin->getId(), 0, 0, 0.0f, nullptr);
}

carla_stdout("DSSI UI finished");
fProcess = nullptr;
}

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

CarlaPlugin* CarlaPlugin::newDSSI(const Initializer& init)


+ 0
- 14
source/utils/CarlaOscUtils.hpp View File

@@ -224,20 +224,6 @@ void osc_send_update(const CarlaOscData& oscData, const char* const url) noexcep
try_lo_send(oscData.target, targetPath, "s", url);
}

static inline
void osc_send_update_url(const CarlaOscData& oscData, const char* const url) noexcept
{
CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);;
CARLA_SAFE_ASSERT_RETURN(url != nullptr && url[0] != '\0',);
carla_debug("osc_send_update_url(path:\"%s\", \"%s\")", oscData.path, url);

char targetPath[std::strlen(oscData.path)+12];
std::strcpy(targetPath, oscData.path);
std::strcat(targetPath, "/update_url");
try_lo_send(oscData.target, targetPath, "s", url);
}

static inline
void osc_send_show(const CarlaOscData& oscData) noexcept
{


Loading…
Cancel
Save