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