Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/reference/plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Effects

.. autoclass:: FruityBalance
:members:
.. autoclass:: FruityBloodOverdrive
:members:
.. autoclass:: FruityFastDist
:members:
.. autoclass:: FruityNotebook2
Expand Down
3 changes: 3 additions & 0 deletions pyflp/mixer.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
from .plugin import (
FruityBalance,
FruityBalanceEvent,
FruityBloodOverdrive,
FruityBloodOverdriveEvent,
FruityFastDist,
FruityFastDistEvent,
FruityNotebook2,
Expand Down Expand Up @@ -385,6 +387,7 @@ def __index__(self) -> int:
VSTPluginEvent: VSTPlugin,
FruityBalanceEvent: FruityBalance,
FruityFastDistEvent: FruityFastDist,
FruityBloodOverdriveEvent: FruityBloodOverdrive,
FruityNotebook2Event: FruityNotebook2,
FruitySendEvent: FruitySend,
FruitySoftClipperEvent: FruitySoftClipper,
Expand Down
96 changes: 96 additions & 0 deletions pyflp/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
__all__ = [
"BooBass",
"FruityBalance",
"FruityBloodOverdrive",
"FruityFastDist",
"FruityFastDistKind",
"FruityNotebook2",
Expand All @@ -67,6 +68,23 @@ class _FruityBalanceStruct(StructBase):
PROPS = {"pan": "I", "volume": "I"}


class _FruityBloodOverdriveStruct(StructBase):
PROPS = dict.fromkeys(
(
"plugin_marker",
"pre_band",
"color",
"pre_amp",
"x100",
"post_filter",
"post_gain",
"_u1",
"_u2",
),
"I",
)


Copy link
Contributor Author

@ttaschke ttaschke Sep 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To support both the recent and the old version of BloodOverdrive two Structs would be used here.

class _FruityBloodOverdriveStruct(StructBase)
->
class _FruityBloodOverdriveNewStruct(StructBase)

class _FruityBloodOverdriveOldStruct(StructBase):
    PROPS = dict.fromkeys(
        (
            ...
            "pre_band",
            "color",
            "pre_amp",
            "x100",
            "post_filter",
            "post_gain",
            ...
        ),
        "I",
    )

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't think about how big the names would get, use _FruityBloodOverdriveStruct2 probably?

class _FruityFastDistStruct(StructBase):
PROPS = dict.fromkeys(("pre", "threshold", "kind", "mix", "post"), "I")

Expand Down Expand Up @@ -113,6 +131,10 @@ class FruityBalanceEvent(StructEventBase):
STRUCT = _FruityBalanceStruct


class FruityBloodOverdriveEvent(StructEventBase):
STRUCT = _FruityBloodOverdriveStruct


Copy link
Contributor Author

@ttaschke ttaschke Sep 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The BO event would set both versions of the struct, so NativePluginEvent can use the one it decides to be appropriate.

class FruityBloodOverdriveEvent(NativePluginEvent):
    struct_old = _FruityBloodOverdriveOldStruct
    struct_new = _FruityBloodOverdriveNewStruct

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NativePluginEvent would look at the events stream and decide which plugin version it encountered.

class NativePluginEvent(StructEventBase)

    # check the version of the plugin based on stream size and/or plugin marker in the first 4 bytes?
   
    # set the appropriate struct

Copy link
Owner

@demberto demberto Sep 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to consider whether I should just modify existing StructEventBase logic to accomodate multiple structs, since its very possible that the functionality NativePluginEvent might be used by other events

class FruityFastDistEvent(StructEventBase):
STRUCT = _FruityFastDistStruct

Expand Down Expand Up @@ -450,6 +472,80 @@ class FruityBalance(_PluginBase[FruityBalanceEvent], _IPlugin, ModelReprMixin):
"""


class FruityBloodOverdrive(
_PluginBase[FruityBloodOverdriveEvent], _IPlugin, ModelReprMixin
):
"""![]()""" # noqa

INTERNAL_NAME = "Fruity Blood Overdrive"

plugin_marker = _PluginDataProp[int]() # 3
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to expose an internal parameter in the public interface.

I think this can be better exposed via a normal boolean is_old property.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was my workaround to get it to work with StructEventBase.
The proper way would probably be to read the first 4 bytes self._stream.read_I() and then set is_old in NativePluginEvent?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe, it can be added as a property in _PluginBase itself


pre_band = _PluginDataProp[int]()
"""Linear.

| Type | Value | Representation |
|---------|-------|----------------|
| Min | 0 | 0.0000 |
| Max | 10000 | 1.0000 |
| Default | 0 | 0.0000 |
"""

color = _PluginDataProp[int]()
"""Linear.

| Type | Value | Representation |
|---------|-------|----------------|
| Min | 0 | 0.0000 |
| Max | 10000 | 1.0000 |
| Default | 5000 | 0.5000 |

"""

pre_amp = _PluginDataProp[int]()
"""Linear.

| Type | Value | Representation |
|---------|-------|----------------|
| Min | 0 | 0.0000 |
| Max | 10000 | 1.0000 |
| Default | 0 | 0.0000 |
"""

x100 = _PluginDataProp[bool]()
"""Boolean.

| Type | Value | Representation |
|---------|-------|----------------|
| Off | 0 | Off |
| On | 1 | On |
| Default | 0 | Off |
"""

post_filter = _PluginDataProp[int]()
"""Linear.

| Type | Value | Representation |
|---------|-------|----------------|
| Min | 0 | 0.0000 |
| Max | 10000 | 1.0000 |
| Default | 0 | 0.0000 |
"""

post_gain = _PluginDataProp[int]()
"""Linear.

| Type | Value | Representation |
|---------|-------|----------------|
| Min | 0 | -1.0000 |
| Max | 10000 | 0.0000 |
| Default | 10000 | 0.0000 |
"""

_u1 = _PluginDataProp[int]()
_u2 = _PluginDataProp[int]()


@enum.unique
class FruityFastDistKind(enum.IntEnum):
"""Used by :attr:`FruityFastDist.kind`."""
Expand Down
14 changes: 13 additions & 1 deletion tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from pyflp.plugin import (
AnyPlugin,
FruityBalance,
FruityBloodOverdrive,
FruityFastDist,
FruityFastDistKind,
FruitySend,
Expand All @@ -23,7 +24,7 @@

@pytest.fixture(scope="session")
def plugins(inserts: tuple[Insert, ...]):
return [slot.plugin for slot in inserts[19]][:7]
return [slot.plugin for slot in inserts[19]][:8]


def test_plugin_types(plugins: tuple[AnyPlugin, ...]):
Expand All @@ -35,6 +36,7 @@ def test_plugin_types(plugins: tuple[AnyPlugin, ...]):
FruityStereoEnhancer,
Soundgoodizer,
VSTPlugin,
FruityBloodOverdrive,
]


Expand Down Expand Up @@ -91,3 +93,13 @@ def test_vst_plugin(plugins: tuple[AnyPlugin, ...]):

with pytest.raises(KeyError):
ott.fourcc


def test_fruity_blood_overdrive(plugins: tuple[AnyPlugin, ...]):
fruity_blood_overdrive = cast(FruityBloodOverdrive, plugins[7])
print(plugins[7].color)
assert fruity_blood_overdrive.pre_band == 0
assert fruity_blood_overdrive.color == 5000
assert fruity_blood_overdrive.pre_amp == 0
assert fruity_blood_overdrive.x100 == 0
assert fruity_blood_overdrive.post_filter == 0