def setUp(self): self.world = lilv.World() self.world.set_option( lilv.OPTION_FILTER_LANG, self.world.new_bool(True) ) self.bundle_uri = self.world.new_uri(location) self.assertIsNotNone( self.bundle_uri, "Invalid URI: '" + location + "'" ) self.world.load_bundle(self.bundle_uri) self.plugins = self.world.get_all_plugins() self.plugin = self.plugins.get(self.plugins.begin()) self.assertTrue(self.plugin.verify()) self.assertTrue(self.plugin in self.plugins) self.assertTrue(self.plugin.get_uri() in self.plugins) self.assertEqual(self.plugins[self.plugin.get_uri()], self.plugin) with self.assertRaises(KeyError): self.plugins["http://example.org/notaplugin"].get_uri() self.assertIsNotNone( self.plugin, msg="Test plugin not found at location: '" + location + "'", ) self.assertEqual(location, str(self.plugin.get_bundle_uri())) self.plugin_uri = self.plugin.get_uri() self.assertEqual( self.plugin.get_uri(), self.plugin_uri, "URI equality broken" ) self.lv2_InputPort = self.world.new_uri(lilv.LILV_URI_INPUT_PORT) self.lv2_OutputPort = self.world.new_uri(lilv.LILV_URI_OUTPUT_PORT) self.lv2_AudioPort = self.world.new_uri(lilv.LILV_URI_AUDIO_PORT) self.lv2_ControlPort = self.world.new_uri(lilv.LILV_URI_CONTROL_PORT)
def setUp(self): self.world = lilv.World() self.world.load_all() self.bundle_uri = self.world.new_uri(location) self.world.load_bundle(self.bundle_uri) self.plugins = self.world.get_all_plugins() self.plugin = self.plugins.get(self.plugins.begin())
def get_plugins_info(bundles): if len(bundles) == 0: raise Exception('get_plugins_info() - no bundles provided') world = lilv.World() # this is needed when loading specific bundles instead of load_all # (these functions are not exposed via World yet) lilv.lilv_world_load_specifications(world.me) lilv.lilv_world_load_plugin_classes(world.me) # load all bundles for bundle in bundles: # lilv wants the last character as the separator bundle = os.path.abspath(bundle) if not bundle.endswith(os.sep): bundle += os.sep # convert bundle string into a lilv node bundlenode = lilv.lilv_new_file_uri(world.me, None, bundle) # load the bundle world.load_bundle(bundlenode) # free bundlenode, no longer needed lilv.lilv_node_free(bundlenode) plugins = world.get_all_plugins() if plugins.size() == 0: raise Exception( 'get_plugins_info() - selected bundles have no plugins') return [Plugin(world, p, False) for p in plugins]
def main(args=None): args = sys.argv[1:] if args is None else args if args: uri = args[0] else: return "Usage: lv2_list_plugin_presets <plugin URI>" world = lilv.World() world.load_all() plugins = world.get_all_plugins() try: plugin = plugins[uri] except KeyError as exc: return "error: no plugin with URI '%s' found." % uri except ValueError as exc: return "error: %s" % exc presets = get_presets(world, plugin) for label, preset_uri in sorted(presets, key=lambda x: x[0] or ''): if label is None: print("Preset '%s' has no rdfs:label" % preset, file=sys.stderr) print("Label: %s" % label or "") print("URI: %s\n" % preset_uri)
def __init__(self): world = lilv.World() world.load_all() all_plugins = list(world.get_all_plugins()) self.root = None for a in all_plugins: if not a.get_class().get_parent_uri().is_uri(): if not self.root: self.root = CategoryNode(str(a.get_class().get_uri())) plugin = PluginNode(str(a.get_name()), str(a.get_uri()), a.get_author_name().as_string()) self.root.add(plugin) all_plugins.remove(a) self.build_tree(all_plugins, self.root) uncat = CategoryNode('Uncategorized', uncategorized=True) i = 0 while i < len(self.root): child = self.root[i] if type(child) == PluginNode: self.root.remove(child, True) uncat.add(child) else: i += 1 self.root.add(uncat)
def main(args=None): ap = argparse.ArgumentParser() ap.add_argument( '-c', '--categories', action="store_true", help="Add list of categories for each plugin (requires -j)") ap.add_argument('-i', '--ignore-case', action="store_true", help="Ignore case") ap.add_argument('-j', '--json', action="store_true", help="Print output as list of objects in JSON format") ap.add_argument( '-p', '--pretty', action="store_true", help="Pretty format JSON output with indentation and linebreaks") ap.add_argument('pattern', nargs='?', help="LV2 plugin URI pattern") args = ap.parse_args(args) if args.pattern: rx = re.compile(args.pattern, re.I if args.ignore_case else 0) world = lilv.World() world.load_all() results = [] for node in world.get_all_plugins(): uri = str(node.get_uri()) if not args.pattern or rx.search(uri): if args.json: # load all resources in bundle world.load_resource(uri) name = node.get_name() plugin_data = { 'name': str(name) if name is not None else None, 'uri': uri } if args.categories: categories = [] for cat in node.get_value(world.ns.rdf.type): cat = str(cat) if not cat.endswith('#Plugin'): categories.append(str(cat).split('#', 1)[-1]) plugin_data['categories'] = categories results.append(plugin_data) else: print(uri) if args.json: json.dump(results, sys.stdout, indent=2 if args.pretty else None)
def init_lilv(): global world world = lilv.World() world.load_all() world.ns.ev = lilv.Namespace(world, "http://lv2plug.in/ns/ext/event#") world.ns.presets = lilv.Namespace(world, "http://lv2plug.in/ns/ext/presets#")
def main(): """ LV2 plugin binaries are designed to be accessed via a symbol 'lv2_descriptor'. This is a problem when linking statically as the descriptor symbols clash. This script renames the symbols to a name containing the md5 hash of the plugin uri, and also writes a C header (.h) file containing info about the available plugins, and a file containing a list of plugin libraries for linking.""" world = lilv.World() world.load_all() plugins = world.get_all_plugins() initial_plugin_list = [] for plugin in plugins: uri = plugin.get_uri() library = plugin.get_library_uri().get_path() initial_plugin_list.append({ 'uri': uri, 'library': library, 'symbol': "lv2_descriptor_%s" % md5(uri).hexdigest() }) f = open("descriptors.h", "w") f.write("/* This file is automatically generated by staticizer.py*/\n\n") plugin_list = [] for p in initial_plugin_list: try: subprocess.check_output([ "arm-none-eabi-objcopy", "--redefine-sym", "lv2_descriptor=%s" % (p['symbol'], ), p['library'] ], stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: print("Failed to process %s (%d): %s" % (p['uri'], e.returncode, e.output)) continue plugin_list.append(p) for p in plugin_list: f.write("extern const LV2_Descriptor *%s(uint32_t index);\n" % p['symbol']) f.write("\nconst void* lv2_descriptor_loaders[] = {\n") for p in plugin_list: f.write(" %s,\n" % p['symbol']) f.write(" NULL\n};\n\n") f.close() f = open("plugin_library_list.txt", "w") f.write(" ".join([p['library'] for p in plugin_list])) f.close()
def setUp(self): self.world = lilv.World() self.bundle_uri = self.world.new_uri(location) self.world.load_bundle(self.bundle_uri) self.plugins = self.world.get_all_plugins() self.plugin = self.plugins[0] self.instance = lilv.Instance(self.plugin, 48000) self.assertEqual(self.plugin.get_uri(), self.instance.get_uri()) self.assertIsNone( self.instance.get_extension_data( self.world.new_uri("http://example.org/ext"))) self.assertIsNone( self.instance.get_extension_data("http://example.org/ext"))
def get_plugins_info(uri=None): class _context(): pass ctx = _context() ctx.world = lilv.World() ctx.world.load_all() plugins = ctx.world.get_all_plugins() if uri: uri = ctx.world.new_uri(uri) return _get_plugin_info(ctx, plugins[uri]) else: return [_get_plugin_info(ctx, p) for p in plugins]
def setUp(self): self.world = lilv.World() location = "file://" + os.getcwd() + "/bindings/bindings_test_plugin.lv2/" self.plugin_uri = self.world.new_uri(location) self.assertIsNotNone(self.plugin_uri, "Invalid URI: '" + location + "'") self.world.load_bundle(self.plugin_uri) self.plugins = self.world.get_all_plugins() self.plugin = self.plugins.get(self.plugins.begin()) self.assertIsNotNone(self.plugin, msg="Test plugin not found at location: '" + location + "'") self.assertEqual(location, self.plugin.get_bundle_uri().as_string()) self.instance = lilv.Instance(self.plugin, 48000, None) self.assertIsNotNone(self.instance) self.lv2_InputPort = self.world.new_uri(lilv.LILV_URI_INPUT_PORT) self.lv2_OutputPort = self.world.new_uri(lilv.LILV_URI_OUTPUT_PORT) self.lv2_AudioPort = self.world.new_uri(lilv.LILV_URI_AUDIO_PORT) self.lv2_ControlPort = self.world.new_uri(lilv.LILV_URI_CONTROL_PORT)
def __init__(self, title, bundle): self.root_uri = "http://localhost:80/" self.title = title self.bundle = bundle # TODO used? self.plugins = [] self.world = lilv.World() # this is needed when loading specific bundles instead of load_all # (these functions are not exposed via World yet) self.world.load_specifications() self.world.load_plugin_classes() self.uri_block = self.world.new_uri( "http://drobilla.net/ns/ingen#block") self.uri_head = self.world.new_uri("http://drobilla.net/ns/ingen#head") self.uri_port = self.world.new_uri("http://lv2plug.in/ns/lv2core#port") self.uri_tail = self.world.new_uri("http://drobilla.net/ns/ingen#tail") self.uri_value = self.world.new_uri( "http://drobilla.net/ns/ingen#value")
def print_presets(uri): """Print all presets of an LV2 plugin to stdout.""" world = lilv.World() world.load_all() world.ns.presets = lilv.Namespace(world, NS_PRESETS) plugins = world.get_all_plugins() plugin = plugins[uri] presets = plugin.get_related(world.ns.presets.Preset) preset_list = [] for preset in presets: world.load_resource(preset) label = world.get(preset, world.ns.rdfs.label, None) if label is None: sys.stderr.write("warning: Preset <%s> has no label\n" % preset) preset_list.append((str(preset), str(label))) for preset in sorted(preset_list): print('<%s> "%s"' % preset)
def __init__(self, path, idx=0): world = lilv.World() ns = world.ns #world.load_all() world.load_bundle(world.new_file_uri(None, path)) plugins = world.get_all_plugins() #plugin_uri_node = world.new_uri("XXX") #plugin = plugins[plugin_uri_node] self._plugin = plugin = plugins[idx] self._uri = str(plugin.get_uri()) self._bundle = str(plugin.get_bundle_uri()) self._name = str(plugin.get_name()) self._num_ports = plugin.get_num_ports() self._params = {} self._input_idx = [] self._output_idx = [] self._instance = None self._samplerate = None self._time_per_sample = 0.0 self._control_input_buffers = [] self._control_output_buffers = [] for i in range(self._num_ports): port = plugin.get_port(i) if port.is_a(ns.lv2.ControlPort): symbol = str(port.get_symbol()) lst = tuple(float(v) for v in port.get_range()) val = numpy.array([lst[0]], numpy.float32) self._params[symbol] = LV2_Port(symbol, i, str(port.get_name()), lst[0], lst[1:], port.is_a(ns.lv2.OutputPort), val) else: assert port.is_a(ns.lv2.AudioPort) if port.is_a(ns.lv2.InputPort): self._input_idx.append(i) else: assert port.is_a(ns.lv2.OutputPort) self._output_idx.append(i)
#!/usr/bin/env python3 import lilv import json import shutil import os world = lilv.World() modgui = lilv.Namespace(world, "http://moddevices.com/ns/modgui#") world.load_all() plugins = [] def get_first(list): for i in list: return i return None def get_first_value(p, ns): return get_first(p.get_value(ns)) def to_str(s): if s is None: return None # return str(str(s).encode('utf-8')) return str(s)
def get_pedalboard_name(bundle): # lilv wants the last character as the separator bundle = os.path.abspath(bundle) if not bundle.endswith(os.sep): bundle += os.sep # Create our own unique lilv world # We'll load a single bundle and get all plugins from it world = lilv.World() # this is needed when loading specific bundles instead of load_all # (these functions are not exposed via World yet) lilv.lilv_world_load_specifications(world.me) lilv.lilv_world_load_plugin_classes(world.me) # convert bundle string into a lilv node bundlenode = lilv.lilv_new_file_uri(world.me, None, bundle) # load the bundle world.load_bundle(bundlenode) # free bundlenode, no longer needed lilv.lilv_node_free(bundlenode) # get all plugins in the bundle plugins = world.get_all_plugins() # make sure the bundle includes 1 and only 1 plugin (the pedalboard) if plugins.size() != 1: raise Exception( 'get_pedalboard_info(%s) - bundle has 0 or > 1 plugin'.format( bundle)) # no indexing in python-lilv yet, just get the first item plugin = None for p in plugins: plugin = p break if plugin is None: raise Exception( 'get_pedalboard_info(%s) - failed to get plugin, you are using an old lilv!' .format(bundle)) # define the needed stuff ns_rdf = NS(world, lilv.LILV_NS_RDF) # check if the plugin is a pedalboard def fill_in_type(node): return node.as_string() plugin_types = [ i for i in LILV_FOREACH(plugin.get_value(ns_rdf.type_), fill_in_type) ] if "http://moddevices.com/ns/modpedal#Pedalboard" not in plugin_types: raise Exception( 'get_pedalboard_info(%s) - plugin has no mod:Pedalboard type'. format(bundle)) return plugin.get_name().as_string()
def lv2_init(): global _W _W = lilv.World() _W.load_all() lv2_init2()
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. #!/usr/bin/env python """List URIs associated with an LV2 plugin.""" import sys import lilv if len(sys.argv) < 2: sys.exit("Usage: %s <plugin URI>" % sys.argv[0]) w = lilv.World() w.load_all() plugins = w.get_all_plugins() plugin = plugins[w.new_uri(sys.argv[1])] print("Name: %s" % plugin.get_name()) print("Plugin URI: %s" % plugin.get_uri()) print("Bundle URI: %s" % plugin.get_bundle_uri()) print("Shared library URI: %s" % plugin.get_library_uri()) nodelist = plugin.get_data_uris() uris = [str(n) for n in nodelist] print("Data URIs:") for uri in uris: print("-", uri)
def main(): # Read command line arguments if len(sys.argv) != 4: print('USAGE: lv2_apply.py PLUGIN_URI INPUT_WAV OUTPUT_WAV') sys.exit(1) # Initialise Lilv world = lilv.World() world.load_all() plugin_uri = sys.argv[1] wav_in_path = sys.argv[2] wav_out_path = sys.argv[3] # Find plugin plugin_uri_node = world.new_uri(plugin_uri) plugin = world.get_all_plugins().get_by_uri(plugin_uri_node) if not plugin: print("Unknown plugin `%s'\n" % plugin_uri) sys.exit(1) lv2_InputPort = world.new_uri(lilv.LILV_URI_INPUT_PORT) lv2_OutputPort = world.new_uri(lilv.LILV_URI_OUTPUT_PORT) lv2_AudioPort = world.new_uri(lilv.LILV_URI_AUDIO_PORT) lv2_ControlPort = world.new_uri(lilv.LILV_URI_CONTROL_PORT) lv2_default = world.new_uri("http://lv2plug.in/ns/lv2core#default") n_audio_in = plugin.get_num_ports_of_class(lv2_InputPort, lv2_AudioPort) n_audio_out = plugin.get_num_ports_of_class(lv2_OutputPort, lv2_AudioPort) if n_audio_out == 0: print("Plugin has no audio outputs\n") sys.exit(1) # Open input file try: wav_in = WavFile(wav_in_path) except: print("Failed to open input `%s'\n" % wav_in_path) sys.exit(1) if wav_in.nchannels != n_audio_in: print("Input has %d channels, but plugin has %d audio inputs\n" % ( wav_in.nchannels, n_audio_in)) sys.exit(1) # Open output file wav_out = wave.open(wav_out_path, 'w') if not wav_out: print("Failed to open output `%s'\n" % wav_out_path) sys.exit(1) # Set output file to same format as input (except possibly nchannels) wav_out.setparams(wav_in.wav_in.getparams()) wav_out.setnchannels(n_audio_out) print('%s => %s => %s @ %d Hz' % (wav_in_path, plugin.get_name(), wav_out_path, wav_in.framerate)) instance = lilv.Instance(plugin, wav_in.framerate) channels = wav_in.read() wav_in.close() # Connect all ports to buffers. NB if we fail to connect any buffer, lilv # will segfault. audio_input_buffers = [] audio_output_buffers = [] control_input_buffers = [] control_output_buffers = [] for index in range(plugin.get_num_ports()): port = plugin.get_port_by_index(index) if port.is_a(lv2_InputPort): if port.is_a(lv2_AudioPort): audio_input_buffers.append(numpy.array(channels[len(audio_input_buffers)], numpy.float32)) instance.connect_port(index, audio_input_buffers[-1]) elif port.is_a(lv2_ControlPort): #if port.has_property(lv2_default): # Doesn't seem to work default = lilv.lilv_node_as_float(lilv.lilv_nodes_get_first(port.get_value(lv2_default))) control_input_buffers.append(numpy.array([default], numpy.float32)) instance.connect_port(index, control_input_buffers[-1]) else: raise ValueError("Unhandled port type") elif port.is_a(lv2_OutputPort): if port.is_a(lv2_AudioPort): audio_output_buffers.append(numpy.array([0] * wav_in.nframes, numpy.float32)) instance.connect_port(index, audio_output_buffers[-1]) elif port.is_a(lv2_ControlPort): control_output_buffers.append(numpy.array([0], numpy.float32)) instance.connect_port(index, control_output_buffers[-1]) else: raise ValueError("Unhandled port type") # Run the plugin: instance.run(wav_in.nframes) # Interleave output buffers: data = numpy.dstack(audio_output_buffers).flatten() # Return to original int range: if wav_in.signed: data = data * float(wav_in.range / 2) else: data = (data + 1) * float(wav_in.range/2) # Write output file in chunks to stop memory usage getting out of hand: CHUNK_SIZE = 8192 for chunk in numpy.array_split(data, CHUNK_SIZE): wav_out.writeframes(wave.struct.pack("%u%s" % (len(chunk), wav_in.struct_fmt_code), *chunk)) wav_out.close()
def get_info_from_lv2_bundle(bundle): # lilv wants the last character as the separator if not bundle.endswith(os.sep): bundle += os.sep # Create our own unique lilv world # We'll load a single bundle and get all plugins from it world = lilv.World() # this is needed when loading specific bundles instead of load_all # (these functions are not exposed via World yet) lilv.lilv_world_load_specifications(world.me) lilv.lilv_world_load_plugin_classes(world.me) # convert bundle string into a lilv node bundlenode = lilv.lilv_new_file_uri(world.me, None, bundle) # load the bundle world.load_bundle(bundlenode) # free bundlenode, no longer needed lilv.lilv_node_free(bundlenode) # get all plugins in the bundle plugins = world.get_all_plugins() # make sure the bundle includes 1 and only 1 plugin (the pedalboard) if plugins.size() != 1: raise Exception('get_info_from_lv2_bundle(%s) - bundle has 0 or > 1 plugin'.format(bundle)) # no indexing in python-lilv yet, just get the first item plugin = None for p in plugins: plugin = p break if plugin is None: raise Exception('get_info_from_lv2_bundle(%s) - failed to get plugin, you are using an old lilv!'.format(bundle)) # handy class to get lilv nodes from. copied from lv2.py in mod-ui class NS(object): def __init__(self, base): self.base = base self._cache = {} def __getattr__(self, attr): if attr not in self._cache: self._cache[attr] = lilv.Node(world.new_uri(self.base+attr)) return self._cache[attr] # define the needed stuff NS_lv2core = NS('http://lv2plug.in/ns/lv2core#') NS_lv2core_proto = NS_lv2core.prototype NS_modgui = NS('http://moddevices.com/ns/modgui#') NS_modgui_thumb = NS_modgui.thumbnail NS_ingen = NS('http://drobilla.net/ns/ingen#') NS_ingen_block = NS_ingen.block NS_ingen_prototype = NS_ingen.prototype # check if the plugin has modgui:thumnail, if not it's probably not a real pedalboard thumbnail_check = plugin.get_value(NS_modgui_thumb).get_first() if thumbnail_check.me is None: raise Exception('get_info_from_lv2_bundle(%s) - plugin has no modgui:thumbnail'.format(bundle)) # let's get all the info now ingenplugins = [] info = { 'name': plugin.get_name().as_string(), #'author': plugin.get_author_name().as_string() or '', # Might be empty #'uri': plugin.get_uri().as_string(), 'thumbnail': os.path.basename(thumbnail_check.as_string()), 'plugins': [] # we save this info later } blocks = plugin.get_value(NS_ingen_block) it = blocks.begin() while not blocks.is_end(it): block = blocks.get(it) it = blocks.next(it) if block.me is None: continue protouri1 = lilv.lilv_world_get(world.me, block.me, NS_lv2core_proto.me, None) protouri2 = lilv.lilv_world_get(world.me, block.me, NS_ingen_prototype.me, None) if protouri1 is not None: ingenplugins.append(lilv.lilv_node_as_uri(protouri1)) elif protouri2 is not None: ingenplugins.append(lilv.lilv_node_as_uri(protouri2)) info['plugins'] = ingenplugins return info
def get_all_plugins(): world = lilv.World() world.load_all() plugins = world.get_all_plugins() return [Plugin(world, p, False).data for p in plugins]
def setUp(self): self.world = lilv.World() self.bundle_uri = self.world.new_uri(location) self.world.load_specifications() self.world.load_plugin_classes()
def setUp(self): self.world = lilv.World()
def setUp(self): self.world = lilv.World() self.world.load_all();
class JalvLv2Handler(ZynthianConfigHandler): JALV_LV2_CONFIG_FILE = "{}/jalv/plugins.json".format( os.environ.get('ZYNTHIAN_CONFIG_DIR')) JALV_ALL_LV2_CONFIG_FILE = "{}/jalv/all_plugins.json".format( os.environ.get('ZYNTHIAN_CONFIG_DIR')) all_plugins = None world = lilv.World() @tornado.web.authenticated def get(self, errors=None): if self.all_plugins is None: self.load_all_plugins() config = OrderedDict([]) config['ZYNTHIAN_JALV_PLUGINS'] = self.load_plugins() try: config['ZYNTHIAN_ACTIVE_TAB'] = self.get_argument( 'ZYNTHIAN_ACTIVE_TAB') except: pass if not 'ZYNTHIAN_ACTIVE_TAB' in config or len( config['ZYNTHIAN_ACTIVE_TAB']) == 0: config[ 'ZYNTHIAN_ACTIVE_TAB'] = PluginType.MIDI_SYNTH.value.replace( " ", "_") try: config['ZYNTHIAN_JALV_FILTER'] = self.get_argument( 'ZYNTHIAN_JALV_FILTER') except: config['ZYNTHIAN_JALV_FILTER'] = '' if self.genjson: self.write(config) else: if errors: logging.error("Configuring JALV LV2-Plugins failed: %s" % format(errors)) self.clear() self.set_status(400) self.finish("Configuring JALV LV2-Plugins failed: %s" % format(errors)) else: self.render("config.html", body="jalv_lv2.html", config=config, title="LV2-Plugins", errors=errors) @tornado.web.authenticated def post(self): action = self.get_argument('ZYNTHIAN_JALV_ACTION') if action: errors = { 'ENABLE_PLUGINS': lambda: self.do_enable_plugins(), 'REGENERATE_PLUGIN_LIST': lambda: self.do_regenerate_plugin_list() }[action]() self.get(errors) def load_all_plugins(self): result = OrderedDict() trials = 0 while not result and trials <= 1: try: trials = trials + 1 with open(self.JALV_ALL_LV2_CONFIG_FILE) as f: result = json.load(f, object_pairs_hook=OrderedDict) except Exception as e: logging.warning('Loading list of all LV2-Plugins failed: %s' % e) if not result: self.generate_all_plugins_config_file() self.all_plugins = result return result def generate_all_plugins_config_file(self): plugins = OrderedDict() self.world.ns.ev = lilv.Namespace(self.world, 'http://lv2plug.in/ns/ext/event#') start = int(round(time.time() * 1000)) try: self.world.load_all() for plugin in self.world.get_all_plugins(): logging.info("Adding '{}'".format(plugin.get_name())) plugins[str(plugin.get_name())] = { 'URL': str(plugin.get_uri()), 'TYPE': self.get_plugin_type(plugin).value, 'ENABLED': False } self.all_plugins = OrderedDict(sorted(plugins.items())) with open(self.JALV_ALL_LV2_CONFIG_FILE, 'w') as f: json.dump(self.all_plugins, f) except Exception as e: logging.error('Generating list of all LV2-Plugins failed: %s' % e) end = int(round(time.time() * 1000)) logging.info('config file generation took %d' % (end - start)) def load_plugins(self): result = OrderedDict() for pluginType in PluginType: result[pluginType.value] = OrderedDict() all_plugins = self.all_plugins enabled_plugins = self.load_enabled_plugins() for plugin_name, plugin_properties in all_plugins.items(): result[plugin_properties['TYPE']][plugin_name] = plugin_properties if plugin_name in enabled_plugins: logging.info("Plugin '{}' enabled".format(plugin_name)) plugin_properties['ENABLED'] = True return result def load_enabled_plugins(self): result = OrderedDict() try: with open(self.JALV_LV2_CONFIG_FILE) as f: result = json.load(f, object_pairs_hook=OrderedDict) except Exception as e: logging.info('Loading list of enabled LV2-Plugins failed: %s' % e) return result def do_enable_plugins(self): try: pluginJson = OrderedDict() self.load_all_plugins() postedPlugins = tornado.escape.recursive_unicode( self.request.arguments) for plugin_name, plugin_properties in self.all_plugins.items(): if "ZYNTHIAN_JALV_ENABLE_%s" % plugin_name in postedPlugins: pp = {} pp['URL'] = plugin_properties['URL'] pp['TYPE'] = plugin_properties['TYPE'] pluginJson[plugin_name] = pp with open(self.JALV_LV2_CONFIG_FILE, 'w') as f: json.dump(pluginJson, f) except Exception as e: logging.error("Installing jalv plugins failed: %s" % format(e)) return format(e) def do_regenerate_plugin_list(self): self.generate_all_plugins_config_file() def get_plugin_type(self, pl): lv2_plugin_classes = { "MIDI_SYNTH": ("Instrument"), "AUDIO_EFFECT": ("Analyser", "Spectral", "Delay", "Compressor", "Distortion", "Filter", "Equaliser", "Modulator", "Expander", "Spatial", "Limiter", "Pitch Shifter", "Reverb", "Simulator", "Envelope", "Gate", "Amplifier", "Chorus", "Flanger", "Phaser", "Highpass", "Lowpass", "Dynamics"), "AUDIO_GENERATOR": ("Oscillator", "Generator"), "UNKNOWN": ("Utility", "Plugin") } # Try to determine the plugin type from the LV2 class ... plugin_class = str(pl.get_class().get_label()) if plugin_class in lv2_plugin_classes["MIDI_SYNTH"]: return PluginType.MIDI_SYNTH elif plugin_class in lv2_plugin_classes["AUDIO_EFFECT"]: return PluginType.AUDIO_EFFECT elif plugin_class in lv2_plugin_classes["AUDIO_GENERATOR"]: return PluginType.AUDIO_GENERATOR # If failed to determine the plugin type using the LV2 class, # inspect the input/output ports ... n_audio_in = pl.get_num_ports_of_class(self.world.ns.lv2.InputPort, self.world.ns.lv2.AudioPort) n_audio_out = pl.get_num_ports_of_class(self.world.ns.lv2.OutputPort, self.world.ns.lv2.AudioPort) n_midi_in = pl.get_num_ports_of_class(self.world.ns.lv2.InputPort, self.world.ns.ev.EventPort) n_midi_out = pl.get_num_ports_of_class(self.world.ns.lv2.OutputPort, self.world.ns.ev.EventPort) n_midi_in += pl.get_num_ports_of_class(self.world.ns.lv2.InputPort, self.world.ns.atom.AtomPort) n_midi_out += pl.get_num_ports_of_class(self.world.ns.lv2.OutputPort, self.world.ns.atom.AtomPort) # Really DIRTY => Should be fixed ASAP!!! TODO!! #plugin_name=str(pl.get_name()) #if plugin_name[-2:]=="v1": # return PluginType.MIDI_SYNTH #if plugin_name[:2]=="EQ": # return PluginType.AUDIO_EFFECT if n_audio_out > 0 and n_audio_in == 0: if n_midi_in > 0: return PluginType.MIDI_SYNTH else: return PluginType.AUDIO_GENERATOR if n_audio_out > 0 and n_audio_in > 0 and n_midi_out == 0: return PluginType.AUDIO_EFFECT if n_midi_in > 0 and n_midi_out > 0 and n_audio_in == n_audio_out == 0: return PluginType.MIDI_TOOL #return PluginType.UNKNOWN return PluginType.AUDIO_EFFECT
def get_pedalboard_info(bundle): # lilv wants the last character as the separator bundle = os.path.abspath(bundle) if not bundle.endswith(os.sep): bundle += os.sep # Create our own unique lilv world # We'll load a single bundle and get all plugins from it world = lilv.World() # this is needed when loading specific bundles instead of load_all # (these functions are not exposed via World yet) lilv.lilv_world_load_specifications(world.me) lilv.lilv_world_load_plugin_classes(world.me) # convert bundle string into a lilv node bundlenode = lilv.lilv_new_file_uri(world.me, None, bundle) # load the bundle world.load_bundle(bundlenode) # free bundlenode, no longer needed lilv.lilv_node_free(bundlenode) # get all plugins in the bundle plugins = world.get_all_plugins() # make sure the bundle includes 1 and only 1 plugin (the pedalboard) if plugins.size() != 1: raise Exception( 'get_pedalboard_info(%s) - bundle has 0 or > 1 plugin'.format( bundle)) # no indexing in python-lilv yet, just get the first item plugin = None for p in plugins: plugin = p break if plugin is None: raise Exception( 'get_pedalboard_info(%s) - failed to get plugin, you are using an old lilv!' .format(bundle)) # define the needed stuff ns_rdf = NS(world, lilv.LILV_NS_RDF) ns_lv2core = NS(world, lilv.LILV_NS_LV2) ns_ingen = NS(world, "http://drobilla.net/ns/ingen#") ns_modpedal = NS(world, "http://moddevices.com/ns/modpedal#") # check if the plugin is a pedalboard def fill_in_type(node): return node.as_string() plugin_types = [ i for i in LILV_FOREACH(plugin.get_value(ns_rdf.type_), fill_in_type) ] if "http://moddevices.com/ns/modpedal#Pedalboard" not in plugin_types: raise Exception( 'get_pedalboard_info(%s) - plugin has no mod:Pedalboard type'. format(bundle)) # let's get all the info now ingenarcs = [] ingenblocks = [] info = { 'name': plugin.get_name().as_string(), 'uri': plugin.get_uri().as_string(), 'author': plugin.get_author_name().as_string() or "", # Might be empty 'hardware': { # we save this info later 'audio': { 'ins': 0, 'outs': 0 }, 'cv': { 'ins': 0, 'outs': 0 }, 'midi': { 'ins': 0, 'outs': 0 } }, 'size': { 'width': plugin.get_value(ns_modpedal.width).get_first().as_int(), 'height': plugin.get_value(ns_modpedal.height).get_first().as_int(), }, 'screenshot': os.path.basename( plugin.get_value(ns_modpedal.screenshot).get_first().as_string() or ""), 'thumbnail': os.path.basename( plugin.get_value(ns_modpedal.thumbnail).get_first().as_string() or ""), 'connections': [], # we save this info later 'plugins': [] # we save this info later } # connections arcs = plugin.get_value(ns_ingen.arc) it = arcs.begin() while not arcs.is_end(it): arc = arcs.get(it) it = arcs.next(it) if arc.me is None: continue head = lilv.lilv_world_get(world.me, arc.me, ns_ingen.head.me, None) tail = lilv.lilv_world_get(world.me, arc.me, ns_ingen.tail.me, None) if head is None or tail is None: continue ingenarcs.append({ "source": lilv.lilv_uri_to_path(lilv.lilv_node_as_string(tail)).replace( bundle, "", 1), "target": lilv.lilv_uri_to_path(lilv.lilv_node_as_string(head)).replace( bundle, "", 1) }) # hardware ports handled_port_uris = [] ports = plugin.get_value(ns_lv2core.port) it = ports.begin() while not ports.is_end(it): port = ports.get(it) it = ports.next(it) if port.me is None: continue # check if we already handled this port port_uri = port.as_uri() if port_uri in handled_port_uris: continue if port_uri.endswith("/control_in") or port_uri.endswith( "/control_out"): continue handled_port_uris.append(port_uri) # get types port_types = lilv.lilv_world_find_nodes(world.me, port.me, ns_rdf.type_.me, None) if port_types is None: continue portDir = "" # input or output portType = "" # atom, audio or cv it2 = lilv.lilv_nodes_begin(port_types) while not lilv.lilv_nodes_is_end(port_types, it2): port_type = lilv.lilv_nodes_get(port_types, it2) it2 = lilv.lilv_nodes_next(port_types, it2) if port_type is None: continue port_type_uri = lilv.lilv_node_as_uri(port_type) if port_type_uri == "http://lv2plug.in/ns/lv2core#InputPort": portDir = "input" elif port_type_uri == "http://lv2plug.in/ns/lv2core#OutputPort": portDir = "output" elif port_type_uri == "http://lv2plug.in/ns/lv2core#AudioPort": portType = "audio" elif port_type_uri == "http://lv2plug.in/ns/lv2core#CVPort": portType = "cv" elif port_type_uri == "http://lv2plug.in/ns/ext/atom#AtomPort": portType = "atom" if not (portDir or portType): continue if portType == "audio": if portDir == "input": info['hardware']['audio']['ins'] += 1 else: info['hardware']['audio']['outs'] += 1 elif portType == "atom": if portDir == "input": info['hardware']['midi']['ins'] += 1 else: info['hardware']['midi']['outs'] += 1 elif portType == "cv": if portDir == "input": info['hardware']['cv']['ins'] += 1 else: info['hardware']['cv']['outs'] += 1 # plugins blocks = plugin.get_value(ns_ingen.block) it = blocks.begin() while not blocks.is_end(it): block = blocks.get(it) it = blocks.next(it) if block.me is None: continue protouri1 = lilv.lilv_world_get(world.me, block.me, ns_lv2core.prototype.me, None) protouri2 = lilv.lilv_world_get(world.me, block.me, ns_ingen.prototype.me, None) if protouri1 is not None: proto = protouri1 elif protouri2 is not None: proto = protouri2 else: continue instance = lilv.lilv_uri_to_path(lilv.lilv_node_as_string( block.me)).replace(bundle, "", 1) uri = lilv.lilv_node_as_uri(proto) enabled = lilv.lilv_world_get(world.me, block.me, ns_ingen.enabled.me, None) minorver = lilv.lilv_world_get(world.me, block.me, ns_lv2core.minorVersion.me, None) microver = lilv.lilv_world_get(world.me, block.me, ns_lv2core.microVersion.me, None) ingenblocks.append({ "instance": instance, "uri": uri, "x": lilv.lilv_node_as_float( lilv.lilv_world_get(world.me, block.me, ns_ingen.canvasX.me, None)), "y": lilv.lilv_node_as_float( lilv.lilv_world_get(world.me, block.me, ns_ingen.canvasY.me, None)), "enabled": lilv.lilv_node_as_bool(enabled) if enabled is not None else False, "minorVersion": lilv.lilv_node_as_int(minorver) if minorver else 0, "microVersion": lilv.lilv_node_as_int(microver) if microver else 0, }) info['connections'] = ingenarcs info['plugins'] = ingenblocks return info