Skip to content

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

0 watching

Forks

Repository files navigation

Rust DAW compatibility rebuild

Parity progress — 2026-11-02

Early prototype; not yet suitable as a full FL Studio replacement. The parity roadmap is an unweighted checklist: partial items cover only their stated subsets, and a completed small item does not count as the same amount of work as a complete subsystem.

  • Working foundations: lossless FLP parsing and round-trip writing, selected project and note edits, saved manual Mixer track PDC offset editing, 25.x Mixer insert recognition, MIDI import and partial export, and cross-platform CI packaging.
  • Partial runtime and editing: early Playlist, Channel Rack, Piano roll, Mixer, plug-in, and audio views; the Piano roll includes a saved Grouping switch and repeatable Magic Lasso selection; Windows shared and exclusive audio; playback and a first combined WAV render for supported audio clips, Sampler notes, and mapped installed VST3 instruments. Loaded VST3 instances support a machine-local manual PDC offset per class UID, added to reported latency. Supported Mixer direct and complete send paths include live fader, pan, stereo-width, phase, and channel-swap smoothing. Direct-to-Master sources smooth live mute changes, and direct plus complete send-routed paths smooth live solo changes; route and parameter mappings remain provisional.
  • Major parity gaps: native verification of Mixer field, route, and sidechain mappings (see the render comparison procedure), unsupported Mixer route shapes and sidechain cases, broad automation parity, VST compatibility and state write-back, full FL Studio window/control behavior, and verified compatibility across FL Studio versions.

See the roadmap for subsystem-level status and evidence.

This is a clean-room Rust project started from the FL Studio 26.1.6.5639 installation supplied with the workspace. It is an independent rebuild; it does not load, patch, or link against the installed FL Studio executable or engine. The end goal is to open and modify any FL Studio project with backwards compatibility, matching controls, windows, and editing behavior, installed plug-in hosting, playback, and rendering. The current code contains the lossless file-format core and the first desktop editing shell; it is still far from full parity.

The first milestone is deliberately a compatibility foundation: inspect FL Studio project (.flp) files and preserve every event, including data the reader does not understand. The reader identifies common .fst header variants for channel, native plug-in, VST generator/effect, and Mixer insert states; plugin payloads are still opaque. FL Studio's own documentation describes .flp as its native project format, .fst as a state/preset format, and ZIP project packages as projects bundled with referenced sample files. The installed projects and presets provide a local compatibility corpus.

The desktop app also opens standard .zip project packages, extracts their regular files to a temporary workspace for relative sample lookup, and writes edited FLP data back while retaining the other files. Saving a plain .flp as .zip bundles resolvable Sampler and Audio Clip samples under Samples/; missing sample references remain external and are reported.

Current milestone

flp-rebuild can read the FLP chunk envelope and event stream, report header information, event counts, channel summaries, and a small set of project fields, and write a lossless round-trip copy. preset-info classifies known FST state-file variants and reports their decoded structure. Unknown event payloads and trailing bytes are retained exactly. The command-line surface is:

flp-rebuild info <file.flp>
flp-rebuild preset-info <file.fst>
flp-rebuild project-info <file.flp>
flp-rebuild project-settings <file.flp>
flp-rebuild global-swing <file.flp>
flp-rebuild midi-info <file.mid>
flp-rebuild midi-events <file.mid> <track> [start] [count]
flp-rebuild export-midi-pattern <project.flp> <output.mid> <pattern-id> [stored|channels] [format0|format1]
flp-rebuild export-midi-cc <project.flp> <output.mid> <pattern-id> <raw-channel> <raw-flags> <cc-0..127> <midi-channel-1..16> [format0|format1]
flp-rebuild export-midi-song <project.flp> <output.mid> <arrangement-id> [stored|channels] [format0|format1]
flp-rebuild export-midi-song-cc <project.flp> <output.mid> <arrangement-id> <raw-channel> <raw-flags> <cc-0..127> <midi-channel-1..16> [format0|format1]
flp-rebuild scan <directory>
flp-rebuild plugin-scan
flp-rebuild vst2-info <plugin-file-or-bundle>
flp-rebuild render-vst2-note <plugin-file-or-bundle> <output.wav> <note-0..127> <velocity-1..127> <note-seconds> <tail-seconds> [sample-rate]
flp-rebuild render-audio-vst2 <input-audio> <effect-file-or-bundle> <output.wav> [tail-seconds]
flp-rebuild render-pattern-vst2 <project.flp> <pattern-id> <channel-id> <plugin-file-or-bundle> <output.wav> [tail-seconds]
flp-rebuild sample-paths <file.flp>
flp-rebuild audio-info <audio-file>
flp-rebuild render-audio-clips <project.flp> <output.wav> [arrangement-id]
flp-rebuild time-markers <file.flp>
flp-rebuild render-pattern-vst3 <project.flp> <pattern-id> <channel-id> <plugin.vst3> <output.{wav|flac|ogg|mp3}> [tail-seconds]
flp-rebuild render-audio-vst3 <input-audio> <effect.vst3> <output.{wav|flac|ogg|mp3}> [class-uid|-] [tail-seconds]
flp-rebuild render-audio-vst2 <input-audio> <effect-file-or-bundle> <output.wav> [tail-seconds]
flp-rebuild plugin-state-preview <file.flp> <channel-id>
flp-rebuild vst2-state-probe <plugin-file-or-bundle> <file.flp> <channel-id>
flp-rebuild vst3-state-probe <plugin.vst3> <file.flp> <channel-id>
flp-rebuild apply-native-channel-plugin-state-preset <input.flp> <output.flp> <native-channel-id> <preset.fst>
flp-rebuild export-native-channel-plugin-state-preset <input.flp> <output.fst> <native-channel-id>
flp-rebuild export-native-mixer-effect-state-preset <input.flp> <output.fst> <insert-ordinal> <slot-index>
flp-rebuild channels <file.flp>
flp-rebuild plugin-states <file.flp>
flp-rebuild channel-events <file.flp> <channel-id>
flp-rebuild mixer <file.flp>
flp-rebuild set-mixer-insert-manual-pdc <input.flp> <output.flp> <insert-ordinal> <offset-ms>
flp-rebuild set-mixer-parameter-record-value <input.flp> <output.flp> <event-index> <record-index> <signed-value>
flp-rebuild set-mixer-eq-parameter-raw <input.flp> <output.flp> <insert-ordinal> <low-gain|mid-gain|high-gain|low-frequency|mid-frequency|high-frequency|low-q|mid-q|high-q> <raw-value>
flp-rebuild set-mixer-effect-slot-enabled <input.flp> <output.flp> <insert-ordinal> <slot-index> <0|1>
flp-rebuild set-mixer-effect-slot-mix-raw <input.flp> <output.flp> <insert-ordinal> <slot-index> <-6400..6400>
flp-rebuild rename-mixer-insert <input.flp> <output.flp> <insert-ordinal> <name>
flp-rebuild set-mixer-insert-flag <input.flp> <output.flp> <insert-ordinal> <enabled|soloed|polarity-reversed|swap-left-right|effects-enabled> <0|1>
flp-rebuild set-mixer-routing-flag <input.flp> <output.flp> <event-index> <flag-byte-index> <0|1>
flp-rebuild automation <file.flp>
flp-rebuild automation-targets <file.flp>
flp-rebuild time-markers <file.flp>
flp-rebuild patterns <file.flp>
flp-rebuild pattern-controllers <file.flp> <pattern-id>
flp-rebuild edit-pattern-controller <input.flp> <output.flp> <pattern-id> <controller-index> <position-ticks|-> <value|->
flp-rebuild duplicate-pattern-controller <input.flp> <output.flp> <pattern-id> <template-index> <position-ticks> <value>
flp-rebuild delete-pattern-controller <input.flp> <output.flp> <pattern-id> <controller-index>
flp-rebuild draw-pattern-controller-points <input.flp> <output.flp> <pattern-id> <channel> <flags> <tick:value,...>
flp-rebuild linearize-pattern-controllers <input.flp> <output.flp> <pattern-id> <channel> <flags> <start-tick> <end-tick>
flp-rebuild spline-pattern-controllers <input.flp> <output.flp> <pattern-id> <channel> <flags> <start-tick> <end-tick>
flp-rebuild delete-pattern-controller-range <input.flp> <output.flp> <pattern-id> <channel> <flags> <start-tick> <end-tick>
flp-rebuild playlist <file.flp> [start] [count]
flp-rebuild diff-playlist-clip <before.flp> <after.flp> <arrangement-id> <clip-index>
flp-rebuild notes <file.flp> <pattern-id> [start] [count]
flp-rebuild events <file.flp> [start] [count]
flp-rebuild extract-event <file.flp> <index> <output.bin>
flp-rebuild roundtrip <input.flp> <output.flp>
flp-rebuild set-tempo <input.flp> <output.flp> <bpm>
flp-rebuild create-pattern <input.flp> <output.flp>
flp-rebuild duplicate-pattern <input.flp> <output.flp> <pattern-id>
flp-rebuild rename-pattern <input.flp> <output.flp> <pattern-id> <name>
flp-rebuild delete-pattern <input.flp> <output.flp> <pattern-id>
flp-rebuild set-project-info <input.flp> <output.flp> <title|-> <author|-> <genre|-> <comments|-> <web-link|->
flp-rebuild set-project-settings <input.flp> <output.flp> <play-truncated:0|1|-> <fast-declick:0|1|-> [pan-law-raw|-]
flp-rebuild set-project-master-pitch <input.flp> <output.flp> <cents:-1200..1200>
flp-rebuild set-project-time-signature <input.flp> <output.flp> <numerator> <denominator>
flp-rebuild set-global-swing <input.flp> <output.flp> <percent-0..100>
flp-rebuild rename-channel <input.flp> <output.flp> <channel-id> <name>
flp-rebuild duplicate-channel <input.flp> <output.flp> <channel-id> <name>
flp-rebuild create-sampler-channel <input.flp> <output.flp> <sample-path> <name>
flp-rebuild create-audio-channel <input.flp> <output.flp> <sample-path> <name>
flp-rebuild channel-groups <file.flp>
flp-rebuild create-channel-group <input.flp> <output.flp> <name>
flp-rebuild group-channels <input.flp> <output.flp> <channel-ids:comma-separated> <name>
flp-rebuild rename-channel-group <input.flp> <output.flp> <group-index> <name>
flp-rebuild delete-channel-group <input.flp> <output.flp> <group-index>
flp-rebuild set-channel-color <input.flp> <output.flp> <channel-id> <RRGGBB>
flp-rebuild move-channel <input.flp> <output.flp> <channel-id> <target-index:zero-based>
flp-rebuild reorder-channels <input.flp> <output.flp> <complete-channel-id-order:comma-separated>
flp-rebuild sort-channels <input.flp> <output.flp> <color|mixer-track|name|type>
flp-rebuild set-channel-colors <input.flp> <output.flp> <channel-ids:comma-separated> <RRGGBB>
flp-rebuild set-channel-color-gradient <input.flp> <output.flp> <channel-ids:comma-separated-in-order> <start-RRGGBB> <end-RRGGBB>
flp-rebuild set-channel-levels <input.flp> <output.flp> <channel-id> <volume-0..12800> <pan-0..12800>
flp-rebuild edit-sampler-volume-envelope <input.flp> <output.flp> <sampler-channel-id> <enabled:0|1|-> <tempo-sync:0|1|-> <predelay-raw|-> <attack-raw|-> <hold-raw|-> <decay-raw|-> <sustain-raw|-> <release-raw|-> <amount-raw|-> <attack-tension-raw|-> <decay-tension-raw|-> <release-tension-raw|->
flp-rebuild edit-sampler-envelope-lfo <input.flp> <output.flp> <sampler-channel-id> <target:panning|volume|mod-x|mod-y|pitch> <enabled:0|1|-> <envelope-tempo-sync:0|1|-> <lfo-tempo-sync:0|1|-> <lfo-phase-retrigger:0|1|-> <predelay-raw|-> <attack-raw|-> <hold-raw|-> <decay-raw|-> <sustain-raw|-> <release-raw|-> <amount-raw|-> <attack-tension-raw|-> <decay-tension-raw|-> <release-tension-raw|-> <lfo-predelay-raw|-> <lfo-attack-raw|-> <lfo-amount-raw|-> <lfo-speed-raw|-> <lfo-shape:0|1|2|->
flp-rebuild set-channel-enabled <input.flp> <output.flp> <channel-id> <0|1>
flp-rebuild set-channel-sample-path <input.flp> <output.flp> <channel-id> <sample-path>
flp-rebuild set-channel-zipped <input.flp> <output.flp> <channel-id> <0|1>
flp-rebuild set-channel-main-pitch <input.flp> <output.flp> <channel-id> <0|1>
flp-rebuild set-channel-key-region <input.flp> <output.flp> <channel-id> <low-key:0..127> <high-key:0..127>
flp-rebuild set-channel-sampler-root-key <input.flp> <output.flp> <sampler-channel-id> <root-midi-key:0..127>
flp-rebuild set-channel-add-to-key <input.flp> <output.flp> <channel-id> <0|1>
flp-rebuild edit-channel-level-adjustments <input.flp> <output.flp> <channel-id> <event-index> <pan-raw|-> <volume-raw|-> <mod-x-raw|-> <mod-y-raw|->
flp-rebuild set-channel-midi-out-settings <input.flp> <output.flp> <channel-id> <midi-channel:1..16|-> <use-note-color-channel:0|1|->
flp-rebuild set-channel-swing <input.flp> <output.flp> <channel-id> <percent-0..100>
flp-rebuild set-layer-children <input.flp> <output.flp> <layer-channel-id> <child-ids-comma-separated|->
flp-rebuild set-layer-flags <input.flp> <output.flp> <layer-channel-id> <random:0|1|-> <crossfade:0|1|->
flp-rebuild edit-automation-point <input.flp> <output.flp> <channel-id> <point-index> <position-beats> <value> <tension>
flp-rebuild set-automation-point-tail <input.flp> <output.flp> <channel-id> <point-index> <8-hex-digits>
flp-rebuild init-automation-points <input.flp> <output.flp> <channel-id> <template-channel-id>
flp-rebuild interpolate-automation-points <input.flp> <output.flp> <channel-id> <first-point-index> <last-point-index>
flp-rebuild edit-note <input.flp> <output.flp> <pattern-id> <channel-id> <note-index> <position> <length> <key> <velocity>
flp-rebuild edit-note-properties <input.flp> <output.flp> <pattern-id> <channel-id> <note-index> <flags-raw|-> <group-raw|-> <fine-pitch|-> <release|-> <midi-channel-raw|-> <pan|-> <mod-x|-> <mod-y|->
flp-rebuild quantize-notes <input.flp> <output.flp> <pattern-id> <channel-id> <grid-ticks> <strength-0..1> <swing-0..1>
flp-rebuild quantize-notes-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based> <grid-ticks> <strength-0..1> <swing-0..1> [sensitivity-0..1 duration-strength-0..1 leave-duration|leave-end|quantize-duration|quantize-end]
flp-rebuild quantize-notes-groove <input.flp> <output.flp> <pattern-id> <channel-id> <groove.fsc> <start-strength-0..1> <sensitivity-0..1> <duration-strength-0..1> <leave-duration|leave-end|quantize-duration|quantize-end> [velocity-level pan-level release-level modx-level mody-level]
flp-rebuild quantize-notes-groove-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based> <groove.fsc> <start-strength-0..1> <sensitivity-0..1> <duration-strength-0..1> <leave-duration|leave-end|quantize-duration|quantize-end> [velocity-level pan-level release-level modx-level mody-level]
flp-rebuild legato-notes <input.flp> <output.flp> <pattern-id> <channel-id>
flp-rebuild legato-notes-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based>
flp-rebuild chop-notes <input.flp> <output.flp> <pattern-id> <channel-id> <divisions-2..64>
flp-rebuild chop-notes-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based> <divisions-2..64>
flp-rebuild quick-chop-notes <input.flp> <output.flp> <pattern-id> <channel-id> <snap-ticks>
flp-rebuild quick-chop-notes-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based> <snap-ticks>
flp-rebuild glue-notes <input.flp> <output.flp> <pattern-id> <channel-id>
flp-rebuild glue-notes-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based>
flp-rebuild flip-notes <input.flp> <output.flp> <pattern-id> <channel-id>
flp-rebuild flip-notes-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based>
flp-rebuild strum-notes <input.flp> <output.flp> <pattern-id> <channel-id> <spread-ticks> <up|down>
flp-rebuild strum-notes-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based> <spread-ticks> <up|down> [velocity-amount:-127..127 velocity-tension:-100..100]
flp-rebuild flam-notes <input.flp> <output.flp> <pattern-id> <channel-id> <stroke-ticks> <velocity-0..127> <before|after> [group-notes:0|1]
flp-rebuild flam-notes-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based> <stroke-ticks> <velocity-0..127> <before|after> [group-notes:0|1]
flp-rebuild randomize-notes <input.flp> <output.flp> <pattern-id> <channel-id> <seed> <velocity-amount:-100..100> <pan-amount:-100..100> <pitch-range:0..24> <bipolar:0|1> <reset:0|1>
flp-rebuild randomize-notes-scale <input.flp> <output.flp> <pattern-id> <channel-id> <seed> <velocity-amount:-100..100> <pan-amount:-100..100> <pitch-range:0..24> <bipolar:0|1> <reset:0|1> <scale-name> <scale-root:0..11>
flp-rebuild humanize-notes <input.flp> <output.flp> <pattern-id> <channel-id> <seed> <timing-range-ticks> <velocity-variation-0..100>
flp-rebuild humanize-notes-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based> <seed> <timing-range-ticks> <velocity-variation-0..100>
flp-rebuild limit-notes <input.flp> <output.flp> <pattern-id> <channel-id> <minimum-key-0..127> <maximum-key-0..127> [wrap-to-bottom:0|1 scale-name|none scale-root:0..11|-> snap-direction:up|down|alternate]
flp-rebuild limit-notes-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based> <minimum-key-0..127> <maximum-key-0..127> [wrap-to-bottom:0|1 scale-name|none scale-root:0..11|-> snap-direction:up|down|alternate]
flp-rebuild arp-notes <input.flp> <output.flp> <pattern-id> <channel-id> <step-ticks|1/n> <range-octaves-1..4> <gate-1..100> <up|down|up-down|alternate> [time|block|chord]
flp-rebuild arp-notes-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based> <step-ticks|1/n> <range-octaves-1..4> <gate-1..100> <up|down|up-down|alternate> [time|block|chord]
flp-rebuild slice-notes <input.flp> <output.flp> <pattern-id> <channel-id> <position-ticks>
flp-rebuild slice-notes-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based> <position-ticks>
flp-rebuild slice-notes-at-positions <input.flp> <output.flp> <pattern-id> <cuts:channel-id:note-index:tick,...>
flp-rebuild scale-levels-notes <input.flp> <output.flp> <pattern-id> <channel-id> <center:-100..100> <tension:-100..100> <multiplier:0..200> <offset:-100..100>
flp-rebuild scale-levels-notes-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based> <center:-100..100> <tension:-100..100> <multiplier:0..200> <offset:-100..100>
flp-rebuild articulate-notes <input.flp> <output.flp> <pattern-id> <channel-id> <multiplier:10..100> <variation:0..100> <seed> <use-original-lengths:0|1> <chop-chords:0|1>
flp-rebuild articulate-notes-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based> <multiplier:10..100> <variation:0..100> <seed> <use-original-lengths:0|1> <chop-chords:0|1> <only-with-selection:0|1>
flp-rebuild claw-notes <input.flp> <output.flp> <pattern-id> <channel-id> <period-ticks:16+> <trash-every:2..16> <time-distortion:-100..100> <remove-short-notes:0|1> <stretch-to-compensate:0|1>
flp-rebuild claw-notes-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based> <period-ticks:16+> <trash-every:2..16> <time-distortion:-100..100> <remove-short-notes:0|1> <stretch-to-compensate:0|1>
flp-rebuild add-note <input.flp> <output.flp> <pattern-id> <channel-id> <position> <length> <key> <velocity>
flp-rebuild add-chord <input.flp> <output.flp> <pattern-id> <channel-id> <position> <length> <root-key> <velocity> <quality> <inversion>
flp-rebuild add-scale-chord <input.flp> <output.flp> <pattern-id> <channel-id> <position> <length> <root-or-top-key> <velocity> <quality> <scale|none> <scale-root:0..11> <inversion>
flp-rebuild add-notes <input.flp> <output.flp> <pattern-id> <channel-id> <notes:position:length:key:velocity,...>
flp-rebuild delete-note <input.flp> <output.flp> <pattern-id> <channel-id> <note-index>
flp-rebuild delete-notes <input.flp> <output.flp> <pattern-id> <channel-id>
flp-rebuild delete-notes-selected <input.flp> <output.flp> <pattern-id> <channel-id> <note-indices:comma-separated-zero-based>
flp-rebuild import-midi <input.flp> <input.mid> <output.flp> <track> <pattern-id|new> <channel-id>
flp-rebuild import-midi-cc <input.flp> <input.mid> <output.flp> <track-index> <pattern-id> <raw-channel> <raw-flags> <cc-0..127> <midi-channel-1..16|all>
flp-rebuild import-midi-cc-new-stream <input.flp> <input.mid> <output.flp> <track-index> <pattern-id> <raw-channel> <raw-flags> <cc-0..127> <midi-channel-1..16|all>
flp-rebuild import-midi-template-tracks <input.flp> <input.mid> <output.flp> <pattern-id|new> <template-channel-id> <track-numbers:all|1,2,...>
flp-rebuild import-midi-template-format2 <input.flp> <input.mid> <output.flp> <template-channel-id> <track-numbers:all|1,2,...>
flp-rebuild create-playlist-pattern-clip <input.flp> <output.flp> <arrangement-id> <pattern-id> <position-ticks> <length-ticks> <track-index:zero-based>
flp-rebuild create-playlist-audio-clip <input.flp> <output.flp> <arrangement-id> <channel-id> <position-ticks> <length-ticks> <track-index:zero-based>
flp-rebuild create-playlist-automation-clip <input.flp> <output.flp> <arrangement-id> <channel-id> <position-ticks> <length-ticks> <track-index:zero-based>
flp-rebuild import-midi-new-project <template.flp> <input.mid> <output.flp> <template-channel-id> <track-numbers:all|1,2,...>
flp-rebuild edit-clip <input.flp> <output.flp> <arrangement-id> <clip-index> <position> <length>
flp-rebuild delete-playlist-clip <input.flp> <output.flp> <arrangement-id> <clip-index>
flp-rebuild edit-clip-properties <input.flp> <output.flp> <arrangement-id> <clip-index> <item-index-raw|-> <track-index-raw|-> <group-raw|-> <flags-raw|-> <start-offset|-> <end-offset|-> <scale|->
flp-rebuild duplicate-clip <input.flp> <output.flp> <arrangement-id> <clip-index> <position|-> <track-index-raw|->
flp-rebuild make-audio-clip-unique <input.flp> <output.flp> <arrangement-id> <clip-index>
flp-rebuild make-audio-clip-unique-as-sample <input.flp> <output.flp> <arrangement-id> <clip-index>
flp-rebuild edit-time-marker <input.flp> <output.flp> <arrangement-id> <marker-index> <position-ticks|-> <signature:0|1|-> <numerator|-> <denominator|-> <name|->
flp-rebuild create-time-marker <input.flp> <output.flp> <arrangement-id> <position-ticks> <signature:0|1> <numerator|-> <denominator|-> <name|->
flp-rebuild delete-time-marker <input.flp> <output.flp> <arrangement-id> <marker-index>

