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