diff --git a/Makefile b/Makefile index 73c8d17..8cebabd 100644 --- a/Makefile +++ b/Makefile @@ -26,16 +26,17 @@ claudia: src/ui_claudia.py \ src/ui_claudia_runcustom.py # src/ui_claudia_addnew.py src/ui_claudia_addnew_klaudia.py -carla: carla_backend carla_bridges carla_discovery carla_gui +carla: carla_backend carla_bridge_ui carla_discovery carla_gui carla_backend: + $(MAKE) -C src/carla-lilv $(MAKE) -C src/carla -carla_bridges: -# $(MAKE) native$(_arch_n) -C src/carla-bridges +carla_bridge_ui: $(MAKE) -C src/carla-bridge-ui carla_discovery: + $(MAKE) -C src/carla-lilv # $(MAKE) native$(_arch_n) -C src/carla-discovery carla_gui: src/ui_carla.py src/ui_carla_control.py \ diff --git a/src/carla-discovery/carla-discovery.cpp b/src/carla-discovery/carla-discovery.cpp index c08f2a0..28ba78f 100644 --- a/src/carla-discovery/carla-discovery.cpp +++ b/src/carla-discovery/carla-discovery.cpp @@ -42,6 +42,12 @@ #include "ladspa/ladspa.h" #include "dssi/dssi.h" +#include "lv2/atom.h" +#include "lv2/event.h" +#include "lv2/midi.h" +#include "lilv/lilvmm.hpp" +#define LV2_MIDI_LL__MidiPort "http://ll-plugins.nongnu.org/lv2/ext/MidiPort" + #define VST_FORCE_DEPRECATED 0 #include "aeffectx.h" @@ -287,8 +293,6 @@ intptr_t VstHostCallback(AEffect* effect, int32_t opcode, int32_t index, intptr_ // ------------------------------ Plugin Check ------------------------------ void do_ladspa_check(void* lib_handle) { - LADSPA_Handle handle; - const LADSPA_Descriptor* descriptor; LADSPA_Descriptor_Function descfn = (LADSPA_Descriptor_Function)lib_symbol(lib_handle, "ladspa_descriptor"); if (descfn == nullptr) @@ -298,9 +302,11 @@ void do_ladspa_check(void* lib_handle) } unsigned long i = 0; + const LADSPA_Descriptor* descriptor; + while ((descriptor = descfn(i++))) { - handle = descriptor->instantiate(descriptor, sampleRate); + LADSPA_Handle handle = descriptor->instantiate(descriptor, sampleRate); if (handle) { @@ -503,9 +509,6 @@ void do_ladspa_check(void* lib_handle) void do_dssi_check(void* lib_handle) { - LADSPA_Handle handle; - const LADSPA_Descriptor* ldescriptor; - const DSSI_Descriptor* descriptor; DSSI_Descriptor_Function descfn = (DSSI_Descriptor_Function)lib_symbol(lib_handle, "dssi_descriptor"); if (descfn == nullptr) @@ -515,10 +518,12 @@ void do_dssi_check(void* lib_handle) } unsigned long i = 0; + const DSSI_Descriptor* descriptor; + while ((descriptor = descfn(i++))) { - ldescriptor = descriptor->LADSPA_Plugin; - handle = ldescriptor->instantiate(ldescriptor, sampleRate); + const LADSPA_Descriptor* ldescriptor = descriptor->LADSPA_Plugin; + LADSPA_Handle handle = ldescriptor->instantiate(ldescriptor, sampleRate); if (handle) { @@ -758,6 +763,145 @@ void do_dssi_check(void* lib_handle) } } +void do_lv2_check(const char* bundle) +{ + std::string sbundle; + sbundle += "file://"; + sbundle += bundle; + + Lilv::World World; + Lilv::Node Bundle(lilv_new_uri(World.me, sbundle.c_str())); + World.load_bundle(Bundle); + + Lilv::Node AtomBufferTypes = Lilv::Node(lilv_new_uri(World.me, LV2_ATOM__bufferType)); + Lilv::Node EventTypeMidi = Lilv::Node(lilv_new_uri(World.me, LV2_MIDI__MidiEvent)); + + Lilv::Node PortTypeInput = Lilv::Node(lilv_new_uri(World.me, LV2_CORE__InputPort)); + Lilv::Node PortTypeOutput = Lilv::Node(lilv_new_uri(World.me, LV2_CORE__OutputPort)); + Lilv::Node PortTypeAudio = Lilv::Node(lilv_new_uri(World.me, LV2_CORE__AudioPort)); + Lilv::Node PortTypeControl = Lilv::Node(lilv_new_uri(World.me, LV2_CORE__ControlPort)); + Lilv::Node PortTypeAtom = Lilv::Node(lilv_new_uri(World.me, LV2_ATOM__AtomPort)); + Lilv::Node PortTypeEvent = Lilv::Node(lilv_new_uri(World.me, LV2_EVENT__EventPort)); + Lilv::Node PortTypeMidiLL = Lilv::Node(lilv_new_uri(World.me, LV2_MIDI_LL__MidiPort)); + + Lilv::Node PortPropertyLatency = Lilv::Node(lilv_new_uri(World.me, LV2_CORE__latency)); + + const Lilv::Plugins Plugins = World.get_all_plugins(); + + LILV_FOREACH(plugins, i, Plugins) + { + Lilv::Plugin p(lilv_plugins_get(Plugins, i)); + + //Lilv::Nodes requiredFeatures(p.get_required_features()); + // check + + const char* filename = lilv_uri_to_path(p.get_library_uri().as_string()); + + // test if DLL is loadable + void* lib_handle = lib_open(filename); + + if (lib_handle == nullptr) + { + DISCOVERY_OUT("error", lib_error(filename)); + continue; + } + + lib_close(lib_handle); + + int hints = 0; + PluginCategory category = PLUGIN_CATEGORY_NONE; + + int audio_ins = 0; + int audio_outs = 0; + int audio_total = 0; + int midi_ins = 0; + int midi_outs = 0; + int midi_total = 0; + int parameters_ins = 0; + int parameters_outs = 0; + int parameters_total = 0; + int programs_total = 0; + + for (unsigned j=0; j < p.get_num_ports(); j++) + { + Lilv::Port Port = p.get_port_by_index(j); + + if (Port.is_a(PortTypeAudio)) + { + if (Port.is_a(PortTypeInput)) + audio_ins += 1; + else if (Port.is_a(PortTypeOutput)) + audio_ins += 1; + audio_total += 1; + } + else if (Port.is_a(PortTypeControl)) + { + if (Port.is_a(PortTypeInput)) + parameters_ins += 1; + else if (Port.is_a(PortTypeOutput)) + { + if (Port.has_property(PortPropertyLatency) == false) + parameters_ins += 1; + } + parameters_total += 1; + } + else if (Port.is_a(PortTypeAtom)) + { + Lilv::Nodes bufferTypes(Port.get_value(AtomBufferTypes)); + if (bufferTypes.contains(EventTypeMidi)) + { + if (Port.is_a(PortTypeInput)) + midi_ins += 1; + else if (Port.is_a(PortTypeOutput)) + midi_ins += 1; + midi_total += 1; + } + } + else if (Port.is_a(PortTypeEvent)) + { + if (Port.supports_event(EventTypeMidi)) + { + if (Port.is_a(PortTypeInput)) + midi_ins += 1; + else if (Port.is_a(PortTypeOutput)) + midi_ins += 1; + midi_total += 1; + } + } + else if (Port.is_a(PortTypeMidiLL)) + { + if (Port.is_a(PortTypeInput)) + midi_ins += 1; + else if (Port.is_a(PortTypeOutput)) + midi_ins += 1; + midi_total += 1; + } + } + + DISCOVERY_OUT("init", "-----------"); + DISCOVERY_OUT("name", p.get_name().as_string()); + DISCOVERY_OUT("label", p.get_uri().as_string()); + DISCOVERY_OUT("maker", p.get_author_name().as_string()); + //DISCOVERY_OUT("copyright", ldescriptor->Copyright); + //DISCOVERY_OUT("unique_id", ldescriptor->UniqueID); + DISCOVERY_OUT("hints", hints); + DISCOVERY_OUT("category", category); + DISCOVERY_OUT("audio.ins", audio_ins); + DISCOVERY_OUT("audio.outs", audio_outs); + DISCOVERY_OUT("audio.total", audio_total); + DISCOVERY_OUT("midi.ins", midi_ins); + DISCOVERY_OUT("midi.outs", midi_outs); + DISCOVERY_OUT("midi.total", midi_total); + DISCOVERY_OUT("parameters.ins", parameters_ins); + DISCOVERY_OUT("parameters.outs", parameters_outs); + DISCOVERY_OUT("parameters.total", parameters_total); + DISCOVERY_OUT("programs.total", programs_total); + + DISCOVERY_OUT("build", BINARY_TYPE); + DISCOVERY_OUT("end", "------------"); + } +} + void do_vst_check(void* lib_handle) { VST_Function vstfn = (VST_Function)lib_symbol(lib_handle, "VSTPluginMain"); @@ -1072,6 +1216,11 @@ int main(int argc, char* argv[]) open_lib = true; type = PLUGIN_DSSI; } + else if (strcmp(type_str, "LV2") == 0) + { + open_lib = false; + type = PLUGIN_LV2; + } else if (strcmp(type_str, "VST") == 0) { open_lib = true; @@ -1110,6 +1259,9 @@ int main(int argc, char* argv[]) case PLUGIN_DSSI: do_dssi_check(handle); break; + case PLUGIN_LV2: + do_lv2_check(filename); + break; case PLUGIN_VST: do_vst_check(handle); break; diff --git a/src/carla-discovery/qtcreator/carla-discovery.pro b/src/carla-discovery/qtcreator/carla-discovery.pro index 58be23c..b054294 100644 --- a/src/carla-discovery/qtcreator/carla-discovery.pro +++ b/src/carla-discovery/qtcreator/carla-discovery.pro @@ -8,6 +8,9 @@ VERSION = 0.5.0 SOURCES = \ ../carla-discovery.cpp +HEADERS = \ + ../../carla-includes/carla_includes.h + INCLUDEPATH = .. \ ../../carla-includes \ ../../carla-includes/vestige @@ -16,4 +19,4 @@ TARGET = carla-discovery-qtcreator DEFINES = VESTIGE_HEADER BUILD_UNIX64 -LIBS += -ldl +LIBS += ../../carla-lilv/carla_lilv.a -ldl diff --git a/src/carla-includes/carla_includes.h b/src/carla-includes/carla_includes.h index ddd37e0..4b1a36a 100644 --- a/src/carla-includes/carla_includes.h +++ b/src/carla-includes/carla_includes.h @@ -53,11 +53,13 @@ // needed for qDebug/Warning/Critical sections #if __WORDSIZE == 64 -# define P_INTPTR "%li" -# define P_SIZE "%lu" +# define P_INTPTR "%li" +# define P_UINTPTR "%llu" +# define P_SIZE "%lu" #else -# define P_INTPTR "%i" -# define P_SIZE "%u" +# define P_INTPTR "%i" +# define P_UINTPTR "%lu" +# define P_SIZE "%u" #endif // set native binary type diff --git a/src/carla/carla_backend.cpp b/src/carla/carla_backend.cpp index 9008d88..fa78bdd 100644 --- a/src/carla/carla_backend.cpp +++ b/src/carla/carla_backend.cpp @@ -435,7 +435,7 @@ ParameterData* get_parameter_data(unsigned short plugin_id, uint32_t parameter_i { qDebug("get_parameter_data(%i, %i)", plugin_id, parameter_id); - static ParameterData data = { PARAMETER_UNKNOWN, -1, -1, 0, 0, -1 }; + static ParameterData data = { PARAMETER_UNKNOWN, /*-1,*/ -1, 0, 0, -1 }; for (unsigned short i=0; iType = 0; + desc->URI = strdup(p.get_uri().as_string()); + desc->Name = strdup(p.get_name().as_string()); + desc->Author = strdup(p.get_author_name().as_string()); + desc->License = nullptr; + desc->Binary = strdup(lilv_uri_to_path(p.get_library_uri().as_string())); + desc->Bundle = strdup(lilv_uri_to_path(p.get_bundle_uri().as_string())); + + desc->PortCount = 0; + desc->PresetCount = 0; + desc->FeatureCount = 0; + desc->ExtensionCount = 0; + desc->UICount = 0; + + qDebug("%03i - %s", j++, lilv_uri_to_path(p.get_library_uri().as_string())); + + lv2_rdf_free(desc); + } + + return 0; +} +#endif + + #include #include @@ -1019,7 +1060,7 @@ public: const LV2_RDF_PortPoints PortPoints = rdf_descriptor->Ports[i].Points; j = param.count++; - param.data[j].index = j; + //param.data[j].index = j; param.data[j].rindex = i; param.data[j].hints = 0; param.data[j].midi_channel = 0; diff --git a/src/carla/qtcreator/carla-backend.pro b/src/carla/qtcreator/carla-backend.pro index ad4f6b6..d6305a9 100644 --- a/src/carla/qtcreator/carla-backend.pro +++ b/src/carla/qtcreator/carla-backend.pro @@ -19,7 +19,8 @@ SOURCES = \ ../dssi.cpp \ ../lv2.cpp \ ../vst.cpp \ - ../sf2.cpp + ../sf2.cpp \ + ../lv2-rtmempool/rtmempool.c HEADERS = \ ../carla_backend.h \ @@ -40,3 +41,5 @@ INCLUDEPATH = .. \ TARGET = carla_backend DEFINES = VESTIGE_HEADER + +LIBS = ../../carla-lilv/carla_lilv.a diff --git a/src/carla/sf2.cpp b/src/carla/sf2.cpp index cdf4322..8460dee 100644 --- a/src/carla/sf2.cpp +++ b/src/carla/sf2.cpp @@ -378,7 +378,7 @@ public: // ---------------------- j = Sf2ReverbOnOff; - param.data[j].index = j; + //param.data[j].index = j; param.data[j].rindex = j; param.data[j].type = PARAMETER_INPUT; param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE; @@ -394,7 +394,7 @@ public: // ---------------------- j = Sf2ReverbRoomSize; - param.data[j].index = j; + //param.data[j].index = j; param.data[j].rindex = j; param.data[j].type = PARAMETER_INPUT; param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE; @@ -410,7 +410,7 @@ public: // ---------------------- j = Sf2ReverbDamp; - param.data[j].index = j; + //param.data[j].index = j; param.data[j].rindex = j; param.data[j].type = PARAMETER_INPUT; param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE; @@ -426,7 +426,7 @@ public: // ---------------------- j = Sf2ReverbLevel; - param.data[j].index = j; + //param.data[j].index = j; param.data[j].rindex = j; param.data[j].type = PARAMETER_INPUT; param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE; @@ -442,7 +442,7 @@ public: // ---------------------- j = Sf2ReverbWidth; - param.data[j].index = j; + //param.data[j].index = j; param.data[j].rindex = j; param.data[j].type = PARAMETER_INPUT; param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE; @@ -458,7 +458,7 @@ public: // ---------------------- j = Sf2ChorusOnOff; - param.data[j].index = j; + //param.data[j].index = j; param.data[j].rindex = j; param.data[j].type = PARAMETER_INPUT; param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE; @@ -474,7 +474,7 @@ public: // ---------------------- j = Sf2ChorusNr; - param.data[j].index = j; + //param.data[j].index = j; param.data[j].rindex = j; param.data[j].type = PARAMETER_INPUT; param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE; @@ -490,7 +490,7 @@ public: // ---------------------- j = Sf2ChorusLevel; - param.data[j].index = j; + //param.data[j].index = j; param.data[j].rindex = j; param.data[j].type = PARAMETER_INPUT; param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE; @@ -506,7 +506,7 @@ public: // ---------------------- j = Sf2ChorusSpeedHz; - param.data[j].index = j; + //param.data[j].index = j; param.data[j].rindex = j; param.data[j].type = PARAMETER_INPUT; param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE; @@ -522,7 +522,7 @@ public: // ---------------------- j = Sf2ChorusDepthMs; - param.data[j].index = j; + //param.data[j].index = j; param.data[j].rindex = j; param.data[j].type = PARAMETER_INPUT; param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE; @@ -538,7 +538,7 @@ public: // ---------------------- j = Sf2ChorusType; - param.data[j].index = j; + //param.data[j].index = j; param.data[j].rindex = j; param.data[j].type = PARAMETER_INPUT; param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_USES_SCALEPOINTS; @@ -554,7 +554,7 @@ public: // ---------------------- j = Sf2Polyphony; - param.data[j].index = j; + //param.data[j].index = j; param.data[j].rindex = j; param.data[j].type = PARAMETER_INPUT; param.data[j].hints = PARAMETER_IS_ENABLED; @@ -570,7 +570,7 @@ public: // ---------------------- j = Sf2Interpolation; - param.data[j].index = j; + //param.data[j].index = j; param.data[j].rindex = j; param.data[j].type = PARAMETER_INPUT; param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_USES_SCALEPOINTS; @@ -586,7 +586,7 @@ public: // ---------------------- j = Sf2VoiceCount; - param.data[j].index = j; + //param.data[j].index = j; param.data[j].rindex = j; param.data[j].type = PARAMETER_OUTPUT; param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE; diff --git a/src/carla/vst.cpp b/src/carla/vst.cpp index 82c0262..d66e634 100644 --- a/src/carla/vst.cpp +++ b/src/carla/vst.cpp @@ -25,7 +25,6 @@ #if VESTIGE_HEADER #warning Using vestige header -#define kVstVersion 2400 #define effFlagsProgramChunks (1 << 5) #define effGetParamLabel 6 #define effGetChunk 23 @@ -38,8 +37,6 @@ #define effStartProcess 71 #define effStopProcess 72 #define effSetProcessPrecision 77 -#define kVstProcessPrecision32 0 -#define kVstTransportChanged 1 #define kPlugCategSynth 2 #define kPlugCategAnalysis 3 #define kPlugCategMastering 4 @@ -47,6 +44,9 @@ #define kPlugCategRestoration 8 #define kPlugCategShell 10 #define kPlugCategGenerator 11 +#define kVstProcessPrecision32 0 +#define kVstTransportChanged 1 +#define kVstVersion 2400 struct VstTimeInfo_R { double samplePos, sampleRate, nanoSeconds, ppqPos, tempo, barStartPos, cycleStartPos, cycleEndPos; int32_t timeSigNumerator, timeSigDenominator, smpteOffset, smpteFrameRate, samplesToNextClock, flags; @@ -341,7 +341,7 @@ public: for (j=0; j