add-notes appends multiple notes to one channel in a pattern using comma-separated position:length:key:velocity tuples; each record gets the same neutral defaults as add-note. add-chord appends a manual chord voicing from a named quality, MIDI root key, velocity, position, length, and inversion; root-position notes stay within MIDI keys 0–127, and inversions that would exceed that range are rejected. add-scale-chord adds scale-derived triads through thirteenths or top-down triads/sevenths, snaps the root or top key to the selected scale, and accepts none for major-interval stackings. delete-notes removes every note from one pattern channel while preserving other channels. delete-notes-selected removes only the comma-separated zero-based channel-local indexes; delete-note remains available for one index.

For MIDI import commands, use new as the Pattern target to create a Pattern in the current project. The project must contain an existing Pattern marker and a uniquely recognized Pattern note-event encoding; this does not create a separate FLP project.

To create a separate project from an FL Studio template, use flp-rebuild import-midi-new-project <template.flp> <input.mid> <output.flp> <template-channel-id> <track-numbers:all|1,2,...>. The template channel can be a kind-0 Sampler or kind-2 Native instrument; format-0/1 tracks share a new Pattern, while selected Format-2 sequences each receive a separate Pattern and cloned channel. The desktop MIDI import panel can discover the installed Empty.flp or let you choose a project template. The import-midi-template-tracks and import-midi-template-format2 commands provide the same template-based imports inside an existing project.

Source builds require Rust 1.99 or newer. Run python scripts/build_desktop_binaries.py --profile release (or use --profile debug for a debug build) before launching the desktop shell. This builds the vst3-host-helper beside the app; VST3 loading, state calls, and audio processing run in that child process so plug-in crashes are reported to the app. VST2 scans and render commands use the application executable in a separate worker process; macOS .vst bundles and platform module files are accepted. Native VST3 editor windows across the process boundary are supported on macOS; editor hosting on Windows and Linux remains incomplete.

