Browse Source

More work on internal plugins and lv2 export

tags/1.9.4
falkTX 11 years ago
parent
commit
119a3b5ac4
10 changed files with 522 additions and 231 deletions
  1. +34
    -33
      .gitignore
  2. +6
    -10
      source/backend/Makefile.mk
  3. +3
    -6
      source/backend/plugin/NativePlugin.cpp
  4. +3
    -2
      source/includes/lv2/atom-util.h
  5. +17
    -16
      source/modules/carla_native/Makefile
  6. +46
    -48
      source/plugin/Makefile
  7. +21
    -23
      source/plugin/carla-native-base.cpp
  8. +32
    -6
      source/plugin/carla-native-export.cpp
  9. +353
    -85
      source/plugin/carla-native-plugin.cpp
  10. +7
    -2
      source/utils/CarlaString.hpp

+ 34
- 33
.gitignore View File

@@ -50,12 +50,13 @@ carla-bridge-native
carla-bridge-posix32 carla-bridge-posix32
carla-bridge-posix64 carla-bridge-posix64
carla-bridge-lv2-cocoa carla-bridge-lv2-cocoa
carla-bridge-lv2-external
carla-bridge-lv2-gtk2 carla-bridge-lv2-gtk2
carla-bridge-lv2-gtk3 carla-bridge-lv2-gtk3
carla-bridge-lv2-qt4 carla-bridge-lv2-qt4
carla-bridge-lv2-qt5 carla-bridge-lv2-qt5
carla-bridge-lv2-x11 carla-bridge-lv2-x11
carla-bridge-vst-cocoa
carla-bridge-vst-mac
carla-bridge-vst-x11 carla-bridge-vst-x11


carla-discovery-qtcreator carla-discovery-qtcreator
@@ -90,38 +91,38 @@ src/dist/
*build-*Release/ *build-*Release/


# ZynAddSubFX UI # ZynAddSubFX UI
source/backend/native/zynaddsubfx/UI/ADnoteUI.cpp
source/backend/native/zynaddsubfx/UI/ADnoteUI.h
source/backend/native/zynaddsubfx/UI/BankUI.cpp
source/backend/native/zynaddsubfx/UI/BankUI.h
source/backend/native/zynaddsubfx/UI/ConfigUI.cpp
source/backend/native/zynaddsubfx/UI/ConfigUI.h
source/backend/native/zynaddsubfx/UI/EffUI.cpp
source/backend/native/zynaddsubfx/UI/EffUI.h
source/backend/native/zynaddsubfx/UI/EnvelopeUI.cpp
source/backend/native/zynaddsubfx/UI/EnvelopeUI.h
source/backend/native/zynaddsubfx/UI/FilterUI.cpp
source/backend/native/zynaddsubfx/UI/FilterUI.h
source/backend/native/zynaddsubfx/UI/LFOUI.cpp
source/backend/native/zynaddsubfx/UI/LFOUI.h
source/backend/native/zynaddsubfx/UI/MasterUI.cpp
source/backend/native/zynaddsubfx/UI/MasterUI.h
source/backend/native/zynaddsubfx/UI/MicrotonalUI.cpp
source/backend/native/zynaddsubfx/UI/MicrotonalUI.h
source/backend/native/zynaddsubfx/UI/OscilGenUI.cpp
source/backend/native/zynaddsubfx/UI/OscilGenUI.h
source/backend/native/zynaddsubfx/UI/PADnoteUI.cpp
source/backend/native/zynaddsubfx/UI/PADnoteUI.h
source/backend/native/zynaddsubfx/UI/PartUI.cpp
source/backend/native/zynaddsubfx/UI/PartUI.h
source/backend/native/zynaddsubfx/UI/PresetsUI.cpp
source/backend/native/zynaddsubfx/UI/PresetsUI.h
source/backend/native/zynaddsubfx/UI/ResonanceUI.cpp
source/backend/native/zynaddsubfx/UI/ResonanceUI.h
source/backend/native/zynaddsubfx/UI/SUBnoteUI.cpp
source/backend/native/zynaddsubfx/UI/SUBnoteUI.h
source/backend/native/zynaddsubfx/UI/VirKeyboard.cpp
source/backend/native/zynaddsubfx/UI/VirKeyboard.h
source/modules/carla_native/zynaddsubfx/UI/ADnoteUI.cpp
source/modules/carla_native/zynaddsubfx/UI/ADnoteUI.h
source/modules/carla_native/zynaddsubfx/UI/BankUI.cpp
source/modules/carla_native/zynaddsubfx/UI/BankUI.h
source/modules/carla_native/zynaddsubfx/UI/ConfigUI.cpp
source/modules/carla_native/zynaddsubfx/UI/ConfigUI.h
source/modules/carla_native/zynaddsubfx/UI/EffUI.cpp
source/modules/carla_native/zynaddsubfx/UI/EffUI.h
source/modules/carla_native/zynaddsubfx/UI/EnvelopeUI.cpp
source/modules/carla_native/zynaddsubfx/UI/EnvelopeUI.h
source/modules/carla_native/zynaddsubfx/UI/FilterUI.cpp
source/modules/carla_native/zynaddsubfx/UI/FilterUI.h
source/modules/carla_native/zynaddsubfx/UI/LFOUI.cpp
source/modules/carla_native/zynaddsubfx/UI/LFOUI.h
source/modules/carla_native/zynaddsubfx/UI/MasterUI.cpp
source/modules/carla_native/zynaddsubfx/UI/MasterUI.h
source/modules/carla_native/zynaddsubfx/UI/MicrotonalUI.cpp
source/modules/carla_native/zynaddsubfx/UI/MicrotonalUI.h
source/modules/carla_native/zynaddsubfx/UI/OscilGenUI.cpp
source/modules/carla_native/zynaddsubfx/UI/OscilGenUI.h
source/modules/carla_native/zynaddsubfx/UI/PADnoteUI.cpp
source/modules/carla_native/zynaddsubfx/UI/PADnoteUI.h
source/modules/carla_native/zynaddsubfx/UI/PartUI.cpp
source/modules/carla_native/zynaddsubfx/UI/PartUI.h
source/modules/carla_native/zynaddsubfx/UI/PresetsUI.cpp
source/modules/carla_native/zynaddsubfx/UI/PresetsUI.h
source/modules/carla_native/zynaddsubfx/UI/ResonanceUI.cpp
source/modules/carla_native/zynaddsubfx/UI/ResonanceUI.h
source/modules/carla_native/zynaddsubfx/UI/SUBnoteUI.cpp
source/modules/carla_native/zynaddsubfx/UI/SUBnoteUI.h
source/modules/carla_native/zynaddsubfx/UI/VirKeyboard.cpp
source/modules/carla_native/zynaddsubfx/UI/VirKeyboard.h


# Other # Other
source/includes/rewire/ source/includes/rewire/


+ 6
- 10
source/backend/Makefile.mk View File

@@ -8,13 +8,7 @@ include ../../Makefile.mk


# -------------------------------------------------------------- # --------------------------------------------------------------


BACKEND_FLAGS = -I. -I.. -I../../includes -I../../modules -I../../utils

BUILD_C_FLAGS += $(BACKEND_FLAGS)
BUILD_CXX_FLAGS += $(BACKEND_FLAGS)

# --------------------------------------------------------------

BUILD_CXX_FLAGS += -I. -I.. -I../../includes -I../../modules -I../../utils
BUILD_CXX_FLAGS += -DWANT_NATIVE BUILD_CXX_FLAGS += -DWANT_NATIVE


ifeq ($(CARLA_PLUGIN_SUPPORT),true) ifeq ($(CARLA_PLUGIN_SUPPORT),true)
@@ -42,9 +36,7 @@ ifeq ($(HAVE_LINUXSAMPLER),true)
BUILD_CXX_FLAGS += -DWANT_LINUXSAMPLER BUILD_CXX_FLAGS += -DWANT_LINUXSAMPLER
endif endif


ifeq ($(HAVE_OPENGL),true)
BUILD_CXX_FLAGS += -DWANT_OPENGL
endif
# --------------------------------------------------------------


ifeq ($(HAVE_AF_DEPS),true) ifeq ($(HAVE_AF_DEPS),true)
BUILD_CXX_FLAGS += -DWANT_AUDIOFILE BUILD_CXX_FLAGS += -DWANT_AUDIOFILE
@@ -57,6 +49,10 @@ ifeq ($(HAVE_MF_DEPS),true)
BUILD_CXX_FLAGS += -DWANT_MIDIFILE BUILD_CXX_FLAGS += -DWANT_MIDIFILE
endif endif


ifeq ($(HAVE_OPENGL),true)
BUILD_CXX_FLAGS += -DWANT_OPENGL
endif

