From 706701bb469b7ce957c0ec2c8e5fce8654cc1483 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Sun, 15 Oct 2017 00:34:56 -0300 Subject: [PATCH 01/31] Start process to supports midi ports --- .gitignore | 3 +- CHANGES | 21 ++- README.rst | 25 +--- docs/source/conf.py | 1 + docs/source/model.rst | 77 +++++++++-- docs/source/model_system.rst | 25 ++++ makefile | 58 +++++++++ pluginsmanager/model/effect.py | 38 +++++- pluginsmanager/model/input.py | 49 +------ pluginsmanager/model/lv2/lv2_effect.py | 8 ++ pluginsmanager/model/lv2/lv2_input.py | 7 - pluginsmanager/model/lv2/lv2_midi_input.py | 44 +++++++ pluginsmanager/model/lv2/lv2_midi_output.py | 47 +++++++ pluginsmanager/model/lv2/lv2_output.py | 7 - pluginsmanager/model/midi_input.py | 27 ++++ pluginsmanager/model/midi_output.py | 114 +++++++++++++++++ pluginsmanager/model/midi_port.py | 24 ++++ pluginsmanager/model/output.py | 55 ++------ pluginsmanager/model/port.py | 78 +++++++++++ pluginsmanager/model/system/system_effect.py | 29 +++-- pluginsmanager/model/system/system_input.py | 33 ++--- .../model/system/system_midi_input.py | 36 ++++++ .../model/system/system_midi_output.py | 36 ++++++ pluginsmanager/model/system/system_output.py | 33 ++--- .../model/system/system_port_mixing.py | 45 +++++++ test/model/midi_output_test.py | 121 ++++++++++++++++++ test/observer/autosaver_test.py | 2 +- 27 files changed, 844 insertions(+), 199 deletions(-) create mode 100644 makefile create mode 100644 pluginsmanager/model/lv2/lv2_midi_input.py create mode 100644 pluginsmanager/model/lv2/lv2_midi_output.py create mode 100644 pluginsmanager/model/midi_input.py create mode 100644 pluginsmanager/model/midi_output.py create mode 100644 pluginsmanager/model/midi_port.py create mode 100644 pluginsmanager/model/port.py create mode 100644 pluginsmanager/model/system/system_midi_input.py create mode 100644 pluginsmanager/model/system/system_midi_output.py create mode 100644 pluginsmanager/model/system/system_port_mixing.py create mode 100644 test/model/midi_output_test.py diff --git a/.gitignore b/.gitignore index c77818b..728b69d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ htmlcov docs/build .eggs dist/ -build/ \ No newline at end of file +build/ +test/autosaver_data \ No newline at end of file diff --git a/CHANGES b/CHANGES index e10a7ef..dd364fa 100644 --- a/CHANGES +++ b/CHANGES @@ -1,10 +1,25 @@ -Version 0.5.1 -- released 06//17 +Version 0.6.0 -- released ? +********************************** + - Add makefile. Now is possible run tests and generate docs easly (`make help`); + - Improve :class:`SystemInput` and :class:`SystemOutputs` documentation; + - Implementing midi support; + - Now :class:`Effect` list yours `midi_inputs` and `midi_outputs`; + - :class:`SystemEffect` now supports `midi_inputs` and `midi_outputs`; + - :class:`Lv2Effect` now supports `midi_inputs` and `midi_outputs`; + - Created :class:`MidiPort`, :class:`MidiInput`, :class:`MidiOutput`; + - Created :class:`SystemMidiInput`, :class:`SystemMidiOutput`; + - Created :class:`Lv2MidiInput`, :class:`Lv2MidiOutput`; + - Fix autosaver_test creation folder. Now is more easily configure test workspace; + - Refactored :class:`Input`, :class:`Output`: Created :class:`Port` for remove duplicated code; + - Refactored :class:`SystemInput`, :class:`SystemInput`: Created :class:`SystemPortMixing` for remove duplicated code. + +Version 0.5.1 -- released 08/16/17 ********************************** - `Issue #52`_ - :class:`Autosaver` - Change connection with :class:`SystemInput` and :class:`SystemOutput` causes error; - `Issue #53`_ - :class:`Autosaver` - Remove effect with connections breaks. Disable connections removed notification when a effect with connections has removed; - - :class:`Autosaver` - Add :attr:`.Observable.real_list` attribute for access the list of :class:`ObservableList`. - - `Issue #54`_ - :class:`Mod-host` - Fix `feedback_socket optional`_ problem + - :class:`Autosaver` - Add :attr:`.Observable.real_list` attribute for access the list of :class:`ObservableList`; + - `Issue #54`_ - :class:`Mod-host` - Fix `feedback_socket optional`_ problem. .. _Issue #52: https://github.com/PedalPi/PluginsManager/issues/52 .. _Issue #53: https://github.com/PedalPi/PluginsManager/issues/53 diff --git a/README.rst b/README.rst index f183d8a..120a534 100644 --- a/README.rst +++ b/README.rst @@ -269,35 +269,16 @@ Changelog Maintenance ----------- -Test -**** +Makefile +******** -It is not necessary for the mod_host process to be running - -.. code-block:: bash - - coverage3 run --source=pluginsmanager setup.py test - - coverage3 report - coverage3 html - firefox htmlcov/index.html +Execute ``make help`` for see the options Generate documentation ********************** This project uses `Sphinx`_ + `Read the Docs`_. -You can generate the documentation in your local machine: - -.. code-block:: bash - - pip3 install sphinx - - cd docs - make html - - firefox build/html/index.html - .. _Sphinx: http://www.sphinx-doc.org/ .. _Read the Docs: http://readthedocs.org .. _Calf: http://calf-studio-gear.org/ diff --git a/docs/source/conf.py b/docs/source/conf.py index 0baaed3..76d8b5a 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -42,6 +42,7 @@ 'sphinx.ext.viewcode', 'sphinx.ext.todo', 'sphinx.ext.graphviz', + #'sphinx.ext.inheritance_diagram', # 'sphinx.ext.githubpages', ] diff --git a/docs/source/model.rst b/docs/source/model.rst index 3632f9e..8a09986 100644 --- a/docs/source/model.rst +++ b/docs/source/model.rst @@ -39,24 +39,35 @@ This page contains the model classes. .. graphviz:: - digraph classes { - graph [rankdir=BT]; - node [shape=rect, style=filled, color="#298029", fontname=Sans, fontcolor="#ffffff", fontsize=10]; + 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; + Lv2Effect->Lv2Plugin[ + dir="backward", arrowhead="diamond", arrowtail="normal" + ]; + Lv2Effect->Effect; + SystemEffect->Effect; - Lv2Input->Input; - SystemInput->Input; + Input->Port; + Output->Port; - Lv2Output->Output; - SystemOutput->Output; + MidiPort->Port; + MidiInput->MidiPort; + MidiOutput->MidiPort; - Lv2Param->Param; - } + Lv2Input->Input; + Lv2Output->Output; + Lv2MidiInput->MidiInput; + Lv2MidiOutput->MidiOutput; + + SystemInput->Input; + SystemOutput->Output; + SystemMidiInput->MidiInput; + SystemMidiOutput->MidiOutput; + + Lv2Param->Param; + } .. graphviz:: @@ -71,6 +82,11 @@ This page contains the model classes. AutoSaver->UpdatesObserver } +.. .. inheritance-diagram:: + pluginsmanager.model.output.Output + pluginsmanager.model.input.Input + + BanksManager ------------ @@ -103,6 +119,14 @@ Effect :special-members: :exclude-members: __weakref__ +Port +---- + +.. autoclass:: pluginsmanager.model.port.Port + :members: + :special-members: + :exclude-members: __weakref__ + Input ----- @@ -119,6 +143,31 @@ Output :special-members: :exclude-members: __weakref__ +MidiPort +-------- + +.. autoclass:: pluginsmanager.model.midi_port.MidiPort + :members: + :special-members: + :exclude-members: __weakref__ + + +MidiInput +--------- + +.. autoclass:: pluginsmanager.model.midi_input.MidiInput + :members: + :special-members: + :exclude-members: __weakref__ + +MidiOutput +---------- + +.. autoclass:: pluginsmanager.model.midi_output.MidiOutput + :members: + :special-members: + :exclude-members: __weakref__ + Param ----- diff --git a/docs/source/model_system.rst b/docs/source/model_system.rst index 36f3952..f5afefd 100644 --- a/docs/source/model_system.rst +++ b/docs/source/model_system.rst @@ -32,3 +32,28 @@ SystemOutput :members: :special-members: :exclude-members: __weakref__ + + +SystemMidiInput +--------------- + +.. autoclass:: pluginsmanager.model.system.system_midi_input.SystemMidiInput + :members: + :special-members: + :exclude-members: __weakref__ + +SystemMidiOutput +---------------- + +.. autoclass:: pluginsmanager.model.system.system_midi_output.SystemMidiOutput + :members: + :special-members: + :exclude-members: __weakref__ + +SystemPortMixing +---------------- + +.. autoclass:: pluginsmanager.model.system.system_port_mixing.SystemPortMixing + :members: + :special-members: + :exclude-members: __weakref__ diff --git a/makefile b/makefile new file mode 100644 index 0000000..8f30aee --- /dev/null +++ b/makefile @@ -0,0 +1,58 @@ +#https://krzysztofzuraw.com/blog/2016/makefiles-in-python-projects.html +.RECIPEPREFIX += +BROWSER=firefox + +default: run + +clean: clean-pyc clean-test + +clean-pyc: + find . -name '*.pyc' -exec rm --force {} + + find . -name '*.pyo' -exec rm --force {} + + +clean-test: + rm -rf htmlcov + rm -rf test/autosaver_data + +clean-docs: + rm -rf docs/build + +docs: clean-docs + cd docs && $(MAKE) html + +docs-see: docs + $(BROWSER) docs/build/html/index.html + +install-tests-requirements: + # For midi tests - https://github.com/x42/midifilter.lv2 + cd /tmp && git clone git://github.com/x42/midifilter.lv2.git && \ + cd midifilter.lv2 && \ + make && \ + sudo make install PREFIX=/usr + +run: + @echo "Run option isn't created =)" + +test: clean-test + mkdir test/autosaver_data + coverage3 run --source=pluginsmanager setup.py test + coverage3 report + coverage3 html + +test-details: test + $(BROWSER) htmlcov/index.html + +help: + @echo " clean" + @echo " Clean the files" + @echo " docs" + @echo " Make the docs" + @echo " docs-see" + @echo " Make the docs and open it in BROWSER" + @echo " test" + @echo " Execute the tests" + @echo " test-details" + @echo " Execute the tests and shows the result in BROWSER" + @echo " - BROWSER=firefox" + @echo " help" + @echo " Show the valid commands" diff --git a/pluginsmanager/model/effect.py b/pluginsmanager/model/effect.py index ca92def..5bbefc1 100644 --- a/pluginsmanager/model/effect.py +++ b/pluginsmanager/model/effect.py @@ -13,9 +13,10 @@ # limitations under the License. from abc import ABCMeta, abstractmethod - from unittest.mock import MagicMock +from pluginsmanager.util.dict_tuple import DictTuple + class Effect(metaclass=ABCMeta): """ @@ -53,8 +54,10 @@ def __init__(self): self._active = True self._params = () - self._inputs = () - self._outputs = () + self._inputs = DictTuple([], lambda: None) + self._outputs = DictTuple([], lambda: None) + self._midi_inputs = DictTuple([], lambda: None) + self._midi_outputs = DictTuple([], lambda: None) self._observer = MagicMock() @@ -90,6 +93,20 @@ def outputs(self): """ return self._outputs + @property + def midi_inputs(self): + """ + :return list[MidiInput]: MidiInputs of effect + """ + return self._midi_inputs + + @property + def midi_outputs(self): + """ + :return list[MidiOutput]: MidiOutputs of effect + """ + return self._midi_outputs + @property def active(self): """ @@ -155,3 +172,18 @@ def is_possible_connect_itself(self): return bool: Is possible connect the with it self? """ return False + + @property + def is_unique_for_all_pedalboards(self): + """ + return bool: Is unique for all pedalboards? + Example: :class:`.SystemEffect` is unique for all pedalboards + """ + return False + + def __repr__(self): + return "<{} object as '{}' at 0x{:x}>".format( + self.__class__.__name__, + str(self), + id(self) + ) diff --git a/pluginsmanager/model/input.py b/pluginsmanager/model/input.py index e214bf5..6c280a9 100644 --- a/pluginsmanager/model/input.py +++ b/pluginsmanager/model/input.py @@ -12,12 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -from abc import ABCMeta, abstractmethod +from abc import ABCMeta -from unittest.mock import MagicMock +from pluginsmanager.model.port import Port -class Input(metaclass=ABCMeta): +class Input(Port, metaclass=ABCMeta): """ Input is the medium in which the audio will go into effect to be processed. @@ -43,53 +43,14 @@ class Input(metaclass=ABCMeta): >>> my_awesome_effect.inputs[symbol] == effect_input True - For connections between effects, view :class:`pluginsmanager.mod_host.connection.Connection`. + For connections between effects, view :class:`pluginsmanager.connection.Connection`. :param Effect effect: Effect of input """ - def __init__(self, effect): - self._effect = effect - - self.observer = MagicMock() - - self._unique_for_all_pedalboards = False - - @property - def effect(self): - """ - :return: Effect of input - """ - return self._effect - - @property - @abstractmethod - def symbol(self): - """ - :return: Input identifier - """ - pass - - @property - def json(self): - """ - Get a json decodable representation of this input - - :return dict: json representation - """ - return self.__dict__ - - @property - def __dict__(self): - return { - 'effect': self.effect.index, - 'symbol': self.symbol, - 'index': self.index, - } - @property def index(self): """ - :return Input index in the your effect + :return: Input index in the your effect """ return self.effect.inputs.index(self) diff --git a/pluginsmanager/model/lv2/lv2_effect.py b/pluginsmanager/model/lv2/lv2_effect.py index d690465..63db6d5 100644 --- a/pluginsmanager/model/lv2/lv2_effect.py +++ b/pluginsmanager/model/lv2/lv2_effect.py @@ -16,6 +16,8 @@ from pluginsmanager.model.lv2.lv2_param import Lv2Param from pluginsmanager.model.lv2.lv2_input import Lv2Input from pluginsmanager.model.lv2.lv2_output import Lv2Output +from pluginsmanager.model.lv2.lv2_midi_input import Lv2MidiInput +from pluginsmanager.model.lv2.lv2_midi_output import Lv2MidiOutput from pluginsmanager.util.dict_tuple import DictTuple @@ -50,6 +52,12 @@ def __init__(self, plugin): outputs = [Lv2Output(self, effect_output) for effect_output in plugin['ports']['audio']['output']] self._outputs = DictTuple(outputs, lambda _output: _output.symbol) + midi_inputs = [Lv2MidiInput(self, midi_input) for midi_input in plugin['ports']['midi']['input']] + self._midi_inputs = DictTuple(midi_inputs, lambda _output: _output.symbol) + + midi_outputs = [Lv2MidiOutput(self, midi_output) for midi_output in plugin['ports']['midi']['output']] + self._midi_outputs = DictTuple(midi_outputs, lambda _output: _output.symbol) + self.instance = None def __str__(self): diff --git a/pluginsmanager/model/lv2/lv2_input.py b/pluginsmanager/model/lv2/lv2_input.py index 2cd6a3e..4029a42 100644 --- a/pluginsmanager/model/lv2/lv2_input.py +++ b/pluginsmanager/model/lv2/lv2_input.py @@ -34,13 +34,6 @@ def __init__(self, effect, effect_input): def __str__(self): return self._input['name'] - def __repr__(self): - return "<{} object as {} at 0x{:x}>".format( - self.__class__.__name__, - str(self), - id(self) - ) - @property def symbol(self): return self._input['symbol'] diff --git a/pluginsmanager/model/lv2/lv2_midi_input.py b/pluginsmanager/model/lv2/lv2_midi_input.py new file mode 100644 index 0000000..b6af02f --- /dev/null +++ b/pluginsmanager/model/lv2/lv2_midi_input.py @@ -0,0 +1,44 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from pluginsmanager.model.midi_input import MidiInput + + +class Lv2MidiInput(MidiInput): + """ + Representation of a Lv2 midi input port instance. + + For general input use, see :class:`.MidiInput` and :class:`.Input` classes documentation. + + :param Lv2Effect effect: Effect that contains the midi input + :param dict effect_midi_input: *midi input port* json representation + """ + + def __init__(self, effect, effect_midi_input): + super(Lv2MidiInput, self).__init__(effect) + self._input = effect_midi_input + + def __str__(self): + return self._input['name'] + + @property + def symbol(self): + return self._input['symbol'] + + @property + def __dict__(self): + dictionary = super(Lv2MidiInput, self).__dict__ + dictionary['index'] = self._input['index'] + + return dictionary diff --git a/pluginsmanager/model/lv2/lv2_midi_output.py b/pluginsmanager/model/lv2/lv2_midi_output.py new file mode 100644 index 0000000..68d080b --- /dev/null +++ b/pluginsmanager/model/lv2/lv2_midi_output.py @@ -0,0 +1,47 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from pluginsmanager.model.midi_output import MidiOutput + + +class Lv2MidiOutput(MidiOutput): + """ + Representation of a Lv2 midi output port instance. + + For general input use, see :class:`.MidiOutput` and + :class:`.Output` classes documentation. + + .. _output audio port: http://lv2plug.in/ns/lv2core/#OutputPort + + :param Lv2Effect effect: Effect that contains the midi output + :param dict output: *midi output port* json representation + """ + + def __init__(self, effect, output): + super(Lv2MidiOutput, self).__init__(effect) + self._output = output + + def __str__(self): + return self._output['name'] + + @property + def symbol(self): + return self._output['symbol'] + + @property + def __dict__(self): + dictionary = super(Lv2MidiOutput, self).__dict__ + dictionary['index'] = self._output['index'] + + return dictionary diff --git a/pluginsmanager/model/lv2/lv2_output.py b/pluginsmanager/model/lv2/lv2_output.py index f3c6dfb..22d56ad 100644 --- a/pluginsmanager/model/lv2/lv2_output.py +++ b/pluginsmanager/model/lv2/lv2_output.py @@ -34,13 +34,6 @@ def __init__(self, effect, effect_output): def __str__(self): return self._output['name'] - def __repr__(self): - return "<{} object as {} at 0x{:x}>".format( - self.__class__.__name__, - str(self), - id(self) - ) - @property def symbol(self): return self._output['symbol'] diff --git a/pluginsmanager/model/midi_input.py b/pluginsmanager/model/midi_input.py new file mode 100644 index 0000000..08a62b9 --- /dev/null +++ b/pluginsmanager/model/midi_input.py @@ -0,0 +1,27 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from abc import ABCMeta + +from pluginsmanager.model.midi_port import MidiPort + + +class MidiInput(MidiPort, metaclass=ABCMeta): + + @property + def index(self): + """ + :return: MidiInput index in the your effect + """ + return self.effect.midi_inputs.index(self) diff --git a/pluginsmanager/model/midi_output.py b/pluginsmanager/model/midi_output.py new file mode 100644 index 0000000..e70d76f --- /dev/null +++ b/pluginsmanager/model/midi_output.py @@ -0,0 +1,114 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from abc import ABCMeta + +from pluginsmanager.model.connection import Connection, ConnectionError +from pluginsmanager.model.port import Port + + +class MidiOutput(Port, metaclass=ABCMeta): + """ + 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 + + >>> my_awesome_effect.outputs + (, ) + + >>> output = my_awesome_effect.outputs[0] + >>> output + + + >>> symbol = my_awesome_effect.outputs[0].symbol + >>> symbol + 'output_l' + + >>> my_awesome_effect.outputs[symbol] == output + True + + For connections between effects, view :class:`.pluginsmanager.mod_host.connection.Connection`. + + :param Effect effect: Effect that contains the output + """ + + def connect(self, effect_input): + """ + Connect it with effect_input:: + + >>> driver_output = driver.outputs[0] + >>> reverb_input = reverb.inputs[0] + >>> Connection(driver_output, reverb_input) in driver.effect.connections + False + >>> driver_output.connect(reverb_input) + >>> Connection(driver_output, reverb_input) in driver.effect.connections + True + + .. note:: + + This method does not work for all cases. + class:`SystemOutput` can not be connected with class:`SystemInput` this way. + For this case, use :: + + >>> pedalboard.connections.append(Connection(system_output, system_input)) + + :param Input effect_input: Input that will be connected with it + """ + if self.effect.is_unique_for_all_pedalboards and effect_input.effect.is_unique_for_all_pedalboards: + error = "Isn't possible connect ports that both are from effects uniques for all pedalboards. " + error += "Please use pedalboard.connect(Connection(output, input))" + raise ConnectionError(error) + + pedalboard = self.effect.pedalboard if not self.effect.is_unique_for_all_pedalboards else effect_input.effect.pedalboard + pedalboard.connections.append(Connection(self, effect_input)) + + def disconnect(self, effect_input): + """ + Disconnect it with effect_input + + >>> driver_output = driver.outputs[0] + >>> reverb_input = reverb.inputs[0] + >>> Connection(driver_output, reverb_input) in driver.effect.connections + True + >>> driver_output.disconnect(reverb_input) + >>> Connection(driver_output, reverb_input) in driver.effect.connections + False + + .. note:: + + This method does not work for all cases. + class:`SystemOutput` can not be disconnected with class:`SystemInput` this way. + For this case, use :: + + >>> pedalboard.connections.remove(Connection(system_output, system_input)) + + :param Input effect_input: Input that will be disconnected with it + """ + if self.effect.is_unique_for_all_pedalboards and effect_input.effect.is_unique_for_all_pedalboards: + error = "Isn't possible connect ports that both are from effects uniques for all pedalboards. " + error += "Please use pedalboard.connect(Connection(output, input))" + raise ConnectionError(error) + + self.effect.pedalboard.connections.remove(Connection(self, effect_input)) + + @property + def index(self): + """ + :return: Output index in the your effect + """ + return self.effect.midi_outputs.index(self) diff --git a/pluginsmanager/model/midi_port.py b/pluginsmanager/model/midi_port.py new file mode 100644 index 0000000..a43e2b9 --- /dev/null +++ b/pluginsmanager/model/midi_port.py @@ -0,0 +1,24 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from abc import ABCMeta + +from pluginsmanager.model.port import Port + + +class MidiPort(Port, metaclass=ABCMeta): + """ + Port is a parent abstraction for midi inputs and midi outputs + """ + pass diff --git a/pluginsmanager/model/output.py b/pluginsmanager/model/output.py index 6fcd876..7c435d4 100644 --- a/pluginsmanager/model/output.py +++ b/pluginsmanager/model/output.py @@ -12,14 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -from abc import ABCMeta, abstractmethod +from abc import ABCMeta from pluginsmanager.model.connection import Connection, ConnectionError +from pluginsmanager.model.port import Port -from unittest.mock import MagicMock - -class Output(metaclass=ABCMeta): +class Output(Port, metaclass=ABCMeta): """ Output is the medium in which the audio processed by the effect is returned. @@ -48,20 +47,6 @@ class Output(metaclass=ABCMeta): :param Effect effect: Effect that contains the output """ - def __init__(self, effect): - self._effect = effect - - self.observer = MagicMock() - - self._unique_for_all_pedalboards = False - - @property - def effect(self): - """ - :return: Effect of output - """ - return self._effect - def connect(self, effect_input): """ Connect it with effect_input:: @@ -84,11 +69,12 @@ def connect(self, effect_input): :param Input effect_input: Input that will be connected with it """ - if self._unique_for_all_pedalboards and effect_input._unique_for_all_pedalboards: - error = "Isn't possible connect this way. Please use pedalboard.connect(Connection(output, input))" + if self.effect.is_unique_for_all_pedalboards and effect_input.effect.is_unique_for_all_pedalboards: + error = "Isn't possible connect ports that both are from effects uniques for all pedalboards. " + error += "Please use pedalboard.connect(Connection(output, input))" raise ConnectionError(error) - pedalboard = self.effect.pedalboard if not self._unique_for_all_pedalboards else effect_input.effect.pedalboard + pedalboard = self.effect.pedalboard if not self.effect.is_unique_for_all_pedalboards else effect_input.effect.pedalboard pedalboard.connections.append(Connection(self, effect_input)) def disconnect(self, effect_input): @@ -119,34 +105,9 @@ def disconnect(self, effect_input): self.effect.pedalboard.connections.remove(Connection(self, effect_input)) - @property - @abstractmethod - def symbol(self): - """ - :return: Output identifier - """ - pass - - @property - def json(self): - """ - Get a json decodable representation of this output - - :return dict: json representation - """ - return self.__dict__ - - @property - def __dict__(self): - return { - 'effect': self.effect.index, - 'symbol': self.symbol, - 'index': self.index, - } - @property def index(self): """ - :return Output index in the your effect + :return: Output index in the your effect """ return self.effect.outputs.index(self) diff --git a/pluginsmanager/model/port.py b/pluginsmanager/model/port.py new file mode 100644 index 0000000..e2f5b8d --- /dev/null +++ b/pluginsmanager/model/port.py @@ -0,0 +1,78 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from abc import ABCMeta, abstractmethod + +from unittest.mock import MagicMock + + +class Port(metaclass=ABCMeta): + """ + Port is a parent abstraction for inputs and outputs + + :param Effect effect: Effect that contains port + """ + + def __init__(self, effect): + self._effect = effect + self.observer = MagicMock() + + @property + @abstractmethod + def symbol(self): + """ + :return: Identifier for this port + """ + pass + + @property + def effect(self): + """ + :return: Effect that this port is related + """ + return self._effect + + @property + def json(self): + """ + Get a json decodable representation + + :return dict: json representation + """ + return self.__dict__ + + @property + @abstractmethod + def index(self): + """ + :return: Index in the effect related based in your category. + As example, if this port is a :class:`input`, the + index returns your position in the inputs ports. + """ + pass + + @property + def __dict__(self): + return { + 'effect': self.effect.index, + 'symbol': self.symbol, + 'index': self.index, + } + + def __repr__(self): + return "<{} object as {} at 0x{:x}>".format( + self.__class__.__name__, + str(self), + id(self) + ) diff --git a/pluginsmanager/model/system/system_effect.py b/pluginsmanager/model/system/system_effect.py index c89ac64..99a9794 100644 --- a/pluginsmanager/model/system/system_effect.py +++ b/pluginsmanager/model/system/system_effect.py @@ -15,6 +15,8 @@ from pluginsmanager.model.effect import Effect from pluginsmanager.model.system.system_input import SystemInput from pluginsmanager.model.system.system_output import SystemOutput +from pluginsmanager.model.system.system_midi_input import SystemMidiInput +from pluginsmanager.model.system.system_midi_output import SystemMidiOutput from pluginsmanager.util.dict_tuple import DictTuple @@ -61,8 +63,10 @@ class SystemEffect(Effect): starts with `capture_` :param tuple(string) inputs: Tuple of inputs representation. Usually a input representation starts with `playback_` + :param tuple(string) midi_outputs: Tuple of midi outputs representation. + :param tuple(string) midi_inputs: Tuple of midi inputs representation. """ - def __init__(self, representation, outputs, inputs): + def __init__(self, representation, outputs, inputs, midi_outputs=None, midi_inputs=None): super(SystemEffect, self).__init__() self.representation = representation @@ -75,16 +79,17 @@ def __init__(self, representation, outputs, inputs): outputs = [SystemOutput(self, effect_output) for effect_output in outputs] self._outputs = DictTuple(outputs, lambda _output: str(_output)) + midi_inputs = midi_inputs if midi_inputs is not None else [] + midi_inputs = [SystemMidiInput(self, effect_input) for effect_input in midi_inputs] + self._midi_inputs = DictTuple(midi_inputs, lambda _input: str(_input)) + + midi_outputs = midi_outputs if midi_outputs is not None else [] + midi_outputs = [SystemMidiOutput(self, effect_output) for effect_output in midi_outputs] + self._midi_outputs = DictTuple(midi_outputs, lambda _output: str(_output)) + def __str__(self): return self.representation - def __repr__(self): - return "<{} object as '{}' at 0x{:x}>".format( - self.__class__.__name__, - str(self), - id(self) - ) - @property def __dict__(self): return { @@ -97,3 +102,11 @@ def is_possible_connect_itself(self): return bool: Is possible connect the with it self? """ return True + + @property + def is_unique_for_all_pedalboards(self): + """ + return bool: Is unique for all pedalboards? + Example: :class:`.SystemEffect` is unique for all pedalboards + """ + return True diff --git a/pluginsmanager/model/system/system_input.py b/pluginsmanager/model/system/system_input.py index 4ba941b..fc82dde 100644 --- a/pluginsmanager/model/system/system_input.py +++ b/pluginsmanager/model/system/system_input.py @@ -13,32 +13,23 @@ # limitations under the License. from pluginsmanager.model.input import Input +from pluginsmanager.model.system.system_port_mixing import SystemPortMixing -class SystemInput(Input): +class SystemInput(SystemPortMixing, Input): + """ + Representation of a System input audio port instance. - def __init__(self, effect, system_input): - super(SystemInput, self).__init__(effect) - self._input = system_input - self._unique_for_all_pedalboards = True + For general input use, see :class:`.Input` class documentation. - def __str__(self): - return self._input + :param SystemEffect effect: Effect that contains the input + :param string symbol: *input audio port* symbol identifier + """ - def __repr__(self): - return "<{} object as {} at 0x{:x}>".format( - self.__class__.__name__, - str(self), - id(self) - ) + def __init__(self, effect, symbol): + super(SystemInput, self).__init__(effect) + self._symbol = symbol @property def symbol(self): - return str(self) - - @property - def __dict__(self): - return { - 'symbol': self.symbol, - 'index': self.effect.inputs.index(self), - } + return self._symbol diff --git a/pluginsmanager/model/system/system_midi_input.py b/pluginsmanager/model/system/system_midi_input.py new file mode 100644 index 0000000..eb7b2f3 --- /dev/null +++ b/pluginsmanager/model/system/system_midi_input.py @@ -0,0 +1,36 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from pluginsmanager.model.midi_input import MidiInput +from pluginsmanager.model.system.system_port_mixing import SystemPortMixing + + +class SystemMidiInput(SystemPortMixing, MidiInput): + """ + Representation of a System midi input port instance. + + For general input use, see :class:`.Input` and + :class:`.MidiInput` classes documentation. + + :param SystemEffect effect: Effect that contains the input + :param string symbol: *midi input port* symbol identifier + """ + + def __init__(self, effect, symbol): + super(SystemMidiInput, self).__init__(effect) + self._symbol = symbol + + @property + def symbol(self): + return self._symbol diff --git a/pluginsmanager/model/system/system_midi_output.py b/pluginsmanager/model/system/system_midi_output.py new file mode 100644 index 0000000..9364ddb --- /dev/null +++ b/pluginsmanager/model/system/system_midi_output.py @@ -0,0 +1,36 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from pluginsmanager.model.midi_output import MidiOutput +from pluginsmanager.model.system.system_port_mixing import SystemPortMixing + + +class SystemMidiOutput(SystemPortMixing, MidiOutput): + """ + Representation of a System midi output port instance. + + For general input use, see :class:`.Output` and + :class:`.MidiOutput` classes documentation. + + :param SystemEffect effect: Effect that contains the input + :param string symbol: *midi output port* symbol identifier + """ + + def __init__(self, effect, symbol): + super(SystemMidiOutput, self).__init__(effect) + self._symbol = symbol + + @property + def symbol(self): + return self._symbol diff --git a/pluginsmanager/model/system/system_output.py b/pluginsmanager/model/system/system_output.py index 64f1afe..3258359 100644 --- a/pluginsmanager/model/system/system_output.py +++ b/pluginsmanager/model/system/system_output.py @@ -13,32 +13,23 @@ # limitations under the License. from pluginsmanager.model.output import Output +from pluginsmanager.model.system.system_port_mixing import SystemPortMixing -class SystemOutput(Output): +class SystemOutput(SystemPortMixing, Output): + """ + Representation of a System output audio port instance. - def __init__(self, effect, output): - super(SystemOutput, self).__init__(effect) - self._output = output - self._unique_for_all_pedalboards = True + For general input use, see :class:`.Output` class documentation. - def __str__(self): - return self._output + :param SystemEffect effect: Effect that contains the input + :param string symbol: *output audio port* symbol identifier + """ - def __repr__(self): - return "<{} object as {} at 0x{:x}>".format( - self.__class__.__name__, - str(self), - id(self) - ) + def __init__(self, effect, symbol): + super(SystemOutput, self).__init__(effect) + self._symbol = symbol @property def symbol(self): - return str(self) - - @property - def __dict__(self): - return { - 'symbol': self.symbol, - 'index': self.effect.outputs.index(self), - } + return self._symbol diff --git a/pluginsmanager/model/system/system_port_mixing.py b/pluginsmanager/model/system/system_port_mixing.py new file mode 100644 index 0000000..c0b2321 --- /dev/null +++ b/pluginsmanager/model/system/system_port_mixing.py @@ -0,0 +1,45 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from abc import ABCMeta + + +class SystemPortMixing(object, metaclass=ABCMeta): + """ + Contains the default implementation of System ports: + :class:`.SystemInput`, :class:`.SystemOutput`, + :class:`.SystemMidiInput` and :class:`.SystemMidiInput` + + If you uses it, in the class constructor is necessary + define the symbol (`string`):: + + class MySystemPort(SystemPortMixing, InputPort): + def __init__(self, effect): + super(MySystemPort, self).__init__(effect) + self._symbol = 'symbol' + """ + + def __init__(self, *args, **kwargs): + super(SystemPortMixing, self).__init__(*args, **kwargs) + self._symbol = None + + def __str__(self): + return self._symbol + + @property + def __dict__(self): + return { + 'symbol': self.symbol, + 'index': self.index(), + } diff --git a/test/model/midi_output_test.py b/test/model/midi_output_test.py new file mode 100644 index 0000000..ec336d3 --- /dev/null +++ b/test/model/midi_output_test.py @@ -0,0 +1,121 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest +from unittest.mock import MagicMock + +from pluginsmanager.model.connection import ConnectionError +from pluginsmanager.model.lv2.lv2_effect_builder import Lv2EffectBuilder +from pluginsmanager.model.pedalboard import Pedalboard +from pluginsmanager.model.system.system_effect import SystemEffect +from pluginsmanager.observer.update_type import UpdateType + + +class MidiOutputTest(unittest.TestCase): + builder = None + + @classmethod + def setUpClass(cls): + cls.builder = Lv2EffectBuilder() + + def test_connect(self): + pedalboard = Pedalboard('Pedalboard name') + pedalboard.observer = MagicMock() + + builder = MidiOutputTest.builder + cctonode = builder.build('http://gareus.org/oss/lv2/midifilter#cctonote') + cctonode2 = builder.build('http://gareus.org/oss/lv2/midifilter#cctonote') + + pedalboard.append(cctonode) + pedalboard.append(cctonode2) + + self.assertEqual(0, len(pedalboard.connections)) + cctonode.midi_outputs[0].connect(cctonode2.midi_inputs[0]) + self.assertEqual(1, len(pedalboard.connections)) + + new_connection = pedalboard.connections[0] + pedalboard.observer.on_connection_updated.assert_called_with(new_connection, UpdateType.CREATED, pedalboard=pedalboard) + + cctonode.midi_outputs[0].connect(cctonode2.midi_inputs[0]) + self.assertEqual(2, len(pedalboard.connections)) + + new_connection = pedalboard.connections[-1] + pedalboard.observer.on_connection_updated.assert_called_with(new_connection, UpdateType.CREATED, pedalboard=pedalboard) + + def test_disconnect(self): + pedalboard = Pedalboard('Pedalboard name') + + builder = MidiOutputTest.builder + cctonode = builder.build('http://gareus.org/oss/lv2/midifilter#cctonote') + cctonode2 = builder.build('http://gareus.org/oss/lv2/midifilter#cctonote') + + pedalboard.append(cctonode) + pedalboard.append(cctonode2) + + cctonode.midi_outputs[0].connect(cctonode2.midi_inputs[0]) + self.assertEqual(1, len(pedalboard.connections)) + + pedalboard.observer = MagicMock() + + disconnected = pedalboard.connections[-1] + cctonode.midi_outputs[0].disconnect(cctonode2.midi_inputs[0]) + self.assertEqual(0, len(pedalboard.connections)) + pedalboard.observer.on_connection_updated.assert_called_with(disconnected, UpdateType.DELETED, pedalboard=pedalboard) + + def test_disconnect_connection_not_created(self): + pedalboard = Pedalboard('Pedalboard name') + + builder = MidiOutputTest.builder + cctonode = builder.build('http://gareus.org/oss/lv2/midifilter#cctonote') + cctonode2 = builder.build('http://gareus.org/oss/lv2/midifilter#cctonote') + + pedalboard.append(cctonode) + pedalboard.append(cctonode2) + + pedalboard.observer = MagicMock() + + with self.assertRaises(ValueError): + cctonode.midi_outputs[0].disconnect(cctonode2.midi_inputs[0]) + + pedalboard.observer.on_connection_updated.assert_not_called() + + def test_connect_system_effect(self): + sys_effect = SystemEffect( + 'system', + ['capture_1'], + ['playback_1', 'playback_2'], + ['midi_capture_1'], + ['midi_playback_1'] + ) + + effect_output = sys_effect.midi_outputs[0] + effect_input = sys_effect.midi_inputs[0] + + with self.assertRaises(ConnectionError): + effect_output.connect(effect_input) + + def test_disconnect_system_effect(self): + sys_effect = SystemEffect( + 'system', + ['capture_1'], + ['playback_1', 'playback_2'], + ['midi_capture_1'], + ['midi_playback_1'] + ) + + effect_output = sys_effect.midi_outputs[0] + effect_input = sys_effect.midi_inputs[0] + + with self.assertRaises(ConnectionError): + effect_output.disconnect(effect_input) diff --git a/test/observer/autosaver_test.py b/test/observer/autosaver_test.py index 8a55e21..7d69711 100644 --- a/test/observer/autosaver_test.py +++ b/test/observer/autosaver_test.py @@ -26,7 +26,7 @@ class AutoSaverTest(unittest.TestCase): def autosaver(self, auto_save=True): - return Autosaver('../data/autosaver_data/', auto_save=auto_save) + return Autosaver('test/autosaver_data/', auto_save=auto_save) def test_observers(self): save_mock = MagicMock() From 8e7acb6a020d3b78a11c329615bab1a79acf3e79 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Sun, 15 Oct 2017 11:05:09 -0300 Subject: [PATCH 02/31] #57 - Refactored Lv2(Input(Midi, 1), Output(Midi, 1)) -> Lv2PortMixing. Improve some tests --- .travis.yml | 10 +--- CHANGES | 3 +- makefile | 2 +- pluginsmanager/model/lv2/lv2_input.py | 23 +++------ pluginsmanager/model/lv2/lv2_midi_input.py | 26 ++++------ pluginsmanager/model/lv2/lv2_midi_output.py | 25 +++------- pluginsmanager/model/lv2/lv2_output.py | 23 +++------ pluginsmanager/model/lv2/lv2_port_mixing.py | 50 +++++++++++++++++++ pluginsmanager/model/output.py | 5 +- .../model/system/system_port_mixing.py | 13 +---- test/banks_manager_test.py | 10 ++++ test/model/midi_output_test.py | 20 ++++++++ 12 files changed, 120 insertions(+), 90 deletions(-) create mode 100644 pluginsmanager/model/lv2/lv2_port_mixing.py diff --git a/.travis.yml b/.travis.yml index bbf8029..fe1386e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,13 +19,7 @@ install: script: - lv2ls - - cd .. - - mkdir data - - cd data - - mkdir autosaver_data - - cd ../PluginsManager - - coverage3 run --source=pluginsmanager setup.py test - - cd docs - - make html + - make test + - make docs after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/CHANGES b/CHANGES index dd364fa..eae6c87 100644 --- a/CHANGES +++ b/CHANGES @@ -11,7 +11,8 @@ Version 0.6.0 -- released ? - Created :class:`Lv2MidiInput`, :class:`Lv2MidiOutput`; - Fix autosaver_test creation folder. Now is more easily configure test workspace; - Refactored :class:`Input`, :class:`Output`: Created :class:`Port` for remove duplicated code; - - Refactored :class:`SystemInput`, :class:`SystemInput`: Created :class:`SystemPortMixing` for remove duplicated code. + - Refactored :class:`SystemInput`, :class:`SystemOutput`: Created :class:`SystemPortMixing` for remove duplicated code; + - Refactored :class:`Lv2Input`, :class:`Lv2Output`: Created :class:`Lv2PortMixing` for remove duplicated code. Version 0.5.1 -- released 08/16/17 ********************************** diff --git a/makefile b/makefile index 8f30aee..f98c363 100644 --- a/makefile +++ b/makefile @@ -37,9 +37,9 @@ test: clean-test mkdir test/autosaver_data coverage3 run --source=pluginsmanager setup.py test coverage3 report - coverage3 html test-details: test + coverage3 html $(BROWSER) htmlcov/index.html help: diff --git a/pluginsmanager/model/lv2/lv2_input.py b/pluginsmanager/model/lv2/lv2_input.py index 4029a42..1875ff3 100644 --- a/pluginsmanager/model/lv2/lv2_input.py +++ b/pluginsmanager/model/lv2/lv2_input.py @@ -13,9 +13,10 @@ # limitations under the License. from pluginsmanager.model.input import Input +from pluginsmanager.model.lv2.lv2_port_mixing import Lv2PortMixing -class Lv2Input(Input): +class Lv2Input(Lv2PortMixing, Input): """ Representation of a Lv2 `input audio port`_ instance. @@ -24,23 +25,13 @@ class Lv2Input(Input): .. _input audio port: http://lv2plug.in/ns/lv2core/#InputPort :param Lv2Effect effect: Effect that contains the input - :param dict effect_input: *input audio port* json representation + :param dict data: *input audio port* json representation """ - def __init__(self, effect, effect_input): + def __init__(self, effect, data): super(Lv2Input, self).__init__(effect) - self._input = effect_input - - def __str__(self): - return self._input['name'] - - @property - def symbol(self): - return self._input['symbol'] + self._data = data @property - def __dict__(self): - dictionary = super(Lv2Input, self).__dict__ - dictionary['index'] = self._input['index'] - - return dictionary + def data(self): + return self._data diff --git a/pluginsmanager/model/lv2/lv2_midi_input.py b/pluginsmanager/model/lv2/lv2_midi_input.py index b6af02f..64e62e3 100644 --- a/pluginsmanager/model/lv2/lv2_midi_input.py +++ b/pluginsmanager/model/lv2/lv2_midi_input.py @@ -13,32 +13,24 @@ # limitations under the License. from pluginsmanager.model.midi_input import MidiInput +from pluginsmanager.model.lv2.lv2_port_mixing import Lv2PortMixing -class Lv2MidiInput(MidiInput): +class Lv2MidiInput(Lv2PortMixing, MidiInput): """ Representation of a Lv2 midi input port instance. - For general input use, see :class:`.MidiInput` and :class:`.Input` classes documentation. + For general input use, see :class:`.MidiInput` and + :class:`.Input` classes documentation. :param Lv2Effect effect: Effect that contains the midi input - :param dict effect_midi_input: *midi input port* json representation + :param dict data: *midi input port* json representation """ - def __init__(self, effect, effect_midi_input): + def __init__(self, effect, data): super(Lv2MidiInput, self).__init__(effect) - self._input = effect_midi_input - - def __str__(self): - return self._input['name'] - - @property - def symbol(self): - return self._input['symbol'] + self._data = data @property - def __dict__(self): - dictionary = super(Lv2MidiInput, self).__dict__ - dictionary['index'] = self._input['index'] - - return dictionary + def data(self): + return self._data diff --git a/pluginsmanager/model/lv2/lv2_midi_output.py b/pluginsmanager/model/lv2/lv2_midi_output.py index 68d080b..4b87685 100644 --- a/pluginsmanager/model/lv2/lv2_midi_output.py +++ b/pluginsmanager/model/lv2/lv2_midi_output.py @@ -13,35 +13,24 @@ # limitations under the License. from pluginsmanager.model.midi_output import MidiOutput +from pluginsmanager.model.lv2.lv2_port_mixing import Lv2PortMixing -class Lv2MidiOutput(MidiOutput): +class Lv2MidiOutput(Lv2PortMixing, MidiOutput): """ Representation of a Lv2 midi output port instance. For general input use, see :class:`.MidiOutput` and :class:`.Output` classes documentation. - .. _output audio port: http://lv2plug.in/ns/lv2core/#OutputPort - :param Lv2Effect effect: Effect that contains the midi output - :param dict output: *midi output port* json representation + :param dict data: *midi output port* json representation """ - def __init__(self, effect, output): + def __init__(self, effect, data): super(Lv2MidiOutput, self).__init__(effect) - self._output = output - - def __str__(self): - return self._output['name'] + self._data = data @property - def symbol(self): - return self._output['symbol'] - - @property - def __dict__(self): - dictionary = super(Lv2MidiOutput, self).__dict__ - dictionary['index'] = self._output['index'] - - return dictionary + def data(self): + return self._data diff --git a/pluginsmanager/model/lv2/lv2_output.py b/pluginsmanager/model/lv2/lv2_output.py index 22d56ad..18e1187 100644 --- a/pluginsmanager/model/lv2/lv2_output.py +++ b/pluginsmanager/model/lv2/lv2_output.py @@ -13,9 +13,10 @@ # limitations under the License. from pluginsmanager.model.output import Output +from pluginsmanager.model.lv2.lv2_port_mixing import Lv2PortMixing -class Lv2Output(Output): +class Lv2Output(Lv2PortMixing, Output): """ Representation of a Lv2 `output audio port`_ instance. @@ -24,23 +25,13 @@ class Lv2Output(Output): .. _output audio port: http://lv2plug.in/ns/lv2core/#OutputPort :param Lv2Effect effect: Effect that contains the output - :param dict effect_output: *output audio port* json representation + :param dict data: *output audio port* json representation """ - def __init__(self, effect, effect_output): + def __init__(self, effect, data): super(Lv2Output, self).__init__(effect) - self._output = effect_output - - def __str__(self): - return self._output['name'] - - @property - def symbol(self): - return self._output['symbol'] + self._data = data @property - def __dict__(self): - dictionary = super(Lv2Output, self).__dict__ - dictionary['index'] = self._output['index'] - - return dictionary + def data(self): + return self._data diff --git a/pluginsmanager/model/lv2/lv2_port_mixing.py b/pluginsmanager/model/lv2/lv2_port_mixing.py new file mode 100644 index 0000000..15db289 --- /dev/null +++ b/pluginsmanager/model/lv2/lv2_port_mixing.py @@ -0,0 +1,50 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from abc import ABCMeta, abstractmethod + + +class Lv2PortMixing(object, metaclass=ABCMeta): + """ + Contains the default implementation of System ports: + :class:`.Lv2Input`, :class:`.Lv2Output`, + :class:`.Lv2MidiInput` and :class:`.Lv2MidiInput` + """ + + def __init__(self, *args, **kwargs): + super(Lv2PortMixing, self).__init__(*args, **kwargs) + self._data = None + + @property + @abstractmethod + def data(self): + """ + :return dict: Metadata used for provide the required information + in this object + """ + pass + + def __str__(self): + return self.data['name'] + + @property + def symbol(self): + return self.data['symbol'] + + @property + def __dict__(self): + dictionary = super(Lv2PortMixing, self).__dict__ + dictionary['index'] = self.data['index'] + + return dictionary diff --git a/pluginsmanager/model/output.py b/pluginsmanager/model/output.py index 7c435d4..590a439 100644 --- a/pluginsmanager/model/output.py +++ b/pluginsmanager/model/output.py @@ -99,8 +99,9 @@ def disconnect(self, effect_input): :param Input effect_input: Input that will be disconnected with it """ - if self._unique_for_all_pedalboards and effect_input._unique_for_all_pedalboards: - error = "Isn't possible connect this way. Please use pedalboard.connect(Connection(output, input))" + if self.effect.is_unique_for_all_pedalboards and effect_input.effect.is_unique_for_all_pedalboards: + error = "Isn't possible disconnect ports that both are from effects uniques for all pedalboards. " + error += "Please use `del pedalboard.connections[connection.index]`" raise ConnectionError(error) self.effect.pedalboard.connections.remove(Connection(self, effect_input)) diff --git a/pluginsmanager/model/system/system_port_mixing.py b/pluginsmanager/model/system/system_port_mixing.py index c0b2321..33cc1a3 100644 --- a/pluginsmanager/model/system/system_port_mixing.py +++ b/pluginsmanager/model/system/system_port_mixing.py @@ -20,26 +20,17 @@ class SystemPortMixing(object, metaclass=ABCMeta): Contains the default implementation of System ports: :class:`.SystemInput`, :class:`.SystemOutput`, :class:`.SystemMidiInput` and :class:`.SystemMidiInput` - - If you uses it, in the class constructor is necessary - define the symbol (`string`):: - - class MySystemPort(SystemPortMixing, InputPort): - def __init__(self, effect): - super(MySystemPort, self).__init__(effect) - self._symbol = 'symbol' """ def __init__(self, *args, **kwargs): super(SystemPortMixing, self).__init__(*args, **kwargs) - self._symbol = None def __str__(self): - return self._symbol + return self.symbol @property def __dict__(self): return { 'symbol': self.symbol, - 'index': self.index(), + 'index': self.index, } diff --git a/test/banks_manager_test.py b/test/banks_manager_test.py index cbf6240..3463e7c 100644 --- a/test/banks_manager_test.py +++ b/test/banks_manager_test.py @@ -139,3 +139,13 @@ def test_observers(self): manager.register(observer2) self.assertListEqual([observer1, observer2], manager.observers) + + def test_unregister(self): + observer = MagicMock() + + manager = BanksManager() + manager.register(observer) + + self.assertIn(observer, manager.observers) + manager.unregister(observer) + self.assertNotIn(observer, manager.observers) diff --git a/test/model/midi_output_test.py b/test/model/midi_output_test.py index ec336d3..8fe2f4c 100644 --- a/test/model/midi_output_test.py +++ b/test/model/midi_output_test.py @@ -119,3 +119,23 @@ def test_disconnect_system_effect(self): with self.assertRaises(ConnectionError): effect_output.disconnect(effect_input) + + def test_port_symbol(self): + builder = MidiOutputTest.builder + cctonode = builder.build('http://gareus.org/oss/lv2/midifilter#cctonote') + sys_effect = SystemEffect( + 'system', + ['capture_1'], + ['playback_1', 'playback_2'], + ['midi_capture_1'], + ['midi_playback_1'] + ) + + self.port_symbol_test(cctonode) + self.port_symbol_test(sys_effect) + + def port_symbol_test(self, effect): + port = effect.midi_outputs[0] + self.assertEqual(effect.midi_outputs[port.index], effect.midi_outputs[port.symbol]) + port = effect.midi_inputs[0] + self.assertEqual(effect.midi_inputs[port.index], effect.midi_inputs[port.symbol]) From fe55fd3d2f531ca69db6a432b4eee2501bd2f95a Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Sun, 15 Oct 2017 11:46:52 -0300 Subject: [PATCH 03/31] #57 - Improve SystemEffectBuilder and JackClient --- CHANGES | 8 +++-- makefile | 9 ++++-- pluginsmanager/jack/jack_client.py | 30 ++++++++++++++++++- pluginsmanager/model/input.py | 2 +- pluginsmanager/model/midi_input.py | 26 ++++++++++++++++ pluginsmanager/model/midi_output.py | 25 ++++++++-------- pluginsmanager/model/output.py | 2 +- .../model/system/system_effect_builder.py | 15 ++++------ 8 files changed, 88 insertions(+), 29 deletions(-) diff --git a/CHANGES b/CHANGES index eae6c87..a4299d3 100644 --- a/CHANGES +++ b/CHANGES @@ -2,17 +2,21 @@ Version 0.6.0 -- released ? ********************************** - Add makefile. Now is possible run tests and generate docs easly (`make help`); - Improve :class:`SystemInput` and :class:`SystemOutputs` documentation; - - Implementing midi support; + - `Issue #57`_ Implementing midi support; - Now :class:`Effect` list yours `midi_inputs` and `midi_outputs`; - :class:`SystemEffect` now supports `midi_inputs` and `midi_outputs`; - :class:`Lv2Effect` now supports `midi_inputs` and `midi_outputs`; - Created :class:`MidiPort`, :class:`MidiInput`, :class:`MidiOutput`; - Created :class:`SystemMidiInput`, :class:`SystemMidiOutput`; - Created :class:`Lv2MidiInput`, :class:`Lv2MidiOutput`; + - :class:`SystemEffectBuilder` now creates :class:`SystemEffect` with your midi outputs and midi inputs; - Fix autosaver_test creation folder. Now is more easily configure test workspace; - Refactored :class:`Input`, :class:`Output`: Created :class:`Port` for remove duplicated code; - Refactored :class:`SystemInput`, :class:`SystemOutput`: Created :class:`SystemPortMixing` for remove duplicated code; - - Refactored :class:`Lv2Input`, :class:`Lv2Output`: Created :class:`Lv2PortMixing` for remove duplicated code. + - Refactored :class:`Lv2Input`, :class:`Lv2Output`: Created :class:`Lv2PortMixing` for remove duplicated code; + - :class:`JackClient` - Add attributes: `audio_inputs`, `audio_outputs`, `midi_inputs`, `midi_outputs`. + +.. _Issue #57: https://github.com/PedalPi/PluginsManager/issues/57 Version 0.5.1 -- released 08/16/17 ********************************** diff --git a/makefile b/makefile index f98c363..ec8fa7a 100644 --- a/makefile +++ b/makefile @@ -1,16 +1,21 @@ -#https://krzysztofzuraw.com/blog/2016/makefiles-in-python-projects.html .RECIPEPREFIX += BROWSER=firefox default: run -clean: clean-pyc clean-test +clean: clean-pyc clean-test clean-build + +clean-build: + rm -rf .eggs + rm -rf build + rm -rf dist clean-pyc: find . -name '*.pyc' -exec rm --force {} + find . -name '*.pyo' -exec rm --force {} + clean-test: + rm -f .coverage rm -rf htmlcov rm -rf test/autosaver_data diff --git a/pluginsmanager/jack/jack_client.py b/pluginsmanager/jack/jack_client.py index fa8f186..8a06b75 100644 --- a/pluginsmanager/jack/jack_client.py +++ b/pluginsmanager/jack/jack_client.py @@ -62,9 +62,37 @@ def shutdown(status, reason): self.client.activate() + @property + def audio_inputs(self): + """ + :return: A list of audio input :class:`Ports`. + """ + return self.client.get_ports(is_audio=True, is_physical=True, is_input=True) + + @property + def audio_outputs(self): + """ + :return: A list of audio output :class:`Ports`. + """ + return self.client.get_ports(is_audio=True, is_physical=True, is_output=True) + + @property + def midi_inputs(self): + """ + :return: A list of MIDI input :class:`Ports`. + """ + return self.client.get_ports(is_midi=True, is_physical=True, is_input=True) + + @property + def midi_outputs(self): + """ + :return: A list of MIDI output :class:`Ports`. + """ + return self.client.get_ports(is_midi=True, is_physical=True, is_output=True) + def close(self): """ - Deactive and closes the jack client + Deactivate and closes the jack client """ self.client.deactivate() self.client.close() diff --git a/pluginsmanager/model/input.py b/pluginsmanager/model/input.py index 6c280a9..0dd9c09 100644 --- a/pluginsmanager/model/input.py +++ b/pluginsmanager/model/input.py @@ -43,7 +43,7 @@ class Input(Port, metaclass=ABCMeta): >>> my_awesome_effect.inputs[symbol] == effect_input True - For connections between effects, view :class:`pluginsmanager.connection.Connection`. + For connections between effects, view :class:`pluginsmanager.model.connection.Connection`. :param Effect effect: Effect of input """ diff --git a/pluginsmanager/model/midi_input.py b/pluginsmanager/model/midi_input.py index 08a62b9..127fd20 100644 --- a/pluginsmanager/model/midi_input.py +++ b/pluginsmanager/model/midi_input.py @@ -18,6 +18,32 @@ class MidiInput(MidiPort, metaclass=ABCMeta): + """ + MidiInput is the medium in which the midi input port will go into + effect to be processed. + + For obtains the inputs:: + + >>> cctonode + + >>> cctonode.midi_inputs + (,) + + >>> midi_input = cctonode.midi_inputs[0] + >>> midi_input + + + >>> symbol = midi_input.symbol + >>> symbol + 'midiin' + + >>> cctonode.midi_inputs[symbol] == midi_input + True + + For connections between effects, view :class:`pluginsmanager.model.connection.Connection`. + + :param Effect effect: Effect of midi input + """ @property def index(self): diff --git a/pluginsmanager/model/midi_output.py b/pluginsmanager/model/midi_output.py index e70d76f..71f50e1 100644 --- a/pluginsmanager/model/midi_output.py +++ b/pluginsmanager/model/midi_output.py @@ -20,29 +20,28 @@ class MidiOutput(Port, metaclass=ABCMeta): """ - 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). . + MidiOutput is the medium in which the midi output processed + by the effect is returned. For obtains the outputs:: - >>> my_awesome_effect - - >>> my_awesome_effect.outputs - (, ) + >>> cctonode + + >>> cctonode.outputs + (,) - >>> output = my_awesome_effect.outputs[0] - >>> output + >>> midi_output = cctonode.midi_outputs[0] + >>> midi_output - >>> symbol = my_awesome_effect.outputs[0].symbol + >>> symbol = midi_output.symbol >>> symbol - 'output_l' + 'midiout' - >>> my_awesome_effect.outputs[symbol] == output + >>> cctonode.midi_outputs[symbol] == midi_output True - For connections between effects, view :class:`.pluginsmanager.mod_host.connection.Connection`. + For connections between effects, view :class:`.pluginsmanager.model.connection.Connection`. :param Effect effect: Effect that contains the output """ diff --git a/pluginsmanager/model/output.py b/pluginsmanager/model/output.py index 590a439..669a5e8 100644 --- a/pluginsmanager/model/output.py +++ b/pluginsmanager/model/output.py @@ -42,7 +42,7 @@ class Output(Port, metaclass=ABCMeta): >>> my_awesome_effect.outputs[symbol] == output True - For connections between effects, view :class:`.pluginsmanager.mod_host.connection.Connection`. + For connections between effects, view :class:`.pluginsmanager.model.connection.Connection`. :param Effect effect: Effect that contains the output """ diff --git a/pluginsmanager/model/system/system_effect_builder.py b/pluginsmanager/model/system/system_effect_builder.py index f4c8636..949c305 100644 --- a/pluginsmanager/model/system/system_effect_builder.py +++ b/pluginsmanager/model/system/system_effect_builder.py @@ -15,6 +15,7 @@ from pluginsmanager.model.system.system_effect import SystemEffect + class SystemEffectBuilder(object): """ Automatic system physical ports detection @@ -26,13 +27,9 @@ def __init__(self, jack_client): self.client = jack_client def build(self): - inputs = [] - outputs = [] - - for port in self.client.client.get_ports(is_audio=True, is_physical=True): - if port.is_input: - inputs.append(port.shortname) - else: - outputs.append(port.shortname) + inputs = (port.shortname for port in self.client.audio_inputs) + outputs = (port.shortname for port in self.client.audio_outputs) + midi_inputs = (port.shortname for port in self.client.midi_inputs) + midi_outputs = (port.shortname for port in self.client.midi_outputs) - return SystemEffect('system', tuple(outputs), tuple(inputs)) + return SystemEffect('system', outputs, inputs, midi_outputs, midi_inputs) From 0b4d79231de931d36c1725e427398423776ebaaf Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Sun, 15 Oct 2017 14:12:14 -0300 Subject: [PATCH 04/31] #67 - Created AudioPort. Fix changelog docs --- CHANGES | 41 ++++++++------- README.rst | 4 -- docs/source/changelog.rst | 4 ++ docs/source/index.rst | 8 +++ docs/source/model.rst | 42 +++++++++++++--- makefile | 2 +- pluginsmanager/model/audio_port.py | 24 +++++++++ pluginsmanager/model/connection.py | 48 +++++++++++++----- pluginsmanager/model/effect.py | 2 +- pluginsmanager/model/input.py | 7 +-- pluginsmanager/model/midi_connection.py | 53 +++++++++++++++++++ pluginsmanager/model/midi_input.py | 3 +- pluginsmanager/model/midi_output.py | 62 +---------------------- pluginsmanager/model/output.py | 67 ++----------------------- pluginsmanager/model/pedalboard.py | 22 +++++++- test/util/persistence_decoder_test.py | 8 ++- 16 files changed, 223 insertions(+), 174 deletions(-) create mode 100644 docs/source/changelog.rst create mode 100644 pluginsmanager/model/audio_port.py create mode 100644 pluginsmanager/model/midi_connection.py diff --git a/CHANGES b/CHANGES index a4299d3..803637c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,35 +1,40 @@ -Version 0.6.0 -- released ? +Version 0.6.0 -- released 10/?/17 ********************************** - Add makefile. Now is possible run tests and generate docs easly (`make help`); - - Improve :class:`SystemInput` and :class:`SystemOutputs` documentation; + - Improve :class:`.SystemInput` and :class:`.SystemOutputs` documentation; - `Issue #57`_ Implementing midi support; - - Now :class:`Effect` list yours `midi_inputs` and `midi_outputs`; - - :class:`SystemEffect` now supports `midi_inputs` and `midi_outputs`; - - :class:`Lv2Effect` now supports `midi_inputs` and `midi_outputs`; - - Created :class:`MidiPort`, :class:`MidiInput`, :class:`MidiOutput`; - - Created :class:`SystemMidiInput`, :class:`SystemMidiOutput`; - - Created :class:`Lv2MidiInput`, :class:`Lv2MidiOutput`; - - :class:`SystemEffectBuilder` now creates :class:`SystemEffect` with your midi outputs and midi inputs; + - Now :class:`.Effect` list yours `midi_inputs` and `midi_outputs`; + - :class:`.SystemEffect` now supports `midi_inputs` and `midi_outputs`; + - :class:`.Lv2Effect` now supports `midi_inputs` and `midi_outputs`; + - Created :class:`.MidiPort`, :class:`.MidiInput`, :class:`.MidiOutput`; + - Created :class:`.SystemMidiInput`, :class:`.SystemMidiOutput`; + - Created :class:`.Lv2MidiInput`, :class:`.Lv2MidiOutput`; + - :class:`.SystemEffectBuilder` now creates :class:`.SystemEffect` with your midi outputs and midi inputs; - Fix autosaver_test creation folder. Now is more easily configure test workspace; - - Refactored :class:`Input`, :class:`Output`: Created :class:`Port` for remove duplicated code; - - Refactored :class:`SystemInput`, :class:`SystemOutput`: Created :class:`SystemPortMixing` for remove duplicated code; - - Refactored :class:`Lv2Input`, :class:`Lv2Output`: Created :class:`Lv2PortMixing` for remove duplicated code; - - :class:`JackClient` - Add attributes: `audio_inputs`, `audio_outputs`, `midi_inputs`, `midi_outputs`. + - Refactored :class:`.Input`, :class:`.Output`: Created :class:`.Port` for remove duplicated code; + - Refactored :class:`.SystemInput`, :class:`.SystemOutput`: Created :class:`.SystemPortMixing` for remove duplicated code; + - Refactored :class:`.Lv2Input`, :class:`.Lv2Output`: Created :class:`.Lv2PortMixing` for remove duplicated code; + - :class:`.JackClient` - Add attributes: `audio_inputs`, `audio_outputs`, `midi_inputs`, `midi_outputs`; + - Break change: Removed :meth:`Output.connect()` and :meth:`Output.disconnect()` :class:`.Output` methods. + Use instead :meth:`~pluginsmanager.model.pedalboard.Pedalboard.connect()`, :meth:`~pluginsmanager.model.pedalboard.Pedalboard.disconnect()` :class:`.Pedalboard` methods; + - `Issue #67`_ Created :meth:`~pluginsmanager.model.pedalboard.Pedalboard.connect()`, :meth:`~pluginsmanager.model.pedalboard.Pedalboard.disconnect()` :class:`.Pedalboard` methods; + - Fixed Changelog: Now is possible see it in the documentation. .. _Issue #57: https://github.com/PedalPi/PluginsManager/issues/57 +.. _Issue #67: https://github.com/PedalPi/PluginsManager/issues/67 Version 0.5.1 -- released 08/16/17 ********************************** - - `Issue #52`_ - :class:`Autosaver` - Change connection with :class:`SystemInput` and :class:`SystemOutput` causes error; - - `Issue #53`_ - :class:`Autosaver` - Remove effect with connections breaks. + - `Issue #52`_ - :class:`.Autosaver` - Change connection with :class:`.SystemInput` and :class:`.SystemOutput` causes error; + - `Issue #53`_ - :class:`.Autosaver` - Remove effect with connections breaks. Disable connections removed notification when a effect with connections has removed; - - :class:`Autosaver` - Add :attr:`.Observable.real_list` attribute for access the list of :class:`ObservableList`; - - `Issue #54`_ - :class:`Mod-host` - Fix `feedback_socket optional`_ problem. + - :class:`.Autosaver` - Add :attr:`.Observable.real_list` attribute for access the list of :class:`.ObservableList`; + - `Issue #54`_ - :class:`.Mod-host` - Fix `feedback_socket optional`_ problem. .. _Issue #52: https://github.com/PedalPi/PluginsManager/issues/52 .. _Issue #53: https://github.com/PedalPi/PluginsManager/issues/53 .. _Issue #54: https://github.com/PedalPi/PluginsManager/issues/54 -.. _default feedback_socket disabled: https://github.com/moddevices/mod-host/commit/31b1d04deb91c88420e1e0dd0cc4fad523f55712 +.. _feedback_socket optional: https://github.com/moddevices/mod-host/commit/31b1d04deb91c88420e1e0dd0cc4fad523f55712 Version 0.5.0 -- released 05/29/17 ********************************** diff --git a/README.rst b/README.rst index 120a534..13c094d 100644 --- a/README.rst +++ b/README.rst @@ -261,10 +261,6 @@ library can be accessed in the `Observer section `__. .. _Carla: https://github.com/falkTX/Carla -Changelog ---------- - -..include:: ../../CHANGES Maintenance ----------- diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst new file mode 100644 index 0000000..f8b67d6 --- /dev/null +++ b/docs/source/changelog.rst @@ -0,0 +1,4 @@ +Changelog +========= + +.. include:: ../../CHANGES diff --git a/docs/source/index.rst b/docs/source/index.rst index 4872ca6..5837ec3 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,5 +1,13 @@ .. include:: ../../README.rst +Changelog +--------- + +.. toctree:: + :maxdepth: 2 + + changelog + API --- diff --git a/docs/source/model.rst b/docs/source/model.rst index 8a09986..ce7d853 100644 --- a/docs/source/model.rst +++ b/docs/source/model.rst @@ -43,14 +43,10 @@ This page contains the model 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; + AudioPort->Port; - Input->Port; - Output->Port; + Input->AudioPort; + Output->AudioPort; MidiPort->Port; MidiInput->MidiPort; @@ -66,7 +62,23 @@ This page contains the model classes. SystemMidiInput->MidiInput; SystemMidiOutput->MidiOutput; + } + +.. graphviz:: + + 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; } .. graphviz:: @@ -111,6 +123,14 @@ Connection :special-members: :exclude-members: __weakref__ +MidiConnection +-------------- + +.. autoclass:: pluginsmanager.model.midi_connection.MidiConnection + :members: + :special-members: + :exclude-members: __weakref__ + Effect ------ @@ -127,6 +147,14 @@ Port :special-members: :exclude-members: __weakref__ +AudioPort +--------- + +.. autoclass:: pluginsmanager.model.audio_port.AudioPort + :members: + :special-members: + :exclude-members: __weakref__ + Input ----- diff --git a/makefile b/makefile index ec8fa7a..452e23c 100644 --- a/makefile +++ b/makefile @@ -49,7 +49,7 @@ test-details: test help: @echo " clean" - @echo " Clean the files" + @echo " Clean files" @echo " docs" @echo " Make the docs" @echo " docs-see" diff --git a/pluginsmanager/model/audio_port.py b/pluginsmanager/model/audio_port.py new file mode 100644 index 0000000..e2bf051 --- /dev/null +++ b/pluginsmanager/model/audio_port.py @@ -0,0 +1,24 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from abc import ABCMeta + +from pluginsmanager.model.port import Port + + +class AudioPort(Port, metaclass=ABCMeta): + """ + Port is a parent abstraction for audio inputs and audio outputs + """ + pass diff --git a/pluginsmanager/model/connection.py b/pluginsmanager/model/connection.py index c70cfde..2577c65 100644 --- a/pluginsmanager/model/connection.py +++ b/pluginsmanager/model/connection.py @@ -13,6 +13,9 @@ # limitations under the License. +from pluginsmanager.model.audio_port import AudioPort + + class ConnectionError(Exception): def __init__(self, message): super(ConnectionError, self).__init__(message) @@ -21,9 +24,10 @@ def __init__(self, message): class Connection(object): """ - :class:`pluginsmanager.model.connection.Connection` represents a connection between two - distinct effects by your ports (effect :class:`.Output` with effect :class:`.Input`):: + :class:`~pluginsmanager.model.connection.Connection` represents a connection between two + distinct effects by your :class:`.AudioPort` (effect :class:`.Output` with effect :class:`.Input`):: + >>> from pluginsmanager.model.pedalboard import Pedalboard >>> californication = Pedalboard('Californication') >>> californication.append(driver) >>> californication.append(reverb) @@ -42,21 +46,38 @@ class Connection(object): Another way to use implicitly connections:: - >>> guitar_output.connect(driver_input) - >>> driver_output.connect(reverb_input) - >>> reverb_output.connect(amp_input) + >>> californication.connect(guitar_output, driver_input) + >>> californication.connect(driver_output, reverb_input) + >>> californication.connect(reverb_output, amp_input) - :param Output effect_output: Output port that will be connected with input port - :param Input effect_input: Input port that will be connected with output port + :param Output output_port: Audio output port that will be connected with audio input port + :param Input input_port: Audio input port that will be connected with audio output port """ - def __init__(self, effect_output, effect_input): - if effect_output.effect == effect_input.effect\ - and not effect_output.effect.is_possible_connect_itself: - raise ConnectionError('Effect of output and effect of input are equals') + def __init__(self, output_port, input_port): + if not self._valid_instance(output_port)\ + or not self._valid_instance(input_port): + raise ConnectionError("Connection only accepts ports that inherits {}".format(self.ports_class.__name__)) + + if output_port.effect == input_port.effect\ + and not output_port.effect.is_possible_connect_itself: + effect_name = str(input_port.effect) + raise ConnectionError("The output {} and input {} are from the same effect {}. " + "This effect doesn't accept connections between itself instance." + .format(effect_name, str(output_port), str(input_port))) + + self._output = output_port + self._input = input_port - self._output = effect_output - self._input = effect_input + def _valid_instance(self, port): + return isinstance(port, self.ports_class) + + @property + def ports_class(self): + """ + :return class: Port class that this connection only accepts + """ + return AudioPort @property def output(self): @@ -101,4 +122,5 @@ def __dict__(self): return { 'output': self.output.json, 'input': self.input.json, + 'type': 'audio' } diff --git a/pluginsmanager/model/effect.py b/pluginsmanager/model/effect.py index 5bbefc1..0280537 100644 --- a/pluginsmanager/model/effect.py +++ b/pluginsmanager/model/effect.py @@ -23,7 +23,7 @@ class Effect(metaclass=ABCMeta): Representation of a audio plugin instance - LV2 plugin encapsulated as a jack client. Effect contains a `active` status (off=bypass), a list of :class:`.Param`, - a list of :class:`.Input` and a list of :class:`pluginsmanager.mod_host.connection.Connection`:: + a list of :class:`.Input` and a list of :class:`~pluginsmanager.model.connection.Connection`:: >>> reverb = builder.build('http://calf.sourceforge.net/plugins/Reverb') >>> pedalboard.append(reverb) diff --git a/pluginsmanager/model/input.py b/pluginsmanager/model/input.py index 0dd9c09..9f7754b 100644 --- a/pluginsmanager/model/input.py +++ b/pluginsmanager/model/input.py @@ -14,10 +14,10 @@ from abc import ABCMeta -from pluginsmanager.model.port import Port +from pluginsmanager.model.audio_port import AudioPort -class Input(Port, metaclass=ABCMeta): +class Input(AudioPort, metaclass=ABCMeta): """ Input is the medium in which the audio will go into effect to be processed. @@ -43,7 +43,8 @@ class Input(Port, metaclass=ABCMeta): >>> my_awesome_effect.inputs[symbol] == effect_input True - For connections between effects, view :class:`pluginsmanager.model.connection.Connection`. + For connections between effects, see :meth:`~pluginsmanager.model.pedalboard.Pedalboard.connect()` + and :meth:`~pluginsmanager.model.pedalboard.Pedalboard.disconnect()` :class:`.Pedalboard` class methods. :param Effect effect: Effect of input """ diff --git a/pluginsmanager/model/midi_connection.py b/pluginsmanager/model/midi_connection.py new file mode 100644 index 0000000..fe97605 --- /dev/null +++ b/pluginsmanager/model/midi_connection.py @@ -0,0 +1,53 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from pluginsmanager.model.connection import Connection +from pluginsmanager.model.midi_port import MidiPort + + +class MidiConnection(Connection): + """ + :class:`.MidiConnection` represents a connection between two + distinct effects by your :class:`.MidiPort` (effect :class:`.MidiOutput` with effect :class:`.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) + + :param MidiOutput output_port: MidiOutput port that will be connected with midi input port + :param MidiInput input_port: MidiInput port that will be connected with midi output port + """ + + @property + def ports_class(self): + """ + :return class: Port class that this connection only accepts + """ + return MidiPort + + @property + def __dict__(self): + dictionary = super(MidiConnection, self).__dict__ + dictionary['type'] = 'midi' + + return dictionary diff --git a/pluginsmanager/model/midi_input.py b/pluginsmanager/model/midi_input.py index 127fd20..5dc3b10 100644 --- a/pluginsmanager/model/midi_input.py +++ b/pluginsmanager/model/midi_input.py @@ -40,7 +40,8 @@ class MidiInput(MidiPort, metaclass=ABCMeta): >>> cctonode.midi_inputs[symbol] == midi_input True - For connections between effects, view :class:`pluginsmanager.model.connection.Connection`. + For connections between effects, see :meth:`~pluginsmanager.model.pedalboard.Pedalboard.connect()` + and :meth:`~pluginsmanager.model.pedalboard.Pedalboard.disconnect()` :class:`.Pedalboard` class methods. :param Effect effect: Effect of midi input """ diff --git a/pluginsmanager/model/midi_output.py b/pluginsmanager/model/midi_output.py index 71f50e1..21796fd 100644 --- a/pluginsmanager/model/midi_output.py +++ b/pluginsmanager/model/midi_output.py @@ -41,70 +41,12 @@ class MidiOutput(Port, metaclass=ABCMeta): >>> cctonode.midi_outputs[symbol] == midi_output True - For connections between effects, view :class:`.pluginsmanager.model.connection.Connection`. + For connections between effects, see :meth:`~pluginsmanager.model.pedalboard.Pedalboard.connect()` + and :meth:`~pluginsmanager.model.pedalboard.Pedalboard.disconnect()` :class:`.Pedalboard` class methods. :param Effect effect: Effect that contains the output """ - def connect(self, effect_input): - """ - Connect it with effect_input:: - - >>> driver_output = driver.outputs[0] - >>> reverb_input = reverb.inputs[0] - >>> Connection(driver_output, reverb_input) in driver.effect.connections - False - >>> driver_output.connect(reverb_input) - >>> Connection(driver_output, reverb_input) in driver.effect.connections - True - - .. note:: - - This method does not work for all cases. - class:`SystemOutput` can not be connected with class:`SystemInput` this way. - For this case, use :: - - >>> pedalboard.connections.append(Connection(system_output, system_input)) - - :param Input effect_input: Input that will be connected with it - """ - if self.effect.is_unique_for_all_pedalboards and effect_input.effect.is_unique_for_all_pedalboards: - error = "Isn't possible connect ports that both are from effects uniques for all pedalboards. " - error += "Please use pedalboard.connect(Connection(output, input))" - raise ConnectionError(error) - - pedalboard = self.effect.pedalboard if not self.effect.is_unique_for_all_pedalboards else effect_input.effect.pedalboard - pedalboard.connections.append(Connection(self, effect_input)) - - def disconnect(self, effect_input): - """ - Disconnect it with effect_input - - >>> driver_output = driver.outputs[0] - >>> reverb_input = reverb.inputs[0] - >>> Connection(driver_output, reverb_input) in driver.effect.connections - True - >>> driver_output.disconnect(reverb_input) - >>> Connection(driver_output, reverb_input) in driver.effect.connections - False - - .. note:: - - This method does not work for all cases. - class:`SystemOutput` can not be disconnected with class:`SystemInput` this way. - For this case, use :: - - >>> pedalboard.connections.remove(Connection(system_output, system_input)) - - :param Input effect_input: Input that will be disconnected with it - """ - if self.effect.is_unique_for_all_pedalboards and effect_input.effect.is_unique_for_all_pedalboards: - error = "Isn't possible connect ports that both are from effects uniques for all pedalboards. " - error += "Please use pedalboard.connect(Connection(output, input))" - raise ConnectionError(error) - - self.effect.pedalboard.connections.remove(Connection(self, effect_input)) - @property def index(self): """ diff --git a/pluginsmanager/model/output.py b/pluginsmanager/model/output.py index 669a5e8..86acbfb 100644 --- a/pluginsmanager/model/output.py +++ b/pluginsmanager/model/output.py @@ -14,11 +14,10 @@ from abc import ABCMeta -from pluginsmanager.model.connection import Connection, ConnectionError -from pluginsmanager.model.port import Port +from pluginsmanager.model.audio_port import AudioPort -class Output(Port, metaclass=ABCMeta): +class Output(AudioPort, metaclass=ABCMeta): """ Output is the medium in which the audio processed by the effect is returned. @@ -42,70 +41,12 @@ class Output(Port, metaclass=ABCMeta): >>> my_awesome_effect.outputs[symbol] == output True - For connections between effects, view :class:`.pluginsmanager.model.connection.Connection`. + For connections between effects, see :meth:`~pluginsmanager.model.pedalboard.Pedalboard.connect()` + and :meth:`~pluginsmanager.model.pedalboard.Pedalboard.disconnect()` :class:`.Pedalboard` class methods. :param Effect effect: Effect that contains the output """ - def connect(self, effect_input): - """ - Connect it with effect_input:: - - >>> driver_output = driver.outputs[0] - >>> reverb_input = reverb.inputs[0] - >>> Connection(driver_output, reverb_input) in driver.effect.connections - False - >>> driver_output.connect(reverb_input) - >>> Connection(driver_output, reverb_input) in driver.effect.connections - True - - .. note:: - - This method does not work for all cases. - class:`SystemOutput` can not be connected with class:`SystemInput` this way. - For this case, use :: - - >>> pedalboard.connections.append(Connection(system_output, system_input)) - - :param Input effect_input: Input that will be connected with it - """ - if self.effect.is_unique_for_all_pedalboards and effect_input.effect.is_unique_for_all_pedalboards: - error = "Isn't possible connect ports that both are from effects uniques for all pedalboards. " - error += "Please use pedalboard.connect(Connection(output, input))" - raise ConnectionError(error) - - pedalboard = self.effect.pedalboard if not self.effect.is_unique_for_all_pedalboards else effect_input.effect.pedalboard - pedalboard.connections.append(Connection(self, effect_input)) - - def disconnect(self, effect_input): - """ - Disconnect it with effect_input - - >>> driver_output = driver.outputs[0] - >>> reverb_input = reverb.inputs[0] - >>> Connection(driver_output, reverb_input) in driver.effect.connections - True - >>> driver_output.disconnect(reverb_input) - >>> Connection(driver_output, reverb_input) in driver.effect.connections - False - - .. note:: - - This method does not work for all cases. - class:`SystemOutput` can not be disconnected with class:`SystemInput` this way. - For this case, use :: - - >>> pedalboard.connections.remove(Connection(system_output, system_input)) - - :param Input effect_input: Input that will be disconnected with it - """ - if self.effect.is_unique_for_all_pedalboards and effect_input.effect.is_unique_for_all_pedalboards: - error = "Isn't possible disconnect ports that both are from effects uniques for all pedalboards. " - error += "Please use `del pedalboard.connections[connection.index]`" - raise ConnectionError(error) - - self.effect.pedalboard.connections.remove(Connection(self, effect_input)) - @property def index(self): """ diff --git a/pluginsmanager/model/pedalboard.py b/pluginsmanager/model/pedalboard.py index 002dec9..0d385df 100644 --- a/pluginsmanager/model/pedalboard.py +++ b/pluginsmanager/model/pedalboard.py @@ -21,7 +21,7 @@ class Pedalboard(object): """ Pedalboard is a patch representation: your structure contains - :class:`.Effect` and :class:`pluginsmanager.mod_host.connection.Connection`:: + :class:`.Effect` and :class:`~pluginsmanager.model.connection.Connection`:: >>> pedalboard = Pedalboard('Rocksmith') >>> bank.append(pedalboard) @@ -42,7 +42,8 @@ class Pedalboard(object): >>> 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 - >>> reverb.outputs[1].connect(sys_effect.inputs[0]) + >>> pedalboard.connect(reverb.outputs[1], sys_effect.inputs[0]) + >>> pedalboard.connections ObservableList: [ GxFuzzFaceFullerMod.In' at 0x7f60f45f3f60>, Calf Reverb.In L' at 0x7f60f45f57f0>, system.playback_1' at 0x7f60f45dacc0>] >>> pedalboard.data @@ -187,3 +188,20 @@ def index(self): raise IndexError('Pedalboard not contains a bank') return self.bank.pedalboards.index(self) + + def connect(self, output_port, input_port): + + """ + :param output_port: + :param input_port: + :return: + """ + pass + + def disconnect(self, output_port, input_port): + """ + :param output_port: + :param input_port: + :return: + """ + pass diff --git a/test/util/persistence_decoder_test.py b/test/util/persistence_decoder_test.py index afadab1..331e7ae 100644 --- a/test/util/persistence_decoder_test.py +++ b/test/util/persistence_decoder_test.py @@ -33,7 +33,7 @@ def setUpClass(cls): @property def bank(self): - sys_effect = SystemEffect('system', ('capture_1', 'capture_2'), ('playback_1', 'playback_2')) + sys_effect = SystemEffect('system', ('capture_1', 'capture_2'), ('playback_1', 'playback_2'), ('midi_out',), ('midi_in',)) bank = Bank('Bank 1') pedalboard = Pedalboard('Pedalboard 1') @@ -44,16 +44,20 @@ def bank(self): reverb = self.builder.build('http://calf.sourceforge.net/plugins/Reverb') filter = self.builder.build('http://calf.sourceforge.net/plugins/Filter') reverb2 = self.builder.build('http://calf.sourceforge.net/plugins/Reverb') + cctonode = self.builder.build('http://gareus.org/oss/lv2/midifilter#cctonote') pedalboard.append(reverb) pedalboard.append(filter) pedalboard.append(reverb2) + pedalboard.append(cctonode) reverb.outputs[0].connect(filter.inputs[0]) reverb.outputs[1].connect(filter.inputs[0]) filter.outputs[0].connect(reverb2.inputs[0]) reverb.outputs[0].connect(reverb2.inputs[0]) + cctonode.midi_outputs[0].connect(sys_effect.midi_inputs[0]) + pedalboard.connections.append(Connection(sys_effect.outputs[0], reverb.inputs[0])) pedalboard.connections.append(Connection(reverb2.outputs[0], sys_effect.inputs[0])) @@ -68,6 +72,8 @@ def test_read(self): util = PersistenceDecoder(system_effect) bank = self.bank + import pprint + pprint.pprint(bank.json) bank_readed = util.read(bank.json) self.maxDiff = None From d85dd38829086423192dafa1acf58052f38a17cc Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Sun, 15 Oct 2017 15:15:09 -0300 Subject: [PATCH 05/31] #67 - created Pedalboard.connect() and Pedalboard.disconnect(). Removed Output.connect() and Output.disconnect() --- pluginsmanager/model/audio_port.py | 9 +++++++- pluginsmanager/model/midi_output.py | 5 ++-- pluginsmanager/model/midi_port.py | 8 +++++++ pluginsmanager/model/pedalboard.py | 7 +++--- pluginsmanager/model/port.py | 8 +++++++ test/banks_manager_test.py | 8 +++---- test/mod_host/mod_host_test.py | 12 +++++----- test/model/bank_test.py | 12 +++++----- test/model/effect_test.py | 8 +++---- test/model/midi_output_test.py | 33 +++++++++------------------ test/model/output_test.py | 31 +++++++++++-------------- test/model/pedalboard_test.py | 9 ++++---- test/observer/autosaver_test.py | 12 +++++----- test/util/persistence_decoder_test.py | 10 ++++---- 14 files changed, 89 insertions(+), 83 deletions(-) diff --git a/pluginsmanager/model/audio_port.py b/pluginsmanager/model/audio_port.py index e2bf051..accadea 100644 --- a/pluginsmanager/model/audio_port.py +++ b/pluginsmanager/model/audio_port.py @@ -21,4 +21,11 @@ class AudioPort(Port, metaclass=ABCMeta): """ Port is a parent abstraction for audio inputs and audio outputs """ - pass + + @property + def connection_class(self): + """ + :return Connection: Class used for connections in this port + """ + from pluginsmanager.model.connection import Connection + return Connection diff --git a/pluginsmanager/model/midi_output.py b/pluginsmanager/model/midi_output.py index 21796fd..878c7b8 100644 --- a/pluginsmanager/model/midi_output.py +++ b/pluginsmanager/model/midi_output.py @@ -14,11 +14,10 @@ from abc import ABCMeta -from pluginsmanager.model.connection import Connection, ConnectionError -from pluginsmanager.model.port import Port +from pluginsmanager.model.midi_port import MidiPort -class MidiOutput(Port, metaclass=ABCMeta): +class MidiOutput(MidiPort, metaclass=ABCMeta): """ MidiOutput is the medium in which the midi output processed by the effect is returned. diff --git a/pluginsmanager/model/midi_port.py b/pluginsmanager/model/midi_port.py index a43e2b9..37177de 100644 --- a/pluginsmanager/model/midi_port.py +++ b/pluginsmanager/model/midi_port.py @@ -22,3 +22,11 @@ class MidiPort(Port, metaclass=ABCMeta): Port is a parent abstraction for midi inputs and midi outputs """ pass + + @property + def connection_class(self): + """ + :return MidiConnection: Class used for connections in this port + """ + from pluginsmanager.model.midi_connection import MidiConnection + return MidiConnection diff --git a/pluginsmanager/model/pedalboard.py b/pluginsmanager/model/pedalboard.py index 0d385df..acfafe3 100644 --- a/pluginsmanager/model/pedalboard.py +++ b/pluginsmanager/model/pedalboard.py @@ -190,13 +190,13 @@ def index(self): return self.bank.pedalboards.index(self) def connect(self, output_port, input_port): - """ :param output_port: :param input_port: :return: """ - pass + ConnectionClass = output_port.connection_class + self.connections.append(ConnectionClass(output_port, input_port)) def disconnect(self, output_port, input_port): """ @@ -204,4 +204,5 @@ def disconnect(self, output_port, input_port): :param input_port: :return: """ - pass + ConnectionClass = output_port.connection_class + self.connections.remove(ConnectionClass(output_port, input_port)) diff --git a/pluginsmanager/model/port.py b/pluginsmanager/model/port.py index e2f5b8d..1404c6d 100644 --- a/pluginsmanager/model/port.py +++ b/pluginsmanager/model/port.py @@ -76,3 +76,11 @@ def __repr__(self): str(self), id(self) ) + + @property + @abstractmethod + def connection_class(self): + """ + :return: Class used for connections in this port + """ + pass diff --git a/test/banks_manager_test.py b/test/banks_manager_test.py index 3463e7c..ac58e6f 100644 --- a/test/banks_manager_test.py +++ b/test/banks_manager_test.py @@ -51,25 +51,25 @@ def test_observers_calls(self): pedalboard.append(reverb2) observer.on_effect_updated.assert_called_with(reverb2, UpdateType.CREATED, index=reverb2.index, origin=pedalboard) - reverb.outputs[0].connect(filter.inputs[0]) + pedalboard.connect(reverb.outputs[0], filter.inputs[0]) observer.on_connection_updated.assert_called_with( Connection(reverb.outputs[0], filter.inputs[0]), UpdateType.CREATED, pedalboard=pedalboard ) - reverb.outputs[1].connect(filter.inputs[0]) + pedalboard.connect(reverb.outputs[1], filter.inputs[0]) observer.on_connection_updated.assert_called_with( Connection(reverb.outputs[1], filter.inputs[0]), UpdateType.CREATED, pedalboard=pedalboard ) - filter.outputs[0].connect(reverb2.inputs[0]) + pedalboard.connect(filter.outputs[0], reverb2.inputs[0]) observer.on_connection_updated.assert_called_with( Connection(filter.outputs[0], reverb2.inputs[0]), UpdateType.CREATED, pedalboard=pedalboard ) - reverb.outputs[0].connect(reverb2.inputs[0]) + pedalboard.connect(reverb.outputs[0], reverb2.inputs[0]) observer.on_connection_updated.assert_called_with( Connection(reverb.outputs[0], reverb2.inputs[0]), UpdateType.CREATED, diff --git a/test/mod_host/mod_host_test.py b/test/mod_host/mod_host_test.py index 6e08575..25bae66 100644 --- a/test/mod_host/mod_host_test.py +++ b/test/mod_host/mod_host_test.py @@ -100,15 +100,15 @@ def test_observers_mock(self): pedalboard.append(filter) pedalboard.append(reverb2) - reverb.outputs[0].connect(filter.inputs[0]) - reverb.outputs[1].connect(filter.inputs[0]) - filter.outputs[0].connect(reverb2.inputs[0]) - reverb.outputs[0].connect(reverb2.inputs[0]) + pedalboard.connect(reverb.outputs[0], filter.inputs[0]) + pedalboard.connect(reverb.outputs[1], filter.inputs[0]) + pedalboard.connect(filter.outputs[0], reverb2.inputs[0]) + pedalboard.connect(reverb.outputs[0], reverb2.inputs[0]) filter.toggle() filter.params[0].value = (filter.params[0].maximum - filter.params[0].minimum) / 2 - filter.outputs[0].disconnect(reverb2.inputs[0]) + pedalboard.disconnect(filter.outputs[0], reverb2.inputs[0]) filter.toggle() pedalboard.effects.remove(filter) @@ -217,4 +217,4 @@ def test_connection_not_current_pedalboard(self): mod_host.pedalboard = pedalboard - pedalboard2.effects[0].outputs[0].connect(pedalboard2.effects[1].inputs[0]) + pedalboard2.connect(pedalboard2.effects[0].outputs[0], pedalboard2.effects[1].inputs[0]) diff --git a/test/model/bank_test.py b/test/model/bank_test.py index 585e8e8..0a54dec 100644 --- a/test/model/bank_test.py +++ b/test/model/bank_test.py @@ -105,12 +105,12 @@ def test_json(self): pedalboard.append(filter) pedalboard.append(reverb2) - system_effect.outputs[0].connect(reverb.inputs[0]) - reverb.outputs[0].connect(filter.inputs[0]) - reverb.outputs[1].connect(filter.inputs[0]) - filter.outputs[0].connect(reverb2.inputs[0]) - reverb.outputs[0].connect(reverb2.inputs[0]) - reverb.outputs[0].connect(system_effect.inputs[0]) + pedalboard.connect(system_effect.outputs[0], reverb.inputs[0]) + pedalboard.connect(reverb.outputs[0], filter.inputs[0]) + pedalboard.connect(reverb.outputs[1], filter.inputs[0]) + pedalboard.connect(filter.outputs[0], reverb2.inputs[0]) + pedalboard.connect(reverb.outputs[0], reverb2.inputs[0]) + pedalboard.connect(reverb.outputs[0], system_effect.inputs[0]) bank.append(pedalboard) diff --git a/test/model/effect_test.py b/test/model/effect_test.py index d26840b..143d511 100644 --- a/test/model/effect_test.py +++ b/test/model/effect_test.py @@ -71,10 +71,10 @@ def test_connections_effect_remove_your_connections(self): pedalboard.append(filter) pedalboard.append(reverb2) - reverb.outputs[0].connect(filter.inputs[0]) - reverb.outputs[1].connect(filter.inputs[0]) - filter.outputs[0].connect(reverb2.inputs[0]) - reverb.outputs[0].connect(reverb2.inputs[0]) + pedalboard.connect(reverb.outputs[0], filter.inputs[0]) + pedalboard.connect(reverb.outputs[1], filter.inputs[0]) + pedalboard.connect(filter.outputs[0], reverb2.inputs[0]) + pedalboard.connect(reverb.outputs[0], reverb2.inputs[0]) reverb_connections = ( Connection(reverb.outputs[0], filter.inputs[0]), diff --git a/test/model/midi_output_test.py b/test/model/midi_output_test.py index 8fe2f4c..e2afc05 100644 --- a/test/model/midi_output_test.py +++ b/test/model/midi_output_test.py @@ -41,13 +41,13 @@ def test_connect(self): pedalboard.append(cctonode2) self.assertEqual(0, len(pedalboard.connections)) - cctonode.midi_outputs[0].connect(cctonode2.midi_inputs[0]) + pedalboard.connect(cctonode.midi_outputs[0], cctonode2.midi_inputs[0]) self.assertEqual(1, len(pedalboard.connections)) new_connection = pedalboard.connections[0] pedalboard.observer.on_connection_updated.assert_called_with(new_connection, UpdateType.CREATED, pedalboard=pedalboard) - cctonode.midi_outputs[0].connect(cctonode2.midi_inputs[0]) + pedalboard.connect(cctonode.midi_outputs[0], cctonode2.midi_inputs[0]) self.assertEqual(2, len(pedalboard.connections)) new_connection = pedalboard.connections[-1] @@ -63,13 +63,13 @@ def test_disconnect(self): pedalboard.append(cctonode) pedalboard.append(cctonode2) - cctonode.midi_outputs[0].connect(cctonode2.midi_inputs[0]) + pedalboard.connect(cctonode.midi_outputs[0], cctonode2.midi_inputs[0]) self.assertEqual(1, len(pedalboard.connections)) pedalboard.observer = MagicMock() disconnected = pedalboard.connections[-1] - cctonode.midi_outputs[0].disconnect(cctonode2.midi_inputs[0]) + pedalboard.disconnect(cctonode.midi_outputs[0], cctonode2.midi_inputs[0]) self.assertEqual(0, len(pedalboard.connections)) pedalboard.observer.on_connection_updated.assert_called_with(disconnected, UpdateType.DELETED, pedalboard=pedalboard) @@ -86,11 +86,12 @@ def test_disconnect_connection_not_created(self): pedalboard.observer = MagicMock() with self.assertRaises(ValueError): - cctonode.midi_outputs[0].disconnect(cctonode2.midi_inputs[0]) + pedalboard.disconnect(cctonode.midi_outputs[0], cctonode2.midi_inputs[0]) pedalboard.observer.on_connection_updated.assert_not_called() - def test_connect_system_effect(self): + def test_system_effect_connections(self): + pedalboard = Pedalboard('A pedalboard') sys_effect = SystemEffect( 'system', ['capture_1'], @@ -102,23 +103,11 @@ def test_connect_system_effect(self): effect_output = sys_effect.midi_outputs[0] effect_input = sys_effect.midi_inputs[0] - with self.assertRaises(ConnectionError): - effect_output.connect(effect_input) + pedalboard.connect(effect_output, effect_input) + self.assertEqual(len(pedalboard.connections), 1) - def test_disconnect_system_effect(self): - sys_effect = SystemEffect( - 'system', - ['capture_1'], - ['playback_1', 'playback_2'], - ['midi_capture_1'], - ['midi_playback_1'] - ) - - effect_output = sys_effect.midi_outputs[0] - effect_input = sys_effect.midi_inputs[0] - - with self.assertRaises(ConnectionError): - effect_output.disconnect(effect_input) + pedalboard.disconnect(effect_output, effect_input) + self.assertEqual(len(pedalboard.connections), 0) def test_port_symbol(self): builder = MidiOutputTest.builder diff --git a/test/model/output_test.py b/test/model/output_test.py index f91164c..8617760 100644 --- a/test/model/output_test.py +++ b/test/model/output_test.py @@ -41,13 +41,13 @@ def test_connect(self): pedalboard.append(reverb2) self.assertEqual(0, len(pedalboard.connections)) - reverb.outputs[0].connect(reverb2.inputs[0]) + pedalboard.connect(reverb.outputs[0], reverb2.inputs[0]) self.assertEqual(1, len(pedalboard.connections)) new_connection = pedalboard.connections[0] pedalboard.observer.on_connection_updated.assert_called_with(new_connection, UpdateType.CREATED, pedalboard=pedalboard) - reverb.outputs[1].connect(reverb2.inputs[1]) + pedalboard.connect(reverb.outputs[1], reverb2.inputs[1]) self.assertEqual(2, len(pedalboard.connections)) new_connection = pedalboard.connections[-1] @@ -63,19 +63,19 @@ def test_disconnect(self): pedalboard.append(reverb) pedalboard.append(reverb2) - reverb.outputs[0].connect(reverb2.inputs[0]) - reverb.outputs[1].connect(reverb2.inputs[0]) + pedalboard.connect(reverb.outputs[0], reverb2.inputs[0]) + pedalboard.connect(reverb.outputs[1], reverb2.inputs[0]) self.assertEqual(2, len(pedalboard.connections)) pedalboard.observer = MagicMock() disconnected = pedalboard.connections[-1] - reverb.outputs[1].disconnect(reverb2.inputs[0]) + pedalboard.disconnect(reverb.outputs[1], reverb2.inputs[0]) self.assertEqual(1, len(pedalboard.connections)) pedalboard.observer.on_connection_updated.assert_called_with(disconnected, UpdateType.DELETED, pedalboard=pedalboard) disconnected = pedalboard.connections[-1] - reverb.outputs[0].disconnect(reverb2.inputs[0]) + pedalboard.disconnect(reverb.outputs[0], reverb2.inputs[0]) self.assertEqual(0, len(pedalboard.connections)) pedalboard.observer.on_connection_updated.assert_called_with(disconnected, UpdateType.DELETED, pedalboard=pedalboard) @@ -92,24 +92,19 @@ def test_disconnect_connection_not_created(self): pedalboard.observer = MagicMock() with self.assertRaises(ValueError): - reverb.outputs[1].disconnect(reverb2.inputs[0]) + pedalboard.disconnect(reverb.outputs[1], reverb2.inputs[0]) pedalboard.observer.on_connection_updated.assert_not_called() - def test_connect_system_effect(self): + def test_system_effect_connections(self): + pedalboard = Pedalboard('A pedalboard') sys_effect = SystemEffect('system', ['capture_1'], ['playback_1', 'playback_2']) effect_output = sys_effect.outputs[0] effect_input = sys_effect.inputs[0] - with self.assertRaises(ConnectionError): - effect_output.connect(effect_input) + pedalboard.connect(effect_output, effect_input) + self.assertEqual(len(pedalboard.connections), 1) - def test_disconnect_system_effect(self): - sys_effect = SystemEffect('system', ['capture_1'], ['playback_1', 'playback_2']) - - effect_output = sys_effect.outputs[0] - effect_input = sys_effect.inputs[0] - - with self.assertRaises(ConnectionError): - effect_output.disconnect(effect_input) + pedalboard.disconnect(effect_output, effect_input) + self.assertEqual(len(pedalboard.connections), 0) diff --git a/test/model/pedalboard_test.py b/test/model/pedalboard_test.py index f67a027..cf0036f 100644 --- a/test/model/pedalboard_test.py +++ b/test/model/pedalboard_test.py @@ -152,15 +152,14 @@ def test_delete_effect_remove_your_connections(self): pedalboard.append(filter) pedalboard.append(reverb2) - reverb.outputs[0].connect(filter.inputs[0]) - reverb.outputs[1].connect(filter.inputs[0]) - filter.outputs[0].connect(reverb2.inputs[0]) - reverb.outputs[0].connect(reverb2.inputs[0]) + pedalboard.connect(reverb.outputs[0], filter.inputs[0]) + pedalboard.connect(reverb.outputs[1], filter.inputs[0]) + pedalboard.connect(filter.outputs[0], reverb2.inputs[0]) + pedalboard.connect(reverb.outputs[0], reverb2.inputs[0]) self.assertEqual(4, len(pedalboard.connections)) pedalboard.observer = MagicMock() - fuzz_connections = filter.connections pedalboard.effects.remove(filter) diff --git a/test/observer/autosaver_test.py b/test/observer/autosaver_test.py index 7d69711..ae30f56 100644 --- a/test/observer/autosaver_test.py +++ b/test/observer/autosaver_test.py @@ -64,16 +64,16 @@ def test_observers(self): save_mock.assert_called_with(bank) save_mock.reset_mock() - reverb.outputs[0].connect(filter.inputs[0]) + pedalboard.connect(reverb.outputs[0], filter.inputs[0]) save_mock.assert_called_with(bank) save_mock.reset_mock() - reverb.outputs[1].connect(filter.inputs[0]) + pedalboard.connect(reverb.outputs[1], filter.inputs[0]) save_mock.assert_called_with(bank) save_mock.reset_mock() - filter.outputs[0].connect(reverb2.inputs[0]) + pedalboard.connect(filter.outputs[0], reverb2.inputs[0]) save_mock.assert_called_with(bank) save_mock.reset_mock() - reverb.outputs[0].connect(reverb2.inputs[0]) + pedalboard.connect(reverb.outputs[0], reverb2.inputs[0]) save_mock.assert_called_with(bank) save_mock.reset_mock() @@ -198,8 +198,8 @@ def test_connections_effect_removed(self): bank.append(pedalboard) pedalboard.append(reverb) - reverb.outputs[0].connect(system_effect.inputs[0]) - reverb.outputs[0].connect(system_effect.inputs[1]) + pedalboard.connect(reverb.outputs[0], system_effect.inputs[0]) + pedalboard.connect(reverb.outputs[0], system_effect.inputs[1]) pedalboard.effects.remove(reverb) diff --git a/test/util/persistence_decoder_test.py b/test/util/persistence_decoder_test.py index 331e7ae..6f490ec 100644 --- a/test/util/persistence_decoder_test.py +++ b/test/util/persistence_decoder_test.py @@ -51,12 +51,12 @@ def bank(self): pedalboard.append(reverb2) pedalboard.append(cctonode) - reverb.outputs[0].connect(filter.inputs[0]) - reverb.outputs[1].connect(filter.inputs[0]) - filter.outputs[0].connect(reverb2.inputs[0]) - reverb.outputs[0].connect(reverb2.inputs[0]) + pedalboard.connect(reverb.outputs[0], filter.inputs[0]) + pedalboard.connect(reverb.outputs[1], filter.inputs[0]) + pedalboard.connect(filter.outputs[0], reverb2.inputs[0]) + pedalboard.connect(reverb.outputs[0], reverb2.inputs[0]) - cctonode.midi_outputs[0].connect(sys_effect.midi_inputs[0]) + pedalboard.connect(cctonode.midi_outputs[0], sys_effect.midi_inputs[0]) pedalboard.connections.append(Connection(sys_effect.outputs[0], reverb.inputs[0])) pedalboard.connections.append(Connection(reverb2.outputs[0], sys_effect.inputs[0])) From e85ee5e9eb4e48544bf709ffb6f09b87fafe2708 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Sun, 15 Oct 2017 18:00:32 -0300 Subject: [PATCH 06/31] #38 #67 #57 - Raise erros then add sys_effect in any Pedalboard --- CHANGES | 8 +++-- pluginsmanager/model/connection.py | 2 +- pluginsmanager/model/pedalboard.py | 8 +++++ pluginsmanager/util/builder/builder.py | 16 +++++++++- .../util/builder/lv2_json_builder.py | 9 +++++- .../util/builder/system_json_builder.py | 8 +++++ pluginsmanager/util/persistence_decoder.py | 17 ++++++----- test/model/connection_test.py | 12 ++++++++ test/model/pedalboard_test.py | 30 +++++++++++++------ test/util/persistence_decoder_test.py | 25 ++++++++-------- 10 files changed, 101 insertions(+), 34 deletions(-) diff --git a/CHANGES b/CHANGES index 803637c..c02c881 100644 --- a/CHANGES +++ b/CHANGES @@ -2,7 +2,7 @@ Version 0.6.0 -- released 10/?/17 ********************************** - Add makefile. Now is possible run tests and generate docs easly (`make help`); - Improve :class:`.SystemInput` and :class:`.SystemOutputs` documentation; - - `Issue #57`_ Implementing midi support; + - `Issue #57`_ - Implementing midi support: - Now :class:`.Effect` list yours `midi_inputs` and `midi_outputs`; - :class:`.SystemEffect` now supports `midi_inputs` and `midi_outputs`; - :class:`.Lv2Effect` now supports `midi_inputs` and `midi_outputs`; @@ -17,9 +17,11 @@ Version 0.6.0 -- released 10/?/17 - :class:`.JackClient` - Add attributes: `audio_inputs`, `audio_outputs`, `midi_inputs`, `midi_outputs`; - Break change: Removed :meth:`Output.connect()` and :meth:`Output.disconnect()` :class:`.Output` methods. Use instead :meth:`~pluginsmanager.model.pedalboard.Pedalboard.connect()`, :meth:`~pluginsmanager.model.pedalboard.Pedalboard.disconnect()` :class:`.Pedalboard` methods; - - `Issue #67`_ Created :meth:`~pluginsmanager.model.pedalboard.Pedalboard.connect()`, :meth:`~pluginsmanager.model.pedalboard.Pedalboard.disconnect()` :class:`.Pedalboard` methods; - - Fixed Changelog: Now is possible see it in the documentation. + - `Issue #67`_ - Created :meth:`~pluginsmanager.model.pedalboard.Pedalboard.connect()`, :meth:`~pluginsmanager.model.pedalboard.Pedalboard.disconnect()` :class:`.Pedalboard` methods; + - Fixed Changelog: Now is possible see it in the documentation; + - `Issue #38`_ - Raise erros then add sys_effect in any Pedalboard. +.. _Issue #38: https://github.com/PedalPi/PluginsManager/issues/38 .. _Issue #57: https://github.com/PedalPi/PluginsManager/issues/57 .. _Issue #67: https://github.com/PedalPi/PluginsManager/issues/67 diff --git a/pluginsmanager/model/connection.py b/pluginsmanager/model/connection.py index 2577c65..6fabd4c 100644 --- a/pluginsmanager/model/connection.py +++ b/pluginsmanager/model/connection.py @@ -57,7 +57,7 @@ class Connection(object): def __init__(self, output_port, input_port): if not self._valid_instance(output_port)\ or not self._valid_instance(input_port): - raise ConnectionError("Connection only accepts ports that inherits {}".format(self.ports_class.__name__)) + raise ConnectionError("'{}' only accepts ports that inherits {}".format(self.__class__.__name__, self.ports_class.__name__)) if output_port.effect == input_port.effect\ and not output_port.effect.is_possible_connect_itself: diff --git a/pluginsmanager/model/pedalboard.py b/pluginsmanager/model/pedalboard.py index acfafe3..36327c6 100644 --- a/pluginsmanager/model/pedalboard.py +++ b/pluginsmanager/model/pedalboard.py @@ -18,6 +18,10 @@ from unittest.mock import MagicMock +class PedalboardError(Exception): + pass + + class Pedalboard(object): """ Pedalboard is a patch representation: your structure contains @@ -151,6 +155,10 @@ def append(self, effect): :param Effect effect: Effect that will be added """ + if effect.is_unique_for_all_pedalboards: + raise PedalboardError("The effect '{}' is unique for all pedalboards. " + "Then, isn't allowed add it in any pedalboard.".format(str(effect))) + self.effects.append(effect) @property diff --git a/pluginsmanager/util/builder/builder.py b/pluginsmanager/util/builder/builder.py index 84d8835..3580f60 100644 --- a/pluginsmanager/util/builder/builder.py +++ b/pluginsmanager/util/builder/builder.py @@ -34,7 +34,21 @@ def build_input(self, json): @abstractmethod def build_output(self, json): """ - :return Output: Input of an effect defined in json + :return Output: Output of an effect defined in json + """ + pass + + @abstractmethod + def build_midi_input(self, json): + """ + :return MidiInput: MidiInput of an effect defined in json + """ + pass + + @abstractmethod + def build_midi_output(self, json): + """ + :return MidiOutput: MidiOutput of an effect defined in json """ pass diff --git a/pluginsmanager/util/builder/lv2_json_builder.py b/pluginsmanager/util/builder/lv2_json_builder.py index 7e51fac..a890bfa 100644 --- a/pluginsmanager/util/builder/lv2_json_builder.py +++ b/pluginsmanager/util/builder/lv2_json_builder.py @@ -30,6 +30,14 @@ def build_output(self, json): symbol = json['symbol'] return self.get_effect(json).outputs[symbol] + def build_midi_input(self, json): + symbol = json['symbol'] + return self.get_effect(json).midi_inputs[symbol] + + def build_midi_output(self, json): + symbol = json['symbol'] + return self.get_effect(json).midi_outputs[symbol] + def get_effect(self, json): effect_index = json['effect'] return self.pedalboard.effects[effect_index] @@ -51,4 +59,3 @@ def build(self, json): effect.active = json['active'] return effect - diff --git a/pluginsmanager/util/builder/system_json_builder.py b/pluginsmanager/util/builder/system_json_builder.py index 35cb394..f2ab3ab 100644 --- a/pluginsmanager/util/builder/system_json_builder.py +++ b/pluginsmanager/util/builder/system_json_builder.py @@ -30,3 +30,11 @@ def build_input(self, json): def build_output(self, json): symbol = json['symbol'] return self.system_effect.outputs[symbol] + + def build_midi_input(self, json): + symbol = json['symbol'] + return self.system_effect.midi_inputs[symbol] + + def build_midi_output(self, json): + symbol = json['symbol'] + return self.system_effect.midi_outputs[symbol] diff --git a/pluginsmanager/util/persistence_decoder.py b/pluginsmanager/util/persistence_decoder.py index 289478f..1ae002f 100644 --- a/pluginsmanager/util/persistence_decoder.py +++ b/pluginsmanager/util/persistence_decoder.py @@ -13,10 +13,8 @@ # limitations under the License. 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 as Lv2LilvEffectBuilder +from pluginsmanager.model.pedalboard import Pedalboard from pluginsmanager.util.builder.lv2_json_builder import Lv2AudioPortBuilder, Lv2EffectBuilder from pluginsmanager.util.builder.system_json_builder import SystemAudioPortBuilder @@ -67,7 +65,8 @@ def read(self, json): connection_reader = ConnectionReader(pedalboard, self.system_effect) for connection_json in json['connections']: - pedalboard.connections.append(connection_reader.read(connection_json)) + port_output, port_input = connection_reader.read(connection_json) + pedalboard.connect(port_output, port_input) if 'data' in json: pedalboard.data = json['data'] @@ -100,10 +99,14 @@ def __init__(self, pedalboard, system_effect): self.pedalboard = pedalboard def read(self, json): - connection_output = self.generate_builder(json, 'output').build_output(json['output']) - connection_input = self.generate_builder(json, 'input').build_input(json['input']) + if json['type'] == 'audio': + connection_output = self.generate_builder(json, 'output').build_output(json['output']) + connection_input = self.generate_builder(json, 'input').build_input(json['input']) + else: + connection_output = self.generate_builder(json, 'output').build_midi_output(json['output']) + connection_input = self.generate_builder(json, 'input').build_midi_input(json['input']) - return Connection(connection_output, connection_input) + return connection_output, connection_input def generate_builder(self, json, audio_port): """ diff --git a/test/model/connection_test.py b/test/model/connection_test.py index 41b0025..974a4ab 100644 --- a/test/model/connection_test.py +++ b/test/model/connection_test.py @@ -14,6 +14,7 @@ import unittest from pluginsmanager.model.connection import Connection, ConnectionError +from pluginsmanager.model.midi_connection import MidiConnection from pluginsmanager.model.lv2.lv2_effect_builder import Lv2EffectBuilder from pluginsmanager.model.system.system_effect import SystemEffect @@ -62,3 +63,14 @@ def test_connect_effect_itself_successful(self): self.assertEqual(connection.input, system_effect.inputs[0]) self.assertEqual(connection.output, system_effect.outputs[0]) + + def test_connection_midi_ports(self): + cctonode1 = self.builder.build('http://gareus.org/oss/lv2/midifilter#cctonote') + cctonode2 = self.builder.build('http://gareus.org/oss/lv2/midifilter#cctonote') + + system_effect = SystemEffect('system', ('capture_1', 'capture_2'), ('playback_1', 'playback_2')) + + with self.assertRaises(ConnectionError): + Connection(cctonode1.midi_outputs[0], cctonode2.midi_inputs[0]) + with self.assertRaises(ConnectionError): + MidiConnection(system_effect.outputs[0], system_effect.inputs[0]) diff --git a/test/model/pedalboard_test.py b/test/model/pedalboard_test.py index cf0036f..67af093 100644 --- a/test/model/pedalboard_test.py +++ b/test/model/pedalboard_test.py @@ -17,17 +17,24 @@ from pluginsmanager.model.bank import Bank from pluginsmanager.model.lv2.lv2_effect_builder import Lv2EffectBuilder -from pluginsmanager.model.pedalboard import Pedalboard +from pluginsmanager.model.pedalboard import Pedalboard, PedalboardError +from pluginsmanager.model.system.system_effect import SystemEffect from pluginsmanager.observer.update_type import UpdateType class PedalboardTest(unittest.TestCase): + @property + def mock_effect(self): + effect = MagicMock() + effect.is_unique_for_all_pedalboards = False + return effect + def test_add_effect_by_effects(self): pedalboard = Pedalboard('Pedalboard 1') - effect1 = MagicMock() - effect2 = MagicMock() + effect1 = self.mock_effect + effect2 = self.mock_effect pedalboard.observer = MagicMock() @@ -44,8 +51,8 @@ def test_add_effect_by_effects(self): def test_add_effect(self): pedalboard = Pedalboard('Pedalboard 1') - effect1 = MagicMock() - effect2 = MagicMock() + effect1 = self.mock_effect + effect2 = self.mock_effect pedalboard.observer = MagicMock() @@ -62,8 +69,8 @@ def test_add_effect(self): def test_update_effect(self): pedalboard = Pedalboard('Pedalboard 1') - effect1 = MagicMock() - effect2 = MagicMock() + effect1 = self.mock_effect + effect2 = self.mock_effect pedalboard.append(effect1) @@ -77,8 +84,8 @@ def test_update_effect(self): def test_delete_effect(self): pedalboard = Pedalboard('Bank 1') - effect = MagicMock() - effect2 = MagicMock() + effect = self.mock_effect + effect2 = self.mock_effect pedalboard.append(effect) pedalboard.append(effect2) @@ -197,3 +204,8 @@ def test_index(self): with self.assertRaises(IndexError): pedalboard2.index + + def test_add_system_effect(self): + pedalboard = Pedalboard('test_add_system_effect') + with self.assertRaises(PedalboardError): + pedalboard.append(SystemEffect('System Effect', (), ())) diff --git a/test/util/persistence_decoder_test.py b/test/util/persistence_decoder_test.py index 6f490ec..6770eef 100644 --- a/test/util/persistence_decoder_test.py +++ b/test/util/persistence_decoder_test.py @@ -32,8 +32,11 @@ def setUpClass(cls): cls.builder = Lv2EffectBuilder() @property - def bank(self): - sys_effect = SystemEffect('system', ('capture_1', 'capture_2'), ('playback_1', 'playback_2'), ('midi_out',), ('midi_in',)) + def system_effect(self): + return SystemEffect('system', ('capture_1', 'capture_2'), ('playback_1', 'playback_2'), ('midi_out',), ('midi_in',)) + + def bank(self, midi=True): + sys_effect = self.system_effect bank = Bank('Bank 1') pedalboard = Pedalboard('Pedalboard 1') @@ -44,19 +47,21 @@ def bank(self): reverb = self.builder.build('http://calf.sourceforge.net/plugins/Reverb') filter = self.builder.build('http://calf.sourceforge.net/plugins/Filter') reverb2 = self.builder.build('http://calf.sourceforge.net/plugins/Reverb') - cctonode = self.builder.build('http://gareus.org/oss/lv2/midifilter#cctonote') pedalboard.append(reverb) pedalboard.append(filter) pedalboard.append(reverb2) - pedalboard.append(cctonode) pedalboard.connect(reverb.outputs[0], filter.inputs[0]) pedalboard.connect(reverb.outputs[1], filter.inputs[0]) pedalboard.connect(filter.outputs[0], reverb2.inputs[0]) pedalboard.connect(reverb.outputs[0], reverb2.inputs[0]) - pedalboard.connect(cctonode.midi_outputs[0], sys_effect.midi_inputs[0]) + if midi: + cctonode = self.builder.build('http://gareus.org/oss/lv2/midifilter#cctonote') + pedalboard.append(cctonode) + pedalboard.connect(cctonode.midi_outputs[0], sys_effect.midi_inputs[0]) + pedalboard.connect(sys_effect.midi_outputs[0], cctonode.midi_inputs[0]) pedalboard.connections.append(Connection(sys_effect.outputs[0], reverb.inputs[0])) pedalboard.connections.append(Connection(reverb2.outputs[0], sys_effect.inputs[0])) @@ -67,13 +72,9 @@ def bank(self): return bank def test_read(self): - system_effect = SystemEffect('system', ('capture_1', 'capture_2'), ('playback_1', 'playback_2')) - - util = PersistenceDecoder(system_effect) + util = PersistenceDecoder(self.system_effect) - bank = self.bank - import pprint - pprint.pprint(bank.json) + bank = self.bank() bank_readed = util.read(bank.json) self.maxDiff = None @@ -112,7 +113,7 @@ def test_read_system_builder(self): util = PersistenceDecoder(system_effect) - bank = self.bank + bank = self.bank(midi=False) bank_readed = util.read(bank.json) self.assertEqual(bank.json, bank_readed.json) From fd03832ad45e910a78087b2b316f40bc8fdadee4 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Mon, 16 Oct 2017 22:30:21 -0300 Subject: [PATCH 07/31] #67 - Improve pedalboard.connect and pedalboard.disconnect docs --- docs/source/model.rst | 15 ++++++------ pluginsmanager/model/pedalboard.py | 37 +++++++++++++++++++++++++----- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/docs/source/model.rst b/docs/source/model.rst index ce7d853..5e1f693 100644 --- a/docs/source/model.rst +++ b/docs/source/model.rst @@ -115,6 +115,14 @@ Bank :special-members: :exclude-members: __weakref__ +Pedalboard +---------- + +.. autoclass:: pluginsmanager.model.pedalboard.Pedalboard + :members: + :special-members: + :exclude-members: __weakref__ + Connection ---------- @@ -204,10 +212,3 @@ Param :special-members: :exclude-members: __weakref__ -Pedalboard ----------- - -.. autoclass:: pluginsmanager.model.pedalboard.Pedalboard - :members: - :special-members: - :exclude-members: __weakref__ diff --git a/pluginsmanager/model/pedalboard.py b/pluginsmanager/model/pedalboard.py index 36327c6..06eff1c 100644 --- a/pluginsmanager/model/pedalboard.py +++ b/pluginsmanager/model/pedalboard.py @@ -199,18 +199,43 @@ def index(self): def connect(self, output_port, input_port): """ - :param output_port: - :param input_port: - :return: + Connect two :class:`.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 + + :param Port output_port: Effect output port + :param Port input_port: Effect input port """ ConnectionClass = output_port.connection_class self.connections.append(ConnectionClass(output_port, input_port)) def disconnect(self, output_port, input_port): """ - :param output_port: - :param input_port: - :return: + Remove a connection between (two ports of) :class:`.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 + + :param Port output_port: Effect output port + :param Port input_port: Effect input port """ ConnectionClass = output_port.connection_class self.connections.remove(ConnectionClass(output_port, input_port)) From 3305740312ccdd22d14c6f5370ff93c3205e6702 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Tue, 17 Oct 2017 20:15:39 -0300 Subject: [PATCH 08/31] Fix documentation bug --- CHANGES | 3 ++- README.rst | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index c02c881..3271d72 100644 --- a/CHANGES +++ b/CHANGES @@ -19,7 +19,8 @@ Version 0.6.0 -- released 10/?/17 Use instead :meth:`~pluginsmanager.model.pedalboard.Pedalboard.connect()`, :meth:`~pluginsmanager.model.pedalboard.Pedalboard.disconnect()` :class:`.Pedalboard` methods; - `Issue #67`_ - Created :meth:`~pluginsmanager.model.pedalboard.Pedalboard.connect()`, :meth:`~pluginsmanager.model.pedalboard.Pedalboard.disconnect()` :class:`.Pedalboard` methods; - Fixed Changelog: Now is possible see it in the documentation; - - `Issue #38`_ - Raise erros then add sys_effect in any Pedalboard. + - `Issue #38`_ - Raise erros then add sys_effect in any Pedalboard; + - `Issue #65`_ - Fix documentation bug `SystemEffectBuilder(client).build()` instead `SystemEffectBuilder(client)`; .. _Issue #38: https://github.com/PedalPi/PluginsManager/issues/38 .. _Issue #57: https://github.com/PedalPi/PluginsManager/issues/57 diff --git a/README.rst b/README.rst index 13c094d..6401caf 100644 --- a/README.rst +++ b/README.rst @@ -157,7 +157,7 @@ It requires a `JackClient` instance, that uses `JACK-Client`_. client = JackClient() from pluginsmanager.model.system.system_effect_builder import SystemEffectBuilder - sys_effect = SystemEffectBuilder(client) + sys_effect = SystemEffectBuilder(client).build() For manual input and output sound card definition, use: From 483c50afa3faa013c5125c90080ac2f02bedd327 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Tue, 17 Oct 2017 20:15:39 -0300 Subject: [PATCH 09/31] Fix documentation bug --- CHANGES | 3 ++- README.rst | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index c02c881..3271d72 100644 --- a/CHANGES +++ b/CHANGES @@ -19,7 +19,8 @@ Version 0.6.0 -- released 10/?/17 Use instead :meth:`~pluginsmanager.model.pedalboard.Pedalboard.connect()`, :meth:`~pluginsmanager.model.pedalboard.Pedalboard.disconnect()` :class:`.Pedalboard` methods; - `Issue #67`_ - Created :meth:`~pluginsmanager.model.pedalboard.Pedalboard.connect()`, :meth:`~pluginsmanager.model.pedalboard.Pedalboard.disconnect()` :class:`.Pedalboard` methods; - Fixed Changelog: Now is possible see it in the documentation; - - `Issue #38`_ - Raise erros then add sys_effect in any Pedalboard. + - `Issue #38`_ - Raise erros then add sys_effect in any Pedalboard; + - `Issue #65`_ - Fix documentation bug `SystemEffectBuilder(client).build()` instead `SystemEffectBuilder(client)`; .. _Issue #38: https://github.com/PedalPi/PluginsManager/issues/38 .. _Issue #57: https://github.com/PedalPi/PluginsManager/issues/57 diff --git a/README.rst b/README.rst index 13c094d..6401caf 100644 --- a/README.rst +++ b/README.rst @@ -157,7 +157,7 @@ It requires a `JackClient` instance, that uses `JACK-Client`_. client = JackClient() from pluginsmanager.model.system.system_effect_builder import SystemEffectBuilder - sys_effect = SystemEffectBuilder(client) + sys_effect = SystemEffectBuilder(client).build() For manual input and output sound card definition, use: From f4d06b56082316f1593abd2da9d2d03cdb1fef8c Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Tue, 17 Oct 2017 20:30:41 -0300 Subject: [PATCH 10/31] \#68 Remove current mod-host pedalboard don't removes systems connection (system.output to system.input) --- CHANGES | 3 +++ pluginsmanager/observer/mod_host/mod_host.py | 1 + 2 files changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 3271d72..d37d5e2 100644 --- a/CHANGES +++ b/CHANGES @@ -21,10 +21,13 @@ Version 0.6.0 -- released 10/?/17 - 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 #38: https://github.com/PedalPi/PluginsManager/issues/38 .. _Issue #57: https://github.com/PedalPi/PluginsManager/issues/57 +.. _Issue #65: https://github.com/PedalPi/PluginsManager/issues/65 .. _Issue #67: https://github.com/PedalPi/PluginsManager/issues/67 +.. _Issue #68: https://github.com/PedalPi/PluginsManager/issues/68 Version 0.5.1 -- released 08/16/17 ********************************** diff --git a/pluginsmanager/observer/mod_host/mod_host.py b/pluginsmanager/observer/mod_host/mod_host.py index 644cd01..e00bf36 100644 --- a/pluginsmanager/observer/mod_host/mod_host.py +++ b/pluginsmanager/observer/mod_host/mod_host.py @@ -292,6 +292,7 @@ def _change_pedalboard(self, pedalboard): def _remove_pedalboard(self, pedalboard): self._remove_effects(pedalboard.effects) + self._remove_connections_of(pedalboard) def _remove_connections_of(self, pedalboard): for connection in pedalboard.connections: From 4da8f6bd85bd9dacfbc4da59d6008a558390ff7d Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Tue, 17 Oct 2017 20:56:08 -0300 Subject: [PATCH 11/31] Fix build --- makefile | 91 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 40 deletions(-) diff --git a/makefile b/makefile index 452e23c..fc853f8 100644 --- a/makefile +++ b/makefile @@ -1,63 +1,74 @@ -.RECIPEPREFIX += BROWSER=firefox +BOLD=\033[1m +NORMAL=\033[0m -default: run +default: help -clean: clean-pyc clean-test clean-build +clean: clean-pyc clean-test clean-build clean-docs clean-build: - rm -rf .eggs - rm -rf build - rm -rf dist + rm -rf .eggs + rm -rf build + rm -rf dist clean-pyc: - find . -name '*.pyc' -exec rm --force {} + - find . -name '*.pyo' -exec rm --force {} + + find . -name '*.pyc' -exec rm --force {} + + find . -name '*.pyo' -exec rm --force {} + clean-test: - rm -f .coverage - rm -rf htmlcov - rm -rf test/autosaver_data + rm -rf .cache + rm -f .coverage + rm -rf htmlcov + rm -rf test/autosaver_data clean-docs: - rm -rf docs/build + rm -rf docs/build docs: clean-docs - cd docs && $(MAKE) html + cd docs && $(MAKE) html docs-see: docs - $(BROWSER) docs/build/html/index.html + $(BROWSER) docs/build/html/index.html install-tests-requirements: - # For midi tests - https://github.com/x42/midifilter.lv2 - cd /tmp && git clone git://github.com/x42/midifilter.lv2.git && \ - cd midifilter.lv2 && \ - make && \ - sudo make install PREFIX=/usr + # For midi tests - https://github.com/x42/midifilter.lv2 + cd /tmp && git clone git://github.com/x42/midifilter.lv2.git && \ + cd midifilter.lv2 && \ + make && \ + sudo make install PREFIX=/usr run: - @echo "Run option isn't created =)" + @echo "Run option isn't created =)" test: clean-test - mkdir test/autosaver_data - coverage3 run --source=pluginsmanager setup.py test - coverage3 report + mkdir test/autosaver_data + pytest --cov=pluginsmanager test-details: test - coverage3 html - $(BROWSER) htmlcov/index.html - -help: - @echo " clean" - @echo " Clean files" - @echo " docs" - @echo " Make the docs" - @echo " docs-see" - @echo " Make the docs and open it in BROWSER" - @echo " test" - @echo " Execute the tests" - @echo " test-details" - @echo " Execute the tests and shows the result in BROWSER" - @echo " - BROWSER=firefox" - @echo " help" - @echo " Show the valid commands" + coverage3 html + $(BROWSER) htmlcov/index.html + +help: cabecalho + @echo "" + @echo "Commands" + @echo " $(BOLD)clean$(NORMAL)" + @echo " Clean files" + @echo " $(BOLD)docs$(NORMAL)" + @echo " Make the docs" + @echo " $(BOLD)docs-see$(NORMAL)" + @echo " Make the docs and open it in BROWSER" + @echo " $(BOLD)test$(NORMAL)" + @echo " Execute the tests" + @echo " $(BOLD)test-details$(NORMAL)" + @echo " Execute the tests and shows the result in BROWSER" + @echo " - BROWSER=firefox" + @echo " $(BOLD)help$(NORMAL)" + @echo " Show the valid commands" + +cabecalho: + @echo "$(BOLD) _____ _ _ _____" + @echo "| _ || | _ _ ___ |_| ___ ___ | | ___ ___ ___ ___ ___ ___" + @echo "| __|| || | || . || || ||_ -|| | | || .'|| || .'|| . || -_|| _|" + @echo "|__| |_||___||_ ||_||_|_||___||_|_|_||__,||_|_||__,||_ ||___||_|" + @echo " |___| |___|" + @echo "Github$(NORMAL): https://pypi.org/project/PedalPi-PluginsManager/" From c832d921705778f4a0f41650a877a0b5ff3908a2 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Tue, 17 Oct 2017 21:31:15 -0300 Subject: [PATCH 12/31] Issue #66 - Improve json effect informations --- CHANGES | 2 ++ pluginsmanager/model/effect.py | 7 +++++++ pluginsmanager/model/lv2/lv2_effect.py | 8 ++++++++ pluginsmanager/model/lv2/lv2_plugin.py | 4 ++++ pluginsmanager/model/param.py | 2 -- test/model/system/system_effect_builder_test.py | 1 + 6 files changed, 22 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index d37d5e2..d841e60 100644 --- a/CHANGES +++ b/CHANGES @@ -22,10 +22,12 @@ Version 0.6.0 -- released 10/?/17 - `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 #38: https://github.com/PedalPi/PluginsManager/issues/38 .. _Issue #57: https://github.com/PedalPi/PluginsManager/issues/57 .. _Issue #65: https://github.com/PedalPi/PluginsManager/issues/65 +.. _Issue #66: https://github.com/PedalPi/PluginsManager/issues/66 .. _Issue #67: https://github.com/PedalPi/PluginsManager/issues/67 .. _Issue #68: https://github.com/PedalPi/PluginsManager/issues/68 diff --git a/pluginsmanager/model/effect.py b/pluginsmanager/model/effect.py index 0280537..486a968 100644 --- a/pluginsmanager/model/effect.py +++ b/pluginsmanager/model/effect.py @@ -187,3 +187,10 @@ def __repr__(self): str(self), id(self) ) + + @property + def version(self): + """ + :return string: Effect version + """ + return '' diff --git a/pluginsmanager/model/lv2/lv2_effect.py b/pluginsmanager/model/lv2/lv2_effect.py index 63db6d5..9afaf04 100644 --- a/pluginsmanager/model/lv2/lv2_effect.py +++ b/pluginsmanager/model/lv2/lv2_effect.py @@ -78,4 +78,12 @@ def __dict__(self): 'plugin': self.plugin['uri'], 'active': self.active, 'params': [param.json for param in self.params], + 'version': self.version } + + @property + def version(self): + """ + :return string: Version of plugin of effect + """ + return self.plugin.version diff --git a/pluginsmanager/model/lv2/lv2_plugin.py b/pluginsmanager/model/lv2/lv2_plugin.py index 31394a8..170e669 100644 --- a/pluginsmanager/model/lv2/lv2_plugin.py +++ b/pluginsmanager/model/lv2/lv2_plugin.py @@ -43,3 +43,7 @@ def __repr__(self): str(self), id(self) ) + + @property + def version(self): + return '' if 'version' not in self.json else self.json['version'] diff --git a/pluginsmanager/model/param.py b/pluginsmanager/model/param.py index 353a5c3..cc8a892 100644 --- a/pluginsmanager/model/param.py +++ b/pluginsmanager/model/param.py @@ -148,8 +148,6 @@ def json(self): def __dict__(self): return { 'index': self.index, - 'minimum': self.minimum, - 'maximum': self.maximum, 'symbol': self.symbol, 'value': self.value, } diff --git a/test/model/system/system_effect_builder_test.py b/test/model/system/system_effect_builder_test.py index d450277..2535788 100644 --- a/test/model/system/system_effect_builder_test.py +++ b/test/model/system/system_effect_builder_test.py @@ -29,3 +29,4 @@ def test_mock_system_effect_builder(self): self.assertEqual((), system_effect.inputs) self.assertTupleEqual((), system_effect.outputs) + self.assertEqual('', system_effect.version) From 69943bd0f410c13025fa2074d5be0332ac819750 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Tue, 17 Oct 2017 21:34:09 -0300 Subject: [PATCH 13/31] #70 - Try fix build --- .gitignore | 3 ++- .travis.yml | 4 ++-- setup.py | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 728b69d..c9ebea5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,9 @@ *.egg-info htmlcov .coverage +.cache docs/build .eggs dist/ build/ -test/autosaver_data \ No newline at end of file +test/autosaver_data diff --git a/.travis.yml b/.travis.yml index fe1386e..ff964b8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,9 +13,9 @@ install: - sudo apt-get install -y portaudio19-dev python-all-dev --no-install-recommends - sudo apt-get install -y lilv-utils calf-plugins guitarix --no-install-recommends - pip3 install sphinx - - pip3 install coveralls - pip3 install cffi - - pip3 install JACK-Client + - python setup.py develop + - pip3 install pytest pytest-cov script: - lv2ls diff --git a/setup.py b/setup.py index 7716bd8..59a4238 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ def readme(): setup( name='PedalPi-PluginsManager', - version='0.5.1', + version='0.6.0', description='Pythonic management of LV2 audio plugins with mod-host.', long_description=readme(), @@ -62,7 +62,7 @@ def readme(): ], test_suite='test', - tests_require=['JACK-Client'], + tests_require=['JACK-Client', 'pytest', 'pytest-cov'], classifiers=[ 'Development Status :: 3 - Alpha', From e9f53b08a545f98e02ed6e5b730bc84424118c73 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Tue, 17 Oct 2017 21:46:03 -0300 Subject: [PATCH 14/31] Try fix missin midifilter plugin --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index ff964b8..50f4383 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,10 +16,13 @@ install: - pip3 install cffi - python setup.py develop - pip3 install pytest pytest-cov + - make install-tests-requirements script: - lv2ls - make test - make docs + - pytest --doctest-glob='*.rst' + - pytest --doctest-modules after_success: - bash <(curl -s https://codecov.io/bash) From 72b2e6e507cfe23c2cf011f6ded08f2f9ffd2b65 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Tue, 17 Oct 2017 21:53:34 -0300 Subject: [PATCH 15/31] Try fix missin midifilter plugin --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 50f4383..1629243 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ sudo: required install: - sudo apt-get install -y portaudio19-dev python-all-dev --no-install-recommends - sudo apt-get install -y lilv-utils calf-plugins guitarix --no-install-recommends + - sudo apt-get install -y lv2-dev --no-install-recommends - pip3 install sphinx - pip3 install cffi - python setup.py develop From 61992d012fba21fcb6685b9fd9e189729c6411ec Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Thu, 19 Oct 2017 09:28:49 -0300 Subject: [PATCH 16/31] Create make test-docs. Implementing --- .travis.yml | 10 ++++++---- docs/source/observer.rst | 5 +++-- makefile | 4 ++++ pluginsmanager/banks_manager.py | 3 ++- pluginsmanager/util/dict_tuple.py | 2 +- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1629243..b5e5f81 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,8 +22,10 @@ install: script: - lv2ls - make test - - make docs - - pytest --doctest-glob='*.rst' - - pytest --doctest-modules -after_success: - bash <(curl -s https://codecov.io/bash) + - make docs + - make test-docd + - #pytest --doctest-modules + +#after_success: +# - bash <(curl -s https://codecov.io/bash) diff --git a/docs/source/observer.rst b/docs/source/observer.rst index 3104ffb..8839908 100644 --- a/docs/source/observer.rst +++ b/docs/source/observer.rst @@ -203,10 +203,11 @@ of the change:: We'll now limit the notification by telling you who performed the actions:: >>> with observer1: - >>> del manager.banks[0] + >>> with observer1: + ... del manager.banks[0] "Hi! I am observer2" >>> with observer2: - >>> manager.banks.append(bank) + ... manager.banks.append(bank) "Hi! I am observer1" diff --git a/makefile b/makefile index fc853f8..bd54f1e 100644 --- a/makefile +++ b/makefile @@ -44,6 +44,10 @@ test: clean-test mkdir test/autosaver_data pytest --cov=pluginsmanager +test-docs: + python -m doctest *.rst -v + python -m doctest docs/*/*.rst -v + test-details: test coverage3 html $(BROWSER) htmlcov/index.html diff --git a/pluginsmanager/banks_manager.py b/pluginsmanager/banks_manager.py index f7fc244..b45f715 100644 --- a/pluginsmanager/banks_manager.py +++ b/pluginsmanager/banks_manager.py @@ -47,8 +47,9 @@ def __iter__(self): """ Iterates banks of the banksmanager:: + >>> banks_manager = BanksManager() >>> for index, bank in enumerate(banks_manager): - >>> print(index, '-', bank) + ... print(index, '-', bank) :return: Iterator for banks list """ diff --git a/pluginsmanager/util/dict_tuple.py b/pluginsmanager/util/dict_tuple.py index d22f584..db21a10 100644 --- a/pluginsmanager/util/dict_tuple.py +++ b/pluginsmanager/util/dict_tuple.py @@ -16,7 +16,7 @@ class DictTuple(tuple): """ Dict tuple is a union with dicts and tuples. It's possible obtains an element - by index or by a key. + by index or by a key The key is not been a int or long instance From 039e8cdf8441b2e45e83d0c7dc954575df2c69bd Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Thu, 19 Oct 2017 09:45:25 -0300 Subject: [PATCH 17/31] Disable test-docs from build --- .travis.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b5e5f81..6a7dfe6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,10 +22,9 @@ install: script: - lv2ls - make test - - bash <(curl -s https://codecov.io/bash) - make docs - - make test-docd + - #make test-docs - #pytest --doctest-modules -#after_success: -# - bash <(curl -s https://codecov.io/bash) +after_success: + - bash <(curl -s https://codecov.io/bash) From 11849eb771145b5b8f2b37fdeddf522b3e825823 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Thu, 19 Oct 2017 10:13:50 -0300 Subject: [PATCH 18/31] Change version to alpha 1 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 59a4238..d291359 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ def readme(): setup( name='PedalPi-PluginsManager', - version='0.6.0', + version='0.6.0alpha1', description='Pythonic management of LV2 audio plugins with mod-host.', long_description=readme(), From 97dd850bd5b45cb4b25dadc372c22f9454b96047 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Thu, 19 Oct 2017 23:01:00 -0300 Subject: [PATCH 19/31] Create a conversor 'mod-ui pedalboard' -> 'pluginsmanager' pedalboard --- CHANGES | 2 + docs/source/util.rst | 24 ++-- pluginsmanager/jack/jack_interface.py | 14 +++ pluginsmanager/util/dict_tuple.py | 3 + .../util/mod_pedalboard_converter.py | 109 ++++++++++++++++++ test/jack/__init__.py | 13 +++ .../observable_list_test.py | 0 test/util/dict_tuple_test.py | 35 ++++++ test/util/mod_pedalboard_converter_test.py | 39 +++++++ 9 files changed, 231 insertions(+), 8 deletions(-) create mode 100644 pluginsmanager/util/mod_pedalboard_converter.py rename test/{util => observer}/observable_list_test.py (100%) create mode 100644 test/util/dict_tuple_test.py create mode 100644 test/util/mod_pedalboard_converter_test.py diff --git a/CHANGES b/CHANGES index d841e60..bca5369 100644 --- a/CHANGES +++ b/CHANGES @@ -23,9 +23,11 @@ Version 0.6.0 -- released 10/?/17 - `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 #38: https://github.com/PedalPi/PluginsManager/issues/38 .. _Issue #57: https://github.com/PedalPi/PluginsManager/issues/57 +.. _Issue #62: https://github.com/PedalPi/PluginsManager/issues/65 .. _Issue #65: https://github.com/PedalPi/PluginsManager/issues/65 .. _Issue #66: https://github.com/PedalPi/PluginsManager/issues/66 .. _Issue #67: https://github.com/PedalPi/PluginsManager/issues/67 diff --git a/docs/source/util.rst b/docs/source/util.rst index 0da7bc7..d1bf696 100644 --- a/docs/source/util.rst +++ b/docs/source/util.rst @@ -1,32 +1,40 @@ PedalPi - PluginsManager - Util =============================== -pluginsmanager.util.dict_tuple.DictTuple ----------------------------------------- +DictTuple +--------- .. autoclass:: pluginsmanager.util.dict_tuple.DictTuple :members: :special-members: :exclude-members: __weakref__ -pluginsmanager.util.pairs_list.PairsList ----------------------------------------- +ModPedalboardConverter +---------------------- + +.. autoclass:: pluginsmanager.util.mod_pedalboard_converter.ModPedalboardConverter + :members: + :special-members: + :exclude-members: __weakref__ + +PairsList +--------- .. autoclass:: pluginsmanager.util.pairs_list.PairsList :members: :special-members: :exclude-members: __weakref__ -pluginsmanager.util.pairs_list.PairsListResult ----------------------------------------------- +PairsListResult +--------------- .. autoclass:: pluginsmanager.util.pairs_list.PairsListResult :members: :special-members: :exclude-members: __weakref__ -pluginsmanager.util.persistence_decoder ---------------------------------------- +persistence_decoder +------------------- .. autoclass:: pluginsmanager.util.persistence_decoder.PersistenceDecoderError :members: diff --git a/pluginsmanager/jack/jack_interface.py b/pluginsmanager/jack/jack_interface.py index a6eb323..4799638 100644 --- a/pluginsmanager/jack/jack_interface.py +++ b/pluginsmanager/jack/jack_interface.py @@ -1,3 +1,17 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import pyaudio diff --git a/pluginsmanager/util/dict_tuple.py b/pluginsmanager/util/dict_tuple.py index db21a10..0961f7d 100644 --- a/pluginsmanager/util/dict_tuple.py +++ b/pluginsmanager/util/dict_tuple.py @@ -41,3 +41,6 @@ def __getitem__(self, index): else: return self._dict[index] + + def __contains__(self, item): + return item in self._dict diff --git a/pluginsmanager/util/mod_pedalboard_converter.py b/pluginsmanager/util/mod_pedalboard_converter.py new file mode 100644 index 0000000..c4109fe --- /dev/null +++ b/pluginsmanager/util/mod_pedalboard_converter.py @@ -0,0 +1,109 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +from pathlib import Path + +from pluginsmanager.model.pedalboard import Pedalboard +from pluginsmanager.model.system.system_effect import SystemEffect + + +class ModPedalboardConverter(object): + """ + ModPedalboardConverter is a utility to convert MOD pedalboards structure + in plugins manager pedalboard. + + `MOD`_, an awesome music enterprise, create the `mod-ui`_, a visual interface + that enable create pedalboards in a simple way. + + .. _MOD: http://moddevices.com/ + .. _mod-ui: https://github.com/moddevices/mod-ui + """ + + def __init__(self, mod_ui_path, builder): + """ + :param Path mod_ui_path: path that mod_ui has in the computer. + :param Lv2EffectBuilder builder: Builder for generate the lv2 effects + """ + self._load_mod_ui_libraries(mod_ui_path) + self.builder = builder + + def _load_mod_ui_libraries(self, path): + """ + :param Path path: + """ + path = path / Path('mod') + sys.path.append(str(path)) + + def get_pedalboard_info(self, path): + """ + :param Path path: Path that the pedalboard has been persisted. + Generally is in format `path/to/pedalboard/name.pedalboard` + :return dict: pedalboard persisted configurations + """ + from utils import get_pedalboard_info + + return get_pedalboard_info(str(path)) + + def convert(self, pedalboard_path, system_effect): + """ + :param Path pedalboard_path: Path that the pedalboard has been persisted. + Generally is in format `path/to/pedalboard/name.pedalboard` + :param SystemEffect system_effect: Effect that contains the audio interface outputs and inputs + :return Pedalboard: Pedalboard loaded + """ + info = self.get_pedalboard_info(pedalboard_path) + + pedalboard = Pedalboard(info['title']) + + effects_instance = {} + + for effect_data in info['plugins']: + effect = self._generate_effect(effect_data) + pedalboard.append(effect) + effects_instance[effect_data['instance']] = effect + + for connection_data in info['connections']: + output_port = self._get_port(connection_data['source'], effects_instance, system_effect) + input_port = self._get_port(connection_data['target'], effects_instance, system_effect) + + pedalboard.connect(output_port, input_port) + + return pedalboard + + def _generate_effect(self, effect_data): + effect = self.builder.build(effect_data['uri']) + effect.active = not effect_data['bypassed'] + + for param_data in effect_data['ports']: + effect.params[param_data['symbol']].value = param_data['value'] + + return effect + + def _get_port(self, name, effects_instance, system_effect): + effect, port = None, None + + if name.startswith('capture_') or name.startswith('playback_'): + effect = system_effect + port = name + else: + instance, port = name.split('/') + effect = effects_instance[instance] + + possible_ports = (effect.outputs, effect.inputs, effect.midi_outputs, effect.midi_inputs) + filtered = filter(lambda ports: port in ports, possible_ports) + + ports = list(filtered)[0] + return ports[port] + diff --git a/test/jack/__init__.py b/test/jack/__init__.py index e69de29..75323bb 100644 --- a/test/jack/__init__.py +++ b/test/jack/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/test/util/observable_list_test.py b/test/observer/observable_list_test.py similarity index 100% rename from test/util/observable_list_test.py rename to test/observer/observable_list_test.py diff --git a/test/util/dict_tuple_test.py b/test/util/dict_tuple_test.py new file mode 100644 index 0000000..c757377 --- /dev/null +++ b/test/util/dict_tuple_test.py @@ -0,0 +1,35 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from pluginsmanager.util.dict_tuple import DictTuple + + +class DictTupleTest(unittest.TestCase): + + def test__get_item__(self): + elements = ('123', '456', '789') + data = DictTuple(elements, lambda e: e) + + for index, element in enumerate(elements): + self.assertEqual(element, data[index]) + self.assertEqual(element, data[element]) + + def test_in(self): + elements = ('abc', 'cde', 'def') + data = DictTuple(elements, lambda e: e.upper()) + + self.assertTrue('ABC' in data) + self.assertFalse('abc' in data) diff --git a/test/util/mod_pedalboard_converter_test.py b/test/util/mod_pedalboard_converter_test.py new file mode 100644 index 0000000..07a34fd --- /dev/null +++ b/test/util/mod_pedalboard_converter_test.py @@ -0,0 +1,39 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import unittest +from pathlib import Path + +from pluginsmanager.model.lv2.lv2_effect_builder import Lv2EffectBuilder +from pluginsmanager.model.system.system_effect import SystemEffect +from pluginsmanager.util.mod_pedalboard_converter import ModPedalboardConverter + + +class ModPedalboardConverterTest(unittest.TestCase): + + @unittest.skipIf('TRAVIS' in os.environ, 'Mod-ui not configured in Travis build') + def test_all(self): + path = Path('/home/paulo/git/mod/mod_ui/') + builder = Lv2EffectBuilder() + #builder.reload(builder.lv2_plugins_data()) + + converter = ModPedalboardConverter(path, builder) + + pedalboard_path = Path('/home/paulo/.pedalboards/teste.pedalboard') + system_effect = SystemEffect('system', ['capture_1', 'capture_2'], ['playback_1', 'playback_2']) + + print(converter.get_pedalboard_info(pedalboard_path)) + pedalboard = converter.convert(pedalboard_path, system_effect) + print(pedalboard.json) From c8a3d197c0512374d71136036d001db4b2d359b6 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Sun, 29 Oct 2017 09:34:56 -0300 Subject: [PATCH 20/31] Issue #78 - Lv2EffectBuilder now raises a message when try create a not loaded plugin data --- .../model/lv2/lv2_effect_builder.py | 14 +++++++++- test/model/lv2/__init__.py | 13 ++++++++++ test/model/lv2/lv2_effect_builder_test.py | 26 +++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 test/model/lv2/__init__.py create mode 100644 test/model/lv2/lv2_effect_builder_test.py diff --git a/pluginsmanager/model/lv2/lv2_effect_builder.py b/pluginsmanager/model/lv2/lv2_effect_builder.py index e8f530e..7890ad6 100644 --- a/pluginsmanager/model/lv2/lv2_effect_builder.py +++ b/pluginsmanager/model/lv2/lv2_effect_builder.py @@ -20,6 +20,10 @@ from pluginsmanager.model.lv2.lv2_effect import Lv2Effect +class Lv2EffectBuilderError(Exception): + pass + + class Lv2EffectBuilder(object): """ Generates lv2 audio plugins instance (as :class:`.Lv2Effect` object). @@ -78,7 +82,15 @@ def build(self, lv2_uri): :param string lv2_uri: :return Lv2Effect: Effect created """ - return Lv2Effect(self._plugins[lv2_uri]) + try: + plugin = self._plugins[lv2_uri] + except KeyError: + raise Lv2EffectBuilderError( + "Lv2EffectBuilder not contains metadata information about the plugin '{}'. \n" + "Try re-scan the installed plugins using the reload method::\n" + " >>> lv2_effect_builder.reload(lv2_effect_builder.lv2_plugins_data())".format(lv2_uri)) + + return Lv2Effect(plugin) def lv2_plugins_data(self): """ diff --git a/test/model/lv2/__init__.py b/test/model/lv2/__init__.py new file mode 100644 index 0000000..75323bb --- /dev/null +++ b/test/model/lv2/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/test/model/lv2/lv2_effect_builder_test.py b/test/model/lv2/lv2_effect_builder_test.py new file mode 100644 index 0000000..9b7718e --- /dev/null +++ b/test/model/lv2/lv2_effect_builder_test.py @@ -0,0 +1,26 @@ +# Copyright 2017 SrMouraSilva +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from pluginsmanager.model.lv2.lv2_effect_builder import Lv2EffectBuilder +from pluginsmanager.model.lv2.lv2_effect_builder import Lv2EffectBuilderError + + +class Lv2EffecBuilderTest(unittest.TestCase): + + def test_load_nonexistent_effect(self): + builder = Lv2EffectBuilder() + with self.assertRaises(Lv2EffectBuilderError): + builder.build('nonexistent_effect') From 0b9b6a98053d59738a1d43f866aad729f53fc908 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Sun, 29 Oct 2017 13:16:11 -0300 Subject: [PATCH 21/31] Issue #77 - Fix SystemMidi connection support in ProtocolParser. Not finish --- pluginsmanager/model/effect.py | 14 ++++++ pluginsmanager/model/system/system_effect.py | 7 +++ .../observer/mod_host/protocol_parser.py | 20 ++++----- test/mod_host/mod_host_test.py | 43 +++++++++++++++++++ test/model/midi_output_test.py | 1 - 5 files changed, 74 insertions(+), 11 deletions(-) diff --git a/pluginsmanager/model/effect.py b/pluginsmanager/model/effect.py index 486a968..7cfedd7 100644 --- a/pluginsmanager/model/effect.py +++ b/pluginsmanager/model/effect.py @@ -181,6 +181,20 @@ def is_unique_for_all_pedalboards(self): """ return False + @property + def use_real_identifier(self): + """ + 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: :class:`.Lv2Effect` is False + Example: :class:`.SystemEffect` is True + """ + return False + def __repr__(self): return "<{} object as '{}' at 0x{:x}>".format( self.__class__.__name__, diff --git a/pluginsmanager/model/system/system_effect.py b/pluginsmanager/model/system/system_effect.py index 99a9794..be1437f 100644 --- a/pluginsmanager/model/system/system_effect.py +++ b/pluginsmanager/model/system/system_effect.py @@ -110,3 +110,10 @@ def is_unique_for_all_pedalboards(self): Example: :class:`.SystemEffect` is unique for all pedalboards """ return True + + @property + def use_real_identifier(self): + """ + return bool: For this audio plugin, is necessary use the real effect identifier? + """ + return True diff --git a/pluginsmanager/observer/mod_host/protocol_parser.py b/pluginsmanager/observer/mod_host/protocol_parser.py index 9db2dbc..834d44c 100644 --- a/pluginsmanager/observer/mod_host/protocol_parser.py +++ b/pluginsmanager/observer/mod_host/protocol_parser.py @@ -80,22 +80,22 @@ def _connect_message(origin_port, destination_port): return 'connect {} {}'.format(origin_port, destination_port) @staticmethod - def _get_out_name_of(effect_output): - effect = effect_output.effect + def _get_out_name_of(output_of_effect): + effect = output_of_effect.effect - if isinstance(effect_output, SystemOutput): - return '{}:{}'.format(effect, effect_output) + if effect.use_real_identifier: + return '{}:{}'.format(effect, output_of_effect) - return 'effect_{}:{}'.format(effect.instance, effect_output.symbol) + return 'effect_{}:{}'.format(effect.instance, output_of_effect.symbol) @staticmethod - def _get_in_name_of(effect_input): - effect = effect_input.effect + def _get_in_name_of(input_of_effect): + effect = input_of_effect.effect - if isinstance(effect_input, SystemInput): - return '{}:{}'.format(effect, effect_input) + if effect.use_real_identifier: + return '{}:{}'.format(effect, input_of_effect) - return 'effect_{}:{}'.format(effect.instance, effect_input.symbol) + return 'effect_{}:{}'.format(effect.instance, input_of_effect.symbol) @staticmethod def disconnect(connection): diff --git a/test/mod_host/mod_host_test.py b/test/mod_host/mod_host_test.py index 25bae66..3ccc448 100644 --- a/test/mod_host/mod_host_test.py +++ b/test/mod_host/mod_host_test.py @@ -218,3 +218,46 @@ def test_connection_not_current_pedalboard(self): mod_host.pedalboard = pedalboard pedalboard2.connect(pedalboard2.effects[0].outputs[0], pedalboard2.effects[1].inputs[0]) + + #@unittest.skip + def test_system_midi_port(self): + from pluginsmanager.observer.mod_host.mod_host import ModHost + from pluginsmanager.model.pedalboard import Pedalboard + from pluginsmanager.model.lv2.lv2_effect_builder import Lv2EffectBuilder + from pluginsmanager.model.system.system_effect import SystemEffect + + jack_system = SystemEffect( + 'system', + [], # audio inputs + ['playback_1', 'playback_2'], # audio output + [], # midi inputs + [] # midi outputs + ) + jack_ttymidi = SystemEffect( + 'ttymidi', + [], # audio inputs + [], # audio output + ['MIDI_in'], # midi inputs + ['MIDI_out'] # midi outputs + ) + + modhost = ModHost('localhost') + modhost.connect() + + pedalboard = Pedalboard('MDA-EP') + builder = Lv2EffectBuilder() + ep = builder.build('http://guitarix.sourceforge.net/plugins/gx_oc_2_#_oc_2_') + + pedalboard.append(ep) + + # REMEMBER: FIRST OUTPUT, SECOND INPUT + # EPiano contains two audio output ports and one midi input port + pedalboard.connect(ep.outputs[0], jack_system.inputs[0]) + pedalboard.connect(jack_ttymidi.midi_outputs[0], ep.midi_inputs[0]) + + # If not using banks manager, the changes will not be applied automatically + # then, is necessary changes the pedalboard at the end + modhost.pedalboard = pedalboard + + # Safe close + modhost.close() \ No newline at end of file diff --git a/test/model/midi_output_test.py b/test/model/midi_output_test.py index e2afc05..5287b5d 100644 --- a/test/model/midi_output_test.py +++ b/test/model/midi_output_test.py @@ -15,7 +15,6 @@ import unittest from unittest.mock import MagicMock -from pluginsmanager.model.connection import ConnectionError from pluginsmanager.model.lv2.lv2_effect_builder import Lv2EffectBuilder from pluginsmanager.model.pedalboard import Pedalboard from pluginsmanager.model.system.system_effect import SystemEffect From 173d1f2df05cc8760f1ea367b4a018dbf519525e Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Tue, 31 Oct 2017 22:45:29 -0300 Subject: [PATCH 22/31] Issue #77 - Fix test build --- test/mod_host/mod_host_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/mod_host/mod_host_test.py b/test/mod_host/mod_host_test.py index 3ccc448..add25f6 100644 --- a/test/mod_host/mod_host_test.py +++ b/test/mod_host/mod_host_test.py @@ -219,7 +219,7 @@ def test_connection_not_current_pedalboard(self): pedalboard2.connect(pedalboard2.effects[0].outputs[0], pedalboard2.effects[1].inputs[0]) - #@unittest.skip + @unittest.skip def test_system_midi_port(self): from pluginsmanager.observer.mod_host.mod_host import ModHost from pluginsmanager.model.pedalboard import Pedalboard From 717af61c9cc472e4a433378b7068ca76332af35d Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Tue, 31 Oct 2017 22:45:58 -0300 Subject: [PATCH 23/31] Improve documentation for midi informations --- pluginsmanager/model/system/system_effect.py | 59 ++++++++++++++++--- .../model/system/system_effect_builder.py | 8 ++- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/pluginsmanager/model/system/system_effect.py b/pluginsmanager/model/system/system_effect.py index be1437f..47aea8d 100644 --- a/pluginsmanager/model/system/system_effect.py +++ b/pluginsmanager/model/system/system_effect.py @@ -23,7 +23,7 @@ class SystemEffect(Effect): """ - Representation of the system instance (audio cards). + 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 @@ -49,33 +49,78 @@ class SystemEffect(Effect): However the pedalboard must have the connections:: - >>> pedalboard.connections.append(Connection(sys_effect.outputs[0], reverb.inputs[0])) + >>> 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.connections.append(Connection(sys_effect.outputs[0], sys_effect.inputs[0])) - >>> pedalboard.connections.append(Connection(sys_effect.outputs[1], sys_effect.inputs[1])) + >>> 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 + + .. _jack_lsp: http://manpages.ubuntu.com/manpages/xenial/man1/jack_lsp.1.html + + 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]) :param string representation: Audio card representation. Usually 'system' :param tuple(string) outputs: Tuple of outputs representation. Usually a output representation - starts with `capture_` + starts with ``capture_`` :param tuple(string) inputs: Tuple of inputs representation. Usually a input representation - starts with `playback_` + starts with ``playback_`` :param tuple(string) midi_outputs: Tuple of midi outputs representation. :param tuple(string) midi_inputs: Tuple of midi inputs representation. """ - def __init__(self, representation, outputs, inputs, midi_outputs=None, midi_inputs=None): + def __init__(self, representation, outputs=None, inputs=None, midi_outputs=None, midi_inputs=None): super(SystemEffect, self).__init__() self.representation = representation self._params = tuple() + inputs = inputs if inputs is not None else [] inputs = [SystemInput(self, effect_input) for effect_input in inputs] self._inputs = DictTuple(inputs, lambda _input: str(_input)) + outputs = outputs if outputs is not None else [] outputs = [SystemOutput(self, effect_output) for effect_output in outputs] self._outputs = DictTuple(outputs, lambda _output: str(_output)) diff --git a/pluginsmanager/model/system/system_effect_builder.py b/pluginsmanager/model/system/system_effect_builder.py index 949c305..8854cd7 100644 --- a/pluginsmanager/model/system/system_effect_builder.py +++ b/pluginsmanager/model/system/system_effect_builder.py @@ -18,7 +18,13 @@ class SystemEffectBuilder(object): """ - Automatic system physical ports detection + 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. + + .. _a2jmidid: http://manual.ardour.org/setting-up-your-system/setting-up-midi/midi-on-linux/ :param JackClient jack_client: :class:`.JackClient` instance that will get the information to generate :class:`.SystemEffect` From e9cd69a4ef8d43fad47561ba7946dccfc64ebf86 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Wed, 1 Nov 2017 22:54:08 -0300 Subject: [PATCH 24/31] Issue #62 - Improve documentation, discover SystemEffect audio ports --- .../util/mod_pedalboard_converter.py | 37 +- test/util/mod_pedalboard_converter_test.py | 17 +- test/util/teste.pedalboard/addressings.json | 1 + test/util/teste.pedalboard/manifest.ttl | 11 + test/util/teste.pedalboard/teste.ttl | 398 ++++++++++++++++++ 5 files changed, 454 insertions(+), 10 deletions(-) create mode 100644 test/util/teste.pedalboard/addressings.json create mode 100644 test/util/teste.pedalboard/manifest.ttl create mode 100644 test/util/teste.pedalboard/teste.ttl diff --git a/pluginsmanager/util/mod_pedalboard_converter.py b/pluginsmanager/util/mod_pedalboard_converter.py index c4109fe..fcc87e3 100644 --- a/pluginsmanager/util/mod_pedalboard_converter.py +++ b/pluginsmanager/util/mod_pedalboard_converter.py @@ -21,21 +21,31 @@ class ModPedalboardConverter(object): """ - ModPedalboardConverter is a utility to convert MOD pedalboards structure + ModPedalboardConverter is a utility to convert MOD [#]_ pedalboards structure in plugins manager pedalboard. - `MOD`_, an awesome music enterprise, create the `mod-ui`_, a visual interface - that enable create pedalboards in a simple way. + For use, is necessary that the computer system contains the mod_ui with your codes compiled [#]_ + 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) + + .. [#] `MOD`_, an awesome music enterprise, create the `mod-ui`_, a visual interface + that enable create pedalboards in a simple way. + .. [#] See the docs: https://github.com/moddevices/mod-ui#install .. _MOD: http://moddevices.com/ .. _mod-ui: https://github.com/moddevices/mod-ui + + :param Path mod_ui_path: path that mod_ui has in the computer. + :param Lv2EffectBuilder builder: Builder for generate the lv2 effects """ def __init__(self, mod_ui_path, builder): - """ - :param Path mod_ui_path: path that mod_ui has in the computer. - :param Lv2EffectBuilder builder: Builder for generate the lv2 effects - """ self._load_mod_ui_libraries(mod_ui_path) self.builder = builder @@ -49,22 +59,26 @@ def _load_mod_ui_libraries(self, path): def get_pedalboard_info(self, path): """ :param Path path: Path that the pedalboard has been persisted. - Generally is in format `path/to/pedalboard/name.pedalboard` + Generally is in format ``path/to/pedalboard/name.pedalboard`` :return dict: pedalboard persisted configurations """ from utils import get_pedalboard_info return get_pedalboard_info(str(path)) - def convert(self, pedalboard_path, system_effect): + def convert(self, pedalboard_path, system_effect=None): """ :param Path pedalboard_path: Path that the pedalboard has been persisted. Generally is in format `path/to/pedalboard/name.pedalboard` :param SystemEffect system_effect: Effect that contains the audio interface outputs and inputs + or None for auto discover :return Pedalboard: Pedalboard loaded """ info = self.get_pedalboard_info(pedalboard_path) + if system_effect is None: + system_effect = self._discover_system_effect(info['hardware']) + pedalboard = Pedalboard(info['title']) effects_instance = {} @@ -107,3 +121,8 @@ def _get_port(self, name, effects_instance, system_effect): ports = list(filtered)[0] return ports[port] + def _discover_system_effect(self, hardware): + outputs = ['capture_{}'.format(i) for i in range(1, hardware['audio_outs']+1)] + inputs = ['playback_{}'.format(i) for i in range(1, hardware['audio_ins']+1)] + + return SystemEffect('system', outputs, inputs) diff --git a/test/util/mod_pedalboard_converter_test.py b/test/util/mod_pedalboard_converter_test.py index 07a34fd..e6cb053 100644 --- a/test/util/mod_pedalboard_converter_test.py +++ b/test/util/mod_pedalboard_converter_test.py @@ -23,6 +23,7 @@ class ModPedalboardConverterTest(unittest.TestCase): + @unittest.skipIf('TRAVIS' in os.environ, 'Mod-ui not configured in Travis build') def test_all(self): path = Path('/home/paulo/git/mod/mod_ui/') @@ -31,9 +32,23 @@ def test_all(self): converter = ModPedalboardConverter(path, builder) - pedalboard_path = Path('/home/paulo/.pedalboards/teste.pedalboard') + here = os.path.abspath(os.path.dirname(__file__)) + pedalboard_path = Path(here+'/teste.pedalboard') system_effect = SystemEffect('system', ['capture_1', 'capture_2'], ['playback_1', 'playback_2']) print(converter.get_pedalboard_info(pedalboard_path)) pedalboard = converter.convert(pedalboard_path, system_effect) print(pedalboard.json) + + @unittest.skipIf('TRAVIS' in os.environ, 'Mod-ui not configured in Travis build') + def test_discover_system_effect(self): + path = Path('/home/paulo/git/mod/mod_ui/') + builder = Lv2EffectBuilder() + + converter = ModPedalboardConverter(path, builder) + here = os.path.abspath(os.path.dirname(__file__)) + pedalboard_path = Path(here + '/teste.pedalboard') + + print(converter.get_pedalboard_info(pedalboard_path)) + pedalboard = converter.convert(pedalboard_path) + print(pedalboard.json) diff --git a/test/util/teste.pedalboard/addressings.json b/test/util/teste.pedalboard/addressings.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/test/util/teste.pedalboard/addressings.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/util/teste.pedalboard/manifest.ttl b/test/util/teste.pedalboard/manifest.ttl new file mode 100644 index 0000000..4df670e --- /dev/null +++ b/test/util/teste.pedalboard/manifest.ttl @@ -0,0 +1,11 @@ +@prefix ingen: . +@prefix lv2: . +@prefix pedal: . +@prefix rdfs: . + + + lv2:prototype ingen:GraphPrototype ; + a lv2:Plugin , + ingen:Graph , + pedal:Pedalboard ; + rdfs:seeAlso . diff --git a/test/util/teste.pedalboard/teste.ttl b/test/util/teste.pedalboard/teste.ttl new file mode 100644 index 0000000..2db5889 --- /dev/null +++ b/test/util/teste.pedalboard/teste.ttl @@ -0,0 +1,398 @@ +@prefix atom: . +@prefix doap: . +@prefix ingen: . +@prefix lv2: . +@prefix midi: . +@prefix mod: . +@prefix pedal: . +@prefix rdfs: . + +_:b1 + ingen:tail ; + ingen:head . + +_:b2 + ingen:tail ; + ingen:head . + +_:b3 + ingen:tail ; + ingen:head . + +_:b4 + ingen:tail ; + ingen:head . + +_:b5 + ingen:tail ; + ingen:head . + +_:b6 + ingen:tail ; + ingen:head . + +_:b7 + ingen:tail ; + ingen:head . + +_:b8 + ingen:tail ; + ingen:head . + +_:b9 + ingen:tail ; + ingen:head . + + + ingen:canvasX 1585.0 ; + ingen:canvasY 1.0 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 0 ; + lv2:minorVersion 34 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + , + , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 1.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + a lv2:ControlPort , + lv2:OutputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:canvasX 743.3 ; + ingen:canvasY 1143.7 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 3 ; + lv2:minorVersion 1039 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + a atom:AtomPort , + lv2:OutputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + a lv2:ControlPort , + lv2:OutputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:canvasX 1911.5 ; + ingen:canvasY 1137.5 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 3 ; + lv2:minorVersion 1039 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + , + , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + a atom:AtomPort , + lv2:OutputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 1.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 48.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + a lv2:ControlPort , + lv2:OutputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:canvasX 2543.1 ; + ingen:canvasY 490.9 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + a atom:AtomPort , + lv2:InputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:canvasX 1519.3 ; + ingen:canvasY 320.6 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + a atom:AtomPort , + lv2:InputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + +<:bpb> + ingen:value 4.000000 ; + lv2:index 0 ; + a lv2:ControlPort , + lv2:InputPort . + +<:bpm> + ingen:value 120.000000 ; + lv2:index 1 ; + a lv2:ControlPort , + lv2:InputPort . + +<:rolling> + ingen:value 0 ; + lv2:index 2 ; + a lv2:ControlPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + lv2:index 3 ; + lv2:name "Control In" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_in" ; + 4096 ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + lv2:index 4 ; + lv2:name "Control Out" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_out" ; + 4096 ; + a atom:AtomPort , + lv2:OutputPort . + + + lv2:index 5 ; + lv2:name "Capture 1" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "capture_1" ; + a lv2:AudioPort , + lv2:InputPort . + + + lv2:index 6 ; + lv2:name "Capture 2" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "capture_2" ; + a lv2:AudioPort , + lv2:InputPort . + + + lv2:index 7 ; + lv2:name "Playback 1" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "playback_1" ; + a lv2:AudioPort , + lv2:OutputPort . + + + lv2:index 8 ; + lv2:name "Playback 2" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "playback_2" ; + a lv2:AudioPort , + lv2:OutputPort . + +<> + doap:name "teste" ; + pedal:width 1342 ; + pedal:height 1176 ; + pedal:addressings ; + pedal:screenshot ; + pedal:thumbnail ; + ingen:polyphony 1 ; + ingen:arc _:b1 , + _:b2 , + _:b3 , + _:b4 , + _:b5 , + _:b6 , + _:b7 , + _:b8 , + _:b9 ; + ingen:block , + , + , + , + ; + lv2:port <:bpb> , + <:bpm> , + <:rolling> , + , + , + , + , + , + ; + lv2:extensionData ; + a lv2:Plugin , + ingen:Graph , + pedal:Pedalboard . From 146b62546d4b17943ff0123f5e0bf12742c71110 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Thu, 2 Nov 2017 10:20:01 -0300 Subject: [PATCH 25/31] Issue #62 - discover_system-effect is now public. Improve discover_system_effect to discover midi-in and midi-out --- .../util/mod_pedalboard_converter.py | 19 +- test/util/EPiano.pedalboard/EPiano.ttl | 1056 +++++++++++++++++ test/util/EPiano.pedalboard/addressings.json | 1 + test/util/EPiano.pedalboard/manifest.ttl | 11 + test/util/EPiano.pedalboard/screenshot.png | Bin 0 -> 137508 bytes test/util/EPiano.pedalboard/thumbnail.png | Bin 0 -> 31315 bytes .../EPiano_simple_tt.ttl | 246 ++++ .../addressings.json | 1 + .../EPiano_simple_tt.pedalboard/manifest.ttl | 11 + .../screenshot.png | Bin 0 -> 48859 bytes .../EPiano_simple_tt.pedalboard/thumbnail.png | Bin 0 -> 12510 bytes test/util/mod_pedalboard_converter_test.py | 42 + .../addressings.json | 1 + .../setBfree_ttymidi.pedalboard/manifest.ttl | 11 + .../screenshot.png | Bin 0 -> 62368 bytes .../setBfree_ttymidi.ttl | 186 +++ .../setBfree_ttymidi.pedalboard/thumbnail.png | Bin 0 -> 14979 bytes 17 files changed, 1581 insertions(+), 4 deletions(-) create mode 100644 test/util/EPiano.pedalboard/EPiano.ttl create mode 100644 test/util/EPiano.pedalboard/addressings.json create mode 100644 test/util/EPiano.pedalboard/manifest.ttl create mode 100644 test/util/EPiano.pedalboard/screenshot.png create mode 100644 test/util/EPiano.pedalboard/thumbnail.png create mode 100644 test/util/EPiano_simple_tt.pedalboard/EPiano_simple_tt.ttl create mode 100644 test/util/EPiano_simple_tt.pedalboard/addressings.json create mode 100644 test/util/EPiano_simple_tt.pedalboard/manifest.ttl create mode 100644 test/util/EPiano_simple_tt.pedalboard/screenshot.png create mode 100644 test/util/EPiano_simple_tt.pedalboard/thumbnail.png create mode 100644 test/util/setBfree_ttymidi.pedalboard/addressings.json create mode 100644 test/util/setBfree_ttymidi.pedalboard/manifest.ttl create mode 100644 test/util/setBfree_ttymidi.pedalboard/screenshot.png create mode 100644 test/util/setBfree_ttymidi.pedalboard/setBfree_ttymidi.ttl create mode 100644 test/util/setBfree_ttymidi.pedalboard/thumbnail.png diff --git a/pluginsmanager/util/mod_pedalboard_converter.py b/pluginsmanager/util/mod_pedalboard_converter.py index fcc87e3..2afa47d 100644 --- a/pluginsmanager/util/mod_pedalboard_converter.py +++ b/pluginsmanager/util/mod_pedalboard_converter.py @@ -71,13 +71,13 @@ def convert(self, pedalboard_path, system_effect=None): :param Path pedalboard_path: Path that the pedalboard has been persisted. Generally is in format `path/to/pedalboard/name.pedalboard` :param SystemEffect system_effect: Effect that contains the audio interface outputs and inputs - or None for auto discover + or None for **auto discover** :return Pedalboard: Pedalboard loaded """ info = self.get_pedalboard_info(pedalboard_path) if system_effect is None: - system_effect = self._discover_system_effect(info['hardware']) + system_effect = self.discover_system_effect(info) pedalboard = Pedalboard(info['title']) @@ -121,8 +121,19 @@ def _get_port(self, name, effects_instance, system_effect): ports = list(filtered)[0] return ports[port] - def _discover_system_effect(self, hardware): + def discover_system_effect(self, pedalboard_info): + """ + Generate the system effect based in pedalboard_info + + :param dict pedalboard_info: For obtain this, see + :meth:`~pluginsmanager.util.mod_pedalboard_converter.ModPedalboardConvert.get_pedalboard_info()` + :return SystemEffect: SystemEffect generated based in pedalboard_info + """ + hardware = pedalboard_info['hardware'] + outputs = ['capture_{}'.format(i) for i in range(1, hardware['audio_outs']+1)] inputs = ['playback_{}'.format(i) for i in range(1, hardware['audio_ins']+1)] + midi_outputs = [midi_out['symbol'] for midi_out in hardware['midi_outs'] if midi_out['valid']] + midi_inputs = [midi_in['symbol'] for midi_in in hardware['midi_ins'] if midi_in['valid']] - return SystemEffect('system', outputs, inputs) + return SystemEffect('system', outputs, inputs, midi_outputs, midi_inputs) diff --git a/test/util/EPiano.pedalboard/EPiano.ttl b/test/util/EPiano.pedalboard/EPiano.ttl new file mode 100644 index 0000000..fc6664c --- /dev/null +++ b/test/util/EPiano.pedalboard/EPiano.ttl @@ -0,0 +1,1056 @@ +@prefix atom: . +@prefix doap: . +@prefix ingen: . +@prefix lv2: . +@prefix midi: . +@prefix mod: . +@prefix pedal: . +@prefix rdfs: . + +_:b1 + ingen:tail ; + ingen:head . + +_:b2 + ingen:tail ; + ingen:head . + +_:b3 + ingen:tail ; + ingen:head . + +_:b4 + ingen:tail ; + ingen:head . + +_:b5 + ingen:tail ; + ingen:head . + +_:b6 + ingen:tail ; + ingen:head . + +_:b7 + ingen:tail ; + ingen:head . + +_:b8 + ingen:tail ; + ingen:head . + +_:b9 + ingen:tail ; + ingen:head . + +_:b10 + ingen:tail ; + ingen:head . + +_:b11 + ingen:tail ; + ingen:head . + +_:b12 + ingen:tail ; + ingen:head . + +_:b13 + ingen:tail ; + ingen:head . + +_:b14 + ingen:tail ; + ingen:head . + +_:b15 + ingen:tail ; + ingen:head . + +_:b16 + ingen:tail ; + ingen:head . + +_:b17 + ingen:tail ; + ingen:head . + +_:b18 + ingen:tail ; + ingen:head . + +_:b19 + ingen:tail ; + ingen:head . + +_:b20 + ingen:tail ; + ingen:head . + +_:b21 + ingen:tail ; + ingen:head . + + + ingen:canvasX 261.0 ; + ingen:canvasY 997.0 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 3 ; + lv2:minorVersion 0 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + a atom:AtomPort , + lv2:InputPort . + + + ingen:value 23.285000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 50.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 1.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 100.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 7.300000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 50.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:canvasX 3287.0 ; + ingen:canvasY 301.0 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 2 ; + lv2:minorVersion 0 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + , + , + , + , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + ingen:value 234.449997 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value -16.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 4.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 758.500000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:canvasX 2681.0 ; + ingen:canvasY 1142.0 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 6 ; + lv2:minorVersion 2 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + ingen:value 186.015747 ; + midi:binding [ + midi:channel 0 ; + midi:controllerNumber 78 ; + lv2:minimum 6.000000 ; + lv2:maximum 1000.000000 ; + a midi:Controller ; + ] ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 5.511811 ; + midi:binding [ + midi:channel 0 ; + midi:controllerNumber 76 ; + lv2:minimum 0.000000 ; + lv2:maximum 100.000000 ; + a midi:Controller ; + ] ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 21.259842 ; + midi:binding [ + midi:channel 0 ; + midi:controllerNumber 5 ; + lv2:minimum 0.000000 ; + lv2:maximum 100.000000 ; + a midi:Controller ; + ] ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 1.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 7500.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 20.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 120.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 1.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 16.535433 ; + midi:binding [ + midi:channel 0 ; + midi:controllerNumber 77 ; + lv2:minimum 0.000000 ; + lv2:maximum 100.000000 ; + a midi:Controller ; + ] ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 1.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + a lv2:ControlPort , + lv2:OutputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:canvasX 2433.0 ; + ingen:canvasY 122.0 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 0 ; + lv2:minorVersion 0 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + ingen:value 31.000000 ; + midi:binding [ + midi:channel 0 ; + midi:controllerNumber 94 ; + lv2:minimum 0.000000 ; + lv2:maximum 127.000000 ; + a midi:Controller ; + ] ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 64.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 18.000000 ; + midi:binding [ + midi:channel 0 ; + midi:controllerNumber 93 ; + lv2:minimum 0.000000 ; + lv2:maximum 127.000000 ; + a midi:Controller ; + ] ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 85.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 118.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 109.000000 ; + midi:binding [ + midi:channel 0 ; + midi:controllerNumber 92 ; + lv2:minimum 1.000000 ; + lv2:maximum 600.000000 ; + a midi:Controller ; + ] ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 16.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:canvasX 1026.4 ; + ingen:canvasY 1005.3 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 0 ; + lv2:minorVersion 2 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + , + , + , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + ingen:value 0.582677 ; + midi:binding [ + midi:channel 0 ; + midi:controllerNumber 75 ; + lv2:minimum 0.000000 ; + lv2:maximum 1.000000 ; + a midi:Controller ; + ] ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.500000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.637795 ; + midi:binding [ + midi:channel 0 ; + midi:controllerNumber 91 ; + lv2:minimum 0.000000 ; + lv2:maximum 1.000000 ; + a midi:Controller ; + ] ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.503937 ; + midi:binding [ + midi:channel 0 ; + midi:controllerNumber 72 ; + lv2:minimum 0.000000 ; + lv2:maximum 1.000000 ; + a midi:Controller ; + ] ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 1.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.645669 ; + midi:binding [ + midi:channel 0 ; + midi:controllerNumber 73 ; + lv2:minimum 0.000000 ; + lv2:maximum 1.000000 ; + a midi:Controller ; + ] ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:canvasX 700.0 ; + ingen:canvasY 1049.0 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 0 ; + lv2:minorVersion 770 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + ingen:value -16.473213 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 1.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + a lv2:ControlPort , + lv2:OutputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:canvasX 438.4 ; + ingen:canvasY 158.2 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 0 ; + lv2:minorVersion 2 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + , + , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + ingen:value 0.236220 ; + midi:binding [ + midi:channel 0 ; + midi:controllerNumber 65 ; + lv2:minimum 0.000000 ; + lv2:maximum 1.000000 ; + a midi:Controller ; + ] ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.346457 ; + midi:binding [ + midi:channel 0 ; + midi:controllerNumber 74 ; + lv2:minimum 0.000000 ; + lv2:maximum 1.000000 ; + a midi:Controller ; + ] ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.527559 ; + midi:binding [ + midi:channel 0 ; + midi:controllerNumber 71 ; + lv2:minimum 0.000000 ; + lv2:maximum 1.000000 ; + a midi:Controller ; + ] ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:canvasX 3764.0 ; + ingen:canvasY 679.0 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 0 ; + lv2:minorVersion 770 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + , + , + , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + ingen:value -2.991071 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 1.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + a lv2:ControlPort , + lv2:OutputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:canvasX 1866.0 ; + ingen:canvasY 150.0 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 0 ; + lv2:minorVersion 520 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + , + , + , + , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:InputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + a lv2:AudioPort , + lv2:OutputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value -0.748031 ; + midi:binding [ + midi:channel 0 ; + midi:controllerNumber 95 ; + lv2:minimum -1.000000 ; + lv2:maximum 1.000000 ; + a midi:Controller ; + ] ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + +<:bpb> + ingen:value 4.000000 ; + lv2:index 0 ; + a lv2:ControlPort , + lv2:InputPort . + +<:bpm> + ingen:value 120.000000 ; + lv2:index 1 ; + a lv2:ControlPort , + lv2:InputPort . + +<:rolling> + ingen:value 0 ; + lv2:index 2 ; + a lv2:ControlPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + lv2:index 3 ; + lv2:name "Control In" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_in" ; + 4096 ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + lv2:index 4 ; + lv2:name "Control Out" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_out" ; + 4096 ; + a atom:AtomPort , + lv2:OutputPort . + + + lv2:index 5 ; + lv2:name "Playback 1" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "playback_1" ; + a lv2:AudioPort , + lv2:OutputPort . + + + lv2:index 6 ; + lv2:name "Playback 2" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "playback_2" ; + a lv2:AudioPort , + lv2:OutputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + lv2:index 7 ; + lv2:name "pisound MIDI PS 19FP3ND" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "midi_capture_1" ; + 4096 ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + lv2:index 8 ; + lv2:name "pisound MIDI PS 19FP3ND" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "midi_playback_1" ; + 4096 ; + a atom:AtomPort , + lv2:OutputPort . + +<> + doap:name "EPiano" ; + pedal:width 0 ; + pedal:height 0 ; + pedal:addressings ; + pedal:screenshot ; + pedal:thumbnail ; + ingen:polyphony 1 ; + ingen:arc _:b1 , + _:b2 , + _:b3 , + _:b4 , + _:b5 , + _:b6 , + _:b7 , + _:b8 , + _:b9 , + _:b10 , + _:b11 , + _:b12 , + _:b13 , + _:b14 , + _:b15 , + _:b16 , + _:b17 , + _:b18 , + _:b19 , + _:b20 , + _:b21 ; + ingen:block , + , + , + , + , + , + , + , + ; + lv2:port <:bpb> , + <:bpm> , + <:rolling> , + , + , + , + , + , + ; + lv2:extensionData ; + a lv2:Plugin , + ingen:Graph , + pedal:Pedalboard . diff --git a/test/util/EPiano.pedalboard/addressings.json b/test/util/EPiano.pedalboard/addressings.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/test/util/EPiano.pedalboard/addressings.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/util/EPiano.pedalboard/manifest.ttl b/test/util/EPiano.pedalboard/manifest.ttl new file mode 100644 index 0000000..4592f7d --- /dev/null +++ b/test/util/EPiano.pedalboard/manifest.ttl @@ -0,0 +1,11 @@ +@prefix ingen: . +@prefix lv2: . +@prefix pedal: . +@prefix rdfs: . + + + lv2:prototype ingen:GraphPrototype ; + a lv2:Plugin , + ingen:Graph , + pedal:Pedalboard ; + rdfs:seeAlso . diff --git a/test/util/EPiano.pedalboard/screenshot.png b/test/util/EPiano.pedalboard/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..4889752a2d25cbcc3c4ef1c9057ab81f9d79c0cb GIT binary patch literal 137508 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%0A1Zy0j7)1`GnJd>DCMVK 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 Y*n+iJB=tK40KDtc1)K8~W*#yB12d{1TmS$7 literal 0 HcmV?d00001 diff --git a/test/util/data/EPiano_simple.pedalboard/thumbnail.png b/test/util/data/EPiano_simple.pedalboard/thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..1720d811a3131c5d249caf04af2eb5801aea1c1a GIT binary patch literal 13672 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 literal 0 HcmV?d00001 diff --git a/test/util/data/setBfree_simple.pedalboard/addressings.json b/test/util/data/setBfree_simple.pedalboard/addressings.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/test/util/data/setBfree_simple.pedalboard/addressings.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/util/data/setBfree_simple.pedalboard/manifest.ttl b/test/util/data/setBfree_simple.pedalboard/manifest.ttl new file mode 100644 index 0000000..f2e3ed8 --- /dev/null +++ b/test/util/data/setBfree_simple.pedalboard/manifest.ttl @@ -0,0 +1,11 @@ +@prefix ingen: . +@prefix lv2: . +@prefix pedal: . +@prefix rdfs: . + + + lv2:prototype ingen:GraphPrototype ; + a lv2:Plugin , + ingen:Graph , + pedal:Pedalboard ; + rdfs:seeAlso . diff --git a/test/util/data/setBfree_simple.pedalboard/screenshot.png b/test/util/data/setBfree_simple.pedalboard/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..2611d827f058d9d4aba6847b14d2aa361b4db707 GIT binary patch literal 77762 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�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 Q1pz;5%9=`L3Krr22S*q;ssI20 literal 0 HcmV?d00001 diff --git a/test/util/data/setBfree_simple.pedalboard/setBfree_simple.ttl b/test/util/data/setBfree_simple.pedalboard/setBfree_simple.ttl new file mode 100644 index 0000000..cdd96b2 --- /dev/null +++ b/test/util/data/setBfree_simple.pedalboard/setBfree_simple.ttl @@ -0,0 +1,151 @@ +@prefix atom: . +@prefix doap: . +@prefix ingen: . +@prefix lv2: . +@prefix midi: . +@prefix mod: . +@prefix pedal: . +@prefix rdfs: . + +_:b1 + ingen:tail ; + ingen:head . + +_:b2 + ingen:tail ; + ingen:head . + +_:b3 + ingen:tail ; + ingen:head . + +_:b4 + ingen:tail ; + ingen:head . + +_:b5 + ingen:tail ; + ingen:head . + +_:b6 + ingen:tail ; + ingen:head . + + + ingen:canvasX 956.4 ; + ingen:canvasY 294.9 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 9 ; + lv2:minorVersion 2059 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + a atom:AtomPort , + lv2:OutputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + lv2:index 0 ; + lv2:name "Control In" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_in" ; + 4096 ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + lv2:index 1 ; + lv2:name "Control Out" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_out" ; + 4096 ; + a atom:AtomPort , + lv2:OutputPort . + + + lv2:index 2 ; + lv2:name "Playback 1" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "playback_1" ; + a lv2:AudioPort , + lv2:OutputPort . + + + lv2:index 3 ; + lv2:name "Playback 2" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "playback_2" ; + a lv2:AudioPort , + lv2:OutputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + lv2:index 4 ; + lv2:name "Serial MIDI In" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "serial_midi_in" ; + 4096 ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + lv2:index 5 ; + lv2:name "Serial MIDI In" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "serial_midi_out" ; + 4096 ; + a atom:AtomPort , + lv2:OutputPort . + +<> + doap:name "setBfree_simple" ; + pedal:width 0 ; + pedal:height 0 ; + pedal:addressings ; + pedal:screenshot ; + pedal:thumbnail ; + ingen:polyphony 1 ; + ingen:arc _:b1 , + _:b2 , + _:b3 , + _:b4 , + _:b5 , + _:b6 ; + ingen:block ; + lv2:port , + , + , + , + , + ; + lv2:extensionData ; + a lv2:Plugin , + ingen:Graph , + pedal:Pedalboard . diff --git a/test/util/data/setBfree_simple.pedalboard/thumbnail.png b/test/util/data/setBfree_simple.pedalboard/thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..de00de78d8dcf378415f6e6f4f0b76089ab318a5 GIT binary patch literal 17233 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 Date: Thu, 30 Nov 2017 08:01:12 -0300 Subject: [PATCH 30/31] Issue #62 Improve docs --- pluginsmanager/util/mod_pedalboard_converter.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pluginsmanager/util/mod_pedalboard_converter.py b/pluginsmanager/util/mod_pedalboard_converter.py index 97c8b6d..65b4f09 100644 --- a/pluginsmanager/util/mod_pedalboard_converter.py +++ b/pluginsmanager/util/mod_pedalboard_converter.py @@ -38,6 +38,23 @@ class ModPedalboardConverter(object): >>> 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) + .. [#] `MOD`_, an awesome music enterprise, create the `mod-ui`_, a visual interface that enable create pedalboards in a simple way. .. [#] See the docs: https://github.com/moddevices/mod-ui#install From 8a6f7e8d408743d7559ed41ba48af238510720ba Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Thu, 30 Nov 2017 10:19:26 -0300 Subject: [PATCH 31/31] Version 0.6.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index d291359..59a4238 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ def readme(): setup( name='PedalPi-PluginsManager', - version='0.6.0alpha1', + version='0.6.0', description='Pythonic management of LV2 audio plugins with mod-host.', long_description=readme(),