Launch the native desktop shell with cargo run --release --bin fl-studio-rebuild. It uses the bundled Inter UI font under SIL OFL 1.1 (license included in assets/fonts/Inter-OFL.txt) and eframe's WGPU renderer, opens maximized, can open/save FLP files, and displays the decoded Playlist, Channel Rack, Piano roll, Mixer, Plug-ins, and Audio views. F5, F6, F7, and F9 switch between Playlist, Channel Rack, Piano roll, and Mixer, respectively. The Audio view selects input/output devices and provides a live capture meter, stereo input monitoring, a quiet output test tone, and direct input recording to WAV. The Audio settings MIDI input can record notes into the selected Pattern/channel, sampling CC10 pan, CC74/CC71 modulation, and pitch bend at each Note On; CC64 sustain holds released notes until pedal-up, and CC66 sostenuto holds only notes already active when the pedal goes down. CC120 closes open notes on its channel immediately; CC123–127 act as note-offs and respect both pedals. Pan defaults to center 64 and bend sensitivity defaults to ±2 semitones unless MIDI RPN 0 sets another range. With transport stopped, incoming notes also audition the selected enabled Sampler channel; this requires a saved project so sample paths resolve. The MIDI input scale-snap preference also applies to live Sampler audition, with note-offs paired to the snapped note even if the scale changes while held. Live Sampler voices follow pitch-bend messages using the current RPN 0 sensitivity and apply CC10 pan to new and already sounding voices; CC121 resets pan and releases pedal-held voices. CC64 sustain holds released voices until pedal-up; CC66 sostenuto holds only voices whose keys were already down when the pedal was pressed, and voices held by both pedals release only after both are up. CC120 immediately silences active voices, and CC123–127 release that MIDI channel’s live notes while respecting both pedals. Live MIDI input also auditions a selected loaded VST3 instrument or supported Layer through Sampler and VST3 descendants, both with transport stopped and during Pattern, Playlist, or Performance playback; the configured Performance MIDI channel remains reserved for clip and scene controls. With both devices connected, the session-only MIDI Thru option forwards incoming notes, controllers, pitch bend, clock, song position, and transport to an external MIDI output, and sends note-offs when disabled or disconnected. Forwarded CC120/CC123–127 clear tracked notes on their output channel, and CC121 clears tracked sustain and sostenuto state. A separate option snaps forwarded note-on/off pairs to the selected Piano roll scale and root, and the channel selector can preserve the input channel or force a chosen MIDI output channel. Mono inputs are duplicated to both outputs. Playlist recording defaults to dry hardware input and can optionally capture the signal after the selected Mixer route and its supported effects. The resulting sample-backed Audio Clip is placed at the Playlist playhead on the first non-overlapping lane and follows its saved Mixer route during playback; recording requires an Audio Clip record template somewhere in the project. Audio settings provides a persisted ±200 ms input-latency compensation offset: positive values move the Playlist clip earlier and negative values move it later, without changing the captured WAV. Browser audio files can also be dropped on a Playlist track to create a sample-backed Audio Clip. The clip length follows the decoded sample duration at the project base tempo; an Audio Clip template must exist in the project, and tempo automation is not reflected in that length. Windows offers WASAPI shared and exclusive access; shared mode uses the Windows audio engine, while exclusive mode opens the selected endpoint directly and reports unsupported formats or access conflicts. The Playlist supports selecting tracks and clips, editing clips, and duplicating clips; Ctrl/Cmd+A selects every clip in the active arrangement, Ctrl/Cmd+D clears the selection, and Shift+I inverts it. Dragging a selected clip moves the selection together while preserving relative timing and track spacing. Delete/Backspace and the context-menu Delete action remove all selected clips. With the Playlist focused, 9 toggles Reverse for selected Audio Clips. Shift-dragging the right edge resizes the dragged clip; if all selected clips support timeline resizing, it applies one shared duration change to the selection. Selected 2026 Audio Clips can trim or extend together from either edge when every source window matches its clip length, fits within the loaded sample, uses default scale, and has no overlapping Playlist tempo automation; eligible legacy Audio Clips can trim or extend from either edge when the sample is loaded, the decoded source window matches the timeline at base tempo, scale is default, and no Playlist tempo automation overlaps; selected eligible clips share one tick delta; the S-key Slip tool can slide eligible selected legacy Audio Clips together by one shared source-time delta and selected 2026 Audio Clips by one shared source-tick delta when every selected clip has room within its loaded sample, uses the default scale, and has no overlapping Playlist tempo automation. Playlist audio waveforms and supported audio playback/rendering crop to decoded source windows; 2026 tick windows map to sample frames at the project's base tempo. Its clip data inspector exposes the raw item index, track index, group, flags, offsets, and decoded scale field, plus editable tick bounds for 2026 Audio Clip source windows. The Channel Rack's pattern/bar selector and sixteenth-note step grid can add notes at key 60; populated cells show counts for multiple notes in one step, and clicking one removes all notes in that step; right-click a cell to add another note at a chosen key. Graph editor (Ctrl/Cmd+K) exposes per-step note key, velocity, pan, release, fine pitch, modulation X/Y, and shift; click-drag bars to edit values or create a C5 note on an empty step, and right-drag to interpolate values across steps. The Piano roll supports choosing a pattern and channel, adding a note with a left-click in empty grid space in Draw (P) mode, repositioning it by dragging before release, setting its length with Shift-drag, bypassing snap with Alt, and editing its start, length, key, and velocity. Its Draw (P), Paint (B), Slice (C), Delete (D), Select (E), Mute (T), Zoom (Z), and Playback (Y) tools include box and modifier selection, region zoom, background-click zoom out, cursor-centered Page Up/Down zoom, and note audition while clicking or dragging; Quantize can target a channel or the selected notes; Alt/Option+X opens Scale Levels for velocity Center, Tension, Multiply, and Offset; Shift+D sets selected note lengths to the current snap value; selected groups can be moved, resized, stretched together with Right-Shift+drag on a note edge (Alt+Right-Shift uses 25% steps), or deleted; Draw and Paint modes also erase notes on right-click or right-drag; the Delete tool removes notes by click or drag, and Slice draws a cut line that splits each crossed note. In Mute mode, left-click or left-drag toggles note mute, while right-click or right-drag deletes notes; Alt+M and Alt+Shift+M mute or unmute the selection, or the target channel when nothing is selected. Selection > Select muted notes finds muted notes, which are excluded from supported playback, audition, and MIDI export. An independent zoom slider is also provided. Selected notes at an onset display an inferred chord name with bass inversions for common, altered, augmented, minor-major, and suspended chord sets, and supported seventh or extended voicings that omit the fifth are marked (no5).Its advanced note properties editor also exposes raw flags/group, a Muted checkbox, fine pitch, release, stored MIDI channel, pan, and modulation X/Y fields. Drag a note body to move it on the grid; drag its right edge to resize it. The snap menu offers no snap, subdivisions of a beat, one or two beats, and a bar sized to the project's time signature. Dragging vertically changes the key within the visible keyboard range. These note operations rewrite only the affected length-prefixed score event and preserve other event bytes. Tempo edits are also written into the loaded project. The Plug-ins tab scans conventional VST locations on Windows, macOS, and Linux, plus directories listed in VST3_PATH and VST2_PATH. On project open, recognized VST3 channels are matched to installed bundles by wrapper-reported plug-in or bundle name and loaded into the isolated VST3 helper process; marker-12 state maps nested record 3 to the VST3 component stream and record 4 to its controller stream. Recognized marker-12 VST3 Mixer effect slots also match installed bundles, restore their saved state, and write edits back on project save; loaded effects process on supported Mixer routes with graph-level PDC. The loaded instance is linked to its Channel Rack row for playback, and its native editor can be opened on request. Unsupported state layouts and missing or failed plug-ins are reported; state write-back remains incomplete. The Plug-ins view can also load additional VST3 instances and expose host-reported parameters. CLAP instruments can be auditioned at a selected MIDI note and velocity with a 50–1,000 ms note length; each audition renders 1.5 seconds. The Plug-ins view can also render unmuted notes from the selected project Pattern/channel through an explicitly chosen CLAP instrument at the project base tempo, with a short release tail. CLAP note-dialect plug-ins receive per-note fine pitch, pan, Mod X as brightness, and release; MIDI 1.0/2.0 inputs receive key, velocity, channel, and release. Machine-local CLAP instrument assignments, captured plug-in state, and parameter overrides save per project path and Pattern channel; supported playback restores that state, which is not embedded in the FLP. Pattern transport loops assigned CLAP channels at project base tempo, follows Pattern seek, expands Layer notes to assigned CLAP children, applies Layer/source gain and pan, and routes through saved Mixer inserts including loaded VST3 insert effects. Playlist playback follows clip repeats, track mute/solo, and tempo automation for default-scale Pattern clips with recognized 88-byte source windows whose span matches the clip length, expands Layer notes to assigned CLAP children with Layer/source gain and pan, and routes through saved Mixer inserts including loaded VST3 insert effects. Nondefault scales, unrecognized legacy source windows, and native FLP plug-in state embedding remain unsupported. Assigned CLAP Mixer effects process on supported routes with PDC and sidechains and open isolated native editors that save state and writable parameters on close; assigned CLAP instruments also open isolated native editors that save state and writable parameters on close, then stop transport so state reloads on restart. Mixer inserts show editable raw fader and pan candidates when each has a unique zero-scope 0xE1 record matched by the corpus-derived target convention; a unique in-range stereo-separation record adds a raw slider. Supported direct routes apply unique candidate faders with provisional raw/10,000 linear gain and pan by linear cross-channel mixing at raw/6,400, including on the Master mix. Stereo separation uses a mid/side transform: −64 widens, 0 leaves stereo unchanged, and +64 produces mono. Project Circular Pan Law adds center compensation; Triangular adds none. The exact Mixer curves and visible track mapping still need native audio comparison; unsupported route mappings and offline insert metering remain incomplete. Loaded VST3 effects process on supported routes with graph-level PDC. The Master strip shows a live output peak meter in dBFS.

Machine-local Pattern Event links route normalized 0–1 streams to automatable CLAP parameters in selected Pattern previews, Pattern transport, Playlist and Performance playback, and offline song/stem renders. Playlist clips repeat Pattern points at the clip loop length and follow the Playlist tempo map. Machine-local Playlist Automation links can also route Automation Clip points to automatable parameters on assigned CLAP instruments during Playlist and Performance playback and offline song/stem renders. These points follow the Playlist timeline and stop at each Automation Clip end. Machine-local Pattern LFO links can target an automatable parameter on the selected project channel’s CLAP instrument, scoped to the project, Pattern, channel, plug-in, and parameter. They use Sine, Triangle, or Square shape, a 0.25–64 beat period, normalized minimum and maximum, and phase, and follow the same Pattern, Playlist, Performance, and render paths; Pattern Event points take precedence for a shared parameter. Recognized 88-byte Pattern tick windows whose span matches the clip length work in Playlist and offline song/stem paths. Nondefault scales and unrecognized legacy source windows, CLAP Mixer effects, and FLP-stored links remain unsupported; Performance Mode still requires full-source clips.

The Sample Editor opens Browser samples and direct recordings in a waveform or spectrum view. Select a range, adjust pitch shift and time stretch, and audition the processed selection before export. Fades, peak normalization, and reversal apply to both preview and WAV export; the source sample is unchanged.

Right-click inside an Audio Clip and choose Split audio at cursor to divide it at that tick. When the clicked Audio Clip is part of a multi-selection, Split selected Audio Clips at cursor applies the same absolute tick to every eligible selected clip as one atomic update and keeps all resulting pieces selected; full-source legacy clips need a loaded sample duration. In 2026 88-byte clips, the explicit source tick window must have the same span as the clip's timeline length; full-source windows and other ratios remain unsupported. Layouts with an established per-arrangement clip ID assign the new segment a unique one; the 88-byte layout's other bytes remain opaque and are preserved. Adjacent 2026 Audio Clips can be joined when their explicit source windows touch, each window span matches its timeline length, and all other record bytes match; the left record is kept. The Playlist context menu can also join two or more selected adjacent Audio Clips as a chain when every neighboring pair meets the same compatibility checks; it updates the project atomically and keeps the leftmost record. The context menu can also join a selection of adjacent Pattern Clips that reference the same pattern when each pair passes the existing repeat-boundary and note-cycle checks; the operation is atomic and keeps the leftmost record. It can split all selected Pattern Clips at one timeline cursor when that tick is inside every clip, lands on each pattern repeat boundary, each record has a recognized full source window and default scale, notes stay within repeat cycles, and no overlapping tempo automation exists; all resulting pieces stay selected and the change is atomic. The S-key Slip tool also moves an explicit 2026 source tick window when the sample duration is known, using the project base tempo. Shift-drag the right edge of a 2026 Audio Clip to extend or trim its explicit 1:1 tick window; the loaded sample duration caps the new end. Shift-drag its left edge to move the timeline and source starts together, bounded by tick zero and the sample start. Sample tempo metadata, clip-specific stretch, and tempo automation remain unsupported for these tick-window edits.

In the Playlist, Ctrl/Cmd+C and Ctrl/Cmd+X copy or cut the selected clips, and Ctrl/Cmd+V pastes the set after the active clip while preserving relative timing and track spacing. Ctrl/Cmd+B duplicates selected clips as a group after their right edge, or duplicates all clips when nothing is selected. Shift+Left/Right moves selected clips by one sixteenth note (Image-Line Playlist manual).

The View menu's Detach Piano roll, Detach Channel Rack, Detach Mixer, Detach Playlist, Detach Plug-ins, Detach Audio settings, and Detach Automation actions open those editors in resizable native windows; the matching Dock action in that menu or the main workspace returns each view. Detached editors share the active project, editing state, and undo/redo history with the main window. Their positions and sizes are saved between launches on platforms that report window geometry; size persists where the platform does not expose position.

The Playlist Audio Clip context menu offers Make unique, which gives one clip its own channel, and Make unique as sample, which also copies its audio file to Samples/ and points that channel at the copy. The CLI exposes both actions; saving the project as a ZIP package includes the copied file.

The desktop shell's Undo/Redo buttons and Ctrl/Cmd+Z, Ctrl/Cmd+Shift+Z shortcuts restore lossless FLP document snapshots across editors. History storage is capped at 64 MiB; undoing plug-in-host state and non-project UI state is not included.

