Community코딩 & 개발github.com

TheCoolHippo/fm3-syx-editor

Fractal FM3 프리셋 저장 파일(.syx)을 FM3-Edit 없이 읽고, 분석하고, 수정합니다. USB를 통해 저장된 프리셋을 가져오고, 그리드/블록/채널/씬/모디파이어 및 모든 블록 파라미터를 나열하고, 값을 변경하고, 블록 유형을 교체하고, 이름을 바꾸고, 다른 슬롯으로 재타겟하고, 두 저장 파일을 비교하고, 파일을 다시 슬롯에 푸시할 수 있습니다. 사용자가 FM3 프리셋이나 .syx 파일을 내부적으로 살펴보거나, 비교, 복사, 수정을 요청하거나, '파일로' 패치를 빌드하거나, 데스크탑 제어로 FM3-Edit을 구동하기에는 너무 느릴 때 사용하세요.

fm3-syx-editor란 무엇인가요?

이 스킬은 Fractal FM3 사용자와 개발자를 위한 강력한 명령줄 도구 모음입니다. FM3-Edit에 의존하지 않고 FM3 프리셋(.syx) 파일을 직접 읽고, 분석하고, 수정할 수 있게 해줍니다. USB를 통해 프리셋을 가져오고(pull), 모든 블록 파라미터를 검사하고(params, get), 값을 변경하고(set), 블록 유형을 교체하고(type), 프리셋 이름을 바꾸고(rename), 다른 슬롯으로 재타겟하는(slot) 등의 작업을 수행할 수 있습니다. 또한 두 프리셋 파일 간의 차이점을 파라미터 수준에서 비교(diff)하고, 수정된 파일을 FM3로 다시 푸시(push)할 수 있습니다. 'add' 명령어를 사용하여 FM3 자체 기본값으로 새 블록을 추가하고, 'midi' 명령어로 씬 MIDI 행을 편집할 수 있습니다. 이 스킬은 FM3 하드웨어와 직접 통신하므로 FM3-Edit이 필요하지 않으며, 대규모 편집 작업을 자동화하거나 스크립트에 통합하는 데 이상적입니다. 주의할 점: 푸시(push) 작업은 항상 사용자 확인을 거쳐야 하며, CPU 사용률이 80%를 초과하지 않도록 해야 합니다. 이 스킬은 Claude Code, Cursor, Codex와 같은 AI 에이전트 및 개발 도구와 함께 사용하도록 설계되었습니다.

지원 대상~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에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

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]그리드 셀 + 이를 공급하는 행 (케이블). 행/열은 FM3-Edit처럼 1부터 시작
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]씬당 Scene Controller 1-4 값 (하나의 값 = 모든 8개 씬)
mods <file> [all] / mod <in> <out> <1-32> FIELD=val ...32개의 모디파이어: CTRLID (소스 이름), EFFECTID (블록), PARAM (파라미터 이름), MIN/MAX/STARTPT/MIDPT/ENDPT (N% 또는 raw), 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에 raw→표시 보정 포인트 추가
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에 있습니다 (동일한 공식 적용).
  • 값은 raw uint16 0..65534 (라이브 와이어와 동일)이며, 정수 파라미터는 일반 정수로 저장되는 경우는 제외: 유형/모델, 열거형, 템포 분할, 반음 (부호 있음: 12 = +12, 0 = 0).
  • FM3-Edit에서 확인된 스케일 (2026-11-03), 정식 스크립트 옆의 calib.json에 저장:
    • 선형: 백분율, bipolar_percent, 노브 0-10, Pitch 피드백 0..100%, Pitch 디튠 −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. 알 수 없는 스케일? raw 값을 추측하여 설정하고, 푸시한 다음 FM3-Edit에서 읽고 포인트를 추가하세요 (learn).
  • 블록 헤더: 워드 −1 = 씬-1 채널, 워드 0..6 = 씬 2-8 채널 (0=A..3=D), 워드 7..14 = 씬 1-8 바이패스 (1 = 바이패스됨); scene 명령어가 이를 편집합니다.
  • FM3는 푸시된 덤프를 헤더의 슬롯에 직접 저장합니다 (추가 저장 없음).

