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 #ifndef __AUDACITY_OLD_STD__
47 #include <unordered_map>
48 #endif
49 
50 // ============================================================================
51 // Module registration entry point
52 //
53 // This is the symbol that Audacity looks for when the module is built as a
54 // dynamic library.
55 //
56 // When the module is builtin to Audacity, we use the same function, but it is
57 // declared static so as not to clash with other builtin modules.
58 // ============================================================================
59 DECLARE_MODULE_ENTRY(AudacityModule)
60 {
61  // Create and register the importer
62  // Trust the module manager not to leak this
63  return safenew LV2EffectsModule(moduleManager, path);
64 }
65 
66 // ============================================================================
67 // Register this as a builtin module
68 // ============================================================================
69 DECLARE_BUILTIN_MODULE(LV2sEffectBuiltin);
70 
72 //
73 // LV2EffectsModule
74 //
76 using UriHash = std::unordered_map<wxString, LilvNode*>;
77 
78 LilvWorld *gWorld = NULL;
79 
80 LV2EffectsModule::LV2EffectsModule(ModuleManagerInterface *moduleManager,
81  const wxString *path)
82 {
83  mModMan = moduleManager;
84  if (path)
85  {
86  mPath = *path;
87  }
88 }
89 
91 {
92 }
93 
94 // ============================================================================
95 // IdentInterface implementation
96 // ============================================================================
97 
99 {
100  return mPath;
101 }
102 
104 {
105  return XO("LV2 Effects");
106 }
107 
108 wxString LV2EffectsModule::GetName()
109 {
110  return GetSymbol();
111 }
112 
114 {
115  return XO("The Audacity Team");
116 }
117 
119 {
120  // This "may" be different if this were to be maintained as a separate DLL
121  return LV2EFFECTS_VERSION;
122 }
123 
125 {
126  return _("Provides LV2 Effects support to Audacity");
127 }
128 
129 // ============================================================================
130 // ModuleInterface implementation
131 // ============================================================================
132 
134 {
135  // Try to initialise Lilv, or return.
136  gWorld = lilv_world_new();
137  if (!gWorld)
138  {
139  return false;
140  }
141 
142  // Create LilvNodes for each of the URIs we need
143  #undef URI
144  #define URI(n, u) LV2Effect::n = lilv_new_uri(gWorld, u);
145  URILIST
146 
147  wxString newVar;
148 
149 #if defined(__WXMAC__)
150 #define LV2PATH wxT("/Library/Audio/Plug-Ins/LV2")
151 
152  wxFileName libdir;
153 // libdir.AssignDir(wxT(LIBDIR));
154  libdir.AppendDir(wxT("lv2"));
155 
156  newVar += wxT(":$HOME/.lv2");
157 
158  // Look in ~/Library/Audio/Plug-Ins/lv2 and /Library/Audio/Plug-Ins/lv2
159  newVar += wxT(":$HOME") LV2PATH;
160  newVar += wxT(":") LV2PATH;
161 
162  newVar += wxT(":/usr/local/lib/lv2");
163  newVar += wxT(":/usr/lib/lv2");
164  newVar += wxT(":") + libdir.GetPath();
165 
166 #elif defined(__WXMSW__)
167 
168  newVar += wxT(";%APPDATA%\\LV2");
169  newVar += wxT(";%COMMONPROGRAMFILES%\\LV2");
170  newVar += wxT(";%COMMONPROGRAMFILES(x86)%\\LV2");
171 
172 #else
173 
174  wxFileName libdir;
175  libdir.AssignDir(wxT(LIBDIR));
176  libdir.AppendDir(wxT("lv2"));
177 
178  newVar += wxT(":$HOME/.lv2");
179  newVar += wxT(":/usr/local/lib/lv2");
180  newVar += wxT(":/usr/lib/lv2");
181  newVar += wxT(":/usr/local/lib64/lv2");
182  newVar += wxT(":/usr/lib64/lv2");
183  newVar += wxT(":") + libdir.GetPath();
184 
185 #endif
186 
187  // Start with the LV2_PATH environment variable (if any)
188  wxString pathVar;
189  wxGetEnv(wxT("LV2_PATH"), &pathVar);
190 
191  if (pathVar.IsEmpty())
192  {
193  pathVar = newVar.Mid(1);
194  }
195  else
196  {
197  pathVar += newVar;
198  }
199 
200  wxSetEnv(wxT("LV2_PATH"), pathVar);
201 
202  lilv_world_load_all(gWorld);
203 
204  return true;
205 }
206 
208 {
209  // Free the LilvNodes for each of the URIs we need
210  #undef URI
211  #define URI(n, u) lilv_node_free(LV2Effect::n);
212  URILIST
213 
214  lilv_world_free(gWorld);
215  gWorld = NULL;
216 
217  return;
218 }
219 
220 bool LV2EffectsModule::AutoRegisterPlugins(PluginManagerInterface & WXUNUSED(pm))
221 {
222  return false;
223 }
224 
225 wxArrayString LV2EffectsModule::FindPluginPaths(PluginManagerInterface & WXUNUSED(pm))
226 {
227  // Retrieve data about all LV2 plugins
228  const LilvPlugins *plugs = lilv_world_get_all_plugins(gWorld);
229 
230  // Iterate over all plugins retrieve their URI
231  wxArrayString plugins;
232  LILV_FOREACH(plugins, i, plugs)
233  {
234  const LilvPlugin *plug = lilv_plugins_get(plugs, i);
235 
236  // Bypass Instrument (MIDI) plugins for now
237  const LilvPluginClass *cls = lilv_plugin_get_class(plug);
238  if (lilv_node_equals(lilv_plugin_class_get_uri(cls), LV2Effect::gInstrument))
239  {
240  continue;
241  }
242 
243  plugins.Add(LilvString(lilv_plugin_get_uri(plug)));
244  }
245 
246  return plugins;
247 }
248 
250  const wxString & path, wxString &errMsg,
251  const RegistrationCallback &callback)
252 {
253  errMsg.clear();
254  const LilvPlugin *plug = GetPlugin(path);
255  if (plug)
256  {
257  LV2Effect effect(plug);
258  if (effect.SetHost(NULL))
259  {
260  if (callback)
261  callback( this, &effect );
262  return 1;
263  }
264  }
265 
266  errMsg = _("Could not load the library");
267  return 0;
268 }
269 
270 bool LV2EffectsModule::IsPluginValid(const wxString & path, bool bFast)
271 {
272  if( bFast )
273  return true;
274  return GetPlugin(path) != NULL;
275 }
276 
277 IdentInterface *LV2EffectsModule::CreateInstance(const wxString & path)
278 {
279  // Acquires a resource for the application.
280  const LilvPlugin *plug = GetPlugin(path);
281  if (!plug)
282  {
283  return NULL;
284  }
285 
286  // Safety of this depends on complementary calls to DeleteInstance on the module manager side.
287  return safenew LV2Effect(plug);
288 }
289 
290 void LV2EffectsModule::DeleteInstance(IdentInterface *instance)
291 {
292  std::unique_ptr < LV2Effect > {
293  dynamic_cast<LV2Effect *>(instance)
294  };
295 }
296 
297 // ============================================================================
298 // LV2EffectsModule implementation
299 // ============================================================================
300 
301 const LilvPlugin *LV2EffectsModule::GetPlugin(const wxString & path)
302 {
303  LilvNode *uri = lilv_new_uri(gWorld, path.ToUTF8());
304  if (!uri)
305  {
306  return NULL;
307  }
308 
309  const LilvPlugin *plug = lilv_plugins_get_by_uri(lilv_world_get_all_plugins(gWorld), uri);
310 
311  lilv_node_free(uri);
312 
313  return plug;
314 }
315 
316 #endif
wxString GetVendor() override
wxArrayString FindPluginPaths(PluginManagerInterface &pm) override
wxString GetSymbol() override
#define URILIST
Definition: LoadLV2.h:38
wxString GetDescription() override
DECLARE_BUILTIN_MODULE(LadspaBuiltin)
bool Initialize() override
LV2EffectsModule(ModuleManagerInterface *moduleManager, const wxString *path)
#define XO(s)
Definition: Internat.h:30
void Terminate() override
#define safenew
Definition: Audacity.h:223
const LilvPlugin * GetPlugin(const wxString &path)
virtual ~LV2EffectsModule()
unsigned DiscoverPluginsAtPath(const wxString &path, wxString &errMsg, const RegistrationCallback &callback) override
wxString GetPath() override
wxString GetVersion() override
wxString GetName() override
IdentInterface * CreateInstance(const wxString &path) override
DECLARE_MODULE_ENTRY(AudacityModule)
ModuleManagerInterface * mModMan
Definition: LoadLV2.h:112
LilvWorld * gWorld
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
bool IsPluginValid(const wxString &path, bool bFast) override
void DeleteInstance(IdentInterface *instance) override
wxString mPath
Definition: LoadLV2.h:113
bool AutoRegisterPlugins(PluginManagerInterface &pm) override