The File menu keeps up to 50 recent projects across launches, shows the first ten with a More submenu, and opens the first ten with Alt/Option+1–0. It also offers autosave intervals of 5, 10, or 15 minutes (or Never). Regular modes pause during playback; Frequent mode saves every five minutes during playback and before plug-in loads, while Very frequent mode saves every minute and before plug-in loads. Backup location chooses a persistent folder for the configurable shared set of backups; prior locations and the default user data folder remain available for recovery. Manual saves preserve the previous project, and a newer autosave prompts for recovery when a project opens. Backup now, Revert to last autosave, and numbered Save new version (Ctrl/Cmd+N) are also available. Opening another project or using File > Exit or the window close button with unsaved edits prompts to Save, Don't Save, or Cancel. Untitled projects also autosave and offer startup recovery while retaining their template path.

In the Piano roll, Draw (P) adds a note with a left-click in empty grid space, lets you drag to reposition it before release, and uses Shift-drag to set its length; hold Alt to bypass snap. Paint (B) adds snap-length notes while dragging across empty cells; hold Shift while painting to replace overlapping notes in the selected channel and keep the pass monophonic. Draw and Paint modes also erase notes on right-click or right-drag. In Draw mode, Alt+right-click-and-drag scrubs the selected channel; Playback (Y) enables the same scrub gesture.

Piano roll Chord Stamp mode offers root position and selectable inversions for manual chords and scale-derived triads through thirteenths. Each inversion raises the lowest voice by an octave; top-down stamps keep the clicked pitch as their highest voice. Preview C5 auditions the selected stamp and inversion on the selected Sampler or loaded VST3 channel using the current snap length.

The Piano roll View menu can snap dragged notes to the nearest pitch in the selected scale or the current automatic detection. The scale is held constant for the full drag; equal-distance pitches resolve downward.

In Audio settings, Snap recorded notes to selected scale moves incoming MIDI note pitches to the nearest note in the selected Piano roll scale before the take is saved. The scale is captured when recording starts; timing, velocity, and note properties are preserved.

Audio settings' controller templates include Akai MIDImix Master Fader (channel 1 CC 62) and Fader 1 (channel 1 CC 19) profiles for output gain. Other MIDImix controls are not mapped yet.

Resolved audio-channel clips show an asynchronously decoded combined waveform in the Playlist. It follows horizontal zoom and clip source offsets. Stereo or spectral previews, fades, and gain envelopes are not shown yet.

The Browser now navigates local folders, filters samples/projects/presets/MIDI, opens FLP projects, and queues MIDI files for import. In the Piano roll, Route all tracks assigns each format-0/1 MIDI track to an existing Channel Rack channel and imports the notes into one Pattern; individual tracks remain available for separate imports. Format-2 tracks are imported one at a time because each represents an independent sequence. Double-clicking an .fst preset or choosing Inspect preset… opens details parsed from its lossless document, including preset kind, header format, version, and event/state counts; format-48 presets also show a recognized native plug-in identifier and state length. Expandable sections show decoded channel identities and paths, recognized plug-in state metadata, Mixer insert fields, and automation point counts. Apply to selected Channel restores a format-32 channel-state preset into an already loaded marker-12 VST3 channel when the class UID matches, then writes the result into the existing channel state while preserving its wrapper and unrelated FLP bytes; other plug-in payload variants remain opaque. The Channel Rack row menu also saves a single channel as a format-32 .fst, capturing live state for a hosted VST3; Layer channels with child references cannot be exported alone. Native Channel Rack plug-ins with the recognized format-48 wrapper fields can also save a standalone native state preset from the existing channel state; export-native-channel-plugin-state-preset provides the same operation, while recognized VST wrapper states are rejected. Recognized native Mixer effect slots with the same wrapper fields can save an individual format-48 state preset from the Mixer inspector; export-native-mixer-effect-state-preset provides the same operation. In the Mixer inspector, Load Mixer state… copies the ten-slot event block from a single-insert format-64 .fst into a compatible selected insert while preserving its route, name, color, flags, and project-wide parameter records. Save Mixer state as… exports the selected insert and complete ten-slot block when its boundaries and closing marker are recognized. Browser FST details can apply a format-48 native plug-in state to a selected Native Channel Rack plug-in with the same unique 0xC9 identifier and one data-encoded 0xD5 event, retaining the target channel wrapper, ID, and name; the apply-native-channel-plugin-state-preset CLI command provides the same operation. They can also apply a format-48 native effect preset to a selected Mixer slot with the same recognized plug-in identifier and one state event, retaining the target slot wrapper and Mixer controls; the apply-native-mixer-effect-state-preset CLI command provides the same operation. The app retains opaque effect events but does not host or process those plug-ins; native FL Studio save/reopen behavior remains unverified. Right-clicking audio in Files or Favorites offers Send to [channel] for the selected sample-bearing Channel Rack row and updates its existing sample-path event. Audio files can also be dragged from Files onto a compatible existing sample-bearing Channel Rack row to replace its sample, or onto the Channel Rack add area to create a new Sampler channel. In Files and Favorites, Shift+Up/Down sends the previous/next visible audio file to the selected sample channel when no text field has keyboard focus. Sending samples to plug-ins and other Browser drag targets remain unsupported. Its Project tab shows the current project's channels, patterns, and plug-in state; Plugins lists scanned candidates; Favorites persist starred file and plug-in paths; Recent keeps projects opened during the session. Search filters the current folder, plug-in list, or favorites. Files and Favorites can assign persistent tags individually or add and remove comma-separated tags across all currently filtered files in one edit; saved searches can match any or all selected tags. Clicking a supported audio file opens a Preview player at the bottom of the Browser and starts a five-second preview; Shift-clicking its row starts from the pointer's horizontal position. Full sample, Play-to-end, volume, Stop, seek, and Loop controls are available, and preview mixes with project output. Loop repeats the loaded preview region; Full sample or Play-to-end loads the whole file for seeking and looping. When the persisted Audio settings Read sample tempo information preference is enabled, valid, stretch-enabled WAVE ACID loop tempo metadata time-stretches Browser previews to the project tempo. The same preference also applies valid WAVE ACID loop tempo metadata when dropping a sample onto a Playlist grid track: the new Audio Clip gets a beat-aligned duration and Elastique 3 Generic pitch-preserving stretch settings. One-shots and samples without valid loop tempo metadata retain their original timing. Drops that cross Playlist tempo automation or need a stretch ratio outside 0.5x–2x keep the existing source-duration placement. Channel-level Sampler and Playlist stretch settings use the metadata to calculate target duration; channels without stretch settings and Audio Clip instances explicitly fitted to their visible duration keep their saved timing. When key preview is enabled, Browser sends and Channel Rack Sampler drops store the selected key as that Sampler’s root note for supported WAVE/AIFF samples. Playlist Audio Clip drops do not apply the Browser key selection. Preview loop and volume controls are not carried through drops. Preview supports mono or stereo WAV, AIFF, FLAC, MP3, M4A (AAC/ALAC), Ogg, and WavPack files.

Stamp mode adds the selected chord voicing on a grid click. Note lengths use the active snap, and Only one returns to Draw after a stamp.

The Piano roll's Selection menu provides Select all, Invert selection, and Deselect commands, with Ctrl/Cmd+A, Shift+I, and Ctrl/Cmd+D shortcuts. These operate on the current pattern and channel.

Shift+G groups selected notes and Alt/Option+G ungroups them. Clicking, box-selecting, moving, resizing, or deleting a grouped note applies to its group. Drag the selection stretch handle to scale selected note positions and lengths together; hold Alt on the handle to bypass snap. Right-Shift-drag a selected note edge for the same stretch, while Alt+Right-Shift uses 25% duration steps. The persisted Edit > Allow resizing from left option enables left-edge drags that change each note start while preserving its end; Alt bypasses snap for note movement and resizing. After starting a note drag, hold Shift to lock pitch or Ctrl/Cmd to lock timing. Shift+Arrow nudges by snap or semitone; Alt+Left/Right nudges by one screen pixel converted to ticks at the current zoom, and Alt+Up/Down nudges by a semitone.

The Piano roll's Events panel displays per-note velocity, pan, release, fine pitch, Mod X, or Mod Y as draggable stems. Select a target from the toolbar menu or press Shift+F to cycle through them. The raw Pattern controller lane supports drawing, painting, linear and spline interpolation, and range erase; native controller target mapping and scale behavior remain incomplete.

The selected-note inspector can toggle a Slide note flag and shows a small marker at the start of the note. The flag is preserved in the FLP, but native-instrument glide playback and portamento remain unsupported.

Use Ctrl/Cmd+B or Selection → Duplicate to right to copy the selected notes, or all notes in the current channel when nothing is selected. The copy preserves note properties and moves right by the notes' combined time span; a separate time-range repeat interval is not available yet.

Slice channel/selected and slice-notes split targeted notes that cross the chosen tick into two notes. Both pieces retain the source note's properties. slice-notes-selected accepts comma-separated zero-based channel-local note indexes. slice-notes-at-positions accepts per-note channel-id:note-index:tick triples, allowing one command to cut notes on multiple channels at different ticks.

The desktop executable also accepts an .flp path as its first argument to open that project at startup.

The Project Info… control edits the project's title, author, genre, comments, and web link. project-info prints those fields; set-project-info accepts - for fields to leave unchanged and an empty quoted string to clear a field. Missing fields are inserted before the first channel marker, and all other event bytes remain unchanged.

The Project settings… control edits the currently mapped Advanced options: “Play truncated notes in clips” and “Fast declick for cut groups.” It also reads and edits project pan law: Circular (0, the default) or Triangular (2), the project-wide time signature, and Master pitch in cents. project-settings prints the mapped values; set-project-settings accepts 0, 1, or - for each Advanced field and an optional raw pan-law byte (or -). set-project-master-pitch accepts −1200 through +1200 cents. Sampler note playback/rendering and unstretched Playlist Audio Clips (scale unset or 1.0) follow Master pitch when Enable main pitch is on for their channel; hosted VST3 pattern and Playlist notes also apply it. Native instruments and stretched Audio Clips remain incomplete. The Channel Rack context menu and CLI expose both Enable main pitch and Add to Key; Add to Key transposes supported Sampler and hosted VST3 notes by the nearest semitone of enabled Master pitch. Saved Sampler Root Key offsets also transpose note input relative to the sample root; VST3 Root Key offsets and native instruments remain incomplete. set-project-time-signature writes the project numerator and denominator. These are the project defaults; Playlist and Pattern time signatures are separate. In the Piano roll, Pattern time signatures can be added, updated, and deleted at tick positions with Shift+Ctrl/Cmd+P; meter changes are shown as bar divisions in that Pattern's grid. The patterns command lists signatures, while set-pattern-time-signature and delete-pattern-time-signature edit them by Pattern ID and tick. The Channel Rack also reads and edits its global swing amount through the 0x0B project event; global-swing reports it and set-global-swing accepts 0–100 percent. Supported Pattern playback shifts every second 16th-step onset using the combined global and source-channel swing mix. The one-third-step maximum is an inferred triplet mapping and still needs comparison with native FL Studio audio. The Ctrl/Cmd+M toolbar toggle enables the realtime metronome. Right-click MET to choose separate saved accent and beat samples; the samples are mixed to mono and used by realtime playback and the PRE recording count-in. PRE or Ctrl/Cmd+P enables the saved recording count-in, with a right-click menu for one, two, or four bars; stopped audio and MIDI recordings start after the count-in, while record requests during playback start immediately. Right-click MET also selects Master or a recognized Mixer insert for Song, Performance, Pattern, and PRE clicks. Live clicks use the selected insert and Master processing on the next playback; a PRE count-in snapshots the selected route when it is queued and runs through loaded Mixer effects and Master processing. Offline renders omit transport metronome clicks, and remaining project controls are incomplete.

create-pattern adds an empty pattern after the highest recognized pattern ID. It only works when the project has a unique, recognized D0 or E0 note-event encoding; ambiguous or unrecognized layouts are refused without editing the source. duplicate-pattern creates a new pattern containing the source pattern's note records, name, and explicit length while preserving unrelated events.

The same menu can delete the selected Pattern after confirmation. delete-pattern removes the Pattern's event region only when its ID is unique and no Playlist Clip references it; projects with an undecodable Playlist layout are refused so unknown clips cannot be orphaned.

edit-note-properties updates a note's raw flags/group, fine-pitch, release, raw MIDI-channel, pan, and modulation X/Y fields. Pass - for any property to leave it unchanged. The reserved byte remains untouched.

quantize-notes moves note starts toward the nearest grid points for one pattern channel. Strength and swing are fractions from 0 to 1; lengths and other note properties are retained. Its advanced form also accepts sensitivity, duration strength, and a duration/end mode. quantize-notes-selected applies the same controls to comma-separated zero-based channel-local note indexes. The quantize-notes-groove commands use an .fsc score as a repeating groove: template note starts and ends provide snap points, and zero-velocity template notes delete target notes snapped to those starts. The optional velocity, pan, release, Mod X, and Mod Y levels linearly mix target note values toward the matched template note, from 0 (retain) to 1 (use the template). The Piano roll can load the same score in Edit tool settings and previews its snap points as red lines. Quick Quantize remains grid-based. The score supplies its own timing offsets, so score mode has no separate swing control. The repeat period currently uses the latest template note end; verify this against an FL Studio-saved quantization because Image-Line's manual does not specify the period.

