| @@ -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; | |||||
| } | |||||