From 9333b1ff0fd5a8f27f9359821cc0a01250fb1c01 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 8 Apr 2019 09:34:15 -0400 Subject: [PATCH 1/4] remove unused --- src/PluginManager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/PluginManager.cpp b/src/PluginManager.cpp index 0e49824d8..efa52cdcf 100644 --- a/src/PluginManager.cpp +++ b/src/PluginManager.cpp @@ -439,7 +439,6 @@ private: void OnDisable(wxCommandEvent & evt); private: - ModuleInterface *mMod; EffectType mType; int mFilter; From 15983499c8db3b9fe184fe8b92d3f31cc2c68e98 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 8 Apr 2019 09:29:42 -0400 Subject: [PATCH 2/4] New virtual function in ModuleInterface --- include/audacity/ModuleInterface.h | 5 +++++ src/commands/LoadCommands.cpp | 6 ++++++ src/commands/LoadCommands.h | 1 + src/effects/LoadEffects.cpp | 7 +++++++ src/effects/LoadEffects.h | 1 + src/effects/VST/VSTEffect.cpp | 9 +++++++++ src/effects/VST/VSTEffect.h | 1 + src/effects/audiounits/AudioUnitEffect.cpp | 9 +++++++++ src/effects/audiounits/AudioUnitEffect.h | 1 + src/effects/ladspa/LadspaEffect.cpp | 9 +++++++++ src/effects/ladspa/LadspaEffect.h | 1 + src/effects/lv2/LoadLV2.cpp | 9 +++++++++ src/effects/lv2/LoadLV2.h | 1 + src/effects/nyquist/LoadNyquist.cpp | 9 +++++++++ src/effects/nyquist/LoadNyquist.h | 2 ++ src/effects/vamp/LoadVamp.cpp | 9 +++++++++ src/effects/vamp/LoadVamp.h | 1 + 17 files changed, 81 insertions(+) diff --git a/include/audacity/ModuleInterface.h b/include/audacity/ModuleInterface.h index fd95811f1..cd66790f4 100644 --- a/include/audacity/ModuleInterface.h +++ b/include/audacity/ModuleInterface.h @@ -76,6 +76,11 @@ public: // Called just prior to deletion to allow releasing any resources. virtual void Terminate() = 0; + // A symbol identifying the family of plugin provided by this module; + // if it is not empty, then the family as a whole can be enabled or + // disabled by the user in Preferences + virtual EffectFamilySymbol GetOptionalFamilySymbol() = 0; + // "Paths" returned by FindPluginPaths() and passed back to // DiscoverPluginsAtPath() have module-specific meaning. // They are not necessarily file system paths to existent files that diff --git a/src/commands/LoadCommands.cpp b/src/commands/LoadCommands.cpp index 5edcc8ab8..ad5491bcb 100644 --- a/src/commands/LoadCommands.cpp +++ b/src/commands/LoadCommands.cpp @@ -224,6 +224,12 @@ void BuiltinCommandsModule::Terminate() return; } +EffectFamilySymbol BuiltinCommandsModule::GetOptionalFamilySymbol() +{ + // Commands are not enabled and disabled in EffectsPrefs + return {}; +} + const FileExtensions &BuiltinCommandsModule::GetFileExtensions() { static FileExtensions empty; diff --git a/src/commands/LoadCommands.h b/src/commands/LoadCommands.h index 7a3811d76..c4192b55a 100644 --- a/src/commands/LoadCommands.h +++ b/src/commands/LoadCommands.h @@ -39,6 +39,7 @@ public: bool Initialize() override; void Terminate() override; + EffectFamilySymbol GetOptionalFamilySymbol() override; const FileExtensions &GetFileExtensions() override; FilePath InstallPath() override { return {}; } diff --git a/src/effects/LoadEffects.cpp b/src/effects/LoadEffects.cpp index ea162d120..f7d4deac2 100644 --- a/src/effects/LoadEffects.cpp +++ b/src/effects/LoadEffects.cpp @@ -290,6 +290,13 @@ void BuiltinEffectsModule::Terminate() return; } +EffectFamilySymbol BuiltinEffectsModule::GetOptionalFamilySymbol() +{ + // Returns empty, because there should not be an option in Preferences to + // disable the built-in effects. + return {}; +} + const FileExtensions &BuiltinEffectsModule::GetFileExtensions() { static FileExtensions empty; diff --git a/src/effects/LoadEffects.h b/src/effects/LoadEffects.h index a1cf30d25..fe8b89f3f 100644 --- a/src/effects/LoadEffects.h +++ b/src/effects/LoadEffects.h @@ -38,6 +38,7 @@ public: bool Initialize() override; void Terminate() override; + EffectFamilySymbol GetOptionalFamilySymbol() override; const FileExtensions &GetFileExtensions() override; FilePath InstallPath() override { return {}; } diff --git a/src/effects/VST/VSTEffect.cpp b/src/effects/VST/VSTEffect.cpp index cce5ff4e1..23b915230 100644 --- a/src/effects/VST/VSTEffect.cpp +++ b/src/effects/VST/VSTEffect.cpp @@ -366,6 +366,15 @@ void VSTEffectsModule::Terminate() return; } +EffectFamilySymbol VSTEffectsModule::GetOptionalFamilySymbol() +{ +#if USE_VST + return VSTPLUGINTYPE; +#else + return {}; +#endif +} + const FileExtensions &VSTEffectsModule::GetFileExtensions() { static FileExtensions result{{ _T("vst") }}; diff --git a/src/effects/VST/VSTEffect.h b/src/effects/VST/VSTEffect.h index 27c088aa4..1ecf26859 100644 --- a/src/effects/VST/VSTEffect.h +++ b/src/effects/VST/VSTEffect.h @@ -417,6 +417,7 @@ public: bool Initialize() override; void Terminate() override; + EffectFamilySymbol GetOptionalFamilySymbol() override; const FileExtensions &GetFileExtensions() override; FilePath InstallPath() override; diff --git a/src/effects/audiounits/AudioUnitEffect.cpp b/src/effects/audiounits/AudioUnitEffect.cpp index 576ff9407..d7daa8d3b 100644 --- a/src/effects/audiounits/AudioUnitEffect.cpp +++ b/src/effects/audiounits/AudioUnitEffect.cpp @@ -153,6 +153,15 @@ void AudioUnitEffectsModule::Terminate() return; } +EffectFamilySymbol AudioUnitEffectsModule::GetOptionalFamilySymbol() +{ +#if USE_AUDIO_UNITS + return AUDIOUNITEFFECTS_FAMILY; +#else + return {}; +#endif +} + bool AudioUnitEffectsModule::AutoRegisterPlugins(PluginManagerInterface & pm) { // Nothing to be done here diff --git a/src/effects/audiounits/AudioUnitEffect.h b/src/effects/audiounits/AudioUnitEffect.h index 137bba299..2fc996395 100644 --- a/src/effects/audiounits/AudioUnitEffect.h +++ b/src/effects/audiounits/AudioUnitEffect.h @@ -241,6 +241,7 @@ public: bool Initialize() override; void Terminate() override; + EffectFamilySymbol GetOptionalFamilySymbol() override; const FileExtensions &GetFileExtensions() override; FilePath InstallPath() override { return {}; } diff --git a/src/effects/ladspa/LadspaEffect.cpp b/src/effects/ladspa/LadspaEffect.cpp index db9837a48..b4492fd71 100644 --- a/src/effects/ladspa/LadspaEffect.cpp +++ b/src/effects/ladspa/LadspaEffect.cpp @@ -162,6 +162,15 @@ void LadspaEffectsModule::Terminate() return; } +EffectFamilySymbol LadspaEffectsModule::GetOptionalFamilySymbol() +{ +#if USE_LADSPA + return LADSPAEFFECTS_FAMILY; +#else + return {}; +#endif +} + const FileExtensions &LadspaEffectsModule::GetFileExtensions() { static FileExtensions result{{ diff --git a/src/effects/ladspa/LadspaEffect.h b/src/effects/ladspa/LadspaEffect.h index bf328242a..6ffb6eac1 100644 --- a/src/effects/ladspa/LadspaEffect.h +++ b/src/effects/ladspa/LadspaEffect.h @@ -222,6 +222,7 @@ public: bool Initialize() override; void Terminate() override; + EffectFamilySymbol GetOptionalFamilySymbol() override; const FileExtensions &GetFileExtensions() override; FilePath InstallPath() override; diff --git a/src/effects/lv2/LoadLV2.cpp b/src/effects/lv2/LoadLV2.cpp index 6fcaef762..46f7676a9 100644 --- a/src/effects/lv2/LoadLV2.cpp +++ b/src/effects/lv2/LoadLV2.cpp @@ -207,6 +207,15 @@ void LV2EffectsModule::Terminate() return; } +EffectFamilySymbol LV2EffectsModule::GetOptionalFamilySymbol() +{ +#if USE_LV2 + return LV2EFFECTS_FAMILY; +#else + return {}; +#endif +} + const FileExtensions &LV2EffectsModule::GetFileExtensions() { static FileExtensions empty; diff --git a/src/effects/lv2/LoadLV2.h b/src/effects/lv2/LoadLV2.h index 8f07e06d4..72983a425 100644 --- a/src/effects/lv2/LoadLV2.h +++ b/src/effects/lv2/LoadLV2.h @@ -85,6 +85,7 @@ public: bool Initialize() override; void Terminate() override; + EffectFamilySymbol GetOptionalFamilySymbol() override; const FileExtensions &GetFileExtensions() override; FilePath InstallPath() override { return {}; } diff --git a/src/effects/nyquist/LoadNyquist.cpp b/src/effects/nyquist/LoadNyquist.cpp index 96909a2ab..9f94dd5f3 100644 --- a/src/effects/nyquist/LoadNyquist.cpp +++ b/src/effects/nyquist/LoadNyquist.cpp @@ -154,6 +154,15 @@ void NyquistEffectsModule::Terminate() return; } +EffectFamilySymbol NyquistEffectsModule::GetOptionalFamilySymbol() +{ +#if USE_NYQUIST + return NYQUISTEFFECTS_FAMILY; +#else + return {}; +#endif +} + const FileExtensions &NyquistEffectsModule::GetFileExtensions() { static FileExtensions result{{ _T("ny") }}; diff --git a/src/effects/nyquist/LoadNyquist.h b/src/effects/nyquist/LoadNyquist.h index f11b0ec7c..b9800db26 100644 --- a/src/effects/nyquist/LoadNyquist.h +++ b/src/effects/nyquist/LoadNyquist.h @@ -36,6 +36,8 @@ public: bool Initialize() override; void Terminate() override; + EffectFamilySymbol GetOptionalFamilySymbol() override; + const FileExtensions &GetFileExtensions() override; FilePath InstallPath() override; diff --git a/src/effects/vamp/LoadVamp.cpp b/src/effects/vamp/LoadVamp.cpp index 219168f94..2ae86f582 100644 --- a/src/effects/vamp/LoadVamp.cpp +++ b/src/effects/vamp/LoadVamp.cpp @@ -111,6 +111,15 @@ void VampEffectsModule::Terminate() return; } +EffectFamilySymbol VampEffectsModule::GetOptionalFamilySymbol() +{ +#if USE_VAMP + return VAMPEFFECTS_FAMILY; +#else + return {}; +#endif +} + const FileExtensions &VampEffectsModule::GetFileExtensions() { static FileExtensions empty; diff --git a/src/effects/vamp/LoadVamp.h b/src/effects/vamp/LoadVamp.h index 23a18cc29..9b24d53f1 100644 --- a/src/effects/vamp/LoadVamp.h +++ b/src/effects/vamp/LoadVamp.h @@ -44,6 +44,7 @@ public: bool Initialize() override; void Terminate() override; + EffectFamilySymbol GetOptionalFamilySymbol() override; const FileExtensions &GetFileExtensions() override; FilePath InstallPath() override { return {}; } From 82e3ec6818eba66e181802cbe77c6a91c720d3fd Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 8 Apr 2019 09:35:17 -0400 Subject: [PATCH 3/4] Don't duplicate registry path calculation in PluginManager.cpp --- src/PluginManager.cpp | 51 ++++++++++++++++++++++++++++++++++++++----- src/PluginManager.h | 3 +++ 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/PluginManager.cpp b/src/PluginManager.cpp index efa52cdcf..667fd6b07 100644 --- a/src/PluginManager.cpp +++ b/src/PluginManager.cpp @@ -1396,6 +1396,31 @@ const PluginID &PluginManagerInterface::AudacityCommandRegistrationCallback( return empty; } +RegistryPath PluginManager::GetPluginEnabledSetting( const PluginID &ID ) +{ + auto pPlugin = GetPlugin( ID ); + if ( pPlugin ) + return GetPluginEnabledSetting( *pPlugin ); + return {}; +} + +RegistryPath PluginManager::GetPluginEnabledSetting( + const PluginDescriptor &desc ) +{ + switch ( desc.GetPluginType() ) { + case PluginTypeEffect: { + // Retrieve optional family symbol that was recorded in + // RegisterPlugin() for the module + auto family = desc.GetEffectFamily(); + if ( family.empty() ) + return {}; + else + return wxT('/') + family + wxT("/Enable"); + } + default: + return {}; + } +} bool PluginManager::IsPluginRegistered(const PluginPath &path) { @@ -2509,9 +2534,13 @@ const PluginDescriptor *PluginManager::GetFirstPlugin(int type) if( plug.IsValid() && plug.IsEnabled() && ((plugType & type) != 0)) { bool familyEnabled = true; - if( (plugType & PluginTypeEffect) != 0) + if( (plugType & PluginTypeEffect) != 0) { // This preference may be written by EffectsPrefs - gPrefs->Read(plug.GetEffectFamily() + wxT("/Enable"), &familyEnabled, true); + auto setting = GetPluginEnabledSetting( plug ); + familyEnabled = setting.empty() + ? true + : gPrefs->Read( setting, true ); + } if (familyEnabled) return &mPluginsIter->second; } @@ -2529,9 +2558,13 @@ const PluginDescriptor *PluginManager::GetNextPlugin(int type) if( plug.IsValid() && plug.IsEnabled() && ((plugType & type) != 0)) { bool familyEnabled = true; - if( (plugType & PluginTypeEffect) != 0) + if( (plugType & PluginTypeEffect) != 0) { // This preference may be written by EffectsPrefs - gPrefs->Read(plug.GetEffectFamily() + wxT("/Enable"), &familyEnabled, true); + auto setting = GetPluginEnabledSetting( plug ); + familyEnabled = setting.empty() + ? true + : gPrefs->Read( setting, true ); + } if (familyEnabled) return &mPluginsIter->second; } @@ -2548,7 +2581,10 @@ const PluginDescriptor *PluginManager::GetFirstPluginForEffectType(EffectType ty bool familyEnabled; // This preference may be written by EffectsPrefs - gPrefs->Read(plug.GetEffectFamily() + wxT("/Enable"), &familyEnabled, true); + auto setting = GetPluginEnabledSetting( plug ); + familyEnabled = setting.empty() + ? true + : gPrefs->Read( setting, true ); if (plug.IsValid() && plug.IsEnabled() && plug.GetEffectType() == type && familyEnabled) { return &plug; @@ -2565,7 +2601,10 @@ const PluginDescriptor *PluginManager::GetNextPluginForEffectType(EffectType typ PluginDescriptor & plug = mPluginsIter->second; bool familyEnabled; // This preference may be written by EffectsPrefs - gPrefs->Read(plug.GetEffectFamily() + wxT("/Enable"), &familyEnabled, true); + auto setting = GetPluginEnabledSetting( plug ); + familyEnabled = setting.empty() + ? true + : gPrefs->Read( setting, true ); if (plug.IsValid() && plug.IsEnabled() && plug.GetEffectType() == type && familyEnabled) { return &plug; diff --git a/src/PluginManager.h b/src/PluginManager.h index 40d0f833f..00a12473d 100644 --- a/src/PluginManager.h +++ b/src/PluginManager.h @@ -173,6 +173,9 @@ class PluginManager final : public PluginManagerInterface { public: + RegistryPath GetPluginEnabledSetting( const PluginID &ID ); + RegistryPath GetPluginEnabledSetting( const PluginDescriptor &desc ); + // PluginManagerInterface implementation bool IsPluginRegistered(const PluginPath &path) override; From af3b54ba2ab48557aeb17f527daab3d8ab87d02d Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 8 Apr 2019 09:38:27 -0400 Subject: [PATCH 4/4] EffectsPrefs queries PluginManager for checkbox settings paths --- src/PluginManager.cpp | 10 ++- src/prefs/EffectsPrefs.cpp | 148 ++++++++++++++++++++++++------------- 2 files changed, 106 insertions(+), 52 deletions(-) diff --git a/src/PluginManager.cpp b/src/PluginManager.cpp index 667fd6b07..238677b2b 100644 --- a/src/PluginManager.cpp +++ b/src/PluginManager.cpp @@ -1408,15 +1408,20 @@ RegistryPath PluginManager::GetPluginEnabledSetting( const PluginDescriptor &desc ) { switch ( desc.GetPluginType() ) { - case PluginTypeEffect: { + case PluginTypeModule: { // Retrieve optional family symbol that was recorded in // RegisterPlugin() for the module auto family = desc.GetEffectFamily(); - if ( family.empty() ) + if ( family.empty() ) // as for built-in effect and command modules return {}; else return wxT('/') + family + wxT("/Enable"); } + case PluginTypeEffect: + // do NOT use GetEffectFamily() for this descriptor, but instead, + // delegate to the plugin descriptor of the provider, which may + // be different (may be empty) + return GetPluginEnabledSetting( desc.GetProviderID() ); default: return {}; } @@ -1438,6 +1443,7 @@ bool PluginManager::IsPluginRegistered(const PluginPath &path) const PluginID & PluginManager::RegisterPlugin(ModuleInterface *module) { PluginDescriptor & plug = CreatePlugin(GetID(module), module, PluginTypeModule); + plug.SetEffectFamily(module->GetOptionalFamilySymbol().Internal()); plug.SetEnabled(true); plug.SetValid(true); diff --git a/src/prefs/EffectsPrefs.cpp b/src/prefs/EffectsPrefs.cpp index 5278628eb..2a3d319c7 100644 --- a/src/prefs/EffectsPrefs.cpp +++ b/src/prefs/EffectsPrefs.cpp @@ -26,6 +26,7 @@ #include #include "../Languages.h" +#include "../PluginManager.h" #include "../Prefs.h" #include "../ShuttleGui.h" @@ -65,6 +66,95 @@ void EffectsPrefs::Populate() // ----------------------- End of main section -------------- } +namespace { + +// Rather than hard-code an exhaustive list of effect families in this file, +// pretend we don't know, but discover them instead by querying the module and +// effect managers. + +// But then we would like to have prompts with accelerator characters that are +// distinct. We collect some prompts in the following map. + +// It is not required that each module be found here, nor that each module +// mentioned here be found. +const std::map< wxString, wxString > SuggestedPrompts{ + +/* i18n-hint: Audio Unit is the name of an Apple audio software protocol */ + { wxT("AudioUnit"), XO("Audio Unit") }, + +/* i18n-hint: abbreviates "Linux Audio Developer's Simple Plugin API" + (Application programming interface) + */ + { wxT("LADSPA"), XO("&LADSPA") }, + +/* i18n-hint: abbreviates + "Linux Audio Developer's Simple Plugin API (LADSPA) version 2" */ + { wxT("LV2"), XO("LV&2") }, + +/* i18n-hint: "Nyquist" is an embedded interpreted programming language in + Audacity, named in honor of the Swedish-American Harry Nyquist (or Nyqvist). + In the translations of this and other strings, you may transliterate the + name into another alphabet. */ + { wxT("Nyquist"), XO("N&yquist") }, + +/* i18n-hint: Vamp is the proper name of a software protocol for sound analysis. + It is not an abbreviation for anything. See http://vamp-plugins.org */ + { wxT("Vamp"), XO("&Vamp") }, + +/* i18n-hint: Abbreviates Virtual Studio Technology, an audio software protocol + developed by Steinberg GmbH */ + { wxT("VST"), XO("V&ST") }, + +}; + +// Collect needed prompts and settings paths, at most once, on demand +struct Entry { + wxString prompt; // untranslated + wxString setting; +}; +static const std::vector< Entry > &GetModuleData() +{ + struct ModuleData : public std::vector< Entry > { + ModuleData() { + auto &pm = PluginManager::Get(); + for (auto plug = pm.GetFirstPlugin(PluginTypeModule); + plug; + plug = pm.GetNextPlugin(PluginTypeModule)) { + auto internal = plug->GetEffectFamily(); + if ( internal.empty() ) + continue; + + wxString prompt; + auto iter = SuggestedPrompts.find( internal ); + if ( iter == SuggestedPrompts.end() ) + // For the built-in modules this Msgid includes " Effects", + // but those strings were never shown to the user, + // and the prompts in the table above do not include it. + // If there should be new modules, it is not important for them + // to follow the " Effects" convention, but instead they can + // have shorter msgids. + prompt = plug->GetSymbol().Msgid(); + else + prompt = iter->second; + + auto setting = pm.GetPluginEnabledSetting( *plug ); + + push_back( { prompt, setting } ); + } + // Guarantee some determinate ordering + std::sort( begin(), end(), + []( const Entry &a, const Entry &b ){ + return a.setting < b.setting; + } + ); + } + }; + static ModuleData theData; + return theData; +} + +} + void EffectsPrefs::PopulateOrExchange(ShuttleGui & S) { S.SetBorder(2); @@ -72,56 +162,14 @@ void EffectsPrefs::PopulateOrExchange(ShuttleGui & S) S.StartStatic(_("Enable Effects")); { - -#if USE_AUDIO_UNITS -/* i18n-hint: Audio Unit is the name of an Apple audio software protocol */ - S.TieCheckBox(_("Audio Unit"), - wxT("/AudioUnit/Enable"), - true); -#endif - - // JKC: LADSPA, LV2, Nyquist, VST, VAMP should not be translated. -#if USE_LADSPA -/* i18n-hint: abbreviates "Linux Audio Developer's Simple Plugin API" - (Application programming interface) - */ - S.TieCheckBox(_("&LADSPA"), - wxT("/LADSPA/Enable"), - true); -#endif - -#if USE_LV2 -/* i18n-hint: abbreviates - "Linux Audio Developer's Simple Plugin API (LADSPA) version 2" */ - S.TieCheckBox(_("LV&2"), - wxT("/LV2/Enable"), - true); -#endif -#if USE_NYQUIST -/* i18n-hint: "Nyquist" is an embedded interpreted programming language in - Audacity, named in honor of the Swedish-American Harry Nyquist (or Nyqvist). - In the translations of this and other strings, you may transliterate the - name into another alphabet. */ - S.TieCheckBox(_("N&yquist"), - wxT("/Nyquist/Enable"), - true); -#endif - -#if USE_VAMP -/* i18n-hint: Vamp is the proper name of a software protocol for sound analysis. - It is not an abbreviation for anything. See http://vamp-plugins.org */ - S.TieCheckBox(_("&Vamp"), - wxT("/Vamp/Enable"), - true); -#endif - -#if USE_VST -/* i18n-hint: Abbreviates Virtual Studio Technology, an audio software protocol - developed by Steinberg GmbH */ - S.TieCheckBox(_("V&ST"), - wxT("/VST/Enable"), - true); -#endif + for ( const auto &entry : GetModuleData() ) + { + S.TieCheckBox( + GetCustomTranslation( entry.prompt ), + entry.setting, + true + ); + } } S.EndStatic();