@@ -63,6 +63,8 @@ carla-discovery-native | |||||
carla-discovery-posix32 | carla-discovery-posix32 | ||||
carla-discovery-posix64 | carla-discovery-posix64 | ||||
carla-native-export | |||||
data/windows/Carla | data/windows/Carla | ||||
data/windows/CarlaControl | data/windows/CarlaControl | ||||
source/tests/ANSI | source/tests/ANSI | ||||
@@ -201,11 +201,11 @@ zynaddsubfx-ui.cpp.o: zynaddsubfx-ui.cpp $(ZYN_UI_FILES_H) | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
# %.c.o: %.c | |||||
# $(CC) $< $(BUILD_C_FLAGS) -c -o $@ | |||||
# | |||||
# %.cpp.o: %.cpp | |||||
# $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||||
%.c.o: %.c | |||||
$(CC) $< $(BUILD_C_FLAGS) -c -o $@ | |||||
%.cpp.o: %.cpp | |||||
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||||
moc_%.cpp: %.hpp | moc_%.cpp: %.hpp | ||||
$(MOC) $< -DMOC_PARSING -o $@ | $(MOC) $< -DMOC_PARSING -o $@ | ||||
@@ -262,6 +262,7 @@ static const PluginDescriptor audiofileDesc = { | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
CARLA_EXPORT | |||||
void carla_register_native_plugin_audiofile() | void carla_register_native_plugin_audiofile() | ||||
{ | { | ||||
carla_register_native_plugin(&audiofileDesc); | carla_register_native_plugin(&audiofileDesc); | ||||
@@ -50,6 +50,7 @@ END_NAMESPACE_DISTRHO | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
CARLA_EXPORT | |||||
void carla_register_native_plugin_3BandEQ() | void carla_register_native_plugin_3BandEQ() | ||||
{ | { | ||||
USE_NAMESPACE_DISTRHO | USE_NAMESPACE_DISTRHO | ||||
@@ -50,6 +50,7 @@ END_NAMESPACE_DISTRHO | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
CARLA_EXPORT | |||||
void carla_register_native_plugin_3BandSplitter() | void carla_register_native_plugin_3BandSplitter() | ||||
{ | { | ||||
USE_NAMESPACE_DISTRHO | USE_NAMESPACE_DISTRHO | ||||
@@ -50,6 +50,7 @@ END_NAMESPACE_DISTRHO | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
CARLA_EXPORT | |||||
void carla_register_native_plugin_Nekobi() | void carla_register_native_plugin_Nekobi() | ||||
{ | { | ||||
USE_NAMESPACE_DISTRHO | USE_NAMESPACE_DISTRHO | ||||
@@ -49,6 +49,7 @@ END_NAMESPACE_DISTRHO | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
CARLA_EXPORT | |||||
void carla_register_native_plugin_Notes() | void carla_register_native_plugin_Notes() | ||||
{ | { | ||||
USE_NAMESPACE_DISTRHO | USE_NAMESPACE_DISTRHO | ||||
@@ -50,6 +50,7 @@ END_NAMESPACE_DISTRHO | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
CARLA_EXPORT | |||||
void carla_register_native_plugin_PingPongPan() | void carla_register_native_plugin_PingPongPan() | ||||
{ | { | ||||
USE_NAMESPACE_DISTRHO | USE_NAMESPACE_DISTRHO | ||||
@@ -50,6 +50,7 @@ END_NAMESPACE_DISTRHO | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
CARLA_EXPORT | |||||
void carla_register_native_plugin_StereoEnhancer() | void carla_register_native_plugin_StereoEnhancer() | ||||
{ | { | ||||
USE_NAMESPACE_DISTRHO | USE_NAMESPACE_DISTRHO | ||||
@@ -237,6 +237,7 @@ static const PluginDescriptor midifileDesc = { | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
CARLA_EXPORT | |||||
void carla_register_native_plugin_midifile() | void carla_register_native_plugin_midifile() | ||||
{ | { | ||||
carla_register_native_plugin(&midifileDesc); | carla_register_native_plugin(&midifileDesc); | ||||
@@ -251,6 +251,7 @@ static const PluginDescriptor midiSequencerDesc = { | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
CARLA_EXPORT | |||||
void carla_register_native_plugin_midiSequencer() | void carla_register_native_plugin_midiSequencer() | ||||
{ | { | ||||
carla_register_native_plugin(&midiSequencerDesc); | carla_register_native_plugin(&midiSequencerDesc); | ||||
@@ -177,6 +177,7 @@ static const PluginDescriptor sunvoxfileDesc = { | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
CARLA_EXPORT | |||||
void carla_register_native_plugin_sunvoxfile() | void carla_register_native_plugin_sunvoxfile() | ||||
{ | { | ||||
carla_register_native_plugin(&sunvoxfileDesc); | carla_register_native_plugin(&sunvoxfileDesc); | ||||
@@ -2169,6 +2169,7 @@ static const PluginDescriptor zynaddsubfxDesc = { | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
CARLA_EXPORT | |||||
void carla_register_native_plugin_zynaddsubfx() | void carla_register_native_plugin_zynaddsubfx() | ||||
{ | { | ||||
carla_register_native_plugin(&fxAlienWahDesc); | carla_register_native_plugin(&fxAlienWahDesc); | ||||
@@ -60,11 +60,11 @@ void carla_register_native_plugin_3BandEQ(); | |||||
void carla_register_native_plugin_3BandSplitter(); | void carla_register_native_plugin_3BandSplitter(); | ||||
void carla_register_native_plugin_Nekobi(); | void carla_register_native_plugin_Nekobi(); | ||||
void carla_register_native_plugin_PingPongPan(); | void carla_register_native_plugin_PingPongPan(); | ||||
// void carla_register_native_plugin_StereoEnhancer(); | |||||
void carla_register_native_plugin_StereoEnhancer(); | |||||
#endif | #endif | ||||
// DISTRHO plugins (Qt) | // DISTRHO plugins (Qt) | ||||
// void carla_register_native_plugin_Notes(); | |||||
void carla_register_native_plugin_Notes(); | |||||
#ifdef WANT_ZYNADDSUBFX | #ifdef WANT_ZYNADDSUBFX | ||||
// ZynAddSubFX | // ZynAddSubFX | ||||
@@ -104,11 +104,11 @@ void carla_register_all_plugins() | |||||
carla_register_native_plugin_3BandSplitter(); | carla_register_native_plugin_3BandSplitter(); | ||||
carla_register_native_plugin_Nekobi(); | carla_register_native_plugin_Nekobi(); | ||||
carla_register_native_plugin_PingPongPan(); | carla_register_native_plugin_PingPongPan(); | ||||
//carla_register_native_plugin_StereoEnhancer(); // unfinished | |||||
carla_register_native_plugin_StereoEnhancer(); // unfinished | |||||
#endif | #endif | ||||
// DISTRHO plugins (Qt) | // DISTRHO plugins (Qt) | ||||
//carla_register_native_plugin_Notes(); // unfinished | |||||
carla_register_native_plugin_Notes(); // unfinished | |||||
#ifdef WANT_ZYNADDSUBFX | #ifdef WANT_ZYNADDSUBFX | ||||
// ZynAddSubFX | // ZynAddSubFX | ||||
@@ -8,7 +8,7 @@ include ../Makefile.mk | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
BUILD_CXX_FLAGS += -I../../theme | |||||
BUILD_CXX_FLAGS += -I../../modules/theme | |||||
BUILD_CXX_FLAGS += $(shell pkg-config --cflags liblo) | BUILD_CXX_FLAGS += $(shell pkg-config --cflags liblo) | ||||
ifeq ($(HAVE_QT4),true) | ifeq ($(HAVE_QT4),true) | ||||
@@ -20,6 +20,8 @@ | |||||
#include "CarlaUtils.hpp" | #include "CarlaUtils.hpp" | ||||
#include <new> | |||||
extern "C" { | extern "C" { | ||||
#include "rtmempool/list.h" | #include "rtmempool/list.h" | ||||
#include "rtmempool/rtmempool.h" | #include "rtmempool/rtmempool.h" | ||||
@@ -8,7 +8,7 @@ include ../../Makefile.mk | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
BUILD_CXX_FLAGS += -I. -I../../includes -I../utils | |||||
BUILD_CXX_FLAGS += -I. -I.. -I../utils -I../../includes | |||||
ifeq ($(HAVE_QT4),true) | ifeq ($(HAVE_QT4),true) | ||||
BUILD_CXX_FLAGS += $(shell pkg-config --cflags QtCore QtGui) | BUILD_CXX_FLAGS += $(shell pkg-config --cflags QtCore QtGui) | ||||
@@ -6,6 +6,26 @@ | |||||
include ../Makefile.mk | include ../Makefile.mk | ||||
BUILD_CXX_FLAGS += -I../backend -I../includes -I../modules -I../modules/utils | |||||
# -------------------------------------------------------------- | |||||
ifeq ($(HAVE_OPENGL),true) | |||||
BUILD_CXX_FLAGS += -DWANT_OPENGL | |||||
endif | |||||
ifeq ($(HAVE_AF_DEPS),true) | |||||
BUILD_CXX_FLAGS += -DWANT_AUDIOFILE | |||||
endif | |||||
ifeq ($(HAVE_MF_DEPS),true) | |||||
BUILD_CXX_FLAGS += -DWANT_MIDIFILE | |||||
endif | |||||
ifeq ($(HAVE_ZYN_DEPS),true) | |||||
BUILD_CXX_FLAGS += -DWANT_ZYNADDSUBFX | |||||
endif | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
# Common | # Common | ||||
@@ -59,50 +79,73 @@ LINK_FLAGS += $(EXTRA_LIBS) | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
LIBS = ../backend/libcarla_engine_plugin.a | |||||
LIBS += ../backend/libcarla_plugin.a | |||||
# LIBS = ../backend/libcarla_engine_xx.a | |||||
# LIBS += ../backend/libcarla_plugin.a | |||||
LIBS += ../backend/libcarla_native.a | LIBS += ../backend/libcarla_native.a | ||||
LIBS += ../libs/rtmempool.a | |||||
LIBS += ../libs/widgets.a | |||||
LIBS += ../modules/rtmempool.a | |||||
LIBS += ../modules/widgets.a | |||||
LIBS += ../modules/juce_core.a | |||||
ifeq ($(CARLA_PLUGIN_SUPPORT),true) | ifeq ($(CARLA_PLUGIN_SUPPORT),true) | ||||
LIBS += ../libs/lilv.a | |||||
LIBS += ../modules/lilv.a | |||||
endif | endif | ||||
ifeq ($(HAVE_OPENGL),true) | ifeq ($(HAVE_OPENGL),true) | ||||
LIBS += ../libs/dgl.a | |||||
LIBS += ../modules/dgl.a | |||||
endif | |||||
ifeq ($(WIN32),true) | |||||
TARGETS = carla-native.lv2/carla-native.dll | |||||
TARGETS += carla-native-export.exe | |||||
else | |||||
ifeq ($(MACOS),true) | |||||
TARGETS = carla-native.lv2/carla-native.dylib | |||||
else | |||||
TARGETS = carla-native.lv2/carla-native.so | |||||
endif | |||||
TARGETS += carla-native-export | |||||
endif | endif | ||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
all: dssi vst | |||||
# all: dssi lv2 vst | |||||
all: $(TARGETS) | |||||
clean: | |||||
rm -f *.o | |||||
rm -f carla-native.lv2/* | |||||
dssi: carla-dssi.so | |||||
vst: carla-vst.so | |||||
lv2: carla.lv2/carla-lv2.so | |||||
debug: | |||||
$(MAKE) DEBUG=true | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
carla-dssi.so: ../backend/engine/CarlaEnginePlugin.cpp.dssi.o $(LIBS) | |||||
$(CXX) $^ -shared $(LINK_FLAGS) -o $@ | |||||
%.cpp.o: %.cpp ../backend/CarlaNative.h | |||||
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||||
carla-vst.so: ../backend/engine/CarlaEnginePlugin.cpp.vst.o $(LIBS) | |||||
carla-native.lv2/carla-native.dll: carla-native-plugin.cpp.o $(LIBS) | |||||
$(CXX) $^ -shared $(LINK_FLAGS) -o $@ | $(CXX) $^ -shared $(LINK_FLAGS) -o $@ | ||||
carla.lv2/carla-lv2.so: ../backend/engine/CarlaEnginePlugin.cpp.lv2.o $(LIBS) | |||||
$(CXX) $^ -shared $(LINK_FLAGS) -o $@ | |||||
carla-native.lv2/carla-native.dylib: carla-native-plugin.cpp.o $(LIBS) | |||||
$(CXX) $^ -dynamiclib $(LINK_FLAGS) -o $@ | |||||
# -------------------------------------------------------------- | |||||
carla-native.lv2/carla-native.so: carla-native-plugin.cpp.o $(LIBS) | |||||
$(CXX) $^ -shared $(LINK_FLAGS) -o $@ | |||||
clean: | |||||
rm -f *.dll *.dylib *.so | |||||
rm -f carla.lv2/*.dll carla.lv2/*.dylib carla.lv2/*.so | |||||
carla-native-export: carla-native-export.cpp.o $(LIBS) | |||||
$(CXX) $^ $(LINK_FLAGS) -o $@ | |||||
./carla-native-export | |||||
debug: | |||||
$(MAKE) DEBUG=true | |||||
carla-native-export.exe: carla-native-export.cpp.o $(LIBS) | |||||
$(CXX) $^ $(LINK_FLAGS) -o $@ | |||||
./carla-native-export.exe | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
../backend/engine/CarlaEnginePlugin.cpp.%.o: ../backend/engine/CarlaEnginePlugin.cpp | |||||
make -C ../backend/engine CarlaEnginePlugin.cpp.$*.o | |||||
.FORCE: | |||||
.PHONY: .FORCE | |||||
../backend/libcarla_%.a: .FORCE | |||||
$(MAKE) -C ../backend/$* | |||||
../modules/%.a: .FORCE | |||||
$(MAKE) -C ../modules $* |
@@ -0,0 +1,145 @@ | |||||
/* | |||||
* Carla Native Plugins | |||||
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||||
* | |||||
* This program is free software; you can redistribute it and/or | |||||
* modify it under the terms of the GNU General Public License as | |||||
* published by the Free Software Foundation; either version 2 of | |||||
* the License, or any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||||
*/ | |||||
#include "CarlaNative.h" | |||||
#include "RtList.hpp" | |||||
#include "lv2/lv2.h" | |||||
// ----------------------------------------------------------------------- | |||||
// Plugin register calls | |||||
extern "C" { | |||||
// Simple plugins | |||||
void carla_register_native_plugin_bypass(); | |||||
void carla_register_native_plugin_lfo(); | |||||
//void carla_register_native_plugin_midiSequencer(); | |||||
void carla_register_native_plugin_midiSplit(); | |||||
void carla_register_native_plugin_midiThrough(); | |||||
void carla_register_native_plugin_midiTranspose(); | |||||
void carla_register_native_plugin_nekofilter(); | |||||
//void carla_register_native_plugin_sunvoxfile(); | |||||
#if 0 //ndef BUILD_BRIDGE | |||||
// Carla | |||||
void carla_register_native_plugin_carla(); | |||||
#endif | |||||
#ifdef WANT_AUDIOFILE | |||||
// AudioFile | |||||
void carla_register_native_plugin_audiofile(); | |||||
#endif | |||||
#ifdef WANT_MIDIFILE | |||||
// MidiFile | |||||
void carla_register_native_plugin_midifile(); | |||||
#endif | |||||
#ifdef WANT_OPENGL | |||||
// DISTRHO plugins (OpenGL) | |||||
void carla_register_native_plugin_3BandEQ(); | |||||
void carla_register_native_plugin_3BandSplitter(); | |||||
void carla_register_native_plugin_Nekobi(); | |||||
void carla_register_native_plugin_PingPongPan(); | |||||
void carla_register_native_plugin_StereoEnhancer(); | |||||
#endif | |||||
// DISTRHO plugins (Qt) | |||||
void carla_register_native_plugin_Notes(); | |||||
#ifdef WANT_ZYNADDSUBFX | |||||
// ZynAddSubFX | |||||
void carla_register_native_plugin_zynaddsubfx(); | |||||
#endif | |||||
} | |||||
// ----------------------------------------------------------------------- | |||||
// Plugin List | |||||
struct PluginListManager { | |||||
PluginListManager() | |||||
{ | |||||
// Simple plugins | |||||
carla_register_native_plugin_bypass(); | |||||
carla_register_native_plugin_lfo(); | |||||
//carla_register_native_plugin_midiSequencer(); // unfinished | |||||
carla_register_native_plugin_midiSplit(); | |||||
carla_register_native_plugin_midiThrough(); | |||||
carla_register_native_plugin_midiTranspose(); | |||||
carla_register_native_plugin_nekofilter(); | |||||
//carla_register_native_plugin_sunvoxfile(); // unfinished | |||||
#if 0 //ndef BUILD_BRIDGE | |||||
// Carla | |||||
carla_register_native_plugin_carla(); // kinda unfinished | |||||
#endif | |||||
#ifdef WANT_AUDIOFILE | |||||
// AudioFile | |||||
carla_register_native_plugin_audiofile(); | |||||
#endif | |||||
#ifdef WANT_MIDIFILE | |||||
// MidiFile | |||||
carla_register_native_plugin_midifile(); | |||||
#endif | |||||
#ifdef WANT_OPENGL | |||||
// DISTRHO plugins (OpenGL) | |||||
carla_register_native_plugin_3BandEQ(); | |||||
carla_register_native_plugin_3BandSplitter(); | |||||
carla_register_native_plugin_Nekobi(); | |||||
carla_register_native_plugin_PingPongPan(); | |||||
carla_register_native_plugin_StereoEnhancer(); // unfinished | |||||
#endif | |||||
// DISTRHO plugins (Qt) | |||||
carla_register_native_plugin_Notes(); // unfinished | |||||
#ifdef WANT_ZYNADDSUBFX | |||||
// ZynAddSubFX | |||||
carla_register_native_plugin_zynaddsubfx(); | |||||
#endif | |||||
} | |||||
~PluginListManager() | |||||
{ | |||||
for (auto it = lv2Descs.begin(); it.valid(); it.next()) | |||||
{ | |||||
const LV2_Descriptor*& lv2Desc(*it); | |||||
delete[] lv2Desc->URI; | |||||
delete lv2Desc; | |||||
} | |||||
descs.clear(); | |||||
lv2Descs.clear(); | |||||
} | |||||
NonRtList<const PluginDescriptor*> descs; | |||||
NonRtList<const LV2_Descriptor*> lv2Descs; | |||||
}; | |||||
static PluginListManager sPluginDescsMgr; | |||||
void carla_register_native_plugin(const PluginDescriptor* desc) | |||||
{ | |||||
sPluginDescsMgr.descs.append(desc); | |||||
} | |||||
// ----------------------------------------------------------------------- |
@@ -0,0 +1,450 @@ | |||||
/* | |||||
* Carla Native Plugins | |||||
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||||
* | |||||
* This program is free software; you can redistribute it and/or | |||||
* modify it under the terms of the GNU General Public License as | |||||
* published by the Free Software Foundation; either version 2 of | |||||
* the License, or any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||||
*/ | |||||
#include "carla-native-base.cpp" | |||||
#include "JuceHeader.h" | |||||
#include "lv2/atom.h" | |||||
#include "lv2/buf-size.h" | |||||
#include "lv2/instance-access.h" | |||||
#include "lv2/midi.h" | |||||
#include "lv2/options.h" | |||||
#include "lv2/state.h" | |||||
#include "lv2/time.h" | |||||
#include "lv2/ui.h" | |||||
#include "lv2/units.h" | |||||
#include "lv2/urid.h" | |||||
#include "lv2/lv2_external_ui.h" | |||||
#include <fstream> | |||||
#if JUCE_WINDOWS | |||||
# define PLUGIN_EXT ".dll" | |||||
#elif JUCE_MAC | |||||
# define PLUGIN_EXT ".dylib" | |||||
#else | |||||
# define PLUGIN_EXT ".so" | |||||
#endif | |||||
using juce::String; | |||||
using juce::StringArray; | |||||
using juce::juce_wchar; | |||||
// ----------------------------------------------------------------------- | |||||
// Converts a parameter name to an LV2 compatible symbol | |||||
static StringArray gUsedSymbols; | |||||
const String nameToSymbol(const String& name, const uint32_t portIndex) | |||||
{ | |||||
String symbol, trimmedName = name.trimStart().trimEnd().toLowerCase(); | |||||
if (trimmedName.isEmpty()) | |||||
{ | |||||
symbol += "lv2_port_"; | |||||
symbol += String(portIndex+1); | |||||
} | |||||
else | |||||
{ | |||||
for (int i=0; i < trimmedName.length(); ++i) | |||||
{ | |||||
const juce_wchar c = trimmedName[i]; | |||||
if (i == 0 && std::isdigit(c)) | |||||
symbol += "_"; | |||||
else if (std::isalpha(c) || std::isdigit(c)) | |||||
symbol += c; | |||||
else | |||||
symbol += "_"; | |||||
} | |||||
} | |||||
// Do not allow identical symbols | |||||
if (gUsedSymbols.contains(symbol)) | |||||
{ | |||||
int offset = 2; | |||||
String offsetStr = "_2"; | |||||
symbol += offsetStr; | |||||
while (gUsedSymbols.contains(symbol)) | |||||
{ | |||||
offset += 1; | |||||
String newOffsetStr = "_" + String(offset); | |||||
symbol = symbol.replace(offsetStr, newOffsetStr); | |||||
offsetStr = newOffsetStr; | |||||
} | |||||
} | |||||
gUsedSymbols.add(symbol); | |||||
return symbol; | |||||
} | |||||
// ----------------------------------------------------------------------- | |||||
void writeManifestFile() | |||||
{ | |||||
String text; | |||||
// ------------------------------------------------------------------- | |||||
// Header | |||||
text += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n"; | |||||
text += "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n"; | |||||
text += "@prefix ui: <" LV2_UI_PREFIX "> .\n"; | |||||
text += "\n"; | |||||
// ------------------------------------------------------------------- | |||||
// Plugins | |||||
for (NonRtList<const PluginDescriptor*>::Itenerator it = sPluginDescsMgr.descs.begin(); it.valid(); it.next()) | |||||
{ | |||||
const PluginDescriptor*& pluginDesc(*it); | |||||
const String label(pluginDesc->label); | |||||
if (label == "carla") | |||||
text += "<http://kxstudio.sf.net/carla>\n"; | |||||
else | |||||
text += "<http://kxstudio.sf.net/carla/plugins/" + label + ">\n"; | |||||
text += " a lv2:Plugin ;\n"; | |||||
text += " lv2:binary <carla-native" PLUGIN_EXT "> ;\n"; | |||||
text += " rdfs:seeAlso <" + label + ".ttl> .\n"; | |||||
text += "\n"; | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
// UI | |||||
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:requiredFeature <" LV2_INSTANCE_ACCESS_URI "> .\n"; | |||||
// ------------------------------------------------------------------- | |||||
// Write file now | |||||
std::fstream manifest("carla-native.lv2/manifest.ttl", std::ios::out); | |||||
manifest << text.toRawUTF8(); | |||||
manifest.close(); | |||||
} | |||||
// ----------------------------------------------------------------------- | |||||
static uint32_t host_getBufferSize(HostHandle) { return 512; } | |||||
static double host_getSampleRate(HostHandle) { return 44100.0; } | |||||
static bool host_isOffline(HostHandle) { return true; } | |||||
static intptr_t host_dispatcher(HostHandle, HostDispatcherOpcode, int32_t, intptr_t, void*, float) { return 0; } | |||||
void writePluginFile(const PluginDescriptor* const pluginDesc) | |||||
{ | |||||
const String pluginLabel(pluginDesc->label); | |||||
const String pluginFile("carla-native.lv2/" + pluginLabel + ".ttl"); | |||||
uint32_t portIndex = 0; | |||||
String text; | |||||
gUsedSymbols.clear(); | |||||
carla_stdout("Generating data for %s...", pluginDesc->name); | |||||
// ------------------------------------------------------------------- | |||||
// Init plugin | |||||
HostDescriptor hostDesc; | |||||
hostDesc.handle = nullptr; | |||||
hostDesc.resourceDir = ""; | |||||
hostDesc.uiName = ""; | |||||
hostDesc.get_buffer_size = host_getBufferSize; | |||||
hostDesc.get_sample_rate = host_getSampleRate; | |||||
hostDesc.is_offline = host_isOffline; | |||||
hostDesc.get_time_info = nullptr; | |||||
hostDesc.write_midi_event = nullptr; | |||||
hostDesc.ui_parameter_changed = nullptr; | |||||
hostDesc.ui_midi_program_changed = nullptr; | |||||
hostDesc.ui_custom_data_changed = nullptr; | |||||
hostDesc.ui_closed = nullptr; | |||||
hostDesc.ui_open_file = nullptr; | |||||
hostDesc.ui_save_file = nullptr; | |||||
hostDesc.dispatcher = host_dispatcher; | |||||
PluginHandle pluginHandle = pluginDesc->instantiate(&hostDesc); | |||||
CARLA_SAFE_ASSERT_RETURN(pluginHandle != nullptr,) | |||||
// ------------------------------------------------------------------- | |||||
// Header | |||||
text += "@prefix atom: <" LV2_ATOM_PREFIX "> .\n"; | |||||
text += "@prefix doap: <http://usefulinc.com/ns/doap#> .\n"; | |||||
text += "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n"; | |||||
text += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n"; | |||||
text += "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n"; | |||||
text += "@prefix ui: <" LV2_UI_PREFIX "> .\n"; | |||||
text += "@prefix unit: <" LV2_UNITS_PREFIX "> .\n"; | |||||
text += "\n"; | |||||
// ------------------------------------------------------------------- | |||||
// Plugin | |||||
if (pluginLabel == "carla") | |||||
text += "<http://kxstudio.sf.net/carla>\n"; | |||||
else | |||||
text += "<http://kxstudio.sf.net/carla/plugins/" + pluginLabel + ">\n"; | |||||
//text += " a " + getPluginType() + " ;\n"; | |||||
text += " lv2:requiredFeature <" LV2_BUF_SIZE__boundedBlockLength "> ,\n"; | |||||
text += " <" LV2_URID__map "> ;\n"; | |||||
text += " lv2:extensionData <" LV2_OPTIONS__interface "> ,\n"; | |||||
text += " <" LV2_STATE__interface "> ;\n"; | |||||
text += "\n"; | |||||
// ------------------------------------------------------------------- | |||||
// UIs | |||||
if (pluginDesc->hints & PLUGIN_HAS_GUI) | |||||
{ | |||||
text += " ui:ui <http://kxstudio.sf.net/carla#UI> ;\n"; | |||||
text += "\n"; | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
// MIDI inputs | |||||
for (uint32_t i=0; i < pluginDesc->midiIns; ++i) | |||||
{ | |||||
if (i == 0) | |||||
text += " lv2:port [\n"; | |||||
else | |||||
text += " [\n"; | |||||
text += " a lv2:InputPort, atom:AtomPort ;\n"; | |||||
text += " atom:bufferType atom:Sequence ;\n"; | |||||
if (i == 0) | |||||
{ | |||||
text += " atom:supports <" LV2_MIDI__MidiEvent "> ,\n"; | |||||
text += " <" LV2_TIME__Position "> ;\n"; | |||||
text += " lv2:designation lv2:control ;\n"; | |||||
} | |||||
else | |||||
{ | |||||
text += " atom:supports <" LV2_MIDI__MidiEvent "> ;\n"; | |||||
} | |||||
text += " lv2:index " + String(portIndex++) + " ;\n"; | |||||
if (pluginDesc->midiIns > 1) | |||||
{ | |||||
text += " lv2:symbol \"lv2_events_in_" + String(i+1) + "\" ;\n"; | |||||
text += " lv2:name \"Events Input #" + String(i+1) + "\" ;\n"; | |||||
} | |||||
else | |||||
{ | |||||
text += " lv2:symbol \"lv2_events_in\" ;\n"; | |||||
text += " lv2:name \"Events Input\" ;\n"; | |||||
} | |||||
if (i+1 == pluginDesc->midiIns) | |||||
text += " ] ;\n\n"; | |||||
else | |||||
text += " ] ,\n"; | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
// MIDI outputs | |||||
for (uint32_t i=0; i < pluginDesc->midiOuts; ++i) | |||||
{ | |||||
if (i == 0) | |||||
text += " lv2:port [\n"; | |||||
else | |||||
text += " [\n"; | |||||
text += " a lv2:OutputPort, atom:AtomPort ;\n"; | |||||
text += " atom:bufferType atom:Sequence ;\n"; | |||||
text += " atom:supports <" LV2_MIDI__MidiEvent "> ;\n"; | |||||
text += " lv2:index " + String(portIndex++) + " ;\n"; | |||||
if (pluginDesc->midiOuts > 1) | |||||
{ | |||||
text += " lv2:symbol \"lv2_midi_out_" + String(i+1) + "\" ;\n"; | |||||
text += " lv2:name \"MIDI Output #" + String(i+1) + "\" ;\n"; | |||||
} | |||||
else | |||||
{ | |||||
text += " lv2:symbol \"lv2_midi_out\" ;\n"; | |||||
text += " lv2:name \"MIDI Output\" ;\n"; | |||||
} | |||||
if (i+1 == pluginDesc->midiOuts) | |||||
text += " ] ;\n\n"; | |||||
else | |||||
text += " ] ,\n"; | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
// Freewheel port | |||||
text += " lv2:port [\n"; | |||||
text += " a lv2:InputPort, lv2:ControlPort ;\n"; | |||||
text += " lv2:index " + String(portIndex++) + " ;\n"; | |||||
text += " lv2:symbol \"lv2_freewheel\" ;\n"; | |||||
text += " lv2:name \"Freewheel\" ;\n"; | |||||
text += " lv2:default 0.0 ;\n"; | |||||
text += " lv2:minimum 0.0 ;\n"; | |||||
text += " lv2:maximum 1.0 ;\n"; | |||||
text += " lv2:designation <" LV2_CORE__freeWheeling "> ;\n"; | |||||
text += " lv2:portProperty lv2:toggled ;\n"; | |||||
text += " ] ;\n"; | |||||
text += "\n"; | |||||
// ------------------------------------------------------------------- | |||||
// Audio inputs | |||||
for (uint32_t i=0; i < pluginDesc->audioIns; ++i) | |||||
{ | |||||
if (i == 0) | |||||
text += " lv2:port [\n"; | |||||
else | |||||
text += " [\n"; | |||||
text += " a lv2:InputPort, lv2:AudioPort ;\n"; | |||||
text += " lv2:index " + String(portIndex++) + " ;\n"; | |||||
text += " lv2:symbol \"lv2_audio_in_" + String(i+1) + "\" ;\n"; | |||||
text += " lv2:name \"Audio Input " + String(i+1) + "\" ;\n"; | |||||
if (i+1 == pluginDesc->audioIns) | |||||
text += " ] ;\n\n"; | |||||
else | |||||
text += " ] ,\n"; | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
// Audio outputs | |||||
for (uint32_t i=0; i < pluginDesc->audioOuts; ++i) | |||||
{ | |||||
if (i == 0) | |||||
text += " lv2:port [\n"; | |||||
else | |||||
text += " [\n"; | |||||
text += " a lv2:OutputPort, lv2:AudioPort ;\n"; | |||||
text += " lv2:index " + String(portIndex++) + " ;\n"; | |||||
text += " lv2:symbol \"lv2_audio_out_" + String(i+1) + "\" ;\n"; | |||||
text += " lv2:name \"Audio Output " + String(i+1) + "\" ;\n"; | |||||
if (i+1 == pluginDesc->audioOuts) | |||||
text += " ] ;\n\n"; | |||||
else | |||||
text += " ] ,\n"; | |||||
} | |||||
// ------------------------------------------------------------------- | |||||
// Parameters | |||||
const uint32_t paramCount(pluginDesc->get_parameter_count != nullptr ? pluginDesc->get_parameter_count(pluginHandle) : 0); | |||||
if (paramCount > 0) | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(pluginDesc->get_parameter_info != nullptr,) | |||||
CARLA_SAFE_ASSERT_RETURN(pluginDesc->get_parameter_value != nullptr,) | |||||
} | |||||
for (uint32_t i=0; i < paramCount; ++i) | |||||
{ | |||||
const Parameter* paramInfo(pluginDesc->get_parameter_info(pluginHandle, i)); | |||||
const String paramName(paramInfo->name); | |||||
const String paramUnit(paramInfo->unit != nullptr ? paramInfo->unit : ""); | |||||
const float paramValue(pluginDesc->get_parameter_value(pluginHandle, i)); | |||||
CARLA_SAFE_ASSERT_RETURN(paramInfo != nullptr,) | |||||
if (i == 0) | |||||
text += " lv2:port [\n"; | |||||
else | |||||
text += " [\n"; | |||||
text += " a lv2:InputPort, lv2:ControlPort ;\n"; | |||||
text += " lv2:index " + String(portIndex++) + " ;\n"; | |||||
text += " lv2:symbol \"" + nameToSymbol(paramName, i) + "\" ;\n"; | |||||
if (paramName.isNotEmpty()) | |||||
text += " lv2:name \"" + paramName + "\" ;\n"; | |||||
else | |||||
text += " lv2:name \"Port " + String(i+1) + "\" ;\n"; | |||||
text += " lv2:default " + String::formatted("%f", paramValue) + " ;\n"; | |||||
text += " lv2:minimum 0.0 ;\n"; | |||||
text += " lv2:maximum 1.0 ;\n"; | |||||
if (paramUnit.isNotEmpty()) | |||||
{ | |||||
text += " units:unit [\n"; | |||||
text += " a units:Unit ;\n"; | |||||
text += " rdfs:label \"" + paramUnit + "\" ;\n"; | |||||
text += " units:symbol \"" + paramUnit + "\" ;\n"; | |||||
text += " units:render \"%f " + paramUnit + "\" ;\n"; | |||||
text += " ] ;\n"; | |||||
} | |||||
// if (! filter->isParameterAutomatable(i)) | |||||
// text += " lv2:portProperty <" LV2_PORT_PROPS__expensive "> ;\n"; | |||||
if (i+1 == paramCount) | |||||
text += " ] ;\n\n"; | |||||
else | |||||
text += " ] ,\n"; | |||||
} | |||||
text += " doap:name \"" + String(pluginDesc->name) + "\" ;\n"; | |||||
text += " doap:maintainer [ foaf:name \"" + String(pluginDesc->maker) + "\" ] .\n"; | |||||
// ------------------------------------------------------------------- | |||||
// Write file now | |||||
std::fstream pluginStream(pluginFile.toRawUTF8(), std::ios::out); | |||||
pluginStream << text.toRawUTF8(); | |||||
pluginStream.close(); | |||||
// ------------------------------------------------------------------- | |||||
// Cleanup plugin | |||||
if (pluginDesc->cleanup != nullptr) | |||||
pluginDesc->cleanup(pluginHandle); | |||||
} | |||||
// ----------------------------------------------------------------------- | |||||
int main() | |||||
{ | |||||
writeManifestFile(); | |||||
for (NonRtList<const PluginDescriptor*>::Itenerator it = sPluginDescsMgr.descs.begin(); it.valid(); it.next()) | |||||
{ | |||||
const PluginDescriptor*& pluginDesc(*it); | |||||
writePluginFile(pluginDesc); | |||||
} | |||||
carla_stdout("Done."); | |||||
return 0; | |||||
} | |||||
// ----------------------------------------------------------------------- |
@@ -0,0 +1,91 @@ | |||||
/* | |||||
* Carla Native Plugins | |||||
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||||
* | |||||
* This program is free software; you can redistribute it and/or | |||||
* modify it under the terms of the GNU General Public License as | |||||
* published by the Free Software Foundation; either version 2 of | |||||
* the License, or any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU General Public License for more details. | |||||
* | |||||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||||
*/ | |||||
#include "carla-native-base.cpp" | |||||
#include "CarlaString.hpp" | |||||
// ----------------------------------------------------------------------- | |||||
// LV2 descriptor functions | |||||
// ----------------------------------------------------------------------- | |||||
// Static LV2 Descriptor objects | |||||
// ----------------------------------------------------------------------- | |||||
// Startup code | |||||
// CARLA_EXPORT void lv2_generate_ttl(const char* basename) | |||||
// { | |||||
// createLv2Files (basename); | |||||
// } | |||||
CARLA_EXPORT const LV2_Descriptor* lv2_descriptor(uint32_t index) | |||||
{ | |||||
if (index >= sPluginDescsMgr.descs.count()) | |||||
return nullptr; | |||||
if (index < sPluginDescsMgr.lv2Descs.count()) | |||||
return sPluginDescsMgr.lv2Descs.getAt(index); | |||||
const PluginDescriptor*& pluginDesc(sPluginDescsMgr.descs.getAt(index)); | |||||
CarlaString tmpURI; | |||||
if (std::strcmp(pluginDesc->label, "carla") == 0) | |||||
{ | |||||
tmpURI = "http://kxstudio.sf.net/carla"; | |||||
} | |||||
else | |||||
{ | |||||
tmpURI = "http://kxstudio.sf.net/carla/plugins/"; | |||||
tmpURI += pluginDesc->label; | |||||
} | |||||
LV2_Descriptor* lv2Desc(new LV2_Descriptor); | |||||
lv2Desc->URI = carla_strdup(tmpURI); | |||||
lv2Desc->instantiate = nullptr; | |||||
lv2Desc->connect_port = nullptr; | |||||
lv2Desc->activate = nullptr; | |||||
lv2Desc->run = nullptr; | |||||
lv2Desc->deactivate = nullptr; | |||||
lv2Desc->cleanup = nullptr; | |||||
lv2Desc->extension_data = nullptr; | |||||
sPluginDescsMgr.lv2Descs.append(lv2Desc); | |||||
return lv2Desc; | |||||
} | |||||
// CARLA_EXPORT const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index) | |||||
// { | |||||
// switch (index) | |||||
// { | |||||
// case 0: | |||||
// return &JuceLv2UI_External; | |||||
// case 1: | |||||
// return &JuceLv2UI_Parent; | |||||
// default: | |||||
// return nullptr; | |||||
// } | |||||
// } | |||||
// ----------------------------------------------------------------------- | |||||
int main() | |||||
{ | |||||
return 0; | |||||
} |