Skip to content

Commit

Permalink
Merge pull request #16 from PedalPi/issue-15-mod-host-parameter
Browse files Browse the repository at this point in the history
Issue 15 mod host parameter
  • Loading branch information
SrMouraSilva committed May 7, 2017
2 parents a409628 + 6197e99 commit 502ccf2
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 52 deletions.
8 changes: 7 additions & 1 deletion CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version 0.2.1 -- released 05/07/17
=================================
- Refactor persistence_decoder: Using now design pattern;
- Fix mod-host: Bug when changing value of a parameter from a plugin;
- observable_list: Add method ``.pop()``.

Version 0.2.0 -- released 3/31/17
=================================
- Initial release
- Initial release
8 changes: 5 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ PedalPi - PluginsManager

.. image:: https://codecov.io/gh/PedalPi/PluginsManager/branch/master/graph/badge.svg
:target: https://codecov.io/gh/PedalPi/PluginsManager
:alt: codecov
:alt: Code coverage

.. image:: https://landscape.io/github/PedalPi/PluginsManager/master/landscape.svg?style=flat
:target: https://landscape.io/github/PedalPi/PluginsManager/master
Expand All @@ -29,10 +29,12 @@ Pythonic management of LV2 audio plugins with `mod-host`_.
https://github.com/PedalPi/PluginsManager

**Python Package Index:**
https://github.com/PedalPi/PluginsManager/tarball/master#egg=PedalPi-PluginsManager
https://pypi.org/project/PedalPi-PluginsManager

**License:**
Open source license will be selected
`Apache License 2.0`_

.. _Apache License 2.0: https://github.com/PedalPi/PluginsManager/blob/master/LICENSE

Example
-------
Expand Down
4 changes: 2 additions & 2 deletions pluginsmanager/mod_host/protocol_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ def param_set(param):
:param Lv2Param param: Parameter that will be updated your value
"""
instance = param.effect
instance = param.effect.instance

return 'param_set {} {} {}'.format(instance, param.symbol, param.value)

Expand All @@ -225,7 +225,7 @@ def param_get(param):
:param Lv2Param param: Parameter that will be get your current value
"""
instance = param.effect
instance = param.effect.instance

return 'param_get {} {}'.format(instance, param.symbol)

Expand Down
13 changes: 13 additions & 0 deletions pluginsmanager/util/builder/__init__.py
Original file line number Diff line number Diff line change
@@ -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.
46 changes: 46 additions & 0 deletions pluginsmanager/util/builder/builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# 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 AudioPortBuilder(metaclass=ABCMeta):
"""
Extracts the inputs and outputs of an effect defined in a json.
Use it to get the `AudioPorts`_ (inputs and outputs) to build a connection correctly.
.. _AudioPorts: http://lv2plug.in/ns/lv2core/#AudioPort
"""

@abstractmethod
def build_input(self, json):
"""
:return Input: Input of an effect defined in json
"""
pass

@abstractmethod
def build_output(self, json):
"""
:return Output: Input of an effect defined in json
"""
pass


class EffectBuilder(metaclass=ABCMeta):

@abstractmethod
def build(self, json):
pass
54 changes: 54 additions & 0 deletions pluginsmanager/util/builder/lv2_json_builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# 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.util.builder.builder import AudioPortBuilder, EffectBuilder


class Lv2AudioPortBuilder(AudioPortBuilder):
"""
Extracts the :class:`Lv2Input`s and :class:`Lv2Outputs`s of an :class:`Lv2Effect` defined in a json.
"""

def __init__(self, pedalboard):
self.pedalboard = pedalboard

def build_input(self, json):
symbol = json['symbol']
return self.get_effect(json).inputs[symbol]

def build_output(self, json):
symbol = json['symbol']
return self.get_effect(json).outputs[symbol]

def get_effect(self, json):
effect_index = json['effect']
return self.pedalboard.effects[effect_index]


class Lv2EffectBuilder(EffectBuilder):
def __init__(self, lv2_effect_builder):
"""
:param model.lv2.lv2_effect_builder.Lv2EffectBuilder lv2_effect_builder:
"""
self.builder = lv2_effect_builder

def build(self, json):
effect = self.builder.build(json['plugin'])

for param, param_json in zip(effect.params, json['params']):
param.value = param_json['value']

effect.active = json['active']

return effect

32 changes: 32 additions & 0 deletions pluginsmanager/util/builder/system_json_builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# 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.util.builder.builder import AudioPortBuilder


class SystemAudioPortBuilder(AudioPortBuilder):
"""
Extracts the :class:`SystemInput`s and :class:`SystemOutputs`s of an :class:`SystemEffect` defined in a json.
"""

def __init__(self, system_effect):
self.system_effect = system_effect

def build_input(self, json):
symbol = json['symbol']
return self.system_effect.inputs[symbol]

