Community程式設計與開發github.com

FM3 .syx 編輯器

無需 FM3-Edit,即可讀取、分析與編輯 Fractal FM3 預設保存檔案 (.syx) — 透過 USB 拉取存儲預設、列出其網格、區塊、頻道、場景與調製器,更改參數值、交換區塊類型、重新命名、重新定位至另一個插槽、比對兩個存檔,然後將檔案推回至插槽。當使用者要求檢視、比較、複製或修改 FM3 預設或 .syx 檔案、透過檔案建構音色,或使用桌面控制驅動 FM3-Edit 過於緩慢時使用。

FM3 .syx 編輯器 是什麼?

此技能提供一個全面的命令列工具集,用於管理 Fractal FM3 預設存檔 (.syx) 和系統設置,完全獨立於官方的 FM3-Edit 軟體。它能讓開發者或進階使用者在不需桌面應用程式的圖形介面情況下,直接透過 USB 序列埠通訊來拉取、推回、檢查和修改預設內容。功能包括詳盡的預設調檢視 (列出所有區塊、參數、場景、調製器)、精準的參數級讀取/寫入 (支援純量值、列舉選項和原始十六進位數據)、場景控制、MIDI 控制、格網單元操作,以及進行兩個預設檔案之間逐參數的差異比對。 該技能也涵蓋全域系統設定,例如 I/O 設定、MIDI 設定、腳踏開關佈局以及場景控制器,透過專用命令 (`fm3sys.mjs`, `fm3fc.mjs`, `fcset.mjs`) 進行管理。這在不需要開啟 FM3-Edit 的情況下進行批次編輯、持續整合驗證、備份或雙向同步設定甚至 FC 腳踏控制器佈局時特別有價值。 支援的平台包括 Claude Code、Coder 以及支援以檔案為基礎的工具呼叫的任何 AI 代理環境。該技能參考了基於逆向工程 FM3 通訊協定、韌體物件格式和校準比例的高品質程式庫,最終在大多數參數上達到位元組等級的準確性,並且對於未文件化的 FC 參數提供了明確的安全性規則,以防止設備凍結。對於使用 Fractal Audio 設備的現場音響工程師和音色設計師來說,這使得在自動化工作流程中無需使用圖形介面編輯器即可實現精確的程式化預設管理。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/TheCoolHippo/fm3-syx-editor/tree/HEAD

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

FM3 .syx 編輯器 是做什麼的?

一個腳本搞定一切:scripts/fm3syx.mjs。它重用了 mcp-midi-control v0.8.0 附帶的編解碼器,因此請使用該套件的 node 來執行:

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

命令