rotate-notes moves channel note starts left or right by one snap step, wrapping each note inside its meter-aware measure. rotate-notes-selected applies the same operation to comma-separated zero-based channel-local note indexes; selecting a grouped note also rotates the other members of its group.

In the Piano roll, Quantize selected targets the current selection. The Edit target selector routes other note-transform buttons to Auto (use the selection when present, otherwise the channel), Channel, or Selected notes.

The Piano roll's Edit target selector applies note-transform buttons to either the whole channel or only selected notes. Legato channel/selected extends targeted notes to the next distinct onset in the channel; notes in the final onset group keep their current lengths. legato-notes-selected applies this to comma-separated zero-based channel-local note indexes.

Quick Chop channel/selected and quick-chop-notes split notes longer than the supplied snap into snap-sized segments; any final partial segment keeps its remaining length. quick-chop-notes-selected accepts comma-separated zero-based channel-local note indexes. Chop channel/selected and chop-notes divide eligible notes into equal segments; each new segment retains the source note's properties and any leftover ticks stay in the final segment. chop-notes-selected accepts the same index format.

Glue channel/selected and glue-notes join touching or overlapping targeted notes when all stored properties besides position and length match. glue-notes-selected limits joining to comma-separated zero-based channel-local note indexes.

Flip channel/selected and flip-notes mirror note positions around the end of the latest channel note or, for a selection, within the selected notes' time bounds. Note lengths and other properties are retained. flip-notes-selected accepts comma-separated zero-based channel-local note indexes.

Strum channel/selected and strum-notes stagger simultaneous targeted notes by pitch over the configured tick spread. Choose low-to-high (up) or high-to-low (down); note lengths and other properties are retained. strum-notes-selected accepts comma-separated zero-based channel-local note indexes and the optional velocity shaping controls.

Flam channel/selected and flam-notes add a short same-pitch stroke for each targeted note. Set stroke time and velocity, and choose before or after placement. Before strokes earlier than tick zero are clamped to tick zero. The Piano roll also offers absolute millisecond or tempo-based tick timing, 1/64, 1/32, and 1/16 timing presets, and note grouping. Its saved toolbar Grouping switch enables or disables selecting and editing group members together without changing their group IDs. The CLI uses ticks and can group originals with their new strokes; flam-notes-selected targets comma-separated zero-based channel-local note indexes. The legacy channel-wide command keeps grouping off unless group-notes:1 is supplied. Exact native preset labels and values remain unverified.

Randomize channel/selected and randomize-notes apply repeatable seeded changes to targeted note velocity, pan, and pitch. Velocity and pan amounts range from -100 to 100 percent; pitch range is 0 to 24 semitones. Bipolar mode allows changes in either direction, and Reset levels first uses velocity 100 and centered pan as the starting values. Keep pitches in scale restricts generated pitches to the Piano roll's selected scale and root while staying within the configured pitch range. randomize-notes-scale exposes the same option with a scale name (major, major-locrian, harmonic-major, double-harmonic-major, ionian-sharp-5, ionian-sharp-2, ionian-sharp-2-sharp-6, ionian-augmented-sharp-2, dorian, dorian-b2, ukrainian-dorian-b2, dorian-sharp-4, dorian-b5, phrygian, phrygian-b4, ultraphrygian, ultraphrygian-bb3, phrygian-dominant, lydian, lydian-sharp-2, lydian-sharp-2-sharp-6, lydian-sharp-3-sharp-6, lydian-sharp-6, lydian-b3, lydian-augmented-sharp-2, lydian-augmented-sharp-3, lydian-augmented-sharp-6, lydian-augmented-dominant, lydian-augmented, lydian-dominant, lydian-dominant-b6, mixolydian, mixolydian-augmented, mixolydian-augmented-sharp-2, mixolydian-b2, mixolydian-b6, natural-minor, locrian, locrian-dominant, locrian-natural-2, locrian-natural-6, locrian-bb7, locrian-bb3-bb7, ultra-locrian-bb3, harmonic-minor, harmonic-minor-b5, melodic-minor, melodic-minor-sharp-5, neapolitan-minor, neapolitan-minor-sharp-4, romanian-minor, neapolitan-major, hungarian-minor, hungarian-major, hungarian-major-mode-2, chromatic-hypophrygian-inverse, persian, oriental, blues, major-pentatonic, minor-pentatonic, whole-tone, whole-half-diminished, half-whole-diminished, half-diminished-b4, altered, altered-dominant-natural-6, altered-dominant-bb3, or super-locrian-bb7) and a root pitch class from 0 (C) through 11 (B).

Humanize channel/selected and humanize-notes apply seeded onset shifts within a symmetric tick range and velocity variation within a symmetric percentage range. Note lengths and other properties are retained. The CLI also offers humanize-notes-selected for comma-separated zero-based channel-local note indexes, plus optional pan, release, Mod X, and Mod Y variations. Timing is expressed in project ticks; tempo-relative timing remains incomplete.

Limit channel/selected and limit-notes fold targeted note pitches by octaves into the chosen key range, then clamp notes whose pitch classes cannot fit. The Piano roll can also wrap notes to the lowest octave in the range and snap out-of-scale pitches to the currently selected key and scale, upward, downward, or alternating. The CLI exposes these options in its extended form, and limit-notes-selected applies them to comma-separated zero-based channel-local note indexes. Use none - when scale snapping is disabled; native alternate-snap edge behavior has not been compared.

Arpeggiate channel/selected and arp-notes replace targeted simultaneous chord groups with configurable Up, Down, Up/Down, or Alternate range patterns across an octave range. Alternate traverses low-to-high and high-to-low, repeating both turning notes. Step time accepts project ticks or straight note divisions from 1/1 through 1/128, gate length is configurable, and Time/Block/Chord sync controls repetitions: Time runs one pass, Block repeats until the last source note ends, and Chord stops at the first source-note release. arp-notes-selected targets comma-separated zero-based channel-local note indexes. Custom .fsc arp scores, score flipping/alternation, and exact native timing remain incomplete.

Riff machine channel/selected and riff-machine-notes use the targeted notes or an optional progression score, build diatonic triads or custom chord voicings, arpeggiate them, and apply seeded level variation, note-length scaling and variation, and key-range fitting. riff-machine-notes-selected takes comma-separated zero-based channel-local note indexes before any options. Both commands accept any subset of --scale, --root, --min-key, --max-key, --wrap-to-bottom, --snap-direction, --step-ticks, --range-octaves, --gate-percent, --direction, --sync, --progression-score, --progression-time-multiplier, --chord-score, --chord-time-multiplier, --chord-progression, --arpeggiation, --mirroring, --levels, --articulation, --groove, --fit, --arpeggio-score, --arpeggio-mode, --arpeggio-time-multiplier, --arpeggio-levels-percent, --length-variation-percent, --articulation-seed, --use-original-lengths, --mirror-horizontal, --preserve-start-times, --mirror-vertical, --group-notes, --groove-score, --groove-snap-ticks, --groove-start-percent, --groove-sensitivity-percent, --groove-duration-percent, --groove-velocity-level-percent, --groove-pan-level-percent, --groove-mod-x-level-percent, --groove-mod-y-level-percent, --groove-pitch-level-percent, --groove-mode, --pan-variation-percent, --length-multiplier-percent, --velocity-variation-percent, --release-variation-percent, --mod-x-variation-percent, --mod-y-variation-percent, --pitch-variation-semitones, --reset-levels, --bipolar-levels, and --seed in --name=value form; --sync accepts time, block, or chord and defaults to block; omitted values use the API defaults; all seven stage switches default to true. --progression-score=progression.fsc uses the score notes as the Note Progression stage input, normalizing the pattern to its first note and scaling timing to project PPQ; in selected-note mode, the first score note starts at the earliest selected onset. --progression-time-multiplier accepts 1/8, 1/4, 1/2, 1, 2, 3, or 4 and scales progression note lengths without moving their onsets; --chord-time-multiplier uses the same values to scale generated chord lengths. --chord-score=chords.fsc groups positive-length score notes by onset into voicings, maps each voicing's lowest pitch to a progression root, and cycles through the voicings in order. --groove-score=groove.fsc uses the score's note starts and ends as repeating timing anchors, scaled from score PPQ to project PPQ. --group-notes=true assigns generated notes one fresh channel-local note group per progression onset. --arpeggio-score=pattern.fsc uses a custom .fsc pattern for the Arpeggiation stage; --arpeggio-mode accepts normal, flip-vertical, or alternate, and time multiplier accepts 1/8, 1/4, 1/2, 1, 2, 3, or 4. Articulation supports a separate variation seed; the Piano roll Throw dice button chooses fresh independent level and articulation seeds and generates immediately. The Chords, Arpeggiation, Mirror, Levels, Articulation, Groove, and Fit stages can be enabled independently in the Piano roll and with the matching boolean CLI options. Articulation can use generated lengths or legato distances to the next onset. The Groove level options mix generated velocity, pan, Mod X, Mod Y, and pitch toward the nearest matching score note and require a score template; --groove-snap-ticks=none disables grid-based Groove snapping. The Piano roll can preview through any stage using an isolated project copy without committing edits. Generated note lengths use the current snap as their Articulation base, and the length multiplier and variation controls require an active snap. The progression and chord score pickers open the matching FL Studio preset folder when a standard install is detected; this app does not bundle the FL Studio score files. Exact score repeat-period behavior and native formulas remain incomplete (FL Studio Riff Machine manual).

Claw machine channel/selected and claw-notes apply a repeating period gate, split notes that cross clawed slices into retained fragments, slew fragment onsets toward the period start or end, and optionally remove short fragments or stretch across removed gaps. claw-notes-selected accepts comma-separated zero-based channel-local note indexes. The 16-slice schedule, distortion curve, and short-note threshold are local interpretations that still need native comparison (FL Studio Claw Machine manual).

Slice channel/selected splits targeted notes that cross the configured tick, retaining their note properties. In the Piano roll, Slice (C) also cuts notes where a dragged line intersects them; Shift-click makes a single vertical cut at the clicked time, and Shift+Alt-click bypasses snap.

Scale Levels channel/selected and scale-levels-notes adjust note velocities with Center, logarithmic Tension, Multiply, and Offset. scale-levels-notes-selected accepts comma-separated zero-based channel-local note indexes. Center and Tension use local formulas pending comparison against native FL Studio.

Articulate channel/selected scales original note lengths or uses the next onset as a legato boundary, with optional seeded Variation and chord chopping. articulate-notes exposes channel-wide processing; articulate-notes-selected accepts comma-separated zero-based channel-local note indexes and the Only with selection option. Quick preset values and the variation distribution remain unverified against native FL Studio.

The Piano roll key and scale selectors highlight C through B in major, natural minor, harmonic minor, and major or minor pentatonic scales. Selecting None disables highlighting; the helper does not constrain note entry.

When a note is selected, the inspector names a recognized chord made from notes at the same onset in the target channel. It detects common triads, suspended chords, seventh chords, and power chords; inversions and more complex voicings appear as a note count.

The Piano roll's Ghost channels toggle (Alt/Option+V) shows every channel in the current pattern in muted blue-gray while keeping the target channel green. Ghost notes remain editable through the same note controls.

Enable Color by MIDI channel to assign each note's stored low four MIDI-channel bits a distinct display color. Native color groups and color-based selection remain undecoded.

edit-clip-properties edits a clip's raw item/track/group/flags fields, source offsets, and scale when that field is present. Use - to leave a value unchanged; scale edits are rejected for layouts without the established scale field. edit-audio-clip-window-ticks <input.flp> <output.flp> <arrangement-id> <clip-index> <source-start-tick> <source-end-tick> <timeline-length|-> edits an 88-byte Audio Clip's explicit source tick bounds. Pass - to leave its timeline length unchanged, or provide a length equal to end tick minus start tick to resize both together. Tick values map at the project base tempo. The command requires a resolvable, decodable sample and rejects source ends beyond its decoded duration in base-tempo ticks. Sample tempo metadata, clip-specific stretch, and tempo automation remain unsupported. edit-playlist-track <input.flp> <output.flp> <track-id> <enabled:0|1|-> <grouped:0|1|-> updates the observed mute/group fields on an existing Playlist track while preserving its other event bytes. set-playlist-track-trigger-sync <input.flp> <output.flp> <arrangement-id> <track-id> <mode> edits one track's Performance Mode Trigger Sync setting; modes are off, quarter-beat, half-beat, beat, two-beats, four-beats, and auto. set-playlist-track-press saves retrigger, hold-stop, hold-motion, or latch; set-playlist-track-motion saves stay, one-shot, march-wrap, march-stay, march-stop, random, or exclusive-random. Press and Motion playback behavior is partly implemented: Latch stops the same playing clip on a repeated trigger, One Shot plays its first pass then stops, and Hold & stop starts on mouse press and stops on release; Hold & motion and other Motion behavior remain incomplete. set-playlist-track-position-sync <input.flp> <output.flp> <arrangement-id> <track-id> <mode> edits its Position Sync setting using the same modes. set-playlist-track-tolerant <input.flp> <output.flp> <arrangement-id> <track-id> <enabled:0|1> edits its Tolerant launch flag. set-playlist-track-queued <input.flp> <output.flp> <arrangement-id> <track-id> <queued:0|1> edits the saved per-track Queue setting. In Performance Mode, this setting and the clip context menu’s Queue this clip action enqueue launches in request order on that track. An idle track starts a queued clip at the next safe audio tick; otherwise each queued clip replaces the playing clip at its next cycle boundary, and the final queued clip continues looping. The manual specifies selection order but not this boundary timing, so the timing remains inferred and open for native comparison. rename-playlist-track <input.flp> <output.flp> <track-id> <name> changes an existing Playlist track name while preserving its other events. In the desktop Playlist, the Select menu selects all clips, selects muted clips, selects stacked clips (all but the lowest visible clip among clips with identical start and end positions), inverts selection, or clears it. Alt+M mutes the selected clips; Alt+Shift+M unmutes them. Right-click a track header to set its saved Press and Motion modes, Trigger Sync, Position Sync, Queue, and Tolerant settings; Latch stops the same active clip on a repeated trigger, One Shot plays its first pass then stops, and Hold & stop starts on mouse press and stops on release; Hold & motion and other Motion playback remain incomplete. The same menu can Rename… or Auto name to use its earliest Pattern Clip's name, or mute/unmute every clip on that track. Click a track name to select it, Ctrl/Cmd-click to toggle a track, and Shift-click to extend a contiguous selection. Ctrl/Cmd+Up/Down moves the active track selection; Ctrl/Cmd+Alt/Option+Up/Down extends it. The Tracks menu can select clips on selected tracks, mute or unmute selected tracks, solo a contiguous selected range, group selected tracks with the track above, ungroup them, and clear the selection; the first Playlist track cannot be grouped. Shift+Up/Down moves selected clips vertically, or all clips when the arrangement has no clip selection. A clip context menu can select every clip in the arrangement that uses the same source pattern or channel (Image-Line Playlist manual).

