Skip to content

Commit

Permalink
feat: closes #24
Browse files Browse the repository at this point in the history
  • Loading branch information
demberto committed Sep 21, 2022
1 parent 5f98d45 commit 8c363ab
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 9 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `Note.slide` which indicates whether a note is a sliding note.
- Plugin wrapper properties to docs.
- A user guide section in docs.
- `Sampler.content`, `Layer.random` & `Layer.crossfade` [#24].

### Changed

Expand All @@ -45,11 +46,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `Slot.plugin` wasn't working at all (events, properties, repr) [#53].
- `FruitySend.send_to` was interepreted incorrectly.
- `Instrument.plugin` and `Slot.plugin` setter.
- `Playback.use_loop_points`.

### Removed

- `Arrangements.height`.

[#24]: https://github.com/demberto/PyFLP/issues/24
[#28]: https://github.com/demberto/PyFLP/issues/28
[#32]: https://github.com/demberto/PyFLP/issues/32
[#33]: https://github.com/demberto/PyFLP/issues/33
Expand Down
Binary file added docs/img/channel/content.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 23 additions & 2 deletions pyflp/channel.py
Expand Up @@ -181,7 +181,8 @@ class ChannelID(EventEnum):
_VolByte = (2, U8Event)
_PanByte = (3, U8Event)
Zipped = (15, BoolEvent)
UsesLoopPoints = (19, BoolEvent)
# _19 = (19, BoolEvent)
PingPongLoop = (20, BoolEvent)
Type = (21, U8Event)
RoutedTo = (22, I8Event)
# FXProperties = 27
Expand Down Expand Up @@ -322,6 +323,14 @@ class _LayerFlags(enum.IntFlag):
Crossfade = 1 << 1


class _SamplerFlags(enum.IntFlag):
Resample = 1 << 0
LoadRegions = 1 << 1
LoadSliceMarkers = 1 << 2
UsesLoopPoints = 1 << 3
KeepOnDisk = 1 << 8


class DisplayGroup(MultiEventModel, ModelReprMixin):
def __repr__(self):
if self.name is None:
Expand Down Expand Up @@ -737,6 +746,16 @@ class TimeStretching(MultiEventModel, ModelReprMixin):
time = EventProp[float](ChannelID.StretchTime)


class Content(MultiEventModel, ModelReprMixin):
"""Used by :class:`Sampler`."""

# declick_mode: enum
keep_on_disk = FlagProp(_SamplerFlags.KeepOnDisk, ChannelID.SamplerFlags)
load_regions = FlagProp(_SamplerFlags.LoadRegions, ChannelID.SamplerFlags)
load_slices = FlagProp(_SamplerFlags.LoadSliceMarkers, ChannelID.SamplerFlags)
resample = FlagProp(_SamplerFlags.Resample, ChannelID.SamplerFlags)


class Channel(MultiEventModel, SupportsIndex):
"""Represents a channel in the channel rack."""

Expand Down Expand Up @@ -906,7 +925,8 @@ def __len__(self):
"""Returns the number of channels whose parent this layer is."""
return len(self._events.get(ChannelID.Children, []))

flags = EventProp[int](ChannelID.LayerFlags) # TODO
crossfade = FlagProp(_LayerFlags.Crossfade, ChannelID.LayerFlags)
random = FlagProp(_LayerFlags.Random, ChannelID.LayerFlags)


class _SamplerInstrument(Channel):
Expand Down Expand Up @@ -952,6 +972,7 @@ def __repr__(self):
au_sample_rate = EventProp[int](ChannelID.AUSampleRate)
"""AU-format sample specific."""

content = NestedProp(Content, ChannelID.SamplerFlags)
cut_group = EventProp[Tuple[int, int]](ChannelID.CutGroup)
"""Cut group in the form of (Cut self, cut by)."""

Expand Down
Binary file modified tests/assets/FL 20.8.4.flp
Binary file not shown.
26 changes: 19 additions & 7 deletions tests/test_channel.py
Expand Up @@ -5,7 +5,7 @@
import colour
import pytest

from pyflp.channel import Channel, ChannelRack, Sampler
from pyflp.channel import Channel, ChannelRack, Layer, Sampler


def test_channels(rack: ChannelRack):
Expand All @@ -22,12 +22,13 @@ def channels(rack: ChannelRack):


@pytest.fixture(scope="session")
def samplers(channels: tuple[Channel, ...]):
samplers: list[Sampler] = []
for channel in channels:
if isinstance(channel, Sampler):
samplers.append(channel)
return samplers
def layer(rack: ChannelRack):
return tuple(rack.layers)[0]


@pytest.fixture(scope="session")
def samplers(rack: ChannelRack):
return [s for s in rack.samplers]


def test_channel_name(channels: tuple[Channel]):
Expand Down Expand Up @@ -64,6 +65,9 @@ def test_channel_color(channels: tuple[Channel, ...]):
assert channel.color == colour.Color("#5C656A")


# TODO: Test `Channel.content`


def test_channel_enabled(channels: tuple[Channel, ...]):
for ch in channels:
assert not ch.enabled if ch.name == "Disabled" else ch.enabled
Expand All @@ -74,6 +78,14 @@ def test_channel_icon(channels: tuple[Channel, ...]):
assert ch.icon == 116 if ch.name == "Iconified" else not ch.icon


def test_layer_crossfade(layer: Layer):
assert layer.crossfade


def test_layer_random(layer: Layer):
assert layer.random


def test_sampler_path(samplers: tuple[Sampler, ...]):
for sampler in samplers:
if sampler.name == "22in Kick":
Expand Down

0 comments on commit 8c363ab

Please sign in to comment.