CommunityCodierung & Entwicklunggithub.com

TheCoolHippo/fm3-syx-editor

Liest, analysiert und bearbeitet Fractal FM3 Preset-Sicherungsdateien (.syx) ohne FM3-Edit – ruft ein gespeichertes Preset über USB ab, listet dessen Grid/Blöcke/Kanäle/Szenen/Modulatoren und jeden Blockparameter auf, ändert Werte, tauscht Blocktypen, benennt um, verschiebt in einen anderen Slot, vergleicht zwei Dateien und legt die Datei wieder in einem Slot ab.

Was ist fm3-syx-editor?

Dieses Tool ermöglicht die vollständige Bearbeitung von Fractal FM3 Preset-Dateien (.syx) ohne die proprietäre FM3-Edit Software. Es kommuniziert direkt mit dem FM3 über USB (Standardport COM7) und bietet eine umfangreiche Befehlszeilenschnittstelle für alle Preset-Aspekte: Blockparameter (Amp, Reverb, Cab, Delay usw.), Grid-Zellen und -Verbindungen, Szenennamen und -MIDI-Befehle, Modulatoren (bis zu 32), Scene-Controller und sogar Per-Preset-Fußschalter. Die Bearbeitung erfolgt auf Dateiebene: Der Benutzer arbeitet mit Kopien, nicht direkt auf dem Gerät. Ein leistungsfähiges diff-Tool zeigt Parameterunterschiede zwischen zwei Dateien an. Das Tool umfasst auch die Bearbeitung von Systemeinstellungen (globale Parameter wie Eingangsquelle, MIDI-Kanal, Display-Offset) und Fußschalter-Layouts, entweder durch Dateibearbeitung (mit nachfolgendem Senden der Systemdatei an das FM3) oder live über MIDI-SysEx-Befehle. Die Skill-Dokumentation ist extrem detailliert und beschreibt das Dateiformat, die Parametrierung (lineare, logarithmische und punktbasierte Skalierung), die katalogisierten Parameter-IDs und die spezifischen Einschränkungen (z. B. geschützte Slots, CPU-Auslastung unter 80 %, lesegeschützte FC-Blöcke). Das Tool wurde umfassend gegen FM3-Edit verifiziert, kann aber vollständig ohne dieses betrieben werden. Es ist als Node.js-Skript (fm3syx.mjs) implementiert und nutzt den Codec aus mcp-midi-control. Der Fokus liegt auf Präzision: Die neu erstellten Preset-Dateien sind Byte-für-Byte identisch mit denen, die FM3-Edit erzeugt.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/TheCoolHippo/fm3-syx-editor/tree/HEAD

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

FM3 .syx Editor

Ein Skript macht alles: scripts/fm3syx.mjs. Es verwendet den Codec, der mit mcp-midi-control v0.8.0 ausgeliefert wird. Führen Sie es daher mit der Node-Installation dieser Version aus:

N="$LOCALAPPDATA/mcp-midi-control/mcp-midi-control-v0.8.0/node.exe"
"$N" scripts/fm3syx.mjs <Befehl> ...

Befehle