duplicate-clip copies a clip's complete record and inserts it after the source. Its default position is the source clip's end; an optional position and raw track index can be supplied.

channels <file.flp> reports each channel's raw kind, known type label, observed Layer child IDs/flags, sample source path, volume, pan, and raw per-channel swing mix. Sample paths are decoded from 0xC4 for kind-0 Sampler channels and kind-4 sample-backed channels; plugin channel payloads remain excluded. Known type labels cover Sampler, MIDI Out, Native, Layer, Instrument, and Automation; unrecognized raw values remain available. Right-clicking a MIDI Out row opens recognized MIDI channel and note-color routing settings in the Channel Rack. These settings also affect Pattern preview, live Pattern-mode MIDI output, and MIDI export. Layer Random and Crossfade can be toggled in the Channel Rack or with set-layer-flags, preserving all other 0x90 bits. mixer <file.flp> reports recognized Mixer insert names and raw fields from the observed 0x9A/0x93/0x95 sequence, decoded insert flag states and raw flags, fixed-size 0xE1 parameter records, and saved send levels with paired routing flag locations when recognized. Fader and send-destination mappings remain incomplete. Unique, unscoped effect-slot enabled and Mix records are now shown and editable using the candidate target mapping. sample-paths <file.flp> tries to resolve each reference using the project folder, configured factory roots, and common FL Studio install locations; it reports paths it cannot find. Set FL_STUDIO_ROOT or FL_STUDIO_FACTORY_DATA to select a custom installation. audio-info <audio-file> decodes WAV, OGG/Vorbis, FLAC, MP3, AIFF, and lossless mono/stereo WavPack media by content, including FL Studio's private RIFF wrapper around Ogg data. render-audio-clips <project.flp> <output.wav> makes an experimental stereo float render of enabled Playlist clips that target audio channels, using the base project tempo and observed source offsets. Clips with non-default scale are skipped and counted. The Playlist transport mixes audio clips, supported Sampler notes, and mapped VST3 instruments placed by Pattern Clips in bounded worker blocks at the device rate. Opening a project auto-loads recognized VST3 channels when an installed bundle matches; unsupported or missing plug-ins are reported. VST3 output is resampled and mixed from the same instances used by open editors. It applies provisional channel volume/pan mapping and inferred pattern repeat behavior, which still need comparison against native FL Studio output. Pattern Sampler and VST3 notes use the same swing scheduler; Playlist audio clips are unaffected. Tempo automation, supported Mixer routing and loaded effects are part of Song transport; broader parameter automation and unsupported route mappings remain incomplete.

time-markers <file.flp> lists arrangement time markers with positions, names, signature status, and meter values. It prints the raw position dword so unknown bits remain visible. edit-time-marker changes an existing marker's position, kind, meter, or name; create-time-marker inserts a time or signature marker in event order; and delete-time-marker removes the marker's recognized position, meter, and name events. These operations preserve unrelated events. The Playlist desktop view also displays marker lines and lets you select, edit, create, and delete markers. Its playhead follows device-consumed frames at the project's base tempo; seeking to markers and tempo-automation timing remain incomplete.

pattern-controllers <file.flp> <pattern-id> lists candidate raw controller records, including tick position, raw channel/flags/reserved fields, decoded float value, and original float bits. edit-pattern-controller updates one zero-based record; pass - to leave either field unchanged. duplicate-pattern-controller copies an existing point's opaque fields and sets a new tick position and value. delete-pattern-controller removes a point by zero-based index. draw-pattern-controller-points accepts comma-separated tick:value pairs and updates matching ticks or appends new points from the stream's first record template. linearize-pattern-controllers and spline-pattern-controllers interpolate existing points between the selected inclusive tick endpoints; delete-pattern-controller-range removes matching points in that inclusive range. These stream commands take the raw channel and flags bytes (0–255 each), and drawing requires at least one existing point in the stream. In the Piano roll's Events lane, select Raw controllers to view points, filter by the exact stored channel/flags pair, drag to edit, click empty space to add a point from the selected stream, or right-click a point to delete it. Adding points requires at least one existing point in that stream so the opaque fields can be copied. import-midi-cc imports one selected MIDI CC from a track into an existing raw stream; import-midi-cc-new-stream creates a stream using the supplied raw channel and flags bytes. Both optionally filter by MIDI channel, preserve source tempo timing, and map values linearly to 0.0–1.0. The Piano roll Events panel exposes both actions; a new stream begins at the first imported point and is not created when no matching CC messages exist. Automatic target-stream discovery and parameter-specific scaling remain incomplete. export-midi-cc writes the selected raw stream as one MIDI CC on an explicitly chosen MIDI channel and CC number, preserving Pattern ticks and project PPQ; raw values clamp to 0.0–1.0 and map to MIDI 0–127. The Piano roll Events panel also offers Export MIDI CC… for its selected stream. Channel/flags meanings, native target mapping and scale, and native save verification remain incomplete.

In the desktop Piano roll, Open MIDI… loads a MIDI file, lets you choose one track or route every format-0/1 track into the selected pattern, and imports notes into existing channels. Create Sampler channels or Create Native channels makes one named channel per format-0/1 track by copying the selected kind-0 Sampler or kind-2 Native instrument template, then imports each track into its new channel. For Format-2 files, Create separate patterns + Sampler channels or Create separate patterns + Native channels keeps every independent sequence in its own new Pattern and template-based channel, both named after the MIDI track. The selected track's note timing is converted from MIDI PPQ to project PPQ. Export pattern MIDI… exports the selected pattern; Export song MIDI… exports the selected Playlist arrangement. The Piano roll's MIDI channel mapping control preserves each note's stored low four channel bits or assigns one MIDI channel per FL channel. Render pattern audio… exports the selected pattern/channel through its loaded VST3 instance using the shared Playlist audio output settings. Preview VST3 processes that pattern in VST3-sized blocks on a worker and streams the stereo output through the selected device at its sample rate, using the same plug-in instance as the open editor. Preview Samplers streams enabled kind-0 Sampler notes from the selected pattern through the selected output. Render Sampler pattern… exports those notes with the shared output settings and applies loaded VST3 Mixer effects and linked Pattern effect automation when available. Render Playlist mix… renders supported audio clips, Sampler Pattern Clips, and mapped installed VST3 instruments in bounded blocks to WAV (16/24-bit integer PCM or 32-bit float), FLAC (16/24-bit integer), Ogg Vorbis (64–450 kbps target average bitrate), or MP3 (32–320 kbps constant bitrate at 32/44.1/48 kHz), with stereo/merged-mono/left-only/right-only channels and 0-, 1-, 2-, or 5-second tails. Playlist WAV and Mixer stem renders can also save arrangement time markers as RIFF cue points and labels, extending output through the last marker. The separate Save note markers option writes cue points for Playlist Pattern note onsets and active Audio Clip starts. Off, TPDF, or high-pass TPDF dither is available for 16-bit WAV; the selected mode also applies during MP3 16-bit quantization. FLAC uses the encoder defaults; Render audio clips… exports enabled audio-channel clips using the selected WAV, FLAC, Ogg Vorbis, or MP3 format with matching depth/bitrate and channel-mode settings; MP3 uses 32/44.1/48 kHz only, while WAV also uses the shared PCM depth and dither options. File > Export > Render selected Audio Clip… writes the selected enabled audio-channel Playlist clip in the chosen output format; when multiple Audio Clips are selected, Render selected Audio Clips… mixes them into one file while preserving their relative song positions from the earliest selected clip or song start. Choose whether the output starts at the clip start or preserves its song position; loaded VST3 Mixer insert/Master effects, supported linked Playlist Automation Clip and Pattern Event/LFO effect automation, reported tails, and automatic PDC apply when available. Render and insert selected Audio Clip… adds the render as a new Audio Clip on the source track and leaves the original unchanged; Consolidate selected Audio Clip… inserts it at the same position and mutes the source. Both actions support clip-start or song-start placement; Freeze track from song start… in a Playlist track header renders supported Audio Clips and Pattern notes from Sampler, loaded VST3, or assigned CLAP instruments from tick zero, inserts the result on the same track, and mutes its source clips as one undoable edit. CLAP Pattern clips must use the default scale and full source range; raw Pattern controller points and unavailable sources remain unsupported. Supported loaded VST3 Mixer effects, linked effect automation, reported tails, and automatic PDC apply when available. Render selected Pattern Clip… in File > Export or its Playlist context menu writes one selected Pattern Clip, or renders multiple selected Pattern Clips together, using supported Sampler, loaded VST3, and assigned CLAP instrument notes. Pattern Clips must use the default scale; CLAP clips also require the full Pattern source range. Raw Pattern controller points and unavailable sources remain unsupported. Choose clip start or song start; for a group, the clip-start render begins at the earliest selected clip and preserves the clips’ relative song positions through the latest endpoint and configured tail. It includes tempo automation, supported linked Playlist Automation Clip and Pattern Event/LFO effect automation, loaded Mixer effects, reported effect tails, and automatic PDC. Merge selected Pattern Clips (Ctrl/Cmd+G) combines clips into a new Pattern, retaining the uppermost clip's Pattern name/color and repeating source notes, raw 0xDF controller points, and recognized time markers across their clip ranges; controller targets remain uninterpreted, and unknown Pattern data is rejected. Consolidate Pattern Clip… (or Consolidate selected Pattern Clips… for a multi-selection) in the Playlist context menu inserts one Audio Clip at the earliest source position on the earliest source clip's Playlist track and mutes the sources as one undoable edit, including selections across tracks. Unsupported effect automation links and native FL Studio output comparison remain incomplete. Both operations leave the arrangement unchanged when the renderer reports unsupported or unavailable sources or the project changes during rendering. Playlist rendering follows tempo automation and supported VST3 parameter automation and processes loaded Mixer effects on supported routes; looping or stretching a clip beyond its source duration remains incomplete; File > Export > Render Sampler pattern… writes enabled Sampler notes from the selected pattern using the shared WAV/FLAC/Ogg Vorbis/MP3 output selection and its bit-depth, bitrate, and channel-mode settings. The selected TPDF or high-pass TPDF mode applies to 16-bit WAV and MP3 quantization; WAV also supports dither Off. Performance Mode is available from the Playlist toolbar when the arrangement has a non-signature time marker named Start. Playback begins at that marker; supported unmuted, default-scale Audio Clips (including 2026 clips with no scale field) and Pattern Clips before it can be launched from their context menu, with one active clip per Playlist track. The track header menu or a Playlist clip context menu can stop its track’s launched clip at the next safe audio tick. Launch timing uses the track's saved Trigger Sync and Tolerant settings; the current clip continues until the replacement reaches its scheduled boundary. Shift-click, the Queue setting, and the Queue this clip action preserve request order per track; queued replacements start at the current clip's next cycle boundary, with Position Sync evaluated at that start. The manual documents selection order but not this boundary timing, which remains inferred pending native comparison. Position Sync Off starts at the clip beginning; Auto uses the clip-relative song phase, while fixed beat modes start at the nearest matching subdivision within the current bar. Pattern notes and supported Audio Clips begin at the selected phase, reach the clip end, then loop from the beginning; loops follow Playlist tempo automation. The Position Sync phase mapping and Tolerant late-window behavior still need native comparison. Performance Mode supports Sampler and loaded VST3 Pattern Clip launches, including clips that mix both destination types. Layer notes route only when each listed direct child is an enabled Sampler or loaded VST3; Layer Random remains stable per placed note and saved key regions filter routing. Nested Layers and unsupported or unavailable child types are excluded. Scenes, controller launching, and Motion behavior work for supported clips. Song transport also schedules Sampler and loaded VST3 instrument notes from Playlist Pattern Clips; Layer notes route to enabled supported child channels, and Layer Random chooses one child per placed note using a stable pseudo-random choice shared by both renderers. This selection is not verified against FL Studio’s native Random sequence. Matching installed VST3 channels load when the project opens, while unavailable or unrecognized channels remain unmapped. Sampler playback uses a provisional C5 root, channel-level gain/pan mapping, and pattern-length inference; Layer level/pan, key/velocity splits, Sequential mode, Crossfade, envelopes, loops, unsupported Mixer mappings, sidechains, and guaranteed underrun-free processing remain incomplete.

