Browse Source

Make internal plugins with Juce UI work in LV2 mode

tags/1.9.4
falkTX 12 years ago
parent
commit
c90826b0fe
3 changed files with 107 additions and 11 deletions
  1. +11
    -5
      source/plugin/Makefile
  2. +4
    -2
      source/plugin/carla-native-lv2-export.cpp
  3. +92
    -4
      source/plugin/carla-native-lv2.cpp

+ 11
- 5
source/plugin/Makefile View File

@@ -45,10 +45,8 @@ endif
# --------------------------------------------------------------
# Native

DGL_LIBS = -lX11 -lXext

ifeq ($(HAVE_OPENGL),true)
LINK_FLAGS += $(shell pkg-config --libs gl) $(DGL_LIBS)
LINK_FLAGS += $(shell pkg-config --libs gl)
endif

ifeq ($(HAVE_AF_DEPS),true)
@@ -69,7 +67,15 @@ LINK_FLAGS += $(shell pkg-config --libs ntk_images ntk) -lfreetype # FIXME
endif
endif

LINK_FLAGS += $(EXTRA_LIBS)
# --------------------------------------------------------------
# Juce

LINK_FLAGS += $(JUCE_AUDIO_BASICS_LIBS)
LINK_FLAGS += $(JUCE_CORE_LIBS)
LINK_FLAGS += $(JUCE_DATA_STRUCTURES_LIBS)
LINK_FLAGS += $(JUCE_EVENTS_LIBS)
LINK_FLAGS += $(JUCE_GRAPHICS_LIBS)
LINK_FLAGS += $(JUCE_GUI_BASICS_LIBS)

# --------------------------------------------------------------

@@ -147,7 +153,7 @@ carla-native-lv2-export.exe: carla-native-lv2-export.cpp.o $(LIBS)
# --------------------------------------------------------------

.FORCE:
.PHONY: .FORCE carla-native-lv2-export carla-native-lv2-export.exe
.PHONY: .FORCE

../modules/%.a: .FORCE
$(MAKE) -C ../modules $*

+ 4
- 2
source/plugin/carla-native-lv2-export.cpp View File

@@ -133,7 +133,7 @@ void writeManifestFile()
// -------------------------------------------------------------------
// UI

text += "<http://kxstudio.sf.net/carla#UI>\n";
text += "<http://kxstudio.sf.net/carla/ui>\n";
text += " a <" LV2_EXTERNAL_UI__Widget "> ;\n";
text += " ui:binary <carla-native" PLUGIN_EXT "> ;\n";
text += " lv2:extensionData <" LV2_PROGRAMS__UIInterface "> ;\n";
@@ -242,6 +242,8 @@ void writePluginFile(const PluginDescriptor* const pluginDesc)
break;
}

text += "\n";

// -------------------------------------------------------------------
// Features

@@ -290,7 +292,7 @@ void writePluginFile(const PluginDescriptor* const pluginDesc)

if (pluginDesc->hints & PLUGIN_HAS_GUI)
{
text += " ui:ui <http://kxstudio.sf.net/carla#UI> ;\n";
text += " ui:ui <http://kxstudio.sf.net/carla/ui> ;\n";
text += "\n";
}



+ 92
- 4
source/plugin/carla-native-lv2.cpp View File

@@ -19,6 +19,7 @@
#include "carla-native-base.cpp"

#include "juce_audio_basics.h"
#include "juce_gui_basics.h"

#include "CarlaString.hpp"

@@ -35,7 +36,52 @@
#include "lv2/lv2_external_ui.h"
#include "lv2/lv2_programs.h"

using juce::FloatVectorOperations;
using namespace juce;

// -----------------------------------------------------------------------
// Juce Message Thread

class JuceMessageThread : public Thread
{
public:
JuceMessageThread()
: Thread("JuceMessageThread"),
fInitialised(false)
{
startThread(7);

while (! fInitialised)
sleep(1);
}

~JuceMessageThread()
{
signalThreadShouldExit();
JUCEApplication::quit();
waitForThreadToExit(5000);
clearSingletonInstance();
}

void run()
{
initialiseJuce_GUI();
fInitialised = true;

MessageManager::getInstance()->setCurrentThreadAsMessageThread();

while ((! threadShouldExit()) && MessageManager::getInstance()->runDispatchLoopUntil(250))
{}
}

juce_DeclareSingleton(JuceMessageThread, false);

private:
bool fInitialised;
};

juce_ImplementSingleton(JuceMessageThread)

static Array<void*> gActivePlugins;

// -----------------------------------------------------------------------
// LV2 descriptor functions
@@ -49,6 +95,7 @@ public:
: fHandle(nullptr),
fDescriptor(desc),
fMidiEventCount(0),
fUiWasShown(false),
fIsProcessing(false),
fVolume(1.0f),
fDryWet(1.0f),
@@ -142,6 +189,7 @@ public:
~NativePlugin()
{
CARLA_ASSERT(fHandle == nullptr);
CARLA_ASSERT(! fUiWasShown);

if (fHost.resourceDir != nullptr)
{
@@ -205,7 +253,27 @@ public:
{
if (fDescriptor->cleanup != nullptr)
fDescriptor->cleanup(fHandle);

fHandle = nullptr;

if (fUiWasShown)
{
CARLA_SAFE_ASSERT_RETURN(gActivePlugins.contains(this),);

gActivePlugins.removeFirstMatchingValue(this);

JUCE_AUTORELEASEPOOL

MessageManagerLock mmLock;

if (gActivePlugins.size() == 0)
{
JuceMessageThread::deleteInstance();
shutdownJuce_GUI();
}

fUiWasShown = false;
}
}

void lv2_run(const uint32_t frames)
@@ -573,7 +641,26 @@ protected:
void handleUiShow()
{
if (fDescriptor->ui_show != nullptr)
fDescriptor->ui_show(fHandle, true);
{
if (fDescriptor->hints & PLUGIN_NEEDS_UI_JUCE)
{
JUCE_AUTORELEASEPOOL

if (gActivePlugins.size() == 0)
{
initialiseJuce_GUI();
JuceMessageThread::getInstance();
}

MessageManagerLock mmLock;
fDescriptor->ui_show(fHandle, true);

fUiWasShown = true;
gActivePlugins.add(this);
}
else
fDescriptor->ui_show(fHandle, true);
}

fUI.isVisible = true;
}
@@ -737,6 +824,7 @@ private:
MidiEvent fMidiEvents[kMaxMidiEvents*2];
TimeInfo fTimeInfo;

bool fUiWasShown;
bool fIsProcessing;
float fVolume;
float fDryWet;
@@ -1095,7 +1183,7 @@ static LV2_Handle lv2_instantiate(const LV2_Descriptor* lv2Descriptor, double sa
if (std::strncmp(lv2Descriptor->URI, "http://kxstudio.sf.net/carla/plugins/", 37) == 0)
pluginLabel = lv2Descriptor->URI+37;
else if (std::strcmp(lv2Descriptor->URI, "http://kxstudio.sf.net/carla") == 0)
pluginLabel = lv2Descriptor->URI+23;
pluginLabel = "carla";

if (pluginLabel == nullptr)
{
@@ -1346,7 +1434,7 @@ const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index)
carla_debug("lv2ui_descriptor(%i)", index);

static const LV2UI_Descriptor lv2UiDesc = {
/* URI */ "http://kxstudio.sf.net/carla#UI",
/* URI */ "http://kxstudio.sf.net/carla/ui",
/* instantiate */ lv2ui_instantiate,
/* cleanup */ lv2ui_cleanup,
/* port_event */ lv2ui_port_event,


Loading…
Cancel
Save