From: IOhannes m zmölnig (Debian/GNU) Date: Tue, 21 Jun 2022 15:59:28 +0000 (+0200) Subject: Drop additional LV2-files, now that JUCE supports LV2 natively X-Git-Tag: archive/raspbian/7.0.0_ds0-1+rpi1^2~23 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=278f8e0f943425ddf1ba42314b906ddd81e68d0b;p=juce.git Drop additional LV2-files, now that JUCE supports LV2 natively --- diff --git a/debian/copyright b/debian/copyright index b0d8bd28..076fec1b 100644 --- a/debian/copyright +++ b/debian/copyright @@ -61,10 +61,6 @@ Copyright: 2019, Olivier Humbert License: GPL-2+ or GPL-3 -Files: debian/extra/juce_audio_plugin_client/* debian/extra/lv2-ttl-generator/lv2_ttl_generator.c -Copyright: Filipe Coelho -License: GPL-2+ or AGPL-3 - Files: debian/extra/juce_audio_plugin_client/LV2/includes/lv2_external_ui.h Copyright: NONE License: public-domain diff --git a/debian/extra/juce_audio_plugin_client/LV2/includes/lv2_external_ui.h b/debian/extra/juce_audio_plugin_client/LV2/includes/lv2_external_ui.h deleted file mode 100644 index 789cd3ff..00000000 --- a/debian/extra/juce_audio_plugin_client/LV2/includes/lv2_external_ui.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - LV2 External UI extension - This work is in public domain. - - This file is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - If you have questions, contact Filipe Coelho (aka falkTX) - or ask in #lad channel, FreeNode IRC network. -*/ - -/** - @file lv2_external_ui.h - C header for the LV2 External UI extension . -*/ - -#ifndef LV2_EXTERNAL_UI_H -#define LV2_EXTERNAL_UI_H - -#include "ui.h" - -#define LV2_EXTERNAL_UI_URI "http://kxstudio.sf.net/ns/lv2ext/external-ui" -#define LV2_EXTERNAL_UI_PREFIX LV2_EXTERNAL_UI_URI "#" - -#define LV2_EXTERNAL_UI__Host LV2_EXTERNAL_UI_PREFIX "Host" -#define LV2_EXTERNAL_UI__Widget LV2_EXTERNAL_UI_PREFIX "Widget" - -/** This extension used to be defined by a lv2plug.in URI */ -#define LV2_EXTERNAL_UI_DEPRECATED_URI "http://lv2plug.in/ns/extensions/ui#external" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * When LV2_EXTERNAL_UI__Widget UI is instantiated, the returned - * LV2UI_Widget handle must be cast to pointer to LV2_External_UI_Widget. - * UI is created in invisible state. - */ -typedef struct _LV2_External_UI_Widget { - /** - * Host calls this function regulary. UI library implementing the - * callback may do IPC or redraw the UI. - * - * @param _this_ the UI context - */ - void (*run)(struct _LV2_External_UI_Widget * _this_); - - /** - * Host calls this function to make the plugin UI visible. - * - * @param _this_ the UI context - */ - void (*show)(struct _LV2_External_UI_Widget * _this_); - - /** - * Host calls this function to make the plugin UI invisible again. - * - * @param _this_ the UI context - */ - void (*hide)(struct _LV2_External_UI_Widget * _this_); - -} LV2_External_UI_Widget; - -#define LV2_EXTERNAL_UI_RUN(ptr) (ptr)->run(ptr) -#define LV2_EXTERNAL_UI_SHOW(ptr) (ptr)->show(ptr) -#define LV2_EXTERNAL_UI_HIDE(ptr) (ptr)->hide(ptr) - -/** - * On UI instantiation, host must supply LV2_EXTERNAL_UI__Host feature. - * LV2_Feature::data must be pointer to LV2_External_UI_Host. - */ -typedef struct _LV2_External_UI_Host { - /** - * Callback that plugin UI will call when UI (GUI window) is closed by user. - * This callback will be called during execution of LV2_External_UI_Widget::run() - * (i.e. not from background thread). - * - * After this callback is called, UI is defunct. Host must call LV2UI_Descriptor::cleanup(). - * If host wants to make the UI visible again, the UI must be reinstantiated. - * - * @note When using the depreated URI LV2_EXTERNAL_UI_DEPRECATED_URI, - * some hosts will not call LV2UI_Descriptor::cleanup() as they should, - * and may call show() again without re-initialization. - * - * @param controller Host context associated with plugin UI, as - * supplied to LV2UI_Descriptor::instantiate(). - */ - void (*ui_closed)(LV2UI_Controller controller); - - /** - * Optional (may be NULL) "user friendly" identifier which the UI - * may display to allow a user to easily associate this particular - * UI instance with the correct plugin instance as it is represented - * by the host (e.g. "track 1" or "channel 4"). - * - * If supplied by host, the string will be referenced only during - * LV2UI_Descriptor::instantiate() - */ - const char * plugin_human_id; - -} LV2_External_UI_Host; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* LV2_EXTERNAL_UI_H */ diff --git a/debian/extra/juce_audio_plugin_client/LV2/includes/lv2_programs.h b/debian/extra/juce_audio_plugin_client/LV2/includes/lv2_programs.h deleted file mode 100644 index 01e28771..00000000 --- a/debian/extra/juce_audio_plugin_client/LV2/includes/lv2_programs.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - LV2 Programs Extension - Copyright 2012 Filipe Coelho - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -/** - @file lv2_programs.h - C header for the LV2 programs extension . -*/ - -#ifndef LV2_PROGRAMS_H -#define LV2_PROGRAMS_H - -#include "lv2.h" -#include "ui.h" - -#define LV2_PROGRAMS_URI "http://kxstudio.sf.net/ns/lv2ext/programs" -#define LV2_PROGRAMS_PREFIX LV2_PROGRAMS_URI "#" - -#define LV2_PROGRAMS__Host LV2_PROGRAMS_PREFIX "Host" -#define LV2_PROGRAMS__Interface LV2_PROGRAMS_PREFIX "Interface" -#define LV2_PROGRAMS__UIInterface LV2_PROGRAMS_PREFIX "UIInterface" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void* LV2_Programs_Handle; - -typedef struct _LV2_Program_Descriptor { - - /** Bank number for this program. Note that this extension does not - support MIDI-style separation of bank LSB and MSB values. There is - no restriction on the set of available banks: the numbers do not - need to be contiguous, there does not need to be a bank 0, etc. */ - uint32_t bank; - - /** Program number (unique within its bank) for this program. There is - no restriction on the set of available programs: the numbers do not - need to be contiguous, there does not need to be a program 0, etc. */ - uint32_t program; - - /** Name of the program. */ - const char * name; - -} LV2_Program_Descriptor; - -/** - Programs extension, plugin data. - - When the plugin's extension_data is called with argument LV2_PROGRAMS__Interface, - the plugin MUST return an LV2_Programs_Instance structure, which remains valid - for the lifetime of the plugin. -*/ -typedef struct _LV2_Programs_Interface { - /** - * get_program() - * - * This member is a function pointer that provides a description - * of a program (named preset sound) available on this plugin. - * - * The index argument is an index into the plugin's list of - * programs, not a program number as represented by the Program - * field of the LV2_Program_Descriptor. (This distinction is - * needed to support plugins that use non-contiguous program or - * bank numbers.) - * - * This function returns a LV2_Program_Descriptor pointer that is - * guaranteed to be valid only until the next call to get_program - * or deactivate, on the same plugin instance. This function must - * return NULL if passed an index argument out of range, so that - * the host can use it to query the number of programs as well as - * their properties. - */ - const LV2_Program_Descriptor *(*get_program)(LV2_Handle handle, - uint32_t index); - - /** - * select_program() - * - * This member is a function pointer that selects a new program - * for this plugin. The program change should take effect - * immediately at the start of the next run() call. (This - * means that a host providing the capability of changing programs - * between any two notes on a track must vary the block size so as - * to place the program change at the right place. A host that - * wanted to avoid this would probably just instantiate a plugin - * for each program.) - * - * Plugins should ignore a select_program() call with an invalid - * bank or program. - * - * A plugin is not required to select any particular default - * program on activate(): it's the host's duty to set a program - * explicitly. - * - * A plugin is permitted to re-write the values of its input - * control ports when select_program is called. The host should - * re-read the input control port values and update its own - * records appropriately. (This is the only circumstance in which - * a LV2 plugin is allowed to modify its own control-input ports.) - */ - void (*select_program)(LV2_Handle handle, - uint32_t bank, - uint32_t program); - -} LV2_Programs_Interface; - -/** - Programs extension, UI data. - - When the UI's extension_data is called with argument LV2_PROGRAMS__UIInterface, - the UI MUST return an LV2_Programs_UI_Interface structure, which remains valid - for the lifetime of the UI. -*/ -typedef struct _LV2_Programs_UI_Interface { - /** - * select_program() - * - * This is exactly the same as select_program in LV2_Programs_Instance, - * but this struct relates to the UI instead of the plugin. - * - * When called, UIs should update their state to match the selected program. - */ - void (*select_program)(LV2UI_Handle handle, - uint32_t bank, - uint32_t program); - -} LV2_Programs_UI_Interface; - -/** - Feature data for LV2_PROGRAMS__Host. -*/ -typedef struct _LV2_Programs_Host { - /** - * Opaque host data. - */ - LV2_Programs_Handle handle; - - /** - * program_changed() - * - * Tell the host to reload a plugin's program. - * Parameter handle MUST be the 'handle' member of this struct. - * Parameter index is program index to change. - * When index is -1, host should reload all the programs. - * - * The plugin MUST NEVER call this function on a RT context or during run(). - * - * NOTE: This call is to inform the host about a program's bank, program or name change. - * It DOES NOT change the current selected program. - */ - void (*program_changed)(LV2_Programs_Handle handle, - int32_t index); - -} LV2_Programs_Host; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* LV2_PROGRAMS_H */ diff --git a/debian/extra/juce_audio_plugin_client/LV2/juce_LV2_Wrapper.cpp b/debian/extra/juce_audio_plugin_client/LV2/juce_LV2_Wrapper.cpp deleted file mode 100644 index f21292da..00000000 --- a/debian/extra/juce_audio_plugin_client/LV2/juce_LV2_Wrapper.cpp +++ /dev/null @@ -1,2170 +0,0 @@ -/* - ============================================================================== - - Juce LV2 Wrapper - - ============================================================================== -*/ - -#include -#include -#include "../utility/juce_CheckSettingMacros.h" - -#if JucePlugin_Build_LV2 - -/** Plugin requires processing with a fixed/constant block size */ -#ifndef JucePlugin_WantsLV2FixedBlockSize - #define JucePlugin_WantsLV2FixedBlockSize 0 -#endif - -/** Enable latency port */ -#ifndef JucePlugin_WantsLV2Latency - #define JucePlugin_WantsLV2Latency 1 -#endif - -/** Use non-parameter states */ -#ifndef JucePlugin_WantsLV2State - #define JucePlugin_WantsLV2State 1 -#endif - -/** States are strings, needs custom get/setStateInformationString */ -#ifndef JucePlugin_WantsLV2StateString - #define JucePlugin_WantsLV2StateString 0 -#endif - -/** Export presets */ -#ifndef JucePlugin_WantsLV2Presets - #define JucePlugin_WantsLV2Presets 1 -#endif - -/** Request time position */ -#ifndef JucePlugin_WantsLV2TimePos - #define JucePlugin_WantsLV2TimePos 1 -#endif - -/** Using string states require enabling states first */ -#if JucePlugin_WantsLV2StateString && ! JucePlugin_WantsLV2State - #undef JucePlugin_WantsLV2State - #define JucePlugin_WantsLV2State 1 -#endif - -#if JUCE_LINUX && ! JUCE_AUDIOPROCESSOR_NO_GUI - #include - #undef KeyPress -#endif - -#include -#include - -// LV2 includes.. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "includes/lv2_external_ui.h" -#include "includes/lv2_programs.h" - -#include "../utility/juce_IncludeModuleHeaders.h" - -#define JUCE_LV2_STATE_STRING_URI "urn:juce:stateString" -#define JUCE_LV2_STATE_BINARY_URI "urn:juce:stateBinary" - -//============================================================================== -// Various helper functions for creating the ttl files - -#if JUCE_MAC - #define PLUGIN_EXT ".dylib" -#elif JUCE_LINUX - #define PLUGIN_EXT ".so" -#elif JUCE_WINDOWS - #define PLUGIN_EXT ".dll" -#endif - -using namespace juce; - -/** Returns plugin type, defined in AppConfig.h or JucePluginCharacteristics.h */ -const String getPluginType() -{ - String pluginType; -#ifdef JucePlugin_LV2Category - pluginType = "lv2:" JucePlugin_LV2Category; - pluginType += ", "; -#elif JucePlugin_IsSynth - pluginType = "lv2:InstrumentPlugin, "; -#endif - pluginType += "lv2:Plugin"; - return pluginType; -} - -/** Returns plugin URI */ -static const String& getPluginURI() -{ - // JucePlugin_LV2URI might be defined as a function (eg. allowing dynamic URIs based on filename) - static const String pluginURI(JucePlugin_LV2URI); - return pluginURI; -} - -static Array usedSymbols; - -/** Converts a parameter name to an LV2 compatible symbol. */ -const String nameToSymbol (const String& name, const uint32 portIndex) -{ - String symbol, trimmedName = name.trimStart().trimEnd().toLowerCase(); - - if (trimmedName.isEmpty()) - { - symbol += "lv2_port_"; - symbol += String(portIndex+1); - } - else - { - for (int i=0; i < trimmedName.length(); ++i) - { - const juce_wchar c = trimmedName[i]; - if (i == 0 && std::isdigit(c)) - symbol += "_"; - else if (std::isalpha(c) || std::isdigit(c)) - symbol += c; - else - symbol += "_"; - } - } - - // Do not allow identical symbols - if (usedSymbols.contains(symbol)) - { - int offset = 2; - String offsetStr = "_2"; - symbol += offsetStr; - - while (usedSymbols.contains(symbol)) - { - offset += 1; - String newOffsetStr = "_" + String(offset); - symbol = symbol.replace(offsetStr, newOffsetStr); - offsetStr = newOffsetStr; - } - } - usedSymbols.add(symbol); - - return symbol; -} - -/** Prevents NaN or out of 0.0<->1.0 bounds parameter values. */ -float safeParamValue (float value) -{ - if (std::isnan(value)) - value = 0.0f; - else if (value < 0.0f) - value = 0.0f; - else if (value > 1.0f) - value = 1.0f; - return value; -} - -/** Create the manifest.ttl file contents */ -const String makeManifestFile (AudioProcessor* const filter, const String& binary) -{ - const String& pluginURI(getPluginURI()); - String text; - - // Header - text += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n"; - text += "@prefix pset: <" LV2_PRESETS_PREFIX "> .\n"; - text += "@prefix rdfs: .\n"; - text += "@prefix ui: <" LV2_UI_PREFIX "> .\n"; - text += "\n"; - - // Plugin - text += "<" + pluginURI + ">\n"; - text += " a lv2:Plugin ;\n"; - text += " lv2:binary <" + binary + PLUGIN_EXT "> ;\n"; - text += " rdfs:seeAlso <" + binary + ".ttl> .\n"; - text += "\n"; - -#if ! JUCE_AUDIOPROCESSOR_NO_GUI - // UIs - if (filter->hasEditor()) - { - text += "<" + pluginURI + "#ExternalUI>\n"; - text += " a <" LV2_EXTERNAL_UI__Widget "> ;\n"; - text += " ui:binary <" + binary + PLUGIN_EXT "> ;\n"; - text += " lv2:requiredFeature <" LV2_INSTANCE_ACCESS_URI "> ;\n"; - text += " lv2:extensionData <" LV2_PROGRAMS__UIInterface "> .\n"; - text += "\n"; - - text += "<" + pluginURI + "#ParentUI>\n"; - #if JUCE_MAC - text += " a ui:CocoaUI ;\n"; - #elif JUCE_LINUX - text += " a ui:X11UI ;\n"; - #elif JUCE_WINDOWS - text += " a ui:WindowsUI ;\n"; - #endif - text += " ui:binary <" + binary + PLUGIN_EXT "> ;\n"; - text += " lv2:requiredFeature <" LV2_INSTANCE_ACCESS_URI "> ;\n"; - text += " lv2:optionalFeature ui:noUserResize ;\n"; - text += " lv2:extensionData <" LV2_PROGRAMS__UIInterface "> .\n"; - text += "\n"; - } -#endif - -#if JucePlugin_WantsLV2Presets - const String presetSeparator(pluginURI.contains("#") ? ":" : "#"); - - // Presets - for (int i = 0; i < filter->getNumPrograms(); ++i) - { - text += "<" + pluginURI + presetSeparator + "preset" + String::formatted("%03i", i+1) + ">\n"; - text += " a pset:Preset ;\n"; - text += " lv2:appliesTo <" + pluginURI + "> ;\n"; - text += " rdfs:label \"" + filter->getProgramName(i) + "\" ;\n"; - text += " rdfs:seeAlso .\n"; - text += "\n"; - } -#endif - - return text; -} - -/** Create the -plugin-.ttl file contents */ -const String makePluginFile (AudioProcessor* const filter, const int maxNumInputChannels, const int maxNumOutputChannels) -{ - const String& pluginURI(getPluginURI()); - String text; - - // Header - text += "@prefix atom: <" LV2_ATOM_PREFIX "> .\n"; - text += "@prefix doap: .\n"; - text += "@prefix foaf: .\n"; - text += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n"; - text += "@prefix rdfs: .\n"; - text += "@prefix ui: <" LV2_UI_PREFIX "> .\n"; - text += "\n"; - - // Plugin - text += "<" + pluginURI + ">\n"; - text += " a " + getPluginType() + " ;\n"; - text += " lv2:requiredFeature <" LV2_BUF_SIZE__boundedBlockLength "> ,\n"; -#if JucePlugin_WantsLV2FixedBlockSize - text += " <" LV2_BUF_SIZE__fixedBlockLength "> ,\n"; -#endif - text += " <" LV2_URID__map "> ;\n"; - text += " lv2:extensionData <" LV2_OPTIONS__interface "> ,\n"; -#if JucePlugin_WantsLV2State - text += " <" LV2_STATE__interface "> ,\n"; -#endif - text += " <" LV2_PROGRAMS__Interface "> ;\n"; - text += "\n"; - -#if ! JUCE_AUDIOPROCESSOR_NO_GUI - // UIs - if (filter->hasEditor()) - { - text += " ui:ui <" + pluginURI + "#ExternalUI> ,\n"; - text += " <" + pluginURI + "#ParentUI> ;\n"; - text += "\n"; - } -#endif - - uint32 portIndex = 0; - -#if (JucePlugin_WantsMidiInput || JucePlugin_WantsLV2TimePos) - // MIDI input - text += " lv2:port [\n"; - text += " a lv2:InputPort, atom:AtomPort ;\n"; - text += " atom:bufferType atom:Sequence ;\n"; - #if JucePlugin_WantsMidiInput - text += " atom:supports <" LV2_MIDI__MidiEvent "> ;\n"; - #endif - #if JucePlugin_WantsLV2TimePos - text += " atom:supports <" LV2_TIME__Position "> ;\n"; - #endif - text += " lv2:index " + String(portIndex++) + " ;\n"; - text += " lv2:symbol \"lv2_events_in\" ;\n"; - text += " lv2:name \"Events Input\" ;\n"; - text += " lv2:designation lv2:control ;\n"; - #if ! JucePlugin_IsSynth - text += " lv2:portProperty lv2:connectionOptional ;\n"; - #endif - text += " ] ;\n"; - text += "\n"; -#endif - -#if JucePlugin_ProducesMidiOutput - // MIDI output - text += " lv2:port [\n"; - text += " a lv2:OutputPort, atom:AtomPort ;\n"; - text += " atom:bufferType atom:Sequence ;\n"; - text += " atom:supports <" LV2_MIDI__MidiEvent "> ;\n"; - text += " lv2:index " + String(portIndex++) + " ;\n"; - text += " lv2:symbol \"lv2_midi_out\" ;\n"; - text += " lv2:name \"MIDI Output\" ;\n"; - text += " ] ;\n"; - text += "\n"; -#endif - - // Freewheel port - text += " lv2:port [\n"; - text += " a lv2:InputPort, lv2:ControlPort ;\n"; - text += " lv2:index " + String(portIndex++) + " ;\n"; - text += " lv2:symbol \"lv2_freewheel\" ;\n"; - text += " lv2:name \"Freewheel\" ;\n"; - text += " lv2:default 0.0 ;\n"; - text += " lv2:minimum 0.0 ;\n"; - text += " lv2:maximum 1.0 ;\n"; - text += " lv2:designation <" LV2_CORE__freeWheeling "> ;\n"; - text += " lv2:portProperty lv2:toggled, <" LV2_PORT_PROPS__notOnGUI "> ;\n"; - text += " ] ;\n"; - text += "\n"; - -#if JucePlugin_WantsLV2Latency - // Latency port - text += " lv2:port [\n"; - text += " a lv2:OutputPort, lv2:ControlPort ;\n"; - text += " lv2:index " + String(portIndex++) + " ;\n"; - text += " lv2:symbol \"lv2_latency\" ;\n"; - text += " lv2:name \"Latency\" ;\n"; - text += " lv2:designation <" LV2_CORE__latency "> ;\n"; - text += " lv2:portProperty lv2:reportsLatency, lv2:integer ;\n"; - text += " ] ;\n"; - text += "\n"; -#endif - - // Audio inputs - for (int i=0; i < maxNumInputChannels; ++i) - { - if (i == 0) - text += " lv2:port [\n"; - else - text += " [\n"; - - text += " a lv2:InputPort, lv2:AudioPort ;\n"; - text += " lv2:index " + String(portIndex++) + " ;\n"; - text += " lv2:symbol \"lv2_audio_in_" + String(i+1) + "\" ;\n"; - text += " lv2:name \"Audio Input " + String(i+1) + "\" ;\n"; - - if (i+1 == maxNumInputChannels) - text += " ] ;\n\n"; - else - text += " ] ,\n"; - } - - // Audio outputs - for (int i=0; i < maxNumOutputChannels; ++i) - { - if (i == 0) - text += " lv2:port [\n"; - else - text += " [\n"; - - text += " a lv2:OutputPort, lv2:AudioPort ;\n"; - text += " lv2:index " + String(portIndex++) + " ;\n"; - text += " lv2:symbol \"lv2_audio_out_" + String(i+1) + "\" ;\n"; - text += " lv2:name \"Audio Output " + String(i+1) + "\" ;\n"; - - if (i+1 == maxNumOutputChannels) - text += " ] ;\n\n"; - else - text += " ] ,\n"; - } - - // Parameters - for (int i=0; i < filter->getNumParameters(); ++i) - { - if (i == 0) - text += " lv2:port [\n"; - else - text += " [\n"; - - text += " a lv2:InputPort, lv2:ControlPort ;\n"; - text += " lv2:index " + String(portIndex++) + " ;\n"; - text += " lv2:symbol \"" + nameToSymbol(filter->getParameterName(i), i) + "\" ;\n"; - - if (filter->getParameterName(i).isNotEmpty()) - text += " lv2:name \"" + filter->getParameterName(i) + "\" ;\n"; - else - text += " lv2:name \"Port " + String(i+1) + "\" ;\n"; - - text += " lv2:default " + String::formatted("%f", safeParamValue(filter->getParameter(i))) + " ;\n"; - text += " lv2:minimum 0.0 ;\n"; - text += " lv2:maximum 1.0 ;\n"; - - if (! filter->isParameterAutomatable(i)) - text += " lv2:portProperty <" LV2_PORT_PROPS__expensive "> ;\n"; - - if (i+1 == filter->getNumParameters()) - text += " ] ;\n\n"; - else - text += " ] ,\n"; - } - - text += " doap:name \"" + filter->getName() + "\" ;\n"; - text += " doap:maintainer [ foaf:name \"" JucePlugin_Manufacturer "\" ] .\n"; - - return text; -} - -/** Create the presets.ttl file contents */ -const String makePresetsFile (AudioProcessor* const filter) -{ - const String& pluginURI(getPluginURI()); - String text; - - // Header - text += "@prefix atom: <" LV2_ATOM_PREFIX "> .\n"; - text += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n"; - text += "@prefix pset: <" LV2_PRESETS_PREFIX "> .\n"; - text += "@prefix rdf: .\n"; - text += "@prefix rdfs: .\n"; - text += "@prefix state: <" LV2_STATE_PREFIX "> .\n"; - text += "@prefix xsd: .\n"; - text += "\n"; - - // Presets - const int numPrograms = filter->getNumPrograms(); - const String presetSeparator(pluginURI.contains("#") ? ":" : "#"); - - for (int i = 0; i < numPrograms; ++i) - { - std::cout << "\nSaving preset " << i+1 << "/" << numPrograms+1 << "..."; - std::cout.flush(); - - String preset; - - // Label - filter->setCurrentProgram(i); - preset += "<" + pluginURI + presetSeparator + "preset" + String::formatted("%03i", i+1) + "> a pset:Preset ;\n"; - - // State -#if JucePlugin_WantsLV2State - preset += " state:state [\n"; - #if JucePlugin_WantsLV2StateString - preset += " <" JUCE_LV2_STATE_STRING_URI ">\n"; - preset += "\"\"\"\n"; - preset += filter->getStateInformationString().replace("\r\n","\n"); - preset += "\"\"\"\n"; - #else - MemoryBlock chunkMemory; - filter->getCurrentProgramStateInformation(chunkMemory); - const String chunkString(Base64::toBase64(chunkMemory.getData(), chunkMemory.getSize())); - - preset += " <" JUCE_LV2_STATE_BINARY_URI "> [\n"; - preset += " a atom:Chunk ;\n"; - preset += " rdf:value \"" + chunkString + "\"^^xsd:base64Binary ;\n"; - preset += " ] ;\n"; - #endif - if (filter->getNumParameters() == 0) - { - preset += " ] .\n\n"; - continue; - } - - preset += " ] ;\n\n"; -#endif - - // Port values - usedSymbols.clear(); - - for (int j=0; j < filter->getNumParameters(); ++j) - { - if (j == 0) - preset += " lv2:port [\n"; - else - preset += " [\n"; - - preset += " lv2:symbol \"" + nameToSymbol(filter->getParameterName(j), j) + "\" ;\n"; - preset += " pset:value " + String::formatted("%f", safeParamValue(filter->getParameter(j))) + " ;\n"; - - if (j+1 == filter->getNumParameters()) - preset += " ] "; - else - preset += " ] ,\n"; - } - preset += ".\n\n"; - - text += preset; - } - - return text; -} - -/** Creates manifest.ttl, plugin.ttl and presets.ttl files */ -void createLv2Files(const char* basename) -{ - const ScopedJuceInitialiser_GUI juceInitialiser; - ScopedPointer filter (createPluginFilterOfType (AudioProcessor::wrapperType_LV2)); - - String binary(basename); - String binaryTTL(binary + ".ttl"); - - std::cout << "Writing manifest.ttl..."; std::cout.flush(); - std::fstream manifest("manifest.ttl", std::ios::out); - manifest << makeManifestFile(filter, binary) << std::endl; - manifest.close(); - std::cout << " done!" << std::endl; - - std::cout << "Writing " << binary << ".ttl..."; std::cout.flush(); - std::fstream plugin(binaryTTL.toUTF8(), std::ios::out); - plugin << makePluginFile(filter, JucePlugin_MaxNumInputChannels, JucePlugin_MaxNumOutputChannels) << std::endl; - plugin.close(); - std::cout << " done!" << std::endl; - -#if JucePlugin_WantsLV2Presets - std::cout << "Writing presets.ttl..."; std::cout.flush(); - std::fstream presets("presets.ttl", std::ios::out); - presets << makePresetsFile(filter) << std::endl; - presets.close(); - std::cout << " done!" << std::endl; -#endif -} - -//============================================================================== -#if JUCE_LINUX - -class SharedMessageThread : public Thread -{ -public: - SharedMessageThread() - : Thread ("Lv2MessageThread"), - initialised (false) - { - startThread (7); - - while (! initialised) - sleep (1); - } - - ~SharedMessageThread() - { - MessageManager::getInstance()->stopDispatchLoop(); - waitForThreadToExit (5000); - } - - void run() override - { - const ScopedJuceInitialiser_GUI juceInitialiser; - - MessageManager::getInstance()->setCurrentThreadAsMessageThread(); - initialised = true; - - MessageManager::getInstance()->runDispatchLoop(); - } - -private: - volatile bool initialised; -}; -#endif - -#if ! JUCE_AUDIOPROCESSOR_NO_GUI -//============================================================================== -/** - Lightweight DocumentWindow subclass for external ui -*/ -class JuceLv2ExternalUIWindow : public DocumentWindow -{ -public: - /** Creates a Document Window wrapper */ - JuceLv2ExternalUIWindow (AudioProcessorEditor* editor, const String& title) : - DocumentWindow (title, Colours::white, DocumentWindow::minimiseButton | DocumentWindow::closeButton, false), - closed (false), - lastPos (0, 0) - { - setOpaque (true); - setContentNonOwned (editor, true); - setSize (editor->getWidth(), editor->getHeight()); - setUsingNativeTitleBar (true); - } - - /** Close button handler */ - void closeButtonPressed() - { - saveLastPos(); - removeFromDesktop(); - closed = true; - } - - void saveLastPos() - { - lastPos = getScreenPosition(); - } - - void restoreLastPos() - { - setTopLeftPosition (lastPos.getX(), lastPos.getY()); - } - - Point getLastPos() - { - return lastPos; - } - - bool isClosed() - { - return closed; - } - - void reset() - { - closed = false; - } - -private: - bool closed; - Point lastPos; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JuceLv2ExternalUIWindow); -}; - -//============================================================================== -/** - Juce LV2 External UI handle -*/ -class JuceLv2ExternalUIWrapper : public LV2_External_UI_Widget -{ -public: - JuceLv2ExternalUIWrapper (AudioProcessorEditor* editor, const String& title) - : window (editor, title) - { - // external UI calls - run = doRun; - show = doShow; - hide = doHide; - } - - ~JuceLv2ExternalUIWrapper() - { - if (window.isOnDesktop()) - window.removeFromDesktop(); - } - - void close() - { - window.closeButtonPressed(); - } - - bool isClosed() - { - return window.isClosed(); - } - - void reset(const String& title) - { - window.reset(); - window.setName(title); - } - - void repaint() - { - window.repaint(); - } - - Point getScreenPosition() - { - if (window.isClosed()) - return window.getLastPos(); - else - return window.getScreenPosition(); - } - - void setScreenPos (int x, int y) - { - if (! window.isClosed()) - window.setTopLeftPosition(x, y); - } - - //============================================================================== - static void doRun (LV2_External_UI_Widget* _this_) - { - const MessageManagerLock mmLock; - JuceLv2ExternalUIWrapper* self = (JuceLv2ExternalUIWrapper*) _this_; - - if (! self->isClosed()) - self->window.repaint(); - } - - static void doShow (LV2_External_UI_Widget* _this_) - { - const MessageManagerLock mmLock; - JuceLv2ExternalUIWrapper* self = (JuceLv2ExternalUIWrapper*) _this_; - - if (! self->isClosed()) - { - if (! self->window.isOnDesktop()) - self->window.addToDesktop(); - - self->window.restoreLastPos(); - self->window.setVisible(true); - } - } - - static void doHide (LV2_External_UI_Widget* _this_) - { - const MessageManagerLock mmLock; - JuceLv2ExternalUIWrapper* self = (JuceLv2ExternalUIWrapper*) _this_; - - if (! self->isClosed()) - { - self->window.saveLastPos(); - self->window.setVisible(false); - } - } - -private: - JuceLv2ExternalUIWindow window; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JuceLv2ExternalUIWrapper); -}; - -//============================================================================== -/** - Juce LV2 Parent UI container, listens for resize events and passes them to ui-resize -*/ -class JuceLv2ParentContainer : public Component -{ -public: - JuceLv2ParentContainer (AudioProcessorEditor* editor, const LV2UI_Resize* uiResize_) - : uiResize(uiResize_) - { - setOpaque (true); - editor->setOpaque (true); - setBounds (editor->getBounds()); - - editor->setTopLeftPosition (0, 0); - addAndMakeVisible (editor); - } - - ~JuceLv2ParentContainer() - { - } - - void paint (Graphics&) {} - void paintOverChildren (Graphics&) {} - - void childBoundsChanged (Component* child) - { - const int cw = child->getWidth(); - const int ch = child->getHeight(); - -#if JUCE_LINUX - XResizeWindow (display.display, (Window) getWindowHandle(), cw, ch); -#else - setSize (cw, ch); -#endif - - if (uiResize != nullptr) - uiResize->ui_resize (uiResize->handle, cw, ch); - } - - void reset (const LV2UI_Resize* uiResize_) - { - uiResize = uiResize_; - - if (uiResize != nullptr) - uiResize->ui_resize (uiResize->handle, getWidth(), getHeight()); - } - -private: - //============================================================================== - const LV2UI_Resize* uiResize; -#if JUCE_LINUX - ScopedXDisplay display; -#endif - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JuceLv2ParentContainer); -}; - -//============================================================================== -/** - Juce LV2 UI handle -*/ -class JuceLv2UIWrapper : public AudioProcessorListener, - public Timer -{ -public: - JuceLv2UIWrapper (AudioProcessor* filter_, LV2UI_Write_Function writeFunction_, LV2UI_Controller controller_, - LV2UI_Widget* widget, const LV2_Feature* const* features, bool isExternal_) - : filter (filter_), - writeFunction (writeFunction_), - controller (controller_), - isExternal (isExternal_), - controlPortOffset (0), - lastProgramCount (0), - uiTouch (nullptr), - programsHost (nullptr), - externalUIHost (nullptr), - lastExternalUIPos (-1, -1), - uiResize (nullptr) - { - jassert (filter != nullptr); - - filter->addListener(this); - - if (filter->hasEditor()) - { - editor = filter->createEditorIfNeeded(); - - if (editor == nullptr) - { - *widget = nullptr; - return; - } - } - - for (int i = 0; features[i] != nullptr; ++i) - { - if (strcmp(features[i]->URI, LV2_UI__touch) == 0) - uiTouch = (const LV2UI_Touch*)features[i]->data; - - else if (strcmp(features[i]->URI, LV2_PROGRAMS__Host) == 0) - programsHost = (const LV2_Programs_Host*)features[i]->data; - } - - if (isExternal) - { - resetExternalUI (features); - - if (externalUIHost != nullptr) - { - String title (filter->getName()); - - if (externalUIHost->plugin_human_id != nullptr) - title = externalUIHost->plugin_human_id; - - externalUI = new JuceLv2ExternalUIWrapper (editor, title); - *widget = externalUI; - startTimer (100); - } - else - { - *widget = nullptr; - } - } - else - { - resetParentUI (features); - - if (parentContainer != nullptr) - *widget = parentContainer->getWindowHandle(); - else - *widget = nullptr; - } - -#if (JucePlugin_WantsMidiInput || JucePlugin_WantsLV2TimePos) - controlPortOffset += 1; -#endif -#if JucePlugin_ProducesMidiOutput - controlPortOffset += 1; -#endif - controlPortOffset += 1; // freewheel -#if JucePlugin_WantsLV2Latency - controlPortOffset += 1; -#endif - controlPortOffset += JucePlugin_MaxNumInputChannels; - controlPortOffset += JucePlugin_MaxNumOutputChannels; - - lastProgramCount = filter->getNumPrograms(); - } - - ~JuceLv2UIWrapper() - { - PopupMenu::dismissAllActiveMenus(); - - filter->removeListener(this); - - parentContainer = nullptr; - externalUI = nullptr; - externalUIHost = nullptr; - - if (editor != nullptr) - { - filter->editorBeingDeleted (editor); - editor = nullptr; - } - } - - //============================================================================== - // LV2 core calls - - void lv2Cleanup() - { - const MessageManagerLock mmLock; - - if (isExternal) - { - if (isTimerRunning()) - stopTimer(); - - externalUIHost = nullptr; - - if (externalUI != nullptr) - { - lastExternalUIPos = externalUI->getScreenPosition(); - externalUI->close(); - } - } - else - { - if (parentContainer) - { - parentContainer->setVisible (false); - if (parentContainer->isOnDesktop()) - parentContainer->removeFromDesktop(); - } - } - } - - //============================================================================== - // Juce calls - - void audioProcessorParameterChanged (AudioProcessor*, int index, float newValue) - { - if (writeFunction != nullptr && controller != nullptr) - writeFunction (controller, index + controlPortOffset, sizeof (float), 0, &newValue); - } - - void audioProcessorChanged (AudioProcessor*) - { - if (filter != nullptr && programsHost != nullptr) - { - if (filter->getNumPrograms() != lastProgramCount) - { - programsHost->program_changed (programsHost->handle, -1); - lastProgramCount = filter->getNumPrograms(); - } - else - programsHost->program_changed (programsHost->handle, filter->getCurrentProgram()); - } - } - - void audioProcessorParameterChangeGestureBegin (AudioProcessor*, int parameterIndex) - { - if (uiTouch != nullptr) - uiTouch->touch (uiTouch->handle, parameterIndex + controlPortOffset, true); - } - - void audioProcessorParameterChangeGestureEnd (AudioProcessor*, int parameterIndex) - { - if (uiTouch != nullptr) - uiTouch->touch (uiTouch->handle, parameterIndex + controlPortOffset, false); - } - - void timerCallback() - { - if (externalUI != nullptr && externalUI->isClosed()) - { - if (externalUIHost != nullptr) - externalUIHost->ui_closed (controller); - - if (isTimerRunning()) - stopTimer(); - } - } - - //============================================================================== - void resetIfNeeded (LV2UI_Write_Function writeFunction_, LV2UI_Controller controller_, LV2UI_Widget* widget, - const LV2_Feature* const* features) - { - writeFunction = writeFunction_; - controller = controller_; - uiTouch = nullptr; - programsHost = nullptr; - - for (int i = 0; features[i] != nullptr; ++i) - { - if (strcmp(features[i]->URI, LV2_UI__touch) == 0) - uiTouch = (const LV2UI_Touch*)features[i]->data; - - else if (strcmp(features[i]->URI, LV2_PROGRAMS__Host) == 0) - programsHost = (const LV2_Programs_Host*)features[i]->data; - } - - if (isExternal) - { - resetExternalUI (features); - *widget = externalUI; - } - else - { - resetParentUI (features); - *widget = parentContainer->getWindowHandle(); - } - } - - void repaint() - { - const MessageManagerLock mmLock; - - if (editor != nullptr) - editor->repaint(); - - if (parentContainer != nullptr) - parentContainer->repaint(); - - if (externalUI != nullptr) - externalUI->repaint(); - } - -private: - AudioProcessor* const filter; - ScopedPointer editor; - - LV2UI_Write_Function writeFunction; - LV2UI_Controller controller; - const bool isExternal; - - uint32 controlPortOffset; - int lastProgramCount; - - const LV2UI_Touch* uiTouch; - const LV2_Programs_Host* programsHost; - - ScopedPointer externalUI; - const LV2_External_UI_Host* externalUIHost; - Point lastExternalUIPos; - - ScopedPointer parentContainer; - const LV2UI_Resize* uiResize; - -#if JUCE_LINUX - ScopedXDisplay display; -#endif - - //============================================================================== - void resetExternalUI (const LV2_Feature* const* features) - { - externalUIHost = nullptr; - - for (int i = 0; features[i] != nullptr; ++i) - { - if (strcmp(features[i]->URI, LV2_EXTERNAL_UI__Host) == 0) - { - externalUIHost = (const LV2_External_UI_Host*)features[i]->data; - break; - } - } - - if (externalUI != nullptr) - { - String title(filter->getName()); - - if (externalUIHost->plugin_human_id != nullptr) - title = externalUIHost->plugin_human_id; - - if (lastExternalUIPos.getX() != -1 && lastExternalUIPos.getY() != -1) - externalUI->setScreenPos(lastExternalUIPos.getX(), lastExternalUIPos.getY()); - - externalUI->reset(title); - startTimer (100); - } - } - - void resetParentUI (const LV2_Feature* const* features) - { - void* parent = nullptr; - uiResize = nullptr; - - for (int i = 0; features[i] != nullptr; ++i) - { - if (strcmp(features[i]->URI, LV2_UI__parent) == 0) - parent = features[i]->data; - - else if (strcmp(features[i]->URI, LV2_UI__resize) == 0) - uiResize = (const LV2UI_Resize*)features[i]->data; - } - - if (parent != nullptr) - { - if (parentContainer == nullptr) - parentContainer = new JuceLv2ParentContainer (editor, uiResize); - - parentContainer->setVisible (false); - - if (parentContainer->isOnDesktop()) - parentContainer->removeFromDesktop(); - - parentContainer->addToDesktop (0, parent); - -#if JUCE_LINUX - Window hostWindow = (Window) parent; - Window editorWnd = (Window) parentContainer->getWindowHandle(); - XReparentWindow (display.display, editorWnd, hostWindow, 0, 0); -#endif - - parentContainer->reset (uiResize); - parentContainer->setVisible (true); - } - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JuceLv2UIWrapper) -}; - -#endif /* JUCE_AUDIOPROCESSOR_NO_GUI */ - -//============================================================================== -/** - Juce LV2 handle -*/ -class JuceLv2Wrapper : public AudioPlayHead -{ -public: - //============================================================================== - JuceLv2Wrapper (double sampleRate_, const LV2_Feature* const* features) - : numInChans (JucePlugin_MaxNumInputChannels), - numOutChans (JucePlugin_MaxNumOutputChannels), - bufferSize (2048), - sampleRate (sampleRate_), - uridMap (nullptr), - uridAtomBlank (0), - uridAtomObject (0), - uridAtomDouble (0), - uridAtomFloat (0), - uridAtomInt (0), - uridAtomLong (0), - uridAtomSequence (0), - uridMidiEvent (0), - uridTimePos (0), - uridTimeBar (0), - uridTimeBarBeat (0), - uridTimeBeatsPerBar (0), - uridTimeBeatsPerMinute (0), - uridTimeBeatUnit (0), - uridTimeFrame (0), - uridTimeSpeed (0), - usingNominalBlockLength (false) - { - { - const MessageManagerLock mmLock; - filter = createPluginFilterOfType (AudioProcessor::wrapperType_LV2); - } - jassert (filter != nullptr); - - filter->setPlayConfigDetails (numInChans, numOutChans, 0, 0); - filter->setPlayHead (this); - -#if (JucePlugin_WantsMidiInput || JucePlugin_WantsLV2TimePos) - portEventsIn = nullptr; -#endif -#if JucePlugin_ProducesMidiOutput - portMidiOut = nullptr; -#endif - - portFreewheel = nullptr; - -#if JucePlugin_WantsLV2Latency - portLatency = nullptr; -#endif - - for (int i=0; i < numInChans; ++i) - portAudioIns[i] = nullptr; - for (int i=0; i < numOutChans; ++i) - portAudioOuts[i] = nullptr; - - portControls.insertMultiple (0, nullptr, filter->getNumParameters()); - - for (int i=0; i < filter->getNumParameters(); ++i) - lastControlValues.add (filter->getParameter(i)); - - curPosInfo.resetToDefault(); - - // we need URID_Map first - for (int i=0; features[i] != nullptr; ++i) - { - if (strcmp(features[i]->URI, LV2_URID__map) == 0) - { - uridMap = (const LV2_URID_Map*)features[i]->data; - break; - } - } - - // we require uridMap to work properly (it's set as required feature) - jassert (uridMap != nullptr); - - if (uridMap != nullptr) - { - uridAtomBlank = uridMap->map(uridMap->handle, LV2_ATOM__Blank); - uridAtomObject = uridMap->map(uridMap->handle, LV2_ATOM__Object); - uridAtomDouble = uridMap->map(uridMap->handle, LV2_ATOM__Double); - uridAtomFloat = uridMap->map(uridMap->handle, LV2_ATOM__Float); - uridAtomInt = uridMap->map(uridMap->handle, LV2_ATOM__Int); - uridAtomLong = uridMap->map(uridMap->handle, LV2_ATOM__Long); - uridAtomSequence = uridMap->map(uridMap->handle, LV2_ATOM__Sequence); - uridMidiEvent = uridMap->map(uridMap->handle, LV2_MIDI__MidiEvent); - uridTimePos = uridMap->map(uridMap->handle, LV2_TIME__Position); - uridTimeBar = uridMap->map(uridMap->handle, LV2_TIME__bar); - uridTimeBarBeat = uridMap->map(uridMap->handle, LV2_TIME__barBeat); - uridTimeBeatsPerBar = uridMap->map(uridMap->handle, LV2_TIME__beatsPerBar); - uridTimeBeatsPerMinute = uridMap->map(uridMap->handle, LV2_TIME__beatsPerMinute); - uridTimeBeatUnit = uridMap->map(uridMap->handle, LV2_TIME__beatUnit); - uridTimeFrame = uridMap->map(uridMap->handle, LV2_TIME__frame); - uridTimeSpeed = uridMap->map(uridMap->handle, LV2_TIME__speed); - - for (int i=0; features[i] != nullptr; ++i) - { - if (strcmp(features[i]->URI, LV2_OPTIONS__options) == 0) - { - const LV2_Options_Option* options = (const LV2_Options_Option*)features[i]->data; - - for (int j=0; options[j].key != 0; ++j) - { - if (options[j].key == uridMap->map(uridMap->handle, LV2_BUF_SIZE__nominalBlockLength)) - { - if (options[j].type == uridAtomInt) - { - bufferSize = *(int*)options[j].value; - usingNominalBlockLength = true; - } - else - { - std::cerr << "Host provides nominalBlockLength but has wrong value type" << std::endl; - } - break; - } - - if (options[j].key == uridMap->map(uridMap->handle, LV2_BUF_SIZE__maxBlockLength)) - { - if (options[j].type == uridAtomInt) - bufferSize = *(int*)options[j].value; - else - std::cerr << "Host provides maxBlockLength but has wrong value type" << std::endl; - - // no break, continue in case host supports nominalBlockLength - } - } - break; - } - } - } - - progDesc.bank = 0; - progDesc.program = 0; - progDesc.name = nullptr; - } - - ~JuceLv2Wrapper () - { - const MessageManagerLock mmLock; - -#if ! JUCE_AUDIOPROCESSOR_NO_GUI - ui = nullptr; -#endif - filter = nullptr; - - if (progDesc.name != nullptr) - free((void*)progDesc.name); - - portControls.clear(); - lastControlValues.clear(); - } - - //============================================================================== - // LV2 core calls - - void lv2ConnectPort (uint32 portId, void* dataLocation) - { - uint32 index = 0; - -#if (JucePlugin_WantsMidiInput || JucePlugin_WantsLV2TimePos) - if (portId == index++) - { - portEventsIn = (LV2_Atom_Sequence*)dataLocation; - return; - } -#endif - -#if JucePlugin_ProducesMidiOutput - if (portId == index++) - { - portMidiOut = (LV2_Atom_Sequence*)dataLocation; - return; - } -#endif - - if (portId == index++) - { - portFreewheel = (float*)dataLocation; - return; - } - -#if JucePlugin_WantsLV2Latency - if (portId == index++) - { - portLatency = (float*)dataLocation; - return; - } -#endif - - for (int i=0; i < numInChans; ++i) - { - if (portId == index++) - { - portAudioIns[i] = (float*)dataLocation; - return; - } - } - - for (int i=0; i < numOutChans; ++i) - { - if (portId == index++) - { - portAudioOuts[i] = (float*)dataLocation; - return; - } - } - - for (int i=0; i < filter->getNumParameters(); ++i) - { - if (portId == index++) - { - portControls.set(i, (float*)dataLocation); - return; - } - } - } - - void lv2Activate() - { - jassert (filter != nullptr); - - filter->prepareToPlay (sampleRate, bufferSize); - filter->setPlayConfigDetails (numInChans, numOutChans, sampleRate, bufferSize); - - channels.calloc (numInChans + numOutChans); - -#if (JucePlugin_WantsMidiInput || JucePlugin_ProducesMidiOutput) - midiEvents.ensureSize (2048); - midiEvents.clear(); -#endif - } - - void lv2Deactivate() - { - jassert (filter != nullptr); - - filter->releaseResources(); - - channels.free(); - } - - void lv2Run (uint32 sampleCount) - { - jassert (filter != nullptr); - -#if JucePlugin_WantsLV2Latency - if (portLatency != nullptr) - *portLatency = filter->getLatencySamples(); -#endif - - if (portFreewheel != nullptr) - filter->setNonRealtime (*portFreewheel >= 0.5f); - - if (sampleCount == 0) - { - /** - LV2 pre-roll - Hosts might use this to force plugins to update its output control ports. - (plugins can only access port locations during run) */ - return; - } - - // Check for updated parameters - { - float curValue; - - for (int i = 0; i < portControls.size(); ++i) - { - if (portControls[i] != nullptr) - { - curValue = *portControls[i]; - - if (lastControlValues[i] != curValue) - { - filter->setParameter (i, curValue); - lastControlValues.setUnchecked (i, curValue); - } - } - } - } - - { - const ScopedLock sl (filter->getCallbackLock()); - - if (filter->isSuspended() && false) - { - for (int i = 0; i < numOutChans; ++i) - zeromem (portAudioOuts[i], sizeof (float) * sampleCount); - } - else - { - int i; - for (i = 0; i < numOutChans; ++i) - { - channels[i] = portAudioOuts[i]; - - if (i < numInChans && portAudioIns[i] != portAudioOuts[i]) - FloatVectorOperations::copy (portAudioOuts [i], portAudioIns[i], sampleCount); - } - - for (; i < numInChans; ++i) - channels [i] = portAudioIns[i]; - -#if (JucePlugin_WantsMidiInput || JucePlugin_WantsLV2TimePos) - if (portEventsIn != nullptr) - { - midiEvents.clear(); - - LV2_ATOM_SEQUENCE_FOREACH(portEventsIn, iter) - { - const LV2_Atom_Event* event = (const LV2_Atom_Event*)iter; - - if (event == nullptr) - continue; - if (event->time.frames >= sampleCount) - break; - - #if JucePlugin_WantsMidiInput - if (event->body.type == uridMidiEvent) - { - const uint8* data = (const uint8*)(event + 1); - midiEvents.addEvent(data, event->body.size, event->time.frames); - continue; - } - #endif - #if JucePlugin_WantsLV2TimePos - if (event->body.type == uridAtomBlank || event->body.type == uridAtomObject) - { - const LV2_Atom_Object* obj = (LV2_Atom_Object*)&event->body; - - if (obj->body.otype != uridTimePos) - continue; - - LV2_Atom* bar = nullptr; - LV2_Atom* barBeat = nullptr; - LV2_Atom* beatUnit = nullptr; - LV2_Atom* beatsPerBar = nullptr; - LV2_Atom* beatsPerMinute = nullptr; - LV2_Atom* frame = nullptr; - LV2_Atom* speed = nullptr; - - lv2_atom_object_get (obj, - uridTimeBar, &bar, - uridTimeBarBeat, &barBeat, - uridTimeBeatUnit, &beatUnit, - uridTimeBeatsPerBar, &beatsPerBar, - uridTimeBeatsPerMinute, &beatsPerMinute, - uridTimeFrame, &frame, - uridTimeSpeed, &speed, - nullptr); - - // need to handle this first as other values depend on it - if (speed != nullptr) - { - /**/ if (speed->type == uridAtomDouble) - lastPositionData.speed = ((LV2_Atom_Double*)speed)->body; - else if (speed->type == uridAtomFloat) - lastPositionData.speed = ((LV2_Atom_Float*)speed)->body; - else if (speed->type == uridAtomInt) - lastPositionData.speed = ((LV2_Atom_Int*)speed)->body; - else if (speed->type == uridAtomLong) - lastPositionData.speed = ((LV2_Atom_Long*)speed)->body; - - curPosInfo.isPlaying = lastPositionData.speed != 0.0; - } - - if (bar != nullptr) - { - /**/ if (bar->type == uridAtomDouble) - lastPositionData.bar = ((LV2_Atom_Double*)bar)->body; - else if (bar->type == uridAtomFloat) - lastPositionData.bar = ((LV2_Atom_Float*)bar)->body; - else if (bar->type == uridAtomInt) - lastPositionData.bar = ((LV2_Atom_Int*)bar)->body; - else if (bar->type == uridAtomLong) - lastPositionData.bar = ((LV2_Atom_Long*)bar)->body; - } - - if (barBeat != nullptr) - { - /**/ if (barBeat->type == uridAtomDouble) - lastPositionData.barBeat = ((LV2_Atom_Double*)barBeat)->body; - else if (barBeat->type == uridAtomFloat) - lastPositionData.barBeat = ((LV2_Atom_Float*)barBeat)->body; - else if (barBeat->type == uridAtomInt) - lastPositionData.barBeat = ((LV2_Atom_Int*)barBeat)->body; - else if (barBeat->type == uridAtomLong) - lastPositionData.barBeat = ((LV2_Atom_Long*)barBeat)->body; - } - - if (beatUnit != nullptr) - { - /**/ if (beatUnit->type == uridAtomDouble) - lastPositionData.beatUnit = ((LV2_Atom_Double*)beatUnit)->body; - else if (beatUnit->type == uridAtomFloat) - lastPositionData.beatUnit = ((LV2_Atom_Float*)beatUnit)->body; - else if (beatUnit->type == uridAtomInt) - lastPositionData.beatUnit = ((LV2_Atom_Int*)beatUnit)->body; - else if (beatUnit->type == uridAtomLong) - lastPositionData.beatUnit = ((LV2_Atom_Long*)beatUnit)->body; - - if (lastPositionData.beatUnit > 0) - curPosInfo.timeSigDenominator = lastPositionData.beatUnit; - } - - if (beatsPerBar != nullptr) - { - /**/ if (beatsPerBar->type == uridAtomDouble) - lastPositionData.beatsPerBar = ((LV2_Atom_Double*)beatsPerBar)->body; - else if (beatsPerBar->type == uridAtomFloat) - lastPositionData.beatsPerBar = ((LV2_Atom_Float*)beatsPerBar)->body; - else if (beatsPerBar->type == uridAtomInt) - lastPositionData.beatsPerBar = ((LV2_Atom_Int*)beatsPerBar)->body; - else if (beatsPerBar->type == uridAtomLong) - lastPositionData.beatsPerBar = ((LV2_Atom_Long*)beatsPerBar)->body; - - if (lastPositionData.beatsPerBar > 0.0f) - curPosInfo.timeSigNumerator = lastPositionData.beatsPerBar; - } - - if (beatsPerMinute != nullptr) - { - /**/ if (beatsPerMinute->type == uridAtomDouble) - lastPositionData.beatsPerMinute = ((LV2_Atom_Double*)beatsPerMinute)->body; - else if (beatsPerMinute->type == uridAtomFloat) - lastPositionData.beatsPerMinute = ((LV2_Atom_Float*)beatsPerMinute)->body; - else if (beatsPerMinute->type == uridAtomInt) - lastPositionData.beatsPerMinute = ((LV2_Atom_Int*)beatsPerMinute)->body; - else if (beatsPerMinute->type == uridAtomLong) - lastPositionData.beatsPerMinute = ((LV2_Atom_Long*)beatsPerMinute)->body; - - if (lastPositionData.beatsPerMinute > 0.0f) - { - curPosInfo.bpm = lastPositionData.beatsPerMinute; - - if (lastPositionData.speed != 0) - curPosInfo.bpm *= std::abs(lastPositionData.speed); - } - } - - if (frame != nullptr) - { - /**/ if (frame->type == uridAtomDouble) - lastPositionData.frame = ((LV2_Atom_Double*)frame)->body; - else if (frame->type == uridAtomFloat) - lastPositionData.frame = ((LV2_Atom_Float*)frame)->body; - else if (frame->type == uridAtomInt) - lastPositionData.frame = ((LV2_Atom_Int*)frame)->body; - else if (frame->type == uridAtomLong) - lastPositionData.frame = ((LV2_Atom_Long*)frame)->body; - - if (lastPositionData.frame >= 0) - { - curPosInfo.timeInSamples = lastPositionData.frame; - curPosInfo.timeInSeconds = double(curPosInfo.timeInSamples)/sampleRate; - } - } - - if (lastPositionData.bar >= 0 && lastPositionData.beatsPerBar > 0.0f) - { - curPosInfo.ppqPositionOfLastBarStart = lastPositionData.bar * lastPositionData.beatsPerBar; - - if (lastPositionData.barBeat >= 0.0f) - curPosInfo.ppqPosition = curPosInfo.ppqPositionOfLastBarStart + lastPositionData.barBeat; - } - - lastPositionData.extraValid = (lastPositionData.beatsPerMinute > 0.0 && - lastPositionData.beatUnit > 0 && - lastPositionData.beatsPerBar > 0.0f); - } - #endif - } - } -#endif - { - AudioSampleBuffer chans (channels, jmax (numInChans, numOutChans), sampleCount); - filter->processBlock (chans, midiEvents); - } - } - } - -#if JucePlugin_WantsLV2TimePos - // update timePos for next callback - if (lastPositionData.speed != 0.0) - { - if (lastPositionData.speed > 0.0) - { - // playing forwards - lastPositionData.frame += sampleCount; - } - else - { - // playing backwards - lastPositionData.frame -= sampleCount; - - if (lastPositionData.frame < 0) - lastPositionData.frame = 0; - } - - curPosInfo.timeInSamples = lastPositionData.frame; - curPosInfo.timeInSeconds = double(curPosInfo.timeInSamples)/sampleRate; - - if (lastPositionData.extraValid) - { - const double beatsPerMinute = lastPositionData.beatsPerMinute * lastPositionData.speed; - const double framesPerBeat = 60.0 * sampleRate / beatsPerMinute; - const double addedBarBeats = double(sampleCount) / framesPerBeat; - - if (lastPositionData.bar >= 0 && lastPositionData.barBeat >= 0.0f) - { - lastPositionData.bar += std::floor((lastPositionData.barBeat+addedBarBeats)/ - lastPositionData.beatsPerBar); - lastPositionData.barBeat = std::fmod(lastPositionData.barBeat+addedBarBeats, - lastPositionData.beatsPerBar); - - if (lastPositionData.bar < 0) - lastPositionData.bar = 0; - - curPosInfo.ppqPositionOfLastBarStart = lastPositionData.bar * lastPositionData.beatsPerBar; - curPosInfo.ppqPosition = curPosInfo.ppqPositionOfLastBarStart + lastPositionData.barBeat; - } - - curPosInfo.bpm = std::abs(beatsPerMinute); - } - } -#endif - -#if JucePlugin_ProducesMidiOutput - if (portMidiOut != nullptr) - { - const uint32_t capacity = portMidiOut->atom.size; - - portMidiOut->atom.size = sizeof(LV2_Atom_Sequence_Body); - portMidiOut->atom.type = uridAtomSequence; - portMidiOut->body.unit = 0; - portMidiOut->body.pad = 0; - - if (! midiEvents.isEmpty()) - { - const uint8* midiEventData; - int midiEventSize, midiEventPosition; - MidiBuffer::Iterator i (midiEvents); - - uint32_t size, offset = 0; - LV2_Atom_Event* aev; - - while (i.getNextEvent (midiEventData, midiEventSize, midiEventPosition)) - { - jassert (midiEventPosition >= 0 && midiEventPosition < (int)sampleCount); - - if (sizeof(LV2_Atom_Event) + midiEventSize > capacity - offset) - break; - - aev = (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, portMidiOut) + offset); - aev->time.frames = midiEventPosition; - aev->body.type = uridMidiEvent; - aev->body.size = midiEventSize; - memcpy(LV2_ATOM_BODY(&aev->body), midiEventData, midiEventSize); - - size = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + midiEventSize); - offset += size; - portMidiOut->atom.size += size; - } - - midiEvents.clear(); - } - } else -#endif - if (! midiEvents.isEmpty()) - { - midiEvents.clear(); - } - } - - //============================================================================== - // LV2 extended calls - - uint32_t lv2GetOptions (LV2_Options_Option* options) - { - // currently unused - ignoreUnused(options); - - return LV2_OPTIONS_SUCCESS; - } - - uint32_t lv2SetOptions (const LV2_Options_Option* options) - { - for (int j=0; options[j].key != 0; ++j) - { - if (options[j].key == uridMap->map(uridMap->handle, LV2_BUF_SIZE__nominalBlockLength)) - { - if (options[j].type == uridAtomInt) - bufferSize = *(int*)options[j].value; - else - std::cerr << "Host changed nominalBlockLength but with wrong value type" << std::endl; - } - else if (options[j].key == uridMap->map(uridMap->handle, LV2_BUF_SIZE__maxBlockLength) && ! usingNominalBlockLength) - { - if (options[j].type == uridAtomInt) - bufferSize = *(int*)options[j].value; - else - std::cerr << "Host changed maxBlockLength but with wrong value type" << std::endl; - } - else if (options[j].key == uridMap->map(uridMap->handle, LV2_CORE__sampleRate)) - { - if (options[j].type == uridAtomDouble) - sampleRate = *(double*)options[j].value; - else - std::cerr << "Host changed sampleRate but with wrong value type" << std::endl; - } - } - - return LV2_OPTIONS_SUCCESS; - } - - const LV2_Program_Descriptor* lv2GetProgram (uint32_t index) - { - jassert (filter != nullptr); - - if (progDesc.name != nullptr) - { - free((void*)progDesc.name); - progDesc.name = nullptr; - } - - if ((int)index < filter->getNumPrograms()) - { - progDesc.bank = index / 128; - progDesc.program = index % 128; - progDesc.name = strdup(filter->getProgramName(index).toUTF8()); - return &progDesc; - } - - return nullptr; - } - - void lv2SelectProgram (uint32_t bank, uint32_t program) - { - jassert (filter != nullptr); - - int realProgram = bank * 128 + program; - - if (realProgram < filter->getNumPrograms()) - { - filter->setCurrentProgram(realProgram); - - // update input control ports now - for (int i = 0; i < portControls.size(); ++i) - { - float value = filter->getParameter(i); - - if (portControls[i] != nullptr) - *portControls[i] = value; - - lastControlValues.set(i, value); - } - } - } - - LV2_State_Status lv2SaveState (LV2_State_Store_Function store, LV2_State_Handle stateHandle) - { - jassert (filter != nullptr); - -#if JucePlugin_WantsLV2StateString - String stateData(filter->getStateInformationString().replace("\r\n","\n")); - CharPointer_UTF8 charData(stateData.toUTF8()); - - store (stateHandle, - uridMap->map(uridMap->handle, JUCE_LV2_STATE_STRING_URI), - charData.getAddress(), - charData.sizeInBytes(), - uridMap->map(uridMap->handle, LV2_ATOM__String), - LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE); -#else - MemoryBlock chunkMemory; - filter->getCurrentProgramStateInformation (chunkMemory); - - store (stateHandle, - uridMap->map(uridMap->handle, JUCE_LV2_STATE_BINARY_URI), - chunkMemory.getData(), - chunkMemory.getSize(), - uridMap->map(uridMap->handle, LV2_ATOM__Chunk), - LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE); -#endif - - return LV2_STATE_SUCCESS; - } - - LV2_State_Status lv2RestoreState (LV2_State_Retrieve_Function retrieve, LV2_State_Handle stateHandle, uint32_t flags) - { - jassert (filter != nullptr); - - size_t size = 0; - uint32 type = 0; - const void* data = retrieve (stateHandle, -#if JucePlugin_WantsLV2StateString - uridMap->map(uridMap->handle, JUCE_LV2_STATE_STRING_URI), -#else - uridMap->map(uridMap->handle, JUCE_LV2_STATE_BINARY_URI), -#endif - &size, &type, &flags); - - if (data == nullptr || size == 0 || type == 0) - return LV2_STATE_ERR_UNKNOWN; - -#if JucePlugin_WantsLV2StateString - if (type == uridMap->map (uridMap->handle, LV2_ATOM__String)) - { - String stateData (CharPointer_UTF8(static_cast(data))); - filter->setStateInformationString (stateData); - - #if ! JUCE_AUDIOPROCESSOR_NO_GUI - if (ui != nullptr) - ui->repaint(); - #endif - - return LV2_STATE_SUCCESS; - } -#else - if (type == uridMap->map (uridMap->handle, LV2_ATOM__Chunk)) - { - filter->setCurrentProgramStateInformation (data, size); - - #if ! JUCE_AUDIOPROCESSOR_NO_GUI - if (ui != nullptr) - ui->repaint(); - #endif - - return LV2_STATE_SUCCESS; - } -#endif - - return LV2_STATE_ERR_BAD_TYPE; - } - - //============================================================================== - // Juce calls - - bool getCurrentPosition (AudioPlayHead::CurrentPositionInfo& info) - { -#if JucePlugin_WantsLV2TimePos - info = curPosInfo; - return true; -#else - ignoreUnused(info); - return false; -#endif - } - -#if ! JUCE_AUDIOPROCESSOR_NO_GUI - //============================================================================== - JuceLv2UIWrapper* getUI (LV2UI_Write_Function writeFunction, LV2UI_Controller controller, LV2UI_Widget* widget, - const LV2_Feature* const* features, bool isExternal) - { - const MessageManagerLock mmLock; - - if (ui != nullptr) - ui->resetIfNeeded (writeFunction, controller, widget, features); - else - ui = new JuceLv2UIWrapper (filter, writeFunction, controller, widget, features, isExternal); - - return ui; - } -#endif - -private: -#if JUCE_LINUX - SharedResourcePointer msgThread; -#else - SharedResourcePointer sharedJuceGUI; -#endif - - ScopedPointer filter; -#if ! JUCE_AUDIOPROCESSOR_NO_GUI - ScopedPointer ui; -#endif - HeapBlock channels; - MidiBuffer midiEvents; - int numInChans, numOutChans; - -#if (JucePlugin_WantsMidiInput || JucePlugin_WantsLV2TimePos) - LV2_Atom_Sequence* portEventsIn; -#endif -#if JucePlugin_ProducesMidiOutput - LV2_Atom_Sequence* portMidiOut; -#endif - float* portFreewheel; -#if JucePlugin_WantsLV2Latency - float* portLatency; -#endif - float* portAudioIns[JucePlugin_MaxNumInputChannels]; - float* portAudioOuts[JucePlugin_MaxNumOutputChannels]; - Array portControls; - - uint32 bufferSize; - double sampleRate; - Array lastControlValues; - AudioPlayHead::CurrentPositionInfo curPosInfo; - - struct Lv2PositionData { - int64_t bar; - float barBeat; - uint32_t beatUnit; - float beatsPerBar; - float beatsPerMinute; - int64_t frame; - double speed; - bool extraValid; - - Lv2PositionData() - : bar(-1), - barBeat(-1.0f), - beatUnit(0), - beatsPerBar(0.0f), - beatsPerMinute(0.0f), - frame(-1), - speed(0.0), - extraValid(false) {} - }; - Lv2PositionData lastPositionData; - - const LV2_URID_Map* uridMap; - LV2_URID uridAtomBlank; - LV2_URID uridAtomObject; - LV2_URID uridAtomDouble; - LV2_URID uridAtomFloat; - LV2_URID uridAtomInt; - LV2_URID uridAtomLong; - LV2_URID uridAtomSequence; - LV2_URID uridMidiEvent; - LV2_URID uridTimePos; - LV2_URID uridTimeBar; - LV2_URID uridTimeBarBeat; - LV2_URID uridTimeBeatsPerBar; // timeSigNumerator - LV2_URID uridTimeBeatsPerMinute; // bpm - LV2_URID uridTimeBeatUnit; // timeSigDenominator - LV2_URID uridTimeFrame; // timeInSamples - LV2_URID uridTimeSpeed; - - bool usingNominalBlockLength; // if false use maxBlockLength - - LV2_Program_Descriptor progDesc; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JuceLv2Wrapper) -}; - -//============================================================================== -// LV2 descriptor functions - -static LV2_Handle juceLV2_Instantiate (const LV2_Descriptor*, double sampleRate, const char*, const LV2_Feature* const* features) -{ - return new JuceLv2Wrapper (sampleRate, features); -} - -#define handlePtr ((JuceLv2Wrapper*)handle) - -static void juceLV2_ConnectPort (LV2_Handle handle, uint32 port, void* dataLocation) -{ - handlePtr->lv2ConnectPort (port, dataLocation); -} - -static void juceLV2_Activate (LV2_Handle handle) -{ - handlePtr->lv2Activate(); -} - -static void juceLV2_Run( LV2_Handle handle, uint32 sampleCount) -{ - handlePtr->lv2Run (sampleCount); -} - -static void juceLV2_Deactivate (LV2_Handle handle) -{ - handlePtr->lv2Deactivate(); -} - -static void juceLV2_Cleanup (LV2_Handle handle) -{ - delete handlePtr; -} - -//============================================================================== -// LV2 extended functions - -static uint32_t juceLV2_getOptions (LV2_Handle handle, LV2_Options_Option* options) -{ - return handlePtr->lv2GetOptions(options); -} - -static uint32_t juceLV2_setOptions (LV2_Handle handle, const LV2_Options_Option* options) -{ - return handlePtr->lv2SetOptions(options); -} - -static const LV2_Program_Descriptor* juceLV2_getProgram (LV2_Handle handle, uint32_t index) -{ - return handlePtr->lv2GetProgram(index); -} - -static void juceLV2_selectProgram (LV2_Handle handle, uint32_t bank, uint32_t program) -{ - handlePtr->lv2SelectProgram(bank, program); -} - -static LV2_State_Status juceLV2_SaveState (LV2_Handle handle, LV2_State_Store_Function store, LV2_State_Handle stateHandle, - uint32_t, const LV2_Feature* const*) -{ - return handlePtr->lv2SaveState(store, stateHandle); -} - -static LV2_State_Status juceLV2_RestoreState (LV2_Handle handle, LV2_State_Retrieve_Function retrieve, LV2_State_Handle stateHandle, - uint32_t flags, const LV2_Feature* const*) -{ - return handlePtr->lv2RestoreState(retrieve, stateHandle, flags); -} - -#undef handlePtr - -static const void* juceLV2_ExtensionData (const char* uri) -{ - static const LV2_Options_Interface options = { juceLV2_getOptions, juceLV2_setOptions }; - static const LV2_Programs_Interface programs = { juceLV2_getProgram, juceLV2_selectProgram }; - static const LV2_State_Interface state = { juceLV2_SaveState, juceLV2_RestoreState }; - - if (strcmp(uri, LV2_OPTIONS__interface) == 0) - return &options; - if (strcmp(uri, LV2_PROGRAMS__Interface) == 0) - return &programs; - if (strcmp(uri, LV2_STATE__interface) == 0) - return &state; - - return nullptr; -} - -#if ! JUCE_AUDIOPROCESSOR_NO_GUI -//============================================================================== -// LV2 UI descriptor functions - -static LV2UI_Handle juceLV2UI_Instantiate (LV2UI_Write_Function writeFunction, LV2UI_Controller controller, - LV2UI_Widget* widget, const LV2_Feature* const* features, bool isExternal) -{ - for (int i = 0; features[i] != nullptr; ++i) - { - if (strcmp(features[i]->URI, LV2_INSTANCE_ACCESS_URI) == 0 && features[i]->data != nullptr) - { - JuceLv2Wrapper* wrapper = (JuceLv2Wrapper*)features[i]->data; - return wrapper->getUI(writeFunction, controller, widget, features, isExternal); - } - } - - std::cerr << "Host does not support instance-access, cannot use UI" << std::endl; - return nullptr; -} - -static LV2UI_Handle juceLV2UI_InstantiateExternal (const LV2UI_Descriptor*, const char*, const char*, LV2UI_Write_Function writeFunction, - LV2UI_Controller controller, LV2UI_Widget* widget, const LV2_Feature* const* features) -{ - return juceLV2UI_Instantiate(writeFunction, controller, widget, features, true); -} - -static LV2UI_Handle juceLV2UI_InstantiateParent (const LV2UI_Descriptor*, const char*, const char*, LV2UI_Write_Function writeFunction, - LV2UI_Controller controller, LV2UI_Widget* widget, const LV2_Feature* const* features) -{ - return juceLV2UI_Instantiate(writeFunction, controller, widget, features, false); -} - -static void juceLV2UI_Cleanup (LV2UI_Handle handle) -{ - ((JuceLv2UIWrapper*)handle)->lv2Cleanup(); -} -#endif - -//============================================================================== -// static LV2 Descriptor objects - -static const LV2_Descriptor JuceLv2Plugin = { - strdup(getPluginURI().toRawUTF8()), - juceLV2_Instantiate, - juceLV2_ConnectPort, - juceLV2_Activate, - juceLV2_Run, - juceLV2_Deactivate, - juceLV2_Cleanup, - juceLV2_ExtensionData -}; - -#if ! JUCE_AUDIOPROCESSOR_NO_GUI -static const LV2UI_Descriptor JuceLv2UI_External = { - strdup(String(getPluginURI() + "#ExternalUI").toRawUTF8()), - juceLV2UI_InstantiateExternal, - juceLV2UI_Cleanup, - nullptr, - nullptr -}; - -static const LV2UI_Descriptor JuceLv2UI_Parent = { - strdup(String(getPluginURI() + "#ParentUI").toRawUTF8()), - juceLV2UI_InstantiateParent, - juceLV2UI_Cleanup, - nullptr, - nullptr -}; -#endif - -static const struct DescriptorCleanup { - DescriptorCleanup() {} - ~DescriptorCleanup() - { - free((void*)JuceLv2Plugin.URI); -#if ! JUCE_AUDIOPROCESSOR_NO_GUI - free((void*)JuceLv2UI_External.URI); - free((void*)JuceLv2UI_Parent.URI); -#endif - } -} _descCleanup; - -#if JUCE_WINDOWS - #define JUCE_EXPORTED_FUNCTION extern "C" __declspec (dllexport) -#else - #define JUCE_EXPORTED_FUNCTION extern "C" __attribute__ ((visibility("default"))) -#endif - -//============================================================================== -// startup code.. - -JUCE_EXPORTED_FUNCTION void lv2_generate_ttl (const char* basename); -JUCE_EXPORTED_FUNCTION void lv2_generate_ttl (const char* basename) -{ - createLv2Files (basename); -} - -JUCE_EXPORTED_FUNCTION const LV2_Descriptor* lv2_descriptor (uint32 index); -JUCE_EXPORTED_FUNCTION const LV2_Descriptor* lv2_descriptor (uint32 index) -{ - return (index == 0) ? &JuceLv2Plugin : nullptr; -} - -#if ! JUCE_AUDIOPROCESSOR_NO_GUI -JUCE_EXPORTED_FUNCTION const LV2UI_Descriptor* lv2ui_descriptor (uint32 index); -JUCE_EXPORTED_FUNCTION const LV2UI_Descriptor* lv2ui_descriptor (uint32 index) -{ - switch (index) - { - case 0: - return &JuceLv2UI_External; - case 1: - return &JuceLv2UI_Parent; - default: - return nullptr; - } -} -#endif - -#endif diff --git a/debian/extra/juce_audio_plugin_client/juce_audio_plugin_client_LV2.cpp b/debian/extra/juce_audio_plugin_client/juce_audio_plugin_client_LV2.cpp deleted file mode 100644 index dc507e12..00000000 --- a/debian/extra/juce_audio_plugin_client/juce_audio_plugin_client_LV2.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2017 - ROLI Ltd. - - JUCE is an open source library subject to commercial or open-source - licensing. - - By using JUCE, you agree to the terms of both the JUCE 5 End-User License - Agreement and JUCE 5 Privacy Policy (both updated and effective as of the - 27th April 2017). - - End User License Agreement: www.juce.com/juce-5-licence - Privacy Policy: www.juce.com/juce-5-privacy-policy - - Or: You may also use this code under the terms of the GPL v3 (see - www.gnu.org/licenses). - - JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER - EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE - DISCLAIMED. - - ============================================================================== -*/ - -#include "LV2/juce_LV2_Wrapper.cpp" diff --git a/debian/extra/lv2-ttl-generator/GNUmakefile b/debian/extra/lv2-ttl-generator/GNUmakefile deleted file mode 100644 index aded2b9e..00000000 --- a/debian/extra/lv2-ttl-generator/GNUmakefile +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/makefile -f - -all: build - -build: lv2_ttl_generator -mingw: lv2_ttl_generator.exe - -lv2_ttl_generator: lv2_ttl_generator.c - $(CXX) $(CPPFLAGS) $(CXXFLAGS) lv2_ttl_generator.c -o lv2_ttl_generator -ldl $(LDFLAGS) - -lv2_ttl_generator.exe: lv2_ttl_generator.c - $(CXX) lv2_ttl_generator.c -o lv2_ttl_generator.exe -static - touch lv2_ttl_generator - -clean: - rm -f lv2_ttl_generator lv2_ttl_generator.exe diff --git a/debian/extra/lv2-ttl-generator/generate-ttl.sh b/debian/extra/lv2-ttl-generator/generate-ttl.sh deleted file mode 100755 index d5ef597e..00000000 --- a/debian/extra/lv2-ttl-generator/generate-ttl.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh - -#set -e -#echo "Please run this script from the _bin folder" - -error() { - echo "$@" 1>&2 -} - -SCRIPTPATH=$(cd ${0%/*}; pwd) - -if [ -f ${SCRIPTPATH}/lv2_ttl_generator.exe ]; then - GEN=${SCRIPTPATH}/lv2_ttl_generator.exe - EXT=dll -else - GEN=${SCRIPTPATH}/lv2_ttl_generator - EXT=so -fi -if [ ! -x "${GEN}" ]; then - error "unable to find lv2_ttl_generator" - exit 1 -fi - -SEARCHPATH=$1 -if [ "x${SEARCHPATH}" = "x" ]; then - if [ -d "lv2" ]; then - SEARCHPATH="lv2" - fi - if [ ! -d "${SEARCHPATH}" ]; then - SEARCHPATH=. - fi -fi -if [ ! -d "${SEARCHPATH}" ]; then - error "cannot search plugins in non-existing directory ${SEARCHPATH}" - exit 1 -fi - - -find ${SEARCHPATH} -type d -name "*.lv2" -exec /bin/sh -c "cd {}; ${GEN} ./*.${EXT}" \; - diff --git a/debian/extra/lv2-ttl-generator/lv2_ttl_generator.c b/debian/extra/lv2-ttl-generator/lv2_ttl_generator.c deleted file mode 100644 index bd19f416..00000000 --- a/debian/extra/lv2-ttl-generator/lv2_ttl_generator.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * JUCE LV2 *.ttl generator - */ - -#include -#include - -#ifdef _WIN32 - #include - #define TTL_GENERATOR_WINDOWS -#else - #include -#endif - -#ifndef nullptr - #define nullptr (0) -#endif - -typedef void (*TTL_Generator_Function)(const char* basename); - -int main(int argc, char* argv[]) -{ - if (argc != 2) - { - printf("usage: %s /path/to/plugin-DLL\n", argv[0]); - return 1; - } - -#ifdef TTL_GENERATOR_WINDOWS - const HMODULE handle = LoadLibraryA(argv[1]); -#else - void* const handle = dlopen(argv[1], RTLD_LAZY); -#endif - - if (! handle) - { -#ifdef TTL_GENERATOR_WINDOWS - printf("Failed to open plugin DLL\n"); -#else - printf("Failed to open plugin DLL, error was:\n%s\n", dlerror()); -#endif - return 2; - } - -#ifdef TTL_GENERATOR_WINDOWS - const TTL_Generator_Function ttlFn = (TTL_Generator_Function)GetProcAddress(handle, "lv2_generate_ttl"); -#else - const TTL_Generator_Function ttlFn = (TTL_Generator_Function)dlsym(handle, "lv2_generate_ttl"); -#endif - - if (ttlFn != NULL) - { - char basename[strlen(argv[1])+1]; - -#ifdef TTL_GENERATOR_WINDOWS - if (char* base2 = strrchr(argv[1], '\\')) -#else - if (char* base2 = strrchr(argv[1], '/')) -#endif - { - strcpy(basename, base2+1); - basename[strrchr(base2, '.')-base2-1] = '\0'; - } - else - strcpy(basename, argv[1]); - - printf("Generate ttl data for '%s', basename: '%s'\n", argv[1], basename); - - ttlFn(basename); - } - else - printf("Failed to find 'lv2_generate_ttl' function\n"); - -#ifdef TTL_GENERATOR_WINDOWS - FreeLibrary(handle); -#else - dlclose(handle); -#endif - - return 0; -} diff --git a/debian/extra/lv2-ttl-generator/readme.txt b/debian/extra/lv2-ttl-generator/readme.txt deleted file mode 100644 index 0bd3ab5e..00000000 --- a/debian/extra/lv2-ttl-generator/readme.txt +++ /dev/null @@ -1,7 +0,0 @@ -this lv2_ttl_generator is taken from DISTRHO by Filipe Coelho (aka 'falkTX') - -http://distrho.sourceforge.net -https://github.com/falkTX/DISTRHO - - -this small tool creates the needed .ttl files out of the plug-in binaries (.so) for the .lv2 bundle diff --git a/debian/juce-modules-source-data.install b/debian/juce-modules-source-data.install index 4b71d259..048bb654 100644 --- a/debian/juce-modules-source-data.install +++ b/debian/juce-modules-source-data.install @@ -1,4 +1,3 @@ -debian/extra/juce_audio_plugin_client/* /usr/share/juce/modules/juce_audio_plugin_client/ debian/extra/juce_audio_processors/format_types/juce_VSTInterface.h /usr/share/juce/modules/juce_audio_processors/format_types/ usr/include/JUCE*/* /usr/share/juce/ ChangeList.txt /usr/share/juce/ diff --git a/debian/rules b/debian/rules index d2eb29f4..a74f3341 100755 --- a/debian/rules +++ b/debian/rules @@ -60,7 +60,6 @@ override_dh_auto_build-arch: dh_auto_build -- Projucer cp $(CURDIR)/examples/DemoRunner/Builds/iOS/DemoRunner/Images.xcassets/AppIcon.appiconset/Icon.png \ $(DEBIAN_BUILD_ARTIFACTS)/juce.png - dh_auto_build -D debian/extra/lv2-ttl-generator/ override_dh_auto_build-indep: mkdir -p docs/doxygen/build @@ -69,8 +68,6 @@ override_dh_auto_build-indep: execute_after_dh_auto_install-arch: install -d debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/juce/lv2-ttl-generator - install debian/extra/lv2-ttl-generator/lv2_ttl_generator debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/juce/lv2-ttl-generator/lv2_ttl_generator - install debian/extra/lv2-ttl-generator/generate-ttl.sh debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/juce/lv2-ttl-generator/generate-ttl.sh override_dh_install-indep: dh_install --indep -X.tag @@ -85,7 +82,6 @@ override_dh_installchangelogs: execute_after_dh_clean: make -C docs/doxygen/ clean - make -C debian/extra/lv2-ttl-generator/ clean rm -f $(DEBIAN_BUILD_ARTIFACTS)/*