Skip to content

🐞 ChannelType is not what it seems #40

@demberto

Description

@demberto

PyFLP/pyflp/channel.py

Lines 311 to 322 in 816c78d

class ChannelType(enum.IntEnum): # cuz Type would be a super generic name
"""An internal marker used to indicate the type of a channel."""
Sampler = 0
"""Used exclusively for the inbuilt Sampler."""
Native = 2
"""Used by audio clips and other native FL Studio synths."""
Layer = 3 # 3.4.0+
Instrument = 4
Automation = 5 # 5.0+

Tests

This code was run with the provided test FLP:

import pyflp
from pyflp.channel import ChannelID, ChannelType

project = pyflp.parse("./tests/assets/FL 20.8.4.flp")

for channel in project.channels:
    print(f"{ChannelType(channel.events_asdict()[ChannelID.Type][0].value).name} - {channel.name}")

Output:

Native - BooBass
Sampler - Instrument track
Layer - Layer
Sampler - Sampler
Instrument - Colored
Automation - Automation Clip
Native - VST2
Instrument - Audio Clip
Native - MIDI Out
Native - Fruit Kick
Native - Plucked!
Instrument - 22in Kick

🙄 Not quite what I expected.

Observations

  • Empty Audio Clip instances are Instrument (Colored, Audio Clip and 22in Kick).

    image

  • 3rd party plugin Sylenth1 (named VST2) is surprisingly of type Native.

    image

Solutions

Channel type detection (Sampler, Instrument or Native) should not be done solely based upon ChannelID.Type event

PyFLP/pyflp/channel.py

Lines 1011 to 1039 in 816c78d

def __iter__(self): # pylint: disable=too-complex
ch_dict: dict[int, Channel] = {}
events: DefaultDict[int, list[AnyEvent]] = collections.defaultdict(list)
cur_ch_events = []
for event in self._events_tuple:
if event.id == ChannelID.New:
cur_ch_events = events[event.value]
if event.id not in RackID:
cur_ch_events.append(event)
for iid, ch_events in events.items():
ct = None
for event in ch_events:
if event.id == ChannelID.Type:
if event.value == ChannelType.Automation:
ct = Automation
elif event.value == ChannelType.Instrument:
ct = Instrument
elif event.value == ChannelType.Layer:
ct = Layer
elif event.value == ChannelType.Sampler:
ct = Sampler
else:
ct = Channel
if ct is not None:
cur_ch = ch_dict[iid] = ct(*ch_events, channels=ch_dict)
yield cur_ch

Feels like I am fixing IL's bugs now 😛

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingchannel-generalProperties affecting all channel types

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions