DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

commit 17f09f33bc046202fd2546a452d9923bf2921596
parent a7c2278668a9fe825c1a9011137c1fe1648531d3
Author: falkTX <falktx@falktx.com>
Date:   Sat,  2 Oct 2021 23:18:42 +0100

VST3: Set factory categories and flags, add documentation

Signed-off-by: falkTX <falktx@falktx.com>

Diffstat:
Mdistrho/DistrhoInfo.hpp | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdistrho/src/DistrhoPluginVST3.cpp | 66+++++++++++++++++++++++++++++++++++++++++++++++-------------------
Mdistrho/src/travesty/factory.h | 9+++++++--
3 files changed, 143 insertions(+), 21 deletions(-)

diff --git a/distrho/DistrhoInfo.hpp b/distrho/DistrhoInfo.hpp @@ -620,6 +620,95 @@ START_NAMESPACE_DISTRHO */ #define DISTRHO_UI_URI DISTRHO_PLUGIN_URI "#UI" +/** + Custom LV2 category for the plugin.@n + This can be one of the following values: + + - lv2:Plugin + - lv2:AllpassPlugin + - lv2:AmplifierPlugin + - lv2:AnalyserPlugin + - lv2:BandpassPlugin + - lv2:ChorusPlugin + - lv2:CombPlugin + - lv2:CompressorPlugin + - lv2:ConstantPlugin + - lv2:ConverterPlugin + - lv2:DelayPlugin + - lv2:DistortionPlugin + - lv2:DynamicsPlugin + - lv2:EQPlugin + - lv2:EnvelopePlugin + - lv2:ExpanderPlugin + - lv2:FilterPlugin + - lv2:FlangerPlugin + - lv2:FunctionPlugin + - lv2:GatePlugin + - lv2:GeneratorPlugin + - lv2:HighpassPlugin + - lv2:InstrumentPlugin + - lv2:LimiterPlugin + - lv2:LowpassPlugin + - lv2:MIDIPlugin + - lv2:MixerPlugin + - lv2:ModulatorPlugin + - lv2:MultiEQPlugin + - lv2:OscillatorPlugin + - lv2:ParaEQPlugin + - lv2:PhaserPlugin + - lv2:PitchPlugin + - lv2:ReverbPlugin + - lv2:SimulatorPlugin + - lv2:SpatialPlugin + - lv2:SpectralPlugin + - lv2:UtilityPlugin + - lv2:WaveshaperPlugin + + See http://lv2plug.in/ns/lv2core for more information. + */ +#define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:Plugin" + +/** + Custom VST3 categories for the plugin.@n + This is a list of categories, separated by a @c |. + + Each effect category can be one of the following values: + + - Fx + - Fx|Ambisonics + - Fx|Analyzer + - Fx|Delay + - Fx|Distortion + - Fx|Dynamics + - Fx|EQ + - Fx|Filter + - Fx|Instrument + - Fx|Instrument|External + - Fx|Spatial + - Fx|Generator + - Fx|Mastering + - Fx|Modulation + - Fx|Network + - Fx|Pitch Shift + - Fx|Restoration + - Fx|Reverb + - Fx|Surround + - Fx|Tools + + Each instrument category can be one of the following values: + + - Instrument + - Instrument|Drum + - Instrument|External + - Instrument|Piano + - Instrument|Sampler + - Instrument|Synth + - Instrument|Synth|Sampler + + @note DPF will automatically set Mono and Stereo categories when appropriate. + */ +#define DISTRHO_PLUGIN_VST3_CATEGORIES "Fx" + /** @} */ /* ------------------------------------------------------------------------------------------------------------ diff --git a/distrho/src/DistrhoPluginVST3.cpp b/distrho/src/DistrhoPluginVST3.cpp @@ -70,8 +70,6 @@ namespace std { * - routing info, do we care? * - set sidechain bus name from port group * - implement getParameterValueForString (use names from enumeration if available, fallback to std::atof) - * - set factory class_flags - * - set factory sub_categories * - set factory email (needs new DPF API, useful for LV2 as well) * - do something with get_controller_class_id and set_io_mode? */ @@ -3468,6 +3466,33 @@ static const PluginExporter& getPluginInfo() return info; } +static const char* getPluginCategories() +{ + static String categories; + static bool firstInit = true; + + if (firstInit) + { +#ifdef DISTRHO_PLUGIN_VST3_CATEGORIES + categories = DISTRHO_PLUGIN_VST3_CATEGORIES; +#elif DISTRHO_PLUGIN_IS_SYNTH + categories = "Instrument"; +#endif +#if (DISTRHO_PLUGIN_NUM_INPUTS == 0 || DISTRHO_PLUGIN_NUM_INPUTS == 1) && DISTRHO_PLUGIN_NUM_OUTPUTS == 1 + if (categories.isNotEmpty()) + categories += "|"; + categories += "Mono"; +#elif (DISTRHO_PLUGIN_NUM_INPUTS == 0 || DISTRHO_PLUGIN_NUM_INPUTS == 2) && DISTRHO_PLUGIN_NUM_OUTPUTS == 2 + if (categories.isNotEmpty()) + categories += "|"; + categories += "Stereo"; +#endif + firstInit = false; + } + + return categories.buffer(); +} + // -------------------------------------------------------------------------------------------------------------------- // dpf_factory @@ -3559,9 +3584,10 @@ struct dpf_factory : v3_plugin_factory_cpp { static V3_API v3_result get_factory_info(void*, v3_factory_info* const info) { std::memset(info, 0, sizeof(*info)); - DISTRHO_NAMESPACE::strncpy(info->vendor, getPluginInfo().getMaker(), sizeof(info->vendor)); - DISTRHO_NAMESPACE::strncpy(info->url, getPluginInfo().getHomePage(), sizeof(info->url)); - // DISTRHO_NAMESPACE::strncpy(info->email, "", sizeof(info->email)); // TODO + DISTRHO_NAMESPACE::strncpy(info->vendor, getPluginInfo().getMaker(), ARRAY_SIZE(info->vendor)); + DISTRHO_NAMESPACE::strncpy(info->url, getPluginInfo().getHomePage(), ARRAY_SIZE(info->url)); + // DISTRHO_NAMESPACE::strncpy(info->email, "", ARRAY_SIZE(info->email)); // TODO + info->flags = 0x10; return V3_OK; } @@ -3573,18 +3599,18 @@ struct dpf_factory : v3_plugin_factory_cpp { static V3_API v3_result get_class_info(void*, int32_t idx, v3_class_info* const info) { std::memset(info, 0, sizeof(*info)); - DISTRHO_SAFE_ASSERT_RETURN(idx == 0, V3_NO_INTERFACE); + DISTRHO_SAFE_ASSERT_RETURN(idx == 0, V3_INVALID_ARG); std::memcpy(info->class_id, dpf_tuid_class, sizeof(v3_tuid)); info->cardinality = 0x7FFFFFFF; - DISTRHO_NAMESPACE::strncpy(info->category, "Audio Module Class", sizeof(info->category)); - DISTRHO_NAMESPACE::strncpy(info->name, getPluginInfo().getName(), sizeof(info->name)); + DISTRHO_NAMESPACE::strncpy(info->category, "Audio Module Class", ARRAY_SIZE(info->category)); + DISTRHO_NAMESPACE::strncpy(info->name, getPluginInfo().getName(), ARRAY_SIZE(info->name)); return V3_OK; } static V3_API v3_result create_instance(void* self, const v3_tuid class_id, const v3_tuid iid, void** instance) { - d_stdout("dpf_factory::create_instance => %p %s %s %p", self, tuid2str(class_id), tuid2str(iid), instance); + d_stdout("dpf_factory::create_instance => %p %s %s %p", self, tuid2str(class_id), tuid2str(iid), instance); DISTRHO_SAFE_ASSERT_RETURN(v3_tuid_match(class_id, *(const v3_tuid*)&dpf_tuid_class) && v3_tuid_match(iid, v3_component_iid), V3_NO_INTERFACE); @@ -3608,7 +3634,7 @@ struct dpf_factory : v3_plugin_factory_cpp { static V3_API v3_result get_class_info_2(void*, int32_t idx, v3_class_info_2* info) { std::memset(info, 0, sizeof(*info)); - DISTRHO_SAFE_ASSERT_RETURN(idx == 0, V3_NO_INTERFACE); + DISTRHO_SAFE_ASSERT_RETURN(idx == 0, V3_INVALID_ARG); std::memcpy(info->class_id, dpf_tuid_class, sizeof(v3_tuid)); info->cardinality = 0x7FFFFFFF; @@ -3616,10 +3642,10 @@ struct dpf_factory : v3_plugin_factory_cpp { DISTRHO_NAMESPACE::strncpy(info->name, getPluginInfo().getName(), ARRAY_SIZE(info->name)); info->class_flags = 0; - // DISTRHO_NAMESPACE::strncpy(info->sub_categories, "", sizeof(info->sub_categories)); // TODO + DISTRHO_NAMESPACE::strncpy(info->sub_categories, getPluginCategories(), ARRAY_SIZE(info->sub_categories)); DISTRHO_NAMESPACE::strncpy(info->vendor, getPluginInfo().getMaker(), ARRAY_SIZE(info->vendor)); DISTRHO_NAMESPACE::snprintf_u32(info->version, getPluginInfo().getVersion(), ARRAY_SIZE(info->version)); // FIXME - DISTRHO_NAMESPACE::strncpy(info->sdk_version, "Travesty", ARRAY_SIZE(info->sdk_version)); // TESTING use "VST 3.7" ? + DISTRHO_NAMESPACE::strncpy(info->sdk_version, "Travesty", ARRAY_SIZE(info->sdk_version)); return V3_OK; } @@ -3629,27 +3655,29 @@ struct dpf_factory : v3_plugin_factory_cpp { static V3_API v3_result get_class_info_utf16(void*, int32_t idx, v3_class_info_3* info) { std::memset(info, 0, sizeof(*info)); - DISTRHO_SAFE_ASSERT_RETURN(idx == 0, V3_NO_INTERFACE); + DISTRHO_SAFE_ASSERT_RETURN(idx == 0, V3_INVALID_ARG); std::memcpy(info->class_id, dpf_tuid_class, sizeof(v3_tuid)); info->cardinality = 0x7FFFFFFF; DISTRHO_NAMESPACE::strncpy(info->category, "Audio Module Class", ARRAY_SIZE(info->category)); DISTRHO_NAMESPACE::strncpy_utf16(info->name, getPluginInfo().getName(), ARRAY_SIZE(info->name)); +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS info->class_flags = 0; - // DISTRHO_NAMESPACE::strncpy(info->sub_categories, "", ARRAY_SIZE(info->sub_categories)); // TODO +#else + info->class_flags = V3_DISTRIBUTABLE; +#endif + DISTRHO_NAMESPACE::strncpy(info->sub_categories, getPluginCategories(), ARRAY_SIZE(info->sub_categories)); DISTRHO_NAMESPACE::strncpy_utf16(info->vendor, getPluginInfo().getMaker(), sizeof(info->vendor)); DISTRHO_NAMESPACE::snprintf_u32_utf16(info->version, getPluginInfo().getVersion(), ARRAY_SIZE(info->version)); // FIXME - DISTRHO_NAMESPACE::strncpy_utf16(info->sdk_version, "Travesty", ARRAY_SIZE(info->sdk_version)); // TESTING use "VST 3.7" ? + DISTRHO_NAMESPACE::strncpy_utf16(info->sdk_version, "Travesty", ARRAY_SIZE(info->sdk_version)); return V3_OK; } static V3_API v3_result set_host_context(void* self, v3_funknown** context) { - d_stdout("dpf_factory::set_host_context => %p %p", self, context); - dpf_factory* const factory = *(dpf_factory**)self; - DISTRHO_SAFE_ASSERT_RETURN(factory != nullptr, V3_NOT_INITIALIZED); - + d_stdout("dpf_factory::set_host_context => %p %p", self, context); + dpf_factory* const factory = *static_cast<dpf_factory**>(self); factory->hostContext = context; return V3_OK; } diff --git a/distrho/src/travesty/factory.h b/distrho/src/travesty/factory.h @@ -26,12 +26,12 @@ struct v3_factory_info { char vendor[64]; char url[256]; char email[128]; - int32_t flags; + int32_t flags; // set to 0x10 (unicode) }; struct v3_class_info { v3_tuid class_id; - int32_t cardinality; // set to 0x7FFFFFFF + int32_t cardinality; // set to 0x7FFFFFFF (many instances) char category[32]; char name[64]; }; @@ -52,6 +52,11 @@ static constexpr const v3_tuid v3_plugin_factory_iid = * plugin factory v2 */ +enum { + V3_DISTRIBUTABLE = 1 << 0, + V3_SIMPLE_MODE = 1 << 1 +}; + struct v3_class_info_2 { v3_tuid class_id; int32_t cardinality; // set to 0x7FFFFFFF