Skip to content

Commit 279aa37

Browse files
committed
Enhance tool registration: Allow registerTool to accept custom ZodType schemas for input and output (modelcontextprotocol#900)
1 parent 29cb080 commit 279aa37

9 files changed

+2454
-0
lines changed

X32_emulator

1.53 MB
Binary file not shown.

docs/OSC-Protocal.md

Lines changed: 373 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,373 @@
1+
# X32/M32 OSC Protocol 핵심 가이드
2+
3+
## UDP 통신 기본 정보
4+
5+
- **포트**: UDP **10023** (X32/M32 기본값), UDP **10024** (XAir 시리즈)
6+
- **프로토콜**: UDP (User Datagram Protocol)
7+
- **통신 방식**: X32/M32가 UDP 10023에서 수신, 클라이언트가 사용한 포트로 응답 전송
8+
- **데이터 형식**: Big-endian, 4-byte aligned/padded (null bytes로 패딩)
9+
- **주의사항**:
10+
- UDP는 패킷 손실을 보고하지 않으므로 버퍼 오버플로우 주의
11+
- WiFi(54Mbps)는 대량 데이터 전송 시 패킷 손실 가능
12+
- 100Mbps 유선 이더넷 연결 권장
13+
14+
## OSC 메시지 구조
15+
16+
```
17+
[Address Pattern (4-byte aligned)] + [Type Tag String (4-byte aligned)] + [Arguments (4-byte aligned)]
18+
```
19+
20+
### Type Tags
21+
22+
| Type | 설명 | 범위 |
23+
|------|------|------|
24+
| `i` | 32-bit signed integer | 정수 값 |
25+
| `f` | 32-bit signed float | 0.0 ~ 1.0 |
26+
| `s` | String | null-terminated |
27+
| `b` | Blob | 임의의 바이너리 데이터 |
28+
29+
### 메시지 예제
30+
31+
```
32+
/info~~~,~~~ (인자 없음)
33+
/ch/01/config/name~~,s~~name~~~~ (문자열 1개)
34+
/ch/01/eq/1 ,ifff [2] [0.26] [0.5] [0.46] (int 1개 + float 3개)
35+
```
36+
37+
## X32/M32 OSC Protocol Parameters
38+
39+
### Type Rules (Get/Set Parameter) 및 데이터 포맷팅
40+
41+
X32/M32는 OSC 1.0 규격을 따르며, 4가지 기본 OSC type tags를 구현합니다: **int32**, **float32**, **string**, **blob**
42+
43+
#### 데이터 형식 규칙
44+
45+
- **모든 파라미터는 big-endian 및 4-byte aligned/padded** (OSC 스펙 준수)
46+
- **패딩은 null bytes(\0)로 수행**
47+
- **Float 파라미터는 0.0 ~ 1.0 범위**여야 함
48+
```
49+
0.0 → 0x00000000 (big-endian)
50+
0.5 → 0x3f000000 (big-endian)
51+
1.0 → 0x3f800000 (big-endian)
52+
```
53+
- **Integer 및 float 파라미터는 signed 32-bit 값**
54+
- **String은 null-terminated**여야 함
55+
- **Enum 파라미터는 string 또는 integer로 전송 가능**
56+
- **Boolean 파라미터는 enum 타입 {OFF, ON} 또는 OSC integer {0, 1}로 매핑**
57+
- **Blob(임의의 바이너리 데이터)은 섹션별로 특정 규칙을 따름**
58+
59+
#### OSC 명령 구조
60+
61+
OSC 명령은 다음과 같이 구성됩니다:
62+
- **4-byte padded OSC message (Address Pattern)**
63+
- **4-byte padded type tag string**
64+
- **Non-empty type tag string이 있을 경우, 하나 이상의 4-byte aligned/padded arguments**
65+
66+
#### OSC 1.0 호환성
67+
68+
OSC 1.0 스펙은 구형 OSC 구현에서 type tag string을 생략할 수 있다고 언급하며, X32/M32는 이를 지원합니다.
69+
70+
**예제: Type tag 없는 명령 (구형 OSC 형식)**
71+
```
72+
/info~~~ (OSC 1.0 비준수지만 X32/M32에서 허용됨)
73+
/info~~~,~~~ (OSC 1.0 준수 - 권장)
74+
```
75+
76+
#### Float 타입 특별 고려사항
77+
78+
X32/M32는 float 범위 [0.0, 1.0]**이산(discrete) 값의 부분집합**만 인식합니다.
79+
80+
- 적용되는 목적지에 따라 "알려진" 값이 결정됨
81+
- 단계 수(steps)가 인식되는 값을 결정
82+
- **예제**: EQ 주파수 - `[20.0, 20k, 201]`
83+
- 20Hz ~ 20kHz 범위가 201개의 이산 값으로 분할됨
84+
- 동일하게 [0.0, 1.0] 범위도 201개의 "알려진" float 값으로 분할됨
85+
- **범위를 벗어난 float 값은 가장 가까운 알려진 값으로 반올림됨**
86+
87+
이는 특히 다음 경우에 유용합니다:
88+
- `/node` 명령으로 반환된 텍스트 형식 데이터를 float 값으로 변환할 때
89+
- MIDI Sysex 명령 내에서 OSC 데이터를 텍스트로 전송해야 할 때
90+
91+
#### Enum 타입 특별 고려사항
92+
93+
Enum은 **문자열(string) 또는 정수(integer)로 전송 가능**합니다.
94+
95+
**예제: 채널 01 게이트 모드 설정**
96+
97+
Enum 타입: `{EXP2, EXP3, EXP4, GATE, DUCK}`
98+
99+
"GATE" 설정 방법 1 - 문자열:
100+
```
101+
/ch/01/gate/mode~~~~,s~~GATE~~~~
102+
```
103+
16진수:
104+
```
105+
2f63682f30312f676174652f6d6f6465000000002c7300004741544500000000
106+
```
107+
108+
"GATE" 설정 방법 2 - 정수(인덱스 3):
109+
```
110+
/ch/01/gate/mode~~~~,i~~[3]
111+
```
112+
16진수:
113+
```
114+
2f63682f30312f676174652f6d6f6465000000002c69000000000003
115+
```
116+
117+
**주의**: 이는 "enum" 타입에만 적용됩니다. 예를 들어, dynamics의 key source 설정은 0~64 사이의 "int" 값만 허용합니다:
118+
```
119+
/ch/[01-32]/dyn/keysrc (int 0~64만 허용, enum 아님)
120+
```
121+
122+
### 명령 예제 모음
123+
124+
#### 간단한 OSC 명령 (인자 없음)
125+
126+
OSC 1.0 준수:
127+
```
128+
/info~~~,~~~
129+
```
130+
131+
구형 형식 (X32/M32에서 허용됨):
132+
```
133+
/info~~~
134+
```
135+
136+
#### 단일 인자를 가진 OSC 명령
137+
138+
```
139+
/ch/01/config/name~~,s~~name~~~~
140+
```
141+
142+
#### 복수 인자를 가진 OSC 명령
143+
144+
```
145+
/ch/01/eq/1 ,ifff [2] [0.2650] [0.5000] [0.4648]
146+
```
147+
148+
이는 다음 4개의 간단한 명령과 동일합니다:
149+
```
150+
/ch/01/eq/1/t~~~,i~~[2]
151+
/ch/01/eq/1/f~~~,f~~[0.2650]
152+
/ch/01/eq/1/g~~~,f~~[0.5000]
153+
/ch/01/eq/1/q~~~,f~~[0.4648]
154+
```
155+
156+
#### 16진수 표현
157+
158+
마지막 명령의 16진수 표현:
159+
```
160+
/ c h / 0 1 / e q / 1 / q ~ ~ ~ , f ~ ~ [0.4648]
161+
2f 63 68 2f 30 31 2f 65 71 2f 31 2f 71 00 00 00 2c 66 00 00 3eedfa44
162+
```
163+
164+
- `3eedfa44`: 0.4648의 32bit float, big-endian 표현
165+
- `~`: null character (\0)
166+
167+
### X32/M32 응답 예제
168+
169+
#### `/info` 응답
170+
171+
**요청:**
172+
```
173+
/info~~~,~~~
174+
```
175+
176+
**응답 (X32 Standard):**
177+
```
178+
/info~~~,ssss~~~V2.05~~~osc-server~~X32~2.10~~~~
179+
```
180+
48 bytes 응답
181+
182+
**다양한 모델별 응답:**
183+
```
184+
X32 Standard: /info~~~,ssss~~~V2.05~~~osc-server~~X32~2.12~~~~
185+
X32 Rack: /info~~~,ssss~~~V2.05~~~osc-server~~X32RACK~2.12~~~~
186+
X32 Compact: /info~~~,ssss~~~V2.05~~~osc-server~~X32C~~2.12~~~~
187+
X32 Producer: /info~~~,ssss~~~V2.05~~~osc-server~~X32P~2.12~~~~
188+
X32 Core: /info~~~,ssss~~~V2.05~~~osc-server~~X32CORE~2.12~~~~
189+
M32 Standard: /info~~~,ssss~~~V2.05~~~osc-server~~M32~2.12~~~~
190+
M32 Compact: /info~~~,ssss~~~V2.05~~~osc-server~~M32C~2.12~~~~
191+
M32 Rack: /info~~~,ssss~~~V2.05~~~osc-server~~M32R~2.12~~~~
192+
```
193+
194+
**XAir 시리즈 (UDP 포트 10024 사용):**
195+
```
196+
XR18: /info~~~,ssss~~~V0.04~~~XR18-1D-DA-B4~~~XR18~~~~1.12~~~~
197+
XR16: /info~~~,ssss~~~V0.04~~~XR16-1D-DA-B4~~~XR16~~~~1.12~~~~
198+
XR12: /info~~~,ssss~~~V0.04~~~XR12-1D-DA-B4~~~XR12~~~~1.12~~~~
199+
```
200+
201+
#### `/status` 응답
202+
203+
**요청:**
204+
```
205+
/status~,~~~
206+
```
207+
208+
**응답:**
209+
```
210+
/status~,sss~~~~active~~192.168.0.64~~~~osc-server~~
211+
```
212+
52 bytes 응답
213+
214+
#### 파라미터 Get 응답
215+
216+
**요청:**
217+
```
218+
/fx/4/par/23~~~~,~~~
219+
```
220+
221+
**응답:**
222+
```
223+
/fx/4/par/23~~~~,f~~[float 0.5]
224+
```
225+
24 bytes 응답
226+
227+
16진수:
228+
```
229+
2f66782f342f7061722f3233000000002c6600003f000000
230+
```
231+
232+
## 통신 모드
233+
234+
#### 즉시형 (Immediate) & 지연형 (Deferred) 업데이트 모드
235+
236+
- **즉시형 (Immediate)**은 클라이언트가 특정 OSC 주소로 명령을 보내면 콘솔이 **즉시 응답하거나 즉시 값을 반영**하는 방식이며, 단일 요청에 대해 **여러 개의 응답 메시지가 반환될 수 있음**
237+
- 예: `/showdump` 는 한 번만 요청해도 설정 정보가 **여러 패킷으로 연속 반환**
238+
- **지연형 (Deferred)**`/xremote`, `/subscribe`, `/batchsubscribe` 와 같이 **10초 동안 상태 변화를 푸시**하는 모드를 의미하며, 클라이언트는 **10초 이내에 갱신 명령을 재전송**해야 푸시가 유지됨
239+
- 서버 UI 또는 다른 클라이언트에서 변경이 발생하면 자동으로 알림 전송
240+
- 이 방식은 **값 그 자체보다 이벤트 스트림**이 중요할 때 사용됨 (예: 페이더 이동, 뮤트 상태 변경 등)
241+
- 즉, 네트워크에서 **대역폭을 점유하는 요소는 데이터 크기 자체가 아니라** **연속 이벤트 발생 빈도와 클라이언트 연결 유지 방식이며**, 전송되는 값은 대부분 **단순 float 또는 enum**이므로 데이터 무게는 매우 가벼움
242+
243+
#### Connection (세션 유지 개념)
244+
245+
##### 다중 클라이언트 관리
246+
247+
- X32/M32는 **여러 UDP 클라이언트를 동시에** 지원
248+
- 각 클라이언트는 독립적으로 `/xremote` 또는 `/subscribe` 등록 필요
249+
- 한 클라이언트의 변경사항이 모든 등록된 클라이언트에게 전파됨
250+
251+
##### `/xremote`
252+
253+
- **서버(콘솔)에서 발생하는 모든 상태 변화****클라이언트로 푸시**하는 모드
254+
- **10초 타임아웃**이 있기 때문에 **9초 간격 정도로 재전송**해야 지속됨
255+
- 페이더 이동, 뱅크 변경, 화면 업데이트 등 전체 UI 변화를 스트리밍
256+
- 용도: **전체 UI 변화 스트림** 수신
257+
258+
```
259+
Client: /xremote~~~,~~~ (파라미터 없음)
260+
Server: (변경사항 자동 푸시, 10초 동안)
261+
```
262+
263+
##### `/subscribe`
264+
265+
- **특정 OSC 주소**를 지정하여 **해당 파라미터 변경 이벤트만** 푸시받는 모드
266+
- `time_factor` 인자를 통해 **업데이트 빈도(분해능)**를 조절 가능
267+
- `0` → 약 200회 업데이트 (10초 동안)
268+
- `1` → 약 100회 업데이트
269+
- `10` → 약 20회 업데이트
270+
- `50` → 약 4회 업데이트
271+
- 용도: **선택적·타겟 변화 스트림** 수신
272+
273+
```
274+
/subscribe ,si /ch/01/mix/on 10
275+
(채널 1의 On/Off 상태를 10초 동안 약 20회 업데이트 수신)
276+
```
277+
278+
##### `/batchsubscribe`
279+
280+
- 여러 파라미터를 한 번에 구독하며, 와일드카드(`*`) 사용 가능
281+
- 예: `/ch/**/mix/on` (모든 채널의 On/Off 상태)
282+
283+
#### 읽기 (Read) Vs 쓰기 (Write)
284+
285+
- OSC 주소에 **인자를 포함하지 않으면** → 해당 파라미터를 **읽기 (Read) 요청**
286+
- 동일한 OSC 주소에 **인자를 포함하면** → 해당 파라미터에 **값 쓰기 (Write)**
287+
- 예:
288+
- 읽기: `/ch/01/mix/fader`
289+
- 쓰기: `/ch/01/mix/fader ,f 0.75`
290+
291+
#### Message Address Pattern
292+
293+
- X32/M32에서는 OSC 주소 문자열(Address String)이 **기능(API 엔드포인트)** 역할을 하며, 아래와 같은 **주소 패밀리(카테고리)**를 통해 믹서의 모든 파라미터에 접근한다
294+
- 이 목록은 "OSC가 지원해야 하는 주소 체계"가 아니라 **X32가 제공하는 제어 가능 명령 집합**이다
295+
- 따라서 **OSC = 메시지 포맷**, **Address Pattern = X32 제어 명령 API**로 이해한다
296+
297+
```
298+
<OSC Address Pattern> ::=
299+
/ | /-action | /add | /auxin | /batchsubscribe | /bus | /ch | /config |
300+
/copy | /dca | /delete | /formatsubscribe | /fx | /fxrtn | /headamp |
301+
/info | /-insert | /-libs | /load | /main/m | /main/st | /meters | /mtx |
302+
/node | /outputs | /-prefs | /rename | /renew | /save | /-show | /showdump |
303+
/-snap | /-stat | /status | /subscribe | /-undo | /unsubscribe | /-urec |
304+
/-usb | /xinfo | /xremote | /xremoteinfo
305+
```
306+
307+
### 주요 명령어
308+
309+
| 명령어 | 설명 | 예제 |
310+
|--------|------|------|
311+
| `/info` | X32/M32 버전 정보 조회 | `/info~~~,~~~` |
312+
| `/status` | 현재 상태 조회 | `/status~,~~~` |
313+
| `/xremote` | 자동 업데이트 활성화 (10초) | `/xremote~~~,~~~` |
314+
| `/subscribe` | 특정 파라미터 구독 | `/subscribe ,si /ch/01/mix/on 1` |
315+
| `/batchsubscribe` | 여러 파라미터 일괄 구독 | `/batchsubscribe ,ssiii /ch/**/mix/on 0 31 1` |
316+
| `/renew` | 구독 갱신 | `/renew ,s /meters/5` |
317+
| `/unsubscribe` | 구독 해제 | `/unsubscribe` |
318+
| `/node` | X32node 데이터 조회 | `/node~~~,s~~ch/01` |
319+
| `/` | X32node 데이터 쓰기 | `/~~~,s~~ch/01 newname 10 CY 1` |
320+
| `/meters/[0-16]` | 미터링 데이터 요청 | `/meters/0` |
321+
322+
### Address Pattern 구조 예제
323+
324+
- 위 Address Pattern은 **각 섹션별로 하위 경로(Sub-address)와 파라미터 구조를 가짐**
325+
- Address Pattern은 믹서 내부 파라미터 구조를 그대로 **트리 형태로 노출한 제어 API**라고 볼 수 있다
326+
327+
#### 채널(Channel) 제어
328+
329+
```
330+
/ch/[01-32]/config/name - 채널 이름
331+
/ch/[01-32]/config/icon - 채널 아이콘
332+
/ch/[01-32]/config/color - 채널 색상
333+
/ch/[01-32]/mix/fader - 페이더 레벨
334+
/ch/[01-32]/mix/on - 채널 On/Off (Mute)
335+
/ch/[01-32]/mix/pan - 패닝
336+
/ch/[01-32]/eq/[1-4]/* - EQ 설정 (4밴드)
337+
/ch/[01-32]/gate/* - Gate 설정
338+
/ch/[01-32]/dyn/* - Dynamics/Compressor 설정
339+
```
340+
341+
#### 버스(Bus) 제어
342+
343+
```
344+
/bus/[01-16]/mix/fader - 버스 페이더
345+
/bus/[01-16]/mix/on - 버스 On/Off
346+
/bus/[01-16]/mix/pan - 버스 패닝
347+
```
348+
349+
#### 메인 출력
350+
351+
```
352+
/main/st/mix/fader - 메인 스테레오 페이더
353+
/main/st/mix/on - 메인 스테레오 On/Off
354+
/main/m/mix/fader - 메인 모노 페이더
355+
/main/m/mix/on - 메인 모노 On/Off
356+
```
357+
358+
### 명령 형식 표현
359+
360+
문서 및 CLI상에서 명령은 두 가지 형식으로 표현될 수 있다:
361+
362+
#### 사람이 읽는 형식
363+
```
364+
<command> <format> <parameters>
365+
/ch/01/mix/fader ,f [0.7]
366+
```
367+
368+
#### 실제 전송되는 네트워크 패킷 형식 (OSC 4-byte padding 포함)
369+
```
370+
<command>~~~<format>~~~<parameter> <parameter> …
371+
/ch/01/mix/fader~~~ ,f~~~ [0.7]
372+
```
373+
- 여기서 `~~~`**OSC 문자열 padding(\0)에 의해 생기는 바이트 단위 정렬 공간**을 나타내는 개념적 표현
2.3 MB
Binary file not shown.

0 commit comments

Comments
 (0)