=%=BgkXxap8gld+APDtH!it3?YbOUg37$_KKa;G3sqv@Pazi)LvwkrMuU&!tw#qE zE1C&DDkR&Uw=k^D$JN+k`hJt!c48>npZtzA?uQE*HASumL~CaJdN}Jf)hDhZM#=!< zC4BZ1vO8Sre@AN5nEh0Gg#RZU1LFKd0<>EHot|tA5HY|OOITVNz{8-{lm$WvnI@f! z)Idy)Mr{o^gmeN}!R!t@H2g0HT~Pq~U8;9q>i~=(DIY2fumB(-ge(|~A^-r>BEY;& zRP#38R|E&|9jvuj>91mWc?D~)ZT$Q`)_HTt=;A-kI(gPHK9Rn7ycAs*v>bl2CR;eRp7#hoQ_xyhJjR}Agf19j(YLwyQ8S%<8psRkzBnOsWi1niFvu)Dhh z@2d2y>B5eSc0vd+9g&v)3)K*Vze2l40FD3oU{*R}S3M%;{S!jS03FGW-N5@;fG--~omZMs4B&aHLdQ!^k4Ifi;D%d>Jqp`lz9(Ic5c2Ag3xs)% z9VCy*{EN$LY!1%hsOVW(^Vjl5JJcTLjiyg zA+3t6t&b)+9{2l~UazXrUT?DV2yiugmyO&i@t@rK?6^+*dX~-Ib)DxObHcey0XujD zzF6Dy@R!i80<9Y%gq#EoMnVW7WR9T#K!}hQL8>4vk;O(1c=Vw7tIsSIn;*-@CSFl2~SSKmPY{)LI@#* z5JDCZ3IK$(bK$l3aS31yV0e7*pVln>{!94&p8;Gx(MCQq^ZCUu&K z7{LfeFoF?`U<4x=!JZG<)YN1EqO{?4pG8wslhM-BBHx$RjbH>L7{LfeFoF?)r;N3<~Yup*|TSV@rfs%n5DJ;z7S&BqmMrNKgHjVjH?m6FW6Hw7>%c? zn8o)Lg>Ie)u2&4m#+d+T)Hp?)b*WMjybWNs|Jnop#!S zNs}f802VG>SaIs9r_NiraN*nq3l^BWqhT#AEmCVO5j)Wh#P-FJ01iF$(1LB-FURBY z7hIuR5dxpjx5;*#exzIrP+MEOIiJt3ip63t;*F_2Md=v9e;{_tL-ZyPfd2HSKRwEI z-5*LRD{R~T*4=mCz3GfI&iG_mS=pzO$>i<#-FM%;)z#G}yRQ4us;a8{fj_sjw8%&# zqTc8Be^4O+nwpwqG#XXYr%(T>)_UKuW5@opwYBwI2OV_KHv)mcDf8ydyRWUS?Hb2% zstSd|*MJ`2+wXPTT3T8}Boa}PNCY4V_=;_ofUeM5B)ok!LWpKi!1Wb=suOuSfto-3 z;Sa6AnLr$nG&L2*Y~K9CuCA^^@jN4AX9VvX-WS2EH3GC;wrrW4H*cQ0@ci?~#ZswB z2m)1AReNcz+s;1w%>6*jsH`mCPiy_RkA3W8eM3Wo75RLj`~7J1hX^GT4uAghpIspY zuIskuayhrWynGd)eLmlM+qM%vpKl|eAAR)E_QMZ9d}S(?+V=9xFFU+<<{ts*NF>6y zzI^scfwB91yr*K?0e0D_5TF%8$XpVC*J_y?JwvNtl}5V=AwdeX<2u?c_@ot3MzUL~ zLV9hiulvbIZuNY{jG1ywZ`bBW z0T(cUxivL48wUpmlf`{TY;x+$Rl`b5CGNH)pJfh`Q+R8+H0=~XmmE071?Z-TrOA0=X3r-p`i2mf>27? zj^kKGFQ@M7>vLXw@x{A=|G`_nXV_KOUkF;%mGa5?cUB*N_62t??=_F>j^~u$=Tqh5 zr^)i#Q8kKld6ZZ$P1tqmcBzUn)dF53U_lP{o|uSd3&mj@AmLG)ieQ*$jqZkjZ4QZ5zjNFbw09 zuIoMotN=RLMS@o=C4~_D;8*|eo9hd8$88zdV$Wfdx%#0)kEzi!=1!V2|JXA&Jo&e- z%83)R@%DC?kyXK$Q1fSxmRg7^V6Q^K-2n9AX)Yu9H)w5b6@aC+_T}?= z>9~$szI?ezrBbxDx06n#7&U4%g+iW0B0(~dKo|zeM1q={8l;p0&;C0e2(ydEPLbCo z_nCXZ5h+_VRMpn&t;wWVz5H>?Yex|bh5?P#nkS!nobu{Ae3lP{KuYNE>*vK69;I&V zcn}h;6prJtY2zls)d{?23xs76su`slCQYBW;Yp_C6Nv#JjVE|VxZ)$&t=O$R-mb1e z0r>NI+YE(54D|Q$;{0O;BhFm5|!|eHto;8n|Cw`WyQDaC9_F@Lgm@xk&#_V$#lMh))E*U4A7-G~u zhf_0YmJqnY@(1gINp3n_QS1kJbT!{D=*zo8OG`^B-$V)j5>YskZ{ov&-Ky~p4kiR( zBvMH+@2Kfq@$E~v^$$@F+^>x+ca|MC-kQj^z-nRk)(A(Qv;=z*7=h@QU&bjBE$LNWZ8GrH=sw*pa=BcOHvUw99 z`NSu=>>J@|5J zmtF7$0)8L+?LC`yt;<1pMnR)sn$v0~8T%jiKgQx{lM=i1xzYdfZV`+A?Fm|GeUp8f z-oln$hbTZ(l+uH`^ysCErJg-DnM#t&=2-gFvm6yHXY7PY^!D_yZQE8*F3&vs9M}Bl z$29J}52>8Zmd%^VW=ir2@a(z@a9dhhWNT}yXo|kI-gvu3iAJLeV9}yQ5-`z97-+Nx zCzl1&WZc}tsU9;4ty~ZS<=WIum`13699C@uZaznDs2A6<8Mp6IplpP8&`RSA2C14f zi^?&R@rT0XGHJ>KE~YL>pd3%zH2^VY%owSZ5=ZqMWkh*j1e*Z#$tRzDxYl}XUtixn z%a$#38XFtKGiS~`ZE$e#$)!t|Zd2gg_&JLZQG=EXLlmXP{h% zSR#QyA*E$%t(~OICX<635*wn;?}4f!cJl7s+5n?(VaqN?@dS@O_L%vNWBw@OHO~a= zri;y-1;hoT#gwtX0ZH)7bq()C!R?0$OC`lrRScZs=As~ zD&-$HZhU#$rgkwgJj43jH$GuSB9Vf3s<+si*XfO@B`(4P`YLR)A3L7y_0>tYag-n$h?IL0s3t&SxpNAicE} zbMhQaD?q?VGPXkctE;O+LqkIjo`1k81y$_Ohxg3pt6!&CF9NYhYkk&PXN?E0kwVne z*Vl($TDI)gy&D_P_XPr<@tNk48ZJE1bw@jn^JU;3;Kin3F4=HUL(wVNj$_R>FAj-6_lPQ#ef zE%uAk-rlbF+i!pQkAM7w>wkDPp`JA8%O`J5oVrzF!i%`8tZ(U1f*}ZIRT~7Bv zl7l{fIiqGBNc`zLaXMF%7);RiOdSWEa|Nlk71+z~Bi7SRENe6Nq;nZPbANI#-c5h& zGpt#&hPwTZW&h89o2(OVTL#8+# z%f~#UbA=ZHqS5GxL+}HNT_Jb{p#O{SjtU0?=SV5W<&CV*w6kjC`mMesiP=dzdAJoc z>7#=&W);E`Y1eT;y8^9?g10y-g+>&IlMo;@UPvffIJQk79JHp_?RENk+D`9_b(8AL zsJ6n!N9zjp8!C;l*@Tm_kcJcjA;=C7Od*6uCD774dWu1W&>DnB!4ROO)+kDrW2KZr zqjk8mS~Gjn)#Wv_J_AR~DD- zN@%TJr4`;e1j++-uEblw_Ql36-pb*P|4JQ>|D3G*Xrps zH@{dpextk1?HCLPDmVG}Qc8`gudCOWU3Qs>#bWgI^e}DOG}f+N%fP?@vu4cXgyT;j zm&=h(r)k@=g~6dA?7S^rT>Wf(109`%9d!d6t;&4Iwrx+>1}ZmB(BVWOnU~T>(DIpn zt)*cKLuxGy6DeG@>BI65#Cm;OH*NIyrQ%k(3I;Z@&FLKoSW~xDBYe|PO0n*tJMbsF zP{L2Le+_FNjbfORl@I(8!ym%$53u2drx`bYApMEj>K(2k<+IzM;h#L;ClM8>vq$IBixS zneQEPvsYFdX5nMUoH5gsQYX`yKVJ6gLp^vAg(Hlf4=CQP;1wFp1uPnE1ogEUGx-QI z7rj6J=bkRQGCW2Is2STZai(7w!Gw_z>J?+gXL{#-!<=P=mFsAMA(ZlTIIZ!7uvWwR zhU+>gT6?Y}is*^5RqXq)0xt?%~=FS2HxedSZN3)f6MXf3mCo`dIAR!+)DX z{D;$nwiaIi8;gIts2XpK|Ixnt?mK-bHl)_9UL#D)L@C9}l`DzGV-)gvve^u-QkbSm zDwP5uw3Je0l4UBf0DcoXEt|J6*$k1-7tjc_));{h0mI;LPu%lQ7jAoXHEUVT zwoiQIQ-{n>)o(WINQQp#X{gdr(F(MIr}$}<>mr5p1hUqchQUx@UveA^4!A%(=Y zZT8)FUo6YQacs)V%gJVQOqei{=bwL`fx!U`Lkh>Xsi>~>9Y6oXnQecMEjawJgBxZY zJ1x_Gf5)qze)8Z|`;Iyx_1x{YyoqH-4fB04Mt3o!$Iz);nWLeVD9vi|;>B`Z*E(zI zi_50^X6o=0m#@}+(>6~YHEzPJI084H74GLjZ6&I^5e>xF@q&uQ0qITY|uar3r6eNuN=S?-v< z%4Qv=eLC>+%^P&X@!_hn>Z&oW+pL{apXumd`yw={j z%X300ErcvOpv3TBA+*#&?%W(-EWX)wXdJeLaV#JH}S^iZ<$jqy9zt171Il&4 zvB{+pR8N}aMYx%Mlw;#66C)UQ=Fd9p*p<(1J1OK3(b?BUYI@s>vnGCSW$lAg);hRj z^CJ5&fHz^hdvxY<1`x7c*KeR@Qil|y4idp^2WoIVwy%o*;7t6fcB%?n$r_aeryfka zeHG!%X7aL%M9mzmWSgwXwhM#|05y1g_7N`oyMt(7T~SYc4Xu% zz&vl}ufNJE>_)K-tBI{||pZ##wt zu&}g`4Z7945yJ)>K(PUn4U|^|Yo}CqR@M*cAruWQK>1 zsy-&19Gy&5pCtynHg_eS`omM%x-oS!>tv;?Tv4XVWI+{V*cTQuZ%ZB>qEvo$PKK8HdQs;b3f z#T4)&gayHhIxl4;3W+zylh6lZ@_|@SeCu3eZmuj)&_Z*g zbj?3_mvYw-{t8M7z*HIo$EIJ^5i8pVBMIa4uM!wDgM7^)3~jO~OKo5%)Ie8oZ&cX9 zH@F(RVFGg6(G0DBp2}1kLLijqTpJO(ZyzNym|VmnS0GBJubn`P78V&}e;o|>-c(&T z`BOD}ZTM@K>Uc7)_CKj%mYC%Jk((Ie9he>7mEdimMMj9I3;ZodE5m7g*?H!$Mmg_t zf8PJp|JsoiJoCD9Ex=?c`(Kv)$gM)kin4G(&Dd*_Oe9l;!$D%PIHuo6WzdhdZIn`M z>+GT|7^Ey5&~eKWUE4a+4=jKAE=>No{NX281KF=MUwE|I64);@KNa8aN8{Fh>x9df z|0nx?lF$zXh29QdG*y-X>V`GZF#1R(BtYfd+wDwitu2^5+D*A|jzWMW~i=Oc3 zwv}(`o<4nYINzfVW)+V&E@%`i-L-c{NdwWpiu?->W}ypNW74+r3DW*9%v>j`Orm;M zk&hRU`A+bglx4OOfB9aFSR2|@Y`+Tcf3)2P1VycOj)>Ci76q+}5TS*ZinwJ>lct(z zYj>*8G|TcTUx^?nxzgy@+FAF=E46t??4#QDZfuKp(np+89ZvkK-#z`7ub%nN8uYFN zZz)pCHL`w_;NTPae{QY`)GQirO#A7@##Mj*-`tgdI&a>ut(#x^imlPkZ;!sxJpY*= z4h8&HpA=%caveQ?|GkS`T^A`0606rBq@--$*=Wa;o`&IRUDA*g3b~9xskKFZ0AvsitYlO4yFP8Py!@pYAx3n+YOQUF@^&Kx4-^khZRuN&*>-qBU6mPX1 zqU7-WmtT4B&GF;M*J%xo;}+*>7lCGLPcQpun?r+eOIn}}11SVbDTJcr@bM@HUXq+} zV`HQJyT!kI7+xqTvRC6dECm zb=I^-m?r(xkDyRB3JdQyiXy2G5X#2qq;M^dpRI~ctemZsKnS1VD;KV)96xP*?yrmg zx^$4iB~8Kqnw=fs2(3-eLA6VTE}*?N*51>{(hzbIibSg@6be#^Vg*C3$!4-h>9Jp36AEiLpnX09Go~Sw>v?k>jcJ*~QEeJ6Y;4ih z)n%N2{`pzp@#2dI*T0({?P^4J=g9=1qeR`yxqkZ4+^zEp2Pa0=Y?^fNgu@%gJo)`q zZhd2AKpi?TZu#<;wbn{1*YlnOSOT`>9pZU~@&%9r9B2Eo!F6BbOHhDnZEbb6*27gN z7qu)Bixw@?rP4yYv0%_8C&hWc{pw+0T3mdc|moH#gLC|?zH%Y;E@cGMeoLrGjB5;I( zwEU3IkEpqC4$;J7xtJ#9S!Cdge6zeNRK7q7aa4g^ox<(PiuB8aV&LAplecW*-=_vm z0X?w|eXo=@{Jqd+&imWE(ye&gc-2^A!gZJWTQ0jkAK65fbI%KX zqvhhj760etil9;i+vlj}P+Z>-za**~UhMb-FCy3HPl zms^$HmRZtxx0l-0IJUz}d*%VkIgb=uaN(#Pe z(2i#p*4|a}6`Q-`leU5t_JXq0>IynLO=@GaWynEz8)49I5mI>9yT7lWO#c8vN=(zD zyQ>SWJ-4frlAfL(Iy*W5fn}NGGHF)5`YM*sA}Ea!HFxI_i&-q2X?CMDy8`%n;F=?p zVV?r-I2(JjEpqogp1S|JR$5;}xm(O)V->4JE3LYbMji2_+UqZ~XliN_MSTI5MxA9W zd&iC41z@dt(8D4G`bi=sgY8Xb0i6;oW9;(>VpMF*MxDkMrxqw8rx|Lb`-R`Rmt2VAX-=? z`e+F|LH)~&9Qwy^(m(qHn}N;6Jyv4^lC9KFwWj@W+_*7kJC3b96R)69u$eMt3JZ=n zf~u-2QbR*L@W9_O43EEypv2>S&pKgReiaN^$TY}87U9~szAzX*@`--7u6z!(!tw{H zs2@wJztan@aU9C)#*$CRsHh*yz_v|H*zYK;U^!^d5r+V`*WKpN^xVlIQJ|9{sa;|3*G6Ftq ztueGly@&VVg9k51Of$`HGtF)bKd;Dz^QYy>o{-h?grf@&zLZ(AbQ#NrO#+KqY($9? zC8_}3%v%bQ(b4E@CgS&x$6G>#h-#wASe*IwE2sO<`sO5K@--KW$Q}P%X!*;{xt}aP zv;51iR5;ZwmsT!%;rhWve-;wk^9*Ru?xi$7)8vU|YcPVfq|<3O=Lh-7g1HE^_n#gK z%Gnv3SS%wnyB7yq{wGQDp5LW^_LqzJxxa=%H$ue4yJ#hwK|Ga8bSc$PG#z-EA~l+L zJjSNYoALR43=It-rGe{u1%*Y?*85(<&Lk<*X)IYzAikA?zZ%zH0ouXv1*slC1GI~Y ziy5w=}FsuM|lV)H@Jgrzt&k!mkQfLqor$_`a02f3heF`uv;XAe< z?AyXR^zmB@zgSnygRx5ooRESB!(^N=DHEobodbp=HA}+Rn;JAq0CM|;r_cn1LC6@% zivwCT5tUJd+YIhEgFhPUio)kpBpYp!U(qAFet2i{=5?jLi(0LY5K(VY(Ei&7yqh2I zvg~A0qHYsSMl^r>hL2Q!-Sgye2~z@Vk1hkdr{!ZGi{?V_`CGa z{sM3Vm*f$kl{WwHqkkG-ez;Nf&u=Y9%}&(Cr?>Cd)6+ftFuO%cUn~}9$&w`m0s*$P zZJ|)Gi`5&7s}f!M`yO>hIhbx9E1w|f#3^a64u;Mm(c5Fj9yvCRHd;7fqV|t@};t`YR?e^9$J_b&R7N?YfRIeHIcgIrjmxClC%8*iIGu&6Yt z*-3-0X56@OgIl+@E3J{P>!7tlN=e?yv3m7tC<+79H1O!B9z0w7d)FC%s0Yw$Ie){h!b@?51L*S9^RWZ7$v^@r-GOk^&a|K4# zRtrNGL*u1^FeJh-J^qFkAO+fW(2k2J&UQk2D-%)~glYMePq{t$cz;h{JXN%-Ck6)x zU(=3v(EdFc!#3Pzn%&F%*G>`A`BFioC#FQ=Z@*3dEJD$AznH~FGtI-!wLKBLJP~>^ z;zP91A|koSPtOi~^$2BF|KRK9RsZ;D{>q!%So@Fian^sC+Gr3GS1Z@hc#eml&tl%3 z$!HC^e8I~OQXE1>6CGki?gFrw#Zn;Li&e{)vLgA{rG3%VrGcx@w%y!`1(Aw&#(P$- zdhUhtKz8lys%+VqPSxiIx~QPI%Mf+}>FIh4#-6jNb1kF>BKD4ca$%w#aR6#|VXRvss*>IQgDFgp?FQ16*Old7TDfdh-ITH|q2Gp{ ziik*Im;m%4Kv9so%{05;2>p08IOp4>XC+kZFTcxP|GmZF4KbHosK08nP&>J(?d=aq84)6O4J;ir1 zLa9w-YbQ;bG~c!zU0GQv_T6t^Qi&vv>*DkINT*XcjzdL7C8HV|SoYFOY}>Yt_v#s* zF{4uh+Rml5>1I*3gLZ5*#k4>rbAjXF4lAL8X}%0moAxPrL4SgfUbL{%2^9-k$(dIT_us7LTEH+hrd!EbLBPJ z&P;BLueG+SZ|I2Ha79BK8=dk*m66xu<5~!9OCbtcA@Vuge4gCk5QTUgAq9qTNyil` zR1TsRCmu&wKI~Kqe`N(BzaQ7JRU#SNzl+WDT03llaesbO|GFi4cihHN#*BryP2Yp} zCa3W3M9GxaOtX6lKdZ7r`SWbD^Rgr!yeadO?*pzt@JT*tM2WiZQ}vK{g!i=On&)L~ zkr5)9o3ht^@3Vm~om|hD%hKD_G-n@MYo%prX{%h9ZC$;HE>q zsZ^5ZpL>py=iV?3^7%YUDSSSQb?YoLnGA*@DcHkfTJP|B*I2T|JLc1ybLy0t7N#oT zxIu)nQPKxqfUuWJUJH-ko6nG0_cXC7<8V4R;uu+s@pI9R7vG_f1nd+VfooP{6n{Uu z++ca!b8fq$kU7vgbUKnL52XM6^UsDZ_|=AV`?-L4yAN<_^>HCro|%z}$Nt}%>wnK0 z0LocL8Q^CPvrn4&sVipm^c~u9>nqx{EP>JpX&_7k!&j`enJ};{Nuj%k{I*VSo7M=^ zAhWTJf)K?0fKR)|7aUglxVW-U~6Lq69wTUl&d;Xj+2jO9U1 z38CjKO+EF0Ck2nYaY%K47f@Gnr7W@;V2413B3#nQj*bon2M2YLpIfpfcu`+sJBz`y z{~8D(wClP%hN$kcWk+l491W=Zp52_8d;nA%8PS&u6S6?NHpM(dUb~7(mbK}lFE4Rk zSx#3xi=MF$Lb)DGKzW(Ia{d~G)|e>L1;w;6<BA~kmB?UY9LYag8e4o_M~u}s-E@8uNG@)|XpR!Ha`_I!XCVUt zEiFr+OM1Qb9LQ+T=B5?W?<>|o7D&^;%@+`WVVJ1IK+cV)yUL(51$_X)in7tYy`6J? zGMo+Mm@V?!D%J`7z&syCL8?4~t7XdnqjM5Q`@#(AWrP0BUy2Sz<2&s4ffTqU?5--q zx|wG8tYgm#-~P|r(}M#W`<`8rnEC3eHOlYz7gIp8y)cT<#j)ruEtT?8MQ+;K$uq0A z04OKx{3i-sno8PL@bVLFRe0`%z_B08$?P+KNdLC2g%&eH){E_kMptRT&8&a1`|)K**=HO**Xke4=%j6mpig?a4TL}lqiEpQ z7=}T1{Cwiw>o6LsF>5EGT^lWpVlsUfiN-~f&bc(yRB-Bkb>iOp9%l2ZS8X6YT1^^n zYIE8x*`I&+lJKJc*XQrXoV1Z%`t`cm8&l)4Brg= z&!>{|s*h%MZf!rEmqatSc9Ypr6aL@|+!A(cdG~zBOE#eX`N-296+zS4+&Lh8rm3{n zMdPhjN^6bAP|DTHRl;#x?JCDLgfx4HQqDj;>i|RcJB*S3us}+Ac-ARAQf~M@_Go(L z#YL0On+jdLhj1g%3RL3Vf8$Ml^ZMVX@PzIFp4WdDOnecjo?2jNQ~T=YpV(GcTQlY0 zy(f_nAqKMGDB&f`@v?M!4m4>X!U25K4nw$(7v(5@sA8f`Ej;b9+y_U@tmVXg>si9IpAxV z_{^TEOE%tfctcrrtt9LoH~C~=&6Jva{;5}#5JGOhaKqN@Qb;El5<8y2$>zvz>nhg3 zk|^88P@0PRO3oO6_{FPNZv0AlS(#qF<|U{3@H1bkXee9m-tSCws5NEq_B!p~i{@|N48sCfMLz&ev$u-fDtM!phXnn zo>%eTd%3RTghZ&(7P%!GcrZVQFaA3Ls_`_|mB8~rBVN^lqH*yJHQ&<1YvT#r4S4jZ zca(>8r^g>E6u{h=SiN+`)8V>txlG!3;{3^a&V*_qLY27Ehr-0POr#JL;xPi)ghB!G zW(Z{lk%quf4nlyX3j~D2lu=0nFo?W7kWan$}X1`6YtF3eAmUH zmj4}O;MagCnGD`8T8oL8GIl!S_vxd$hq_wYS8rOsHQm!w;f5PF(V<0`ukO&z`|VwC znRU3T$kQzaZR=uf!5t1-uu=Kf7L(9IU>cIdP?9H8OIG*NyFRs{!wv-f>8+jHmQPpH zHcc_cU6CCsbRf_>N%ACHT3Uu9JzH9ef-e%;t*gg>5xD*z9<5~IoIJ^RkL>(mH1)ey z*iH-kFbUieb~i=90D`7z9^g36Ilx%Fhu;LWK>Ew5m|$Z0hv;7edJsfy85QIG1j-W( zy=qf<4ESf5@Y*!#A$FYr*yB;s$Sw-Coa=~uh0w-?RhcKhyM!hAw-{w*;bj)vA2_i1 z-s0bngObqh1D?eTMozNpuDwM#Tthm2rVLhnDb#qEhoGZBy`@dGC#QBT~Nq|@5_au%YTB@V}FtQ!Dn8xgC|?}zJB4yuRXFiv2g1^ zzcMV#_J%@BI2(A^;b36;iyEOY~p5ZS@aoiexJSRMc6KI z-;Xx#F6>r~7f(YiIF7T@H2IBkn1JU(FpyFxrF5Ev9%oFNJ=2(TjIHwNWzI8qq=@G$ zjjFk`j3ZA75Uzft@Yhvo(u4Cj&sxS!A1DXHyFn98s)ZIgDBLMp;Rr*uE@f#hO0*aO z`)}dktrT9sD?1s$n+)HI;C1oJ%w&K(yViE-l1`_L0gxG~n-+bfnFy+oaS!@*^b zBwzNG6$;5`D+Ao)D>eXRYzFxNWhBerYbaeLv$ zMICP2^=JCOa_Lt>-}_})g@18f?!TXc?MC zEgqwE{arla>BXhKwckN89VENVzB>#B6u@o=^Y>ag%IR7$pRN_vju|X-4QV*47~=sH zh7+QTf6)(%bZ-PmoLpXL*9H;@bEDSItw)+CE=-Bc@6Ip#?rf!$xFvJ_OHDKxJ1{}s zHs%l&047GKLU);1hee~&`xdj<5KDzxP~WI*+tykjwrZDGVuMr|Chl;)96e)QEPyZ2DVmIISygBAQXyNE~dz#ij|Pt7Opz@3}&iG0^9$)7;&gX609vcV*zJ<4f*;Pu6Xrf7anZAT-2KQ_HBq#&9(=j+9 zt5cbn9=z#}^o=h7w4fy{BJ$yXhKI4c1uwkz;os4SH7o$8F-@+@FWa<=WtTUF&e^ZV z8ugWn&6bl4m+OC)k1YC_b=KZv%?aPUG#oj-(ir>WNTPXAqs1Z?iFdkO+|#j`#iE&J zT#JJgs#?3^)oAY59q(Y$DQT~J+8}p;EI6xyn~`z@N*$n`>}cB|Oi?q}ubU|J>;9HL zYEPKw5n@1SHcG9R%rWL?tIXP(TQdLqmy1I!zliC9-@&_2c)zOXTr;&Vnb-MMC@~+n z?_X@j3M?(~O9Kl*DMzZ1pp=)?M+#4?SFVfHW|2UmkQ14o{wDqN)v%+$-E%{G-z&Tyf)}>^Q%jI zSIxA^TeoF@@%+27?d|{tkW{HH0qGm>;FO>5yL@`25Ly44HcN0FjjI%xUiDysmj^>g z>9I9RDL4UFxo9ub4~7t^QkJ;a-SHw{*A2;vQ6|2CPv*A1u6-gJji!Jv10f&_s(i71npy#P={s2Kv_nopMA+#cF7CL zM+U%Kp*FHg|0fFE65cPt`1lD293b+!1@+iW4_uQ-#>z6;45nr1p3Y?VH7z%NyRWZvEeo(& zii4N*TQ)|AtL`#~Il7ouQ3JZDce};@^R3`D;}!ZKq&irUt}94)ZPv~H{-*S`FO`nr zDMd{xS}INTAB;U(@Op@-2%h$P7k9ZgWqx$?0#3VUR&e%(7l&H@5SA6c{$c8}?=*+M zxOcr6_w7rASGSE0G+g_gq2~DOX)7O8ltP3JA@2P3pou94?;rCD?9` zdM8p+pTtQrO0-aAHGC5935Nj3EoC0_qVgQqMHJJX3gHD(7>4Poo=T&I!clrSJ>-s9#3CIbLPo?> zE;TFv*7di{j>R(~k%&6sth2(~wsw9mIKAi4`h5)KV4i%|CY-OCJA2mbOkZE;rL3b5 zZ#?N}^o@fQzR8cu{bj!K88@S8dJ=4kC zzx#Ul>OV))SKI*~e0oah8Ip*Dm2i!?6Mw9@=>t8X{2P?GrSG_prJ$0pgszyUaI9N1 zH!iyj=HdglYUNY640fy@?>6?Nw=xbU0#+H}5$ zIwSo2jT@Yq17rQxKC-%XS+_eSTT6deS_}=O3Hg+syYD_H&+OWNW^6+`cl1^JigkbA z+8J-`c)5DXgkIU@SNNs0oqU;As>TpjFiS$_px_95t82Kcx7nNT{Cn>1*CYZiB_1!X z$Uck$_gy(6%^ihqsdibku~D;!)-5XvU@!MWs(Cf=mCuJSJk~Mtk*|fn-(Ha(cXfm> z{OL=tocDiX?C0VT2KoP0loUp{I9nZ9V&a|J=#-H$}(nX z@#VOixb~tzWPu~Iy}!@ixOy?i7|rj3$?$rV6oaIh{AZnAzbKX2n3CpYpyxrGGQTYaQbV1b1@huCDU%R`I$ufPRfc zEZV?dgPmufYufqIo1!!}HtJ%a$@Y`H3z$Fs=}(XU`q#hyFubmI*`AGJog^(gbKHPUH@R|PqY91-%Y+R&a5}aTz+ZrsxAJk@46rH!81R!&>|v4bbTl| zQ)s5VW)pz_~p8bLRYrL-QMqk7R|f3tPd1dR`KSc z3&NLY1U}c*w(-TlWs{x_JkW)g9T=^=)0(D<<2oKCPDq3h7+My&yj~DuNu|!2H~wS2y{e|_<;Kkcwx(gG_YOq!qB@3&PI{)taK`GhT-Z0yJf5lRFuLg#PpML{?yM*;?tcI7<6HV1|0C5l*QW4pTe^qf%H4-V zS2wenyLOnWzjX6A7hM9#UFTvo){%jpaYv^csRVS?`mW`Wn%9LcHj#~;e*vL8r2;E2 zedKRWbtx`epv|{CfgO?TN`yI2qP(}Kh^aFHT@MepPBtpg>snsqIJmRj@oh+eZwnkg zjXBNSFbpW9Khc7D!^FWG0)GA4EJ%$^+>N)-dEZ$@o>8`cWQ~bwcD=T>J%MGwFqQ!c zL1IoRQno{iLg*k4)7Y&EN;G$H!pZAKNx^VAU)||j!n3_THcIS~FPn8LST=6Fh?2@p zN6L~MX~fCZ*7me9h!WbIz(^w0nxcdN{SBke%9PF`a!#(mZDiwAb52FC2Jz+ z8;Z#!xHY8&J->x0C}R^6U#0Um#4^ucOF4rr`0kDy802vx0S#6P=fNP07jb`Hs1YgAootH;ck8ExszItOlhje;B0P+3}pib5%p&^D7EdQ@fE`bQ^}Qv z)}aYulUI?Z*7Y&d2Q^CDyCoZ?T~ME)pZ-+Q%HMB>!<%HpOAe*$Z*OmPgDy+4E1Hqc zC;0IPZ<_(>X?U$=S)_7N7^;|`sGlA0R&MG=gt)v;T4Y_oaOq)GifP;dK86QZQ~rE6 zRgMN&acg*V4*`pIJYA?D_3?k3{$5l}risLqpHS^dc6a`CPND|Sbx9g7VzOQlnLP}}czdzlUU!mg!(rpfh z@m0h)bh{m|t#sQOA#b+v)`856>YDff{RH7WWxJKS@JtTNPhng6q39LIKK$JEHdbzb zj-|_##ssb0jGo4IKO#}$taoGa#vAJgXpO>h6-FSde$6~8Qjb82{y-?Mr6E($fYWw^ zEQg}5VG>mw^T=VrQk+7Xw2De63sv=kWsO9y7|n@VJg=t@r;6CBhw$||e6XzK3aL0c zP0gnllQ~>vl-ppNh{gO<)MCQtXde1jEFS5>9x3{QlwQ^9dE|y7C&REN6d8TQ?GTTD z74c$JVR+T^L?z)EdK8U=?);#pG}`B1S!bhOijb`!A`02Z(hkGcgM3eiT{N6oOY_`L z2&JdhU4NT+obE%u>IOl}VH;#+$p1-tkUmdfFjj)>nF7&xc?P<9Im#kiVCxOS6*;-t ztTgX;Yg-_*ICIiww4$oDTls!RZSkE^_jWE1JNmr*AX2Ragc7nz^1~!hTHqb#s2TIq z3wg8@kvq0xL@;kVXxXiYdRsDYh^#s<^CvA}~|3@)c*wcPFvcX4t`pjR)A`u=5PZzQ>r zSS#BYLjE&ZVNi!qKi%Q!=HFC~$Z?&bRJurf3EFaqJR#-PCuwpxcns03FbpfowXdwL zS(d#sz@{Vljibibt4g%bKih=4$F&!ZQLVx&mH~&YD@qT-bm+l!7}fNsrf}7ju3%Eb zQ;-IU5rqeFBI}tRUc>QFs(a+IThU^Hkb(Q!#WDe8;`&+T5;C|gqnzH!cBGXOo ziT$xBDsy{6r7+46r=_Dc=--#DD0Cx&tlLYL%6oYr%6cX_-k;~Yy=2I3EKr=XIL>9) zWEGYgpa^cPbdLPmB1qw58LW*B-k#wmd3u3|mqVjFpZ%o>)sjF=h5&<*S+7zf!M@k#I!>>=W}nzrDkt0{LfeWwTBtxa_22{e*0B& zm6u)Pe(xuxs|{VgU)&C(MxMK1)5es#R6~rX4Q2c7 zH>J}xLRP#*G}v45IrPOh`MJ?WmC=#PNNSzqxzm4A0v$_uVt;z<1Bu)f3Ba#}p`TG~bB{o!~BLfy%GVi^_MTt+B>S8aUsD_)5c_=n! ztWh<$T}fFQ0z7MaB3&=3kU&UQSC?~qvp_wLk@d;a7bLtHIgJi%+SNNMrrDam1YLOT zr```sR_BIJ6f^VlpZ_`Vd~I0S|H=A>NP92+_7=H6{b{8yZO0J-SP+#ha@L%*Klv#I z`To7bQR1#jw+)gay>FRxBL&XPTEvSGKODzDDETdayMIICgFd?EWyL{_*VUzX|3N&r z^m4^H?Nf*h^aQ9X%@%>_r zL+VqAxvp`l+Ec?~r>QP;Rf-;MA`io#vcaF_$L9b?WE;r^C7%1Bqq>R;`@OwCF3}cL zq=|Qf*Zjkwn2S(HNxjkwA3StVS`t|uO+&Sct=K0L=x1@UcA09?N4>A)PFFPB43e_Q zAy(^ZkuZF1mI22IP)T@|X(DYf1Bxa<=_ZwbM={+P>hZoAW9)B2+jUQ1id%W3ZB4KK zTm6mod3VYH%c_-E{Hc>}#t!?(rcFt#XDlM-LP%O-j@Loq#r`{P!gdG!_?!1)!K3*d zhbN5daxNkG+#-?@NBywC3G7n88ZO zuok)auFY0IWQ3)6Bj5Me!HR{mCiq-$9BgA*p7T>VtIW3NNdSeXhWHyt2mAkPx8Q3Y zOmo*@@Mo}GiUr#uAEXN0mL<)Am z#Ns;{uu{I_ZM2D(r@)xuIuWzsvg*e5kJWTwSq)+L3XnlWXqIllgOhNM4OYhN<4VQ6 zUY^`mp5LSq*2p`Co6HYWjXf%q;kx!*{aN=${$Q25&kVTC(EO@=lMIu;Dv_8ti|8Tv zmWYB$S?ryp_{Opfw)3r-dW8*j5~6izDsF`cUn* zWA=_&Woq@vSXw`MB=Ev%08hw0lw*QL4FM6)JWtSR8g%XV5ul{#^D+OQ+AMQjG|g`5 zo-+7d^6A-loR|+JeSs5vX==1r7xwJ<(DwdJiyPh;P?KJj8!B_e`qarMZpBVt68Wa~ zVj}@sN5b<>O?S^!4+!{rfEU<&hH#7QIS8p+TAvg9;nzh{qFQ+Mm24be<89>?1|c^= z{n6L9KSLP?{6QG9h1Axo@0WVVY~AYU$&{jiAe)b{3~vY5c4>38Pf$Py=I&4pP*=Wi zI6C_(BXWJ9+wm&FU#Ot~L7UWmdh_S`CK2_UPPI8452(Zr&U5j&6IE@xe-8*ThAl1H zujk|N9WUt_e)nU2NOq?FRy70B1W{A;Y8`3Bf?JsVcPoir3ly*398_{R7vOpvyOa`m@9}M^&2$=<1-NNS z^*ea{J$y*rR2=OWH9$9Xwtif&l#Zeco@PeT8!s&_B|S|W`HxLNn>+~${?HKY98q-M z1=D6_LC|x`7Re_@(eQPvQdh03y?^t|N{_>X;#1)JV}MP&#CpRKV=9~_S?b6k0ld&iU61eyXhak*RO~JaIwZT z^Is}2>+Lfbn+sFo@ssUdShp^L36L=RQ^+Sj<-%MFN z89%d_xtvvIWIi@Mq9#i{-()?hecPHf+cKG(B6&lJSG{7rZ_;H9gzy z`{(-VQ=Q--*0M&t?W~I@1Ind2@>63NjA)4stv;YPxTj>-@0g1JSURouLVRkDK->PdMkV`&?QW2UCa;V7M|HgOww-c;bEbB-*OqM{hgxJwkJAjiyZskgOTmyw)!GUcNF|a4<~o#T{~~G>>W{qE#(rt+)@X3?vl{lYIZzJ zAVb|B>K|Tnp`iQj^n#a^iXOf|$MM}vPmwqezntC)neJ?p?-%+0;<#KB5cb?V^qnFM z+$cJ98A-P>Src|GHRN}_+RN;CjTVK<=|7*0u~YwbISI ztmB8IllVDb#DsQYJ%Oh@UmTRh=rQNQw;2Pj*(Zrzza4c2dL%;HV+DYS`A*W|JkdC~ zqrlY9jk=4tWgJ4+pe+`o&MM$E>0CyNU4FH&kP(3s=OM|EIzOwdR1|`YFW^|zFe;z7 zElwAf=3~2gFiswLzhr#-@+A1d9#Z-Gw z;w|{HXC_bKXhVQ8R@D-E6U3f5hWN&DF&N_Mwa*$U>SeH@CIMo@lee-M&5_;YKR=51 z6KvI;Yij-VC;8jS&&*;Jq}4@xs=Nsmt^%yUOxdN<02f)w0jnP-l2PARt6;fn^rb(t z_3NAQMTt^eVD_;cEG#Zo8+CYHKK;l1EB6u?3Pgs&AVa0gi@ z=JvBLH(G5JMWrnXQ0IhJoi1e)IYm5ll-E7^xo7d9J$?zB`bA+geb(Wn^uI|r&|Vvu zX|1C=8asCQf1e8S?~L56fKB@Csf`Be_1ovx?I+iF#+P-~E?J&?HZ1Bp@^GH=F9xWE zM~(KS~R2CJyw_>%-v8}xr|3cP5)q^f( zKa!+{6vo_Fx4POype%IBRDbWlsgSo_jXk_sUyN>%Kf&yNE;HWlsKFf>asJxjMcFNU zaz(?kV@Ld#v4c)-^?r>{za+r|jMERpk|!}W8!A?vA7PmdTIX^;Qgeu#nXF24p>E_n zK3*lRp}xlqjAKsZGaWyRjmEx%#ohzSPh(yV1YDc#>~~V`i;JhK#hiC=k!J47eE43a z&yV9ACsDQi8lq{8u@&#Sgt`%hIlWwqIu8}*@^@rhE1I1JO6;82=%I{RvUyGhwbZqC zEk~&0>-<*6#`&!H-LV$eY zQg&8Ye#pO*6zwOHz)??&9h={&^At;5v7>_jaeCdl=L5M%Bgdig%ypIj?7bwyAveL~ z1Y5{C#sp_2Yl?rfk*v^hb8DUmi{fccn83rkpndbPe`c|V$ues5wfk4Dk|`#Ozb|Gd z@vlvF0;TY!6Z8qj>g`bqUvgozD$ZmY<$M#6Lbga;%qqt2P`qWWK+jod+4Qzu_Xs0&hLyqw7K{ld z1|=?e*7n1f&IZ4M5hU>jN3fDm#a&Jh`vg4F(a0qebY2eH(kYViO2ISA*Pd^qx}}!<}>gN6rHN9PAehooVz6q((2XZ6Oh-f8hF{gGk=1{ z?r}+kp2!g|WB1?i64MkWvFA7sx*Qj_L*Dj5(e^g4g#Kna3RLp}WbfzftgN5F-L^=k z9y16SX=HKGvtzO``p!LjL@ehC4>Dpta+e>Ct=6{rX*c9mZ`-ImxLb})zfbaOX`x7J z;?_GWBEYwS1(^0^@r`p(zO_rxZ4HctQw)u@;WJNzC zW}VPU(K8BC>uNjozMS9S1BQliNp45~>upFz@g6$oHtzZ(5;h*TwZyMYkw@rRu@gEs zb-*ifmWLbcNq-5{J(+nfp%fifzJrWDIncr6FJj@_d39wX4hx0f z53j&aLbt=%%7V^B`S|rZ8>$aojYQNi7LA)d6M6b?zX(f6C?Mh@QWtlZ)fse-)t6YR zMg?QkHBKifD10T>H+9(#Cq_;FkvF`IB)^fDl!p)IULH#$!{_iR@Z#A|Tj2cy$d#q_ zt$~rPTZOL+pG7LkkBYwNNaxu96do+BE9{li^}g~D=3`?^_$lQnyel1LRTy+(=QW2l z$G|WSXKIyg+*obMC>3jy@314$phu`Br#X0*QAnE>Ev0=l%f(=m=9pzAkw4rT;?J0D zz%4MMex5{ZwqLA9zjMhehFF~Py( z_iyTAO1%r~X|j1ta$g)@kJQ(@-u3sp>vzvjwF9uY6rKSM(UlmW-1&AZsD2q^<9&tG4&~q+^m~dyriIxNQ*nH5O%w} zO8qt`$LU}!Iod=tikY#ICq>?Um&xB5A{T%ZinQoyYAV|rw0yTUX5&rC67>GVXa1U{ z*iq;9FNe>UJB_t__nxV!t}VnQKSz|Vdn~?MR3Fa9Zx=Ily7>#$j=8u(Cie_~2Y5bt zX${16K3sn<4+|4)U<(>Ow6$SumuRSSHIbT%NDgS#E;v8g>c1@0<`jGlRpi$?LQ>dl zKFRQMNr)tS%$A{6Z>Ub)*?PRr6m&P0K_gqwFg_M}p~}OJWd|K=%q3oI5 zp;tm^k}yU1=K_0NZx4RAvtlv3^WaQ&DN*p!@!lKYdrmMP8+Yn4D8HdYjw7*3WH{+> zW%YrxTsbY7<+Ksu?IXqjL@t<*#<8ZYPe9Dj@E26h#>PgDbyg*`I(_N~zg7c>`qQ>d zv4UFM+S%h9nkDxoTC8ZUpcd;DMWAah6HUv4Z2U$jU5U`J)d0uDmTg7U3i0KJ%?Ba_ z12HjieWFb9g%bJ|1kRE3WM=~W@wh1as{E>V#6yse()x7Hjfqt5pkv!hrh%wxBKcV?|LiNb_Or+WQt)sXwrMlN`!N|I*|!m9MUDpBgI%UnPdCW z0KV+*hQnf(?(b$ljIwca-Sv%^LqdTBIWhbaOVx||LPU+Owj;>SbJOW#7s(bHoh4E2 z=Rfk{4}&6C0Ck(usxU>&TBsv_F-WV1zPX}N$~KtOKVZ+AbB&r6Vl zymh+c(>==JiLs83aU8oBjnzyG0z6blo)t79Wnt$|yI+&kfQ^QIt6AG1IWQEco>R=3 z>&mU-r`rK1ecs*!kkz1o^g#vwLH5#*-Q?``e)D~*uC5MWty}|@;Can;iaN-6XTP@! zw(iii^TSyP3lmE8^hR}4GdFx(2CK`?@w(ypcUVVKfGGY6EBZ)XiErO;$k_qTN3Jrj z*)=DS)eAaoIty*F(3Bs*(C2WnMvD#6UD5XK=8)-Fz{sdqkHUSC&^SYP zLth}UwzGNSMdm4unYF3rOt1crgLj*cDO0u!hr=MmaUx)+I~1M2q`F$k)6FdkXs8?! za+LkhtkgO-pXz$C3K`$k&$U0oAP^T`+Wfm|bbZ~b0&bz#dTn;gdsC{98vVtr9FBwI zqRY^S=R1)l{d^FMijKZRgw-H*YD%qxrf1DLI_H$if@~2x3%|Ph=!#9b11I^J>Qotx zo0NYb>$VIfmQkrz@~vmn(!r}W+JWjz62_tX1#(qZsk6<7j0oOh0f!6!bvmiX1$3iu z9z+gEXtGOn5#d8;ok>vpMCD{D2>Llu4VLs10p-TjVIQ4?x*UMUO*5w~>31eESdx^B z{zkYJG8-dS5Omr?P#TOOCJ;yE+M09PR-LAn6{IB>?Z$telA4++hR9qppQ$kDZn&f( z_bRfrk=;U%KF!Dv`ITQ5z$1Q=Sj!}W=jGGCR(og)Fi-ihqHEnx7e|6cMWKuyz@UD8 z><-b94bc250}w}9v~AZ_Q*M;T!TM$b9#dus2a=pH`3PmOTG*RB2oLrJ6+zA?Pd#M-?%$F^Uz7~W62URHpDGj>-E62dN;$(B>}CW61o@SfC_w;ef&<{YK0Q4FzX85Ne}AFd z+gnsrRE!@3P+!Hx(Ha{Y|9cicgrprNOM|VD`2~&=7Sv=9zg!bcDcgh4A`jK)b z+vJ+U%NKn)Yb`rJq*xjp#GN)4v%xs@d5(etS9`yCOQrXRltFseWaFpJDd7)-S6uH4 z<$m*jm7{Z$9191e)hovseoE_;-|DAn0`vzlL`oXvTm_bN>|E}m28`Yd+rVYx;~IYU z0Mo03_5gnYC))hU&6{6&sCW@KJEa4ItiFNtal%hl3#+RPxq(){6ii}t>}1AHbU(wy z7Kg!#hZYE(H_@3#9`ev*i23Z)J$wlM_NXcjf|6t-NZB2XO}5PSF0}*T*s=d&3vI2_ zTY`zN4lmE;DEHH!-KWf+pW^uCaQgEAuHFo$+zk2!O%aMebA5^%{ELHCZq>CiOhqc6 zWG)|czLH!fz8GwA3V-@oG{=-+^6^|*vI0%(&8$2Uyf{hiJ2Z*&9wu*G-+sDr++x_zb-Gli0fOHt}ffx=(ARA_GUh6$?-c({E&}g!k&quCV{tjZ$ z8h}=%c+MyZk!C25EDiJX{ee0rHIC*>Be!~fJtgv9S*~726O+B!1Qp;La^E;@-e``D zOeAWJPmNQ`>74pQ6yqY?DfNeoVTu+n4x1u2Cn6;<`aA!#I<4&I)3T+pPWuzbo2W{| zt-VK9+~XPcLeGifq__v0erku(Py-;Iqs59%Q>a+1pArUv0PucgN(D49u_Y!~&SSrt zGN*@cux+t>*ZZ6Cu9B)s}M@UQNp*nhF0rlJ>nwvflebVw2}TZ0D@(#!{&@g zA&BTtz(U(=45sF!Lm1MOp;XbM3WuVUF~3TPfBf@=?3&M-xK{g3{O#77HT$84Xgi%} z|9o7egc^Nv3=m`m&{`GhO7#pJp6woq&Ej+(8)`u`0o<*Y%kS_ojEI~3aEzS|U&y{0 z`7;42DJcN+-(Bvw=tcRN$CeAubpWOSx1BP4A+L<#V!>|wirm>H0B6h>+?p;{AS#?k zn>~Sn9;sVzfp)r7Ro2v$21G(k^vGlI$pP?B&3i)N{^&QysnALI`Uw#>d9ZuEN+! z-00M71hhE?^g(!|9Bv<LWy4qAWxu4;@$c3G zHSKzB7ZK%WT0rX+=RB;ZwjCt>IP_~~_toj@3K-k#8zeJWy4d@u=f0p&QK6KF- zj=&X{cnW$(Lh%1Q$M+PG)ZmV`gMf!;w2ylt8=tMTo527fk{MC?H1WF)8S?^8=gRJD z!1qo0u7;g7F!ufXu#wV27;>Y_K;=|QEOP&ikhwZq*QK%UFD2NY`IAYymt|))`1p-E zn9pEzt726sneSBve=cR3)``2gnt)Mj_U5njxa9!tLv8faZvPOFH4RkObjFzLrKG2t zJu+!k8;nH65?|;F10p4)h>(Ux`)%#6CtP!L^PglwL|vOx0GXxra*!A)vhOE357`_i zQn=XK?P2@FkoY?V0iv3=_J3RVelt)+KAlApSr*_F15OIQ;71gIoX7TPkgGx$W)Gsa zA3-5t;D5vWJM5K!aBYlY}_O2L@|$AC$&9H-c$ z^i2+%8P-1Z6zQ4aNZzd|MLAoT{weYa<=nO{-Ne~->SUr4isj{uT5%=Tk41=4$ZdZ` zyIQ`1`px52amn+1OUNx)iGIIN&z4yE2i?B+^6$m~q^UkZrhd77KZmimokxzxE6uoU zv@`>HfIX)LrhG($U@0z*UpR#4+u9bA8s=P$c-0&v~8%Kg)&>Q3hmTuX?F7 z71#+9itFG|#Sl=tWY~b2=0{k*+qa+!`VD(p&SSMgO=UF*Xe~`+!3dK@ zb%ja6%TVPS$e^Z7PHU`ZNFY?{l!^Wjw1YU3jmfjxsI41aTzYKs;Yg# zJ66bI&Tg9CT#EljK(~*F^h0r66)Cq@v#T`^iY#>krM>-+>c z&GVZ-mg_Q*5qLbi21MmdX&;t@>$ahgO6E6%G)3WZ7tMB4E5T5+FSflnhHfTR=4iIM z>T7LSKWxO@{(j6JG)P5FA-!%cIo0fjr0dxhCuEfNe-TvgGya*GTTYp{v){ujcl<5R zQJ+?3EOG#{}_2U=#;FnDD=a)CGOZG@~1#+U*!)N!)80EzdpUxJc`WEZI zGbE%V3XL2R(Rf@&t_?U5tqgaw6@{d0%r*%gmn8t%8E|VMU^4E^0d9%kzdEGqvB&|9LKv z88%rvJPZfnDfqru-ywS7dqi(ZdTS7C3uLTPB$AsN-ZMVDm}@u^h*^@Fy4t9Y7Vyjj z_jkLK;;XHtO{$qppM#Yo7k3 zZ;i{@W9YfQA5v?{Nm9s-E|fR5(gs3A>4hdwn-a5)6-8AahQ+`@*F$N*&`5(L6sd^t z`XWxZXGWL1c$|Y*?nUW%=>7$#Lc1*2r@?>8FmN$bA!2^($&Vosmzcb#46H>-0V1&{ zn{nHO>gs3wnmV^~7lf$Du+N2u2!0uX;W~Y9U2Hk;5nvo5BV4mJ1GTAqN&KXPivyfB zew{&6Uogc?Q?m(5qiqFDkWo>4_bJEqP=+phJJ75#ki#(|y8r$%r9hRT{QDw&hXy}< zP{#|0P&s<_JJKWAfICtRdC9pvL+vX|9#yK6Z)a?Xn0{8rILeZ9rl7Z4BU46WYi#fd zW7qY%Ux`5b#f&X+a{h`mNo(7dg~GCfDPd0}HV~;8aN@y@6;rW=MbEMz#<~a^hGa*;ePlf@Dsi=*vGtTkkRJUc zDQ<0u8a3UAz%X+w*AX%6k!Q|U+L?4!M`5M-=@&`Up}Cu!RFNu-O5o$rPI^!}6xm}J zkIg!wNB@jhzjGHV8tHyi(NM+}+JU+||2vOGdulmA{&}UA&bML608*$>op~5q!iq#G$54UU#ua z1N7&E(b(+HrjkI?%uemOJpO$SWsQ#d;1W7aQVglUeKT$= zK^(oHrY0T|`2H+I&v)K1$Ga5-b98*X4frLQAB<-r(wA4(NVl^5)fwMClp8q|zUKo* z^IM<6T^A>nj07AOsE0YO===NoKw~Ws5IK^6CP7bjca@PhX-C&$cTC!^m(Z4O{xvL8 z*OuJV7_Qyssb0vlbDlNw7Clu$_6z# z4Gj&a>8}Wh3N+CJ5p1ZTBCnUqKn|ZIS2Ao~A2v4H@_Gjv*>`DZZcd)C08S_aVP$(o zG%-ZezXX7tfwtD4t>&&*=If8S%D%qD0bO~wr%Tt*oA0@g*N4}$@~l9ceWaM<`}Z_a z@u-(l!O{do=rr@cjrOPA)6+2m!2+v5${QI}6L6I@Wy#%YJU%({`y_fB$@tg%LY=W> z*4)n&n5SverDZRAWRjt;L<1P!=U);|zL`O2l8#}W38~mfOe;mbKlmz#s!=qEPuE^% z4mj6D4%9>z-nED7Y`m2$nq++6_)4&i_=f8mGs%Skmq$$J8@g`r4N)4I&yJBtF?nOd z2uMYbAP@xDRNT~?n>(i=Qcob>WUvJYzL^BM+b&&>8NVfEoe)_}WQAjx;H+SlS_287 za93V5HqF(tS^VYr+?0x@p(K#V{#P_o&h@*J^%Eus(%8?~vSP;+7R|wwVgzZy>P}yS ztTT|O6b|^*xtJb@MBcL~-uH64g>U!&Y39}B8RuCSNdBxf5bju}4p~Zo*RwU)H?;}} zTvk{Hmj$yy#=untX`(?WGUd*N81WcsOGr_8g=jR#A!l4Z!vl&rj7Jv7^^2FP_lIvO zA*C_awSZF*c7wdI?Q}Y8>FPvBc$gKHm-rtB3u^h+OazA5tLrY(PMY#g?u6aTy36|b zOm5$6>~)ugB4ROYVO%|@clCRCvrzVn9oOHLm1YAmxbq7OfN96bzAKQDXJ)nOJ^4J> zk|GFX?g0Ag!nU@of&$9ARwg-X0M~T+{JMATZDV6|bb2bT2Tz;h^&!(PEzTYUI5LHa zQ3B<#?=Gz*r#ydX)5q9d7Zpf`3YZMwKNuPQ4e?`%|J9t?4q0nc@26EdGTur1<+oBG z+pcZSzgL<*SScH-4?g2#XHJ@u{3N2G=xY-Fgn7n)_9Yfy6j(WiZX)#7X6KsS0HIZ) zeRa$+=+gt-Ir)>?5jku(4$YmyT?9*Sh z+s1aE_*tNbr1{ed|NSH7u-bt&IPq(=v)_~xB$T$L+q=#vjpi(NO6|SM?###L6&gvK zTXNJ_Y-7#dJg^IBp`B}AVMwWYU>131?ta!(G=ptNXji(hVNDNKv(c%PL~3AkN)5$V zw54c}Dwtkf0|%|nQJ@xo`-GOP7L6JvVKpVdQhY;$w{-32>rEuL2p_B^kOm^^X^*^k zSn|H4yP&)O6g-Nct(&Z1ucupwdp@P`Y$dGyP?7MVYct;5o0A<#8Q@`HLn$j57%<{O zFCG(0qpdR$1vhG@4u{yN1I8l15#b<*Z!=jS{{B;K+7;8f+!VUYYgN^8?~XpI39OF> zH63Ac0BcSEx!UCt;RA0|>}lI7(xp>SQEAd+~S_TNqx1D2m~YxHVJX)Y;`ThyVD-&&tg4h8fpd zg-}x>P@%szWI05rw~v*+)K`NjcteR&okh&6pht{t{8B@%AXU1Ak&rA!pzzO`P0GU( zvlV@qiWu8>(B0LaWPfO#PV2eSbhUCfkF(_&g-k&sZS7PbCISOF^9vgFOFzpMF0ylS z&ZUdhzoWpZMSoXiLm1hwD^|De-QWL7D3k@rtgsMa2}A+}HB&W#Eg%(7CeEErm8tOM zTdxGr1CwXTHoH4pk)dC)1RF#|L;xpI0kEe4o3h!F&#eYzB`Msfp~1ny1;FFBdkkpP zP!FY6p_!fDk&WJP-QRrlE49^s@0jVF3Ep-9I*-wYg_ot+goHna+&<;@A2zGVQAtK< zuA~dXhhC%|WcneO7#i$T=gQJ@w3Oc)F1|6wl)|9VY2(|^eAouG{kH6XkWga!QMdUH zil-4NS6~hjK9UO7i|=ujx_7XXz=ti$?O(%@fFxx`ZmiXzzS5C=PF6^SgQuA?`NJxz z@5x$l;0>O%yM^s!a$vx~fuX z5{bw1xBrfsk?+g4HUD_;*IY5hoUSK$>ir&Fic?BXsF7J?%@NsBD(9>2-|p}_>O`lX zvRL9#3qR5WMCJ1%-3sVNkM$=%-#>~se+aQkm3@fpqf7J^NU9BD`w13p!zm@WzwO$I zLVM=~B0>C(^WOq}59dHlm=c$pEV3gp=K40OJY_knME~xmA=9kcz7B97aI8W|T_2~SQ=c1R}#a7cyMhRzp7EfMp3 zRWIC$aMPs`n)M(m!P?z?-5F-yK)FRN2W$2F7J!ZuCR`=L&TBgR2^8V>btBe~Trp(KWJMpuu85(tZIagQhND|iz$l!yL)wZly(LHVTAH#rLlUZD zRWZ~X)=QxCUvCUz^Iv;ccQ0)%bmLrcrKN}5mfAi$izWT`pIbbjIekUr=H>?8!xHCw9j9y(#t^&kHIC|ZFnkj{%+sr|Y|_Qa0wbA7!1(Ga(PZnOq^YZGvfx;z zImav~b(|TEB{uMV%Or)(SV?4+rbv$byY_x9udF zRXXS^t((SPk+Z}NU&AKMJ#-qJgRWfe6=fMIZ@Xj?Yfcs4suj9kO@_4kgd%%2g+YRx%35xlxbi^pN?#V~jz%qs&-jTrXq>B) z4Y-5u7!WwP$lrV8OLUi=@|Vrh`!7mCn4WYyv448D{w`vK(=$ks()3R+zdV@iJN%7; z!{)!X%ierV!O$oNvu@!-Uh!-KbVXh^pDd#g%^x?jb|?9C9yXXYE119nWtk!T>FsU~ z`Q;dqN$0L9Uh;aghPnpQnxQZ*8Ze$=N#J%iWzt)I&RP4lPY&3NIy8J8N*smD|D44Z zGfG3g7OknQU^IA9YY1f&$Ge&8oNzigQ~i$iL=}`6+6p3W@(ff)t-*rJxkJi&zdOxP%-# . +@prefix doap: . +@prefix ingen: . +@prefix lv2: . +@prefix midi: . +@prefix mod: . +@prefix pedal: . +@prefix rdfs: . + +_:b1 + ingen:tail ; + ingen:head . + +_:b2 + ingen:tail ; + ingen:head . + +_:b3 + ingen:tail ; + ingen:head . + + + ingen:canvasX 1310.8 ; + ingen:canvasY 550.9 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 3 ; + lv2:minorVersion 0 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + a atom:AtomPort , + lv2:InputPort . + + + ingen:value 100.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 50.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 7.300000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 1.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 23.285000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 50.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + +<:bpb> + ingen:value 4.000000 ; + lv2:index 0 ; + a lv2:ControlPort , + lv2:InputPort . + +<:bpm> + ingen:value 120.000000 ; + lv2:index 1 ; + a lv2:ControlPort , + lv2:InputPort . + +<:rolling> + ingen:value 0 ; + lv2:index 2 ; + a lv2:ControlPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + lv2:index 3 ; + lv2:name "Control In" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_in" ; + 4096 ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + lv2:index 4 ; + lv2:name "Control Out" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_out" ; + 4096 ; + a atom:AtomPort , + lv2:OutputPort . + + + lv2:index 5 ; + lv2:name "Playback 1" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "playback_1" ; + a lv2:AudioPort , + lv2:OutputPort . + + + lv2:index 6 ; + lv2:name "Playback 2" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "playback_2" ; + a lv2:AudioPort , + lv2:OutputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + lv2:index 7 ; + lv2:name "pisound MIDI PS 19FP3ND" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "midi_capture_1" ; + 4096 ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + lv2:index 8 ; + lv2:name "pisound MIDI PS 19FP3ND" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "midi_playback_1" ; + 4096 ; + a atom:AtomPort , + lv2:OutputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + lv2:index 9 ; + lv2:name "Serial MIDI In" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "serial_midi_in" ; + 4096 ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + lv2:index 10 ; + lv2:name "Serial MIDI In" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "serial_midi_out" ; + 4096 ; + a atom:AtomPort , + lv2:OutputPort . + +<> + doap:name "EPiano-simple-ttymdidi" ; + pedal:width 0 ; + pedal:height 0 ; + pedal:addressings ; + pedal:screenshot ; + pedal:thumbnail ; + ingen:polyphony 1 ; + ingen:arc _:b1 , + _:b2 , + _:b3 ; + ingen:block ; + lv2:port <:bpb> , + <:bpm> , + <:rolling> , + , + , + , + , + , + , + , + ; + lv2:extensionData ; + a lv2:Plugin , + ingen:Graph , + pedal:Pedalboard . diff --git a/test/util/EPiano_simple_tt.pedalboard/addressings.json b/test/util/EPiano_simple_tt.pedalboard/addressings.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/test/util/EPiano_simple_tt.pedalboard/addressings.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/util/EPiano_simple_tt.pedalboard/manifest.ttl b/test/util/EPiano_simple_tt.pedalboard/manifest.ttl new file mode 100644 index 0000000..f37ce31 --- /dev/null +++ b/test/util/EPiano_simple_tt.pedalboard/manifest.ttl @@ -0,0 +1,11 @@ +@prefix ingen: . +@prefix lv2: . +@prefix pedal: . +@prefix rdfs: . + + + lv2:prototype ingen:GraphPrototype ; + a lv2:Plugin , + ingen:Graph , + pedal:Pedalboard ; + rdfs:seeAlso . diff --git a/test/util/EPiano_simple_tt.pedalboard/screenshot.png b/test/util/EPiano_simple_tt.pedalboard/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..75146a3402b32dd0f38235004ebf4103db06d3d6 GIT binary patch literal 48859 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 literal 0 HcmV?d00001 diff --git a/test/util/EPiano_simple_tt.pedalboard/thumbnail.png b/test/util/EPiano_simple_tt.pedalboard/thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..7b1526e25a6268e784aaf0929dfb9855a0295b1d GIT binary patch literal 12510 zcmb_jRYM$2u-#o2x5eFEgKG#b!3n|L-Ccq&7MuXV9fG^Nhu|Sd(8b+?`{ld$FWi@z ze(9R-Q`OaVy3a(ZD$Amy5TgJ90Q8S?Ql9_-py6BF5((k$8R~KG2mo*tf0Ppc?45Oz z?d456*Y?_Tmj1WgkZlalOQE^04*}H2N6QJ3N2+zjc61$uicuzr1p!9sDm;EENub_~ zqvQ)xEn4@vtFLej8E-k-t#(uzww!%)3kV#qZcK{(%F(*-pJSDq;<=lZo=x`U`qXa? zBu9%KB}JY1|M7C&qzTL0`hxMFK|z!vTLs#r?r|XTJ~R!K0|1Jp^h9%;hPWw9(SpIi zu=Uqduc3?*k30WvZzqiMfVGBHIoc!~+<*NFK=4mE%yP9=ruvj0+u%)r)Rg##JMhye z^4nx1>oKmupH9BAF#(_O#84%X>bFYqkHQ^(_bv~;c5Cq zaZ2Zb*zAtu#PAe!1OSAr>zNssMU&MC`nGl%14P-`GRNw)$R#zF}SqZq&qCx`ALiBGGi#4KFtNX_)H31)XyW z*A?-59sVgxiznjV-D1e`E+G0n!jdSbtl4?a1waGb_Km35tRvNQ{7m%2|I9f+`^DFSv8Rl{u)>3_&t#0C(_ZKTN28Zm=HnAOViA}suJ zPo{9}`Px@hubix>qfL<h~prsywK`lPRRMkT%EO@8@% z#&6+&UqFRf{vC1kOS9J!1*03YExgsRw2*?i43^>g&m+S?PA)&Hpxwzn%FZAHT+yfV zfxzjzf)N9Hw}RKVHUxg*3Pef$=07-4{vK{~=$^JGpM0=j$I8hg(}!t0 zv}R?5BGSUjD$ggd)a+|UeD?I)GS_vuXGPPd*Mg}E;#6X0FK8KFHNit4=$pf z3usg<$DQ%GGL$U$z(xL<$>JQz=y&$H`jd%s>R14c);J4JBve;>;IiT3E)XKcVyrVb zt5(JeosyzhK=pmO7v$~nx7zvAv1L2WP0w%M>k!yB*@msM^2h&f!^XP{?JO8rJJ?pK z*n3+X;r*6x-r<)^Xz+XWzxxw0=_2qa(?dRstR#-N$$uT^lKNFQX~_`ET)Y%rAySP0 z^8@A;j3y92P`e3r;#)99{2AuN>G0BoUYfyXT#W-imVdkSaeR6?C{h4?z`=_iB?Sqy zWF)#){XzC38v=+4B^O8Pzmk`Zu9I^8Bx&f4N8z6xxOclq(Y{p8EE-pl*eAYrame*t z)#D^*zlf|o?*RWa9v}VTKwg0K@By79(O@}Jb0CV?ijcE!y4z0WAO|$0$l*Z{zvKX8 z1m*>ON2etCo`fu;OlcX4Oj6yZgQ%WC=}pqx9J(k&TaZb0hXH|3tA8u?(ZEeZ{icC> zw;d=RwJk-LatsTdI`6YW>*LvLigS96SB<4OU@bW-ZvWd58vlwahO}Srm^_2Fn{Rd2 zF)ebt((sylxhuN1M7|J#-xhkp$@aV3ZngtJ9Bl5k>kuuwz?zevNaJUecT zpARzXuT$E-KKS27`IJ3(otJ;q3gIb=0|>o7UDiCqLNQ;GeK#UR@A`P_f(yI5IH`xt zlZjsTc9H{CUtUTdr&!sFHGF(X=g5QQkvJ@oi|!P&8_l-2gZI~+NVzVj!fi8=G{^u$ z^u5;H0)Z4WcZlAX2eGR%KIOQ*m`wfHqiHHrNYKplWuP<>QA?(|A$f_hanIt*p3lbK zI$~wxsvU<`;%Qjn2+BuDh**mImZ*Hn(*5N-N7y7PalykmD@l{Dh3YW?U=^LnMCP>4DYVtRFeSEz~dLrE%Emf6wJ^pOvg zUKnQHz>@l7ca(E3_*I0|(=k3`T3hCOfGX!?ZyP~wMCYc$hI=4<^kI0f?*8t3d)*d* zUMf`R_R3cSp#Km?mt-cZ($_^2NPh6k*y{lI)faIot@`%|f8(~B7kXGxtTH7qSpM@T z0I>ca-gMP##?aMdE;FadT>J@T0}#?X!N2Z*8i_^2x9+o-U9}GlCr@bGz3|2bFtSu& z2M6Uoy_h}lh6q)e#UuXMH-r)HO$d;|7i&p)j0f3{!CUiUFOhaW#Cs*`=3V*{fq+Sx zwNk(Rd{Iubn-PaC7Einw7y|+#b=P&Pznq_!57v_f(Y4|+ICq7a+kE_1nDrZ+Lh&^a z;zBQqoLZDd}}Hzj*Z7s^ER-tW=Q0q-Vx zI&=n-yM=(y5e9HtyF;pY!oB#^MMUUIz#D{g^IeN_+v6Z~qly{w#7{fNt*~QPB)LimE2yH??m8+T70;Z^`=fGNM`z6TSDCdzuNXS(E z^y3NQx{;_kFj)IXeZ&azDb%A_nwxK^lC4b|hudmtXyiYJ(A-A!njnyV1N*`n!$8Yc zF&5U2$NUZ&fg#;j4)5|G5p-Elr}0i=BEj{DRZd6@J{A5GiQyN|(57_26e>zwmET+O zWplvP>h+gAeZPLT=2OU{|GpDu1ePO62>!P9>7)poJ?Z2x<{^D6R?qSJx{eT+%m(-8 zA-?_~zVOgJx9@y#zJG#d%oEgb@HVoA8V#_dj&5w1Nfwqx9i$1#09S@tx;Fnzh&=cJ zLX8UVx~`&U3T0m}HzFuLK>ezHy3lrZ{!B2uKj=p$6xgP3T_Fhh>q(t28kI&7*yh&Z zE-ClGfrxUNOD{wgXGAQgXkS>8W{Cd$xZ(SULbeZYTU@$jvhP68X}HS=I=SgWJUeAl z6vO|K!XhcXEJ|vSwu?UeJe6^QZ$7Fkb1lBR3$gZ4+#eqdLSz7JBO;x{?RWpYG5ps? z2vnmh_qMR0oA@`eNqtfe!3u-4ZYL?o;NjvP2cEX=QSZYuM4Wq?+=q>ogZ;C+v;Fn2 zR*w?WA4L|A0sMP;T^mH5M=c+aR8pw9w`spX;l8wDW;?bp_54ZaD~rw8duF(*iRd4Z zbrv>26x#uI|INI}6#wgaYyN4_N1t(I^cTS?O=42zVkr48YwUX@BOu2T4COu%wo2gSR=rJ zEq*im)gB1&hL_9>DWcGJWpt{iYEqMLu+-5&-Iz$1nR~{3(d86oiPQpQ+R~WxPaGW$k;N za(;~H$C~jaKP2;zSU=8n#=w56akbb`M5n2OyO(2*vWiDsS5HDp3o5;wgn1tle=Bo4 zUp$p!Yn^U88o)evDuNfrKNRd38BBv{yxG>$m+e9Ky&VVnbPQr@ zRt)K2gm9mQ+e&G}V7h~Kz{$>e1E#-D$fFM1Qea#lu25DTk?{jRx~1|olQ^=}LQ}p^ zpY2KLZ3}(#seCSjMgjv<{fKb+ChE>->@|1ab}CorgIlK{;YT4xTS(NM(ZxSep(Ax| zR2MF63D-?G=f0+OI}Qg|mJGvOf`FS~dY(Brqe@sn>f#G{O)b5;Qh{(ln%-u>lywP$ zeR4LJzkA{(QR5%oC=V40YgT!F&MxoI41txI+JGuI3({Yq$03=0pAlQ{weBbaQOZ;k zZ4B`gEIghJ6WZf3JXgDae7pKEB(9ILb;5UT7&ox9kVM0`--zNg}uD& z(C~|lZ=^+h(=_y|0Q}YIMC?ef;^IYkuJ4en?Af=`TC|u=HwwOQOHIt?)v8<5g}1uR zhspBAoyKzQ#_j4TZKlm3Lu;t)RpsD2>{|CALrkmPXKLNAn_bZLjdcKLd}0G_{O)2N zSK~hfs_f=AKMP#uM4+rfpVgPkRf}PS>n(=f=>&!vV(yu@rOoTH9V5>pMz7Rcm}95o zPZOznT&I36mcy~@aP=s^Z*d^oP%WkC=BG^g-wW)6!Kg0kHJxDSvtz^rCt;r8V#5Ka z|G#RyXugRGQ=8(bQ1fxQ_I!QMzZP-)Yu+>&H%s}f2Jm9?ispUCp|D_CCP@t|(T2yl zkx5I80Iw|5Qbg%7g@B8z!ikx8j=}SOH;Py2Mn(lQvt#z2X_6-(2>Ht@^Tj5`xS*L+0md5W3M=bMHcJoS5*AT zs-~NiQ9_Xm->&h!OXT)ns7Oa_h)e+uDxnGc|eqR7H7tyAhHJ zc4F&s{a8SO%@TN)M-a=wu+@2^u#9u$@e7$#B|?$`Uhk}*cgEhmU!;SP{mhGxYWyuSDgRRd zj#Mf@FA+ikxC5w{D9Ic|cBrX#;;ujc)kA7|4+?}fJuoM83L%3*;2j+rQB3iHfuo&G#9-wpu@sIYr9Kblkk_4bW+lXFb zqnyiO65=u=O;C4zv=AY%M^;|0j4#14>EmacBu85>tM-kRDr}T+84h4!Vew@~{?MK> z9lQFq>2*hbF-900cgij=yfhbCEf@b*$6kq2sc7sM*8v>&H3~zAFost%iN_Xg=>J4n=`2j8^VNDv!4hl{bGrZ!{9*J{JzM7XHBSu5;FBSTcDdTf+jqWEytb-UK^ z&Y+zqUoRzg1D zK2LK?KICTVGtq(d&l42Dj$Er+XyzVdoe3`Lfgsr$gP&6uu$rE#`{aPMIF7Y~C zt0*u1V~4248zquDBbDPkT z6;DIvIO2s?VwA78f+w|{)V272Z*}^~qU?*g-;LyKCUNJ1+=j?|M0zv*tL)5#lt8x6 zevpzE{yU1?&_5FgWuIWT=jxQ$A-{h8vJVy$^WW<$ON(J835d_`kXH;v1z|-F!03^r zLcrqACa%gcoa|x9Kp+ISw|rL$oE+IJh{yy9pZ>dqZkPJb$8*f-dbrXzOoG!r>TWdP zp&?@0o-$djOWyIf+}fqjb~ zzAw3ntE91AMEKDWfu<(u;}`z?a$wZ;n!-7YI_^p0>gt*pIg-G!sY;3xvf)YFNEp^H zUM?np9bSM92AkFiw8B)$z>`YW?HCP>eJ2)5(rXI+863AyaZo(2CAoT zJuGul@~jPnd9}J6y7!%8v=0WEw1z(}Dx9*{ioIJgcXc`W ziS=FdrrkW*Y=g0EF$BP&H1jI%*LCDtz zrlH3O>qGxzUn4uQ#1|PBQfu9Jz%A38UUhyG&X}$iqi&4Gjed*>3AMObGS)F+7`v9I z{(%yZ%5Lh_o0+@C{8XL4zpkJ%)l9)jQIVi>+a^izImMdMlA`&#?nlJZN8#f>;(p9HdgUn6N#GMH!(z z%1HWOL-+Faxp`^%6C>3oL35ssY}exL57DRbF*#3hIo^b)amVHe%GHdU0jGzJk!S3Gv;=NVDDGW`IiGjv)iuA!WVeC9QAe$wxOH-vdT(Y0QK7m-PPH8pq!amq06Fp zZZPiJ8jVmPQM+ky8k}}qf8VpqO(O~H*8@)XCHK3q@3BoCd%Z>`O%((osvA}e=cc3w zY6d_U7Y=nOr-a1UE$H8OR1EwS$YbZm=BZ!r?d=U4NN8l@hPxj`YCArg zx4YGv_92+>Sx8_hx7KGbYBZ3AhNBN=;8m#gbVb=?kQh^|i=hSgvTLI{Fbs+Ka9nf{ zyw>z?gp7Q?PJd&Z#L|xiN>Q;|T{S&T!2Ji^^~{9Y(6AsAFuUjH*6s_XzQHDhgVL6K z2Q9c7ze$QOyB4&f6Pz8|>UEM1XdqHP(8YTWL;W;*6cv$w!yu-18#S;0=o( z%nYAD|Jj%bd`0M`;5dn{NL)WdP$YeFQ|xp=#$Mv4)D3oLS+xD*LmkDDo>2yHb~acf zq8Z#&`?D}784MRK0h6E<7Dmihh4^{>$t!LnYHRc1P{M&qOHW^c8|N9X!s5b*Jsp_lEb(_l|6}paD#cIPQZ473M|82LJ{&+m~}NMDn4}uw2s|B)+~O0ycIYwLj4-24LPZ)noC`8(bVf^ z^DrZSO;dx%$a4XHK?%>cwE zp7_o0Wq(%L7lx*e8)Q08h`0q~#@v5%>3I)C_{BQ#_mBlz*w`AM!5g~L-uZt}meTI@ zzIYK2MGz5jhV>efR5JsBHEC23N++H4AC;B3xeOnaKzXGUi>{KD2(`pw^d*Kac>lgy z^`Ca4uXlW*QRF1JZaV8X!aB{`7=)P6g9)*u^uNw}Io;#i-W<#3`Oz2QVA_D= z7}Qh`UFI^64!`$xfgS6{muL-6(nZYwqlEp~ac(+JHEJ5Zii_bz2gBJF`Z(c4LB7EE z-QMsWJqWTaN2NamCBmGB_$#Go2Sga;SL^faxlOQbx?Ply^i@;f#F4Q-yejup<_B+d zL4Mo5C^JP9o8M3;v}U%Q-!9XdfeoVA35-Jr+zjYuV+JChC3l{G68u$0Jja9D5OWn* z&)&uhs^Jyw~Z9gv4v~#cV;?*$Af*|tUA5CdEwC^lGZ{78&Kk4DG|&N^C#N@PrSIp@$)Jxy`WXBn zCs_6?4cJf}y8T>!$T(APBvrXImOZN3?2E=`3iQ%u^=XNI=_4vUPEBB6zk;DRQ;;jO zBrn+_&iLlu4dO^Eu0AE9fi>3`cm20)6eenmdtK8_d_N^CCqs7y>7nU*$z^JmX3yxu zJ2?c?O-6o|vqQ}=G^&1g<)mVN#!Abs?xn)`A+4&MugL?=kt=55`@rZhCIxBi`AQF{ zwY0okzU)UrK*2k}j1CdH@wqpnPL8VxAG;A|9`*oz%)ohF8YN8ws7=SK?=smE!WPk& zMmh7s>EF$F)mZsn1BJK(d1$BKRm~lx-ea7m@5mxYEa-_vlQConcM%(m;D~|~UMA@R z8q@TTTs=C(LLW(-n~LLpM~GO0?aAxZw|n35wl&~!az|gx%H*vl`16d|Vl6h4^ByfF zL=tiwt9?@V;}YI2Y#~ZsBN<%iR`t21Z*9ng=;x3 zrDy0#(oFe;OEcwj1wxc-XhAv|b)AR=*_i`xMc|{F`)GSLocmFpvs5)0C?0S}G`$*o zE_!FCSvKZ_g?q^yE0L_rG(S(DL153j@N6S}Rp?=}RlI&Pxb615rLI+@Z$bPhF-cmA zqqK~ju3#1`J#sis8vz|SlPyJ3x#a59vI()K@vL4)f&p;}ZU+`GOQ^Z+gzV!UHzp^- z_vVEFB;uPmgPSZD59)p!HPat186_YkS^<^>k>#5~KiFAla;L2Bs?x^a2T_alTnv;b za zTP-2~9``m^M-~bg-2n74nUU~c*TrXV&;?%G>p0q?vO4Wss#Z^}9i5b&g;n-5$Yn`l ziWSm`=hNUS{G`)+jv)c-@;QcgJ7U4`zhHHNIO+&Y?25ICRpXRq*bHW^%E zT72ijd+TVTugI)+Bw}fpymJJ{NP{)p55OPW2UPkCo6X1K)%gUR1r>_YqFtdGOUu$@ z9eU#$f%;emiR{hW5xE+91zIlMNjMbkj|4qGUYA+EzTjcV`n;0Lo`fZJN}sXnd_pHW zaeiONx^WdZ$|R#CfL=^98N#wanH_{qKUq-z<-zpZR;aftoK$?v`DC=4x$6x38Bfi%svpVX#9DnhLAB z(1Ux0vb?UnD|33_24rKx^N$FHn@JV$*=2@}asK+GTWeE{*c68MnRrnXqne$R+Hstu zs@=Iy$%mC^FMZ2mViEOqxJG^EF!vMvHXq+(SDQ$1TvPQWWbV%82&<#ZaiB2HU!Wnx zb~aK`Zx^8a)Ce9LVJy1g&qL=KrNxoSq&F4bq;7AHJGi z6DPmZAu4C;`Tzo~#2BIfa^0IWrtP-rXH{UVo2PX8;+3rZ`0wA(i0pK8G_>2TfH_2G z9p~3SvIb4A78c$|^t6Py4$a?EJ$%$ANVLCmWwI0vx_69wuy{MyK z8aVFlXcAHc@vDzrrss%^<&jrB`57x=hnYN#wus+*(!V#$WMHZgeI%@S234ck7}f~D97w|1d~cf?7sW)&SafM= zX?lJMG`o#tzl4-bVr^qB%StM1rw2-pC7R|zmwt}Mijv8rbMM799vmNg*S3jvTMxvM z&IEOg4Ufc<4ul@@=xt1A&xtdcBhziEwu){>nbo|PG@sS!s4!p6agl9f# zuu3`S>6PnudRYZGR5bOGeJ06T+Y1@{bp%{oJj$F%lh-xk7@;1~dQ`4j*9)#zu53V% z9Bqs>52!-{3Jbzt7@Q~5BlFu5{tiQn9!}^Im-Y4nEf@MJyTL1FvhB-%W29CAWPRrd zgSpH~g-O=LQ_tf{wvL9ak?w5FxJ`pQbfeS0nt#o997WE(z;f4ZO!;^l zOfhe@8H(A`tCw{0OCXoi6U%Cs$VJND1q;0~ovlGMn%zJ(v|3{Gz?6l1^ntxz=7yNs2jA1D&$*BP|_>evHSKq(q0ah);=zkV?cNIx_UGJ`H&~tTN)1A>q zDK>N;U+AAM1C6BYzCeho70oTIU@H~MBQdWZNNQfUL^|)s5h)?AZvRx@Gg73j2at39 zBlZ5*omLlUhePVg;9B3nX?aMQ<#(dpd3C6_znDjhFbkVF(sa^34C=s#RS`XNDRQ+M zu77%^3Nnxl6lZ0b#}owyQ3QO;Kb9-RY=?fowzt3lyrMguipfsu=SInBM#EF;)ime;No0n^AWK8yy0g;2$0@!;MMkikj--^B)YAvc-}1KC@> zy;1khdw=`jBO;j=+X~3@=LzM*_oxCJQITn=4Sny~mO5Cm>-ZN58WERY(Gllqf}d+E z#ZD&IS2gipdjlq>6D7y^p8QG+js16X{*fR!RxK}Kt4*vdgumu<+zFJI5duw+S)6$i zNe#Vq06=C*BH*lA)B$27D_|vV{l=?f)hcMbEGz1xP-AfTbiW!(jl)*#*M;vCfsHiX zW=0FpGxBF=+CAz6y*IH6z=rzd0{pYbGB(2m!HuSa_!0d{{svF_|Og5ZS+C3IMsV#Vw_N zi5wIjJaS?!I^;hhnTeE+sk=wf;uC=Vn3$O4jZh&bci&qYJ`^TfXC+tleptIDCavx} ztX^p_&}+=Y&k}IiJo=FPE?V*(sFWHlq272*js5r6q}y#i?*{HaD|NL*Rv}Rzv%K5H zedDOGPdKrb7nzCEPB@y`6>7c$+}j{=T-92?WfS{Z4v>Mh7OCdDVMhaS@>7$YPjMpw zs_BLJb@SnG#d>(PBo(|d2t}PLDYf2Yp92b{Mu0NGVA=4~=mS9zQbm*63XJ{tRJ&dO z@K5x}Pn`b<;WtBg|R?dj6LI(NdO?%xVOdc&}4b@xbR?mCb0jkR+Mjjbi3 za`Kae`hz|onC}u59U;@+3}dZMn>1EyN4ID;4eHu<7}16kaA@f^B^gpxB!9$!%Dv9; zDE%l$=gSn)(MIF&`EBtL6kQ+@3<3g^NnjFU&Oj)WG2gskJS3GbqhHKKJm1cH=KKj$ zRQvSj!h=OQ<1glH>X>}N z8p>vQ;zEs7l;$qK$;5e@NjPq#v6is$6I=KXj^+`u?K}%cO!a;hD4|qAU|jk6PM7yw z3vnA!a>{B_pI8M26ip#jd&-#04VTo~mLNvIQ^JCf@eelfN&*iq*n`Xr)YH*{CKA z^ea+7)kaS(LFrlEIlzV>Zkn`SQc%e%u26;=4tHOsV*Z>I<0l8Pz^>GVV{g%i8%KbH z$a>9A;f_2nGZUU^YGYpUwEQRk?(rrw5Bwx`0+tMIZAb8A5=a5Yv7ws%hEp&EKtM{* zPYD)+V@9jaXZnmOgC^mOP7>TY%N+ilI<=Q z7{QR*ntFH0J58_Pe`rYwuVT++K;N; z4%-7%7;$}Z#kkEI6h`YJLKB<9EnG1|=GqMTJ#ae^@-`r+rv>#<1;o0QTD68GCGZ zg3FFgAp)k+^Ps2f#^88+!zpP)X-PZ18umLKAcg7NsDuC$sMfZqBn%G#Zmsm8ykGI| zGL(^eDl5%lW@BT^77ToOLIfzpM8&Zyi=)(RCpZIGebm!SkU?;XDO}@FG5ADXk$3`$xrv)ULGazq1FHg zy19^R9tR#hfA6<%72;yw4KzUn`bgLzp>AYCmwJzQ8#2-iq*sdmitdG z9jh^%mhn>5UER0JC45UsTR=&xtZK>`n**+rJkHNwBk>0pe{(17{2a=A+W4tfr@L%Apl z_c%oc;0UoCuA)9PhvOGa!gegiMs@j#n`2%_-*8!xrJ~!Cv=t2ybK4!a$$87{B3r|; z3PoK3pWn70Qhcf~i!u}zafPCK2Fg6H4!k~NV&e;>XkD5}tBO=3E$uGWDgi?Ud-W|P zb~t2O209R6zS@99yTj9=hT;DfjaDd=0B%vGCT+t4S^{Wa7i20%)ojR*qGU!1lEmZr?6~Zu}(4BoD$h9L?XTt)C0C(dmAJ9!Tv@FM%|<@p(m{=Zbi{ z?$dGgYIt@P$;|gUbW&0XDWLchlnUTn#A@9pL@&s6ufGxXpUY(_ZT9F1M#6$pfQpp# zy@Zl#BZQ4Zrq(SEp@|$=t7Vj&KZDp*#GFCB$zN?oYq@4Dc*ndsJ{n2N@XBF)#S68Q z=63E&Ml~B{>rdKNI%+XKiesBbhf`wUZmrraUuIec71Pg)?+QkZf6eBCC1`P^VZ0XK(3(?TN z$*&{-1Ih$|b;OD~N)`0&E9F7yPDrTLaGr8Zur$$CD^L$8R;x3LA5!_*gf^nYzY|Qf zNO_R_pKpmP=rN>zvr$U@(h#G>PVEo_^aCPs8FfhIQ$gRsiIr1hvzpUjDOb{>efbC0 zH#lVh!IbU11B!F=@CqpJ2w)P3GzbZJCjjjo3h|E@%F)gCa`XpB|CuJ2A6lo+^;wu2 z1WrsFYmwGgC`&a$6dfh7&{B=L$9lxd5_o_}6>jiFng3S@2)+lwBzkd4V=}W-S&%DG zrEN}aetPUl(vk4w0N^AU*AS?{w!$~st4!nOzonR0wa=^h@DNFrs0Eu6T{@F;Xq9x1 z(m9bnRW64S1`~>*sS?7e|2&j3X`r$UtLw6W!-a}-;2<2Re#VQz`YumN63lq73Mk=9 zhy}_oar)(iO1VZ;zb&UeWF3cJ1txGF*XR(T=|9tGnG@w<_QOg_EL7!yW@vsl zXF#O4)*gsiJ?Wwyl%+Rc4bdcZmUY0jPENN=>W+Bxh&Zwy{=4`Qo=T&RVAHDh#hwZ* zzD(0LjG#$-57TeBDnNmf2 zg%Q|(cKF*;)7@pM&WK3{V)Ypzh2 . +@prefix lv2: . +@prefix pedal: . +@prefix rdfs: . + + + lv2:prototype ingen:GraphPrototype ; + a lv2:Plugin , + ingen:Graph , + pedal:Pedalboard ; + rdfs:seeAlso . diff --git a/test/util/setBfree_ttymidi.pedalboard/screenshot.png b/test/util/setBfree_ttymidi.pedalboard/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..17a3f2d2079a695c4b471c68fa1f449515490e80 GIT binary patch literal 62368 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 literal 0 HcmV?d00001 diff --git a/test/util/setBfree_ttymidi.pedalboard/setBfree_ttymidi.ttl b/test/util/setBfree_ttymidi.pedalboard/setBfree_ttymidi.ttl new file mode 100644 index 0000000..75665d0 --- /dev/null +++ b/test/util/setBfree_ttymidi.pedalboard/setBfree_ttymidi.ttl @@ -0,0 +1,186 @@ +@prefix atom: . +@prefix doap: . +@prefix ingen: . +@prefix lv2: . +@prefix midi: . +@prefix mod: . +@prefix pedal: . +@prefix rdfs: . + +_:b1 + ingen:tail ; + ingen:head . + +_:b2 + ingen:tail ; + ingen:head . + +_:b3 + ingen:tail ; + ingen:head . + +_:b4 + ingen:tail ; + ingen:head . + + + ingen:canvasX 1635.3 ; + ingen:canvasY 520.9 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 9 ; + lv2:minorVersion 2059 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + a atom:AtomPort , + lv2:OutputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + +<:bpb> + ingen:value 4.000000 ; + lv2:index 0 ; + a lv2:ControlPort , + lv2:InputPort . + +<:bpm> + ingen:value 120.000000 ; + lv2:index 1 ; + a lv2:ControlPort , + lv2:InputPort . + +<:rolling> + ingen:value 0 ; + lv2:index 2 ; + a lv2:ControlPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + lv2:index 3 ; + lv2:name "Control In" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_in" ; + 4096 ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + lv2:index 4 ; + lv2:name "Control Out" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_out" ; + 4096 ; + a atom:AtomPort , + lv2:OutputPort . + + + lv2:index 5 ; + lv2:name "Playback 1" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "playback_1" ; + a lv2:AudioPort , + lv2:OutputPort . + + + lv2:index 6 ; + lv2:name "Playback 2" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "playback_2" ; + a lv2:AudioPort , + lv2:OutputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + lv2:index 7 ; + lv2:name "pisound MIDI PS 19FP3ND" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "midi_capture_1" ; + 4096 ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + lv2:index 8 ; + lv2:name "pisound MIDI PS 19FP3ND" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "midi_playback_1" ; + 4096 ; + a atom:AtomPort , + lv2:OutputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + lv2:index 9 ; + lv2:name "Serial MIDI In" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "serial_midi_in" ; + 4096 ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + lv2:index 10 ; + lv2:name "Serial MIDI In" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "serial_midi_out" ; + 4096 ; + a atom:AtomPort , + lv2:OutputPort . + +<> + doap:name "setBfree-ttymidi-in-out" ; + pedal:width 0 ; + pedal:height 0 ; + pedal:addressings ; + pedal:screenshot ; + pedal:thumbnail ; + ingen:polyphony 1 ; + ingen:arc _:b1 , + _:b2 , + _:b3 , + _:b4 ; + ingen:block ; + lv2:port <:bpb> , + <:bpm> , + <:rolling> , + , + , + , + , + , + , + , + ; + lv2:extensionData ; + a lv2:Plugin , + ingen:Graph , + pedal:Pedalboard . diff --git a/test/util/setBfree_ttymidi.pedalboard/thumbnail.png b/test/util/setBfree_ttymidi.pedalboard/thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..c7108fa51863a899f83b447139fc66b015b8979b GIT binary patch literal 14979 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 Date: Tue, 31 Oct 2017 22:45:58 -0300 Subject: [PATCH 26/31] Improve documentation for midi informations --- CHANGES | 6 +- pluginsmanager/model/system/system_effect.py | 59 ++++++++++++++++--- .../model/system/system_effect_builder.py | 8 ++- 3 files changed, 64 insertions(+), 9 deletions(-) diff --git a/CHANGES b/CHANGES index bca5369..2bc06fe 100644 --- a/CHANGES +++ b/CHANGES @@ -23,7 +23,9 @@ Version 0.6.0 -- released 10/?/17 - `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 #62`_ - Create a converter MOD pedalboard -> PluginsManager pedalboard; + - `Issue #77`_ - Fix MidiConnection bugs (:class:`SystemMidiInput` and :class:`SystemMidiOutput` doesn't works in :class:`ModHost`); + - `Issue #78`_ - Improve lv2 effect builder error message when plugin not exists. .. _Issue #38: https://github.com/PedalPi/PluginsManager/issues/38 .. _Issue #57: https://github.com/PedalPi/PluginsManager/issues/57 @@ -32,6 +34,8 @@ Version 0.6.0 -- released 10/?/17 .. _Issue #66: https://github.com/PedalPi/PluginsManager/issues/66 .. _Issue #67: https://github.com/PedalPi/PluginsManager/issues/67 .. _Issue #68: https://github.com/PedalPi/PluginsManager/issues/68 +.. _Issue #77: https://github.com/PedalPi/PluginsManager/issues/77 +.. _Issue #78: https://github.com/PedalPi/PluginsManager/issues/78 Version 0.5.1 -- released 08/16/17 ********************************** diff --git a/pluginsmanager/model/system/system_effect.py b/pluginsmanager/model/system/system_effect.py index be1437f..47aea8d 100644 --- a/pluginsmanager/model/system/system_effect.py +++ b/pluginsmanager/model/system/system_effect.py @@ -23,7 +23,7 @@ class SystemEffect(Effect): """ - Representation of the system instance (audio cards). + 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 @@ -49,33 +49,78 @@ class SystemEffect(Effect): However the pedalboard must have the connections:: - >>> pedalboard.connections.append(Connection(sys_effect.outputs[0], reverb.inputs[0])) + >>> 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.connections.append(Connection(sys_effect.outputs[0], sys_effect.inputs[0])) - >>> pedalboard.connections.append(Connection(sys_effect.outputs[1], sys_effect.inputs[1])) + >>> 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 + + .. _jack_lsp: http://manpages.ubuntu.com/manpages/xenial/man1/jack_lsp.1.html + + 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]) :param string representation: Audio card representation. Usually 'system' :param tuple(string) outputs: Tuple of outputs representation. Usually a output representation - starts with `capture_` + starts with ``capture_`` :param tuple(string) inputs: Tuple of inputs representation. Usually a input representation - starts with `playback_` + starts with ``playback_`` :param tuple(string) midi_outputs: Tuple of midi outputs representation. :param tuple(string) midi_inputs: Tuple of midi inputs representation. """ - def __init__(self, representation, outputs, inputs, midi_outputs=None, midi_inputs=None): + def __init__(self, representation, outputs=None, inputs=None, midi_outputs=None, midi_inputs=None): super(SystemEffect, self).__init__() self.representation = representation self._params = tuple() + inputs = inputs if inputs is not None else [] inputs = [SystemInput(self, effect_input) for effect_input in inputs] self._inputs = DictTuple(inputs, lambda _input: str(_input)) + outputs = outputs if outputs is not None else [] outputs = [SystemOutput(self, effect_output) for effect_output in outputs] self._outputs = DictTuple(outputs, lambda _output: str(_output)) diff --git a/pluginsmanager/model/system/system_effect_builder.py b/pluginsmanager/model/system/system_effect_builder.py index 949c305..8854cd7 100644 --- a/pluginsmanager/model/system/system_effect_builder.py +++ b/pluginsmanager/model/system/system_effect_builder.py @@ -18,7 +18,13 @@ class SystemEffectBuilder(object): """ - Automatic system physical ports detection + 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. + + .. _a2jmidid: http://manual.ardour.org/setting-up-your-system/setting-up-midi/midi-on-linux/ :param JackClient jack_client: :class:`.JackClient` instance that will get the information to generate :class:`.SystemEffect` From 1bd26a0759da55f42650580ee9846d72736eaf58 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Mon, 27 Nov 2017 09:32:43 -0300 Subject: [PATCH 27/31] Add support for git status --- .../util/mod_pedalboard_converter.py | 31 ++++++-- .../{ => data}/EPiano.pedalboard/EPiano.ttl | 0 .../EPiano.pedalboard/addressings.json | 0 .../{ => data}/EPiano.pedalboard/manifest.ttl | 0 .../EPiano.pedalboard/screenshot.png | Bin .../EPiano.pedalboard/thumbnail.png | Bin .../EPiano_simple_tt.ttl | 0 .../addressings.json | 0 .../EPiano_simple_tt.pedalboard/manifest.ttl | 0 .../screenshot.png | Bin .../EPiano_simple_tt.pedalboard/thumbnail.png | Bin .../addressings.json | 0 .../setBfree_ttymidi.pedalboard/manifest.ttl | 0 .../screenshot.png | Bin .../setBfree_ttymidi.ttl | 0 .../setBfree_ttymidi.pedalboard/thumbnail.png | Bin .../teste.pedalboard/addressings.json | 0 .../{ => data}/teste.pedalboard/manifest.ttl | 0 .../{ => data}/teste.pedalboard/teste.ttl | 0 test/util/mod_pedalboard_converter_test.py | 72 +++++++++--------- 20 files changed, 58 insertions(+), 45 deletions(-) rename test/util/{ => data}/EPiano.pedalboard/EPiano.ttl (100%) rename test/util/{ => data}/EPiano.pedalboard/addressings.json (100%) rename test/util/{ => data}/EPiano.pedalboard/manifest.ttl (100%) rename test/util/{ => data}/EPiano.pedalboard/screenshot.png (100%) rename test/util/{ => data}/EPiano.pedalboard/thumbnail.png (100%) rename test/util/{ => data}/EPiano_simple_tt.pedalboard/EPiano_simple_tt.ttl (100%) rename test/util/{ => data}/EPiano_simple_tt.pedalboard/addressings.json (100%) rename test/util/{ => data}/EPiano_simple_tt.pedalboard/manifest.ttl (100%) rename test/util/{ => data}/EPiano_simple_tt.pedalboard/screenshot.png (100%) rename test/util/{ => data}/EPiano_simple_tt.pedalboard/thumbnail.png (100%) rename test/util/{ => data}/setBfree_ttymidi.pedalboard/addressings.json (100%) rename test/util/{ => data}/setBfree_ttymidi.pedalboard/manifest.ttl (100%) rename test/util/{ => data}/setBfree_ttymidi.pedalboard/screenshot.png (100%) rename test/util/{ => data}/setBfree_ttymidi.pedalboard/setBfree_ttymidi.ttl (100%) rename test/util/{ => data}/setBfree_ttymidi.pedalboard/thumbnail.png (100%) rename test/util/{ => data}/teste.pedalboard/addressings.json (100%) rename test/util/{ => data}/teste.pedalboard/manifest.ttl (100%) rename test/util/{ => data}/teste.pedalboard/teste.ttl (100%) diff --git a/pluginsmanager/util/mod_pedalboard_converter.py b/pluginsmanager/util/mod_pedalboard_converter.py index 2afa47d..d4a3bc4 100644 --- a/pluginsmanager/util/mod_pedalboard_converter.py +++ b/pluginsmanager/util/mod_pedalboard_converter.py @@ -19,6 +19,10 @@ from pluginsmanager.model.system.system_effect import SystemEffect +class PortNotFoundError(Exception): + pass + + class ModPedalboardConverter(object): """ ModPedalboardConverter is a utility to convert MOD [#]_ pedalboards structure @@ -106,20 +110,31 @@ def _generate_effect(self, effect_data): return effect def _get_port(self, name, effects_instance, system_effect): - effect, port = None, None + effect, port = self.filter_effect_port_symbol(name, effects_instance, system_effect) + + possible_ports = (effect.outputs, effect.midi_outputs, effect.inputs, effect.midi_inputs) + filtered = filter(lambda ports: port in ports, possible_ports) + + ports = list(filtered)[0] + return ports[port] - if name.startswith('capture_') or name.startswith('playback_'): + def filter_effect_port_symbol(self, name, effects_instance, system_effect): + if '/' in name: + instance, port = name.split('/') + effect = effects_instance[instance] + elif self._is_system_effect(name, system_effect): effect = system_effect port = name else: - instance, port = name.split('/') - effect = effects_instance[instance] + raise PortNotFoundError("Port '{}' registered in system_effect?".format(name)) - possible_ports = (effect.outputs, effect.inputs, effect.midi_outputs, effect.midi_inputs) - filtered = filter(lambda ports: port in ports, possible_ports) + return effect, port - ports = list(filtered)[0] - return ports[port] + def _is_system_effect(self, name, system_effect): + return name in system_effect.inputs or \ + name in system_effect.midi_inputs or \ + name in system_effect.outputs or \ + name in system_effect.midi_outputs def discover_system_effect(self, pedalboard_info): """ diff --git a/test/util/EPiano.pedalboard/EPiano.ttl b/test/util/data/EPiano.pedalboard/EPiano.ttl similarity index 100% rename from test/util/EPiano.pedalboard/EPiano.ttl rename to test/util/data/EPiano.pedalboard/EPiano.ttl diff --git a/test/util/EPiano.pedalboard/addressings.json b/test/util/data/EPiano.pedalboard/addressings.json similarity index 100% rename from test/util/EPiano.pedalboard/addressings.json rename to test/util/data/EPiano.pedalboard/addressings.json diff --git a/test/util/EPiano.pedalboard/manifest.ttl b/test/util/data/EPiano.pedalboard/manifest.ttl similarity index 100% rename from test/util/EPiano.pedalboard/manifest.ttl rename to test/util/data/EPiano.pedalboard/manifest.ttl diff --git a/test/util/EPiano.pedalboard/screenshot.png b/test/util/data/EPiano.pedalboard/screenshot.png similarity index 100% rename from test/util/EPiano.pedalboard/screenshot.png rename to test/util/data/EPiano.pedalboard/screenshot.png diff --git a/test/util/EPiano.pedalboard/thumbnail.png b/test/util/data/EPiano.pedalboard/thumbnail.png similarity index 100% rename from test/util/EPiano.pedalboard/thumbnail.png rename to test/util/data/EPiano.pedalboard/thumbnail.png diff --git a/test/util/EPiano_simple_tt.pedalboard/EPiano_simple_tt.ttl b/test/util/data/EPiano_simple_tt.pedalboard/EPiano_simple_tt.ttl similarity index 100% rename from test/util/EPiano_simple_tt.pedalboard/EPiano_simple_tt.ttl rename to test/util/data/EPiano_simple_tt.pedalboard/EPiano_simple_tt.ttl diff --git a/test/util/EPiano_simple_tt.pedalboard/addressings.json b/test/util/data/EPiano_simple_tt.pedalboard/addressings.json similarity index 100% rename from test/util/EPiano_simple_tt.pedalboard/addressings.json rename to test/util/data/EPiano_simple_tt.pedalboard/addressings.json diff --git a/test/util/EPiano_simple_tt.pedalboard/manifest.ttl b/test/util/data/EPiano_simple_tt.pedalboard/manifest.ttl similarity index 100% rename from test/util/EPiano_simple_tt.pedalboard/manifest.ttl rename to test/util/data/EPiano_simple_tt.pedalboard/manifest.ttl diff --git a/test/util/EPiano_simple_tt.pedalboard/screenshot.png b/test/util/data/EPiano_simple_tt.pedalboard/screenshot.png similarity index 100% rename from test/util/EPiano_simple_tt.pedalboard/screenshot.png rename to test/util/data/EPiano_simple_tt.pedalboard/screenshot.png diff --git a/test/util/EPiano_simple_tt.pedalboard/thumbnail.png b/test/util/data/EPiano_simple_tt.pedalboard/thumbnail.png similarity index 100% rename from test/util/EPiano_simple_tt.pedalboard/thumbnail.png rename to test/util/data/EPiano_simple_tt.pedalboard/thumbnail.png diff --git a/test/util/setBfree_ttymidi.pedalboard/addressings.json b/test/util/data/setBfree_ttymidi.pedalboard/addressings.json similarity index 100% rename from test/util/setBfree_ttymidi.pedalboard/addressings.json rename to test/util/data/setBfree_ttymidi.pedalboard/addressings.json diff --git a/test/util/setBfree_ttymidi.pedalboard/manifest.ttl b/test/util/data/setBfree_ttymidi.pedalboard/manifest.ttl similarity index 100% rename from test/util/setBfree_ttymidi.pedalboard/manifest.ttl rename to test/util/data/setBfree_ttymidi.pedalboard/manifest.ttl diff --git a/test/util/setBfree_ttymidi.pedalboard/screenshot.png b/test/util/data/setBfree_ttymidi.pedalboard/screenshot.png similarity index 100% rename from test/util/setBfree_ttymidi.pedalboard/screenshot.png rename to test/util/data/setBfree_ttymidi.pedalboard/screenshot.png diff --git a/test/util/setBfree_ttymidi.pedalboard/setBfree_ttymidi.ttl b/test/util/data/setBfree_ttymidi.pedalboard/setBfree_ttymidi.ttl similarity index 100% rename from test/util/setBfree_ttymidi.pedalboard/setBfree_ttymidi.ttl rename to test/util/data/setBfree_ttymidi.pedalboard/setBfree_ttymidi.ttl diff --git a/test/util/setBfree_ttymidi.pedalboard/thumbnail.png b/test/util/data/setBfree_ttymidi.pedalboard/thumbnail.png similarity index 100% rename from test/util/setBfree_ttymidi.pedalboard/thumbnail.png rename to test/util/data/setBfree_ttymidi.pedalboard/thumbnail.png diff --git a/test/util/teste.pedalboard/addressings.json b/test/util/data/teste.pedalboard/addressings.json similarity index 100% rename from test/util/teste.pedalboard/addressings.json rename to test/util/data/teste.pedalboard/addressings.json diff --git a/test/util/teste.pedalboard/manifest.ttl b/test/util/data/teste.pedalboard/manifest.ttl similarity index 100% rename from test/util/teste.pedalboard/manifest.ttl rename to test/util/data/teste.pedalboard/manifest.ttl diff --git a/test/util/teste.pedalboard/teste.ttl b/test/util/data/teste.pedalboard/teste.ttl similarity index 100% rename from test/util/teste.pedalboard/teste.ttl rename to test/util/data/teste.pedalboard/teste.ttl diff --git a/test/util/mod_pedalboard_converter_test.py b/test/util/mod_pedalboard_converter_test.py index 5612759..8a8f029 100644 --- a/test/util/mod_pedalboard_converter_test.py +++ b/test/util/mod_pedalboard_converter_test.py @@ -22,18 +22,23 @@ class ModPedalboardConverterTest(unittest.TestCase): + @property + def mod_converter(self): + path = Path('/home/paulo/git/mod/mod_ui/') + builder = Lv2EffectBuilder() + # builder.reload(builder.lv2_plugins_data()) + + return ModPedalboardConverter(path, builder) + @property + def here(self): + return os.path.abspath(os.path.dirname(__file__)) / Path('data') @unittest.skipIf('TRAVIS' in os.environ, 'Mod-ui not configured in Travis build') def test_all(self): - path = Path('/home/paulo/git/mod/mod_ui/') - builder = Lv2EffectBuilder() - #builder.reload(builder.lv2_plugins_data()) - - converter = ModPedalboardConverter(path, builder) + converter = self.mod_converter + pedalboard_path = self.here / Path('teste.pedalboard') - here = os.path.abspath(os.path.dirname(__file__)) - pedalboard_path = Path(here+'/teste.pedalboard') system_effect = SystemEffect('system', ['capture_1', 'capture_2'], ['playback_1', 'playback_2']) print(converter.get_pedalboard_info(pedalboard_path)) @@ -42,55 +47,48 @@ def test_all(self): @unittest.skipIf('TRAVIS' in os.environ, 'Mod-ui not configured in Travis build') def test_discover_system_effect(self): - path = Path('/home/paulo/git/mod/mod_ui/') - builder = Lv2EffectBuilder() - - converter = ModPedalboardConverter(path, builder) - here = os.path.abspath(os.path.dirname(__file__)) - pedalboard_path = Path(here + '/teste.pedalboard') + converter = self.mod_converter + pedalboard_path = self.here / Path('teste.pedalboard') print(converter.get_pedalboard_info(pedalboard_path)) pedalboard = converter.convert(pedalboard_path) print(pedalboard.json) - #@unittest.skipIf('TRAVIS' in os.environ, 'Mod-ui not configured in Travis build') - @unittest.skip + @unittest.skipIf('TRAVIS' in os.environ, 'Mod-ui not configured in Travis build') + #@unittest.skip def test_discover_system_effect_midi(self): - path = Path('/home/paulo/git/mod/mod_ui/') - builder = Lv2EffectBuilder() - - converter = ModPedalboardConverter(path, builder) - here = os.path.abspath(os.path.dirname(__file__)) - pedalboard_path = Path(here + '/EPiano.pedalboard') + converter = self.mod_converter + pedalboard_path = self.here / Path('EPiano.pedalboard') print(converter.get_pedalboard_info(pedalboard_path)) pedalboard = converter.convert(pedalboard_path) print(pedalboard.json) - #@unittest.skipIf('TRAVIS' in os.environ, 'Mod-ui not configured in Travis build') - @unittest.skip + @unittest.skipIf('TRAVIS' in os.environ, 'Mod-ui not configured in Travis build') + #@unittest.skip def test_discover_system_effect_midi_serial(self): - path = Path('/home/paulo/git/mod/mod_ui/') - builder = Lv2EffectBuilder() - - converter = ModPedalboardConverter(path, builder) - here = os.path.abspath(os.path.dirname(__file__)) - pedalboard_path = Path(here + '/EPiano_simple_tt.pedalboard') + converter = self.mod_converter + pedalboard_path = self.here / Path('EPiano_simple_tt.pedalboard') print(converter.get_pedalboard_info(pedalboard_path)) pedalboard = converter.convert(pedalboard_path) print(pedalboard.json) - #@unittest.skipIf('TRAVIS' in os.environ, 'Mod-ui not configured in Travis build') - @unittest.skip + @unittest.skipIf('TRAVIS' in os.environ, 'Mod-ui not configured in Travis build') + #@unittest.skip def test_discover_system_effect_midi_serial_2(self): - path = Path('/home/paulo/git/mod/mod_ui/') - builder = Lv2EffectBuilder() + converter = self.mod_converter + pedalboard_path = self.here / Path('setBfree_ttymidi.pedalboard') - converter = ModPedalboardConverter(path, builder) - here = os.path.abspath(os.path.dirname(__file__)) - pedalboard_path = Path(here + '/setBfree_ttymidi.pedalboard') + system_effect = SystemEffect( + 'system', + ['capture_1', 'capture_2'], + ['playback_1', 'playback_2'], + ['serial_midi_in'], + ['serial_midi_out'] + ) print(converter.get_pedalboard_info(pedalboard_path)) - pedalboard = converter.convert(pedalboard_path) + # Serial midi out raises error + pedalboard = converter.convert(pedalboard_path, system_effect) print(pedalboard.json) From 7180fef47ad28fa84aa15f6354b7109454500306 Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Mon, 27 Nov 2017 09:33:47 -0300 Subject: [PATCH 28/31] Fix discover_system_effect (hardware audio ins and audio outs) --- .../util/mod_pedalboard_converter.py | 19 +++++++++++++++---- test/util/mod_pedalboard_converter_test.py | 13 +++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/pluginsmanager/util/mod_pedalboard_converter.py b/pluginsmanager/util/mod_pedalboard_converter.py index d4a3bc4..8e8db38 100644 --- a/pluginsmanager/util/mod_pedalboard_converter.py +++ b/pluginsmanager/util/mod_pedalboard_converter.py @@ -146,9 +146,20 @@ def discover_system_effect(self, pedalboard_info): """ hardware = pedalboard_info['hardware'] - outputs = ['capture_{}'.format(i) for i in range(1, hardware['audio_outs']+1)] - inputs = ['playback_{}'.format(i) for i in range(1, hardware['audio_ins']+1)] - midi_outputs = [midi_out['symbol'] for midi_out in hardware['midi_outs'] if midi_out['valid']] - midi_inputs = [midi_in['symbol'] for midi_in in hardware['midi_ins'] if midi_in['valid']] + # MOD swap ins and outs + total_audio_outs = hardware['audio_ins'] + total_audio_ins = hardware['audio_outs'] + + outputs = ['capture_{}'.format(i) for i in range(1, total_audio_outs+1)] + inputs = ['playback_{}'.format(i) for i in range(1, total_audio_ins+1)] + + midi_outputs = [ + 'serial_midi_out' if hardware['serial_midi_out'] else midi_out['symbol'] + for midi_out in hardware['midi_outs'] if midi_out['valid'] + ] + midi_inputs = [ + 'serial_midi_in' if hardware['serial_midi_in'] else midi_in['symbol'] + for midi_in in hardware['midi_ins'] if midi_in['valid'] + ] return SystemEffect('system', outputs, inputs, midi_outputs, midi_inputs) diff --git a/test/util/mod_pedalboard_converter_test.py b/test/util/mod_pedalboard_converter_test.py index 8a8f029..1fd23f1 100644 --- a/test/util/mod_pedalboard_converter_test.py +++ b/test/util/mod_pedalboard_converter_test.py @@ -15,6 +15,7 @@ import os import unittest from pathlib import Path +from unittest.mock import MagicMock from pluginsmanager.model.lv2.lv2_effect_builder import Lv2EffectBuilder from pluginsmanager.model.system.system_effect import SystemEffect @@ -25,6 +26,7 @@ class ModPedalboardConverterTest(unittest.TestCase): @property def mod_converter(self): path = Path('/home/paulo/git/mod/mod_ui/') + #builder = MagicMock() builder = Lv2EffectBuilder() # builder.reload(builder.lv2_plugins_data()) @@ -70,6 +72,14 @@ def test_discover_system_effect_midi_serial(self): converter = self.mod_converter pedalboard_path = self.here / Path('EPiano_simple_tt.pedalboard') + system_effect = SystemEffect( + 'system', + ['capture_1', 'capture_2'], + ['playback_1', 'playback_2'], + ['midi_playback_1'], + ['midi_capture_1'] + ) + print(converter.get_pedalboard_info(pedalboard_path)) pedalboard = converter.convert(pedalboard_path) print(pedalboard.json) @@ -80,6 +90,8 @@ def test_discover_system_effect_midi_serial_2(self): converter = self.mod_converter pedalboard_path = self.here / Path('setBfree_ttymidi.pedalboard') + system_effect = None + ''' system_effect = SystemEffect( 'system', ['capture_1', 'capture_2'], @@ -87,6 +99,7 @@ def test_discover_system_effect_midi_serial_2(self): ['serial_midi_in'], ['serial_midi_out'] ) + ''' print(converter.get_pedalboard_info(pedalboard_path)) # Serial midi out raises error From af0cb575e365bf1806a76279eb08b2e9c54eb82e Mon Sep 17 00:00:00 2001 From: SrMouraSilva Date: Thu, 30 Nov 2017 07:52:19 -0300 Subject: [PATCH 29/31] #62 Support serial midi ports. Ignore connections errors if ModPedalboardConverter(..., ignore_errors=True) --- CHANGES | 8 +- .../model/lv2/lv2_effect_builder.py | 12 +- .../util/mod_pedalboard_converter.py | 24 +- .../EPiano_simple.ttl | 235 ++++++++++++++++++ .../EPiano_simple.pedalboard/addressings.json | 1 + .../EPiano_simple.pedalboard/manifest.ttl | 11 + .../EPiano_simple.pedalboard/screenshot.png | Bin 0 -> 55474 bytes .../EPiano_simple.pedalboard/thumbnail.png | Bin 0 -> 13672 bytes .../addressings.json | 1 + .../setBfree_simple.pedalboard/manifest.ttl | 11 + .../setBfree_simple.pedalboard/screenshot.png | Bin 0 -> 77762 bytes .../setBfree_simple.ttl | 151 +++++++++++ .../setBfree_simple.pedalboard/thumbnail.png | Bin 0 -> 17233 bytes test/util/mod_pedalboard_converter_test.py | 41 +-- 14 files changed, 466 insertions(+), 29 deletions(-) create mode 100644 test/util/data/EPiano_simple.pedalboard/EPiano_simple.ttl create mode 100644 test/util/data/EPiano_simple.pedalboard/addressings.json create mode 100644 test/util/data/EPiano_simple.pedalboard/manifest.ttl create mode 100644 test/util/data/EPiano_simple.pedalboard/screenshot.png create mode 100644 test/util/data/EPiano_simple.pedalboard/thumbnail.png create mode 100644 test/util/data/setBfree_simple.pedalboard/addressings.json create mode 100644 test/util/data/setBfree_simple.pedalboard/manifest.ttl create mode 100644 test/util/data/setBfree_simple.pedalboard/screenshot.png create mode 100644 test/util/data/setBfree_simple.pedalboard/setBfree_simple.ttl create mode 100644 test/util/data/setBfree_simple.pedalboard/thumbnail.png diff --git a/CHANGES b/CHANGES index bca5369..e97d6ea 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,4 @@ -Version 0.6.0 -- released 10/?/17 +Version 0.6.0 -- released 11/30/17 ********************************** - Add makefile. Now is possible run tests and generate docs easly (`make help`); - Improve :class:`.SystemInput` and :class:`.SystemOutputs` documentation; @@ -23,7 +23,11 @@ Version 0.6.0 -- released 10/?/17 - `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 #62`_ - Create a converter MOD pedalboard -> PluginsManager pedalboard; + - :class:`.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. .. _Issue #38: https://github.com/PedalPi/PluginsManager/issues/38 .. _Issue #57: https://github.com/PedalPi/PluginsManager/issues/57 diff --git a/pluginsmanager/model/lv2/lv2_effect_builder.py b/pluginsmanager/model/lv2/lv2_effect_builder.py index e8f530e..3c6a1ee 100644 --- a/pluginsmanager/model/lv2/lv2_effect_builder.py +++ b/pluginsmanager/model/lv2/lv2_effect_builder.py @@ -30,6 +30,7 @@ class Lv2EffectBuilder(object): in *plugins.json*. :param Path plugins_json: Plugins json path file + :param bool ignore_unsupported_plugins: Not allows instantiation of uninstalled or unrecognized audio plugins? """ plugins_json_file = os.path.dirname(os.path.abspath(__file__)) + '/plugins.json' @@ -37,7 +38,7 @@ class Lv2EffectBuilder(object): Informs the path of the `plugins.json` file. This file contains the lv2 plugins metadata info """ - def __init__(self, plugins_json=None): + def __init__(self, plugins_json=None, ignore_unsupported_plugins=True): self._plugins = {} if plugins_json is None: @@ -46,17 +47,20 @@ def __init__(self, plugins_json=None): with open(str(plugins_json)) as data_file: data = json.load(data_file) - self.reload(data) + self.reload(data, ignore_unsupported_plugins=ignore_unsupported_plugins) - def reload(self, metadata): + def reload(self, metadata, ignore_unsupported_plugins=True): """ Loads the metadata. They will be used so that it is possible to generate lv2 audio plugins. :param list metadata: lv2 audio plugins metadata + :param bool ignore_unsupported_plugins: Not allows instantiation of uninstalled or unrecognized audio plugins? """ supported_plugins = self._supported_plugins + for plugin in metadata: - if plugin['uri'] in supported_plugins: + if not ignore_unsupported_plugins \ + or plugin['uri'] in supported_plugins: self._plugins[plugin['uri']] = Lv2Plugin(plugin) @property diff --git a/pluginsmanager/util/mod_pedalboard_converter.py b/pluginsmanager/util/mod_pedalboard_converter.py index 8e8db38..97c8b6d 100644 --- a/pluginsmanager/util/mod_pedalboard_converter.py +++ b/pluginsmanager/util/mod_pedalboard_converter.py @@ -47,11 +47,13 @@ class ModPedalboardConverter(object): :param Path mod_ui_path: path that mod_ui has in the computer. :param Lv2EffectBuilder builder: Builder for generate the lv2 effects + :param bool ignore_errors: Ignore pedalboard problems like connections with undefined ports """ - def __init__(self, mod_ui_path, builder): + def __init__(self, mod_ui_path, builder, ignore_errors=False): self._load_mod_ui_libraries(mod_ui_path) self.builder = builder + self.ignore_errors = ignore_errors def _load_mod_ui_libraries(self, path): """ @@ -92,11 +94,17 @@ def convert(self, pedalboard_path, system_effect=None): pedalboard.append(effect) effects_instance[effect_data['instance']] = effect - for connection_data in info['connections']: - output_port = self._get_port(connection_data['source'], effects_instance, system_effect) - input_port = self._get_port(connection_data['target'], effects_instance, system_effect) + try: + for connection_data in info['connections']: + output_port = self._get_port(connection_data['source'], effects_instance, system_effect) + input_port = self._get_port(connection_data['target'], effects_instance, system_effect) - pedalboard.connect(output_port, input_port) + pedalboard.connect(output_port, input_port) + except PortNotFoundError as e: + if self.ignore_errors: + print("WARNING:", e) + else: + raise e return pedalboard @@ -144,20 +152,20 @@ def discover_system_effect(self, pedalboard_info): :meth:`~pluginsmanager.util.mod_pedalboard_converter.ModPedalboardConvert.get_pedalboard_info()` :return SystemEffect: SystemEffect generated based in pedalboard_info """ + # MOD swap ins and outs!!! hardware = pedalboard_info['hardware'] - # MOD swap ins and outs total_audio_outs = hardware['audio_ins'] total_audio_ins = hardware['audio_outs'] outputs = ['capture_{}'.format(i) for i in range(1, total_audio_outs+1)] inputs = ['playback_{}'.format(i) for i in range(1, total_audio_ins+1)] - midi_outputs = [ + midi_inputs = [ 'serial_midi_out' if hardware['serial_midi_out'] else midi_out['symbol'] for midi_out in hardware['midi_outs'] if midi_out['valid'] ] - midi_inputs = [ + midi_outputs = [ 'serial_midi_in' if hardware['serial_midi_in'] else midi_in['symbol'] for midi_in in hardware['midi_ins'] if midi_in['valid'] ] diff --git a/test/util/data/EPiano_simple.pedalboard/EPiano_simple.ttl b/test/util/data/EPiano_simple.pedalboard/EPiano_simple.ttl new file mode 100644 index 0000000..de2ad81 --- /dev/null +++ b/test/util/data/EPiano_simple.pedalboard/EPiano_simple.ttl @@ -0,0 +1,235 @@ +@prefix atom: . +@prefix doap: . +@prefix ingen: . +@prefix lv2: . +@prefix midi: . +@prefix mod: . +@prefix pedal: . +@prefix rdfs: . + +_:b1 + ingen:tail ; + ingen:head . + +_:b2 + ingen:tail ; + ingen:head . + +_:b3 + ingen:tail ; + ingen:head . + +_:b4 + ingen:tail ; + ingen:head . + +_:b5 + ingen:tail ; + ingen:head . + + + ingen:canvasX 983.2 ; + ingen:canvasY 376.3 ; + ingen:enabled true ; + ingen:polyphonic false ; + lv2:microVersion 3 ; + lv2:minorVersion 0 ; + mod:builderVersion 0 ; + mod:releaseNumber 0 ; + lv2:port , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + lv2:prototype ; + pedal:preset <> ; + a ingen:Block . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + a atom:AtomPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 50.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 100.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 23.285000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 7.300000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 1.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 50.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0.000000 ; + a lv2:ControlPort , + lv2:InputPort . + + + ingen:value 0 ; + a lv2:ControlPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + lv2:index 0 ; + lv2:name "Control In" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_in" ; + 4096 ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + lv2:index 1 ; + lv2:name "Control Out" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "control_out" ; + 4096 ; + a atom:AtomPort , + lv2:OutputPort . + + + lv2:index 2 ; + lv2:name "Playback 1" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "playback_1" ; + a lv2:AudioPort , + lv2:OutputPort . + + + lv2:index 3 ; + lv2:name "Playback 2" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "playback_2" ; + a lv2:AudioPort , + lv2:OutputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + lv2:index 4 ; + lv2:name "USB MIDI MIDI 1" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "midi_capture_1" ; + 4096 ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + lv2:index 5 ; + lv2:name "USB MIDI MIDI 1" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "midi_playback_1" ; + 4096 ; + a atom:AtomPort , + lv2:OutputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + lv2:index 6 ; + lv2:name "Serial MIDI In" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "serial_midi_in" ; + 4096 ; + a atom:AtomPort , + lv2:InputPort . + + + atom:bufferType atom:Sequence ; + atom:supports midi:MidiEvent ; + lv2:index 7 ; + lv2:name "Serial MIDI In" ; + lv2:portProperty lv2:connectionOptional ; + lv2:symbol "serial_midi_out" ; + 4096 ; + a atom:AtomPort , + lv2:OutputPort . + +<> + doap:name "EPiano_simple" ; + pedal:width 0 ; + pedal:height 0 ; + pedal:addressings ; + pedal:screenshot ; + pedal:thumbnail ; + ingen:polyphony 1 ; + ingen:arc _:b1 , + _:b2 , + _:b3 , + _:b4 , + _:b5 ; + ingen:block ; + lv2:port , + , + , + , + , + , + , + ; + lv2:extensionData ; + a lv2:Plugin , + ingen:Graph , + pedal:Pedalboard . diff --git a/test/util/data/EPiano_simple.pedalboard/addressings.json b/test/util/data/EPiano_simple.pedalboard/addressings.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/test/util/data/EPiano_simple.pedalboard/addressings.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/util/data/EPiano_simple.pedalboard/manifest.ttl b/test/util/data/EPiano_simple.pedalboard/manifest.ttl new file mode 100644 index 0000000..6f032a1 --- /dev/null +++ b/test/util/data/EPiano_simple.pedalboard/manifest.ttl @@ -0,0 +1,11 @@ +@prefix ingen: . +@prefix lv2: . +@prefix pedal: . +@prefix rdfs: . + + + lv2:prototype ingen:GraphPrototype ; + a lv2:Plugin , + ingen:Graph , + pedal:Pedalboard ; + rdfs:seeAlso . diff --git a/test/util/data/EPiano_simple.pedalboard/screenshot.png b/test/util/data/EPiano_simple.pedalboard/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..e4f12a7275024c6e6a1a4dc4c3f7c77145ef984d GIT binary patch literal 55474 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