A pattern’s notes are stored in its pattern notes event (224) as a run of 24-byte records, one per note, with nothing between them. The number of notes is the event’s size divided by 24. Controller changes are stored the same way in event 223, as 12-byte records.
The 24-byte layout below is the one PyFLP reads, and it has been checked against FL Studio 20 files. PyFLP applies it to every version. LMMS’s old importer, removed after LMMS 1.0, reads 20-byte records from the same event instead, with pan and velocity at offsets 16 and 17. Which size versions 11.5 to 12 write is not confirmed, so check the event size: a size divisible by 24 but not by 20 settles it.
00000000 00 00 00 00 00 00 00 00 60 00 00 00 3C 00 00 00 ........`...<...
00000010 78 00 40 00 40 64 80 80 x.@.@d..
Note record
Every number is little-endian. Positions and lengths are in ticks; the PPQ in the header says how many ticks make one beat.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 4 | u32 | position | Where the note starts, in ticks from the start of the pattern. |
| 4 | 2 | u16 | flags | Note flags. Bit 3 (value 8) marks a slide note. Other bits are unknown. |
| 6 | 2 | u16 | channel | The channel in the rack that plays the note. |
| 8 | 4 | u32 | length | How long the note lasts, in ticks. |
| 12 | 2 | u16 | key | The note number. 60 is middle C. |
| 14 | 2 | u16 | group | The note group, which ties notes together for editing. |
| 16 | 1 | u8 | fine_pitch | Fine pitch of the note, from FL Studio 3.3. |
| 17 | 1 | byte | unknown | Unknown. |
| 18 | 1 | u8 | release | Release. |
| 19 | 1 | u8 | midi_channel | The MIDI channel. Its use changed in FL Studio 6.0.1. |
| 20 | 1 | u8 | pan | Panning of the note. |
| 21 | 1 | u8 | velocity | How hard the note is played. |
| 22 | 1 | u8 | mod_x | Modulation X. |
| 23 | 1 | u8 | mod_y | Modulation Y. |
Controller record
Each record in a pattern controllers event (223) is one controller change at one point in the pattern.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 4 | u32 | position | Where the change happens, in ticks. |
| 4 | 1 | byte | unknown | Unknown. |
| 5 | 1 | byte | unknown | Unknown. |
| 6 | 1 | u8 | channel | The channel the change applies to. |
| 7 | 1 | u8 | flags | Flags. Their meaning is unknown. |
| 8 | 4 | f32 | value | The controller value, as a 32-bit float. |