def build_output(self, json):
symbol = json['symbol']
return self.system_effect.outputs[symbol]
17 changes: 17 additions & 0 deletions pluginsmanager/util/observable_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,23 @@ def insert(self, index, x):
self._list.insert(index, x)
self.observer(UpdateType.CREATED, x, index)

def pop(self, index=None):
"""
Remove the item at the given position in the list, and return it. If no index is specified,
a.pop() removes and returns the last item in the list.
:param int index: element index that will be removed
:return: item removed
"""
if index is None:
index = len(self._list) - 1

item = self[index]
del self[index]

return item

def __len__(self):
return len(self._list)

Expand Down
67 changes: 21 additions & 46 deletions pluginsmanager/util/persistence_decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
from pluginsmanager.model.pedalboard import Pedalboard
from pluginsmanager.model.connection import Connection

from pluginsmanager.model.lv2.lv2_effect_builder import Lv2EffectBuilder
from pluginsmanager.model.lv2.lv2_effect_builder import Lv2EffectBuilder as Lv2LilvEffectBuilder
from pluginsmanager.util.builder.lv2_json_builder import Lv2AudioPortBuilder, Lv2EffectBuilder
from pluginsmanager.util.builder.system_json_builder import SystemAudioPortBuilder


class PersistenceDecoderError(Exception):
Expand Down Expand Up @@ -78,23 +80,18 @@ class EffectReader(Reader):

def __init__(self, system_effect):
super(EffectReader, self).__init__(system_effect)
self.builder = Lv2EffectBuilder()
self.builder = Lv2LilvEffectBuilder()

def read(self, json):
if json['technology'] == 'lv2':
return self.read_lv2(json)
return self.generate_builder(json).build(json)

raise PersistenceDecoderError('Unknown effect technology: ' + json['technology'])
def generate_builder(self, json):
technology = json['technology']

def read_lv2(self, json):
effect = self.builder.build(json['plugin'])

for param, param_json in zip(effect.params, json['params']):
param.value = param_json['value']

effect.active = json['active']

return effect
if technology == 'lv2':
return Lv2EffectBuilder(self.builder)
else:
raise PersistenceDecoderError('Unknown effect technology: ' + technology)


class ConnectionReader(Reader):
Expand All @@ -104,38 +101,16 @@ def __init__(self, pedalboard, system_effect):
self.pedalboard = pedalboard

def read(self, json):
if 'effect' in json['output']:
connection_output = self.read_output(json['output'])
else:
connection_output = self.read_system_output(json['output'])

if 'effect' in json['input']:
connection_input = self.read_input(json['input'])
else:
connection_input = self.read_system_input(json['input'])
connection_output = self.generate_builder(json, 'output').build_output(json['output'])
connection_input = self.generate_builder(json, 'input').build_input(json['input'])

return Connection(connection_output, connection_input)

def read_output(self, json):
effect_index = json['effect']
effect = self.pedalboard.effects[effect_index]

return self.generic_system_output(effect, json['symbol'])

def read_input(self, json):
effect_index = json['effect']
effect = self.pedalboard.effects[effect_index]

return self.generic_system_input(effect, json['symbol'])

def read_system_output(self, json):
return self.generic_system_output(self.system_effect, json['symbol'])

def read_system_input(self, json):
return self.generic_system_input(self.system_effect, json['symbol'])

def generic_system_output(self, effect, symbol):
return effect.outputs[symbol]

def generic_system_input(self, effect, symbol):
return effect.inputs[symbol]
def generate_builder(self, json, audio_port):
"""
:return AudioPortBuilder
"""
if 'effect' in json[audio_port]:
return Lv2AudioPortBuilder(self.pedalboard)
else:
return SystemAudioPortBuilder(self.system_effect)
40 changes: 40 additions & 0 deletions test/util/observable_list_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,46 @@ def test_remove(self):

lista.observer.assert_called_with(UpdateType.DELETED, '2', 1)

def test_pop_empty_parameter(self):
lista = ObservableList()
a = 'a'
b = 'b'
c = 'c'
d = 'd'

lista.append(a)
lista.append(b)
lista.append(c)
lista.append(d)

lista.observer = MagicMock()

self.assertEqual(d, lista.pop())
self.assertEqual(3, len(lista))

lista.observer.assert_any_call(UpdateType.DELETED, d, len(lista))

def test_pop_with_parameter(self):
lista = ObservableList()
a = 'a'
b = 'b'
c = 'c'
d = 'd'

lista.append(a)
lista.append(b)
lista.append(c)
lista.append(d)

lista.observer = MagicMock()

b_index = 1

self.assertEqual(b, lista.pop(b_index))
self.assertEqual(3, len(lista))

lista.observer.assert_any_call(UpdateType.DELETED, b, b_index)

def test__setitem__(self):
lista = ObservableList()

Expand Down

0 comments on commit 502ccf2

Please sign in to comment.