Audacity 3.2.0
LoadVamp.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 LoadVamp.cpp
6
7 Chris Cannam
8
9**********************************************************************/
10
11
12
13#if defined(USE_VAMP)
14#include "LoadVamp.h"
15#include "ModuleManager.h"
16
17#include <wx/filename.h>
18
19#include "VampEffect.h"
20#include "wxArrayStringEx.h"
21
22#include <iostream>
23#include <map>
24
25using namespace Vamp;
26using namespace Vamp::HostExt;
27using namespace Vamp::HostExt;
28
29// ============================================================================
30// Module registration entry point
31//
32// This is the symbol that Audacity looks for when the module is built as a
33// dynamic library.
34//
35// When the module is builtin to Audacity, we use the same function, but it is
36// declared static so as not to clash with other builtin modules.
37// ============================================================================
39{
40 // Create and register the importer
41 // Trust the module manager not to leak this
42 return std::make_unique<VampEffectsModule>();
43}
44
45// ============================================================================
46// Register this as a builtin module
47// ============================================================================
48DECLARE_BUILTIN_PROVIDER(VampsEffectBuiltin);
49
51//
52// VampEffectsModule
53//
55
57{
58}
59
61{
62}
63
64// ============================================================================
65// ComponentInterface implementation
66// ============================================================================
67
69{
70 return {};
71}
72
74{
75 return XO("Vamp Effects");
76}
77
79{
80 return XO("The Audacity Team");
81}
82
84{
85 // This "may" be different if this were to be maintained as a separate DLL
87}
88
90{
91 return XO("Provides Vamp Effects support to Audacity");
92}
93
94// ============================================================================
95// PluginProvider implementation
96// ============================================================================
97
99{
100 // Nothing to do here
101 return true;
102}
103
105{
106 // Nothing to do here
107 return;
108}
109
111{
112#if USE_VAMP
113 return VAMPEFFECTS_FAMILY;
114#else
115 return {};
116#endif
117}
118
120{
121 static FileExtensions empty;
122 return empty;
123}
124
126{
127}
128
130{
132
133 PluginLoader *loader = PluginLoader::getInstance();
134
135 PluginLoader::PluginKeyList keys = loader->listPlugins();
136
137 for (PluginLoader::PluginKeyList::iterator i = keys.begin(); i != keys.end(); ++i)
138 {
139 std::unique_ptr<Plugin> vp{ PluginLoader::getInstance()->loadPlugin(*i, 48000) }; // rate doesn't matter here
140 if (!vp)
141 {
142 continue;
143 }
144
145 // We limit the listed plugin outputs to those whose results can
146 // readily be displayed in an Audacity label track.
147 //
148 // - Any output whose features have no values (time instants only),
149 // with or without duration, is fine
150 //
151 // - Any output whose features have more than one value, or an
152 // unknown or variable number of values, is right out
153 //
154 // - Any output whose features have exactly one value, with
155 // variable sample rate or with duration, should be OK --
156 // this implies a sparse feature, of which the time and/or
157 // duration are significant aspects worth displaying
158 //
159 // - An output whose features have exactly one value, with
160 // fixed sample rate and no duration, cannot be usefully
161 // displayed -- the value is the only significant piece of
162 // data there and we have no good value plot
163
164 Plugin::OutputList outputs = vp->getOutputDescriptors();
165
166 int output = 0;
167
168 for (Plugin::OutputList::iterator j = outputs.begin(); j != outputs.end(); ++j)
169 {
170 if (j->sampleType == Plugin::OutputDescriptor::FixedSampleRate ||
171 j->sampleType == Plugin::OutputDescriptor::OneSamplePerStep ||
172 !j->hasFixedBinCount ||
173 j->binCount > 1)
174 {
175 // All of these qualities disqualify (see notes above)
176
177 ++output;
178 continue;
179 }
180
181 wxString name = wxString::FromUTF8(vp->getName().c_str());
182
183 if (outputs.size() > 1)
184 {
185 // This is not the plugin's only output.
186 // Use "plugin name: output name" as the effect name,
187 // unless the output name is the same as the plugin name
188 wxString outputName = wxString::FromUTF8(j->name.c_str());
189 if (outputName != name)
190 {
191 name = wxString::Format(wxT("%s: %s"),
192 name, outputName);
193 }
194 }
195
196 wxString path = wxString::FromUTF8(i->c_str()) + wxT("/") + name;
197 names.push_back(path);
198
199 ++output;
200 }
201 }
202
203 return names;
204}
205
207 const PluginPath & path, TranslatableString &errMsg,
208 const RegistrationCallback &callback)
209{
210 errMsg = {};
211 int output;
212 bool hasParameters;
213
214 auto vp = FindPlugin(path, output, hasParameters);
215 if (vp)
216 {
217 VampEffect effect(std::move(vp), path, output, hasParameters);
218 if (callback)
219 callback( this, &effect );
220
221 return 1;
222 }
223
224 errMsg = XO("Could not load the library");
225 return 0;
226}
227
228std::unique_ptr<ComponentInterface>
230{
231 // Acquires a resource for the application.
232 int output;
233 bool hasParameters;
234
235 if (auto vp = FindPlugin(path, output, hasParameters))
236 return std::make_unique<VampEffect>(std::move(vp), path, output, hasParameters);
237 return nullptr;
238}
239
241{
242 PluginLoader::PluginKey key = path.BeforeFirst(wxT('/')).ToUTF8().data();
243 const auto libraryPathUTF8 = PluginLoader::getInstance()->getLibraryPathForPlugin(key);
244 if(!libraryPathUTF8.empty())
245 return wxFileName::FileExists(wxString::FromUTF8(libraryPathUTF8));
246 return wxFileName::FileExists(path);
247}
248
249// VampEffectsModule implementation
250
251std::unique_ptr<Vamp::Plugin> VampEffectsModule::FindPlugin(const PluginPath & path,
252 int & output,
253 bool & hasParameters)
254{
255 PluginLoader::PluginKey key = path.BeforeFirst(wxT('/')).ToUTF8().data();
256
257 std::unique_ptr<Plugin> vp{ PluginLoader::getInstance()->loadPlugin(key, 48000) }; // rate doesn't matter here
258 if (!vp)
259 {
260 return nullptr;
261 }
262
263 // We limit the listed plugin outputs to those whose results can
264 // readily be displayed in an Audacity label track.
265 //
266 // - Any output whose features have no values (time instants only),
267 // with or without duration, is fine
268 //
269 // - Any output whose features have more than one value, or an
270 // unknown or variable number of values, is right out
271 //
272 // - Any output whose features have exactly one value, with
273 // variable sample rate or with duration, should be OK --
274 // this implies a sparse feature, of which the time and/or
275 // duration are significant aspects worth displaying
276 //
277 // - An output whose features have exactly one value, with
278 // fixed sample rate and no duration, cannot be usefully
279 // displayed -- the value is the only significant piece of
280 // data there and we have no good value plot
281
282 Plugin::OutputList outputs = vp->getOutputDescriptors();
283
284 output = 0;
285
286 hasParameters = !vp->getParameterDescriptors().empty();
287
288 for (Plugin::OutputList::iterator j = outputs.begin(); j != outputs.end(); ++j)
289 {
290 if (j->sampleType == Plugin::OutputDescriptor::FixedSampleRate ||
291 j->sampleType == Plugin::OutputDescriptor::OneSamplePerStep ||
292 !j->hasFixedBinCount ||
293 j->binCount > 1)
294 {
295 // All of these qualities disqualify (see notes above)
296
297 ++output;
298 continue;
299 }
300
301 wxString name = wxString::FromUTF8(vp->getName().c_str());
302
303 if (outputs.size() > 1)
304 {
305 // This is not the plugin's only output.
306 // Use "plugin name: output name" as the effect name,
307 // unless the output name is the same as the plugin name
308 wxString outputName = wxString::FromUTF8(j->name.c_str());
309 if (outputName != name)
310 {
311 name = wxString::Format(wxT("%s: %s"),
312 name, outputName);
313 }
314 }
315
316 if (wxString::FromUTF8(key.c_str()) + wxT("/") + name == path)
317 {
318 return vp;
319 }
320
321 ++output;
322 }
323
324 return {};
325}
326
327#endif
wxT("CloseDown"))
const TranslatableString name
Definition: Distortion.cpp:76
XO("Cut/Copy/Paste")
std::vector< PluginPath > PluginPaths
Definition: Identifier.h:215
wxString PluginPath
type alias for identifying a Plugin supplied by a module, each module defining its own interpretation...
Definition: Identifier.h:214
DECLARE_PROVIDER_ENTRY(AudacityModule)
Definition: LoadVamp.cpp:38
DECLARE_BUILTIN_PROVIDER(VampsEffectBuiltin)
static const AudacityProject::AttachedObjects::RegisteredFactory key
static TranslatableStrings names
Definition: TagsEditor.cpp:153
#define VAMPEFFECTS_FAMILY
Definition: VampEffect.h:36
#define VAMPEFFECTS_VERSION
Definition: VampEffect.h:33
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
std::function< const PluginID &(PluginProvider *, ComponentInterface *) > RegistrationCallback
Further expand a path reported by FindModulePaths.
Holds a msgid for the translation catalog; may also bind format arguments.
bool Initialize() override
Called immediately after creation. Let provider initialize.
Definition: LoadVamp.cpp:98
VendorSymbol GetVendor() const override
Definition: LoadVamp.cpp:78
virtual ~VampEffectsModule()
Definition: LoadVamp.cpp:60
const FileExtensions & GetFileExtensions() override
File types associated with this protocol.
Definition: LoadVamp.cpp:119
ComponentInterfaceSymbol GetSymbol() const override
Definition: LoadVamp.cpp:73
unsigned DiscoverPluginsAtPath(const PluginPath &path, TranslatableString &errMsg, const RegistrationCallback &callback) override
Definition: LoadVamp.cpp:206
EffectFamilySymbol GetOptionalFamilySymbol() override
A symbol identifying the family of plug-ins provided by this.
Definition: LoadVamp.cpp:110
PluginPaths FindModulePaths(PluginManagerInterface &pm) override
Definition: LoadVamp.cpp:129
PluginPath GetPath() const override
Definition: LoadVamp.cpp:68
std::unique_ptr< Vamp::Plugin > FindPlugin(const PluginPath &wpath, int &output, bool &hasParameters)
Definition: LoadVamp.cpp:251
void Terminate() override
Called just prior to deletion to allow releasing any resources.
Definition: LoadVamp.cpp:104
bool CheckPluginExist(const PluginPath &path) const override
Performs plugin/module existence check, still plugin may fail to load. Implementation should avoid lo...
Definition: LoadVamp.cpp:240
TranslatableString GetDescription() const override
Definition: LoadVamp.cpp:89
void AutoRegisterPlugins(PluginManagerInterface &pm) override
Called so that a provider of a static set of plug-ins can register them.
Definition: LoadVamp.cpp:125
std::unique_ptr< ComponentInterface > LoadPlugin(const PluginPath &path) override
Load the plug-in at a path reported by DiscoverPluginsAtPath.
Definition: LoadVamp.cpp:229
wxString GetVersion() const override
Definition: LoadVamp.cpp:83
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.