BefehlBeschreibung
pull <Slot> <Ausgabe.syx>Liest ein GESPEICHERTES Preset vom FM3 über COM7 (kein FM3-Edit)
info <Datei>Slot, Name, Szenen, Grid-Zeilen, Blocktypen pro Kanal, Szenenkanal/Bypass, Modulatoren
params <Datei> <Block[#n]> [Kanal]Alle Parameter eines Blocks: Name, roher Wert, angezeigter Wert
get <Datei> <Block> <Kanal> <PARAM>Ein einzelner Wert
set <Eingabe> <Ausgabe> <Block> <Kanal> <PARAM> <Wert> ...Wert = Anzeigewert, wie ihn das FM3 zeigt (40 Hz, -12 dB, 3.5), ein Optionsname (post, "Analog Stereo") oder raw:N
scenename <Eingabe> <Ausgabe> <1-8> <Name>Szenenname (31 Zeichen)
`cell [BlockShunt
add <Eingabe> <Ausgabe> <Zeile> <Spalte> <Block[#n]> [von=1,2]Neuer Block mit den werkseitigen Voreinstellungen des FM3 (defaults/<eid>.bin)
`midi [pc:Kanal:Wertcc:Kanal:Nummer:Wert
midishow <Datei>Szenen-MIDI-Zeilen aller Szenen
remove <Eingabe> <Ausgabe> <Block[#n]>Löscht einen Block (Grid-Zellen + Datensatz)
scenectl <Eingabe> <Ausgabe> <1-4> <%> [x8]Scene Controller 1-4 Wert pro Szene (ein Wert = alle 8 Szenen)
mods <Datei> [all] / mod <Eingabe> <Ausgabe> <1-32> FELD=Wert ...Die 32 Modulatoren: CTRLID (Quellenname), EFFECTID (Block), PARAM (Parametername), MIN/MAX/STARTPT/MIDPT/ENDPT (N% oder roh), SLOPE, DAMPING, AUTOENGAGE, PCRESET, SCALE, OFFSET...
type <Eingabe> <Ausgabe> <Block> <Kanal> <Name> / types <Block>Typen tauschen/auflisten (Amp, Reverb, Drive, Delay, Chorus, Comp, Filter, Flanger, Phaser, Wah, Tremolo)
rename <Eingabe> <Ausgabe> <Name>Preset-Name
slot <Eingabe> <Ausgabe> <N>Datei auf Slot N umadressieren (Header + Prüfsumme)
diff <a> <b>Parameterunterschiede, nach Namen
learn <Datei> <Block> <Kanal> <PARAM> <Anzeige>Fügt einen Roh→Anzeige-Kalibrierungspunkt zu calib.json hinzu
node cpu.mjs [Preset]Live-CPU (DSP)-Auslastung des geladenen Presets, wie FM3-Edit sie anzeigt (wechselt zuerst, wenn ein Preset angegeben ist). Exit-Code 2 bei 80 % oder mehr
push <Datei> --yesSpeichert die Datei in den im Header angegebenen Slot

PARAM = Katalogname (PITCH_FEEDBACK1, oder nur FEEDBACK1) oder die FM3-Edit-Bezeichnung (Feedback 1). Block#2 wählt den zweiten Block dieses Namens (Return#2).

Regeln (niemals brechen)

  • Geschützte Slots: Listen Sie sie in scripts/fm3-local.json auf ({"protected":[383]}, git-ignoriert) oder FM3_PROTECTED; push und harvest.mjs lehnen sie ab.
  • push = Speichern auf dem Gerät: Fragen Sie den Benutzer jedes Mal, und nennen Sie den Slot. Führen Sie zuerst pull des Ziel-Slots aus, damit ein Backup des Überschriebenen existiert.
  • Der FM3-Port (COM7, überschreibbar durch FM3_PORT) ist exklusiv: Schließen Sie FM3-Edit oder verwenden Sie Einstellungen > Kommunikation pausieren; kein mcp-midi-control-Server darf ihn halten.
  • Niemals den FC-Block (Effekt-ID 199) abfragen.
  • CPU: Fractal sagt niemals über 80 %. Führen Sie nach jedem add + push das Preset aus und starten Sie cpu.mjs; bei 80 % oder mehr, entfernen/vereinfachen Sie Blöcke, bevor Sie es behalten. Fügen Sie schwere Blöcke (Amp, Cab, Pitch, Reverb) einzeln hinzu.
  • Arbeiten Sie mit Kopien (set Eingabe Ausgabe): Lassen Sie das gezogene Original unberührt.

Wie die Datei aufgebaut ist (verifiziert 2026-11-03)

  • .syx = 0x77 Header (Bytes 6-7 = Slot als 14-Bit, Byte 11 = XOR-Prüfsumme) + 8 × 0x78 Chunks (komprimiertes Patch, CRC-geprüft) + 0x79 XOR-Footer. 24.680 Bytes pro FM3-Preset. Der Codec komprimiert neu und berechnet CRC + Footer bei jedem Schreibvorgang neu.
  • Dekomprimierter Körper: Blockkette; jeder Block hat einen Header (23 Wörter: Szenenkanäle, Szenen-Bypass, …) dann ein pro-Kanal-Parameter-Array: Zeilen Kanäle × Spalten Wörter.
  • Wortindex = FM3 paramId − 6 (paramIds aus fractal-midi/dist/gen3/fm3, extrahiert aus FM3-Edit). Überprüft an Amp (Drive/Bass/Mid/Treble/Master/Präsenz/Tiefe), Pitch (Shift/Pan/Feedback/Mix/Level/Splice) und Delay (Time). ParamIds 0-5 befinden sich in Header-Wörtern 17-22 (gleiche Formel funktioniert).
  • Werte sind rohe uint16 0..65534 (wie beim Live-Draht), AUSSER Integer-Parameter, die als einfache Ints gespeichert werden: Typen/Modelle, Enums, Tempoteilungen, Halbton (vorzeichenbehaftet: 12 = +12, 0 = 0).
  • In FM3-Edit überprüfte Skalen (2026-11-03), gespeichert in calib.json neben dem kanonischen Skript:
    • linear: Prozent, bipolar_prozent, Knob 0-10, Pitch Feedback 0..100 %, Pitch Detune −50..+50 ct, Level −80..+20 dB (52427 = 0 dB), Delay FEED −100..+100 %.
    • log: Hz = min·(max/min)^(raw/65534) unter Verwendung der Katalog-DisplayMin/Max (Pitch High Cut 200..20000 Hz, 42631 = 4000 Hz). Das Skript macht dies automatisch für Einheit hz.
    • Punkte: Delay TIME 2044 = 500 ms; Reverb TIME 2034 = 3,20 s, 5085 = 7,85 s.
    • Tempo-Enum (DTEMPO/TEMPO): 0 None, 11 1/8, 12 1/8 dot, 13 1/4 trip, 14 1/4, 15 1/4 dot.
    • Pitch TYPE (paramId 0): 8 = Crystal Echoes. Delay type = DELAY_MODEL (nicht DELAY_TYPE): 13 = Ambient Stereo, 2 = Analog Mono, 24 = Wandering Delays (types Delay).
    • Cab → DynaCab: CABINET_MODE raw:1 + DYNACAB_TYPE1/2 raw:<id> (types DynaCab; FM3-Edit zeigt id+1, 29 = "30: 2x12 Texas Star"), AUTO_ALIGN raw:1. Unbekannte Skala? Setzen Sie eine rohe Schätzung, pushen Sie, lesen Sie FM3-Edit, fügen Sie den Punkt hinzu (learn).
  • Block-Header: Wort −1 = Szene-1 Kanal, Wörter 0..6 = Szenen 2-8 Kanal (0=A..3=D), Wörter 7..14 = Szene 1-8 Bypass (1 = gebypasst); der scene Befehl bearbeitet sie.
  • Das FM3 speichert einen gepushten Dump direkt in den im Header angegebenen Slot (kein zusätzliches Speichern).

Abdeckung (2026-11-03)

  • Control-Block = das gesamte Controllers-Menü (Tempo, LFO 1/2, ADSR 1/2, Sequenzer, Hüllkurve, Manual 1-5, Scene Controller): Familie CONTROLLERS, eid 2, 130 Parameter × 4 Kanäle, direkt nach dem Grid (Körper 0x1c4). Bearbeiten Sie ihn wie jeden anderen Block: set f out Control A TEMPO raw:120 (Tempo = einfacher BPM), params f Control A. Der Offset des Codecs für Scene-Controller ist falsch (um 9 Wörter verschoben); verwenden Sie scenectl.
  • Verifiziert auf dem FM3 in FM3-Edit: Szenennamen, Grid-Zellen/Kabel, add/remove, Modulator (mod 2 CTRLID="LFO 1A" EFFECTID=Delay PARAM=MIX MIN=10% MAX=40% ließ den Delay-Mix sich bewegen), Scene Controller, Tempo.
  • Live-Pegelmesser (sub 0x2E parseGen3LiveMeters output_left/right) liefert ohne Signal zufällige Werte: nicht verwendbar. Die Szenenlautstärke muss stattdessen durch USB-Re-Amping gemessen werden.
  • scales.json: 1.390 Parameter von 34 Blockfamilien, kalibriert gegen den eigenen Anzeigetext des FM3 (calibrate.mjs durchläuft jeden Parameter live und liest das Echo aus; calfix.mjs zweiter Durchlauf). Kontinuierliche Parameter sind lin/log angepasst oder interpoliert; Enums bilden Namen in beide Richtungen ab. calib.json (manuell geprüft) hat Vorrang davor. Nicht abgedeckt: Parameter ohne Text (einige MIX/Graph-Parameter, 73 Einträge leer), Plex (FM3 weigerte sich, ihn zu platzieren).
  • Jeder Datensatz im Körper = eid Wort + 5 Wörter + 23-Wort-Header + cols×rows Wörter. Reihenfolge: 32 MOD Datensätze (eid 3..34 = Modulatoren 1..32), die Blöcke, dann eid 201 und eid 200 (pro-Preset-Fußschalter-Daten, 1525 Wörter: schreibgeschütztes Wissen, niemals live abfragen). Der Codec benennt Blöcke nach Größe und bekommt einige falsch (Input/Output werden als Vol/Pan/PEQ angezeigt); fm3syx benennt sie um.
  • Ein Block, der nur im Grid platziert wird, erscheint mit ALLEN Parametern auf 0 (Level −80 dB): Verwenden Sie immer add, das den vom FM3 geernteten Standarddatensatz einfügt (harvest.mjs <scratchSlot> <restore.syx> [eids], ein Block pro Charge mit BATCH=1: Das gleichzeitige Platzieren vieler schwerer Blöcke hat das FM3 einmal eingefroren).
  • Ein nie gespeicherter Slot (<EMPTY>) verwendet einen anderen Container, den der Codec nicht dekodieren kann: Ziehen Sie ihn nach einem Speichervorgang.

Funktioniert ohne FM3-Edit

Alles hier kommuniziert direkt mit dem FM3 über USB (standardmäßig COM7, setzen Sie FM3_PORT, wenn sich der Port geändert hat): pull, push, switch.mjs, cpu.mjs, fm3ctl.mjs (Szenenauswahl, Looper-Tasten), levels.py (Szenenlautstärke durch USB-Aufnahme). FM3-Edit wird NICHT benötigt. Überprüfen Sie eine Änderung ohne es: push → pull erneut → cmp/diff (0 Bytes = das FM3 hat genau das gespeichert, was gesendet wurde) → switch.mjs <andere> dann switch.mjs <Slot> um es zu laden → cpu.mjs (< 80 %). FM3-Edit wurde nur während der Erstellung des Skills verwendet, um Ergebnisse zu überprüfen.

Globale (Setup-)Einstellungen — fm3sys.mjs + sendsys.mjs (verifiziert 2026-11-03)

Globale Einstellungen befinden sich nicht in Presets. Sie reisen als gesamte Systembank von 197 kB, 66 Frames. Lesen Sie sie mit node pullsystem.mjs <out.syx> (FM3-Edit geschlossen, schreibgeschützt, Anfrage fn 0x43, wie von Fractal-Bot gesendet, erfasst von USBPcap 2026-11-06; Ausgabe byte-identisch mit einem Fractal-Bot FM3-<date>-system+gb+fc.syx). Die Bank enthält zwei Kopien (Wörter 0.. und 32768.., jede mit eigenem Header und CRC). Das FM3 schreibt die ÄLTERE Kopie und erhöht einen Speicherzähler bei Kopie + 14874, sodass die neueste Kopie abwechselt. fm3sys.mjs und fm3fc.mjs schreiben jede Bearbeitung in beide Kopien.

  • Format: fn 0x51 Header, 64 × fn 0x52 Chunks (2-Byte-Index + 1024 Wörter, 3 Septets pro Wort), fn 0x53 Footer (XOR aller Wörter). NICHT komprimiert. Wort 0 = 0x1008, Wort 1 = 0xAA55, Wort 2 = CRC-CCITT (poly 0x1021, init 0xAA55) über Bytes 8 .. 8 + Wort 3, Wort 3 = Datenlänge (29760). GLOBAL catalog param p = Wort 4 + p (IN1_SOURCE 61, MIDI_CHAN 68 (0-basiert), LINEFREQ 112, DISPLAY_OFFSET 72…).
  • fm3sys.mjs get <Datei> IN1_SOURCE / set <Eingabe> <Ausgabe> IN1_SOURCE 1 / diff a b / check Datei (repariert CRC, Footer und Frame-Prüfsummen; ein unveränderter Roundtrip ist byte-identisch).
  • MIDI/Remote-Tabellen (verifiziert 2026-11-05 durch Schreiben, Zurücklesen und MC8-Tests): Bypass Wort 138 + Block-ID, Kanal Wort 394 + Block-ID, External n Wort 1305 + n; 128 = none. Bearbeiten mit fm3sys.mjs setword <Eingabe> <Ausgabe> <Wort> <raw>.... Modulatorquellen External 6..16 = IDs 19..29.
  • sendsys.mjs <Datei> --yes schreibt die gesamte Bank (FM3 antwortet fn 0x64 code 0 pro Frame). Getestet: Display Offset 1 → 0 per Datei, dann stimmte ein frisches Backup exakt mit der gesendeten Datei überein.
  • Regeln: Beginnen Sie immer mit einem FRISCHEN Backup (es enthält alle globalen Einstellungen + FC-Layouts); fragen Sie den Benutzer vor dem Senden; bewahren Sie das Original-Backup zur Wiederherstellung auf. Niemals nach anderen Anfragecodes suchen.

Fußschalter-Layouts — fm3fc.mjs (gespeichert) + fcset.mjs (live) (verifiziert 2026-11-08)

Die 8 Layouts + Master Layout befinden sich in der Systembank, daher ist keine FC-Block-Abfrage erforderlich. Schalterindex i = Layout × 12 + View × 3 + Switch (0-basiert; Layout 8 = Master Layout). Offsets in einer Kopie:

FeldTapHold
Kategorie (0 Unassigned, 1 Bank, 2 Preset, 3 Scene, 4 Effect, 5 Utility, 6 Layout, 7 Control Switch, 8 Looper, 9 Per-Preset, 10 View, 11 Setlist, 12 Song, 13 Song Section)1658 + i2630 + i
Funktion (FM3-Edit Menüreihenfolge: Utility 0 Tuner 1 Tap Tempo 2 Amp Level+Save 3 Reveal Hold 4 Scene Level+Save; Effect 0 Bypass 1 Chan Select 2 Chan Toggle 3 Chan Inc/Dec)1766 + i2738 + i
Label-Modus (Scene: 0 Name, 1 Number, 2 Custom; Effect: 0 Long Name, 1 Short Name, 2 Long Name + Channel, 3 Short Name + Channel, 4 Custom)1874 + i2846 + i
Parameter, 6 Wörter (Preset/Scene/Layout-Nummer 1-basiert; Effect = [Block, Kanal]; Inc/Dec = [Schritt, Wrap, Lower, Upper], Schritt 65535 = -1)1982 + 6i2954 + 6i
Benutzerdefiniertes Label, 10 Zeichen + 03623 + 11i4811 + 11i
Layout-Namen bei 1370 + 32 × Layout; Farbe bei 6000 + i (0 Standard, 1 rot, 2 orange…).
Effekt-Blocknummern folgen einer alphabetischen internen Liste mit versteckten Einträgen; die Tabelle ist in fm3fc.mjs
(verifiziert: Amp 1 0, Cab 1 1, Chorus 1 2, Comp 1 4, Delay 1 7, Drive 1 9, Drive 2 10, Enhance 1 11, Filter 1 17,
Flanger 1 21, Gate 1 25, GEQ 1 27, In 2 30, MultDly 1 38, Phaser 1 45, Pitch 1 47, Plex 1 48, Reverb 1 51,
Rotary 1 53, TremPan 1 57, Vol/Pan 1 59, Vol/Pan 2 60, Wah 1 61).
  • fm3fc.mjs show <system.syx> [Layout] listet jeden Schalter auf; set <Eingabe> <Ausgabe> <Layout> <View> <Switch> tap=Effect param="Wah 1" ... bearbeitet beide Kopien. Eine mit sendsys.mjs gesendete Datei wird gespeichert, aber das laufende FM3 behält seine Layouts im RAM bis zu einem Neustart (und jeder System-Speichervorgang davor überschreibt die Bearbeitung).
  • Live, kein Neustart: FM3-Edit bearbeitet einen Parameter von Block 199 mit fn 0x01 sub 0x09: F0 00 01 74 11 01 09 00 47 01 <pid lo> <pid hi> <float32 als 5 Septets, LSB zuerst> 00 00 00 00 <xor> F7. Parameter-ID = gespeicherter Offset − 1658 (tap Kategorie i, tap Funktion 108 + i, tap Parameter 324 + 6i + k, hold Kategorie 972 + i, tap Label-Modus 216 + i); vom Textbereich sind die IDs um +276 verschoben: tap benutzerdefinierter Text 2241 + 11i (ein Parameter pro Zeichen, Wert = Zeichencode, 0 nach dem Ende), Farbe 4618 + i. fcset.mjs text <Layout> <View> <Switch> <TEXT> [mode=N] benennt einen Schalter live um. fcset.mjs <pid> <Wert> ... baut die erfassten Nachrichten Byte für Byte wieder auf; das FM3 wendet die Änderung sofort an und speichert sie selbst. Erfasst mit USBPcap von FM3-Edit.
  • NUR bekannte Parameter-IDs SETZEN. Niemals GETs (sub 0x1a/0x1b) an Block 199 für IDs senden, die Sie nicht von FM3-Edit gesehen haben: Das Lesen unbekannter FC-Parameter hat ein FM3 eingefroren.

Pro-Preset-Schalter — fm3syx.mjs pp/ppset (Datei) + fcset.mjs pp (live) (verifiziert 2026-11-08)

Sie befinden sich im Preset selbst: Datensatz eid 200, Daten = Datensatzstart + 23 Wörter. Offsets von dort (j = PP-Nummer − 1) sind auch die Live-Parameter-IDs auf Block 200:

FeldTapHold
Kategoriej216 + j
Funktion24 + j240 + j
Label-Modus48 + j264 + j
Parameter (6)72 + 6j288 + 6j
Benutzerdefinierter Text (11)432 + 11j696 + 11j

Layout-Override-Tabelle bei 960 + i (i = Layout × 12 + View × 3 + Switch, Wert = PP − 1, 65535 = none); Farbe 1069 + j. Codes sind dieselben wie bei den Layouts (Tabellen in fcmap.mjs).

  • fm3syx.mjs pp <Datei> listet sie auf; ppset <Eingabe> <Ausgabe> <PP> Schluessel=Wert ... oder ppset ... override L V S PP|none bearbeitet eine Datei (eine skriptgesteuerte Bearbeitung reproduzierte FM3-Edits Datei Byte für Byte).
  • fcset.mjs p

Verwandte Skills