ifeq ($(HAVE_ZYN_DEPS),true) ifeq ($(HAVE_ZYN_DEPS),true)
BUILD_CXX_FLAGS += -DWANT_ZYNADDSUBFX BUILD_CXX_FLAGS += -DWANT_ZYNADDSUBFX
ifeq ($(HAVE_ZYN_UI_DEPS),true) ifeq ($(HAVE_ZYN_UI_DEPS),true)


+ 3
- 6
source/backend/plugin/NativePlugin.cpp View File

@@ -2151,20 +2151,17 @@ protected:
return false; return false;
} }


if (fMidiEventCount >= MAX_MIDI_EVENTS*2)
return false;

// reverse-find first free event, and put it there // reverse-find first free event, and put it there
for (uint32_t i=(MAX_MIDI_EVENTS*2)-1; i >= fMidiEventCount; --i)
for (uint32_t i=(MAX_MIDI_EVENTS*2)-1; i > fMidiEventCount; --i)
{ {
if (fMidiEvents[i].data[0] == 0) if (fMidiEvents[i].data[0] == 0)
{ {
std::memcpy(&fMidiEvents[i], event, sizeof(::MidiEvent)); std::memcpy(&fMidiEvents[i], event, sizeof(::MidiEvent));
break;
return true;
} }
} }


return true;
return false;
} }


void handleUiParameterChanged(const uint32_t index, const float value) void handleUiParameterChanged(const uint32_t index, const float value)


+ 3
- 2
source/includes/lv2/atom-util.h View File