命令說明
pull <slot> <out.syx>從 FM3 讀取一個已儲存的預設,使用 COM7 (無需 FM3-Edit)
info <file>插槽、名稱、場景、網格行、每個頻道的區塊類型、場景頻道/旁通、調製器
params <file> <Block[#n]> [ch]一個區塊的每個參數:名稱、原始單字、顯示值
get <file> <Block> <ch> <PARAM>一個值
set <in> <out> <Block> <ch> <PARAM> <val> ...val = FM3 顯示的顯示值 (40 Hz, -12 dB, 3.5)、選項名稱 (post, "Analog Stereo") 或 raw:N
scenename <in> <out> <1-8> <name>場景名稱 (31 個字元)
cell <in> <out> <row> <col> [Block|Shunt|empty] [from=1,2|none]網格單元 + 哪些行饋入它 (連接線)。行列從 1 開始,如同 FM3-Edit
add <in> <out> <row> <col> <Block[#n]> [from=1,2]使用 FM3 的預設值 (defaults/<eid>.bin) 的新區塊
midi <in> <out> <scene> [pc:ch:val|cc:ch:num:val|-]...一個場景的場景 MIDI 行;使用 add ... MIDI 添加區塊 (eid 190,無網格連接線)。已驗證:重建的預設與 FM3-Edit 儲存的預設位元組完全一致,並已在場景變換和預設載入時測試過
midishow <file>所有場景的場景 MIDI 行
remove <in> <out> <Block[#n]>刪除一個區塊 (網格單元 + 記錄)
scenectl <in> <out> <1-4> <%> [x8]場景控制器 1-4 每個場景的值 (一個值 = 所有 8 個場景)
mods <file> [all] / mod <in> <out> <1-32> FIELD=val ...32 個調製器:CTRLID (來源名稱), EFFECTID (區塊), PARAM (參數名稱), MIN/MAX/STARTPT/MIDPT/ENDPT (N% 或原始值), SLOPE, DAMPING, AUTOENGAGE, PCRESET, SCALE, OFFSET…
type <in> <out> <Block> <ch> <name> / types <Block>交換 / 列出類型 (Amp, Reverb, Drive, Delay, Chorus, Comp, Filter, Flanger, Phaser, Wah, Tremolo)
rename <in> <out> <name>預設名稱
slot <in> <out> <N>將檔案重新定位到插槽 N (標頭 + 檢查碼)
diff <a> <b>逐參數差異,按名稱顯示
learn <file> <Block> <ch> <PARAM> <display>將一個原始→顯示的校準點添加到 calib.json
node cpu.mjs [preset]目前載入預設的即時 CPU (DSP) 負載,如同 FM3-Edit 顯示的那樣 (若給定預設則先切換)。在 80 % 或更高時退出碼為 2
push <file> --yes將檔案儲存至其標頭中的插槽

PARAM = 種類名稱 (PITCH_FEEDBACK1,或僅 FEEDBACK1) 或 FM3-Edit 標籤 (Feedback 1)。 Block#2 選取第二個同名區塊 (Return#2)。

規則 (絕不違反)

  • 受保護的插槽:將它們列在 scripts/fm3-local.json 中 ({"protected":[383]},已添加到 git 忽略清單) 或 FM3_PROTECTED;push 和 harvest.mjs 會拒絕它們。
  • push = 在設備上儲存:每次都必須先詢問使用者,並告知是哪個插槽。 先 pull 目標插槽,以便備份將被覆蓋的內容。
  • FM3 連接埠 (COM7,由 FM3_PORT 覆蓋) 是獨佔的:關閉 FM3-Edit 或使用「設定 > 暫停通訊」;沒有 mcp-midi-control 伺服器可以持有它。
  • 永遠不要探查 FC 區塊 (效果 id 199)。
  • CPU:Fractal 表示絕不超過 80 %。 每次 add + push 後,載入預設並執行 cpu.mjs; 達到 80 % 或更高時,在保留預設前移除/簡化區塊。一次只添加一個重型區塊 (Amp, Cab, Pitch, Reverb)。
  • 處理副本 (set in out):保持拉取到的原始檔案不變。

檔案的建構方式 (驗證於 2026-11-03)

  • .syx = 0x77 標頭 (位元組 6-7 為 14 位元的插槽,位元組 11 為 XOR 檢查碼) + 8 × 0x78 區塊 (壓縮的音色,CRC 檢查) + 0x79 XOR 結束碼。每個 FM3 預設 24,680 位元組。 編解碼器在每次寫入時重新壓縮並重新計算 CRC + 結束碼。
  • 解壓縮的主體:區塊鏈;每個區塊都有一個標頭 (23 個字:場景頻道、場景旁通…),然後是一個每個頻道的參數陣列:rows 個頻道 × cols 個字。
  • 字索引 = FM3 paramId − 6 (paramId 來自 fractal-midi/dist/gen3/fm3,從 FM3-Edit 挖掘的)。已在 Amp (drive/bass/mid/treble/master/presence/depth)、Pitch (shift/pan/feedback/mix/level/splice) 和 Delay (time) 上檢查過。ParamId 0-5 位於標頭字 17-22 中 (同樣的公式適用)。
  • 數值為原始 uint16 0..65534 (與實時線路相同),除了儲存為純整數的整數參數:類型/型號、列舉、速度除法、半音 (有符號:12 = +12, 0 = 0)。
  • 在 FM3-Edit 中檢查的比例 (驗證於 2026-11-03),儲存在規範腳本旁邊的 calib.json 中:
    • 線性:百分比、雙極百分比、旋鈕 0-10、Pitch feedback 0..100 %、Pitch detune −50..+50 ct、電平 −80..+20 dB (52427 = 0 dB)、Delay FEED −100..+100 %。
    • 對數:Hz = min·(max/min)^(raw/65534) 使用目錄的 displayMin/Max (Pitch high cut 200..20000 Hz,42631 = 4000 Hz)。腳本會自動為單位 hz 執行此操作。
    • 點:Delay TIME 2044 = 500 ms;Reverb TIME 2034 = 3.20 s,5085 = 7.85 s。
    • 速度列舉 (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 (不是 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 顯示 id+1,29 = "30: 2x12 Texas Star"),AUTO_ALIGN raw:1。 未知的比例?設定一個原始猜測值,推送到設備,讀取 FM3-Edit,然後添加校準點 (learn)。
  • 區塊標頭:字 −1 = 場景-1 頻道,字 0..6 = 場景 2-8 頻道 (0=A..3=D), 字 7..14 = 場景 1-8 旁通 (1 = 已旁通);scene 命令編輯它們。
  • FM3 將推送的傾印資料直接儲存到其標頭中的插槽 (無需額外儲存)。

覆蓋範圍 (驗證於 2026-11-03)

  • 控制區塊 = 整個控制器選單 (速度、LFO 1/2、ADSR 1/2、定序器、包絡、Manual 1-5、場景控制器):系列 CONTROLLERS,eid 2,130 個參數 × 4 個頻道,緊接在網格之後 (主體 0x1c4)。像任何區塊一樣編輯它:set f out Control A TEMPO raw:120 (速度 = 純 BPM), params f Control A。編解碼器的場景控制器偏移量是錯誤的 (差了 9 個字);請使用 scenectl。
  • 已在 FM3-Edit 的 FM3 上驗證:場景名稱、網格單元/連接線、add/remove、調製器 (mod 2 CTRLID="LFO 1A" EFFECTID=Delay PARAM=MIX MIN=10% MAX=40% 使 Delay 混合旋鈕移動起來)、 場景控制器、速度。
  • 實時輸出音量計 (子 0x2E parseGen3LiveMeters output_left/right) 在沒有訊號時返回隨機值:無法使用。場景響度必須通過 USB 重錄音錄製來測量。
  • scales.json:34 個區塊系列的 1,390 個參數已根據 FM3 自身的顯示文字進行校準 (calibrate.mjs 實時掃描每個參數並讀取回顯;calfix.mjs 第二遍)。連續參數 是擬合線性/對數或插值的;列舉會雙向映射名稱。calib.json (手動檢查) 優先於它。 未涵蓋:沒有文字的參數 (某些 MIX/圖形參數,73 個條目為空),Plex (FM3 拒絕放置它)。
  • 主體中的每一筆記錄 = eid 字 + 5 個字 + 23 字標頭 + cols×rows 字。順序:32 個 MOD 記錄 (eid 3..34 = 調製器 1..32),然後是區塊,然後是 eid 201 和 eid 200 (每個預設的腳踏開關數據, 1525 個字:僅供參考的知識,永遠不要實時探查它)。編解碼器按大小命名區塊,並且有些弄錯了 (Input/Output 顯示為 Vol/Pan/PEQ);fm3syx 會重新標記它們。
  • 僅放置在網格中的區塊以所有參數為 0 (電平 −80 dB) 出現:始終使用 add,它會插入從 FM3 取得的預設記錄 (harvest.mjs <scratchSlot> <restore.syx> [eids], 每批次一個區塊,使用 BATCH=1:一次放置多個重型區塊曾導致 FM3 凍結)。
  • 從未儲存過的插槽 (<EMPTY>) 使用編解碼器無法解碼的另一種容器:在儲存一次後再拉取它。

無需 FM3-Edit 也能運作

這裡的所有內容都直接透過 USB (預設為 COM7,如果連接埠變更則設定 FM3_PORT) 與 FM3 通訊:pull、push、switch.mjs、cpu.mjs、fm3ctl.mjs (場景選擇、循環器按鈕)、levels.py (透過 USB 錄製場景響度)。 完全不需要 FM3-Edit。無需它即可驗證變更:push → 再次 pull → cmp/diff (0 個位元組 = FM3 儲存了與發送內容完全相同的資料) → switch.mjs <other> 然後 switch.mjs <slot> 來載入它 → cpu.mjs (< 80 %)。FM3-Edit 僅在建構此技能時用於目測檢查結果。

全域 (設定) 設定 — fm3sys.mjs + sendsys.mjs (驗證於 2026-11-03)

全域設定不在預設中。它們作為一個完整的系統庫傳輸,大小為 197 kB,共 66 幀。使用 node pullsystem.mjs <out.syx> 讀取它 (關閉 FM3-Edit,唯讀,請求功能碼 0x43 如同 Fractal-Bot 發送的那樣, 由 USBPcap 於 2026-11-06 捕獲;輸出與 Fractal-Bot 的 FM3-<date>-system+gb+fc.syx 位元組完全一致)。 該庫包含兩個副本 (字 0.. 和 32768..,每個都有自己的標頭和 CRC)。FM3 會寫入較舊的 副本,並在副本 + 14874 處增加一個儲存計數器,因此最新的副本會交替出現。fm3sys.mjs 和 fm3fc.mjs 將每次編輯寫入兩個副本。

  • 格式:fn 0x51 標頭,64 × fn 0x52 區塊 (2 位元組索引 + 1024 個字,每個字 3 個七位元組),fn 0x53 結束碼 (所有字的 XOR)。不壓縮。字 0 = 0x1008,字 1 = 0xAA55,字 2 = CRC-CCITT (多項式 0x1021,初始值 0xAA55) 針對位元組 8 .. 8 + 字 3,字 3 = 數據長度 (29760)。 全域參數種類 p = 字 4 + p (IN1_SOURCE 61,MIDI_CHAN 68 (0 為基底),LINEFREQ 112,DISPLAY_OFFSET 72…)。
  • fm3sys.mjs get <file> IN1_SOURCE / set <in> <out> IN1_SOURCE 1 / diff a b / check file (修復 CRC、結束碼和幀檢查碼;一個不變的往返行程是位元組完全一致)。
  • MIDI/Remote 表 (驗證於 2026-11-05,透過寫入、讀回和 MC8 測試):Bypass 字 138 + 區塊 id,Channel 字 394 + 區塊 id,External n 字 1305 + n;128 = 無。使用 fm3sys.mjs setword <in> <out> <word> <raw>... 編輯。調製器來源 External 6..16 = ids 19..29。
  • sendsys.mjs <file> --yes 寫入整個庫 (FM3 每幀回應 fn 0x64 代碼 0)。已測試:Display Offset 1 → 0 透過檔案,然後一個新的備份與發送的檔案完全匹配。
  • 規則:始終從一個全新的備份開始 (它包含所有全域設定 + FC 佈局);在發送之前詢問使用者; 保留原始備份以便恢復。永遠不要探查其他請求代碼。

腳踏開關佈局 — fm3fc.mjs (已儲存) + fcset.mjs (即時) (驗證於 2026-11-08)

8 個佈局 + 主佈局位於系統庫中,因此無需探查 FC 區塊。 開關索引 i = 佈局 × 12 + 視圖 × 3 + 開關 (0 為基底;佈局 8 = 主佈局)。在一個副本中的偏移量:

欄位TapHold
類別 (0 未指派,1 庫,2 預設,3 場景,4 效果,5 實用,6 佈局,7 控制開關,8 循環器,9 每個預設,10 視圖,11 Setlist,12 歌曲,13 歌曲區段)1658 + i2630 + i
功能 (FM3-Edit 選單順序: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
標籤模式 (Scene:0 名稱,1 編號,2 自訂;Effect:0 長名稱,1 短名稱,2 長名稱 + 頻道,3 短名稱 + 頻道,4 自訂)1874 + i2846 + i
參數,6 個字 (preset/scene/layout number 1 為基底;Effect = [block, channel];Inc/Dec = [step, wrap, lower, upper],step 65535 = -1)1982 + 6i2954 + 6i
自訂標籤,10 個字元 + 03623 + 11i4811 + 11i
佈局名稱位於 1370 + 32 × 佈局;顏色位於 6000 + i (0 預設,1 紅色,2 橙色…)。
效果區塊編號遵循一個字母順序的內部列表,其中包含隱藏條目;該表位於 fm3fc.mjs
(已驗證: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] 列出每個開關;set <in> <out> <layout> <view> <switch> tap=Effect param="Wah 1" ... 編輯兩個副本。使用 sendsys.mjs 發送的檔案會被儲存,但正在執行的 FM3 會將佈局保留在 RAM 中,直到電源循環 (並且在該之前任何系統儲存都會覆蓋此編輯)。
  • 即時,無需重新啟動:FM3-Edit 使用 fn 0x01 sub 0x09 編輯區塊 199 的一個參數: F0 00 01 74 11 01 09 00 47 01 <pid lo> <pid hi> <float32 以 5 個七位元組呈現,LSB 優先> 00 00 00 00 <xor> F7。 參數 id = 儲存偏移量 − 1658 (tap category i,tap function 108 + i,tap params 324 + 6i + k, hold category 972 + i,tap label mode 216 + i);從文字區域看,這些 id 偏移了 +276:tap custom text 2241 + 11i (每個字元一個參數,值 = 字元代碼,結束後為 0),colour 4618 + i。 fcset.mjs text <layout> <view> <switch> <TEXT> [mode=N] 即時重新命名一個開關。fcset.mjs <pid> <value> ... 會逐位元組重建捕獲的訊息;FM3 會立即套用變更並自己儲存它。從 FM3-Edit 使用 USBPcap 捕獲。
  • 僅設定已知的參數 id。永遠不要向區塊 199 發送 GET (sub 0x1a/0x1b) 以獲取您尚未看到 FM3-Edit 使用的 id:讀取未知的 FC 參數會使 FM3 凍結。

每個預設的開關 — fm3syx.mjs pp/ppset (檔案) + fcset.mjs pp (即時) (驗證於 2026-11-08)

它們位於預設本身中:記錄 eid 200,數據 = 記錄起始 + 23 個字。從那裡開始的偏移量 (j = PP 編號 − 1) 也是區塊 200 上的即時參數 id:

欄位TapHold
類別j216 + j
功能24 + j240 + j
標籤模式48 + j264 + j
參數 (6)72 + 6j288 + 6j
自訂文字 (11)432 + 11j696 + 11j

佈局覆蓋表位於 960 + i (i = 佈局 × 12 + 視圖 × 3 + 開關,值 = PP − 1,65535 = 無);顏色 1069 + j。 代碼與佈局相同 (表在 fcmap.mjs 中)。

  • fm3syx.mjs pp <file> 列出它們;ppset <in> <out> <PP> key=value ... 或 ppset ... override L V S PP|none 編輯一個檔案 (一個腳本化的編輯逐位元組重現了 FM3-Edit 的檔案)。
  • fcset.mjs pp ... 透過與 fcset.mjs 相同的即時通訊編輯預設內部的 PP 記錄, 使用區塊 200 的參數 id。已驗證 (2026-11-08):透過 fcset.mjs pp 2 cat=6 func=5 label=3 params=0,2,65535,0,0,0 text="Scn Up", 開關 2 立即顯示 "Scn Up" 並執行 '場景 +'。發送 params=0,2,65535,0,0,0 嘗試時 FM3-Edit 沒有凍結。

所有腳本的一鍵設定

scripts/setup.mjs 複製 mcp-midi-control 的已發行 .syx 演示檔案、校準表、全域預設記錄 和 calib.json,然後安裝 npm 依賴項、測試載入和語法 (目前未涵蓋 pullsystem.mjs 所需的 node-usb)。'calib.json 為空白時' 依賴於 scales.json (內部開發,在 repo 中為 fm3-scales.json + fm3-units.mjs)。

參考實現

整個技能的原型是單一的 fm3syx.mjs 檔案,並帶有輔助 utilities。 與 mcp-midi-control 的 codec-fm3.mjs 共享解析邏輯。

技術附錄

與 CL 工具的整合

工具端點功能
read_preset拉取、進行 info、params、get、diff、mods、midishow
write_presetslot、scenename、set、cell、add、remove、midi、scenectl、mod、type、rename、ppset (然後 push + cpu)
edit_systemfm3sys.mjs set / setword / fm3fc.mjs set,然後 sendsys.mjs
edit_live_fcfcset.mjs 文字/pp/參數
manage_unitswitch.mjs、pull/push、cpu.mjs (fm3ctl.mjs 場景/循環器)

錯誤邊界

  • SMF 訊息或 pull 端的 CRC 失敗 → 使用者看到“資料損壞,再試一次”,而不是損壞的預設。
  • cpu 命令在 80 %+ 時以退出碼 2 退出,適合 CI 閘道。
  • 如果發生異常崩潰,pull 和 push 外層的包裝腳本會記錄原始操作,以便可以手動重播。

未來方向

  • set 和 params 的 JSON 模式 (供動態參數發現使用)。
  • 完全移除 scales.json (僅使用 calib.json)。
  • 現場收聽 MIDI (筆記型電腦作為 MIDI 監聽器)。
  • 視覺編輯器預覽 (DSP 負載、網格佈局類型)。
  • 與 Fractal-Bot 備份/還原工作流程整合。
  • 降噪器 (待 FM3 韌體支援) 參數。

複雜情況

最低層級是原始存取:非專家使用者可能因覆蓋預設、錯誤的 set 或 pull/push 錯誤而破壞工作音色。 這就是為什麼保護插槽和先拉取再推送是強制性的。

系統架構

腳本將自己呈現為可運行的節點工具。依賴項:mcp-midi-control (或其 node_modules) 中的 fractal-midi、 serialport (用於即時) 和 midi 用於 MIDI 位元組操作。

檔案格式細節

區塊偏移量 (十六進制)大小說明
容器0x000x77 標頭插槽、檢查碼、CRC 容器
音色0x778 × 0x78 區塊壓縮的預設體
結束碼0x77 + 8*0x780x79 結束碼XOR 總和
主體解壓縮後可變區塊鏈 + 腳踏開關數據 (eid 200/201)

這些偏移量是連續的;編解碼器管理框架和區塊化。

相關技能