Audacity  2.2.2
LoadLV2.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  LV2Effect.h
6 
7  Audacity(R) is copyright (c) 1999-2008 Audacity Team.
8  License: GPL v2. See License.txt.
9 
10 *******************************************************************//*******************************************************************/
16 
17 #include "../../Audacity.h"
18 
19 #if defined(USE_LV2)
20 
21 #include <cstdio>
22 #include <cstdlib>
23 #include <cstring>
24 #include <iostream>
25 
26 #include <wx/dynlib.h>
27 #include <wx/filename.h>
28 #include <wx/hashmap.h>
29 #include <wx/list.h>
30 #include <wx/log.h>
31 #include <wx/string.h>
32 
33 #include "../../Internat.h"
34 #include "../EffectManager.h"
35 
36 #include "LV2Effect.h"
37 #include "lv2/lv2plug.in/ns/ext/event/event.h"
38 #include "lv2/lv2plug.in/ns/ext/instance-access/instance-access.h"
39 #include "lv2/lv2plug.in/ns/ext/port-groups/port-groups.h"
40 #include "lv2/lv2plug.in/ns/ext/port-props/port-props.h"
41 #include "lv2/lv2plug.in/ns/ext/uri-map/uri-map.h"
42 #include "lv2/lv2plug.in/ns/ext/presets/presets.h"
43 
44 #include "LoadLV2.h"
45 
46 #include <unordered_map>
47 
48 // ============================================================================
49 // Module registration entry point
50 //
51 // This is the symbol that Audacity looks for when the module is built as a
52 // dynamic library.
53 //
54 // When the module is builtin to Audacity, we use the same function, but it is
55 // declared static so as not to clash with other builtin modules.
56 // ============================================================================
57 DECLARE_MODULE_ENTRY(AudacityModule)
58 {
59  // Create and register the importer
60  // Trust the module manager not to leak this
61  return safenew LV2EffectsModule(moduleManager, path);
62 }
63 
64 // ============================================================================
65 // Register this as a builtin module
66 // ============================================================================
67 DECLARE_BUILTIN_MODULE(LV2sEffectBuiltin);
68 
70 //
71 // LV2EffectsModule
72 //
74 using UriHash = std::unordered_map<wxString, LilvNode*>;
75 
76 LilvWorld *gWorld = NULL;
77 
79  const wxString *path)
80 {
81  mModMan = moduleManager;
82  if (path)
83  {
84  mPath = *path;
85  }
86 }
87 
89 {
90 }
91 
92 // ============================================================================
93 // IdentInterface implementation
94 // ============================================================================
95 
97 {
98  return mPath;
99 }
100 
102 {
103  return XO("LV2 Effects");
104 }
105 
107 {
108  return XO("The Audacity Team");
109 }
110 
112 {
113  // This "may" be different if this were to be maintained as a separate DLL
114  return LV2EFFECTS_VERSION;
115 }
116 
118 {
119  return _("Provides LV2 Effects support to Audacity");
120 }
121 
122 // ============================================================================
123 // ModuleInterface implementation
124 // ============================================================================
125 
127 {
128  // Try to initialise Lilv, or return.
129  gWorld = lilv_world_new();
130  if (!gWorld)
131  {
132  return false;
133  }
134 
135  // Create LilvNodes for each of the URIs we need
136  #undef URI
137  #define URI(n, u) LV2Effect::n = lilv_new_uri(gWorld, u);
138  URILIST
139 
140  wxString newVar;
141 
142 #if defined(__WXMAC__)
143 #define LV2PATH wxT("/Library/Audio/Plug-Ins/LV2")
144 
145  wxFileName libdir;
146 // libdir.AssignDir(wxT(LIBDIR));
147  libdir.AppendDir(wxT("lv2"));
148 
149  newVar += wxT(":$HOME/.lv2");
150 
151  // Look in ~/Library/Audio/Plug-Ins/lv2 and /Library/Audio/Plug-Ins/lv2
152  newVar += wxT(":$HOME") LV2PATH;
153  newVar += wxT(":") LV2PATH;
154 
155  newVar += wxT(":/usr/local/lib/lv2");
156  newVar += wxT(":/usr/lib/lv2");
157  newVar += wxT(":") + libdir.GetPath();
158 
159 #elif defined(__WXMSW__)
160 
161  newVar += wxT(";%APPDATA%\\LV2");
162  newVar += wxT(";%COMMONPROGRAMFILES%\\LV2");
163  newVar += wxT(";%COMMONPROGRAMFILES(x86)%\\LV2");
164 
165 #else
166 
167  wxFileName libdir;
168  libdir.AssignDir(wxT(LIBDIR));
169  libdir.AppendDir(wxT("lv2"));
170 
171  newVar += wxT(":$HOME/.lv2");
172  newVar += wxT(":/usr/local/lib/lv2");
173  newVar += wxT(":/usr/lib/lv2");
174  newVar += wxT(":/usr/local/lib64/lv2");
175  newVar += wxT(":/usr/lib64/lv2");
176  newVar += wxT(":") + libdir.GetPath();
177 
178 #endif
179 
180  // Start with the LV2_PATH environment variable (if any)
181  wxString pathVar;
182  wxGetEnv(wxT("LV2_PATH"), &pathVar);
183 
184  if (pathVar.IsEmpty())
185  {
186  pathVar = newVar.Mid(1);
187  }
188  else
189  {
190  pathVar += newVar;
191  }
192 
193  wxSetEnv(wxT("LV2_PATH"), pathVar);
194 
195  lilv_world_load_all(gWorld);
196 
197  return true;
198 }
199 
201 {
202  // Free the LilvNodes for each of the URIs we need
203  #undef URI
204  #define URI(n, u) lilv_node_free(LV2Effect::n);
205  URILIST
206 
207  lilv_world_free(gWorld);
208  gWorld = NULL;
209 
210  return;
211 }
212 
214 {
215  return false;
216 }
217 
218 wxArrayString LV2EffectsModule::FindPluginPaths(PluginManagerInterface & WXUNUSED(pm))
219 {
220  // Retrieve data about all LV2 plugins
221  const LilvPlugins *plugs = lilv_world_get_all_plugins(gWorld);
222 
223  // Iterate over all plugins retrieve their URI
224  wxArrayString plugins;
225  LILV_FOREACH(plugins, i, plugs)
226  {
227  const LilvPlugin *plug = lilv_plugins_get(plugs, i);
228 
229  // Bypass Instrument (MIDI) plugins for now
230  const LilvPluginClass *cls = lilv_plugin_get_class(plug);
231  if (lilv_node_equals(lilv_plugin_class_get_uri(cls), LV2Effect::gInstrument))
232  {
233  continue;
234  }
235 
236  plugins.Add(LilvString(lilv_plugin_get_uri(plug)));
237  }
238 
239  return plugins;
240 }
241 
243  const wxString & path, wxString &errMsg,
244  const RegistrationCallback &callback)
245 {
246  errMsg.clear();
247  const LilvPlugin *plug = GetPlugin(path);
248  if (plug)
249  {
250  LV2Effect effect(plug);
251  if (effect.SetHost(NULL))
252  {
253  if (callback)
254  callback( this, &effect );
255  return 1;
256  }
257  }
258 
259  errMsg = _("Could not load the library");
260  return 0;
261 }
262 
263 bool LV2EffectsModule::IsPluginValid(const wxString & path, bool bFast)
264 {
265  if( bFast )
266  return true;
267  return GetPlugin(path) != NULL;
268 }
269 
270 IdentInterface *LV2EffectsModule::CreateInstance(const wxString & path)
271 {
272  // Acquires a resource for the application.
273  const LilvPlugin *plug = GetPlugin(path);
274  if (!plug)
275  {
276  return NULL;
277  }
278 
279  // Safety of this depends on complementary calls to DeleteInstance on the module manager side.
280  return safenew LV2Effect(plug);
281 }
282 
284 {
285  std::unique_ptr < LV2Effect > {
286  dynamic_cast<LV2Effect *>(instance)
287  };
288 }
289 
290 // ============================================================================
291 // LV2EffectsModule implementation
292 // ============================================================================
293 
294 const LilvPlugin *LV2EffectsModule::GetPlugin(const wxString & path)
295 {
296  LilvNode *uri = lilv_new_uri(gWorld, path.ToUTF8());
297  if (!uri)
298  {
299  return NULL;
300  }
301 
302  const LilvPlugin *plug = lilv_plugins_get_by_uri(lilv_world_get_all_plugins(gWorld), uri);
303 
304  lilv_node_free(uri);
305 
306  return plug;
307 }
308 
309 #endif
IdentInterfaceSymbol GetSymbol() override
#define DECLARE_BUILTIN_MODULE(name)
wxArrayString FindPluginPaths(PluginManagerInterface &pm) override
#define URILIST
Definition: LoadLV2.h:38
wxString GetDescription() override
bool Initialize() override
LV2EffectsModule(ModuleManagerInterface *moduleManager, const wxString *path)
#define XO(s)
Definition: Internat.h:33
void Terminate() override
#define safenew
Definition: Audacity.h:230
IdentInterfaceSymbol GetVendor() override
const LilvPlugin * GetPlugin(const wxString &path)
virtual ~LV2EffectsModule()
unsigned DiscoverPluginsAtPath(const wxString &path, wxString &errMsg, const RegistrationCallback &callback) override
wxString GetPath() override
#define DECLARE_MODULE_ENTRY(name)
wxString GetVersion() override
IdentInterface * CreateInstance(const wxString &path) override
IdentInterfaceSymbol pairs a persistent string identifier used internally with an optional...
ModuleManagerInterface * mModMan
Definition: LoadLV2.h:111
LilvWorld * gWorld
_("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
bool IsPluginValid(const wxString &path, bool bFast) override
void DeleteInstance(IdentInterface *instance) override
IdentInterface provides name / vendor / version functions to identify plugins. It is what makes a cla...
wxString mPath
Definition: LoadLV2.h:112
bool AutoRegisterPlugins(PluginManagerInterface &pm) override