@@ -99,6 +99,7 @@ lv2_atom_sequence_is_end(const LV2_Atom_Sequence_Body* body,
static inline const LV2_Atom_Event* static inline const LV2_Atom_Event*
lv2_atom_sequence_next(const LV2_Atom_Event* i) lv2_atom_sequence_next(const LV2_Atom_Event* i)
{ {
if (!i) return NULL;
return (const LV2_Atom_Event*)((const uint8_t*)i return (const LV2_Atom_Event*)((const uint8_t*)i
+ sizeof(LV2_Atom_Event) + sizeof(LV2_Atom_Event)
+ lv2_atom_pad_size(i->body.size)); + lv2_atom_pad_size(i->body.size));
@@ -117,13 +118,13 @@ lv2_atom_sequence_next(const LV2_Atom_Event* i)
@endcode @endcode
*/ */
#define LV2_ATOM_SEQUENCE_FOREACH(seq, iter) \ #define LV2_ATOM_SEQUENCE_FOREACH(seq, iter) \
for (LV2_Atom_Event* (iter) = lv2_atom_sequence_begin(&(seq)->body); \
for (const LV2_Atom_Event* (iter) = lv2_atom_sequence_begin(&(seq)->body); \
!lv2_atom_sequence_is_end(&(seq)->body, (seq)->atom.size, (iter)); \ !lv2_atom_sequence_is_end(&(seq)->body, (seq)->atom.size, (iter)); \
(iter) = lv2_atom_sequence_next(iter)) (iter) = lv2_atom_sequence_next(iter))


/** Like LV2_ATOM_SEQUENCE_FOREACH but for a headerless sequence body. */ /** Like LV2_ATOM_SEQUENCE_FOREACH but for a headerless sequence body. */
#define LV2_ATOM_SEQUENCE_BODY_FOREACH(body, size, iter) \ #define LV2_ATOM_SEQUENCE_BODY_FOREACH(body, size, iter) \
for (LV2_Atom_Event* (iter) = lv2_atom_sequence_begin(body); \
for (const LV2_Atom_Event* (iter) = lv2_atom_sequence_begin(body); \
!lv2_atom_sequence_is_end(body, size, (iter)); \ !lv2_atom_sequence_is_end(body, size, (iter)); \
(iter) = lv2_atom_sequence_next(iter)) (iter) = lv2_atom_sequence_next(iter))




+ 17
- 16
source/modules/carla_native/Makefile View File

@@ -8,9 +8,17 @@ include ../../Makefile.mk


# -------------------------------------------------------------- # --------------------------------------------------------------


BUILD_C_FLAGS += -I. -I.. -I../../includes
BUILD_C_FLAGS += -I. -I../../includes
BUILD_CXX_FLAGS += -I. -I.. -I../../includes -I../../utils BUILD_CXX_FLAGS += -I. -I.. -I../../includes -I../../utils


# --------------------------------------------------------------

ifeq ($(HAVE_OPENGL),true)
GL_CXX_FLAGS = $(BUILD_CXX_FLAGS)
GL_CXX_FLAGS += -I../distrho
GL_CXX_FLAGS += $(shell pkg-config --cflags gl)
endif

ifeq ($(HAVE_AF_DEPS),true) ifeq ($(HAVE_AF_DEPS),true)
AF_C_FLAGS = $(BUILD_C_FLAGS) AF_C_FLAGS = $(BUILD_C_FLAGS)
AF_C_FLAGS += $(shell pkg-config --cflags sndfile) AF_C_FLAGS += $(shell pkg-config --cflags sndfile)
@@ -25,12 +33,6 @@ MF_CXX_FLAGS = $(BUILD_CXX_FLAGS)
MF_CXX_FLAGS += $(shell pkg-config --cflags smf) MF_CXX_FLAGS += $(shell pkg-config --cflags smf)
endif endif


ifeq ($(HAVE_OPENGL),true)
GL_CXX_FLAGS = $(BUILD_CXX_FLAGS)
GL_CXX_FLAGS += -I../../modules/distrho
GL_CXX_FLAGS += $(shell pkg-config --cflags gl)
endif

ifeq ($(HAVE_ZYN_DEPS),true) ifeq ($(HAVE_ZYN_DEPS),true)
ZYN_CXX_FLAGS = $(BUILD_CXX_FLAGS) ZYN_CXX_FLAGS = $(BUILD_CXX_FLAGS)
ZYN_CXX_FLAGS += $(shell pkg-config --cflags fftw3 mxml zlib) ZYN_CXX_FLAGS += $(shell pkg-config --cflags fftw3 mxml zlib)
@@ -54,7 +56,6 @@ OBJS = \


# Simple plugins (C++) # Simple plugins (C++)
OBJS += \ OBJS += \
midi-sequencer.cpp.o \
vex.cpp.o vex.cpp.o


# AudioFile # AudioFile
@@ -154,9 +155,6 @@ all: ../carla_native.a


# -------------------------------------------------------------- # --------------------------------------------------------------


CDEPS = CarlaNative.h
CXXDEPS = CarlaNative.h CarlaNative.hpp

%.c.o: %.c %.c.o: %.c
$(CC) $< $(BUILD_C_FLAGS) -c -o $@ $(CC) $< $(BUILD_C_FLAGS) -c -o $@


@@ -168,6 +166,9 @@ moc_%.cpp: %.hpp


# -------------------------------------------------------------- # --------------------------------------------------------------


CDEPS = CarlaNative.h
CXXDEPS = CarlaNative.h CarlaNative.hpp

audio_decoder/%.c.o: audio_decoder/%.c audio_decoder/%.c.o: audio_decoder/%.c
$(CC) $< $(AF_C_FLAGS) -c -o $@ $(CC) $< $(AF_C_FLAGS) -c -o $@


@@ -190,7 +191,7 @@ distrho-stereoenhancer.cpp.o: distrho-stereoenhancer.cpp stereoenhancer/*.cpp st
$(CXX) $< $(GL_CXX_FLAGS) -Istereoenhancer -DDISTRHO_NAMESPACE=DISTRHO_StereoEnhancer -c -o $@ $(CXX) $< $(GL_CXX_FLAGS) -Istereoenhancer -DDISTRHO_NAMESPACE=DISTRHO_StereoEnhancer -c -o $@


distrho-notes.cpp.o: distrho-notes.cpp notes/*.cpp notes/*.h notes/*.hpp distrho/DistrhoPluginCarla.cpp $(CXXDEPS) distrho-notes.cpp.o: distrho-notes.cpp notes/*.cpp notes/*.h notes/*.hpp distrho/DistrhoPluginCarla.cpp $(CXXDEPS)
$(CXX) $< $(QT_CXX_FLAGS) -Inotes -DDISTRHO_NAMESPACE=DISTRHO_Notes -c -o $@
$(CXX) $< $(BUILD_CXX_FLAGS) -Inotes -DDISTRHO_NAMESPACE=DISTRHO_Notes -c -o $@


midi-file.cpp.o: midi-file.cpp midi-base.hpp $(CXXDEPS) midi-file.cpp.o: midi-file.cpp midi-base.hpp $(CXXDEPS)
$(CXX) $< $(MF_CXX_FLAGS) -c -o $@ $(CXX) $< $(MF_CXX_FLAGS) -c -o $@
@@ -204,10 +205,10 @@ nekofilter.c.o: nekofilter.c nekofilter/*.c nekofilter/*.h $(CDEPS)
zynaddsubfx.cpp.o: zynaddsubfx.cpp $(CXXDEPS) $(ZYN_UI_FILES_H) zynaddsubfx.cpp.o: zynaddsubfx.cpp $(CXXDEPS) $(ZYN_UI_FILES_H)
$(CXX) $< $(ZYN_CXX_FLAGS) -c -o $@ $(CXX) $< $(ZYN_CXX_FLAGS) -c -o $@


zynaddsubfx-src.cpp.o: zynaddsubfx-src.cpp $(ZYN_UI_FILES_H) $(ZYN_UI_FILES_CPP)
zynaddsubfx-src.cpp.o: zynaddsubfx-src.cpp $(ZYN_UI_FILES_H)
$(CXX) $< $(ZYN_CXX_FLAGS) -c -o $@ $(CXX) $< $(ZYN_CXX_FLAGS) -c -o $@


zynaddsubfx-ui.cpp.o: zynaddsubfx-ui.cpp $(ZYN_UI_FILES_H)
zynaddsubfx-ui.cpp.o: zynaddsubfx-ui.cpp $(ZYN_UI_FILES_H) $(ZYN_UI_FILES_CPP)
$(CXX) $< $(ZYN_CXX_FLAGS) -c -o $@ $(CXX) $< $(ZYN_CXX_FLAGS) -c -o $@


zynaddsubfx/UI/%.cpp: zynaddsubfx/UI/%.fl zynaddsubfx/UI/%.cpp: zynaddsubfx/UI/%.fl
@@ -219,8 +220,8 @@ zynaddsubfx/UI/%.h: zynaddsubfx/UI/%.fl
# -------------------------------------------------------------- # --------------------------------------------------------------


clean: clean:
rm -f *.o ../carla_native.*
rm -f $(ZYN_UI_FILES_H) $(ZYN_UI_FILES_CPP)
rm -f $(OBJS) ../carla_native.*
rm -f $(ZYN_UI_FILES_H) $(ZYN_UI_FILES_CPP)


debug: debug:
$(MAKE) DEBUG=true $(MAKE) DEBUG=true

+ 46
- 48
source/plugin/Makefile View File

@@ -6,13 +6,7 @@


include ../Makefile.mk include ../Makefile.mk


BUILD_CXX_FLAGS += -I../backend -I../includes -I../modules -I../utils

ifeq ($(HAVE_QT4),true)
BUILD_CXX_FLAGS += $(shell pkg-config --cflags QtCore QtGui)
else
BUILD_CXX_FLAGS += $(shell pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets)
endif
BUILD_CXX_FLAGS += -I../includes -I../modules -I../utils


# -------------------------------------------------------------- # --------------------------------------------------------------


@@ -35,30 +29,34 @@ endif
# -------------------------------------------------------------- # --------------------------------------------------------------
# Common # Common


LINK_FLAGS += $(shell pkg-config --libs liblo)
ifeq ($(HAVE_QT4),true)
LINK_FLAGS += $(shell pkg-config --libs QtCore QtGui QtXml)
else
LINK_FLAGS += $(shell pkg-config --libs Qt5Core Qt5Gui Qt5Xml Qt5Widgets)
endif
# LINK_FLAGS += $(shell pkg-config --libs liblo)
#
# ifeq ($(HAVE_QT4),true)
# LINK_FLAGS += $(shell pkg-config --libs QtCore QtGui QtXml)
# else
# LINK_FLAGS += $(shell pkg-config --libs Qt5Core Qt5Gui Qt5Xml Qt5Widgets)
# endif


# -------------------------------------------------------------- # --------------------------------------------------------------
# Plugin # Plugin


ifeq ($(HAVE_FLUIDSYNTH),true)
LINK_FLAGS += $(shell pkg-config --libs fluidsynth)
endif
ifeq ($(HAVE_LINUXSAMPLER),true)
LINK_FLAGS += $(shell pkg-config --libs linuxsampler)
endif
# ifeq ($(HAVE_FLUIDSYNTH),true)
# LINK_FLAGS += $(shell pkg-config --libs fluidsynth)
# endif
#
# ifeq ($(HAVE_LINUXSAMPLER),true)
# LINK_FLAGS += $(shell pkg-config --libs linuxsampler)
# endif


# -------------------------------------------------------------- # --------------------------------------------------------------
# Native # Native


DGL_LIBS = -lX11 DGL_LIBS = -lX11


ifeq ($(HAVE_OPENGL),true)
LINK_FLAGS += $(shell pkg-config --libs gl) $(DGL_LIBS)
endif

ifeq ($(HAVE_AF_DEPS),true) ifeq ($(HAVE_AF_DEPS),true)
LINK_FLAGS += $(shell pkg-config --libs sndfile) LINK_FLAGS += $(shell pkg-config --libs sndfile)
ifeq ($(HAVE_FFMPEG),true) ifeq ($(HAVE_FFMPEG),true)
@@ -70,10 +68,6 @@ ifeq ($(HAVE_MF_DEPS),true)
LINK_FLAGS += $(shell pkg-config --libs smf) LINK_FLAGS += $(shell pkg-config --libs smf)
endif endif


ifeq ($(HAVE_OPENGL),true)
LINK_FLAGS += $(shell pkg-config --libs gl) $(DGL_LIBS)
endif

ifeq ($(HAVE_ZYN_DEPS),true) ifeq ($(HAVE_ZYN_DEPS),true)
LINK_FLAGS += $(shell pkg-config --libs fftw3 mxml zlib) LINK_FLAGS += $(shell pkg-config --libs fftw3 mxml zlib)
ifeq ($(HAVE_ZYN_UI_DEPS),true) ifeq ($(HAVE_ZYN_UI_DEPS),true)
@@ -85,31 +79,30 @@ LINK_FLAGS += $(EXTRA_LIBS)


# -------------------------------------------------------------- # --------------------------------------------------------------


# LIBS = ../backend/libcarla_engine_xx.a
# LIBS += ../backend/libcarla_plugin.a
LIBS += ../backend/libcarla_native.a
LIBS += ../modules/rtmempool.a
LIBS += ../modules/widgets.a
LIBS = ../modules/carla_native.a
LIBS += ../modules/juce_audio_basics.a
LIBS += ../modules/juce_core.a LIBS += ../modules/juce_core.a
LIBS += ../modules/rtmempool.a


ifeq ($(CARLA_PLUGIN_SUPPORT),true)
LIBS += ../modules/lilv.a
endif
# ifeq ($(CARLA_PLUGIN_SUPPORT),true)
# LIBS += ../modules/lilv.a
# endif


ifeq ($(HAVE_OPENGL),true) ifeq ($(HAVE_OPENGL),true)
LIBS += ../modules/dgl.a LIBS += ../modules/dgl.a
endif endif


ifeq ($(WIN32),true) ifeq ($(WIN32),true)
TARGETS = carla-native.lv2/carla-native.dll
TARGETS += carla-native-export.exe
TARGETS = carla-native-export.exe
TARGETS += carla-native.lv2/carla-native.dll
else else
TARGETS = carla-native-export
ifeq ($(MACOS),true) ifeq ($(MACOS),true)
TARGETS = carla-native.lv2/carla-native.dylib
TARGETS += carla-native.lv2/carla-native.dylib
else else
TARGETS = carla-native.lv2/carla-native.so
LIBS += -ldl -lrt
TARGETS += carla-native.lv2/carla-native.so
endif endif
TARGETS += carla-native-export
endif endif


# -------------------------------------------------------------- # --------------------------------------------------------------
@@ -125,17 +118,16 @@ debug:


# -------------------------------------------------------------- # --------------------------------------------------------------


%.cpp.o: %.cpp ../backend/CarlaNative.h
carla-native-base.cpp.o: carla-native-base.cpp ../modules/carla_native/CarlaNative.h
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@


carla-native.lv2/carla-native.dll: carla-native-plugin.cpp.o $(LIBS)
$(CXX) $^ -shared $(LINK_FLAGS) -o $@
carla-native-export.cpp.o: carla-native-export.cpp carla-native-base.cpp ../modules/carla_native/CarlaNative.h
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@


carla-native.lv2/carla-native.dylib: carla-native-plugin.cpp.o $(LIBS)
$(CXX) $^ -dynamiclib $(LINK_FLAGS) -o $@
carla-native-plugin.cpp.o: carla-native-plugin.cpp carla-native-base.cpp ../modules/carla_native/CarlaNative.h
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@


carla-native.lv2/carla-native.so: carla-native-plugin.cpp.o $(LIBS)
$(CXX) $^ -shared $(LINK_FLAGS) -o $@
# --------------------------------------------------------------


carla-native-export: carla-native-export.cpp.o $(LIBS) carla-native-export: carla-native-export.cpp.o $(LIBS)
$(CXX) $^ $(LINK_FLAGS) -o $@ $(CXX) $^ $(LINK_FLAGS) -o $@
@@ -145,13 +137,19 @@ carla-native-export.exe: carla-native-export.cpp.o $(LIBS)
$(CXX) $^ $(LINK_FLAGS) -o $@ $(CXX) $^ $(LINK_FLAGS) -o $@
./carla-native-export.exe ./carla-native-export.exe


carla-native.lv2/carla-native.dll: carla-native-plugin.cpp.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 $@

# -------------------------------------------------------------- # --------------------------------------------------------------


.FORCE: .FORCE:
.PHONY: .FORCE .PHONY: .FORCE


../backend/libcarla_%.a: .FORCE
$(MAKE) -C ../backend/$*

../modules/%.a: .FORCE ../modules/%.a: .FORCE
$(MAKE) -C ../modules $* $(MAKE) -C ../modules $*

+ 21
- 23
source/plugin/carla-native-base.cpp View File

@@ -15,7 +15,7 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/ */


#include "CarlaNative.h"
#include "carla_native/CarlaNative.h"
#include "RtList.hpp" #include "RtList.hpp"


#include "lv2/lv2.h" #include "lv2/lv2.h"
@@ -25,18 +25,17 @@


extern "C" { extern "C" {


// Simple plugins
// Simple plugins (C)
void carla_register_native_plugin_bypass(); void carla_register_native_plugin_bypass();
void carla_register_native_plugin_lfo(); void carla_register_native_plugin_lfo();
//void carla_register_native_plugin_midiSequencer();
void carla_register_native_plugin_midiGain();
void carla_register_native_plugin_midiSplit(); void carla_register_native_plugin_midiSplit();
void carla_register_native_plugin_midiThrough(); void carla_register_native_plugin_midiThrough();
void carla_register_native_plugin_midiTranspose(); void carla_register_native_plugin_midiTranspose();
void carla_register_native_plugin_nekofilter(); void carla_register_native_plugin_nekofilter();
//void carla_register_native_plugin_sunvoxfile();


// Carla
//void carla_register_native_plugin_carla();
// Simple plugins (C++)
void carla_register_native_plugin_vex();


#ifdef WANT_AUDIOFILE #ifdef WANT_AUDIOFILE
// AudioFile // AudioFile
@@ -50,15 +49,15 @@ void carla_register_native_plugin_midifile();


#ifdef WANT_OPENGL #ifdef WANT_OPENGL
// DISTRHO plugins (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();
// 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 #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
@@ -72,18 +71,17 @@ void carla_register_native_plugin_zynaddsubfx();
struct PluginListManager { struct PluginListManager {
PluginListManager() PluginListManager()
{ {
// Simple plugins
// Simple plugins (C)
carla_register_native_plugin_bypass(); carla_register_native_plugin_bypass();
carla_register_native_plugin_lfo(); carla_register_native_plugin_lfo();
//carla_register_native_plugin_midiSequencer(); // unfinished
carla_register_native_plugin_midiGain();
carla_register_native_plugin_midiSplit(); carla_register_native_plugin_midiSplit();
carla_register_native_plugin_midiThrough(); carla_register_native_plugin_midiThrough();
carla_register_native_plugin_midiTranspose(); carla_register_native_plugin_midiTranspose();
carla_register_native_plugin_nekofilter(); carla_register_native_plugin_nekofilter();
//carla_register_native_plugin_sunvoxfile(); // unfinished


// Carla
//carla_register_native_plugin_carla(); // kinda unfinished
// Simple plugins (C++)
carla_register_native_plugin_vex();


#ifdef WANT_AUDIOFILE #ifdef WANT_AUDIOFILE
// AudioFile // AudioFile
@@ -97,15 +95,15 @@ struct PluginListManager {


#ifdef WANT_OPENGL #ifdef WANT_OPENGL
// DISTRHO plugins (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
//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 #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


+ 32
- 6
source/plugin/carla-native-export.cpp View File

@@ -24,12 +24,14 @@
#include "lv2/instance-access.h" #include "lv2/instance-access.h"
#include "lv2/midi.h" #include "lv2/midi.h"
#include "lv2/options.h" #include "lv2/options.h"
#include "lv2/port-props.h"
#include "lv2/state.h" #include "lv2/state.h"
#include "lv2/time.h" #include "lv2/time.h"
#include "lv2/ui.h" #include "lv2/ui.h"
#include "lv2/units.h" #include "lv2/units.h"
#include "lv2/urid.h" #include "lv2/urid.h"
#include "lv2/lv2_external_ui.h" #include "lv2/lv2_external_ui.h"
#include "lv2/lv2_programs.h"


#include <fstream> #include <fstream>


@@ -52,7 +54,7 @@ static StringArray gUsedSymbols;


const String nameToSymbol(const String& name, const uint32_t portIndex) const String nameToSymbol(const String& name, const uint32_t portIndex)
{ {
String symbol, trimmedName = name.trimStart().trimEnd().toLowerCase();
String symbol, trimmedName = name.trim().toLowerCase();


if (trimmedName.isEmpty()) if (trimmedName.isEmpty())
{ {
@@ -133,11 +135,13 @@ void writeManifestFile()
text += "<http://kxstudio.sf.net/carla#UI>\n"; text += "<http://kxstudio.sf.net/carla#UI>\n";
text += " a <" LV2_EXTERNAL_UI__Widget "> ;\n"; text += " a <" LV2_EXTERNAL_UI__Widget "> ;\n";
text += " ui:binary <carla-native" PLUGIN_EXT "> ;\n"; text += " ui:binary <carla-native" PLUGIN_EXT "> ;\n";
text += " lv2:extensionData <" LV2_PROGRAMS__UIInterface "> ;\n";
text += " lv2:requiredFeature <" LV2_INSTANCE_ACCESS_URI "> .\n"; text += " lv2:requiredFeature <" LV2_INSTANCE_ACCESS_URI "> .\n";
text += "\n"; text += "\n";
text += "<http://kxstudio.sf.net/carla#UIold>\n"; text += "<http://kxstudio.sf.net/carla#UIold>\n";
text += " a <" LV2_EXTERNAL_UI_DEPRECATED_URI "> ;\n"; text += " a <" LV2_EXTERNAL_UI_DEPRECATED_URI "> ;\n";
text += " ui:binary <carla-native" PLUGIN_EXT "> ;\n"; text += " ui:binary <carla-native" PLUGIN_EXT "> ;\n";
text += " lv2:extensionData <" LV2_PROGRAMS__UIInterface "> ;\n";
text += " lv2:requiredFeature <" LV2_INSTANCE_ACCESS_URI "> .\n"; text += " lv2:requiredFeature <" LV2_INSTANCE_ACCESS_URI "> .\n";


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -216,7 +220,8 @@ void writePluginFile(const PluginDescriptor* const pluginDesc)
text += " lv2:requiredFeature <" LV2_BUF_SIZE__boundedBlockLength "> ,\n"; text += " lv2:requiredFeature <" LV2_BUF_SIZE__boundedBlockLength "> ,\n";
text += " <" LV2_URID__map "> ;\n"; text += " <" LV2_URID__map "> ;\n";
text += " lv2:extensionData <" LV2_OPTIONS__interface "> ,\n"; text += " lv2:extensionData <" LV2_OPTIONS__interface "> ,\n";
text += " <" LV2_STATE__interface "> ;\n";
text += " <" LV2_STATE__interface "> ,\n";
text += " <" LV2_PROGRAMS__Interface "> ;\n";
text += "\n"; text += "\n";


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -247,7 +252,7 @@ void writePluginFile(const PluginDescriptor* const pluginDesc)
} }


text += " lv2:designation lv2:control ;\n"; text += " lv2:designation lv2:control ;\n";
text += " lv2:index 0" + String(portIndex++) + " ;\n";
text += " lv2:index " + String(portIndex++) + " ;\n";


if (pluginDesc->midiIns > 1) if (pluginDesc->midiIns > 1)
{ {
@@ -425,6 +430,30 @@ void writePluginFile(const PluginDescriptor* const pluginDesc)
text += " lv2:minimum " + String::formatted("%f", paramInfo->ranges.min) + " ;\n"; text += " lv2:minimum " + String::formatted("%f", paramInfo->ranges.min) + " ;\n";
text += " lv2:maximum " + String::formatted("%f", paramInfo->ranges.max) + " ;\n"; text += " lv2:maximum " + String::formatted("%f", paramInfo->ranges.max) + " ;\n";


if (paramInfo->hints & PARAMETER_IS_ENABLED)
{
if ((paramInfo->hints & PARAMETER_IS_AUTOMABLE) == 0)
text += " lv2:portProperty <" LV2_PORT_PROPS__expensive "> ;\n";
if (paramInfo->hints & PARAMETER_IS_BOOLEAN)
text += " lv2:portProperty lv2:toggled ;\n";
if (paramInfo->hints & PARAMETER_IS_INTEGER)
text += " lv2:portProperty lv2:integer ;\n";
if (paramInfo->hints & PARAMETER_IS_LOGARITHMIC)
text += " lv2:portProperty <" LV2_PORT_PROPS__logarithmic "> ;\n";
if (paramInfo->hints & PARAMETER_USES_SAMPLE_RATE)
text += " lv2:portProperty lv2:toggled ;\n";
if (paramInfo->hints & PARAMETER_USES_SCALEPOINTS)
text += " lv2:portProperty lv2:enumeration ;\n";
if (paramInfo->hints & PARAMETER_USES_CUSTOM_TEXT)
pass(); // TODO: custom lv2 extension for this
}
else
{
text += " lv2:portProperty <" LV2_PORT_PROPS__notOnGUI "> ;\n";
}

// TODO - scalepoints

if (paramUnit.isNotEmpty()) if (paramUnit.isNotEmpty())
{ {
text += " units:unit [\n"; text += " units:unit [\n";
@@ -435,9 +464,6 @@ void writePluginFile(const PluginDescriptor* const pluginDesc)
text += " ] ;\n"; text += " ] ;\n";
} }


// if (! filter->isParameterAutomatable(i))
// text += " lv2:portProperty <" LV2_PORT_PROPS__expensive "> ;\n";

if (i+1 == paramCount) if (i+1 == paramCount)
text += " ] ;\n\n"; text += " ] ;\n\n";
else else


+ 353
- 85
source/plugin/carla-native-plugin.cpp View File

@@ -20,20 +20,18 @@
#include "CarlaString.hpp" #include "CarlaString.hpp"


#include "lv2/atom.h" #include "lv2/atom.h"
#include "lv2/atom-util.h"
#include "lv2/buf-size.h" #include "lv2/buf-size.h"
#include "lv2/instance-access.h" #include "lv2/instance-access.h"
#include "lv2/midi.h"
#include "lv2/options.h" #include "lv2/options.h"
#include "lv2/state.h" #include "lv2/state.h"
#include "lv2/time.h"
#include "lv2/ui.h" #include "lv2/ui.h"
#include "lv2/lv2_external_ui.h" #include "lv2/lv2_external_ui.h"
#include "lv2/lv2_programs.h"


#include <QtCore/Qt>

#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
# include <QtWidgets/QFileDialog>
#else
# include <QtGui/QFileDialog>
#endif
using juce::FloatVectorOperations;


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// LV2 descriptor functions // LV2 descriptor functions
@@ -48,8 +46,11 @@ public:
fDescriptor(desc), fDescriptor(desc),
fMidiEventCount(0), fMidiEventCount(0),
fIsProcessing(false), fIsProcessing(false),
fNeedsDryWetFix(false),
fVolume(1.0f),
fBufferSize(0), fBufferSize(0),
fSampleRate(sampleRate)
fSampleRate(sampleRate),
fUridMap(nullptr)
{ {
run = extui_run; run = extui_run;
show = extui_show; show = extui_show;
@@ -88,8 +89,6 @@ public:
return; return;
} }


fBufferSize = 1024;

for (int i=0; options[i].key != 0; ++i) for (int i=0; options[i].key != 0; ++i)
{ {
if (options[i].key == uridMap->map(uridMap->handle, LV2_BUF_SIZE__maxBlockLength)) if (options[i].key == uridMap->map(uridMap->handle, LV2_BUF_SIZE__maxBlockLength))
@@ -104,11 +103,11 @@ public:


fUridMap = uridMap; fUridMap = uridMap;


fUI.offset += (desc->midiIns > 0) ? desc->midiIns : 1;
fUI.offset += desc->midiOuts;
fUI.offset += 1; // freewheel
fUI.offset += desc->audioIns;
fUI.offset += desc->audioOuts;
fUI.portOffset += (desc->midiIns > 0) ? desc->midiIns : 1;
fUI.portOffset += desc->midiOuts;
fUI.portOffset += 1; // freewheel
fUI.portOffset += desc->audioIns;
fUI.portOffset += desc->audioOuts;
} }


~NativePlugin() ~NativePlugin()
@@ -131,7 +130,7 @@ public:
} }
if (fBufferSize == 0) if (fBufferSize == 0)
{ {
carla_stderr("Plugin is missing bufferSize value");
carla_stderr("Host is missing bufferSize feature");
return false; return false;
} }


@@ -142,7 +141,10 @@ public:


carla_zeroStruct<MidiEvent>(fMidiEvents, kMaxMidiEvents*2); carla_zeroStruct<MidiEvent>(fMidiEvents, kMaxMidiEvents*2);
carla_zeroStruct<TimeInfo>(fTimeInfo); carla_zeroStruct<TimeInfo>(fTimeInfo);

fPorts.init(fDescriptor, fHandle); fPorts.init(fDescriptor, fHandle);
fUris.map(fUridMap);

return true; return true;
} }


@@ -154,13 +156,13 @@ public:
fPorts.connectPort(fDescriptor, port, dataLocation); fPorts.connectPort(fDescriptor, port, dataLocation);
} }


void lv2_activate()
void lv2_activate() const
{ {
if (fDescriptor->activate != nullptr) if (fDescriptor->activate != nullptr)
fDescriptor->activate(fHandle); fDescriptor->activate(fHandle);
} }


void lv2_deactivate()
void lv2_deactivate() const
{ {
if (fDescriptor->deactivate != nullptr) if (fDescriptor->deactivate != nullptr)
fDescriptor->deactivate(fHandle); fDescriptor->deactivate(fHandle);
@@ -197,14 +199,194 @@ public:
} }
} }


fDescriptor->process(fHandle, fPorts.audioIns, fPorts.audioOuts, frames, fMidiEventCount, fMidiEvents);
LV2_ATOM_SEQUENCE_FOREACH(fPorts.eventsIn[0], iter)
{
const LV2_Atom_Event* const event((const LV2_Atom_Event*)iter);

if (event == nullptr)
continue;
if (event->body.size > 4)
continue;
if (event->time.frames >= frames)
break;

if (event->body.type == fUris.midiEvent)
{
if (fMidiEventCount >= kMaxMidiEvents*2)
continue;

const uint8_t* const data((const uint8_t*)(event + 1));

fMidiEvents[fMidiEventCount].port = 0;
fMidiEvents[fMidiEventCount].time = event->time.frames;
fMidiEvents[fMidiEventCount].size = event->body.size;

for (uint32_t i=0; i < event->body.size; ++i)
fMidiEvents[fMidiEventCount].data[i] = data[i];

fMidiEventCount += 1;
continue;
}

if (event->body.type == fUris.atomBlank)
{
const LV2_Atom_Object* const obj((LV2_Atom_Object*)&event->body);

if (obj->body.otype != fUris.timePos)
continue;

LV2_Atom* bar = nullptr;
LV2_Atom* barBeat = nullptr;
LV2_Atom* beatsPerBar = nullptr;
LV2_Atom* bpm = nullptr;
LV2_Atom* beatUnit = nullptr;
LV2_Atom* frame = nullptr;
LV2_Atom* speed = nullptr;

lv2_atom_object_get(obj,
fUris.timeBar, &bar,
fUris.timeBarBeat, &barBeat,
fUris.timeBeatsPerBar, &beatsPerBar,
fUris.timeBeatsPerMinute, &bpm,
fUris.timeBeatUnit, &beatUnit,
fUris.timeFrame, &frame,
fUris.timeSpeed, &speed,
nullptr);

if (bpm != nullptr && bpm->type == fUris.atomFloat)
{
fTimeInfo.bbt.beatsPerMinute = ((LV2_Atom_Float*)bpm)->body;
fTimeInfo.bbt.valid = true;
}

if (beatsPerBar != nullptr && beatsPerBar->type == fUris.atomFloat)
{
float beatsPerBarValue = ((LV2_Atom_Float*)beatsPerBar)->body;
fTimeInfo.bbt.beatsPerBar = beatsPerBarValue;

if (bar != nullptr && bar->type == fUris.atomLong)
{
//float barValue = ((LV2_Atom_Long*)bar)->body;
//curPosInfo.ppqPositionOfLastBarStart = barValue * beatsPerBarValue;

if (barBeat != nullptr && barBeat->type == fUris.atomFloat)
{
//float barBeatValue = ((LV2_Atom_Float*)barBeat)->body;
//curPosInfo.ppqPosition = curPosInfo.ppqPositionOfLastBarStart + barBeatValue;
}
}
}

if (beatUnit != nullptr && beatUnit->type == fUris.atomFloat)
fTimeInfo.bbt.beatType = ((LV2_Atom_Float*)beatUnit)->body;

if (frame != nullptr && frame->type == fUris.atomLong)
fTimeInfo.frame = ((LV2_Atom_Long*)frame)->body;

if (speed != nullptr && speed->type == fUris.atomFloat)
fTimeInfo.playing = ((LV2_Atom_Float*)speed)->body == 1.0f;
}
}

for (uint32_t i=1; i < fDescriptor->midiIns; ++i)
{
LV2_ATOM_SEQUENCE_FOREACH(fPorts.eventsIn[i], iter)
{
const LV2_Atom_Event* const event((const LV2_Atom_Event*)iter);

if (event == nullptr)
continue;
if (event->body.type != fUris.midiEvent)
continue;
if (event->body.size > 4)
continue;
if (event->time.frames >= frames)
break;
if (fMidiEventCount >= kMaxMidiEvents*2)
break;

const uint8_t* const data((const uint8_t*)(event + 1));

fMidiEvents[fMidiEventCount].port = i;
fMidiEvents[fMidiEventCount].time = event->time.frames;
fMidiEvents[fMidiEventCount].size = event->body.size;

for (uint32_t j=0; j < event->body.size; ++j)
fMidiEvents[fMidiEventCount].data[j] = data[j];

fMidiEventCount += 1;
}
}

fIsProcessing = true;
fDescriptor->process(fHandle, fPorts.audioIns, fPorts.audioOuts, frames, fMidiEvents, fMidiEventCount);
fIsProcessing = false;

if (fVolume != 1.0f)
{
for (uint32_t i=0; i < fDescriptor->audioOuts; ++i)
FloatVectorOperations::multiply(fPorts.audioOuts[i], fVolume, frames);
}


updateParameterOutputs(); updateParameterOutputs();
} }


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


void lv2ui_instantiate(LV2UI_Write_Function writeFunction, LV2UI_Controller controller, LV2UI_Widget* widget,
uint32_t lv2_get_options(LV2_Options_Option* const /*options*/) const
{
return 0;
}

uint32_t lv2_set_options(const LV2_Options_Option* const /*options*/)
{
return 0;
}

const LV2_Program_Descriptor* lv2_get_program(const uint32_t index) const
{
if (fDescriptor->get_midi_program_count == nullptr)
return nullptr;
if (fDescriptor->get_midi_program_info == nullptr)
return nullptr;
if (index >= fDescriptor->get_midi_program_count(fHandle))
return nullptr;

const MidiProgram* const midiProg(fDescriptor->get_midi_program_info(fHandle, index));

if (midiProg == nullptr)
return nullptr;

static LV2_Program_Descriptor progDesc;

progDesc.bank = midiProg->bank;
progDesc.program = midiProg->program;
progDesc.name = midiProg->name;

return &progDesc;
}

void lv2_select_program(uint32_t bank, uint32_t program) const
{
if (fDescriptor->set_midi_program == nullptr)
return;

fDescriptor->set_midi_program(fHandle, 0, bank, program);
}

LV2_State_Status lv2_save(const LV2_State_Store_Function /*store*/, const LV2_State_Handle /*handle*/, const uint32_t /*flags*/, const LV2_Feature* const* const /*features*/) const
{
return LV2_STATE_ERR_UNKNOWN;
}

LV2_State_Status lv2_restore(const LV2_State_Retrieve_Function /*retrieve*/, const LV2_State_Handle /*handle*/, const uint32_t /*flags*/, const LV2_Feature* const* const /*features*/) const
{
return LV2_STATE_ERR_UNKNOWN;
}

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

bool lv2ui_instantiate(LV2UI_Write_Function writeFunction, LV2UI_Controller controller, LV2UI_Widget* widget,
const LV2_Feature* const* features) const LV2_Feature* const* features)
{ {
for (int i=0; features[i] != nullptr; ++i) for (int i=0; features[i] != nullptr; ++i)
@@ -217,25 +399,29 @@ public:
} }
} }


if (fUI.host != nullptr)
fHost.uiName = fUI.host->plugin_human_id;
if (fUI.host == nullptr)
return false;


fUI.writeFunction = writeFunction; fUI.writeFunction = writeFunction;
fUI.controller = controller; fUI.controller = controller;
*widget = this; *widget = this;

fHost.uiName = fUI.host->plugin_human_id;

return true;
} }


