diff --git a/README.md b/README.md
index a3a7dc6..ee04475 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ THIS IS CURRENTLY A WORK IN PROGRESS RESEARCH PROJECT.
It is not known yet how well this can work, mostly testing waters here.
Currently the plugin will link against an internal [Carla](https://github.com/falkTX/Carla) for the plugin host part, embeding UIs if possible.
-Audio, MIDI and Time information works, but there is no latency, parameters or state handled right now.
+Audio, MIDI, Latency and Time information and State save/loading works, but there are no parameters right now.
Also, only LV2 hosting is enabled at the moment.
Ildaeil basically works as a mini-wrapper around Carla, leveraging it for all its host support.
diff --git a/carla b/carla
index a310640..f93784e 160000
--- a/carla
+++ b/carla
@@ -1 +1 @@
-Subproject commit a310640e0fcb1aef53fe7d15771cccebdc9731c8
+Subproject commit f93784ef1ad549a85f01dc4715920b9485303e0a
diff --git a/plugins/Common/.kdev_include_paths b/plugins/Common/.kdev_include_paths
index bc3a9bb..6bbc750 100644
--- a/plugins/Common/.kdev_include_paths
+++ b/plugins/Common/.kdev_include_paths
@@ -2,5 +2,7 @@
../../dpf/distrho/
../../dpf-widgets/generic
../../dpf-widgets/opengl
-/usr/include/carla
-/usr/include/carla/includes
+../../carla/source/backend
+../../carla/source/includes
+../../carla/source/modules
+../../carla/source/utils
diff --git a/plugins/Common/IldaeilPlugin.cpp b/plugins/Common/IldaeilPlugin.cpp
index be769e7..fb1919b 100644
--- a/plugins/Common/IldaeilPlugin.cpp
+++ b/plugins/Common/IldaeilPlugin.cpp
@@ -16,6 +16,9 @@
*/
#include "CarlaNativePlugin.h"
+#include "CarlaEngine.hpp"
+#include "water/streams/MemoryOutputStream.h"
+#include "water/xml/XmlDocument.h"
#include "DistrhoPlugin.hpp"
@@ -52,11 +55,13 @@ public:
#endif
mutable NativeTimeInfo fCarlaTimeInfo;
+ mutable water::MemoryOutputStream fLastProjectState;
+ uint32_t fLastLatencyValue;
void* fUI;
IldaeilPlugin()
- : Plugin(0, 0, 0),
+ : Plugin(0, 0, 1),
fCarlaPluginDescriptor(nullptr),
fCarlaPluginHandle(nullptr),
fCarlaHostHandle(nullptr),
@@ -65,6 +70,7 @@ public:
fMidiEventCount(0),
fDummyBuffer(nullptr),
#endif
+ fLastLatencyValue(0),
fUI(nullptr)
{
fCarlaPluginDescriptor = carla_get_native_rack_plugin();
@@ -246,16 +252,72 @@ protected:
/* --------------------------------------------------------------------------------------------------------
* Init */
+ void initState(const uint32_t index, String& stateKey, String& defaultStateValue) override
+ {
+ DISTRHO_SAFE_ASSERT_RETURN(index == 0,);
+
+ stateKey = "project";
+ defaultStateValue = ""
+ "\n"
+ "\n"
+ "\n"
+ "\n";
+ }
+
/* --------------------------------------------------------------------------------------------------------
* Internal data */
+ String getState(const char* const key) const override
+ {
+ if (std::strcmp(key, "project") == 0)
+ {
+ CarlaEngine* const engine = carla_get_engine_from_handle(fCarlaHostHandle);
+
+ fLastProjectState.reset();
+ engine->saveProjectInternal(fLastProjectState);
+ return String(static_cast(fLastProjectState.getDataAndRelease()), false);
+ }
+
+ return String();
+ }
+
+ void setState(const char* const key, const char* const value) override
+ {
+ if (std::strcmp(key, "project") == 0)
+ {
+ CarlaEngine* const engine = carla_get_engine_from_handle(fCarlaHostHandle);
+
+ water::XmlDocument xml(value);
+ engine->loadProjectInternal(xml, true);
+ }
+ }
+
/* --------------------------------------------------------------------------------------------------------
* Process */
+ void checkLatencyChanged()
+ {
+ if (fCarlaHostHandle == nullptr)
+ return;
+
+ uint32_t latency = 0;
+
+ for (uint32_t i=0; i < carla_get_current_plugin_count(fCarlaHostHandle); ++i)
+ latency += carla_get_plugin_latency(fCarlaHostHandle, i);
+
+ if (fLastLatencyValue != latency)
+ {
+ fLastLatencyValue = latency;
+ setLatency(latency);
+ }
+ }
+
void activate() override
{
if (fCarlaPluginHandle != nullptr)
fCarlaPluginDescriptor->activate(fCarlaPluginHandle);
+
+ checkLatencyChanged();
}
void deactivate() override
@@ -305,6 +367,8 @@ protected:
#else
fCarlaPluginDescriptor->process(fCarlaPluginHandle, (float**)inputs, outputs, frames, nullptr, 0);
#endif
+
+ checkLatencyChanged();
}
else
{
diff --git a/plugins/Common/IldaeilUI.cpp b/plugins/Common/IldaeilUI.cpp
index 7fbc69b..15447a9 100644
--- a/plugins/Common/IldaeilUI.cpp
+++ b/plugins/Common/IldaeilUI.cpp
@@ -59,7 +59,8 @@ class IldaeilUI : public UI,
kDrawingLoading,
kDrawingPluginList,
kDrawingPluginCustomUI,
- kDrawingPluginGenericUI
+ kDrawingPluginGenericUI,
+ kDrawingPluginPendingFromInit
} fDrawingState;
struct PluginInfoCache {
@@ -130,22 +131,16 @@ public:
carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_UI_SCALE, getScaleFactor()*1000, nullptr);
if (carla_get_current_plugin_count(handle) != 0)
- {
- showPluginUI(handle);
- startThread();
- return;
- }
+ fDrawingState = kDrawingPluginPendingFromInit;
}
~IldaeilUI() override
{
- if (fPlugin == nullptr || fPlugin->fCarlaHostHandle == nullptr)
- return;
-
- stopThread(-1);
+ if (isThreadRunning())
+ stopThread(-1);
// fPlugin->fUI = nullptr;
- hidePluginUI(fPlugin->fCarlaHostHandle);
+ hidePluginUI();
delete[] fPlugins;
}
@@ -161,19 +156,23 @@ public:
}
else
{
+ fDrawingState = kDrawingPluginGenericUI;
// TODO query parameter information and store it
const double scaleFactor = getScaleFactor();
setSize(kGenericWidth * scaleFactor, (kGenericHeight + kExtraHeight) * scaleFactor);
- fDrawingState = kDrawingPluginGenericUI;
}
repaint();
}
- void hidePluginUI(const CarlaHostHandle handle)
+ void hidePluginUI()
{
+
+ if (fPlugin == nullptr || fPlugin->fCarlaHostHandle == nullptr)
+ return;
+
if (fDrawingState == kDrawingPluginGenericUI || fDrawingState == kDrawingPluginCustomUI)
- carla_show_custom_ui(handle, 0, false);
+ carla_show_custom_ui(fPlugin->fCarlaHostHandle, 0, false);
fPluginHostWindow.hide();
}
@@ -194,6 +193,11 @@ protected:
repaint();
break;
+ case kDrawingPluginPendingFromInit:
+ showPluginUI(fPlugin->fCarlaHostHandle);
+ startThread();
+ break;
+
case kDrawingPluginCustomUI:
fPlugin->fCarlaPluginDescriptor->ui_idle(fPlugin->fCarlaPluginHandle);
fPluginHostWindow.idle();
@@ -254,6 +258,9 @@ protected:
switch (fDrawingState)
{
case kDrawingInit:
+ case kDrawingLoading:
+ case kDrawingPluginPendingFromInit:
+ drawLoading();
break;
case kDrawingPluginList:
drawPluginList();
@@ -261,9 +268,6 @@ protected:
case kDrawingError:
// TODO display error message
break;
- case kDrawingLoading:
- drawLoading();
- break;
case kDrawingPluginGenericUI:
drawGenericUI();
// fall-through
@@ -282,7 +286,7 @@ protected:
{
if (ImGui::Button("Pick Another..."))
{
- hidePluginUI(fPlugin->fCarlaHostHandle);
+ hidePluginUI();
fDrawingState = kDrawingPluginList;
const double scaleFactor = getScaleFactor();
@@ -362,7 +366,7 @@ protected:
{
if (pluginIsRunning)
{
- hidePluginUI(handle);
+ hidePluginUI();
carla_replace_plugin(handle, 0);
}
@@ -450,14 +454,16 @@ protected:
/* --------------------------------------------------------------------------------------------------------
* DSP/Plugin Callbacks */
- /**
- A parameter has changed on the plugin side.
- This is called by the host to inform the UI about parameter changes.
- */
void parameterChanged(uint32_t, float) override
{
}
+ void stateChanged(const char* const key, const char* const) override
+ {
+ if (std::strcmp(key, "project") == 0)
+ hidePluginUI();
+ }
+
// -------------------------------------------------------------------------------------------------------
private:
diff --git a/plugins/Common/Makefile.mk b/plugins/Common/Makefile.mk
index 0f57722..e4b3939 100644
--- a/plugins/Common/Makefile.mk
+++ b/plugins/Common/Makefile.mk
@@ -67,6 +67,8 @@ BUILD_CXX_FLAGS += -I../../dpf-widgets/opengl
BUILD_CXX_FLAGS += -DREAL_BUILD
BUILD_CXX_FLAGS += -I../../carla/source/backend
BUILD_CXX_FLAGS += -I../../carla/source/includes
+BUILD_CXX_FLAGS += -I../../carla/source/modules
+BUILD_CXX_FLAGS += -I../../carla/source/utils
LINK_FLAGS += $(STATIC_CARLA_PLUGIN_LIBS)
diff --git a/plugins/FX/.kdev_include_paths b/plugins/FX/.kdev_include_paths
index d960339..136ceaa 100644
--- a/plugins/FX/.kdev_include_paths
+++ b/plugins/FX/.kdev_include_paths
@@ -3,5 +3,7 @@
../../dpf/distrho/
../../dpf-widgets/generic
../../dpf-widgets/opengl
-/usr/include/carla
-/usr/include/carla/includes
+../../carla/source/backend
+../../carla/source/includes
+../../carla/source/modules
+../../carla/source/utils
diff --git a/plugins/FX/DistrhoPluginInfo.h b/plugins/FX/DistrhoPluginInfo.h
index 354444c..6db32fa 100644
--- a/plugins/FX/DistrhoPluginInfo.h
+++ b/plugins/FX/DistrhoPluginInfo.h
@@ -27,6 +27,8 @@
#define DISTRHO_PLUGIN_NUM_INPUTS 2
#define DISTRHO_PLUGIN_NUM_OUTPUTS 2
#define DISTRHO_PLUGIN_WANT_LATENCY 1
+#define DISTRHO_PLUGIN_WANT_STATE 1
+#define DISTRHO_PLUGIN_WANT_FULL_STATE 1
#define DISTRHO_PLUGIN_WANT_MIDI_INPUT 0
#define DISTRHO_PLUGIN_WANT_MIDI_OUTPUT 0
#define DISTRHO_PLUGIN_WANT_TIMEPOS 1
diff --git a/plugins/MIDI/DistrhoPluginInfo.h b/plugins/MIDI/DistrhoPluginInfo.h
index fe5066c..1195e33 100644
--- a/plugins/MIDI/DistrhoPluginInfo.h
+++ b/plugins/MIDI/DistrhoPluginInfo.h
@@ -27,6 +27,8 @@
#define DISTRHO_PLUGIN_NUM_INPUTS 0
#define DISTRHO_PLUGIN_NUM_OUTPUTS 0
#define DISTRHO_PLUGIN_WANT_LATENCY 1
+#define DISTRHO_PLUGIN_WANT_STATE 1
+#define DISTRHO_PLUGIN_WANT_FULL_STATE 1
#define DISTRHO_PLUGIN_WANT_MIDI_INPUT 1
#define DISTRHO_PLUGIN_WANT_MIDI_OUTPUT 1
#define DISTRHO_PLUGIN_WANT_TIMEPOS 1
diff --git a/plugins/Synth/DistrhoPluginInfo.h b/plugins/Synth/DistrhoPluginInfo.h
index a01a5ff..bd84a7f 100644
--- a/plugins/Synth/DistrhoPluginInfo.h
+++ b/plugins/Synth/DistrhoPluginInfo.h
@@ -27,6 +27,8 @@
#define DISTRHO_PLUGIN_NUM_INPUTS 0
#define DISTRHO_PLUGIN_NUM_OUTPUTS 2
#define DISTRHO_PLUGIN_WANT_LATENCY 1
+#define DISTRHO_PLUGIN_WANT_STATE 1
+#define DISTRHO_PLUGIN_WANT_FULL_STATE 1
#define DISTRHO_PLUGIN_WANT_MIDI_INPUT 1
#define DISTRHO_PLUGIN_WANT_MIDI_OUTPUT 0
#define DISTRHO_PLUGIN_WANT_TIMEPOS 1