The native full-song render is still incomplete: the desktop Render Playlist mix… action combines supported enabled audio clips, Sampler notes, and mapped installed VST3 instruments into bounded-block WAV (16/24-bit integer PCM or 32-bit float), FLAC (16/24-bit integer), Ogg Vorbis (64–450 kbps target average bitrate), or MP3 (32–320 kbps constant bitrate at 32/44.1/48 kHz). All formats support stereo/merged-mono/left-only/right-only channel modes and fixed 0/1/2/5-second tails after the last scheduled clip. Off, TPDF, or high-pass TPDF dither is available for 16-bit WAV; the selected mode also applies during MP3 16-bit quantization. FLAC uses the encoder defaults. Resampling offers Linear, 6-point Hermite, or 16/24/32/64/128/256/512-point windowed-sinc (32-point sinc by default, with the last choice retained between launches), and uses the project's base tempo with provisional channel gain/pan and repeat behavior. Non-default scaled clips are skipped and reported; unsupported Mixer route mappings and native sidechain-bus mapping, FL Studio's shaped dither and exact resampling kernels, normalization, non-Master effect-tail detection, and native output comparison remain incomplete. render-pattern-vst3 renders one decoded pattern channel through a selected installed VST3 instrument to WAV, FLAC, Ogg Vorbis, or MP3 based on the output extension, scheduling notes from the project's PPQ and tempo and appending an optional release tail (2 seconds by default). The CLI defaults to 32-bit float WAV, 24-bit FLAC, and 192 kbps Ogg/MP3; the desktop render shares the selected Playlist export format, depth, bitrate, dither, and channel mode. Rendering streams plug-in blocks directly to the output, and accepts mono or stereo VST3 buses. render-pattern-samplers <project.flp> <pattern-id> <output.wav> [sample-rate] [voice-limit] renders enabled kind-0 Sampler notes from one pattern to stereo float WAV, with bounded voices and streaming preview support. Its default MIDI-60 root-key assumption, local 32-point sinc filter, gain/pan mapping, and note envelopes still need native comparison. render-audio-clips separately mixes Playlist clips targeting enabled audio channels into a stereo float WAV. These are early paths, not full FL Studio render parity. The reader exposes channel summaries (including kind-0 Sampler and kind-4 sample-backed channel paths), patterns and notes, Playlist track names and arrangement clips, and opaque channel plug-in payloads; most other event meanings remain opaque. playlist accepts an optional starting clip and count. plugin-states reports channel plug-in payload sizes and event indices without decoding them. edit-note changes an existing note's start, length, key, and velocity while retaining its other note fields. add-note appends a 24-byte note record to a pattern; for an empty pattern it uses a note-event encoding observed elsewhere in the project and refuses to guess when encodings conflict. delete-note removes a channel-scoped note by zero-based index. These note operations rewrite only the affected score event and its length prefix. edit-clip changes an existing Playlist clip's position and length while retaining the other record bytes; delete-playlist-clip removes one clip by its zero-based arrangement index; edit-clip-properties edits recognized raw fields, offsets, and scale without rewriting unrelated record bytes. set-tempo and rename-channel edit existing fields and preserve every unrelated event's original wire bytes. duplicate-channel copies a kind-0 Sampler, kind-2 Native instrument, or kind-5 Automation channel, preserving its saved channel state and curve data while assigning a new channel ID and name; the Channel Rack context menu offers the same action. The CLI can create empty patterns when the note-event encoding is unambiguous, duplicate existing Playlist clips, create Sampler or sample-backed Audio Clip channels from a sample path and display name, and create Playlist Pattern or Audio Clips from recognized record templates. Audio Clip creation uses an existing sample-backed Audio Clip channel. Targetless Playlist clips and projects without the matching clip template remain unsupported.

The Standard MIDI File reader recognizes the MThd header and MTrk event streams, including running-status channel messages, meta events, SysEx, system messages, PPQ timing, and SMPTE timing at -24, -25, drop-frame -29.97, or -30 frames per second. midi-info reports track names, timing, paired note events, and tempo-map spans. import-midi appends notes from one MIDI track to an existing FLP pattern and channel, and imports MIDI time-signature events as Pattern-scoped markers. Format-1 imports read meter changes across tracks, while format-0 and format-2 imports read the selected track. Marker positions follow the MIDI tempo map or SMPTE clock and are converted to the existing project's tempo/PPQ grid. The importer snapshots MIDI CC 10 pan, CC 74 Mod X, CC 71 Mod Y, and pitch bend at each Note On into the corresponding FL note properties. MIDI CC 64 sustain extends each released note through pedal-up; CC 66 sostenuto holds only notes already active when the pedal transitions down. If both pedals hold a note, it ends when the last holding pedal goes up, retaining the paired Note Off release velocity. CC 120 All Sound Off ends active and pedal-held notes immediately on its channel. CC 123–127 end active notes like Note Off and respect both pedals; because these controllers carry no release velocity, imported notes use the default FL note release. CC 121 Reset All Controllers ends deferred notes and restores imported controller snapshots to their defaults. Missing CC 10/74/71 values use center 64, which maps to FL Mod X/Y default 128; pitch sensitivity follows MIDI RPN 0 when present or assumes ±2 semitones otherwise. Later pan, Mod X/Y, or bend changes during held notes remain unimported. PPQ tempo changes and SMPTE clock times are converted to note positions at the project's existing tempo, preserving elapsed note timing while leaving the FLP tempo and unrelated event bytes unchanged. When a PPQ file has no tempo events, the project tempo supplies the source timing baseline. Unclosed MIDI notes use the remaining track duration, or one beat if the track ends at the note start. export-midi-pattern writes one pattern, while export-midi-song expands Pattern Clips in one arrangement; both can write format-0 MIDI as one merged track or format-1 MIDI with a conductor track and separate channel tracks; format 1 is the default. Both retain project PPQ, base tempo, and time signature. Both exports write note pan as MIDI CC 10, mapping FL's 0–128 range to 0–127 with 64 at center. Note Mod X/Mod Y map to MIDI CC 74 (brightness/filter cutoff) and CC 71 (timbre/harmonic intensity), scaling FL's 0–255 range to 0–127. Overlapping notes with different pan, Mod X/Mod Y, or pitch use spare MIDI channels when available; otherwise export returns an error. These controller mappings are export extensions pending comparison with FL Studio's native MIDI export. Song export writes arrangement markers and time-signature changes to the conductor track in Format 1 or the merged track in Format 0. Format 0 preserves channel names as text events. The optional stored mapping keeps the low four bits of each note's stored channel; channels assigns channel numbers by FL channel order, wrapping after 16. Arrangement export currently skips audio clips, rejects non-default Pattern Clip scale, and requires a Playlist layout the reader can decode. export-midi-cc exports one raw Pattern controller stream as format-0 MIDI with a merged track or format-1 MIDI with separate conductor and controller tracks; Format 1 is the default. the raw channel/flags, MIDI CC number, and one-based MIDI channel are supplied explicitly because the stream does not encode those mappings. Pattern ticks and project PPQ are preserved, and values clamp to 0.0–1.0 before mapping to MIDI 0–127. Tempo-map import is baked into note timing rather than creating FL tempo automation. import-midi-cc imports one selected MIDI Control Change number from a track into a chosen existing raw Pattern controller stream; import-midi-cc-new-stream creates a new raw stream from supplied channel/flags bytes. Both can filter to one MIDI channel, convert source tempo-map or SMPTE timing to project ticks, and map values from MIDI 0–127 to 0.0–1.0. A new stream starts at the first imported point and is not created when there are no matching CC messages. import-midi-sampler-tracks <input.flp> <input.mid> <output.flp> <pattern-id> <template-channel-id> creates one named kind-0 Sampler channel per format-0/1 track by copying an existing Sampler template. import-midi-template-tracks supports selected format-0/1 tracks, an existing or new Pattern, Sampler, MIDI Out, Native, or Layer templates, and MIDI import options; import-midi-template-format2 creates a new Pattern and named channel copied from a Sampler, MIDI Out, Native, or Layer template for each selected independent Format-2 sequence. MIDI Out copies retain saved routing; Layer copies retain their saved child references. import-midi-format2 retains its Sampler behavior for compatibility. import-midi-new-project <template.flp> <input.mid> <output.flp> <template-channel-id> <track-numbers> builds a separate project from an FLP template; format-0/1 tracks share one Pattern, while selected Format-2 sequences each receive a separate Pattern. The desktop can use the installed Empty.flp or a user-selected template. Other channel kinds remain unsupported for template-based MIDI import.

export-midi-cc writes one raw Pattern 0xDF controller stream as a selected MIDI CC number and channel in format 0 (one merged track) or format 1 (conductor plus controller tracks). export-midi-song-cc applies that mapping to every matching Pattern Clip in the selected arrangement, repeating events by the saved or note-inferred Pattern loop length when available, otherwise using one pass per clip, clipping at clip boundaries, honoring recognized 88-byte Pattern tick source windows whose span matches the clip length, and retaining tempo automation and markers in the conductor track for Format 1 or merged track for Format 0. The default file format is Format 1. The raw stream does not identify its MIDI controller or channel, so both are supplied explicitly; scaled clips and unrecognized legacy source windows remain unsupported. scan <directory> inventories .flp and .fst files recursively, grouping successfully parsed files by project version, header format, and PPQ while reporting any unparsed files. plugin-scan lists VST3 bundles and platform VST2 module or bundle candidates (.dll, .so, and macOS .vst) without loading their code. vst2-info loads a selected VST2 file in an isolated child process and reports its classes, including VST2 unique IDs for ordinary modules and shell child IDs. render-vst2-note sends one MIDI note through the first class and its first main output bus, compensates host and plug-in latency, and writes at most the first two output channels. render-audio-vst2 processes a mono or stereo file through the first class's main audio buses, removes latency, adds a tail of up to 60 seconds, limits input plus tail to 120 seconds, and writes at most two channels to WAV with output storage capped at 512 MiB. The one-note and audio-effect commands do not restore FLP state; none open the plug-in editor or route instances through Playlist or Mixer playback. plugin-states reports recognized VST wrapper markers and VST2 FourCC identifiers when present; plugin-state-preview also shows the nested state prefix alongside opaque wrapper and payload bytes. vst2-state-probe checks the saved FourCC against one isolated-worker class, loads field 53, and reports whether a new worker snapshot matches the saved bytes exactly; that check does not establish audio equivalence. render-pattern-vst2 selects the VST2 class by the saved channel FourCC, restores nested field 53, and renders unmuted Pattern notes at project tempo and swing to a WAV channel stem; it applies note key, velocity, MIDI channel, and Add-to-Key transposition. It compensates worker and plug-in latency and writes at most two channels. FLP per-note pitch, pan, release, modulation, Mixer routing, and effects are not applied, so this is not full project-render parity. vst3-state-probe loads a VST3 and restores the selected channel's field-53 component/controller records through the host snapshot interface. In the local ZENOLOGY project, the restored component stream matches nested FLP record 3 byte-for-byte; plug-in audio and parameter equivalence still require comparison against FL Studio. State layouts outside the recognized marker-12 record format are rejected with an error.

The original application's MIDI export experiments and their measured results are recorded in docs/oracle-experiments.md. midi-events displays a selected MIDI track's decoded events, including tempo and marker metadata, for further format comparison.

Channel Rack colors, levels, and swing

The Channel Rack inspector exposes the five ordered Sampler 0xDA Envelope/LFO records as raw Panning, Volume, Mod X, Mod Y, and Pitch controls. The channels command prints the decoded records, and the generic editor can change envelope and LFO flags and raw fields while preserving unedited values, unknown flag bits, trailing bytes, and unrelated events. edit-sampler-envelope-lfo takes a target plus - for each field to leave unchanged; envelope and LFO time values use 100..=65536, LFO speed uses 200..=65536, sustain uses 0..=128, amounts and tensions use -128..=128, and LFO shape uses 0 (Sine), 1 (Triangle), or 2 (Pulse). The older edit-sampler-volume-envelope command remains as a Volume-only compatibility command. These field meanings and ranges follow the third-party PyFLP parser and still need a controlled FL Studio save comparison. Supported Sampler playback applies Panning, Volume, and Pitch envelope stages and LFOs; Mod X/Mod Y note values, envelopes, and LFOs modulate filter cutoff and resonance. Envelope tension and tempo-synced timing use provisional mappings, and raw amount/depth scaling still needs controlled FL Studio save and render comparison.

