Audacity 3.2.0
EffectManager.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 EffectManager.cpp
6
7 Audacity(R) is copyright (c) 1999-2008 Audacity Team.
8 License: GPL v2 or later. See License.txt.
9
10******************************************************************//*******************************************************************/
20
21#include "EffectManager.h"
22#include "ConfigInterface.h"
23#include "Effect.h"
24#include "PluginManager.h"
25#include <algorithm>
26
27
28/*******************************************************************************
29Creates a singleton and returns reference
30
31 (Thread-safe...no active threading during construction or after destruction)
32*******************************************************************************/
34{
35 static EffectManager em;
36 return em;
37}
38
39// Here solely for the purpose of Nyquist Workbench until
40// a better solution is devised.
42 std::unique_ptr<EffectPlugin> uEffect)
43{
44 auto pEffect = uEffect.get();
45 const PluginID & ID =
47 mEffects[ID] = { pEffect, {} };
48 return ID;
49}
50
51// Here solely for the purpose of Nyquist Workbench until
52// a better solution is devised.
54{
55 PluginID id = ID;
57 mEffects.erase(id);
58}
59
61{
62 if(auto description = PluginManager::Get().GetPlugin(ID))
63 return TranslatableString { description->GetEffectFamily(), {} };
64
65 auto effect = GetEffect(ID);
66 if (effect)
67 return effect->GetDefinition().GetFamily().Msgid();
68 return {};
69}
70
72{
73 if(auto description = PluginManager::Get().GetPlugin(ID))
74 return TranslatableString { description->GetVendor(), {} };
75
76 auto effect = GetEffect(ID);
77 if (effect)
78 return effect->GetDefinition().GetVendor().Msgid();
79 return {};
80}
81
82
84{
85 if(auto effect = GetEffect(ID))
86 return effect->GetDefinition().IsHiddenFromMenus();
87 return false;
88}
89
91{
93}
94
96{
97 return mSkipStateFlag;
98}
99
101{
104}
105
107{
110}
111
113{
114 RegistryPaths presets;
116 UserPresetsGroup({}), presets);
117 std::sort( presets.begin(), presets.end() );
118 return presets;
119}
120
122{
123 auto effect = GetEffect(ID);
124
125 if (!effect)
126 {
127 return false;
128 }
129
130 return GetUserPresets(*effect).size() > 0 ||
131 effect->GetDefinition().GetFactoryPresets().size() > 0 ||
132 HasCurrentSettings(*effect) ||
133 HasFactoryDefaults(*effect);
134}
135
136// This function is used only in the macro programming user interface
138 const PluginID& ID, const wxString& params, EffectPresetDialog dialog)
139{
140 auto effect = GetEffect(ID);
141
142 if (!effect)
143 {
144 return wxEmptyString;
145 }
146
148
149 wxString preset;
150 if (eap.HasEntry(wxT("Use Preset")))
151 {
152 preset = eap.Read(wxT("Use Preset"));
153 }
154
155 if (const auto answer = dialog(*effect, preset))
156 preset = *answer;
157 else
158 preset = wxEmptyString;
159
160 if (preset.empty())
161 {
162 return preset;
163 }
164
165 // This cleans a config "file" backed by a string in memory.
166 eap.DeleteAll();
167
168 eap.Write(wxT("Use Preset"), preset);
170
171 return preset;
172}
173
174// This function is used only in the macro programming user interface
176{
177 auto effect = GetEffect(ID);
178
179 if (!effect)
180 {
181 return wxEmptyString;
182 }
183
184 wxString preset;
185 if (HasCurrentSettings(*effect))
186 {
188 }
189 else if (HasFactoryDefaults(*effect))
190 {
192 }
193
194 if (!preset.empty())
195 {
197
198 eap.Write(wxT("Use Preset"), preset);
200 }
201
202 return preset;
203}
204
206{
207 return DoGetEffect(ID).effect;
208}
209
211{
212 return GetEffectAndDefaultSettings(ID).second;
213}
214
215std::pair<EffectPlugin*, EffectSettings*>
217{
218 auto &results = DoGetEffect(ID);
219 if (results.effect)
220 return {results.effect, &results.settings};
221 else
222 return {nullptr, nullptr};
223}
224
225namespace {
226// Before: settings are as defaulted by `manager.MakeSettings()`
227// Do as needed (once, persistently, when the plug-in is first used): store
228// those default values into the config under "FactoryDefaults" preset
229// After: settings are loaded for the "CurrentSettings" preset
232 // Config key remembering whether we already stored FactoryDefaults
233 constexpr auto InitializedKey = L"Initialized";
234 if (bool haveDefaults{};
236 InitializedKey, haveDefaults, false),
237 !haveDefaults
238 ) {
239 manager.SaveUserPreset(FactoryDefaultsGroup(), settings);
240 // Also initialize the "current" settings --
241 if (bool haveCurrent{};
243 InitializedKey, haveCurrent, false),
244 !haveCurrent
245 ) {
246 manager.SaveUserPreset(CurrentSettingsGroup(), settings);
247 }
249 InitializedKey, true);
250 }
251 // ignore failure
252 (void) manager.LoadUserPreset(CurrentSettingsGroup(), settings);
253}
254
255std::pair<ComponentInterface *, EffectSettings>
257{
258 if (auto result = dynamic_cast<EffectSettingsManager*>(
259 PluginManager::Get().Load(ID))) {
260 auto settings = result->MakeSettings();
261 InitializePreset(*result, settings);
262 return { result, std::move(settings) };
263 }
264 return { nullptr, {} };
265}
266}
267
269{
270 static EffectAndDefaultSettings empty;
271
272 // Must have a "valid" ID
273 if (ID.empty())
274 return empty;
275
276 if (auto iter = mEffects.find(ID); iter != mEffects.end())
277 return iter->second;
278 else {
279 // This will instantiate the effect client if it hasn't already been done
280 auto [component, settings] = LoadComponent(ID);
281 if (!component)
282 return empty;
283
284 if (auto effect = dynamic_cast<EffectPlugin*>(component))
285 return (mEffects[ID] = { effect, std::move(settings) });
286 else
287 return empty;
288 }
289}
290
293{
294 return Get().GetEffect(ID);
295}
wxT("CloseDown"))
wxString PluginID
EffectDistortionSettings params
RegistryPath UserPresetsGroup(const RegistryPath &name)
Compute part of a registry path, given a name which may be empty.
const RegistryPath & FactoryDefaultsGroup()
Component of a configuration key path, for default state of MakeSettings()
const RegistryPath & CurrentSettingsGroup()
Component of a configuration key path, for last-used destructive settings.
bool HasCurrentSettings(EffectPlugin &host)
bool HasFactoryDefaults(EffectPlugin &host)
RegistryPaths GetUserPresets(EffectPlugin &host)
std::vector< RegistryPath > RegistryPaths
Definition: Identifier.h:219
@ PluginTypeEffect
static const AttachedProjectObjects::RegisteredFactory manager
ReverbSettings preset
Definition: ReverbBase.cpp:25
static Settings & settings()
Definition: TrackInfo.cpp:51
static std::once_flag flag
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the SettingsVis...
virtual bool HasEntry(const wxString &strName) const override
bool GetParameters(wxString &parms)
EffectManager is the class that handles effects and effect categories.
Definition: EffectManager.h:52
bool HasPresets(const PluginID &ID)
std::function< std::optional< wxString >(EffectPlugin &, const wxString &preset)> EffectPresetDialog
Definition: EffectManager.h:86
bool GetSkipStateFlag()
void SetSkipStateFlag(bool flag)
wxString GetPreset(const PluginID &ID, const wxString &params, EffectPresetDialog)
EffectPlugin * GetEffect(const PluginID &ID)
EffectMap mEffects
static const EffectInstanceFactory * GetInstanceFactory(const PluginID &ID)
std::pair< EffectPlugin *, EffectSettings * > GetEffectAndDefaultSettings(const PluginID &ID)
static EffectManager & Get()
EffectSettings * GetDefaultSettings(const PluginID &ID)
TranslatableString GetVendorName(const PluginID &ID)
wxString GetDefaultPreset(const PluginID &ID)
const PluginID & RegisterEffect(std::unique_ptr< EffectPlugin > uEffect)
Here solely for the purpose of Nyquist Workbench until a better solution is devised.
TranslatableString GetEffectFamilyName(const PluginID &ID)
void UnregisterEffect(const PluginID &ID)
Used only by Nyquist Workbench module.
EffectAndDefaultSettings & DoGetEffect(const PluginID &ID)
bool IsHidden(const PluginID &ID)
Factory of instances of an effect.
Definition: EffectPlugin.h:36
virtual const EffectSettingsManager & GetDefinition() const =0
static const wxString kCurrentSettingsIdent
Definition: EffectPlugin.h:42
static const wxString kFactoryDefaultsIdent
Definition: EffectPlugin.h:43
EffectSettingsManager is an EffectDefinitionInterface that adds a factory function for EffectSettings...
void UnregisterPlugin(const PluginID &ID)
void RegisterPlugin(PluginDescriptor &&desc)
static PluginManager & Get()
Holds a msgid for the translation catalog; may also bind format arguments.
bool GetConfigSubgroups(const EffectDefinitionInterface &ident, PluginSettings::ConfigurationType type, const RegistryPath &group, RegistryPaths &subgroups)
bool SetConfig(const EffectDefinitionInterface &ident, ConfigurationType type, const RegistryPath &group, const RegistryPath &key, const Value &value)
bool HasConfigGroup(const EffectDefinitionInterface &ident, PluginSettings::ConfigurationType type, const RegistryPath &group)
bool GetConfig(const EffectDefinitionInterface &ident, ConfigurationType type, const RegistryPath &group, const RegistryPath &key, Value &var, const Value &defval)
THEME_RESOURCES_API void Load()
std::pair< ComponentInterface *, EffectSettings > LoadComponent(const PluginID &ID)
void InitializePreset(EffectSettingsManager &manager, EffectSettings &settings)
const PluginDescriptor * GetPlugin(const PluginID &ID)
Externalized state of a plug-in.