1 /**********************************************************************
2 
3   Audacity: A Digital Audio Editor
4 
5   LoadEffects.cpp
6 
7   Dominic Mazzoni
8 
9 **************************************************************************//**
10 \class BuiltinEffectsModule
11 \brief Internal module to auto register all built in effects.
12 *****************************************************************************/
13 
14 
15 #include "LoadEffects.h"
16 
17 #include "Prefs.h"
18 
19 #include "Effect.h"
20 #include "ModuleManager.h"
21 
22 static bool sInitialized = false;
23 
24 struct BuiltinEffectsModule::Entry {
25    ComponentInterfaceSymbol name;
26    BuiltinEffectsModule::Factory factory;
27    bool excluded;
28 
29    using Entries = std::vector< Entry >;
RegistryBuiltinEffectsModule::Entry30    static Entries &Registry()
31    {
32       static Entries result;
33       return result;
34    }
35 };
36 
DoRegistration(const ComponentInterfaceSymbol & name,const Factory & factory,bool excluded)37 void BuiltinEffectsModule::DoRegistration(
38    const ComponentInterfaceSymbol &name, const Factory &factory, bool excluded )
39 {
40    wxASSERT( !sInitialized );
41    Entry::Registry().emplace_back( Entry{ name, factory, excluded } );
42 }
43 
44 // ============================================================================
45 // Module registration entry point
46 //
47 // This is the symbol that Audacity looks for when the module is built as a
48 // dynamic library.
49 //
50 // When the module is builtin to Audacity, we use the same function, but it is
51 // declared static so as not to clash with other builtin modules.
52 // ============================================================================
DECLARE_MODULE_ENTRY(AudacityModule)53 DECLARE_MODULE_ENTRY(AudacityModule)
54 {
55    // Create and register the importer
56    // Trust the module manager not to leak this
57    return safenew BuiltinEffectsModule();
58 }
59 
60 // ============================================================================
61 // Register this as a builtin module
62 // ============================================================================
63 DECLARE_BUILTIN_MODULE(BuiltinsEffectBuiltin);
64 
65 ///////////////////////////////////////////////////////////////////////////////
66 //
67 // BuiltinEffectsModule
68 //
69 ///////////////////////////////////////////////////////////////////////////////
70 
BuiltinEffectsModule()71 BuiltinEffectsModule::BuiltinEffectsModule()
72 {
73 }
74 
~BuiltinEffectsModule()75 BuiltinEffectsModule::~BuiltinEffectsModule()
76 {
77 }
78 
79 // ============================================================================
80 // ComponentInterface implementation
81 // ============================================================================
82 
GetPath()83 PluginPath BuiltinEffectsModule::GetPath()
84 {
85    return {};
86 }
87 
GetSymbol()88 ComponentInterfaceSymbol BuiltinEffectsModule::GetSymbol()
89 {
90    return XO("Builtin Effects");
91 }
92 
GetVendor()93 VendorSymbol BuiltinEffectsModule::GetVendor()
94 {
95    return XO("The Audacity Team");
96 }
97 
GetVersion()98 wxString BuiltinEffectsModule::GetVersion()
99 {
100    // This "may" be different if this were to be maintained as a separate DLL
101    return AUDACITY_VERSION_STRING;
102 }
103 
GetDescription()104 TranslatableString BuiltinEffectsModule::GetDescription()
105 {
106    return XO("Provides builtin effects to Audacity");
107 }
108 
109 // ============================================================================
110 // ModuleInterface implementation
111 // ============================================================================
112 
Initialize()113 bool BuiltinEffectsModule::Initialize()
114 {
115    for ( const auto &entry : Entry::Registry() ) {
116       auto path = wxString(BUILTIN_EFFECT_PREFIX) + entry.name.Internal();
117       mEffects[ path ] = &entry;
118    }
119    sInitialized = true;
120    return true;
121 }
122 
Terminate()123 void BuiltinEffectsModule::Terminate()
124 {
125    // Nothing to do here
126    return;
127 }
128 
GetOptionalFamilySymbol()129 EffectFamilySymbol BuiltinEffectsModule::GetOptionalFamilySymbol()
130 {
131    // Returns empty, because there should not be an option in Preferences to
132    // disable the built-in effects.
133    return {};
134 }
135 
GetFileExtensions()136 const FileExtensions &BuiltinEffectsModule::GetFileExtensions()
137 {
138    static FileExtensions empty;
139    return empty;
140 }
141 
AutoRegisterPlugins(PluginManagerInterface & pm)142 bool BuiltinEffectsModule::AutoRegisterPlugins(PluginManagerInterface & pm)
143 {
144    TranslatableString ignoredErrMsg;
145    for (const auto &pair : mEffects)
146    {
147       const auto &path = pair.first;
148       if (!pm.IsPluginRegistered(path, &pair.second->name.Msgid()))
149       {
150          if ( pair.second->excluded )
151             continue;
152          // No checking of error ?
153          DiscoverPluginsAtPath(path, ignoredErrMsg,
154             PluginManagerInterface::DefaultRegistrationCallback);
155       }
156    }
157 
158    // We still want to be called during the normal registration process
159    return false;
160 }
161 
FindPluginPaths(PluginManagerInterface & WXUNUSED (pm))162 PluginPaths BuiltinEffectsModule::FindPluginPaths(PluginManagerInterface & WXUNUSED(pm))
163 {
164    PluginPaths names;
165    for ( const auto &pair : mEffects )
166       names.push_back( pair.first );
167    return names;
168 }
169 
DiscoverPluginsAtPath(const PluginPath & path,TranslatableString & errMsg,const RegistrationCallback & callback)170 unsigned BuiltinEffectsModule::DiscoverPluginsAtPath(
171    const PluginPath & path, TranslatableString &errMsg,
172    const RegistrationCallback &callback)
173 {
174    errMsg = {};
175    auto effect = Instantiate(path);
176    if (effect)
177    {
178       if (callback)
179          callback(this, effect.get());
180       return 1;
181    }
182 
183    errMsg = XO("Unknown built-in effect name");
184    return 0;
185 }
186 
IsPluginValid(const PluginPath & path,bool bFast)187 bool BuiltinEffectsModule::IsPluginValid(const PluginPath & path, bool bFast)
188 {
189    // bFast is unused as checking in the list is fast.
190    static_cast<void>(bFast);
191    return mEffects.find( path ) != mEffects.end();
192 }
193 
194 std::unique_ptr<ComponentInterface>
CreateInstance(const PluginPath & path)195 BuiltinEffectsModule::CreateInstance(const PluginPath & path)
196 {
197    // Acquires a resource for the application.
198    return Instantiate(path);
199 }
200 
201 // ============================================================================
202 // BuiltinEffectsModule implementation
203 // ============================================================================
204 
Instantiate(const PluginPath & path)205 std::unique_ptr<Effect> BuiltinEffectsModule::Instantiate(const PluginPath & path)
206 {
207    wxASSERT(path.StartsWith(BUILTIN_EFFECT_PREFIX));
208    auto iter = mEffects.find( path );
209    if ( iter != mEffects.end() )
210       return iter->second->factory();
211 
212    wxASSERT( false );
213    return nullptr;
214 }
215