Audacity  3.0.3
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 
18 
19 #if defined(USE_LV2)
20 
21 #if defined(__GNUC__)
22 #pragma GCC diagnostic ignored "-Wparentheses"
23 #endif
24 
25 #include "LoadLV2.h"
26 #include "../../ModuleManager.h"
27 
28 #include <cstdio>
29 #include <cstdlib>
30 #include <cstring>
31 #include <iostream>
32 
33 #include <wx/dynlib.h>
34 #include <wx/filename.h>
35 #include <wx/log.h>
36 #include <wx/string.h>
37 
38 #include "Internat.h"
39 #include "wxArrayStringEx.h"
40 
41 #include "LV2Effect.h"
42 #include "lv2/event/event.h"
43 #include "lv2/instance-access/instance-access.h"
44 #include "lv2/port-groups/port-groups.h"
45 #include "lv2/port-props/port-props.h"
46 #include "lv2/uri-map/uri-map.h"
47 #include "lv2/presets/presets.h"
48 
49 #include <unordered_map>
50 
51 // ============================================================================
52 // Module registration entry point
53 //
54 // This is the symbol that Audacity looks for when the module is built as a
55 // dynamic library.
56 //
57 // When the module is builtin to Audacity, we use the same function, but it is
58 // declared static so as not to clash with other builtin modules.
59 // ============================================================================
60 DECLARE_MODULE_ENTRY(AudacityModule)
61 {
62  // Create and register the importer
63  // Trust the module manager not to leak this
64  return safenew LV2EffectsModule();
65 }
66 
67 // ============================================================================
68 // Register this as a builtin module
69 // ============================================================================
70 DECLARE_BUILTIN_MODULE(LV2sEffectBuiltin);
71 
73 //
74 // LV2EffectsModule
75 //
77 using UriHash = std::unordered_map<wxString, LilvNode*>;
78 
79 LilvWorld *gWorld = NULL;
80 
82 {
83 }
84 
86 {
87 }
88 
89 // ============================================================================
90 // ComponentInterface implementation
91 // ============================================================================
92 
94 {
95  return {};
96 }
97 
99 {
100  return XO("LV2 Effects");
101 }
102 
104 {
105  return XO("The Audacity Team");
106 }
107 
109 {
110  // This "may" be different if this were to be maintained as a separate DLL
111  return LV2EFFECTS_VERSION;
112 }
113 
115 {
116  return XO("Provides LV2 Effects support to Audacity");
117 }
118 
119 // ============================================================================
120 // ModuleInterface implementation
121 // ============================================================================
122 
124 {
125  // Try to initialise Lilv, or return.
126  gWorld = lilv_world_new();
127  if (!gWorld)
128  {
129  return false;
130  }
131 
132  // Create LilvNodes for each of the URIs we need
133  #undef NODE
134  #define NODE(n, u) LV2Effect::node_##n = lilv_new_uri(gWorld, u);
135  NODELIST
136 
137  // Generate URIDs
138  #undef URID
139  #define URID(n, u) LV2Effect::urid_##n = LV2Effect::Lookup_URI(LV2Effect::gURIDMap, u);
140  URIDLIST
141 
142  wxString newVar;
143 
144 #if defined(__WXMAC__)
145 #define LV2PATH wxT("/Library/Audio/Plug-Ins/LV2")
146 
147  wxFileName libdir;
148 // libdir.AssignDir(wxT(LIBDIR));
149  libdir.AppendDir(wxT("lv2"));
150 
151  newVar += wxT(":$HOME/.lv2");
152 
153  // Look in ~/Library/Audio/Plug-Ins/lv2 and /Library/Audio/Plug-Ins/lv2
154  newVar += wxT(":$HOME") LV2PATH;
155  newVar += wxT(":") LV2PATH;
156 
157  newVar += wxT(":/usr/local/lib/lv2");
158  newVar += wxT(":/usr/lib/lv2");
159  newVar += wxT(":") + libdir.GetPath();
160 
161 #elif defined(__WXMSW__)
162 
163  newVar += wxT(";%APPDATA%\\LV2");
164  newVar += wxT(";%COMMONPROGRAMFILES%\\LV2");
165  newVar += wxT(";%COMMONPROGRAMFILES(x86)%\\LV2");
166 
167 #else
168 
169  wxFileName libdir;
170  libdir.AssignDir(wxT(LIBDIR));
171  libdir.AppendDir(wxT("lv2"));
172 
173  newVar += wxT(":$HOME/.lv2");
174 #if defined(__LP64__)
175  newVar += wxT(":/usr/local/lib64/lv2");
176  newVar += wxT(":/usr/lib64/lv2");
177 #endif
178  newVar += wxT(":/usr/local/lib/lv2");
179  newVar += wxT(":/usr/lib/lv2");
180  newVar += wxT(":") + libdir.GetPath();
181 
182  // Tell SUIL where to find his GUI support modules
183  wxSetEnv(wxT("SUIL_MODULE_DIR"), wxT(PKGLIBDIR));
184 #endif
185 
186  // Start with the LV2_PATH environment variable (if any)
187  wxString pathVar;
188  wxGetEnv(wxT("LV2_PATH"), &pathVar);
189 
190  if (pathVar.empty())
191  {
192  pathVar = newVar.Mid(1);
193  }
194  else
195  {
196  pathVar += newVar;
197  }
198 
199  wxSetEnv(wxT("LV2_PATH"), pathVar);
200  lilv_world_load_all(gWorld);
201 
202  return true;
203 }
204 
206 {
207  // Free the LilvNodes for each of the URIs we need
208  #undef NODE
209  #define NODE(n, u) \
210  lilv_node_free(LV2Effect::node_##n);
211  NODELIST
212 
213  lilv_world_free(gWorld);
214  gWorld = NULL;
215 
216  return;
217 }
218 
220 {
221 #if USE_LV2
222  return LV2EFFECTS_FAMILY;
223 #else
224  return {};
225 #endif
226 }
227 
229 {
230  static FileExtensions empty;
231  return empty;
232 }
233 
235 {
236  return false;
237 }
238 
240 {
241  // Retrieve data about all LV2 plugins
242  const LilvPlugins *plugs = lilv_world_get_all_plugins(gWorld);
243 
244  // Iterate over all plugins retrieve their URI
245  PluginPaths plugins;
246  LILV_FOREACH(plugins, i, plugs)
247  {
248  const LilvPlugin *plug = lilv_plugins_get(plugs, i);
249  const LilvNode *cls = lilv_plugin_class_get_uri(lilv_plugin_get_class(plug));
250  const LilvNode *name = lilv_plugin_get_name(plug);
251 
252  // Bypass unsupported plugin types
253  if (lilv_node_equals(cls, LV2Effect::node_InstrumentPlugin) ||
254  lilv_node_equals(cls, LV2Effect::node_MIDIPlugin) ||
255  lilv_node_equals(cls, LV2Effect::node_MathConstants) ||
256  lilv_node_equals(cls, LV2Effect::node_MathFunctions))
257  {
258  wxLogInfo(wxT("LV2 plugin '%s' has unsupported type '%s'"), lilv_node_as_string(lilv_plugin_get_uri(plug)), lilv_node_as_string(cls));
259  printf("LV2 plugin '%s' has unsupported type '%s'\n", lilv_node_as_string(lilv_plugin_get_uri(plug)), lilv_node_as_string(cls));
260  continue;
261  }
262 
263  // If it doesn't have a name or has no ports, then it's not valid
264  if (!name || !lilv_plugin_get_port_by_index(plug, 0))
265  {
266  wxLogInfo(wxT("LV2 plugin '%s' is invalid"), lilv_node_as_string(lilv_plugin_get_uri(plug)));
267  printf("LV2 plugin '%s' is invalid\n", lilv_node_as_string(lilv_plugin_get_uri(plug)));
268  continue;
269  }
270 
271  plugins.push_back(LilvString(lilv_plugin_get_uri(plug)));
272  }
273 
274  return plugins;
275 }
276 
278  const PluginPath & path, TranslatableString &errMsg,
279  const RegistrationCallback &callback)
280 {
281  errMsg = {};
282  const LilvPlugin *plug = GetPlugin(path);
283  if (plug)
284  {
285  LV2Effect effect(plug);
286  if (effect.SetHost(NULL))
287  {
288  if (callback)
289  callback( this, &effect );
290  return 1;
291  }
292  }
293 
294  errMsg = XO("Could not load the library");
295  return 0;
296 }
297 
298 bool LV2EffectsModule::IsPluginValid(const PluginPath & path, bool bFast)
299 {
300  if( bFast )
301  return true;
302  return GetPlugin(path) != NULL;
303 }
304 
305 std::unique_ptr<ComponentInterface>
307 {
308  // Acquires a resource for the application.
309  if (auto plug = GetPlugin(path))
310  return std::make_unique<LV2Effect>(plug);
311  return nullptr;
312 }
313 
314 // ============================================================================
315 // LV2EffectsModule implementation
316 // ============================================================================
317 
318 const LilvPlugin *LV2EffectsModule::GetPlugin(const PluginPath & path)
319 {
320  LilvNode *uri = lilv_new_uri(gWorld, path.ToUTF8());
321  if (!uri)
322  {
323  return NULL;
324  }
325 
326  const LilvPlugin *plug = lilv_plugins_get_by_uri(lilv_world_get_all_plugins(gWorld), uri);
327 
328  lilv_node_free(uri);
329 
330  return plug;
331 }
332 
333 #endif
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
DECLARE_MODULE_ENTRY
DECLARE_MODULE_ENTRY(AudacityModule)
Definition: LoadLV2.cpp:60
LV2EFFECTS_FAMILY
#define LV2EFFECTS_FAMILY
Definition: LV2Effect.h:62
LV2EffectsModule::CreateInstance
std::unique_ptr< ComponentInterface > CreateInstance(const PluginPath &path) override
Definition: LoadLV2.cpp:306
LV2Effect::SetHost
bool SetHost(EffectHostInterface *host) override
Definition: LV2Effect.cpp:518
UriHash
std::unordered_map< wxString, LilvNode * > UriHash
Definition: LoadLV2.cpp:77
URIDLIST
#define URIDLIST
Definition: LoadLV2.h:111
LV2EffectsModule::~LV2EffectsModule
virtual ~LV2EffectsModule()
Definition: LoadLV2.cpp:85
LV2EffectsModule::GetDescription
TranslatableString GetDescription() override
Definition: LoadLV2.cpp:114
LV2EffectsModule::AutoRegisterPlugins
bool AutoRegisterPlugins(PluginManagerInterface &pm) override
Definition: LoadLV2.cpp:234
LV2EffectsModule::Initialize
bool Initialize() override
Definition: LoadLV2.cpp:123
PluginPath
wxString PluginPath
type alias for identifying a Plugin supplied by a module, each module defining its own interpretation...
Definition: Identifier.h:214
LV2EffectsModule::GetVendor
VendorSymbol GetVendor() override
Definition: LoadLV2.cpp:103
gWorld
LilvWorld * gWorld
Definition: LoadLV2.cpp:79
LV2Effect.h
XO
#define XO(s)
Definition: Internat.h:31
LV2EffectsModule::GetVersion
wxString GetVersion() override
Definition: LoadLV2.cpp:108
wxArrayStringEx
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
Definition: wxArrayStringEx.h:18
ComponentInterfaceSymbol
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Definition: ComponentInterfaceSymbol.h:27
LV2EffectsModule::LV2EffectsModule
LV2EffectsModule()
Definition: LoadLV2.cpp:81
PluginManagerInterface
Definition: PluginInterface.h:55
LV2EffectsModule::DiscoverPluginsAtPath
unsigned DiscoverPluginsAtPath(const PluginPath &path, TranslatableString &errMsg, const RegistrationCallback &callback) override
Definition: LoadLV2.cpp:277
LV2EffectsModule::GetFileExtensions
const FileExtensions & GetFileExtensions() override
Definition: LoadLV2.cpp:228
NODELIST
#define NODELIST
Definition: LoadLV2.h:67
name
const TranslatableString name
Definition: Distortion.cpp:98
LV2EffectsModule::Terminate
void Terminate() override
Definition: LoadLV2.cpp:205
Internat.h
wxArrayStringEx.h
DECLARE_BUILTIN_MODULE
DECLARE_BUILTIN_MODULE(LV2sEffectBuiltin)
PluginPaths
std::vector< PluginPath > PluginPaths
Definition: Identifier.h:215
LV2Effect
Definition: LV2Effect.h:258
LV2EffectsModule::GetSymbol
ComponentInterfaceSymbol GetSymbol() override
Definition: LoadLV2.cpp:98
LV2EffectsModule::FindPluginPaths
PluginPaths FindPluginPaths(PluginManagerInterface &pm) override
Definition: LoadLV2.cpp:239
LV2EffectsModule::GetOptionalFamilySymbol
EffectFamilySymbol GetOptionalFamilySymbol() override
Definition: LoadLV2.cpp:219
LV2EffectsModule::IsPluginValid
bool IsPluginValid(const PluginPath &path, bool bFast) override
Definition: LoadLV2.cpp:298
LV2EFFECTS_VERSION
#define LV2EFFECTS_VERSION
Definition: LV2Effect.h:59
LV2EffectsModule::GetPath
PluginPath GetPath() override
Definition: LoadLV2.cpp:93
ModuleInterface::RegistrationCallback
std::function< const PluginID &(ModuleInterface *, ComponentInterface *) > RegistrationCallback
Definition: ModuleInterface.h:123
safenew
#define safenew
Definition: MemoryX.h:10
LoadLV2.h
LilvString
wxString LilvString(const LilvNode *node)
Definition: LV2Effect.h:572
LV2EffectsModule
Definition: LoadLV2.h:164
LV2EffectsModule::GetPlugin
const LilvPlugin * GetPlugin(const PluginPath &path)
Definition: LoadLV2.cpp:318