Audacity  2.2.2
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 #include "../../Audacity.h"
12 
13 #if defined(USE_VAMP)
14 
15 #include <wx/filename.h>
16 
17 #include "../EffectManager.h"
18 #include "VampEffect.h"
19 #include "LoadVamp.h"
20 
21 #include <iostream>
22 #include <map>
23 
24 using namespace Vamp;
25 using namespace Vamp::HostExt;
26 using namespace Vamp::HostExt;
27 
28 // ============================================================================
29 // Module registration entry point
30 //
31 // This is the symbol that Audacity looks for when the module is built as a
32 // dynamic library.
33 //
34 // When the module is builtin to Audacity, we use the same function, but it is
35 // declared static so as not to clash with other builtin modules.
36 // ============================================================================
37 DECLARE_MODULE_ENTRY(AudacityModule)
38 {
39  // Create and register the importer
40  // Trust the module manager not to leak this
41  return safenew VampEffectsModule(moduleManager, path);
42 }
43 
44 // ============================================================================
45 // Register this as a builtin module
46 // ============================================================================
47 DECLARE_BUILTIN_MODULE(VampsEffectBuiltin);
48 
50 //
51 // VampEffectsModule
52 //
54 
55 VampEffectsModule::VampEffectsModule(ModuleManagerInterface *moduleManager,
56  const wxString *path)
57 {
58  mModMan = moduleManager;
59  if (path)
60  {
61  mPath = *path;
62  }
63 }
64 
65 VampEffectsModule::~VampEffectsModule()
66 {
67 }
68 
69 // ============================================================================
70 // IdentInterface implementation
71 // ============================================================================
72 
73 wxString VampEffectsModule::GetPath()
74 {
75  return mPath;
76 }
77 
78 IdentInterfaceSymbol VampEffectsModule::GetSymbol()
79 {
80  return XO("Vamp Effects");
81 }
82 
83 IdentInterfaceSymbol VampEffectsModule::GetVendor()
84 {
85  return XO("The Audacity Team");
86 }
87 
88 wxString VampEffectsModule::GetVersion()
89 {
90  // This "may" be different if this were to be maintained as a separate DLL
91  return VAMPEFFECTS_VERSION;
92 }
93 
94 wxString VampEffectsModule::GetDescription()
95 {
96  return _("Provides Vamp Effects support to Audacity");
97 }
98 
99 // ============================================================================
100 // ModuleInterface implementation
101 // ============================================================================
102 
103 bool VampEffectsModule::Initialize()
104 {
105  // Nothing to do here
106  return true;
107 }
108 
109 void VampEffectsModule::Terminate()
110 {
111  // Nothing to do here
112  return;
113 }
114 
115 bool VampEffectsModule::AutoRegisterPlugins(PluginManagerInterface & WXUNUSED(pm))
116 {
117  return false;
118 }
119 
120 wxArrayString VampEffectsModule::FindPluginPaths(PluginManagerInterface & WXUNUSED(pm))
121 {
122  wxArrayString names;
123 
124  PluginLoader *loader = PluginLoader::getInstance();
125 
126  PluginLoader::PluginKeyList keys = loader->listPlugins();
127 
128  for (PluginLoader::PluginKeyList::iterator i = keys.begin(); i != keys.end(); ++i)
129  {
130  std::unique_ptr<Plugin> vp{ PluginLoader::getInstance()->loadPlugin(*i, 48000) }; // rate doesn't matter here
131  if (!vp)
132  {
133  continue;
134  }
135 
136  // We limit the listed plugin outputs to those whose results can
137  // readily be displayed in an Audacity label track.
138  //
139  // - Any output whose features have no values (time instants only),
140  // with or without duration, is fine
141  //
142  // - Any output whose features have more than one value, or an
143  // unknown or variable number of values, is right out
144  //
145  // - Any output whose features have exactly one value, with
146  // variable sample rate or with duration, should be OK --
147  // this implies a sparse feature, of which the time and/or
148  // duration are significant aspects worth displaying
149  //
150  // - An output whose features have exactly one value, with
151  // fixed sample rate and no duration, cannot be usefully
152  // displayed -- the value is the only significant piece of
153  // data there and we have no good value plot
154 
155  Plugin::OutputList outputs = vp->getOutputDescriptors();
156 
157  int output = 0;
158 
159  for (Plugin::OutputList::iterator j = outputs.begin(); j != outputs.end(); ++j)
160  {
161  if (j->sampleType == Plugin::OutputDescriptor::FixedSampleRate ||
162  j->sampleType == Plugin::OutputDescriptor::OneSamplePerStep ||
163  !j->hasFixedBinCount ||
164  j->binCount > 1)
165  {
166  // All of these qualities disqualify (see notes above)
167 
168  ++output;
169  continue;
170  }
171 
172  wxString name = wxString::FromUTF8(vp->getName().c_str());
173 
174  if (outputs.size() > 1)
175  {
176  // This is not the plugin's only output.
177  // Use "plugin name: output name" as the effect name,
178  // unless the output name is the same as the plugin name
179  wxString outputName = wxString::FromUTF8(j->name.c_str());
180  if (outputName != name)
181  {
182  name = wxString::Format(wxT("%s: %s"),
183  name, outputName);
184  }
185  }
186 
187  wxString path = wxString::FromUTF8(i->c_str()) + wxT("/") + name;
188  names.Add(path);
189 
190  ++output;
191  }
192  }
193 
194  return names;
195 }
196 
197 unsigned VampEffectsModule::DiscoverPluginsAtPath(
198  const wxString & path, wxString &errMsg,
199  const RegistrationCallback &callback)
200 {
201  errMsg.clear();
202  int output;
203  bool hasParameters;
204 
205  auto vp = FindPlugin(path, output, hasParameters);
206  if (vp)
207  {
208  VampEffect effect(std::move(vp), path, output, hasParameters);
209  if (callback)
210  callback( this, &effect );
211 
212  return 1;
213  }
214 
215  errMsg = _("Could not load the library");
216  return 0;
217 }
218 
219 bool VampEffectsModule::IsPluginValid(const wxString & path, bool bFast)
220 {
221  int output;
222  bool hasParameters;
223  if( bFast )
224  return true;
225 
226  auto vp = FindPlugin(path, output, hasParameters);
227  return bool(vp);
228 }
229 
230 IdentInterface *VampEffectsModule::CreateInstance(const wxString & path)
231 {
232  // Acquires a resource for the application.
233  int output;
234  bool hasParameters;
235 
236  auto vp = FindPlugin(path, output, hasParameters);
237  if (vp)
238  {
239  // Safety of this depends on complementary calls to DeleteInstance on the module manager side.
240  return safenew VampEffect(std::move(vp), path, output, hasParameters);
241  }
242 
243  return NULL;
244 }
245 
246 void VampEffectsModule::DeleteInstance(IdentInterface *instance)
247 {
248  std::unique_ptr < VampEffect > {
249  dynamic_cast<VampEffect *>(instance)
250  };
251 }
252 
253 // VampEffectsModule implementation
254 
255 std::unique_ptr<Vamp::Plugin> VampEffectsModule::FindPlugin(const wxString & path,
256  int & output,
257  bool & hasParameters)
258 {
259  PluginLoader::PluginKey key = path.BeforeLast(wxT('/')).ToUTF8().data();
260 
261  std::unique_ptr<Plugin> vp{ PluginLoader::getInstance()->loadPlugin(key, 48000) }; // rate doesn't matter here
262  if (!vp)
263  {
264  return nullptr;
265  }
266 
267  // We limit the listed plugin outputs to those whose results can
268  // readily be displayed in an Audacity label track.
269  //
270  // - Any output whose features have no values (time instants only),
271  // with or without duration, is fine
272  //
273  // - Any output whose features have more than one value, or an
274  // unknown or variable number of values, is right out
275  //
276  // - Any output whose features have exactly one value, with
277  // variable sample rate or with duration, should be OK --
278  // this implies a sparse feature, of which the time and/or
279  // duration are significant aspects worth displaying
280  //
281  // - An output whose features have exactly one value, with
282  // fixed sample rate and no duration, cannot be usefully
283  // displayed -- the value is the only significant piece of
284  // data there and we have no good value plot
285 
286  Plugin::OutputList outputs = vp->getOutputDescriptors();
287 
288  output = 0;
289 
290  hasParameters = !vp->getParameterDescriptors().empty();
291 
292  for (Plugin::OutputList::iterator j = outputs.begin(); j != outputs.end(); ++j)
293  {
294  if (j->sampleType == Plugin::OutputDescriptor::FixedSampleRate ||
295  j->sampleType == Plugin::OutputDescriptor::OneSamplePerStep ||
296  !j->hasFixedBinCount ||
297  j->binCount > 1)
298  {
299  // All of these qualities disqualify (see notes above)
300 
301  ++output;
302  continue;
303  }
304 
305  wxString name = wxString::FromUTF8(vp->getName().c_str());
306 
307  if (outputs.size() > 1)
308  {
309  // This is not the plugin's only output.
310  // Use "plugin name: output name" as the effect name,
311  // unless the output name is the same as the plugin name
312  wxString outputName = wxString::FromUTF8(j->name.c_str());
313  if (outputName != name)
314  {
315  name = wxString::Format(wxT("%s: %s"),
316  name, outputName);
317  }
318  }
319 
320  if (wxString::FromUTF8(key.c_str()) + wxT("/") + name == path)
321  {
322  return vp;
323  }
324 
325  ++output;
326  }
327 
328  return {};
329 }
330 
331 #endif
static wxArrayString names()
Definition: Tags.cpp:697
#define DECLARE_BUILTIN_MODULE(name)
#define XO(s)
Definition: Internat.h:33
#define safenew
Definition: Audacity.h:230
#define DECLARE_MODULE_ENTRY(name)
IdentInterfaceSymbol pairs a persistent string identifier used internally with an optional...
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
const wxChar * name
Definition: Distortion.cpp:94
IdentInterface provides name / vendor / version functions to identify plugins. It is what makes a cla...