Skip to content

Parse FL Studio 2024/2025 playlist items (80-byte records)#205

Open
CryptoJones wants to merge 1 commit into
demberto:masterfrom
CryptoJones:fl2025-playlist-80byte-records
Open

Parse FL Studio 2024/2025 playlist items (80-byte records)#205
CryptoJones wants to merge 1 commit into
demberto:masterfrom
CryptoJones:fl2025-playlist-80byte-records

Conversation

@CryptoJones

@CryptoJones CryptoJones commented Jul 7, 2026

Copy link
Copy Markdown

What

FL Studio 2024/2025 (21.2+ / 25.x) grew each playlist item to an 80-byte record — a 20-byte tail (_u4) after FL 21's 28-byte tail (_u3). PlaylistEvent only knew the 32- and 60-byte layouts, so FL 2024/2025 playlist events fail the size check and their clips are dropped. Fixes #200 and the same underlying cause behind #199 / #177.

The record

Full 80-byte layout, verified byte-for-byte against FL Studio 2025 (25.x) saves:

offset field notes
0 position u32, PPQ ticks
4 pattern_base u16, always 20480
6 item_index u16
8 length u32, PPQ ticks
12 track_rvidx u16, 499 − track
14 group u16
16 _u1 / item_flags / _u2 existing constants
24 start_offset, end_offset f32 ×2
32 _u3 28 bytes (FL 21)
60 _u4 20 bytes — new in FL 2024/2025

item_index selects the item type: < 20480 references a channel by iid (an audio clip if that channel's ChannelID.Type == 4, an automation clip if == 5); >= 20480 is a pattern clip (pattern_base + pattern#).

The change

  • Add _u4 gated on a new fl2025 struct param; extend SIZES to include 80.
  • Detect the record size by which fixed length divides the payload, preferring the 60-byte reading on a 60/80 common multiple, so files that parsed before are unaffected.
  • Add a synthetic-event unit test asserting the 80-byte records parse and round-trip; full suite stays green.

Known limitation (documented in-code)

A freshly placed clip is exactly 80 bytes, but clips edited in FL (fades, slices, resizes) carry extra per-clip data and grow past it — so a heavily-edited project's Playlist event can be variable-length and still not match a single fixed size. Fully general handling would need the project's FL version to disambiguate; this PR fixes the common (fresh / programmatically-written) case without regressing anything.

How this came up

I hit this building FL-Studio-MCP-Server — an MCP server that lets Claude Code drive FL Studio and generate/edit .flp projects, with PyFLP powering its offline route. Writing FL 2025 audio-clip arrangements is what surfaced the 80-byte record, so the parse fix belongs upstream. Thanks for PyFLP — it's a joy to build on. 🙏

🤖 Generated with Claude Code

Proudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/

FL 2024/2025 (21.2+ / 25.x) grew each playlist item to an 80-byte record: a
20-byte tail (_u4) after FL 21's 28-byte tail (_u3). PlaylistEvent only knew the
32- and 60-byte layouts, so these events failed the size check and their clips
were dropped (demberto#177, demberto#199, demberto#200).

Add the _u4 block gated on a `fl2025` param, extend SIZES to include 80, and
detect it by the fixed size that divides the payload — preferring the 60-byte
reading on a 60/80 common multiple so files that parsed before are unaffected.
The record layout was verified byte-for-byte against FL Studio 2025 saves, and
a synthetic-event test asserts the 80-byte records parse and round-trip.

Known limitation (documented in-code): clips edited in FL grow past 80 bytes, so
a heavily-edited project's Playlist event can be variable-length and still not
match a single fixed size.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐞 Missing playlist data in FL Studio 2025 project files

1 participant