| @@ -63,6 +63,8 @@ carla-discovery-native | |||
| carla-discovery-posix32 | |||
| carla-discovery-posix64 | |||
| carla-native-export | |||
| data/windows/Carla | |||
| data/windows/CarlaControl | |||
| 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) $< -DMOC_PARSING -o $@ | |||
| @@ -262,6 +262,7 @@ static const PluginDescriptor audiofileDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_audiofile() | |||
| { | |||
| carla_register_native_plugin(&audiofileDesc); | |||
| @@ -50,6 +50,7 @@ END_NAMESPACE_DISTRHO | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_3BandEQ() | |||
| { | |||
| USE_NAMESPACE_DISTRHO | |||
| @@ -50,6 +50,7 @@ END_NAMESPACE_DISTRHO | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_3BandSplitter() | |||
| { | |||
| USE_NAMESPACE_DISTRHO | |||
| @@ -50,6 +50,7 @@ END_NAMESPACE_DISTRHO | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_Nekobi() | |||
| { | |||
| USE_NAMESPACE_DISTRHO | |||
| @@ -49,6 +49,7 @@ END_NAMESPACE_DISTRHO | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_Notes() | |||
| { | |||
| USE_NAMESPACE_DISTRHO | |||
| @@ -50,6 +50,7 @@ END_NAMESPACE_DISTRHO | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_PingPongPan() | |||
| { | |||
| USE_NAMESPACE_DISTRHO | |||
| @@ -50,6 +50,7 @@ END_NAMESPACE_DISTRHO | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_StereoEnhancer() | |||
| { | |||
| USE_NAMESPACE_DISTRHO | |||
| @@ -237,6 +237,7 @@ static const PluginDescriptor midifileDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_midifile() | |||
| { | |||
| carla_register_native_plugin(&midifileDesc); | |||
| @@ -251,6 +251,7 @@ static const PluginDescriptor midiSequencerDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_midiSequencer() | |||
| { | |||
| carla_register_native_plugin(&midiSequencerDesc); | |||
| @@ -177,6 +177,7 @@ static const PluginDescriptor sunvoxfileDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_sunvoxfile() | |||
| { | |||
| carla_register_native_plugin(&sunvoxfileDesc); | |||
| @@ -2169,6 +2169,7 @@ static const PluginDescriptor zynaddsubfxDesc = { | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_EXPORT | |||
| void carla_register_native_plugin_zynaddsubfx() | |||
| { | |||
| 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_Nekobi(); | |||
| void carla_register_native_plugin_PingPongPan(); | |||
| // void carla_register_native_plugin_StereoEnhancer(); | |||
| void carla_register_native_plugin_StereoEnhancer(); | |||
| #endif | |||
| // DISTRHO plugins (Qt) | |||
| // void carla_register_native_plugin_Notes(); | |||
| void carla_register_native_plugin_Notes(); | |||
| #ifdef WANT_ZYNADDSUBFX | |||
| // ZynAddSubFX | |||
| @@ -104,11 +104,11 @@ void carla_register_all_plugins() | |||
| carla_register_native_plugin_3BandSplitter(); | |||
| carla_register_native_plugin_Nekobi(); | |||
| carla_register_native_plugin_PingPongPan(); | |||
| //carla_register_native_plugin_StereoEnhancer(); // unfinished | |||
| carla_register_native_plugin_StereoEnhancer(); // unfinished | |||
| #endif | |||
| // DISTRHO plugins (Qt) | |||
| //carla_register_native_plugin_Notes(); // unfinished | |||
| carla_register_native_plugin_Notes(); // unfinished | |||
| #ifdef WANT_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) | |||
| ifeq ($(HAVE_QT4),true) | |||
| @@ -20,6 +20,8 @@ | |||
| #include "CarlaUtils.hpp" | |||
| #include <new> | |||
| extern "C" { | |||
| #include "rtmempool/list.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) | |||
| BUILD_CXX_FLAGS += $(shell pkg-config --cflags QtCore QtGui) | |||
| @@ -6,6 +6,26 @@ | |||
| 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 | |||
| @@ -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 += ../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) | |||
| LIBS += ../libs/lilv.a | |||
| LIBS += ../modules/lilv.a | |||
| endif | |||
| 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 | |||
| # -------------------------------------------------------------- | |||
| 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 $@ | |||
| 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; | |||
| } | |||