Browse Source

Continue cleanup; Initial Carla-as-plugin code (new version)

tags/1.9.4
falkTX 11 years ago
parent
commit
a30575155f
21 changed files with 779 additions and 35 deletions
  1. +2
    -0
      .gitignore
  2. +5
    -5
      source/backend/native/Makefile
  3. +1
    -0
      source/backend/native/audio-file.cpp
  4. +1
    -0
      source/backend/native/distrho-3bandeq.cpp
  5. +1
    -0
      source/backend/native/distrho-3bandsplitter.cpp
  6. +1
    -0
      source/backend/native/distrho-nekobi.cpp
  7. +1
    -0
      source/backend/native/distrho-notes.cpp
  8. +1
    -0
      source/backend/native/distrho-pingpongpan.cpp
  9. +1
    -0
      source/backend/native/distrho-stereoenhancer.cpp
  10. +1
    -0
      source/backend/native/midi-file.cpp
  11. +1
    -0
      source/backend/native/midi-sequencer.cpp
  12. +1
    -0
      source/backend/native/sunvox-file.cpp
  13. +1
    -0
      source/backend/native/zynaddsubfx.cpp
  14. +4
    -4
      source/backend/plugin/NativePlugin.cpp
  15. +1
    -1
      source/backend/standalone/Makefile
  16. +2
    -0
      source/modules/utils/RtList.hpp
  17. +1
    -1
      source/modules/widgets/Makefile
  18. +67
    -24
      source/plugin/Makefile
  19. +145
    -0
      source/plugin/carla-native-base.cpp
  20. +450
    -0
      source/plugin/carla-native-export.cpp
  21. +91
    -0
      source/plugin/carla-native-plugin.cpp

+ 2
- 0
.gitignore View File

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


+ 5
- 5
source/backend/native/Makefile View File

@@ -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 $@


+ 1
- 0
source/backend/native/audio-file.cpp View File

@@ -262,6 +262,7 @@ static const PluginDescriptor audiofileDesc = {

// -----------------------------------------------------------------------

CARLA_EXPORT
void carla_register_native_plugin_audiofile()
{
carla_register_native_plugin(&audiofileDesc);


+ 1
- 0
source/backend/native/distrho-3bandeq.cpp View File

@@ -50,6 +50,7 @@ END_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------

CARLA_EXPORT
void carla_register_native_plugin_3BandEQ()
{
USE_NAMESPACE_DISTRHO


+ 1
- 0
source/backend/native/distrho-3bandsplitter.cpp View File

@@ -50,6 +50,7 @@ END_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------

CARLA_EXPORT
void carla_register_native_plugin_3BandSplitter()
{
USE_NAMESPACE_DISTRHO


+ 1
- 0
source/backend/native/distrho-nekobi.cpp View File

@@ -50,6 +50,7 @@ END_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------

CARLA_EXPORT
void carla_register_native_plugin_Nekobi()
{
USE_NAMESPACE_DISTRHO


+ 1
- 0
source/backend/native/distrho-notes.cpp View File

@@ -49,6 +49,7 @@ END_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------

CARLA_EXPORT
void carla_register_native_plugin_Notes()
{
USE_NAMESPACE_DISTRHO


+ 1
- 0
source/backend/native/distrho-pingpongpan.cpp View File

@@ -50,6 +50,7 @@ END_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------

CARLA_EXPORT
void carla_register_native_plugin_PingPongPan()
{
USE_NAMESPACE_DISTRHO


+ 1
- 0
source/backend/native/distrho-stereoenhancer.cpp View File

@@ -50,6 +50,7 @@ END_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------

CARLA_EXPORT
void carla_register_native_plugin_StereoEnhancer()
{
USE_NAMESPACE_DISTRHO


+ 1
- 0
source/backend/native/midi-file.cpp View File

@@ -237,6 +237,7 @@ static const PluginDescriptor midifileDesc = {

// -----------------------------------------------------------------------

CARLA_EXPORT
void carla_register_native_plugin_midifile()
{
carla_register_native_plugin(&midifileDesc);


+ 1
- 0
source/backend/native/midi-sequencer.cpp View File

@@ -251,6 +251,7 @@ static const PluginDescriptor midiSequencerDesc = {

// -----------------------------------------------------------------------

CARLA_EXPORT
void carla_register_native_plugin_midiSequencer()
{
carla_register_native_plugin(&midiSequencerDesc);


+ 1
- 0
source/backend/native/sunvox-file.cpp View File

@@ -177,6 +177,7 @@ static const PluginDescriptor sunvoxfileDesc = {

// -----------------------------------------------------------------------

CARLA_EXPORT
void carla_register_native_plugin_sunvoxfile()
{
carla_register_native_plugin(&sunvoxfileDesc);


+ 1
- 0
source/backend/native/zynaddsubfx.cpp View File

@@ -2169,6 +2169,7 @@ static const PluginDescriptor zynaddsubfxDesc = {

// -----------------------------------------------------------------------

CARLA_EXPORT
void carla_register_native_plugin_zynaddsubfx()
{
carla_register_native_plugin(&fxAlienWahDesc);


+ 4
- 4
source/backend/plugin/NativePlugin.cpp View File

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


+ 1
- 1
source/backend/standalone/Makefile View File

@@ -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)


+ 2
- 0
source/modules/utils/RtList.hpp View File

@@ -20,6 +20,8 @@

#include "CarlaUtils.hpp"

#include <new>

extern "C" {
#include "rtmempool/list.h"
#include "rtmempool/rtmempool.h"


+ 1
- 1
source/modules/widgets/Makefile View File

@@ -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)


+ 67
- 24
source/plugin/Makefile View File

@@ -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 $*

+ 145
- 0
source/plugin/carla-native-base.cpp View File

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

// -----------------------------------------------------------------------

+ 450
- 0
source/plugin/carla-native-export.cpp View File

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

// -----------------------------------------------------------------------

+ 91
- 0
source/plugin/carla-native-plugin.cpp View File

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

Loading…
Cancel
Save