mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-01 08:09:41 +02:00
EffectsPrefs discovers all registered effect families...
... instead of keeping an exhaustive list of them with hardcoded preference paths. And some duplication of string literals for those paths is eliminated. One small piece of improvements of preference path handling.
This commit is contained in:
commit
5459a7bf27
@ -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
|
||||
|
@ -439,7 +439,6 @@ private:
|
||||
void OnDisable(wxCommandEvent & evt);
|
||||
|
||||
private:
|
||||
ModuleInterface *mMod;
|
||||
EffectType mType;
|
||||
int mFilter;
|
||||
|
||||
@ -1397,6 +1396,36 @@ 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 PluginTypeModule: {
|
||||
// Retrieve optional family symbol that was recorded in
|
||||
// RegisterPlugin() for the module
|
||||
auto family = desc.GetEffectFamily();
|
||||
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 {};
|
||||
}
|
||||
}
|
||||
|
||||
bool PluginManager::IsPluginRegistered(const PluginPath &path)
|
||||
{
|
||||
@ -1414,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);
|
||||
@ -2510,9 +2540,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;
|
||||
}
|
||||
@ -2530,9 +2564,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;
|
||||
}
|
||||
@ -2549,7 +2587,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;
|
||||
@ -2566,7 +2607,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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -39,6 +39,7 @@ public:
|
||||
|
||||
bool Initialize() override;
|
||||
void Terminate() override;
|
||||
EffectFamilySymbol GetOptionalFamilySymbol() override;
|
||||
|
||||
const FileExtensions &GetFileExtensions() override;
|
||||
FilePath InstallPath() override { return {}; }
|
||||
|
@ -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;
|
||||
|
@ -38,6 +38,7 @@ public:
|
||||
|
||||
bool Initialize() override;
|
||||
void Terminate() override;
|
||||
EffectFamilySymbol GetOptionalFamilySymbol() override;
|
||||
|
||||
const FileExtensions &GetFileExtensions() override;
|
||||
FilePath InstallPath() override { return {}; }
|
||||
|
@ -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") }};
|
||||
|
@ -417,6 +417,7 @@ public:
|
||||
|
||||
bool Initialize() override;
|
||||
void Terminate() override;
|
||||
EffectFamilySymbol GetOptionalFamilySymbol() override;
|
||||
|
||||
const FileExtensions &GetFileExtensions() override;
|
||||
FilePath InstallPath() override;
|
||||
|
@ -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
|
||||
|
@ -241,6 +241,7 @@ public:
|
||||
|
||||
bool Initialize() override;
|
||||
void Terminate() override;
|
||||
EffectFamilySymbol GetOptionalFamilySymbol() override;
|
||||
|
||||
const FileExtensions &GetFileExtensions() override;
|
||||
FilePath InstallPath() override { return {}; }
|
||||
|
@ -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{{
|
||||
|
@ -222,6 +222,7 @@ public:
|
||||
|
||||
bool Initialize() override;
|
||||
void Terminate() override;
|
||||
EffectFamilySymbol GetOptionalFamilySymbol() override;
|
||||
|
||||
const FileExtensions &GetFileExtensions() override;
|
||||
FilePath InstallPath() override;
|
||||
|
@ -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;
|
||||
|
@ -85,6 +85,7 @@ public:
|
||||
|
||||
bool Initialize() override;
|
||||
void Terminate() override;
|
||||
EffectFamilySymbol GetOptionalFamilySymbol() override;
|
||||
|
||||
const FileExtensions &GetFileExtensions() override;
|
||||
FilePath InstallPath() override { return {}; }
|
||||
|
@ -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") }};
|
||||
|
@ -36,6 +36,8 @@ public:
|
||||
|
||||
bool Initialize() override;
|
||||
void Terminate() override;
|
||||
EffectFamilySymbol GetOptionalFamilySymbol() override;
|
||||
|
||||
|
||||
const FileExtensions &GetFileExtensions() override;
|
||||
FilePath InstallPath() override;
|
||||
|
@ -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;
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
|
||||
bool Initialize() override;
|
||||
void Terminate() override;
|
||||
EffectFamilySymbol GetOptionalFamilySymbol() override;
|
||||
|
||||
const FileExtensions &GetFileExtensions() override;
|
||||
FilePath InstallPath() override { return {}; }
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <wx/defs.h>
|
||||
|
||||
#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();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user