void lv2ui_port_event(uint32_t portIndex, uint32_t bufferSize, uint32_t format, const void* buffer)
void lv2ui_port_event(uint32_t portIndex, uint32_t bufferSize, uint32_t format, const void* buffer) const
{ {
if (format != 0 || bufferSize != sizeof(float) || buffer == nullptr) if (format != 0 || bufferSize != sizeof(float) || buffer == nullptr)
return; return;
if (portIndex >= fUI.offset || ! fUI.isVisible)
if (portIndex >= fUI.portOffset || ! fUI.isVisible)
return; return;
if (fDescriptor->ui_set_parameter_value == nullptr) if (fDescriptor->ui_set_parameter_value == nullptr)
return; return;


const float value(*(const float*)buffer); const float value(*(const float*)buffer);
fDescriptor->ui_set_parameter_value(fHandle, portIndex-fUI.offset, value);
fDescriptor->ui_set_parameter_value(fHandle, portIndex-fUI.portOffset, value);
} }


void lv2ui_cleanup() void lv2ui_cleanup()
@@ -255,11 +441,19 @@ public:


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


void lv2ui_select_program(uint32_t bank, uint32_t program) const
{
if (fDescriptor->ui_set_midi_program == nullptr)
return;

fDescriptor->ui_set_midi_program(fHandle, 0, bank, program);
}

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

