| @@ -50,12 +50,13 @@ carla-bridge-native | |||
| carla-bridge-posix32 | |||
| carla-bridge-posix64 | |||
| carla-bridge-lv2-cocoa | |||
| carla-bridge-lv2-external | |||
| carla-bridge-lv2-gtk2 | |||
| carla-bridge-lv2-gtk3 | |||
| carla-bridge-lv2-qt4 | |||
| carla-bridge-lv2-qt5 | |||
| carla-bridge-lv2-x11 | |||
| carla-bridge-vst-cocoa | |||
| carla-bridge-vst-mac | |||
| carla-bridge-vst-x11 | |||
| carla-discovery-qtcreator | |||
| @@ -90,38 +91,38 @@ src/dist/ | |||
| *build-*Release/ | |||
| # 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 | |||
| source/includes/rewire/ | |||
| @@ -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 | |||
| ifeq ($(CARLA_PLUGIN_SUPPORT),true) | |||
| @@ -42,9 +36,7 @@ ifeq ($(HAVE_LINUXSAMPLER),true) | |||
| BUILD_CXX_FLAGS += -DWANT_LINUXSAMPLER | |||
| endif | |||
| ifeq ($(HAVE_OPENGL),true) | |||
| BUILD_CXX_FLAGS += -DWANT_OPENGL | |||
| endif | |||
| # -------------------------------------------------------------- | |||
| ifeq ($(HAVE_AF_DEPS),true) | |||
| BUILD_CXX_FLAGS += -DWANT_AUDIOFILE | |||
| @@ -57,6 +49,10 @@ ifeq ($(HAVE_MF_DEPS),true) | |||
| BUILD_CXX_FLAGS += -DWANT_MIDIFILE | |||
| endif | |||
| ifeq ($(HAVE_OPENGL),true) | |||
| BUILD_CXX_FLAGS += -DWANT_OPENGL | |||
| endif | |||
| ifeq ($(HAVE_ZYN_DEPS),true) | |||
| BUILD_CXX_FLAGS += -DWANT_ZYNADDSUBFX | |||
| ifeq ($(HAVE_ZYN_UI_DEPS),true) | |||
| @@ -2151,20 +2151,17 @@ protected: | |||
| return false; | |||
| } | |||
| if (fMidiEventCount >= MAX_MIDI_EVENTS*2) | |||
| return false; | |||
| // 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) | |||
| { | |||
| std::memcpy(&fMidiEvents[i], event, sizeof(::MidiEvent)); | |||
| break; | |||
| return true; | |||
| } | |||
| } | |||
| return true; | |||
| return false; | |||
| } | |||
| void handleUiParameterChanged(const uint32_t index, const float value) | |||
| @@ -99,6 +99,7 @@ lv2_atom_sequence_is_end(const LV2_Atom_Sequence_Body* body, | |||
| static inline const LV2_Atom_Event* | |||
| lv2_atom_sequence_next(const LV2_Atom_Event* i) | |||
| { | |||
| if (!i) return NULL; | |||
| return (const LV2_Atom_Event*)((const uint8_t*)i | |||
| + sizeof(LV2_Atom_Event) | |||
| + lv2_atom_pad_size(i->body.size)); | |||
| @@ -117,13 +118,13 @@ lv2_atom_sequence_next(const LV2_Atom_Event* i) | |||
| @endcode | |||
| */ | |||
| #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)); \ | |||
| (iter) = lv2_atom_sequence_next(iter)) | |||
| /** Like LV2_ATOM_SEQUENCE_FOREACH but for a headerless sequence body. */ | |||
| #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)); \ | |||
| (iter) = lv2_atom_sequence_next(iter)) | |||
| @@ -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 | |||
| # -------------------------------------------------------------- | |||
| 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) | |||
| AF_C_FLAGS = $(BUILD_C_FLAGS) | |||
| 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) | |||
| 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) | |||
| ZYN_CXX_FLAGS = $(BUILD_CXX_FLAGS) | |||
| ZYN_CXX_FLAGS += $(shell pkg-config --cflags fftw3 mxml zlib) | |||
| @@ -54,7 +56,6 @@ OBJS = \ | |||
| # Simple plugins (C++) | |||
| OBJS += \ | |||
| midi-sequencer.cpp.o \ | |||
| vex.cpp.o | |||
| # AudioFile | |||
| @@ -154,9 +155,6 @@ all: ../carla_native.a | |||
| # -------------------------------------------------------------- | |||
| CDEPS = CarlaNative.h | |||
| CXXDEPS = CarlaNative.h CarlaNative.hpp | |||
| %.c.o: %.c | |||
| $(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 | |||
| $(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 $@ | |||
| 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) | |||
| $(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) | |||
| $(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 $@ | |||
| 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 $@ | |||
| zynaddsubfx/UI/%.cpp: zynaddsubfx/UI/%.fl | |||
| @@ -219,8 +220,8 @@ zynaddsubfx/UI/%.h: zynaddsubfx/UI/%.fl | |||
| # -------------------------------------------------------------- | |||
| 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: | |||
| $(MAKE) DEBUG=true | |||
| @@ -6,13 +6,7 @@ | |||
| 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 | |||
| 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 | |||
| 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 | |||
| DGL_LIBS = -lX11 | |||
| ifeq ($(HAVE_OPENGL),true) | |||
| LINK_FLAGS += $(shell pkg-config --libs gl) $(DGL_LIBS) | |||
| endif | |||
| ifeq ($(HAVE_AF_DEPS),true) | |||
| LINK_FLAGS += $(shell pkg-config --libs sndfile) | |||
| ifeq ($(HAVE_FFMPEG),true) | |||
| @@ -70,10 +68,6 @@ ifeq ($(HAVE_MF_DEPS),true) | |||
| LINK_FLAGS += $(shell pkg-config --libs smf) | |||
| endif | |||
| ifeq ($(HAVE_OPENGL),true) | |||
| LINK_FLAGS += $(shell pkg-config --libs gl) $(DGL_LIBS) | |||
| endif | |||
| ifeq ($(HAVE_ZYN_DEPS),true) | |||
| LINK_FLAGS += $(shell pkg-config --libs fftw3 mxml zlib) | |||
| 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/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) | |||
| LIBS += ../modules/dgl.a | |||
| endif | |||
| 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 | |||
| TARGETS = carla-native-export | |||
| ifeq ($(MACOS),true) | |||
| TARGETS = carla-native.lv2/carla-native.dylib | |||
| TARGETS += carla-native.lv2/carla-native.dylib | |||
| else | |||
| TARGETS = carla-native.lv2/carla-native.so | |||
| LIBS += -ldl -lrt | |||
| TARGETS += carla-native.lv2/carla-native.so | |||
| endif | |||
| TARGETS += carla-native-export | |||
| 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 $@ | |||
| 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) | |||
| $(CXX) $^ $(LINK_FLAGS) -o $@ | |||
| @@ -145,13 +137,19 @@ carla-native-export.exe: carla-native-export.cpp.o $(LIBS) | |||
| $(CXX) $^ $(LINK_FLAGS) -o $@ | |||
| ./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: | |||
| .PHONY: .FORCE | |||
| ../backend/libcarla_%.a: .FORCE | |||
| $(MAKE) -C ../backend/$* | |||
| ../modules/%.a: .FORCE | |||
| $(MAKE) -C ../modules $* | |||
| @@ -15,7 +15,7 @@ | |||
| * 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 "lv2/lv2.h" | |||
| @@ -25,18 +25,17 @@ | |||
| extern "C" { | |||
| // Simple plugins | |||
| // Simple plugins (C) | |||
| void carla_register_native_plugin_bypass(); | |||
| 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_midiThrough(); | |||
| void carla_register_native_plugin_midiTranspose(); | |||
| 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 | |||
| // AudioFile | |||
| @@ -50,15 +49,15 @@ void carla_register_native_plugin_midifile(); | |||
| #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(); | |||
| // 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(); | |||
| // void carla_register_native_plugin_Notes(); | |||
| #ifdef WANT_ZYNADDSUBFX | |||
| // ZynAddSubFX | |||
| @@ -72,18 +71,17 @@ void carla_register_native_plugin_zynaddsubfx(); | |||
| struct PluginListManager { | |||
| PluginListManager() | |||
| { | |||
| // Simple plugins | |||
| // Simple plugins (C) | |||
| carla_register_native_plugin_bypass(); | |||
| 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_midiThrough(); | |||
| carla_register_native_plugin_midiTranspose(); | |||
| 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 | |||
| // AudioFile | |||
| @@ -97,15 +95,15 @@ struct PluginListManager { | |||
| #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 | |||
| //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 | |||
| //carla_register_native_plugin_Notes(); // unfinished | |||
| #ifdef WANT_ZYNADDSUBFX | |||
| // ZynAddSubFX | |||
| @@ -24,12 +24,14 @@ | |||
| #include "lv2/instance-access.h" | |||
| #include "lv2/midi.h" | |||
| #include "lv2/options.h" | |||
| #include "lv2/port-props.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 "lv2/lv2_programs.h" | |||
| #include <fstream> | |||
| @@ -52,7 +54,7 @@ static StringArray gUsedSymbols; | |||
| 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()) | |||
| { | |||
| @@ -133,11 +135,13 @@ void writeManifestFile() | |||
| 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:extensionData <" LV2_PROGRAMS__UIInterface "> ;\n"; | |||
| text += " lv2:requiredFeature <" LV2_INSTANCE_ACCESS_URI "> .\n"; | |||
| text += "\n"; | |||
| text += "<http://kxstudio.sf.net/carla#UIold>\n"; | |||
| text += " a <" LV2_EXTERNAL_UI_DEPRECATED_URI "> ;\n"; | |||
| text += " ui:binary <carla-native" PLUGIN_EXT "> ;\n"; | |||
| text += " lv2:extensionData <" LV2_PROGRAMS__UIInterface "> ;\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_URID__map "> ;\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"; | |||
| // ------------------------------------------------------------------- | |||
| @@ -247,7 +252,7 @@ void writePluginFile(const PluginDescriptor* const pluginDesc) | |||
| } | |||
| text += " lv2:designation lv2:control ;\n"; | |||
| text += " lv2:index 0" + String(portIndex++) + " ;\n"; | |||
| text += " lv2:index " + String(portIndex++) + " ;\n"; | |||
| 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: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()) | |||
| { | |||
| text += " units:unit [\n"; | |||
| @@ -435,9 +464,6 @@ void writePluginFile(const PluginDescriptor* const pluginDesc) | |||
| text += " ] ;\n"; | |||
| } | |||
| // if (! filter->isParameterAutomatable(i)) | |||
| // text += " lv2:portProperty <" LV2_PORT_PROPS__expensive "> ;\n"; | |||
| if (i+1 == paramCount) | |||
| text += " ] ;\n\n"; | |||
| else | |||
| @@ -20,20 +20,18 @@ | |||
| #include "CarlaString.hpp" | |||
| #include "lv2/atom.h" | |||
| #include "lv2/atom-util.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/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 | |||
| @@ -48,8 +46,11 @@ public: | |||
| fDescriptor(desc), | |||
| fMidiEventCount(0), | |||
| fIsProcessing(false), | |||
| fNeedsDryWetFix(false), | |||
| fVolume(1.0f), | |||
| fBufferSize(0), | |||
| fSampleRate(sampleRate) | |||
| fSampleRate(sampleRate), | |||
| fUridMap(nullptr) | |||
| { | |||
| run = extui_run; | |||
| show = extui_show; | |||
| @@ -88,8 +89,6 @@ public: | |||
| return; | |||
| } | |||
| fBufferSize = 1024; | |||
| for (int i=0; options[i].key != 0; ++i) | |||
| { | |||
| if (options[i].key == uridMap->map(uridMap->handle, LV2_BUF_SIZE__maxBlockLength)) | |||
| @@ -104,11 +103,11 @@ public: | |||
| 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() | |||
| @@ -131,7 +130,7 @@ public: | |||
| } | |||
| if (fBufferSize == 0) | |||
| { | |||
| carla_stderr("Plugin is missing bufferSize value"); | |||
| carla_stderr("Host is missing bufferSize feature"); | |||
| return false; | |||
| } | |||
| @@ -142,7 +141,10 @@ public: | |||
| carla_zeroStruct<MidiEvent>(fMidiEvents, kMaxMidiEvents*2); | |||
| carla_zeroStruct<TimeInfo>(fTimeInfo); | |||
| fPorts.init(fDescriptor, fHandle); | |||
| fUris.map(fUridMap); | |||
| return true; | |||
| } | |||
| @@ -154,13 +156,13 @@ public: | |||
| fPorts.connectPort(fDescriptor, port, dataLocation); | |||
| } | |||
| void lv2_activate() | |||
| void lv2_activate() const | |||
| { | |||
| if (fDescriptor->activate != nullptr) | |||
| fDescriptor->activate(fHandle); | |||
| } | |||
| void lv2_deactivate() | |||
| void lv2_deactivate() const | |||
| { | |||
| if (fDescriptor->deactivate != nullptr) | |||
| 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(); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| 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) | |||
| { | |||
| 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.controller = controller; | |||
| *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) | |||
| return; | |||
| if (portIndex >= fUI.offset || ! fUI.isVisible) | |||
| if (portIndex >= fUI.portOffset || ! fUI.isVisible) | |||
| return; | |||
| if (fDescriptor->ui_set_parameter_value == nullptr) | |||
| return; | |||
| 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() | |||
| @@ -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: | |||
| void handleUiRun() | |||
| { | |||
| // TODO - idle Qt if needed | |||
| if (fDescriptor->ui_idle != nullptr) | |||
| fDescriptor->ui_idle(fHandle); | |||
| } | |||
| @@ -282,24 +476,24 @@ protected: | |||
| // ------------------------------------------------------------------- | |||
| uint32_t handleGetBufferSize() | |||
| uint32_t handleGetBufferSize() const | |||
| { | |||
| return fBufferSize; | |||
| } | |||
| double handleGetSampleRate() | |||
| double handleGetSampleRate() const | |||
| { | |||
| return fSampleRate; | |||
| } | |||
| bool handleIsOffline() | |||
| bool handleIsOffline() const | |||
| { | |||
| 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); | |||
| @@ -313,26 +507,23 @@ protected: | |||
| CARLA_SAFE_ASSERT_RETURN(event != nullptr, 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 | |||
| 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) | |||
| { | |||
| std::memcpy(&fMidiEvents[i], event, sizeof(MidiEvent)); | |||
| break; | |||
| return true; | |||
| } | |||
| } | |||
| return true; | |||
| return false; | |||
| } | |||
| void handleUiParameterChanged(const uint32_t index, const float value) | |||
| { | |||
| 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*/) | |||
| @@ -351,27 +542,19 @@ protected: | |||
| 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); | |||
| @@ -382,19 +565,16 @@ protected: | |||
| case HOST_OPCODE_NULL: | |||
| break; | |||
| case HOST_OPCODE_SET_VOLUME: | |||
| //setVolume(opt, true, true); | |||
| fVolume = opt; | |||
| break; | |||
| case HOST_OPCODE_SET_DRYWET: | |||
| //setDryWet(opt, true, true); | |||
| carla_stdout("Plugin asked dryWet custom value %f", opt); | |||
| fNeedsDryWetFix = true; | |||
| break; | |||
| case HOST_OPCODE_SET_BALANCE_LEFT: | |||
| //setBalanceLeft(opt, true, true); | |||
| break; | |||
| case HOST_OPCODE_SET_BALANCE_RIGHT: | |||
| //setBalanceRight(opt, true, true); | |||
| break; | |||
| case HOST_OPCODE_SET_PANNING: | |||
| //setPanning(opt, true, true); | |||
| // nothing | |||
| break; | |||
| case HOST_OPCODE_GET_PARAMETER_MIDI_CC: | |||
| case HOST_OPCODE_SET_PARAMETER_MIDI_CC: | |||
| @@ -404,6 +584,7 @@ protected: | |||
| case HOST_OPCODE_RELOAD_PARAMETERS: | |||
| case HOST_OPCODE_RELOAD_MIDI_PROGRAMS: | |||
| case HOST_OPCODE_RELOAD_ALL: | |||
| // nothing | |||
| break; | |||
| case HOST_OPCODE_UI_UNAVAILABLE: | |||
| handleUiClosed(); | |||
| @@ -445,6 +626,8 @@ private: | |||
| TimeInfo fTimeInfo; | |||
| bool fIsProcessing; | |||
| bool fNeedsDryWetFix; | |||
| float fVolume; | |||
| // Lv2 host data | |||
| uint32_t fBufferSize; | |||
| @@ -452,19 +635,67 @@ private: | |||
| 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 { | |||
| const LV2_External_UI_Host* host; | |||
| LV2UI_Write_Function writeFunction; | |||
| LV2UI_Controller controller; | |||
| uint32_t portOffset; | |||
| bool isVisible; | |||
| uint32_t offset; | |||
| UI() | |||
| : host(nullptr), | |||
| writeFunction(nullptr), | |||
| controller(nullptr), | |||
| isVisible(false), | |||
| offset(0) {} | |||
| portOffset(0), | |||
| isVisible(false) {} | |||
| } fUI; | |||
| struct Ports { | |||
| @@ -528,6 +759,8 @@ private: | |||
| void init(const PluginDescriptor* const desc, PluginHandle handle) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(desc != nullptr && handle != nullptr,) | |||
| if (desc->midiIns > 0) | |||
| { | |||
| 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) | |||
| { | |||
| 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; | |||
| } | |||
| 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()) | |||
| { | |||
| @@ -768,7 +1001,7 @@ static LV2_Handle lv2_instantiate(const LV2_Descriptor* lv2Descriptor, double sa | |||
| 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; | |||
| } | |||
| @@ -815,45 +1048,56 @@ static void lv2_cleanup(LV2_Handle instance) | |||
| delete instancePtr; | |||
| } | |||
| #if 0 | |||
| 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); | |||
| } | |||
| 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); | |||
| } | |||
| 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) | |||
| { | |||
| 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); | |||
| } | |||
| 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); | |||
| } | |||
| #endif | |||
| 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) | |||
| return &options; | |||
| if (std::strcmp(uri, LV2_PROGRAMS__Interface) == 0) | |||
| return &programs; | |||
| if (std::strcmp(uri, LV2_STATE__interface) == 0) | |||
| return &state; | |||
| #endif | |||
| return nullptr; | |||
| } | |||
| @@ -883,7 +1127,11 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char*, cons | |||
| 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; | |||
| } | |||
| @@ -902,12 +1150,31 @@ static void lv2ui_cleanup(LV2UI_Handle ui) | |||
| 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 | |||
| // ----------------------------------------------------------------------- | |||
| // 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); | |||
| @@ -936,7 +1203,7 @@ CARLA_EXPORT const LV2_Descriptor* lv2_descriptor(uint32_t index) | |||
| 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{ | |||
| /* URI */ carla_strdup(tmpURI), | |||
| @@ -951,10 +1218,11 @@ CARLA_EXPORT const LV2_Descriptor* lv2_descriptor(uint32_t index) | |||
| 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); | |||
| @@ -963,7 +1231,7 @@ CARLA_EXPORT const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index) | |||
| /* instantiate */ lv2ui_instantiate, | |||
| /* cleanup */ lv2ui_cleanup, | |||
| /* port_event */ lv2ui_port_event, | |||
| /* extension_data */ nullptr | |||
| /* extension_data */ lv2ui_extension_data | |||
| }; | |||
| static const LV2UI_Descriptor lv2UiDescOld = { | |||
| @@ -971,7 +1239,7 @@ CARLA_EXPORT const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index) | |||
| /* instantiate */ lv2ui_instantiate, | |||
| /* cleanup */ lv2ui_cleanup, | |||
| /* port_event */ lv2ui_port_event, | |||
| /* extension_data */ nullptr | |||
| /* extension_data */ lv2ui_extension_data | |||
| }; | |||
| switch (index) | |||
| @@ -381,7 +381,10 @@ public: | |||
| 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]; | |||
| std::strcpy(newBuf, fBuffer); | |||
| @@ -403,7 +406,9 @@ public: | |||
| char newBuf[newBufSize]; | |||
| std::strcpy(newBuf, fBuffer); | |||
| std::strcat(newBuf, strBuf); | |||
| if (strBuf != nullptr) | |||
| std::strcat(newBuf, strBuf); | |||
| return CarlaString(newBuf); | |||
| } | |||