커버리지 (2026-11-03)

  • Control 블록 = 전체 컨트롤러 메뉴 (템포, LFO 1/2, ADSR 1/2, 시퀀서, 엔벨로프, Manual 1-5, Scene Controllers): family 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 믹스가 움직이는 것 확인), Scene Controllers, 템포.
  • 라이브 출력 미터 (sub 0x2E parseGen3LiveMeters output_left/right)는 신호 없이 임의의 값을 반환: 사용 불가. 씬 음량은 USB 재녹음을 통해 측정해야 합니다.
  • scales.json: 34개 블록 패밀리의 1,390개 파라미터가 FM3 자체 표시 텍스트에 대해 보정됨 (calibrate.mjs가 각 파라미터를 라이브로 스윕하고 에코를 읽음; calfix.mjs 2차 패스). 연속 파라미터 는 lin/log으로 피팅되거나 보간됨; 열거형은 양방향으로 이름을 매핑함. 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 (레벨 −80dB)으로 나타납니다: 항상 add를 사용하세요. FM3에서 수집된 기본 레코드를 삽입합니다 (harvest.mjs <scratchSlot> <restore.syx> [eids], BATCH=1로 한 번에 하나의 블록 배치: 한 번에 여러 무거운 블록을 배치하면 FM3가 한 번 멈췄습니다).
  • 저장된 적이 없는 슬롯 (<EMPTY>)은 코덱이 디코딩할 수 없는 다른 컨테이너를 사용합니다: 한 번 저장한 후에 가져오세요.

FM3-Edit 없이 작동

여기의 모든 것은 USB를 통해 FM3와 직접 통신합니다 (기본적으로 COM7, 포트가 변경된 경우 FM3_PORT 설정): pull, push, switch.mjs, cpu.mjs, fm3ctl.mjs (씬 선택, 루퍼 버튼), levels.py (USB 녹음으로 씬 음량). FM3-Edit은 필요하지 않습니다. 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 검증)

글로벌 설정은 프리셋에 없습니다. 이들은 197kB의 시스템 뱅크 전체, 66개 프레임으로 이동합니다. node pullsystem.mjs <out.syx>로 읽으세요 (FM3-Edit 닫힘, 읽기 전용, Fractal-Bot이 보낸 요청 fn 0x43, 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개의 7비트), fn 0x53 푸터 (모든 워드의 XOR). 압축되지 않음. 워드 0 = 0x1008, 워드 1 = 0xAA55, 워드 2 = CRC-CCITT (다항식 0x1021, 초기값 0xAA55) 바이트 8 .. 8 + 워드 3에 대해, 워드 3 = 데이터 길이 (29760). GLOBAL 카탈로그 param 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 by 파일, 그런 다음 새 백업이 보낸 파일과 정확히 일치했습니다.
  • 규칙: 항상 신선한 백업에서 시작하세요 (모든 글로벌 + FC 레이아웃을 보유함); 보내기 전에 사용자에게 물어보세요; 복원할 원본 백업을 보관하세요. 다른 요청 코드를 프로브하지 마세요.

풋스위치 레이아웃 — fm3fc.mjs (저장됨) + fcset.mjs (라이브) (2026-11-08 검증)

8개의 레이아웃 + 마스터 레이아웃은 시스템 뱅크에 있으므로 FC-블록 프로빙이 필요하지 않습니다. 스위치 인덱스 i = layout × 12 + view × 3 + switch (0부터 시작; layout 8 = 마스터 레이아웃). 복사본 내 오프셋:

필드TapHold
카테고리 (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
기능 (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 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
params, 6워드 (preset/scene/layout 번호 1부터 시작; Effect = [block, channel]; Inc/Dec = [step, wrap, lower, upper], step 65535 = -1)1982 + 6i2954 + 6i
사용자 정의 레이블, 10자 + 03623 + 11i4811 + 11i
레이아웃 이름은 1370 + 32 × layout; 색상은 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 서브 0x09로 블록 199의 하나의 파라미터를 편집합니다: F0 00 01 74 11 01 09 00 47 01 <pid lo> <pid hi> <float32 5 septets, LSB first> 00 00 00 00 <xor> F7. 파라미터 id = 저장된 오프셋 − 1658 (tap 카테고리 i, tap 기능 108 + i, tap 파라미터 324 + 6i + k, hold 카테고리 972 + i, tap 레이블 모드 216 + i); 텍스트 영역에서 id는 +276만큼 이동: tap 사용자 정의 텍스트 2241 + 11i (문자당 하나의 파라미터, 값 = 문자 코드, 끝 이후 0), 색상 4618 + i. fcset.mjs text <layout> <view> <switch> <TEXT> [mode=N]는 스위치 이름을 라이브로 변경합니다. fcset.mjs <pid> <value> ...는 캡처된 메시지를 바이트 단위로 재구성합니다; FM3는 변경 사항을 즉시 적용하고 자체적으로 저장합니다. FM3-Edit에서 USBPcap으로 캡처.
  • 알려진 파라미터 id만 설정하세요. 블록 199에 대해 보지 않은 id에 대해 GET (서브 0x1a/0x1b)을 절대 보내지 마세요: 알 수 없는 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
params (6)72 + 6j288 + 6j
사용자 정의 텍스트 (11)432 + 11j696 + 11j

레이아웃 재정의 테이블은 960 + i (i = layout × 12 + view × 3 + switch, 값 = 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 p

관련 스킬