protected: protected:
void handleUiRun() void handleUiRun()
{ {
// TODO - idle Qt if needed

if (fDescriptor->ui_idle != nullptr) if (fDescriptor->ui_idle != nullptr)
fDescriptor->ui_idle(fHandle); fDescriptor->ui_idle(fHandle);
} }
@@ -282,24 +476,24 @@ protected:


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


uint32_t handleGetBufferSize()
uint32_t handleGetBufferSize() const
{ {
return fBufferSize; return fBufferSize;
} }


double handleGetSampleRate()
double handleGetSampleRate() const
{ {
return fSampleRate; return fSampleRate;
} }


bool handleIsOffline()
bool handleIsOffline() const
{ {
CARLA_SAFE_ASSERT_RETURN(fIsProcessing, false); CARLA_SAFE_ASSERT_RETURN(fIsProcessing, false);


return (fPorts.freewheel != nullptr && *fPorts.freewheel > 0.5f);
return (fPorts.freewheel != nullptr && *fPorts.freewheel >= 0.5f);
} }


const TimeInfo* handleGetTimeInfo()
const TimeInfo* handleGetTimeInfo() const
{ {
CARLA_SAFE_ASSERT_RETURN(fIsProcessing, nullptr); CARLA_SAFE_ASSERT_RETURN(fIsProcessing, nullptr);


@@ -313,26 +507,23 @@ protected:
CARLA_SAFE_ASSERT_RETURN(event != nullptr, false); CARLA_SAFE_ASSERT_RETURN(event != nullptr, false);
CARLA_SAFE_ASSERT_RETURN(event->data[0] != 0, false); CARLA_SAFE_ASSERT_RETURN(event->data[0] != 0, false);


if (fMidiEventCount >= kMaxMidiEvents*2)
return false;

// reverse-find first free event, and put it there // reverse-find first free event, and put it there
for (uint32_t i=(kMaxMidiEvents*2)-1; i >= fMidiEventCount; --i)
for (uint32_t i=(kMaxMidiEvents*2)-1; i > fMidiEventCount; --i)
{ {
if (fMidiEvents[i].data[0] == 0) if (fMidiEvents[i].data[0] == 0)
{ {
std::memcpy(&fMidiEvents[i], event, sizeof(MidiEvent)); std::memcpy(&fMidiEvents[i], event, sizeof(MidiEvent));
break;
return true;
} }
} }


return true;
return false;
} }