channels <file.flp> reports raw channel color, volume, and pan values when present, along with observed sample source paths, enabled state, zipped state, Enable main pitch, Add to Key, and the decoded playable key region. set-channel-enabled <input.flp> <output.flp> <channel-id> <0|1> edits the saved enabled/muted state, preserving other channel events and inserting the state event when needed. set-channel-sample-path <input.flp> <output.flp> <channel-id> <sample-path> changes the recognized 0xC4 path on an existing Sampler or Audio Clip channel while preserving its project string encoding and unrelated events. set-channel-zipped <input.flp> <output.flp> <channel-id> <0|1> edits the compact Channel Rack state, inserting the event after the channel kind when needed. Zipped rows keep their step cells inline and hide secondary controls. The desktop Channel Rack exposes a per-row color swatch and picker plus compact type icons with hover descriptions. Sampler, generator, Layer, Instrument, and Automation kinds use distinct glyphs; unknown kinds show their raw type value. set-channel-color <input.flp> <output.flp> <channel-id> <RRGGBB> edits the RGB components and retains the fourth color byte. set-channel-colors applies one color to the listed channel IDs. set-channel-color-gradient applies a linear RGB gradient in the supplied channel order, from the start color on the first channel to the end color on the last; it requires at least two unique IDs. Both operations preserve existing fourth color bytes. move-channel moves one row to a zero-based target index. reorder-channels takes a complete permutation of every channel ID. sort-channels accepts color, mixer-track, name, or type. Color sorting follows hue from red through violet, with achromatic and uncolored channels afterward. Click a channel name to select it, Ctrl/Cmd-click to toggle it in the selection, Shift-click to extend a contiguous selection, or double-click to select all channels. The row context menu can add/remove a channel from the selection, select only that channel, delete the current or selected channels, and toggle Enable main pitch and Add to Key on supported channel types. The Channel Rack’s Playable key range controls edit an existing inclusive key region; set-channel-key-region <input.flp> <output.flp> <channel-id> <low-key> <high-key> updates a unique recognized Parameters event and preserves its other bytes. set-channel-sampler-root-key <input.flp> <output.flp> <sampler-channel-id> <root-midi-key> edits or inserts the Sampler root-note dword (0x87) while preserving unrelated channel events. The Channel Rack’s Sampler root note control edits the same saved value. The Channel Rack also applies one color transactionally to every selected channel, interpolates a linear RGB gradient from the first to last selected row's stored colors, and mutes or unmutes all selected channels. set-channel-main-pitch <input.flp> <output.flp> <channel-id> <0|1> edits Enable main pitch; set-channel-add-to-key <input.flp> <output.flp> <channel-id> <0|1> edits Add to Key. Supported Sampler and hosted VST3 notes use continuous cents pitch unless Add to Key is enabled, which transposes them by the nearest semitone; unstretched Playlist Audio Clips (scale unset or 1.0) use continuous project Master pitch. VST3 Root Key offsets, native instruments, and stretched Audio Clips remain incomplete. Per-row Up/Down controls reorder complete channel event blocks without changing channel IDs, and the Sort by menu orders channels by color, name, or type. Right-click a channel name and choose Piano roll to open that channel in the selected pattern. The Channels menu offers Zip selected, Unzip selected, and Unzip all; Alt/Option+Z zips the selection and Alt/Option+U unzips all; per-row context menus zip or unzip one channel. set-channel-levels edits those first two fields and preserves the remaining event payload. set-channel-swing <input.flp> <output.flp> <channel-id> <percent-0..100> edits the channel swing multiplier; its 0x61 word stores 0–128, with 128 meaning 100% and a missing event defaulting to 100%. The Channel Rack header exposes global swing, while each row context menu edits its own multiplier. Both menus offer FL-style 0/25/50/75/100% presets and a custom percentage slider. Global swing is stored in project event 0x0B (byte, 0–128, default 0) and per-channel swing in channel event 0x61 (word, 0–128, default 128). Pattern playback applies both values to aligned 16th-step onsets; the one-third-step maximum is inferred and needs native FL Studio render comparison. Older byte and word controls are decoded for inspection but remain read-only until their scaling is verified. Playlist audio and Sampler playback apply provisional volume/pan mappings based on observed raw defaults; native FL Studio output has not yet been used to verify the curves.

The channel-groups command lists zero-based group indices, names, and member channel IDs. create-channel-group adds an empty group; group-channels creates or reuses a group with an exact matching name and assigns the listed channel IDs; rename-channel-group changes a group's name; delete-channel-group unassigns its channels and shifts higher group indices down. delete-channels <input.flp> <output.flp> <channel-ids:comma-separated> removes channels, their pattern notes, recognized linked Audio Clip and Automation Playlist clips, and Layer child references. The Channel Rack context menu deletes the current channel or its selected channels, and Alt/Option+Delete deletes the selection.

The Channel Rack step grid selects a pattern and bar, then toggles notes at sixteenth-note positions. New steps use key 60, one step of length, and velocity 100. Cells show counts when multiple notes fall in one step; clicking a populated cell removes all of its notes, and right-clicking opens a key selector to add another note at that step. Open the Graph Editor with Ctrl/Cmd+K to view and edit per-step note key, velocity, pan, release, fine pitch, modulation X/Y, and shift; drawing on an empty step creates a C5 note, right-dragging across steps interpolates a ramp, Ctrl-drag adjusts all active values together, and Alt/Option-click or drag resets active values to the lane default.

Layer children

Layer child relationships and raw flags are available in the project model. The desktop Channel Rack exposes a child selector with channel names and IDs; set-layer-children replaces a Layer channel's repeated 0x5E references while retaining other channel events. Pass comma-separated child IDs or - to clear the list. Playlist pattern notes route through enabled Sampler and mapped VST3 children. The Random option selects one child per note using a stable pseudo-random choice; the exact native sequence, Sequential mode, keyboard/velocity ranges, and Layer level/pan mappings remain incomplete. Layer Crossfade uses the saved Fade position only when every active child subtree resolves to an enabled Sampler. An active external plug-in disables Crossfade for the whole Layer, matching Image-Line’s native-format-only rule (Layer manual). The fade curve still needs native audio comparison.

Mixer

The mixer <file.flp> command reports recognized insert fields and each 0xE1 parameter record's global event index, record index, raw ID, candidate target/slot bits, and signed value. Its output also lists saved send levels and any paired routing flag event/byte location. For a Mixer effect slot with exactly one recognized marker-12 VST3 0xD5 state event, it also reports the class UID and nested state size; the host API restores that state only into a loaded audio effect with a matching UID and can encode edited component/controller state back into the nested FLP stream. The document API writes that stream into field 53 while retaining other wrapper fields and events. set-mixer-parameter-record-value <input.flp> <output.flp> <event-index> <record-index> <signed-value> changes one record's signed value while retaining its prefix, ID, target word, and other records. The desktop Mixer presents recognized insert records as selectable vertical strips, with a Track Inspector for existing names and raw route, color, icon, and event-range fields. rename-mixer-insert <input.flp> <output.flp> <insert-ordinal> <name> edits an existing 0xCC name event while retaining the project's string encoding, terminator convention, and opaque tail bytes. set-mixer-insert-flag <input.flp> <output.flp> <insert-ordinal> <field> <0|1> edits one existing flag (enabled, soloed, polarity-reversed, swap-left-right, or effects-enabled) while preserving reserved and unknown bits. set-mixer-routing-flag <input.flp> <output.flp> <event-index> <flag-byte-index> <0|1> toggles one existing send-routing flag byte at the location reported by mixer. A strip shows editable raw volume and pan controls only when the corpus-derived target convention finds one unique zero-scope record for each; a unique in-range stereo-separation record also gets an editable raw slider. The target-to-visible-track mapping remains unverified. The inspector shows each recognized effect slot and exposes its saved enabled state plus a raw Mix slider when unique, unscoped 0xE1 records use the candidate 64 + insert ordinal mapping. The raw Mix edit range is -6400 through 6400; duplicate, scoped, missing, and out-of-range records stay read-only. The Move up and Move down controls, pointer drag-and-drop, move-mixer-effect-slot <input.flp> <output.flp> <insert-ordinal> <from-slot-0..9> <to-slot-0..9>, and the library API move a slot together with its opaque state events and remap recognized enable/Mix records. Reordering is rejected if unknown slot-parameter records could be affected. Its expandable 0xE1 record list edits raw signed values by exact event and record index, and shows target and slot bits as candidates. Recognized marker-12 VST3 effects auto-load when a matching bundle is installed, restore the saved state, expose an Open editor action in the Mixer slot, and write edited state back when the project is saved; loaded VST3 Mixer effects process on known inserts with route-level PDC across supported saved sends; unsupported route mappings, native sidechain-bus mapping, and offline insert metering remain incomplete. Live Master and recognized direct-route insert peak meters are available. Supported non-Master Audio Clip, Sampler, and loaded VST3 sources follow live Mute, phase-invert, and left/right-swap changes on direct and complete send routes with a 20 ms source smoother during playback.

The Mixer inspector also shows unique, unscoped three-band EQ gain, frequency, and Q values as raw controls. set-mixer-eq-parameter-raw accepts low-gain, mid-gain, high-gain, low-frequency, mid-frequency, high-frequency, low-q, mid-q, or high-q; gain is bounded to -1800 through 1800 and frequency/Q to 0 through 65536. The candidate 64 + insert ordinal mapping is used. Frequency values are nonlinear, duplicate or scoped records remain unavailable, and editing saved EQ values does not process audio.

Automation points

automation <file.flp> lists type-5 channel points, including their four raw tail bytes. edit-automation-point changes a point's position, value, and tension; set-automation-point-tail <input.flp> <output.flp> <channel-id> <point-index> <8-hex-digits> replaces the selected point's four raw bytes without interpreting them as a curve mode. Insert, delete, interpolation, flip, normalization, and Scale Levels operations preserve unmodified point data, the blob header, and its era trailer. New points use a zeroed opaque tail. The API and CLI can initialize a zero-point blob from another type-5 channel in the same project, and copy complete Automation state between channels.

automation-targets <file.flp> lists observed 20-byte 0xE3 records with their raw bytes and candidate source, parameter, and destination fields. It decodes the source channel ID as 16-bit and resolves source and channel-target names and kinds, plus candidate Mixer insert and effect-slot names when available; it also shows the source Automation channel's raw 0xDB Min/Max range. Parameter and destination candidates are interpreted only when the source ID uniquely resolves to a type-5 Automation channel, because 0xE3 also stores other remote-control mappings. The candidate Mixer target decoder uses bits 6–12 for the insert and bits 0–5 for the effect slot, following a 57-example differential survey. PyFLP documents that the channel Levels event is interpreted as Min/Max for Automation channels (source). In desktop playback and rendering, a candidate is applied only when its destination has no unexplained high bits and resolves to a loaded VST3 with an exact matching writable, automatable parameter ID; explicit machine-local links take precedence. Other target types and mappings still need native save/playback comparison.

The desktop Automation view edits point position, value, and tension, shows the selected point's raw tail as hexadecimal, and supports insertion, deletion, interpolation, flip, normalization, Scale Levels, LFO amount edits, and template-based initialization. Its preview, supported linked VST3 playback/renders, and TEMPO export use a bounded single-curve tension approximation. App-local VST3 and CLAP parameter links and CLAP channel volume/pan links apply saved type-5 Min/Max using a provisional mapping from the raw 0–12,800 range to normalized target values; native comparison is still needed. FL Studio's Hold, Stairs, Double/Alt curves, exact tension semantics, and broader native parameter-link execution remains incomplete. App-local VST3 parameter links and linked type-5 Automation Clips are supported when their saved templates and channels are present; candidate native project target records are now available read-only through the API and CLI, desktop playback and rendering also apply candidate native records only when destination bits 14–15 are clear and the loaded VST3 target has an exact writable, automatable parameter-ID match; other target types, native save verification, and legacy Event automation remain incomplete.

Automated checks and installers

GitHub Actions runs formatting checks, Clippy, and the Rust test suite on native x64 and ARM64 runners for Linux and Windows, and on Apple Silicon for macOS. Each job builds and launches its desktop app. CI uploads a macOS ARM64 DMG; Windows x64 and ARM64 setup installers; and, for both Linux architectures, AppImage, Debian (.deb), RPM (.rpm), and Arch (.pkg.tar.zst) packages. Linux package metadata and executable architectures are checked before upload. Artifacts are named installers-<platform> and retained for 14 days. The macOS DMG is signed and notarized when Apple signing secrets are configured, and unsigned otherwise. See macOS CI packaging. The package definitions are in Packager.toml.

Compatibility plan

  1. Project containers: broaden FLP envelope compatibility across releases, add semantic FST preset support, and complete ZIP package sample collection and validation.
  2. Musical model: broaden pattern and note editing, then decode channel and plugin state, Playlist clip variants, automation, mixer routing, and audio-channel clip state, while retaining unsupported fields.
  3. Interchange: MIDI import/export and audio export with stable timing and channel mapping.
  4. Playback: connect the shared/exclusive live device engine to transport, tempo clock, sample scheduling, mixing, and automation.
  5. Instruments and effects: continue VST3 hosting from the current project-open loading and state-restore subset, native editor window, parameter-list prototype, and single-pattern offline render into broader project-state support, state write-back, automation, MIDI/audio routing, Mixer processing, and whole-project rendering. Add VST2 hosting if an applicable legacy licensing path is available. Preserve plug-in identity and opaque state when a plug-in is unavailable. Rebuilding FL's bundled plug-in DSP is out of scope.
  6. User experience: project browser, Playlist, piano roll, channel rack, mixer, plugin windows, editing tools, shortcuts, and accessibility.
  7. Historical compatibility: fixture-driven support across older FLP versions, with explicit reporting where a project depends on unavailable plugins or media.

Full feature parity is a long-running objective. Each milestone should keep unsupported project data intact so opening and saving a project does not silently destroy state. Installed plug-ins are treated as external instruments/effects to host, rather than DSP to reimplement.

Product references

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages