PedalPi - PluginsManager

Build Status Documentation Status Code coverage

Pythonic management of LV2 audio plugins with mod-host.

Documentation:
http://pedalpi-pluginsmanager.readthedocs.io/
Code:
https://github.com/PedalPi/PluginsManager
Python Package Index:
https://pypi.org/project/PedalPi-PluginsManager
License:
Apache License 2.0

Install

Plugin Manager has dependencies that must be installed before installing the library. Among the dependencies are lv2ls to check the installed audio plugins and PortAudio for information on the audio interfaces through PyAudio.

On Debian-based systems, run:

sudo apt-get install -y portaudio19-dev python-all-dev lilv-utils --no-install-recommends

Of course, for PluginsManager to manage Lv2 audio plugins, it is necessary that they have installed audio plugins to be managed. The Guitarix and Calf Studio projects provide some audio plugins. To install them:

pip install PedalPi-PluginsManager

Example

Note

Other examples are in the examples folder in the repository.

This examples uses Calf and Guitarix audio plugins.

Download and install mod-host. For more information, check the ModHost section.

Start audio process

# In this example, is starting a Zoom g3 series audio interface
jackd -R -P70 -t2000 -dalsa -dhw:Series -p256 -n3 -r44100 -s &
mod-host

Play!

from pluginsmanager.banks_manager import BanksManager
from pluginsmanager.observer.mod_host.mod_host import ModHost

from pluginsmanager.model.bank import Bank
from pluginsmanager.model.pedalboard import Pedalboard
from pluginsmanager.model.connection import Connection

from pluginsmanager.model.lv2.lv2_effect_builder import Lv2EffectBuilder

from pluginsmanager.model.system.system_effect import SystemEffect

Creating a bank

# BanksManager manager the banks
manager = BanksManager()

bank = Bank('Bank 1')
manager.append(bank)

Connecting with mod_host. Is necessary that the mod_host process already running

mod_host = ModHost('localhost')
mod_host.connect()
manager.register(mod_host)

Creating pedalboard

pedalboard = Pedalboard('Rocksmith')
bank.append(pedalboard)
# or
# bank.pedalboards.append(pedalboard)

Loads pedalboard. All changes in pedalboard are reproduced in mod_host

mod_host.pedalboard = pedalboard

Add effects in the pedalboard

builder = Lv2EffectBuilder()

reverb = builder.build('http://calf.sourceforge.net/plugins/Reverb')
fuzz = builder.build('http://guitarix.sourceforge.net/plugins/gx_fuzz_#fuzz_')
reverb2 = builder.build('http://calf.sourceforge.net/plugins/Reverb')

pedalboard.append(reverb)
pedalboard.append(fuzz)
pedalboard.append(reverb2)
# or
# pedalboard.effects.append(reverb2)

For obtains automatically the sound card inputs and outputs, use SystemEffectBuilder. It requires a JackClient instance, that uses JACK-Client.

from pluginsmanager.jack.jack_client import JackClient
client = JackClient()

from pluginsmanager.model.system.system_effect_builder import SystemEffectBuilder
sys_effect = SystemEffectBuilder(client).build()

For manual input and output sound card definition, use:

sys_effect = SystemEffect('system', ['capture_1', 'capture_2'], ['playback_1', 'playback_2'])

Note

NOT ADD sys_effect in any Pedalboard

Connecting:

pedalboard.connect(sys_effect.outputs[0], reverb.inputs[0])

pedalboard.connect(reverb.outputs[0], fuzz.inputs[0])
pedalboard.connect(reverb.outputs[1], fuzz.inputs[0])
pedalboard.connect(fuzz.outputs[0], reverb2.inputs[0])
pedalboard.connect(reverb.outputs[0], reverb2.inputs[0])

pedalboard.connect(reverb2.outputs[0], sys_effect.inputs[0])
pedalboard.connect(reverb2.outputs[0], sys_effect.inputs[1])

Connecting using ConnectionList:

pedalboard.connections.append(Connection(sys_effect.outputs[0], reverb.inputs[0]))

pedalboard.connections.append(Connection(reverb.outputs[0], fuzz.inputs[0]))
pedalboard.connections.append(Connection(reverb.outputs[1], fuzz.inputs[0]))
pedalboard.connections.append(Connection(fuzz.outputs[0], reverb2.inputs[0]))
pedalboard.connections.append(Connection(reverb.outputs[0], reverb2.inputs[0]))

pedalboard.connections.append(Connection(reverb2.outputs[0], sys_effect.inputs[0]))
pedalboard.connections.append(Connection(reverb2.outputs[0], sys_effect.inputs[1]))

Set effect status (enable/disable bypass) and param value

fuzz.toggle()
# or
# fuzz.active = not fuzz.active

fuzz.params[0].value = fuzz.params[0].minimum / fuzz.params[0].maximum

Removing effects and connections:

pedalboard.effects.remove(fuzz)

for connection in list(pedalboard.connections):
    pedalboard.disconnect(connection)
    # or
    #pedalboard.connections.remove(connection)

for effect in list(pedalboard.effects):
    pedalboard.effects.remove(effect)
# or
# for index in reversed(range(len(pedalboard.effects))):
    # del pedalboard.effects[index]

Observer

ModHost is an observer (see UpdatesObserver). It is informed about all changes that occur in some model instance (BanksManager, Bank, Pedalboard, Effect, Param, …), allowing it to communicate with the mod-host process transparently.

It is possible to create observers! Some ideas are:

  • Allow the use of other hosts (such as Carla);
  • Automatically persist changes;
  • Automatically update a human-machine interface (such as LEDs and displays that inform the state of the effects).

How to implement and the list of Observers implemented by this library can be accessed in the Observer section.

Maintenance

Makefile

Execute make help for see the options

Generate documentation

This project uses Sphinx + Read the Docs.

Changelog

Changelog

Version 0.8.0 – released 11/16/19

  • Issue #46 - Notify changes: Pedalboard Name, Pedalboard Data, Bank Data
  • Issue #95 - Update readme

Note

In the future, only python version 3.4 or higher will be supported in favor of typing (Issue #50)

Version 0.7.2 – released 11/10/19

  • Issue #103 - Now other developers can informs custom messages notification about changes_

Version 0.7.1 – released 03/15/18

Version 0.7.0 – released 02/17/18

  • Issue #83 - Add EffectsList for raises errors:
    • Error when add twice the effect instance;
    • Error when add any effect.is_unique_for_all_pedalboards == True (e.g.: SystemEffect);
  • Issue #80 - Add ConnectionsList for raises errors:
    • Error when add twice an equals connection;
    • Error when add a connection where the input or output is a effect that not in pedalboard if effect.is_unique_for_all_pedalboards == False (e.g.: is not SystemEffect).
  • Issue #64 - Start process to add Carla support:
  • Defined pattern: Access json metadata (liblilv) from lv2 classes using lv2instance.data attribute.
  • Issue #90 - Reverts Issue #66 - Param now informs minimum and maximum in __dict__()

Version 0.6.0 – released 11/30/17

  • Add makefile. Now is possible run tests and generate docs easily (make help);
  • Improve SystemInput and SystemOutputs documentation;
  • Issue #57 - Implementing midi support:
  • Fix autosaver_test creation folder. Now is more easily configure test workspace;
  • Refactored Input, Output: Created Port for remove duplicated code;
  • Refactored SystemInput, SystemOutput: Created SystemPortMixing for remove duplicated code;
  • Refactored Lv2Input, Lv2Output: Created Lv2PortMixing for remove duplicated code;
  • JackClient - Add attributes: audio_inputs, audio_outputs, midi_inputs, midi_outputs;
  • Break change: Removed Output.connect() and Output.disconnect() Output methods. Use instead connect(), disconnect() Pedalboard methods;
  • Issue #67 - Created connect(), disconnect() Pedalboard methods;
  • Fixed Changelog: Now is possible see it in the documentation;
  • Issue #38 - Raise erros then add sys_effect in any Pedalboard;
  • Issue #65 - Fix documentation bug SystemEffectBuilder(client).build() instead SystemEffectBuilder(client);
  • Issue #68 - Remove current mod-host pedalboard don’t removes systems connection (system.output to system.input);
  • Issue #66 - JSON effect improviments: Add plugin version. Remove min and max;
  • Issue #62 - Create a converter MOD pedalboard -> PluginsManager pedalboard;
  • Issue #77 - Fix MidiConnection bugs (SystemMidiInput and SystemMidiOutput doesn’t works in ModHost);
  • Issue #78 - Improve lv2 effect builder error message when plugin not exists;
  • Lv2EffectBuilder - Add parameter ignore_unsupported_plugins for ignore audio plugins errors if it doesn’t installed in the system. The previous versions raises error if a audio plugin hasn’t installed in the system. Now, is possible use it if plugins_json parameter contains your metadata. Observes that, how the audio plugin aren’t installed, your use with mod-host or other host will raises errors.

Version 0.5.1 – released 08/16/17

Version 0.5.0 – released 05/29/17

  • Issue #29 - List audio interfaces
  • Issue #32 - Add method to starts mod-host in ModHost instance
  • Add banks iterator for PluginsManager
  • Improve documentation (Issue #3)
    • Improve Readme: Add lib requirements
    • Add examples folder
    • Informs the changes in Readme (index.html)
  • Issue #39 - Add ObservableList.move() method (to change order of pedalboards in a bank and banks in a banks manager)
  • Issue #44 - Add thread support for observer scope. Break changes:
    • Moved pluginsmanager.model.updates_observerpluginsmanager.observer.updates_observer
    • Moved pluginsmanager.model.observer_typepluginsmanager.observer.updates_observer
    • Moved pluginsmanager.util.observable_listpluginsmanager.observer.observable_list
    • Moved pluginsmanager.modhostpluginsmanager.modhost.observer
  • Created BanksManager.unregister() method

Version 0.4.0 – released 05/17/17

  • Improve coverage code
  • Remove deprecated files (mod-host auto connect)
  • Issue #23 - Add method for secure close in mod-host
  • Issue #22 - Fastest load pedalboard
  • Issue #19 - x-run callback. Create pluginsmanager.jack.jack_client.JackClient

Version 0.3.2 – released 05/12/17

  • Fix pluginsmanager.util.builder: Add folder in pip

Version 0.3.1 – released 05/10/17

  • Add class method Lv2EffectBuilder.plugins_json_file()

Version 0.3.0 – released 05/08/17

  • Add lilvlib support: - Add object Lv2EffectBuilder method - Lv2EffectBuilder.lv2_plugins_data(): Scan and generate the lv2 plugins metadata - Add object Lv2EffectBuilder attribute - Lv2EffectBuilder.plugins(): List plugins - Add object Lv2EffectBuilder method - Lv2EffectBuilder.reload(): Load lv2 metadata

Version 0.2.1 – released 05/07/17

Version 0.2.0 – released 03/31/17

  • Initial release

API

Contents:

PedalPi - PluginsManager - Jack

pluginsmanager.jack.jack_client.JackClient

pluginsmanager.jack.jack_interface.JackInterfaces

pluginsmanager.jack.jack_interface.AudioInterface

PedalPi - PluginsManager - Host

PedalPi - PluginsManager - HostObserver

HostObserver
class pluginsmanager.observer.host_observer.host_observer.HostObserver[source]

HostObserver contains the basis for Host implementations, like ModHost or Carla.

It is an UpdatesObserver. With it, can be apply the current pedalboard changes transparently.

HostObserver contains an algorithm for improve the change of the current pedalboard. Also, HostObserver process the updates and define abstract methods that hosts needs to implements, usually only with the important part.

__del__()[source]

Calls close() method for remove the audio plugins loaded and closes connection with the host.

__init__()[source]

Initialize self. See help(type(self)) for accurate signature.

close()[source]

Remove the audio plugins loaded and closes connection with the host.

connect()[source]

Connect with the host

on_bank_updated(bank, update_type, **kwargs)[source]

Called when changes occurs in any Bank

Parameters:
  • bank (Bank) – Bank changed.
  • update_type (UpdateType) – Change type
  • index (int) – Bank index (or old index if update_type == UpdateType.DELETED)
  • origin (BanksManager) – BanksManager that the bank is (or has) contained
  • Bank – Contains the old bank occurs a UpdateType.UPDATED
on_connection_updated(connection, update_type, pedalboard, **kwargs)[source]

Called when changes occurs in any pluginsmanager.model.connection.Connection of Pedalboard (adding, updating or removing connections)

Parameters:
on_effect_status_toggled(effect, **kwargs)[source]

Called when any Effect status is toggled

Parameters:effect (Effect) – Effect when status has been toggled
on_effect_updated(effect, update_type, index, origin, **kwargs)[source]

Called when changes occurs in any Effect

Parameters:
  • effect (Effect) – Effect changed
  • update_type (UpdateType) – Change type
  • index (int) – Effect index (or old index if update_type == UpdateType.DELETED)
  • origin (Pedalboard) – Pedalboard that the effect is (or has) contained
on_param_value_changed(param, **kwargs)[source]

Called when a param value change

Parameters:param (Param) – Param with value changed
on_pedalboard_updated(pedalboard, update_type, **kwargs)[source]

Called when changes occurs in any Pedalboard

Parameters:
  • pedalboard (Pedalboard) – Pedalboard changed
  • update_type (UpdateType) – Change type
  • index (int) – Pedalboard index (or old index if update_type == UpdateType.DELETED)
  • origin (Bank) – Bank that the pedalboard is (or has) contained
  • old (Pedalboard) – Contains the old pedalboard when occurs a UpdateType.UPDATED
pedalboard

Currently managed pedalboard (current pedalboard)

Getter:Current pedalboard - Pedalboard loaded by mod-host
Setter:Set the pedalboard that will be loaded by mod-host
Type:Pedalboard
start()[source]

Invokes the process.

HostError
class pluginsmanager.observer.host_observer.host_observer.HostError[source]

PedalPi - PluginsManager - ModHost

About mod-host

mod-host is a LV2 host for Jack controllable via socket or command line. With it you can load audio plugins, connect, manage plugins.

For your use, is necessary download it

git clone https://github.com/moddevices/mod-host
cd mod-host
make
make install

Then boot the JACK process and start the mod-host. Details about “JACK” can be found at https://help.ubuntu.com/community/What%20is%20JACK

# In this example, is starting a Zoom g3 series audio interface
jackd -R -P70 -t2000 -dalsa -dhw:Series -p256 -n3 -r44100 -s &
mod-host

You can now connect to the mod-host through the Plugins Manager API. Create a ModHost object with the address that is running the mod-host process. Being in the same machine, it should be ‘localhost’

mod_host = ModHost('localhost')
mod_host.connect()

Finally, register the mod-host in your BanksManager. Changes made to the current pedalboard will be applied to mod-host

manager = BanksManager()
# ...
manager.register(mod_host)

To change the current pedalboard, change the pedalboard parameter to mod_host. Remember that for changes to occur in mod-host, the pedalboard must belong to some bank of banks_manager.

mod_host.pedalboard = my_awesome_pedalboard
ModHost
class pluginsmanager.observer.mod_host.mod_host.ModHost(address='localhost', port=5555)[source]
Python port for mod-host
Mod-host is a LV2 host for Jack controllable via socket or command line.

This class offers the mod-host control in a python API:

# Create a mod-host, connect and register it in banks_manager
mod_host = ModHost('localhost')
mod_host.connect()
banks_manager.register(mod_host)

# Set the mod_host pedalboard for a pedalboard that the bank
# has added in banks_manager
mod_host.pedalboard = my_awesome_pedalboard

The changes in current pedalboard (pedalboard attribute of mod_host) will also result in mod-host:

driver = my_awesome_pedalboard.effects[0]
driver.active = False

Note

For use, is necessary that the mod-host is running, for use, access

For more JACK information, access Demystifying JACK – A Beginners Guide to Getting Started with JACK

Example:

In this example, is starting a Zoom G3 series audio interface. Others interfaces maybe needs others configurations.
# Starting jackdump process via console
jackd -R -P70 -t2000 -dalsa -dhw:Series -p256 -n3 -r44100 -s &
# Starting mod-host
mod-host &
Parameters:
  • address (string) – Computer mod-host process address (IP). If the process is running on the same computer that is running the python code uses localhost.
  • port (int) – Socket port on which mod-host should be running. Default is 5555
__del__()[source]

Calls close() method for remove the audio plugins loaded and closes connection with mod-host.

>>> mod_host = ModHost()
>>> del mod_host

Note

If the mod-host process has been created with start() method, it will be finished.

__init__(address='localhost', port=5555)[source]

Initialize self. See help(type(self)) for accurate signature.

close()[source]

Remove the audio plugins loaded and closes connection with mod-host.

Note

If the mod-host process has been created with start() method, it will be finished.

connect()[source]

Connect the object with mod-host with the _address_ parameter informed in the constructor method (__init__())

start()[source]

Invokes the mod-host process.

mod-host requires JACK to be running. mod-host does not startup JACK automatically, so you need to start it before running mod-host.

Note

This function is experimental. There is no guarantee that the process will actually be initiated.

ModHost internal

The classes below are for internal use of mod-host

Connection
class pluginsmanager.observer.mod_host.connection.Connection(socket_port=5555, address='localhost')[source]

Class responsible for managing an API connection to the mod-host process via socket

__init__(socket_port=5555, address='localhost')[source]

Initialize self. See help(type(self)) for accurate signature.

close()[source]

Closes socket connection

send(message)[source]

Sends message to mod-host.

Note

Uses ProtocolParser for a high-level management. As example, view Host

Parameters:message (string) – Message that will be sent for mod-host
Host
class pluginsmanager.observer.mod_host.host.Host(address='localhost', port=5555)[source]

Bridge between mod-host API and mod-host process

__init__(address='localhost', port=5555)[source]

Initialize self. See help(type(self)) for accurate signature.

add(effect)[source]

Add an LV2 plugin encapsulated as a jack client

Parameters:effect (Lv2Effect) – Effect that will be loaded as LV2 plugin encapsulated
close()[source]

Quit the connection with mod-host

connect(connection)[source]

Connect two effect audio ports

Parameters:connection (pluginsmanager.model.connection.Connection) – Connection with the two effect audio ports (output and input)
disconnect(connection)[source]

Disconnect two effect audio ports

Parameters:connection (pluginsmanager.model.connection.Connection) – Connection with the two effect audio ports (output and input)
quit()[source]

Quit the connection with mod-host and stop the mod-host process

remove(effect)[source]

Remove an LV2 plugin instance (and also the jack client)

Parameters:effect (Lv2Effect) – Effect that your jack client encapsulated will removed
set_param_value(param)[source]

Set a value to given control

Parameters:param (Lv2Param) – Param that the value will be updated
set_status(effect)[source]

Toggle effect processing

Parameters:effect (Lv2Effect) – Effect with the status updated
ProtocolParser
class pluginsmanager.observer.mod_host.protocol_parser.ProtocolParser[source]

Prepare the objects to mod-host string command

static add(effect)[source]

add <lv2_uri> <instance_number>

add a LV2 plugin encapsulated as a jack client

e.g.:

add http://lv2plug.in/plugins/eg-amp 0

instance_number must be any value between 0 ~ 9999, inclusively

Parameters:effect (Lv2Effect) – Effect will be added
static bypass(effect)[source]

bypass <instance_number> <bypass_value>

toggle plugin processing

e.g.:

bypass 0 1
  • if bypass_value = 1 bypass plugin
  • if bypass_value = 0 process plugin
Parameters:effect (Lv2Effect) – Effect that will be active the bypass or disable the bypass
static connect(connection)[source]

connect <origin_port> <destination_port>

connect two plugin audio ports

e.g.:

connect system:capture_1 plugin_0:in
Parameters:connection (pluginsmanager.model.connection.Connection) – Connection with a valid Output and Input
static disconnect(connection)[source]

disconnect <origin_port> <destination_port>

disconnect two plugin audio ports

e.g.:

disconnect system:capture_1 plugin_0:in
Parameters:connection (pluginsmanager.model.connection.Connection) – Connection with a valid Output and Input
static help()[source]

help

show a help message

static load(filename)[source]

load <file_name>

load a history command file dummy way to save/load workspace state

e.g.:

load my_setup

Note

Not implemented yet

static midi_learn(self, plugin, param)[source]

midi_learn <instance_number> <param_symbol>

This command maps starts MIDI learn for a parameter

e.g.:

midi_learn 0 gain

Note

Not implemented yet

static midi_map(plugin, param, midi_chanel, midi_cc)[source]

midi_map <instance_number> <param_symbol> <midi_channel> <midi_cc>

This command maps a MIDI controller to a parameter

e.g.:

midi_map 0 gain 0 7

Note

Not implemented yet

static midi_unmap(plugin, param)[source]

midi_unmap <instance_number> <param_symbol>

This command unmaps the MIDI controller from a parameter

e.g.:

unmap 0 gain

Note

Not implemented yet

static monitor()[source]

monitor <addr> <port> <status>

open a socket port to monitoring parameters

e.g.:

monitor localhost 12345 1
  • if status = 1 start monitoring
  • if status = 0 stop monitoring

Note

Not implemented yet

static param_get(param)[source]

param_get <instance_number> <param_symbol>

get the value of the request control

e.g.:

param_get 0 gain
Parameters:param (Lv2Param) – Parameter that will be get your current value
static param_monitor()[source]

param_monitor <instance_number> <param_symbol> <cond_op> <value>

do monitoring a plugin instance control port according given condition

e.g.:

param_monitor 0 gain > 2.50

Note

Not implemented yet

static param_set(param)[source]

param_set <instance_number> <param_symbol> <param_value>

set a value to given control

e.g.:

param_set 0 gain 2.50
Parameters:param (Lv2Param) – Parameter that will be updated your value
static preset_load()[source]

preset_load <instance_number> <preset_uri>

load a preset state to given plugin instance

e.g.:

preset_load 0 "http://drobilla.net/plugins/mda/presets#JX10-moogcury-lite"

Note

Not implemented yet

static preset_save()[source]

preset_save <instance_number> <preset_name> <dir> <file_name>

save a preset state from given plugin instance

e.g.:

preset_save 0 "My Preset" /home/user/.lv2/my-presets.lv2 mypreset.ttl

Note

Not implemented yet

static preset_show()[source]

preset_show <instance_number> <preset_uri>

show the preset information of requested instance / URI

e.g.:

preset_show 0 http://drobilla.net/plugins/mda/presets#EPiano-bright

Note

Not implemented yet

static quit()[source]

quit

bye!

static remove(effect)[source]

remove <instance_number>

remove a LV2 plugin instance (and also the jack client)

e.g.:

remove 0
Parameters:effect (Lv2Effect) – Effect will be removed
static save(filename)[source]

save <file_name>

saves the history of typed commands dummy way to save/load workspace state

e.g.:

save my_setup

Note

Not implemented yet

PedalPi - PluginsManager - Carla

It is in alpha, some methods aren’t implemented, as effects connection and disconnection.

About Carla

In development

Carla
class pluginsmanager.observer.carla.carla.Carla(path)[source]
Python port for carla
Carla is a fully-featured audio plugin host, with support for many audio drivers and plugin formats. It’s open source and licensed under the GNU General Public License, version 2 or later.

This class offers the Carla control in a python API:

# Create a carla, connect and register it in banks_manager
host = Carla('localhost')
host.connect()
banks_manager.register(host)

# Set the carla.pedalboard for a pedalboard that the bank
# has added in banks_manager
host.pedalboard = my_awesome_pedalboard

The changes in current pedalboard (pedalboard attribute of carla) will also result in carla host:

driver = my_awesome_pedalboard.effects[0]
driver.active = False

Note

For use, is necessary that the carla is running, for use, access

  • Install dependencies
  • Building Carla
  • Running Carla

For more JACK information, access Demystifying JACK – A Beginners Guide to Getting Started with JACK

Example:

In this example, is starting a Zoom G3 series audio interface. Others interfaces maybe needs others configurations.
# Starting jackdump process via console
jackd -R -P70 -t2000 -dalsa -dhw:Series -p256 -n3 -r44100 -s &
# Starting carla host
# FIXME
Parameters:path (Path) – Path that carla are persisted.
__init__(path)[source]

Initialize self. See help(type(self)) for accurate signature.

CarlaError
class pluginsmanager.observer.carla.carla.CarlaError[source]

PedalPi - PluginsManager - Models

This page contains the model classes.

digraph classes {
     graph [rankdir=BT];

     node [shape=rect, style=filled, color="#298029", fontname=Sans, fontcolor="#ffffff", fontsize=10];

     Pedalboard->Bank [
         dir="forward", arrowhead="odiamond", arrowtail="normal"
     ];
     Effect->Pedalboard [
         dir="forward", arrowhead="odiamond", arrowtail="normal"
     ];
     Param->Effect [
         dir="backward", arrowhead="diamond", arrowtail="normal"
     ];
     Connection->Pedalboard [
         dir="forward", arrowhead="odiamond", arrowtail="normal"
     ];
     Input->Effect [
         dir="backward", arrowhead="diamond", arrowtail="normal"
     ];
     Output->Effect [
        dir="backward", arrowhead="diamond", arrowtail="normal"
     ];

     Input->Connection [
         dir="backward", arrowhead="odiamond", arrowtail="normal"
     ];
     Output->Connection [
         dir="backward", arrowhead="odiamond", arrowtail="normal"
     ];
}
digraph classes {
    graph [rankdir=BT];
    node [shape=rect, style=filled, color="#298029", fontname=Sans, fontcolor="#ffffff", fontsize=10];

    AudioPort->Port;

    Input->AudioPort;
    Output->AudioPort;

    MidiPort->Port;
    MidiInput->MidiPort;
    MidiOutput->MidiPort;

    Lv2Input->Input;
    Lv2Output->Output;
    Lv2MidiInput->MidiInput;
    Lv2MidiOutput->MidiOutput;

    SystemInput->Input;
    SystemOutput->Output;
    SystemMidiInput->MidiInput;
    SystemMidiOutput->MidiOutput;

}
digraph classes {
    graph [rankdir=BT];
    node [shape=rect, style=filled, color="#298029", fontname=Sans, fontcolor="#ffffff", fontsize=10];

    Lv2Effect->Lv2Plugin[
        dir="backward", arrowhead="diamond", arrowtail="normal"
    ];
    Lv2Effect->Effect;
    SystemEffect->Effect;

    Lv2Param->Param;

    MidiConnection->Connection;
}
digraph classes {
    graph [rankdir=BT];
    node [shape=rect, style=filled, color="#298029", fontname=Sans, fontcolor="#ffffff", fontsize=10];

    Bank->BanksManager [dir="forward", arrowhead="odiamond", arrowtail="normal"];
    BanksManager->ObserverManager [dir="forward", arrowhead="none", arrowtail="normal"];
    UpdatesObserver->ObserverManager [dir="forward", arrowhead="odiamond", arrowtail="normal"];
    ModHost->UpdatesObserver
    AutoSaver->UpdatesObserver
}

BanksManager

class pluginsmanager.banks_manager.BanksManager(banks=None)[source]

BanksManager manager the banks. In these is possible add banks, obtains the banks and register observers for will be notified when occurs changes (like added new pedalboard, rename bank, set effect param value or state)

For use details, view Readme.rst example documentation.

Parameters:banks (list[Bank]) – Banks that will be added in this. Useful for loads banks previously loaded, like banks persisted and recovered.
__init__(banks=None)[source]

Initialize self. See help(type(self)) for accurate signature.

__iter__()[source]

Iterates banks of the banksmanager:

>>> banks_manager = BanksManager()
>>> for index, bank in enumerate(banks_manager):
...     print(index, '-', bank)
Returns:Iterator for banks list
append(bank)[source]

Append the bank in banks manager. It will be monitored, changes in this will be notified for the notifiers.

Parameters:bank (Bank) – Bank that will be added in this
enter_scope(observer)[source]

Informs that changes occurs by the observer and isn’t necessary informs the changes for observer

Parameters:observer (UpdatesObserver) – Observer that causes changes
exit_scope()[source]

Closes the last observer scope added

observers
Returns:Observers registered in BanksManager instance
register(observer)[source]

Register an observer for it be notified when occurs changes.

For more details, see UpdatesObserver

Parameters:observer (UpdatesObserver) – Observer that will be notified then occurs changes
unregister(observer)[source]

Remove the observers of the observers list. It will not receive any more notifications when occurs changes.

Parameters:observer (UpdatesObserver) – Observer you will not receive any more notifications then occurs changes.

Bank

class pluginsmanager.model.bank.Bank(name)[source]

Bank is a data structure that contains Pedalboard. It’s useful for group common pedalboards, like “Pedalboards will be used in the Sunday show”

A fast bank overview:

>>> bank = Bank('RHCP')
>>> californication = Pedalboard('Californication')
>>> # Add pedalboard in bank - mode A
>>> bank.append(californication)
>>> californication.bank == bank
True
>>> bank.pedalboards[0] == californication
True
>>> # Add pedalboard in bank - mode B
>>> bank.pedalboards.append(Pedalboard('Dark Necessities'))
>>> bank.pedalboards[1].bank == bank
True
>>> # If you needs change pedalboards order (swap), use pythonic mode
>>> bank.pedalboards[1], bank.pedalboards[0] = bank.pedalboards[0], bank.pedalboards[1]
>>> bank.pedalboards[1] == californication
True
>>> # Set pedalboard
>>> bank.pedalboards[0] = Pedalboard("Can't Stop")
>>> bank.pedalboards[0].bank == bank
True
>>> del bank.pedalboards[0]
>>> bank.pedalboards[0] == californication # Pedalboard Can't stop rermoved, first is now the californication
True

You can also toggle pedalboards into different banks:

>>> bank1.pedalboards[0], bank2.pedalboards[2] = bank2.pedalboards[0], bank1.pedalboards[2]
Parameters:name (string) – Bank name
__init__(name)[source]

Initialize self. See help(type(self)) for accurate signature.

append(pedalboard)[source]

Add a Pedalboard in this bank

This works same as:

>>> bank.pedalboards.append(pedalboard)

or:

>>> bank.pedalboards.insert(len(bank.pedalboards), pedalboard)
Parameters:pedalboard (Pedalboard) – Pedalboard that will be added
index

Returns the first occurrence of the bank in your PluginsManager

json

Get a json decodable representation of this bank

Return dict:json representation
name

Bank name

Getter:Bank name
Setter:Set the Bank name
Type:string
simple_identifier

Simple identifier for index file human comprehension and reordering :return string:

Pedalboard

class pluginsmanager.model.pedalboard.Pedalboard(name)[source]

Pedalboard is a patch representation: your structure contains Effect and Connection:

>>> pedalboard = Pedalboard('Rocksmith')
>>> bank.append(pedalboard)

>>> builder = Lv2EffectBuilder()
>>> pedalboard.effects
[]
>>> reverb = builder.build('http://calf.sourceforge.net/plugins/Reverb')
>>> pedalboard.append(reverb)
>>> pedalboard.effects
[<Lv2Effect object as 'Calf Reverb'  active at 0x7f60effb09e8>]

>>> fuzz = builder.build('http://guitarix.sourceforge.net/plugins/gx_fuzzfacefm_#_fuzzfacefm_')
>>> pedalboard.effects.append(fuzz)

>>> pedalboard.connections
[]
>>> pedalboard.connections.append(Connection(sys_effect.outputs[0], fuzz.inputs[0])) # View SystemEffect for more details
>>> pedalboard.connections.append(Connection(fuzz.outputs[0], reverb.inputs[0]))
>>> # It works too
>>> pedalboard.connect(reverb.outputs[1], sys_effect.inputs[0])
>>> pedalboard.connections
[<Connection object as 'system.capture_1 -> GxFuzzFaceFullerMod.In' at 0x7f60f45f3f60>, <Connection object as 'GxFuzzFaceFullerMod.Out -> Calf Reverb.In L' at 0x7f60f45f57f0>, <Connection object as 'Calf Reverb.Out R -> system.playback_1' at 0x7f60f45dacc0>]

>>> pedalboard.data
{}
>>> pedalboard.data = {'my-awesome-component': True}
>>> pedalboard.data
{'my-awesome-component': True}

For load the pedalboard for play the songs with it:

>>> mod_host.pedalboard = pedalboard

All changes¹ in the pedalboard will be reproduced in mod-host. ¹ Except in data attribute, changes in this does not interfere with anything.

Parameters:name (string) – Pedalboard name
__init__(name)[source]

Initialize self. See help(type(self)) for accurate signature.

append(effect)[source]

Add a Effect in this pedalboard

This works same as:

>>> pedalboard.effects.append(effect)

or:

>>> pedalboard.effects.insert(len(pedalboard.effects), effect)
Parameters:effect (Effect) – Effect that will be added
connect(output_port, input_port)[source]

Connect two Effect instances in this pedalboard. For this, is necessary informs the output port origin and the input port destination:

>>> pedalboard.append(driver)
>>> pedalboard.append(reverb)
>>> driver_output = driver.outputs[0]
>>> reverb_input = reverb.inputs[0]
>>> Connection(driver_output, reverb_input) in driver.connections
False
>>> pedalboard.connect(driver_output, reverb_input)
>>> Connection(driver_output, reverb_input) in driver.connections
True
Parameters:
  • output_port (Port) – Effect output port
  • input_port (Port) – Effect input port
connections

Return the pedalboard connections list

Note

Because the connections is an ObservableList, it isn’t settable. For replace, del the connections unnecessary and add the necessary connections

data

Custom information about pedalboard that is necessary to be persisted. Example is effects disposition in a visual modelling pedalboard.

Note

This operation only will notifies changes if the setter is called:

>>> data = {'level': 50}
>>> # This call the observer on_custom_change(CustomChange.PEDALBOARD_DATA, UpdateType.UPDATED, pedalboard=pedalboard)
>>> pedalboard.data = data
>>> # This doesn't call the observer on_custom_change(...)
>>> data['level'] = 80
>>> # But this call, even though the object is the same.
>>> pedalboard.data = data
Getter:Data
Setter:Set the data
Type:dict
disconnect(output_port, input_port)[source]

Remove a connection between (two ports of) Effect instances. For this, is necessary informs the output port origin and the input port destination:

>>> pedalboard.append(driver)
>>> pedalboard.append(reverb)
>>> driver_output = driver.outputs[0]
>>> reverb_input = reverb.inputs[0]
>>> pedalboard.connect(driver_output, reverb_input)
>>> Connection(driver_output, reverb_input) in driver.connections
True
>>> pedalboard.disconnect(driver_output, reverb_input)
>>> Connection(driver_output, reverb_input) in driver.connections
False
Parameters:
  • output_port (Port) – Effect output port
  • input_port (Port) – Effect input port
effects

Return the effects presents in the pedalboard

Note

Because the effects is an ObservableList, it isn’t settable. For replace, del the effects unnecessary and add the necessary effects

index

Returns the first occurrence of the pedalboard in your bank

json

Get a json decodable representation of this pedalboard

Return dict:json representation
name

Pedalboard name

Getter:Pedalboard name
Setter:Set the pedalboard name
Type:string

Connection

class pluginsmanager.model.connection.Connection(output_port, input_port)[source]

Connection represents a connection between two distinct effects by your AudioPort (effect Output with effect Input):

>>> from pluginsmanager.model.pedalboard import Pedalboard
>>> californication = Pedalboard('Californication')
>>> californication.append(driver)
>>> californication.append(reverb)
>>> guitar_output = sys_effect.outputs[0]
>>> driver_input = driver.inputs[0]
>>> driver_output = driver.outputs[0]
>>> reverb_input = reverb.inputs[0]
>>> reverb_output = reverb.outputs[0]
>>> amp_input = sys_effect.inputs[0]
>>> # Guitar -> driver -> reverb -> amp
>>> californication.connections.append(Connection(guitar_output, driver_input))
>>> californication.connections.append(Connection(driver_output, reverb_input))
>>> californication.connections.append(Connection(reverb_output, amp_input))

Another way to use implicitly connections:

>>> californication.connect(guitar_output, driver_input)
>>> californication.connect(driver_output, reverb_input)
>>> californication.connect(reverb_output, amp_input)
Parameters:
  • output_port (Output) – Audio output port that will be connected with audio input port
  • input_port (Input) – Audio input port that will be connected with audio output port
__eq__(other)[source]

Return self==value.

__hash__()[source]

Return hash(self).

__init__(output_port, input_port)[source]

Initialize self. See help(type(self)) for accurate signature.

__repr__()[source]

Return repr(self).

input
Return Output:Input connection port
json

Get a json decodable representation of this effect

Return dict:json representation
output
Return Output:Output connection port
ports_class
Return class:Port class that this connection only accepts

MidiConnection

class pluginsmanager.model.midi_connection.MidiConnection(output_port, input_port)[source]

MidiConnection represents a connection between two distinct effects by your MidiPort (effect MidiOutput with effect MidiInput):

>>> californication = Pedalboard('Californication')
>>> californication.append(driver)
>>> californication.append(reverb)
>>> output_port = cctonode1.midi_outputs[0]
>>> input_port = cctonode2.midi_inputs[0]
>>> californication.connections.append(MidiConnection(output_port, input_port))

Another way to use implicitly connections:

>>> californication.connect(output_port, input_port)
Parameters:
  • output_port (MidiOutput) – MidiOutput port that will be connected with midi input port
  • input_port (MidiInput) – MidiInput port that will be connected with midi output port
ports_class
Return class:Port class that this connection only accepts

ConnectionsList

class pluginsmanager.model.connections_list.ConnectionsList(pedalboard)[source]

ConnectionsList contains a ObservableList and checks the effect instance unity restrictions

__init__(pedalboard)[source]

Initialize self. See help(type(self)) for accurate signature.

Effect

class pluginsmanager.model.effect.Effect[source]

Representation of a audio plugin instance - LV2 plugin encapsulated as a jack client.

Effect contains a active status (off=bypass), a list of Param, a list of Input and a list of Connection:

>>> reverb = builder.build('http://calf.sourceforge.net/plugins/Reverb')
>>> pedalboard.append(reverb)
>>> reverb
<Lv2Effect object as 'Calf Reverb' active at 0x7fd58d874ba8>

>>> reverb.active
True
>>> reverb.toggle()
>>> reverb.active
False
>>> reverb.active = True
>>> reverb.active
True

>>> reverb.inputs
(<Lv2Input object as In L at 0x7fd58c583208>, <Lv2Input object as In R at 0x7fd58c587320>)
>>> reverb.outputs
(<Lv2Output object as Out L at 0x7fd58c58a438>, <Lv2Output object as Out R at 0x7fd58c58d550>)
>>> reverb.params
(<Lv2Param object as value=1.5 [0.4000000059604645 - 15.0] at 0x7fd587f77908>, <Lv2Param object as value=5000.0 [2000.0 - 20000.0] at 0x7fd587f7a9e8>, <Lv2Param object as value=2 [0 - 5] at 0x7fd587f7cac8>, <Lv2Param object as value=0.5 [0.0 - 1.0] at 0x7fd587f7eba8>, <Lv2Param object as value=0.25 [0.0 - 2.0] at 0x7fd58c576c88>, <Lv2Param object as value=1.0 [0.0 - 2.0] at 0x7fd58c578d68>, <Lv2Param object as value=0.0 [0.0 - 500.0] at 0x7fd58c57ae80>, <Lv2Param object as value=300.0 [20.0 - 20000.0] at 0x7fd58c57df98>, <Lv2Param object as value=5000.0 [20.0 - 20000.0] at 0x7fd58c5810f0>)
Parameters:pedalboard (Pedalboard) – Pedalboard where the effect lies.
__init__()[source]

Initialize self. See help(type(self)) for accurate signature.

__repr__()[source]

Return repr(self).

active

Effect status: active or bypass

Getter:Current effect status
Setter:Set the effect Status
Type:bool
connections
Return list[Connection]:
 Connections that this effects is present (with input or output port)
index

Returns the first occurrence of the effect in your pedalboard

inputs
Return list[Input]:
 Inputs of effect
is_possible_connect_itself

return bool: Is possible connect the with it self?

is_unique_for_all_pedalboards
return bool: Is unique for all pedalboards?
Example: SystemEffect is unique for all pedalboards
json

Get a json decodable representation of this effect

Return dict:json representation
midi_inputs
Return list[MidiInput]:
 MidiInputs of effect
midi_outputs
Return list[MidiOutput]:
 MidiOutputs of effect
outputs
Return list[Output]:
 Outputs of effect
params
Return list[Param]:
 Params of effect
toggle()[source]

Toggle the effect status: self.active = not self.active

use_real_identifier

Instances of audio plugins are dynamically created, so the effect identifier for the jack can be set.

However, SystemEffect correspond (mostly) to the audio interfaces already present in the computational system. The identifier for their jack has already been set.

return bool: For this audio plugin, is necessary use the real effect identifier?
Example: Lv2Effect is False Example: SystemEffect is True
version
Return string:Effect version

EffectsList

class pluginsmanager.model.effects_list.EffectsList[source]

EffectsList contains a ObservableList and checks the effect instance unity restrictions

Port

class pluginsmanager.model.port.Port(effect)[source]

Port is a parent abstraction for inputs and outputs

Parameters:effect (Effect) – Effect that contains port
__init__(effect)[source]

Initialize self. See help(type(self)) for accurate signature.

__repr__()[source]

Return repr(self).

connection_class
Returns:Class used for connections in this port
effect
Returns:Effect that this port is related
index
Returns:Index in the effect related based in your category. As example, if this port is a input, the index returns your position in the inputs ports.
json

Get a json decodable representation

Return dict:json representation
symbol
Returns:Identifier for this port

AudioPort

class pluginsmanager.model.audio_port.AudioPort(effect)[source]

Port is a parent abstraction for audio inputs and audio outputs

connection_class
Return Connection:
 Class used for connections in this port

Input

class pluginsmanager.model.input.Input(effect)[source]

Input is the medium in which the audio will go into effect to be processed.

Effects usually have a one (mono) or two inputs (stereo L + stereo R). But this isn’t a rule: Some have only Output, like audio frequency generators, others have more than two.

For obtains the inputs:

>>> my_awesome_effect
<Lv2Effect object as 'Calf Reverb' active at 0x7fd58d874ba8>
>>> my_awesome_effect.inputs
(<Lv2Input object as In L at 0x7fd58c583208>, <Lv2Input object as In R at 0x7fd58c587320>)

>>> effect_input = my_awesome_effect.inputs[0]
>>> effect_input
<Lv2Input object as In L at 0x7fd58c583208>

>>> symbol = effect_input.symbol
>>> symbol
'in_l'

>>> my_awesome_effect.inputs[symbol] == effect_input
True

For connections between effects, see connect() and disconnect() Pedalboard class methods.

Parameters:effect (Effect) – Effect of input
index
Returns:Input index in the your effect

Output

class pluginsmanager.model.output.Output(effect)[source]

Output is the medium in which the audio processed by the effect is returned.

Effects usually have a one (mono) or two outputs (stereo L + stereo R). .

For obtains the outputs:

>>> my_awesome_effect
<Lv2Effect object as 'Calf Reverb' active at 0x7fd58d874ba8>
>>> my_awesome_effect.outputs
(<Lv2Output object as Out L at 0x7fd58c58a438>, <Lv2Output object as Out R at 0x7fd58c58d550>)

>>> output = my_awesome_effect.outputs[0]
>>> output
<Lv2Output object as Out L at 0x7fd58c58a438>

>>> symbol = my_awesome_effect.outputs[0].symbol
>>> symbol
'output_l'

>>> my_awesome_effect.outputs[symbol] == output
True

For connections between effects, see connect() and disconnect() Pedalboard class methods.

Parameters:effect (Effect) – Effect that contains the output
index
Returns:Output index in the your effect

MidiPort

class pluginsmanager.model.midi_port.MidiPort(effect)[source]

Port is a parent abstraction for midi inputs and midi outputs

connection_class
Return MidiConnection:
 Class used for connections in this port

MidiInput

class pluginsmanager.model.midi_input.MidiInput(effect)[source]

MidiInput is the medium in which the midi input port will go into effect to be processed.

For obtains the inputs:

>>> cctonode
<Lv2Effect object as 'CC2Note'  active at 0x7efe5480af28>
>>> cctonode.midi_inputs
(<Lv2MidiInput object as MIDI In at 0x7efe54535dd8>,)

>>> midi_input = cctonode.midi_inputs[0]
>>> midi_input
<Lv2MidiInput object as MIDI In at 0x7efe54535dd8>

>>> symbol = midi_input.symbol
>>> symbol
'midiin'

>>> cctonode.midi_inputs[symbol] == midi_input
True

For connections between effects, see connect() and disconnect() Pedalboard class methods.

Parameters:effect (Effect) – Effect of midi input
index
Returns:MidiInput index in the your effect

MidiOutput

class pluginsmanager.model.midi_output.MidiOutput(effect)[source]

MidiOutput is the medium in which the midi output processed by the effect is returned.

For obtains the outputs:

>>> cctonode
<Lv2Effect object as 'CC2Note'  active at 0x7efe5480af28>
>>> cctonode.outputs
(<Lv2MidiOutput object as MIDI Out at 0x7efe5420eeb8>,)

>>> midi_output = cctonode.midi_outputs[0]
>>> midi_output
<Lv2Output object as Out L at 0x7fd58c58a438>

>>> symbol = midi_output.symbol
>>> symbol
'midiout'

>>> cctonode.midi_outputs[symbol] == midi_output
True

For connections between effects, see connect() and disconnect() Pedalboard class methods.

Parameters:effect (Effect) – Effect that contains the output
index
Returns:Output index in the your effect

Param

class pluginsmanager.model.param.Param(effect, default)[source]

Param represents an Audio Plugin Parameter:

>>> my_awesome_effect
<Lv2Effect object as 'Calf Reverb' active at 0x7fd58d874ba8>
>>> my_awesome_effect.params
(<Lv2Param object as value=1.5 [0.4000000059604645 - 15.0] at 0x7fd587f77908>, <Lv2Param object as value=5000.0 [2000.0 - 20000.0] at 0x7fd587f7a9e8>, <Lv2Param object as value=2 [0 - 5] at 0x7fd587f7cac8>, <Lv2Param object as value=0.5 [0.0 - 1.0] at 0x7fd587f7eba8>, <Lv2Param object as value=0.25 [0.0 - 2.0] at 0x7fd58c576c88>, <Lv2Param object as value=1.0 [0.0 - 2.0] at 0x7fd58c578d68>, <Lv2Param object as value=0.0 [0.0 - 500.0] at 0x7fd58c57ae80>, <Lv2Param object as value=300.0 [20.0 - 20000.0] at 0x7fd58c57df98>, <Lv2Param object as value=5000.0 [20.0 - 20000.0] at 0x7fd58c5810f0>)

>>> param = my_awesome_effect.params[0]
>>> param
<Lv2Param object as value=1.5 [0.4000000059604645 - 15.0] at 0x7fd587f77908>

>>> param.default
1.5
>>> param.value = 14

>>> symbol = param.symbol
>>> symbol
'decay_time'
>>> param == my_awesome_effect.params[symbol]
True
Parameters:
  • effect (Effect) – Effect in which this parameter belongs
  • default – Default value (initial value parameter)
__init__(effect, default)[source]

Initialize self. See help(type(self)) for accurate signature.

__repr__(*args, **kwargs)[source]

Return repr(self).

default

Default parameter value. Then a effect is instanced, the value initial for a parameter is your default value.

Getter:Default parameter value.
effect
Returns:Effect in which this parameter belongs
json

Get a json decodable representation of this param

Return dict:json representation
maximum
Returns:Greater value that the parameter can assume
minimum
Returns:Smaller value that the parameter can assume
symbol
Returns:Param identifier
value

Parameter value

Getter:Current value
Setter:Set the current value

PedalPi - PluginsManager - Model - Lv2

Lv2EffectBuilder

class pluginsmanager.model.lv2.lv2_effect_builder.Lv2EffectBuilder(plugins_json=None, ignore_unsupported_plugins=True)[source]

Generates lv2 audio plugins instance (as Lv2Effect object).

Note

In the current implementation, the data plugins are persisted in plugins.json.

Parameters:
  • plugins_json (Path) – Plugins json path file
  • ignore_unsupported_plugins (bool) – Not allows instantiation of uninstalled or unrecognized audio plugins?
__init__(plugins_json=None, ignore_unsupported_plugins=True)[source]

Initialize self. See help(type(self)) for accurate signature.

build(lv2_uri)[source]

Returns a new Lv2Effect by the valid lv2_uri

Parameters:lv2_uri (string) –
Return Lv2Effect:
 Effect created
lv2_plugins_data()[source]

Generates a file with all plugins data info. It uses the lilvlib library.

PluginsManager can manage lv2 audio plugins through previously obtained metadata from the lv2 audio plugins descriptor files.

To speed up usage, data has been pre-generated and loaded into this piped packet. This avoids a dependency installation in order to obtain the metadata.

However, this measure makes it not possible to manage audio plugins that were not included in the list.

To work around this problem, this method - using the lilvlib library - can get the information from the audio plugins. You can use this data to generate a file containing the settings:

>>> builder = Lv2EffectBuilder()
>>> plugins_data = builder.lv2_plugins_data()

>>> import json
>>> with open('plugins.json', 'w') as outfile:
>>>     json.dump(plugins_data, outfile)

The next time you instantiate this class, you can pass the configuration file:

>>> builder = Lv2EffectBuilder(os.path.abspath('plugins.json'))

Or, if you want to load the data without having to create a new instance of this class:

>>> builder.reload(builder.lv2_plugins_data())

Warning

To use this method, it is necessary that the system has the lilv in a version equal to or greater than 0.22.0. Many linux systems currently have previous versions on their package lists, so you need to compile them manually.

In order to ease the work, Pedal Pi has compiled lilv for some versions of linux. You can get the list of .deb packages in https://github.com/PedalPi/lilvlib/releases.

# Example
wget https://github.com/PedalPi/lilvlib/releases/download/v1.0.0/python3-lilv_0.22.1.git20160613_amd64.deb
sudo dpkg -i python3-lilv_0.22.1+git20160613_amd64.deb

If the architecture of your computer is not contemplated, moddevices provided a script to generate the package. Go to https://github.com/moddevices/lilvlib to get the script in its most up-to-date version.

Return list:lv2 audio plugins metadata
plugins_json_file = '/home/docs/checkouts/readthedocs.org/user_builds/pedalpi-pluginsmanager/checkouts/latest/pluginsmanager/model/lv2/plugins.json'

Informs the path of the plugins.json file. This file contains the lv2 plugins metadata info

reload(metadata, ignore_unsupported_plugins=True)[source]

Loads the metadata. They will be used so that it is possible to generate lv2 audio plugins.

Parameters:
  • metadata (list) – lv2 audio plugins metadata
  • ignore_unsupported_plugins (bool) – Not allows instantiation of uninstalled or unrecognized audio plugins?

Lv2Effect

class pluginsmanager.model.lv2.lv2_effect.Lv2Effect(plugin)[source]

Representation of a Lv2 audio plugin instance.

For general effect use, see Effect class documentation.

It’s possible obtains the Lv2Plugin information:

>>> reverb
<Lv2Effect object as 'Calf Reverb'  active at 0x7f60effb09e8>
>>> reverb.plugin
<Lv2Plugin object as Calf Reverb at 0x7f60effb9940>
Parameters:plugin (Lv2Plugin) –
__init__(plugin)[source]

Initialize self. See help(type(self)) for accurate signature.

__repr__()[source]

Return repr(self).

__str__()[source]

Return str(self).

version
Return string:Version of plugin of effect

Lv2Input

class pluginsmanager.model.lv2.lv2_input.Lv2Input(effect, data)[source]

Representation of a Lv2 input audio port instance.

For general input use, see Input class documentation.

Parameters:
  • effect (Lv2Effect) – Effect that contains the input
  • data (dict) – input audio port json representation
__init__(effect, data)[source]

Initialize self. See help(type(self)) for accurate signature.

data
Return dict:Metadata used for provide the required information

in this object

Lv2Output

class pluginsmanager.model.lv2.lv2_output.Lv2Output(effect, data)[source]

Representation of a Lv2 output audio port instance.

For general input use, see Output class documentation.

Parameters:
  • effect (Lv2Effect) – Effect that contains the output
  • data (dict) – output audio port json representation
__init__(effect, data)[source]

Initialize self. See help(type(self)) for accurate signature.

data
Return dict:Metadata used for provide the required information

in this object

Lv2Param

class pluginsmanager.model.lv2.lv2_param.Lv2Param(effect, data)[source]

Representation of a Lv2 input control port instance.

For general input use, see Param class documentation.

Parameters:
  • effect (Lv2Effect) – Effect that contains the param
  • data (dict) – input control port json representation
__init__(effect, data)[source]

Initialize self. See help(type(self)) for accurate signature.

maximum
Returns:Greater value that the parameter can assume
minimum
Returns:Smaller value that the parameter can assume
symbol
Returns:Param identifier

Lv2Plugin

class pluginsmanager.model.lv2.lv2_plugin.Lv2Plugin(json)[source]
__getitem__(key)[source]
Parameters:key (string) – Property key
Returns:Returns a Plugin property
__init__(json)[source]

Initialize self. See help(type(self)) for accurate signature.

__repr__()[source]

Return repr(self).

__str__()[source]

Return str(self).

data
Returns:Json decodable representation of this plugin based in moddevices lilvlib.
json
Returns:Json decodable representation of this plugin based in moddevices lilvlib.

PedalPi - PluginsManager - Model - System

SystemEffectBuilder

class pluginsmanager.model.system.system_effect_builder.SystemEffectBuilder(jack_client)[source]

Automatic system physical ports detection.

Maybe the midi ports not will recognize. In these cases, you need to start a2jmidid to get MIDI-ALSA ports automatically mapped to JACK-MIDI ports.

Parameters:jack_client (JackClient) – JackClient instance that will get the information to generate SystemEffect
__init__(jack_client)[source]

Initialize self. See help(type(self)) for accurate signature.

SystemEffect

class pluginsmanager.model.system.system_effect.SystemEffect(representation, outputs=None, inputs=None, midi_outputs=None, midi_inputs=None)[source]

Representation of the system instance: audio and/or midi interfaces.

System output is equivalent with audio input: You connect the instrument in the audio card input and it captures and send the audio to SystemOutput for you connect in a input plugins.

System input is equivalent with audio output: The audio card receives the audio processed in your SystemInput and send it to audio card output for you connects in amplifier, headset.

Because no autodetection of existing ports in audio card has been implemented, you must explicitly inform in the creation of the SystemEffect object:

>>> sys_effect = SystemEffect('system', ('capture_1', 'capture_2'), ('playback_1', 'playback_2'))

Unlike effects that should be added in the pedalboard, SystemEffects MUST NOT:

>>> builder = Lv2EffectBuilder()
>>> pedalboard = Pedalboard('Rocksmith')
>>> reverb = builder.build('http://calf.sourceforge.net/plugins/Reverb')
>>> pedalboard.append(reverb)

However the pedalboard must have the connections:

>>> pedalboard.connect(sys_effect.outputs[0], reverb.inputs[0])

An bypass example:

>>> pedalboard = Pedalboard('Bypass example')
>>> sys_effect = SystemEffect('system', ('capture_1', 'capture_2'), ('playback_1', 'playback_2'))
>>> pedalboard.connect(sys_effect.outputs[0], sys_effect.inputs[0])
>>> pedalboard.connect(sys_effect.outputs[1], sys_effect.inputs[1])

You can create multiple SystemEffect for multiple audio/midi interfaces. In the following example, exists Jack provides audio system ports and two midi ports are added by I/O ports:

>>> audio_system = SystemEffect('system', inputs=['playback_1', 'playback_2'])
>>> midi_system = SystemEffect('ttymidi', midi_outputs=['MIDI_in'], midi_inputs=['MIDI_out'])
>>> pedalboard = Pedalboard('MDA-EP')
>>> ep = builder.build('http://moddevices.com/plugins/mda/EPiano')
>>> pedalboard.connect(ep.outputs[0], audio_system.inputs[0])
>>> pedalboard.connect(ep.outputs[1], audio_system.inputs[1])
>>> pedalboard.connect(audio_system.midi_outputs[0], ep.midi_inputs[0])

You can check the audio/midi ports defined in your environment using jack_lsp:

root@zynthian:~ # As example in Zynthian project: http://zynthian.org
root@zynthian:~ jack_lsp -A
system:playback_1
   alsa_pcm:hw:0:in1
system:playback_2
   alsa_pcm:hw:0:in2
ttymidi:MIDI_in
ttymidi:MIDI_out
Zyncoder:output
Zyncoder:input

If you prefer, you can use a unique SystemEffect if alias the ports:

localhost@localdomain:~ jack_alias system:midi_capture1 ttymidi:MIDI_in
localhost@localdomain:~ jack_alias system:midi_playback1 ttymidi:MIDI_out
>>> sys_effect = SystemEffect(
...     'system',
...     inputs=['playback_1', 'playback_2'],
...     midi_outputs=['midi_capture1'],
...     midi_inputs=['midi_playback1']
... )
>>> pedalboard = Pedalboard('MDA-EP')
>>> ep = builder.build('http://moddevices.com/plugins/mda/EPiano')
>>> pedalboard.connect(ep.outputs[0], sys_effect.inputs[0])
>>> pedalboard.connect(ep.outputs[1], sys_effect.inputs[1])
>>> pedalboard.connect(sys_effect.midi_outputs[0], ep.midi_inputs[0])
Parameters:
  • representation (string) – Audio card representation. Usually ‘system’
  • outputs (tuple(string)) – Tuple of outputs representation. Usually a output representation starts with capture_
  • inputs (tuple(string)) – Tuple of inputs representation. Usually a input representation starts with playback_
  • midi_outputs (tuple(string)) – Tuple of midi outputs representation.
  • midi_inputs (tuple(string)) – Tuple of midi inputs representation.
__init__(representation, outputs=None, inputs=None, midi_outputs=None, midi_inputs=None)[source]

Initialize self. See help(type(self)) for accurate signature.

__str__()[source]

Return str(self).

is_possible_connect_itself

return bool: Is possible connect the with it self?

is_unique_for_all_pedalboards
return bool: Is unique for all pedalboards?
Example: SystemEffect is unique for all pedalboards
use_real_identifier

return bool: For this audio plugin, is necessary use the real effect identifier?

SystemInput

class pluginsmanager.model.system.system_input.SystemInput(effect, symbol)[source]

Representation of a System input audio port instance.

For general input use, see Input class documentation.

Parameters:
  • effect (SystemEffect) – Effect that contains the input
  • symbol (string) – input audio port symbol identifier
__init__(effect, symbol)[source]

Initialize self. See help(type(self)) for accurate signature.

symbol
Returns:Identifier for this port

SystemOutput

class pluginsmanager.model.system.system_output.SystemOutput(effect, symbol)[source]

Representation of a System output audio port instance.

For general input use, see Output class documentation.

Parameters:
  • effect (SystemEffect) – Effect that contains the input
  • symbol (string) – output audio port symbol identifier
__init__(effect, symbol)[source]

Initialize self. See help(type(self)) for accurate signature.

symbol
Returns:Identifier for this port

SystemMidiInput

class pluginsmanager.model.system.system_midi_input.SystemMidiInput(effect, symbol)[source]

Representation of a System midi input port instance.

For general input use, see Input and MidiInput classes documentation.

Parameters:
  • effect (SystemEffect) – Effect that contains the input
  • symbol (string) – midi input port symbol identifier
__init__(effect, symbol)[source]

Initialize self. See help(type(self)) for accurate signature.

symbol
Returns:Identifier for this port

SystemMidiOutput

class pluginsmanager.model.system.system_midi_output.SystemMidiOutput(effect, symbol)[source]

Representation of a System midi output port instance.

For general input use, see Output and MidiOutput classes documentation.

Parameters:
  • effect (SystemEffect) – Effect that contains the input
  • symbol (string) – midi output port symbol identifier
__init__(effect, symbol)[source]

Initialize self. See help(type(self)) for accurate signature.

symbol
Returns:Identifier for this port

SystemPortMixing

class pluginsmanager.model.system.system_port_mixing.SystemPortMixing(*args, **kwargs)[source]

Contains the default implementation of System ports: SystemInput, SystemOutput, SystemMidiInput and SystemMidiInput

__init__(*args, **kwargs)[source]

Initialize self. See help(type(self)) for accurate signature.

__str__()[source]

Return str(self).

PedalPi - PluginsManager - Observers

An observer is a class that receives notifications of changes in model classes (Bank, Pedalboard, Effect, Param …).

Implementations

Some useful UpdatesObserver classes have been implemented. They are:

  • Autosaver: Allows save the changes automatically in json data files.
  • ModHost: Allows use mod-host, a LV2 host for Jack controllable via socket or command line

Using

For use a observer, it’s necessary register it in BanksManager:

>>> saver = Autosaver()  # Autosaver is a UpdatesObserver
>>> banks_manager = BanksManager()
>>> banks_manager.register(saver)

For access all observers registered, use BanksManager.observers:

>>> saver in banks_manager.observers
True

For remove a observer:

>>> banks_manager.unregister(saver)

Creating a observer

It is possible to create observers! Some ideas are:

  • Allow the use of other hosts (such as Carla);
  • Automatically persist changes;
  • Automatically update a human-machine interface (such as LEDs and displays that inform the state of the effects).

For create a observer, is necessary create a class that extends UpdatesObserver:

class AwesomeObserver(UpdatesObserver):
   ...

UpdatesObserver contains a number of methods that must be implemented in the created class. These methods will be called when changes occur:

class AwesomeObserver(UpdatesObserver):

    def on_bank_updated(self, bank, update_type, index, origin, **kwargs):
        pass

    def on_pedalboard_updated(self, pedalboard, update_type, index, origin, **kwargs):
        pass

    def on_effect_status_toggled(self, effect, **kwargs):
        pass

    def on_effect_updated(self, effect, update_type, index, origin, **kwargs):
        pass

    def on_param_value_changed(self, param, **kwargs):
        pass

    def on_connection_updated(self, connection, update_type, pedalboard, **kwargs):
        pass

Use the update_type attribute to check what type of change occurred:

class AwesomeObserver(UpdatesObserver):
    """Registers all pedalboards that have been deleted"""

    def __init__(self):
        super(AwesomeObserver, self).__init__()
        self.pedalboards_removed = []

    ...

    def on_pedalboard_updated(self, pedalboard, update_type, index, origin, **kwargs):
        if update_type == UpdateType.DELETED:
            self.pedalboards_removed.append(update_type)

    ...

Scope

Notification problem

There are cases where it makes no sense for an observer to be notified of a change. Usually this occurs in interfaces for control, where through them actions can be performed (activate an effect when pressing on a footswitch). Control interfaces need to know of changes that occur so that their display mechanisms are updated when some change occurs through another control interface.

Note that it does not make sense for an interface to be notified of the occurrence of any change if it was the one that performed the action.

A classic example would be an interface for control containing footswitch and a led. The footswitch changes the state of an effect and the led indicates whether it is active or not. If another interface to control (a mobile application, for example) changes the state of the effect to off, the led should reverse its state:

class MyControllerObserver(UpdatesObserver):

    ...

    def on_effect_status_toggled(self, effect, **kwargs):
        # Using gpiozero
        # https://gpiozero.readthedocs.io/en/stable/recipes.html#led
        self.led.toggle()

However, in this situation, when the footswitch changes the effect state, it is notified of the change itself. What can lead to inconsistency in the led:

def pressed():
    effect.toggle()
    led.toggle()

# footswitch is a button
# https://gpiozero.readthedocs.io/en/stable/recipes.html#button
footswitch.when_pressed = pressed

In this example, pressing the button:

  1. pressed() is called;
  2. The effect has its changed state (effect.toggle());
  3. on_effect_status_toggled(self, effect, ** kwargs) is called and the led is changed state (self.led.toggle());
  4. Finally, in pressed() is called led.toggle().

That is, led.toggle() will be called twice instead of one.

Scope solution

Using with keyword, you can indicate which observer is performing the action, allowing the observer not to be notified of the updates that occur in the with scope:

>>> with observer1:
>>>     del manager.banks[0]
Example

Note

The complete example can be obtained from the examples folder of the repository. observer_scope.py

Consider an Observer who only prints actions taken on a bank:

class MyAwesomeObserver(UpdatesObserver):

    def __init__(self, message):
        super(MyAwesomeObserver, self).__init__()
        self.message = message

    def on_bank_updated(self, bank, update_type, **kwargs):
        print(self.message)

    ...

We will create two instances of this observer and perform some actions to see how the notification will occur:

>>> observer1 = MyAwesomeObserver("Hi! I am observer1")
>>> observer2 = MyAwesomeObserver("Hi! I am observer2")

>>> manager = BanksManager()
>>> manager.register(observer1)
>>> manager.register(observer1)

When notification occurs outside a with scope, all observers are informed of the change:

>>> bank = Bank('Bank 1')
>>> manager.banks.append(bank)
"Hi! I am observer1"
"Hi! I am observer2"

We’ll now limit the notification by telling you who performed the actions:

>>> with observer1:
>>> with observer1:
...     del manager.banks[0]
"Hi! I am observer2"
>>> with observer2:
...     manager.banks.append(bank)
"Hi! I am observer1"

If there is with inside a with block, the behavior will not change, ie it will not be cumulative

1
2
3
4
 with observer1:
     manager.banks.remove(bank)
     with observer2:
         manager.banks.append(bank)

Line 2 will result in Hi! I am observer2 and line 4 in Hi! I am observer1

Base API

UpdateType
class pluginsmanager.observer.update_type.UpdateType[source]

Enumeration for informs the change type.

See UpdatesObserver for more details

CREATED = 0

Informs that the change is caused by the creation of an object

DELETED = 2

Informs that the change is caused by the removal of an object

UPDATED = 1

Informs that the change is caused by the update of an object

UpdatesObserver
class pluginsmanager.observer.updates_observer.UpdatesObserver[source]

The UpdatesObserver is an abstract class definition for treatment of changes in some class model. Your methods are called when occurs any change in Bank, Pedalboard, Effect, etc.

To do this, it is necessary that the UpdatesObserver objects be registered in some manager, so that it reports the changes. An example of a manager is BanksManager.

__init__()[source]

Initialize self. See help(type(self)) for accurate signature.

on_bank_updated(bank, update_type, index, origin, **kwargs)[source]

Called when changes occurs in any Bank

Parameters:
  • bank (Bank) – Bank changed.
  • update_type (UpdateType) – Change type
  • index (int) – Bank index (or old index if update_type == UpdateType.DELETED)
  • origin (BanksManager) – BanksManager that the bank is (or has) contained
  • Bank – Contains the old bank occurs a UpdateType.UPDATED
on_connection_updated(connection, update_type, pedalboard, **kwargs)[source]

Called when changes occurs in any pluginsmanager.model.connection.Connection of Pedalboard (adding, updating or removing connections)

Parameters:
on_custom_change(identifier, *args, **kwargs)[source]

Called in specific changes that do not fit the other methods. See CustomChange for more details.

Also, called when any changes not officially supported by the PluginsManager library are made.

Developers can implement libraries on PluginsManager to control different equipment. For example, you can implement a host that will communicate with a GT100 or Zoom G3 boss pedal. If the device has any features not officially supported by the PluginsManager library, this method is useful.

For example: Zoom G3 pedalboards have level. If someone changes the level value, this method can be used to communicate this information to all other observers.

Parameters:identifier – Unique identifier to informs that which informs the type of change in which it is being informed
on_effect_status_toggled(effect, **kwargs)[source]

Called when any Effect status is toggled

Parameters:effect (Effect) – Effect when status has been toggled
on_effect_updated(effect, update_type, index, origin, **kwargs)[source]

Called when changes occurs in any Effect

Parameters:
  • effect (Effect) – Effect changed
  • update_type (UpdateType) – Change type
  • index (int) – Effect index (or old index if update_type == UpdateType.DELETED)
  • origin (Pedalboard) – Pedalboard that the effect is (or has) contained
on_param_value_changed(param, **kwargs)[source]

Called when a param value change

Parameters:param (Param) – Param with value changed
on_pedalboard_updated(pedalboard, update_type, index, origin, **kwargs)[source]

Called when changes occurs in any Pedalboard

Parameters:
  • pedalboard (Pedalboard) – Pedalboard changed
  • update_type (UpdateType) – Change type
  • index (int) – Pedalboard index (or old index if update_type == UpdateType.DELETED)
  • origin (Bank) – Bank that the pedalboard is (or has) contained
  • old (Pedalboard) – Contains the old pedalboard when occurs a UpdateType.UPDATED
pluginsmanager.observer.observable_list.ObservableList
class pluginsmanager.observer.observable_list.ObservableList(lista=None)[source]

Detects changes in list.

In append, in remove and in setter, the observer is callable with changes details

Based in https://www.pythonsheets.com/notes/python-basic.html#emulating-a-list

__contains__(item)[source]

See list.__contains__() method

__delitem__(sliced)[source]

See list.__delitem__() method

Calls observer self.observer(UpdateType.DELETED, item, index) where item is self[index]

__getitem__(index)[source]

See list.__getitem__() method

__init__(lista=None)[source]

Initialize self. See help(type(self)) for accurate signature.

__iter__()[source]

See list.__iter__() method

__len__()[source]

See list.__len__() method

__repr__()[source]

See list.__repr__() method

__setitem__(index, val)[source]

See list.__setitem__() method

Calls observer self.observer(UpdateType.UPDATED, item, index) if val != self[index]

__str__()[source]

See list.__repr__() method

append(item)[source]

See list.append() method

Calls observer self.observer(UpdateType.CREATED, item, index) where index is item position

index(x)[source]

See list.index() method

insert(index, x)[source]

See list.insert() method

Calls observer self.observer(UpdateType.CREATED, item, index)

move(item, new_position)[source]

Moves a item list to new position

Calls observer self.observer(UpdateType.DELETED, item, index) and observer self.observer(UpdateType.CREATED, item, index) if val != self[index]

Parameters:
  • item – Item that will be moved to new_position
  • new_position – Item’s new position
pop(index=None)[source]

See list.pop() method

Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list.

Parameters:index (int) – element index that will be removed
Returns:item removed
remove(item)[source]

See list.remove() method

Calls observer self.observer(UpdateType.DELETED, item, index) where index is item position

Implementations API

pluginsmanager.observer.autosaver.autosaver.Autosaver

class pluginsmanager.observer.autosaver.autosaver.Autosaver(data_path, auto_save=True)[source]

The UpdatesObserver Autosaver allows save any changes automatically in json data files. Save all plugins changes in json files in a specified path.

It also allows loading of saved files:

>>> system_effect = SystemEffect('system', ('capture_1', 'capture_2'), ('playback_1', 'playback_2'))
>>>
>>> autosaver = Autosaver('my/path/data/')
>>> banks_manager = autosaver.load(system_effect)

When loads data with Autosaver, the autosaver has registered in observers of the banks_manager generated:

>>> autosaver in banks_manager.observers
True

For manual registering in BanksManager uses register():

>>> banks_manager = BanksManager()
>>> autosaver = Autosaver('my/path/data/')
>>> autosaver in banks_manager.observers
False
>>> banks_manager.register(autosaver)
>>> autosaver in banks_manager.observers
True

After registered, any changes in Bank, Pedalboard, Effect, Connection or Param which belong to the structure of BanksManager instance are persisted automatically by Autosaver:

>>> banks_manager = BanksManager()
>>> banks_manager.register(autosaver)
>>> my_bank = Bank('My bank')
>>> banks_manager.append(my_bank)
>>> # The bank will be added in banksmanger
>>> # and now is observable (and persisted) by autosaver

It’s possible disables autosaver for saves manually:

>>> autosaver.auto_save = False
>>> autosaver.save(banks_manager)  # save() method saves all banks data
Parameters:
  • data_path (string) – Path that banks will be saved (each bank in one file)
  • auto_save (bool) – Auto save any change?
__init__(data_path, auto_save=True)[source]

Initialize self. See help(type(self)) for accurate signature.

load(system_effect)[source]

Return a BanksManager instance contains the banks present in data_path

Parameters:system_effect (SystemEffect) – SystemEffect used in pedalboards
Return BanksManager:
 BanksManager with banks persisted in data_path
on_bank_updated(bank, update_type, index, origin, **kwargs)[source]

Called when changes occurs in any Bank

Parameters:
  • bank (Bank) – Bank changed.
  • update_type (UpdateType) – Change type
  • index (int) – Bank index (or old index if update_type == UpdateType.DELETED)
  • origin (BanksManager) – BanksManager that the bank is (or has) contained
  • Bank – Contains the old bank occurs a UpdateType.UPDATED
on_connection_updated(connection, update_type, pedalboard, **kwargs)[source]

Called when changes occurs in any pluginsmanager.model.connection.Connection of Pedalboard (adding, updating or removing connections)

Parameters:
on_effect_status_toggled(effect, **kwargs)[source]

Called when any Effect status is toggled

Parameters:effect (Effect) – Effect when status has been toggled
on_effect_updated(effect, update_type, index, origin, **kwargs)[source]

Called when changes occurs in any Effect

Parameters:
  • effect (Effect) – Effect changed
  • update_type (UpdateType) – Change type
  • index (int) – Effect index (or old index if update_type == UpdateType.DELETED)
  • origin (Pedalboard) – Pedalboard that the effect is (or has) contained
on_param_value_changed(param, **kwargs)[source]

Called when a param value change

Parameters:param (Param) – Param with value changed
on_pedalboard_updated(pedalboard, update_type, index, origin, **kwargs)[source]

Called when changes occurs in any Pedalboard

Parameters:
  • pedalboard (Pedalboard) – Pedalboard changed
  • update_type (UpdateType) – Change type
  • index (int) – Pedalboard index (or old index if update_type == UpdateType.DELETED)
  • origin (Bank) – Bank that the pedalboard is (or has) contained
  • old (Pedalboard) – Contains the old pedalboard when occurs a UpdateType.UPDATED
save(banks_manager)[source]

Save all data from a banks_manager

Parameters:banks_manager (BanksManager) – BanksManager that your banks data will be persisted

PedalPi - PluginsManager - Util

DictTuple

class pluginsmanager.util.dict_tuple.DictTuple(elements, key_function)[source]

Dict tuple is a union with dicts and tuples. It’s possible obtains an element by index or by a key

The key is not been a int or long instance

Based in http://jfine-python-classes.readthedocs.io/en/latest/subclass-tuple.html

Parameters:
  • elements (iterable) – Elements for the tuple
  • key_function (lambda) – Function mapper: it obtains an element and returns your key.
__contains__(item)[source]

Return key in self.

__getitem__(index)[source]

Return self[key].

__init__(elements, key_function)[source]

Initialize self. See help(type(self)) for accurate signature.

static __new__(cls, elements, key_function)[source]

Create and return a new object. See help(type) for accurate signature.

ModPedalboardConverter

class pluginsmanager.util.mod_pedalboard_converter.ModPedalboardConverter(mod_ui_path, builder, ignore_errors=False)[source]

ModPedalboardConverter is a utility to convert MOD [1] pedalboards structure in plugins manager pedalboard.

For use, is necessary that the computer system contains the mod_ui with your codes compiled [2] and the pedalboard:

>>> path = Path('/home/user/git/mod/mod_ui/')
>>> builder = Lv2EffectBuilder()
>>> converter = ModPedalboardConverter(path, builder)
>>> pedalboard_path = Path('/home/user/.pedalboards/pedalboard_name.pedalboard')
>>> system_effect = SystemEffect('system', ['capture_1', 'capture_2'], ['playback_1', 'playback_2'])
>>> pedalboard = converter.convert(pedalboard_path, system_effect)

ModPedalboardConverter can try discover the system_pedalboard by the pedalboard:

>>> path = Path('/home/user/git/mod/mod_ui/')
>>> builder = Lv2EffectBuilder()
>>> converter = ModPedalboardConverter(path, builder)
>>> pedalboard_path = Path('/home/user/.pedalboards/pedalboard_name.pedalboard')
>>> pedalboard = converter.convert(pedalboard_path)

If you needs only obtain the system effect:

>>> path = Path('/home/user/git/mod/mod_ui/')
>>> builder = Lv2EffectBuilder()
>>> converter = ModPedalboardConverter(path, builder)
>>> pedalboard_path = Path('/home/user/.pedalboards/pedalboard_name.pedalboard')
>>> pedalboard_info = converter.get_pedalboard_info(pedalboard_path)
>>> system_effect = converter.discover_system_effect(pedalboard_info)
[1]MOD, an awesome music enterprise, create the mod-ui, a visual interface that enable create pedalboards in a simple way.
[2]See the docs: https://github.com/moddevices/mod-ui#install
Parameters:
  • mod_ui_path (Path) – path that mod_ui has in the computer.
  • builder (Lv2EffectBuilder) – Builder for generate the lv2 effects
  • ignore_errors (bool) – Ignore pedalboard problems like connections with undefined ports
__init__(mod_ui_path, builder, ignore_errors=False)[source]

Initialize self. See help(type(self)) for accurate signature.

convert(pedalboard_path, system_effect=None)[source]
Parameters:
  • pedalboard_path (Path) – Path that the pedalboard has been persisted. Generally is in format path/to/pedalboard/name.pedalboard
  • system_effect (SystemEffect) – Effect that contains the audio interface outputs and inputs or None for auto discover
Return Pedalboard:
 

Pedalboard loaded

discover_system_effect(pedalboard_info)[source]

Generate the system effect based in pedalboard_info

Parameters:pedalboard_info (dict) – For obtain this, see get_pedalboard_info()
Return SystemEffect:
 SystemEffect generated based in pedalboard_info
get_pedalboard_info(path)[source]
Parameters:path (Path) – Path that the pedalboard has been persisted. Generally is in format path/to/pedalboard/name.pedalboard
Return dict:pedalboard persisted configurations

PairsList

class pluginsmanager.util.pairs_list.PairsList(similarity_key_function)[source]

Receives two lists and generates a result list of pairs of equal elements

Uses calculate method for generate list

Parameters:similarity_key_function – Function that receives a element and returns your identifier to do a mapping with elements from another list
__init__(similarity_key_function)[source]

Initialize self. See help(type(self)) for accurate signature.

PairsListResult

class pluginsmanager.util.pairs_list.PairsListResult[source]
__init__()[source]

Initialize self. See help(type(self)) for accurate signature.

persistence_decoder

class pluginsmanager.util.persistence_decoder.PersistenceDecoderError[source]
class pluginsmanager.util.persistence_decoder.PersistenceDecoder(system_effect)[source]
__init__(system_effect)[source]

Initialize self. See help(type(self)) for accurate signature.

class pluginsmanager.util.persistence_decoder.Reader(system_effect)[source]
__init__(system_effect)[source]

Initialize self. See help(type(self)) for accurate signature.

class pluginsmanager.util.persistence_decoder.BankReader(system_effect)[source]
class pluginsmanager.util.persistence_decoder.PedalboardReader(system_effect)[source]
class pluginsmanager.util.persistence_decoder.EffectReader(system_effect)[source]
__init__(system_effect)[source]

Initialize self. See help(type(self)) for accurate signature.

class pluginsmanager.util.persistence_decoder.ConnectionReader(pedalboard, system_effect)[source]
__init__(pedalboard, system_effect)[source]

Initialize self. See help(type(self)) for accurate signature.

generate_builder(json, audio_port)[source]

:return AudioPortBuilder

pluginsmanager.util.restriction_list.RestrictionList

class pluginsmanager.util.restriction_list.RestrictionList[source]

List with validation when add a element

__contains__(item)[source]

See __contains__() method

__delitem__(sliced)[source]

See __delitem__() method

__getitem__(index)[source]

See __getitem__() method

__init__()[source]

Initialize self. See help(type(self)) for accurate signature.

__iter__()[source]

See __iter__() method

__len__()[source]

See __len__() method

__repr__()[source]

See __repr__() method

__setitem__(index, val)[source]

See __setitem__() method

Swap doesn’t works:

>>> builder = Lv2EffectBuilder()
>>> effects = EffectsList()
>>> effects.append(builder.build('http://calf.sourceforge.net/plugins/Reverb'))
>>> effects.append(builder.build('http://guitarix.sourceforge.net/plugins/gx_fuzzfacefm_#_fuzzfacefm_'))
>>> effects[0], effects[1] = effects[1], effects[0]
pluginsmanager.model.effects_list.AlreadyAddedError: The effect 'GxFuzzFaceFullerMod' already added
__str__()[source]

See __repr__() method

append(item)[source]

See append() method

index(x)[source]

See index() method

insert(index, x)[source]

See insert() method

move(item, new_position)[source]

See move() method

pop(index=None)[source]

See pop() method

remove(item)[source]

See remove() method

remove_silently(item)[source]

Remove item and not notify