void handleUiParameterChanged(const uint32_t index, const float value) void handleUiParameterChanged(const uint32_t index, const float value)
{ {
if (fUI.writeFunction != nullptr && fUI.controller != nullptr) if (fUI.writeFunction != nullptr && fUI.controller != nullptr)
fUI.writeFunction(fUI.controller, index+fUI.offset, sizeof(float), 0, &value);
fUI.writeFunction(fUI.controller, index+fUI.portOffset, sizeof(float), 0, &value);
} }


void handleUiCustomDataChanged(const char* const /*key*/, const char* const /*value*/) void handleUiCustomDataChanged(const char* const /*key*/, const char* const /*value*/)
@@ -351,27 +542,19 @@ protected:
fUI.isVisible = false; fUI.isVisible = false;
} }


const char* handleUiOpenFile(const bool isDir, const char* const title, const char* const filter)
const char* handleUiOpenFile(const bool /*isDir*/, const char* const /*title*/, const char* const /*filter*/) const
{ {
static CarlaString retStr;
QFileDialog::Options options(isDir ? QFileDialog::ShowDirsOnly : 0x0);

retStr = QFileDialog::getOpenFileName(nullptr, title, "", filter, nullptr, options).toUtf8().constData();

return retStr.isNotEmpty() ? (const char*)retStr : nullptr;
// TODO
return nullptr;
} }


const char* handleUiSaveFile(const bool isDir, const char* const title, const char* const filter)
const char* handleUiSaveFile(const bool /*isDir*/, const char* const /*title*/, const char* const /*filter*/) const
{ {
static CarlaString retStr;
QFileDialog::Options options(isDir ? QFileDialog::ShowDirsOnly : 0x0);

retStr = QFileDialog::getSaveFileName(nullptr, title, "", filter, nullptr, options).toUtf8().constData();

return retStr.isNotEmpty() ? (const char*)retStr : nullptr;
// TODO
return nullptr;
} }


intptr_t handleDispatcher(const ::HostDispatcherOpcode opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt)
intptr_t handleDispatcher(const HostDispatcherOpcode opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt)
{ {
carla_debug("NativePlugin::handleDispatcher(%i, %i, " P_INTPTR ", %p, %f)", opcode, index, value, ptr, opt); carla_debug("NativePlugin::handleDispatcher(%i, %i, " P_INTPTR ", %p, %f)", opcode, index, value, ptr, opt);


@@ -382,19 +565,16 @@ protected:
case HOST_OPCODE_NULL: case HOST_OPCODE_NULL:
break; break;
case HOST_OPCODE_SET_VOLUME: case HOST_OPCODE_SET_VOLUME:
//setVolume(opt, true, true);
fVolume = opt;
break; break;
case HOST_OPCODE_SET_DRYWET: case HOST_OPCODE_SET_DRYWET:
//setDryWet(opt, true, true);
carla_stdout("Plugin asked dryWet custom value %f", opt);
fNeedsDryWetFix = true;
break; break;
case HOST_OPCODE_SET_BALANCE_LEFT: case HOST_OPCODE_SET_BALANCE_LEFT:
//setBalanceLeft(opt, true, true);
break;
case HOST_OPCODE_SET_BALANCE_RIGHT: case HOST_OPCODE_SET_BALANCE_RIGHT:
//setBalanceRight(opt, true, true);
break;
case HOST_OPCODE_SET_PANNING: case HOST_OPCODE_SET_PANNING:
//setPanning(opt, true, true);
// nothing
break; break;
case HOST_OPCODE_GET_PARAMETER_MIDI_CC: case HOST_OPCODE_GET_PARAMETER_MIDI_CC:
case HOST_OPCODE_SET_PARAMETER_MIDI_CC: case HOST_OPCODE_SET_PARAMETER_MIDI_CC:
@@ -404,6 +584,7 @@ protected:
case HOST_OPCODE_RELOAD_PARAMETERS: case HOST_OPCODE_RELOAD_PARAMETERS:
case HOST_OPCODE_RELOAD_MIDI_PROGRAMS: case HOST_OPCODE_RELOAD_MIDI_PROGRAMS:
case HOST_OPCODE_RELOAD_ALL: case HOST_OPCODE_RELOAD_ALL:
// nothing
break; break;
case HOST_OPCODE_UI_UNAVAILABLE: case HOST_OPCODE_UI_UNAVAILABLE:
handleUiClosed(); handleUiClosed();
@@ -445,6 +626,8 @@ private:
TimeInfo fTimeInfo; TimeInfo fTimeInfo;


bool fIsProcessing; bool fIsProcessing;
bool fNeedsDryWetFix;
float fVolume;


// Lv2 host data // Lv2 host data
uint32_t fBufferSize; uint32_t fBufferSize;
@@ -452,19 +635,67 @@ private:


const LV2_URID_Map* fUridMap; const LV2_URID_Map* fUridMap;


struct URIDs {
LV2_URID atomBlank;
LV2_URID atomFloat;
LV2_URID atomLong;
LV2_URID atomSequence;
LV2_URID midiEvent;
LV2_URID timePos;
LV2_URID timeBar;
LV2_URID timeBarBeat;
LV2_URID timeBeatsPerBar;
LV2_URID timeBeatsPerMinute;
LV2_URID timeBeatUnit;
LV2_URID timeFrame;
LV2_URID timeSpeed;

URIDs()
: atomBlank(0),
atomFloat(0),
atomLong(0),
atomSequence(0),
midiEvent(0),
timePos(0),
timeBar(0),
timeBarBeat(0),
timeBeatsPerBar(0),
timeBeatsPerMinute(0),
timeBeatUnit(0),
timeFrame(0),
timeSpeed(0) {}

void map(const LV2_URID_Map* const uridMap)
{
atomBlank = uridMap->map(uridMap->handle, LV2_ATOM__Blank);
atomFloat = uridMap->map(uridMap->handle, LV2_ATOM__Float);
atomLong = uridMap->map(uridMap->handle, LV2_ATOM__Long);
atomSequence = uridMap->map(uridMap->handle, LV2_ATOM__Sequence);
midiEvent = uridMap->map(uridMap->handle, LV2_MIDI__MidiEvent);
timePos = uridMap->map(uridMap->handle, LV2_TIME__Position);
timeBar = uridMap->map(uridMap->handle, LV2_TIME__bar);
timeBarBeat = uridMap->map(uridMap->handle, LV2_TIME__barBeat);
timeBeatUnit = uridMap->map(uridMap->handle, LV2_TIME__beatUnit);
timeFrame = uridMap->map(uridMap->handle, LV2_TIME__frame);
timeSpeed = uridMap->map(uridMap->handle, LV2_TIME__speed);
timeBeatsPerBar = uridMap->map(uridMap->handle, LV2_TIME__beatsPerBar);
timeBeatsPerMinute = uridMap->map(uridMap->handle, LV2_TIME__beatsPerMinute);
}
} fUris;

struct UI { struct UI {
const LV2_External_UI_Host* host; const LV2_External_UI_Host* host;
LV2UI_Write_Function writeFunction; LV2UI_Write_Function writeFunction;
LV2UI_Controller controller; LV2UI_Controller controller;
uint32_t portOffset;
bool isVisible; bool isVisible;
uint32_t offset;


UI() UI()
: host(nullptr), : host(nullptr),
writeFunction(nullptr), writeFunction(nullptr),
controller(nullptr), controller(nullptr),
isVisible(false),
offset(0) {}
portOffset(0),
isVisible(false) {}
} fUI; } fUI;


struct Ports { struct Ports {
@@ -528,6 +759,8 @@ private:


void init(const PluginDescriptor* const desc, PluginHandle handle) void init(const PluginDescriptor* const desc, PluginHandle handle)
{ {
CARLA_SAFE_ASSERT_RETURN(desc != nullptr && handle != nullptr,)

if (desc->midiIns > 0) if (desc->midiIns > 0)
{ {
eventsIn = new LV2_Atom_Sequence*[desc->midiIns]; eventsIn = new LV2_Atom_Sequence*[desc->midiIns];
@@ -749,11 +982,11 @@ static LV2_Handle lv2_instantiate(const LV2_Descriptor* lv2Descriptor, double sa


if (pluginLabel == nullptr) if (pluginLabel == nullptr)
{ {
carla_stderr("Failed to find carla native plugin with URI: \"%s\"", lv2Descriptor->URI);
carla_stderr("Failed to find carla native plugin with URI \"%s\"", lv2Descriptor->URI);
return nullptr; return nullptr;
} }


carla_debug("lv2_instantiate() - looking up label %s", pluginLabel);
carla_debug("lv2_instantiate() - looking up label \"%s\"", pluginLabel);


for (NonRtList<const PluginDescriptor*>::Itenerator it = sPluginDescsMgr.descs.begin(); it.valid(); it.next()) for (NonRtList<const PluginDescriptor*>::Itenerator it = sPluginDescsMgr.descs.begin(); it.valid(); it.next())
{ {
@@ -768,7 +1001,7 @@ static LV2_Handle lv2_instantiate(const LV2_Descriptor* lv2Descriptor, double sa


if (pluginDesc == nullptr) if (pluginDesc == nullptr)
{ {
carla_stderr("Failed to find carla native plugin with label: \"%s\"", pluginLabel);
carla_stderr("Failed to find carla native plugin with label \"%s\"", pluginLabel);
return nullptr; return nullptr;
} }


@@ -815,45 +1048,56 @@ static void lv2_cleanup(LV2_Handle instance)
delete instancePtr; delete instancePtr;
} }


#if 0
static uint32_t lv2_get_options(LV2_Handle instance, LV2_Options_Option* options) static uint32_t lv2_get_options(LV2_Handle instance, LV2_Options_Option* options)
{ {
carla_debug("lv2_()", );
carla_debug("lv2_get_options(%p, %p)", instance, options);
return instancePtr->lv2_get_options(options); return instancePtr->lv2_get_options(options);
} }


static uint32_t lv2_set_options(LV2_Handle instance, const LV2_Options_Option* options) static uint32_t lv2_set_options(LV2_Handle instance, const LV2_Options_Option* options)
{ {
carla_debug("lv2_()", );
carla_debug("lv2_set_options(%p, %p)", instance, options);
return instancePtr->lv2_set_options(options); return instancePtr->lv2_set_options(options);
} }


static const LV2_Program_Descriptor* lv2_get_program(LV2_Handle instance, uint32_t index)
{
carla_debug("lv2_get_program(%p, %i)", instance, index);
return instancePtr->lv2_get_program(index);
}

static void lv2_select_program(LV2_Handle instance, uint32_t bank, uint32_t program)
{
carla_debug("lv2_select_program(%p, %i, %i)", instance, bank, program);
return instancePtr->lv2_select_program(bank, program);
}

static LV2_State_Status lv2_save(LV2_Handle instance, LV2_State_Store_Function store, LV2_State_Handle handle, uint32_t flags, const LV2_Feature* const* features) static LV2_State_Status lv2_save(LV2_Handle instance, LV2_State_Store_Function store, LV2_State_Handle handle, uint32_t flags, const LV2_Feature* const* features)
{ {
carla_debug("lv2_()", );
carla_debug("lv2_save(%p, %p, %p, %i, %p)", instance, store, handle, flags, features);
return instancePtr->lv2_save(store, handle, flags, features); return instancePtr->lv2_save(store, handle, flags, features);
} }


static LV2_State_Status lv2_restore(LV2_Handle instance, LV2_State_Retrieve_Function retrieve, LV2_State_Handle handle, uint32_t flags, const LV2_Feature* const* features) static LV2_State_Status lv2_restore(LV2_Handle instance, LV2_State_Retrieve_Function retrieve, LV2_State_Handle handle, uint32_t flags, const LV2_Feature* const* features)
{ {
carla_debug("lv2_()", );
carla_debug("lv2_restore(%p, %p, %p, %i, %p)", instance, retrieve, handle, flags, features);
return instancePtr->lv2_restore(retrieve, handle, flags, features); return instancePtr->lv2_restore(retrieve, handle, flags, features);
} }
#endif


static const void* lv2_extension_data(const char* uri) static const void* lv2_extension_data(const char* uri)
{ {
carla_debug("lv2_extension_data(%s)", uri);
carla_debug("lv2_extension_data(\"%s\")", uri);


#if 0
static const LV2_Options_Interface options = { lv2_get_options, lv2_set_options };
static const LV2_State_Interface state = { lv2_save, lv2_restore };
static const LV2_Options_Interface options = { lv2_get_options, lv2_set_options };
static const LV2_Programs_Interface programs = { lv2_get_program, lv2_select_program };
static const LV2_State_Interface state = { lv2_save, lv2_restore };


if (std::strcmp(uri, LV2_OPTIONS__interface) == 0) if (std::strcmp(uri, LV2_OPTIONS__interface) == 0)
return &options; return &options;
if (std::strcmp(uri, LV2_PROGRAMS__Interface) == 0)
return &programs;
if (std::strcmp(uri, LV2_STATE__interface) == 0) if (std::strcmp(uri, LV2_STATE__interface) == 0)
return &state; return &state;
#endif


return nullptr; return nullptr;
} }
@@ -883,7 +1127,11 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char*, cons
return nullptr; return nullptr;
} }


plugin->lv2ui_instantiate(writeFunction, controller, widget, features);
if (! plugin->lv2ui_instantiate(writeFunction, controller, widget, features))
{
carla_stderr("Host doesn't support external UI");
return nullptr;
}


return (LV2UI_Handle)plugin; return (LV2UI_Handle)plugin;
} }
@@ -902,12 +1150,31 @@ static void lv2ui_cleanup(LV2UI_Handle ui)
uiPtr->lv2ui_cleanup(); uiPtr->lv2ui_cleanup();
} }


static void lv2ui_select_program(LV2UI_Handle ui, uint32_t bank, uint32_t program)
{
carla_debug("lv2ui_select_program(%p, %i, %i)", ui, bank, program);
uiPtr->lv2ui_select_program(bank, program);
}

static const void* lv2ui_extension_data(const char* uri)
{
carla_debug("lv2ui_extension_data(\"%s\")", uri);

static const LV2_Programs_UI_Interface uiprograms = { lv2ui_select_program };

if (std::strcmp(uri, LV2_PROGRAMS__UIInterface) == 0)
return &uiprograms;

return nullptr;
}

#undef uiPtr #undef uiPtr


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// Startup code // Startup code


CARLA_EXPORT const LV2_Descriptor* lv2_descriptor(uint32_t index)
CARLA_EXPORT
const LV2_Descriptor* lv2_descriptor(uint32_t index)
{ {
carla_debug("lv2_descriptor(%i)", index); carla_debug("lv2_descriptor(%i)", index);


@@ -936,7 +1203,7 @@ CARLA_EXPORT const LV2_Descriptor* lv2_descriptor(uint32_t index)
tmpURI += pluginDesc->label; tmpURI += pluginDesc->label;
} }


carla_debug("lv2_descriptor(%i) - not found, allocating new with uri: %s", index, (const char*)tmpURI);
carla_debug("lv2_descriptor(%i) - not found, allocating new with uri \"%s\"", index, (const char*)tmpURI);


const LV2_Descriptor* const lv2Desc(new const LV2_Descriptor{ const LV2_Descriptor* const lv2Desc(new const LV2_Descriptor{
/* URI */ carla_strdup(tmpURI), /* URI */ carla_strdup(tmpURI),
@@ -951,10 +1218,11 @@ CARLA_EXPORT const LV2_Descriptor* lv2_descriptor(uint32_t index)


sPluginDescsMgr.lv2Descs.append(lv2Desc); sPluginDescsMgr.lv2Descs.append(lv2Desc);


return sPluginDescsMgr.lv2Descs.getLast();
return lv2Desc;
} }


CARLA_EXPORT const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index)
CARLA_EXPORT
const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index)
{ {
carla_debug("lv2ui_descriptor(%i)", index); carla_debug("lv2ui_descriptor(%i)", index);


@@ -963,7 +1231,7 @@ CARLA_EXPORT const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index)
/* instantiate */ lv2ui_instantiate, /* instantiate */ lv2ui_instantiate,
/* cleanup */ lv2ui_cleanup, /* cleanup */ lv2ui_cleanup,
/* port_event */ lv2ui_port_event, /* port_event */ lv2ui_port_event,
/* extension_data */ nullptr
/* extension_data */ lv2ui_extension_data
}; };


static const LV2UI_Descriptor lv2UiDescOld = { static const LV2UI_Descriptor lv2UiDescOld = {
@@ -971,7 +1239,7 @@ CARLA_EXPORT const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index)
/* instantiate */ lv2ui_instantiate, /* instantiate */ lv2ui_instantiate,
/* cleanup */ lv2ui_cleanup, /* cleanup */ lv2ui_cleanup,
/* port_event */ lv2ui_port_event, /* port_event */ lv2ui_port_event,
/* extension_data */ nullptr
/* extension_data */ lv2ui_extension_data
}; };


switch (index) switch (index)


+ 7
- 2
source/utils/CarlaString.hpp View File

@@ -381,7 +381,10 @@ public:


CarlaString& operator+=(const char* const strBuf) CarlaString& operator+=(const char* const strBuf)
{ {
const size_t newBufSize = fBufferLen + ((strBuf != nullptr) ? std::strlen(strBuf) : 0) + 1;
if (strBuf == nullptr)
return *this;

const size_t newBufSize = fBufferLen + std::strlen(strBuf) + 1;
char newBuf[newBufSize]; char newBuf[newBufSize];


std::strcpy(newBuf, fBuffer); std::strcpy(newBuf, fBuffer);
@@ -403,7 +406,9 @@ public:
char newBuf[newBufSize]; char newBuf[newBufSize];


std::strcpy(newBuf, fBuffer); std::strcpy(newBuf, fBuffer);
std::strcat(newBuf, strBuf);

if (strBuf != nullptr)
std::strcat(newBuf, strBuf);


return CarlaString(newBuf); return CarlaString(newBuf);
} }


Loading…
Cancel
Save