@djodjonx/x32-simulator 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/package.json +5 -1
  3. package/.commitlintrc.json +0 -3
  4. package/.github/workflows/publish.yml +0 -38
  5. package/.husky/commit-msg +0 -1
  6. package/.husky/pre-commit +0 -1
  7. package/.oxlintrc.json +0 -56
  8. package/INSTALL.md +0 -107
  9. package/docs/OSC-Communication.md +0 -184
  10. package/docs/X32-INTERNAL.md +0 -262
  11. package/docs/X32-OSC.pdf +0 -0
  12. package/docs/behringer-x32-x32-osc-remote-protocol-en-44463.pdf +0 -0
  13. package/src/application/use-cases/BroadcastUpdatesUseCase.ts +0 -120
  14. package/src/application/use-cases/ManageSessionsUseCase.ts +0 -9
  15. package/src/application/use-cases/ProcessPacketUseCase.ts +0 -26
  16. package/src/application/use-cases/SimulationService.ts +0 -146
  17. package/src/domain/entities/SubscriptionManager.ts +0 -126
  18. package/src/domain/entities/X32State.ts +0 -78
  19. package/src/domain/models/MeterConfig.ts +0 -22
  20. package/src/domain/models/MeterData.ts +0 -59
  21. package/src/domain/models/OscMessage.ts +0 -93
  22. package/src/domain/models/X32Address.ts +0 -72
  23. package/src/domain/models/X32Node.ts +0 -43
  24. package/src/domain/models/types.ts +0 -86
  25. package/src/domain/ports/ILogger.ts +0 -27
  26. package/src/domain/ports/INetworkGateway.ts +0 -8
  27. package/src/domain/ports/IStateRepository.ts +0 -16
  28. package/src/domain/services/MeterService.ts +0 -46
  29. package/src/domain/services/OscMessageHandler.ts +0 -88
  30. package/src/domain/services/SchemaFactory.ts +0 -308
  31. package/src/domain/services/SchemaRegistry.ts +0 -67
  32. package/src/domain/services/StaticResponseService.ts +0 -52
  33. package/src/domain/services/strategies/BatchStrategy.ts +0 -74
  34. package/src/domain/services/strategies/MeterStrategy.ts +0 -45
  35. package/src/domain/services/strategies/NodeDiscoveryStrategy.ts +0 -36
  36. package/src/domain/services/strategies/OscCommandStrategy.ts +0 -22
  37. package/src/domain/services/strategies/StateAccessStrategy.ts +0 -71
  38. package/src/domain/services/strategies/StaticResponseStrategy.ts +0 -42
  39. package/src/domain/services/strategies/SubscriptionStrategy.ts +0 -56
  40. package/src/infrastructure/mappers/OscCodec.ts +0 -54
  41. package/src/infrastructure/repositories/InMemoryStateRepository.ts +0 -37
  42. package/src/infrastructure/services/ConsoleLogger.ts +0 -177
  43. package/src/infrastructure/services/UdpNetworkGateway.ts +0 -100
  44. package/src/presentation/cli/server.ts +0 -194
  45. package/src/presentation/library/library.ts +0 -139
  46. package/tests/application/use-cases/BroadcastUpdatesUseCase.test.ts +0 -104
  47. package/tests/application/use-cases/ManageSessionsUseCase.test.ts +0 -12
  48. package/tests/application/use-cases/ProcessPacketUseCase.test.ts +0 -49
  49. package/tests/application/use-cases/SimulationService.test.ts +0 -77
  50. package/tests/domain/entities/SubscriptionManager.test.ts +0 -50
  51. package/tests/domain/entities/X32State.test.ts +0 -52
  52. package/tests/domain/models/MeterData.test.ts +0 -23
  53. package/tests/domain/models/OscMessage.test.ts +0 -38
  54. package/tests/domain/models/X32Address.test.ts +0 -30
  55. package/tests/domain/models/X32Node.test.ts +0 -30
  56. package/tests/domain/services/MeterService.test.ts +0 -27
  57. package/tests/domain/services/OscMessageHandler.test.ts +0 -51
  58. package/tests/domain/services/SchemaRegistry.test.ts +0 -47
  59. package/tests/domain/services/StaticResponseService.test.ts +0 -15
  60. package/tests/domain/services/strategies/BatchStrategy.test.ts +0 -41
  61. package/tests/domain/services/strategies/MeterStrategy.test.ts +0 -19
  62. package/tests/domain/services/strategies/NodeDiscoveryStrategy.test.ts +0 -22
  63. package/tests/domain/services/strategies/StateAccessStrategy.test.ts +0 -49
  64. package/tests/domain/services/strategies/StaticResponseStrategy.test.ts +0 -15
  65. package/tests/domain/services/strategies/SubscriptionStrategy.test.ts +0 -45
  66. package/tests/infrastructure/mappers/OscCodec.test.ts +0 -41
  67. package/tests/infrastructure/repositories/InMemoryStateRepository.test.ts +0 -29
  68. package/tests/infrastructure/services/ConsoleLogger.test.ts +0 -74
  69. package/tests/infrastructure/services/UdpNetworkGateway.test.ts +0 -61
  70. package/tests/presentation/cli/server.test.ts +0 -178
  71. package/tests/presentation/library/library.test.ts +0 -13
  72. package/tsconfig.json +0 -21
  73. package/tsdown.config.ts +0 -15
  74. package/vitest.config.ts +0 -9
package/CHANGELOG.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [0.0.4](https://github.com/djodjonx/x32-simulator/compare/v0.0.3...v0.0.4) (2026-01-08)
6
+
5
7
  ### [0.0.3](https://github.com/djodjonx/x32-simulator/compare/v0.0.2...v0.0.3) (2026-01-08)
6
8
 
7
9
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djodjonx/x32-simulator",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "X32 Simulator",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -21,6 +21,10 @@
21
21
  }
22
22
  }
23
23
  },
24
+ "files": [
25
+ "dist",
26
+ "CHANGELOG.md"
27
+ ],
24
28
  "scripts": {
25
29
  "dev": "tsdown --watch",
26
30
  "build": "tsdown",
@@ -1,3 +0,0 @@
1
- {
2
- "extends": ["@commitlint/config-conventional"]
3
- }
@@ -1,38 +0,0 @@
1
- name: Publish Package to npmjs
2
-
3
- on:
4
- push:
5
- tags:
6
- - 'v*'
7
-
8
- permissions:
9
- id-token: write # Required for OIDC
10
- contents: write # Required to create GitHub Releases
11
-
12
- jobs:
13
- publish:
14
- runs-on: ubuntu-latest
15
- steps:
16
- - uses: actions/checkout@v4
17
-
18
- - uses: actions/setup-node@v4
19
- with:
20
- node-version: '20.x'
21
- registry-url: 'https://registry.npmjs.org'
22
-
23
- # Ensure npm is up-to-date
24
- - name: Update npm
25
- run: npm install -g npm@latest
26
-
27
- - run: npm ci
28
- - run: npm run build
29
- - run: npm test
30
- - run: npm publish --provenance --access public
31
- env:
32
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
33
-
34
- - name: Create GitHub Release
35
- uses: softprops/action-gh-release@v2
36
- with:
37
- generate_release_notes: true
38
- make_latest: true
package/.husky/commit-msg DELETED
@@ -1 +0,0 @@
1
- npx --no -- commitlint --edit $1
package/.husky/pre-commit DELETED
@@ -1 +0,0 @@
1
- npx lint-staged
package/.oxlintrc.json DELETED
@@ -1,56 +0,0 @@
1
- {
2
- "$schema": "./node_modules/oxlint/configuration_schema.json",
3
- "plugins": [
4
- "typescript",
5
- "vitest",
6
- "unicorn",
7
- "oxc",
8
- "import",
9
- "jsdoc"
10
- ],
11
- "categories": {
12
- "correctness": "error",
13
- "suspicious": "error",
14
- "pedantic": "off",
15
- "style": "off",
16
- "perf": "warn"
17
- },
18
- "rules": {
19
- "import/prefer-default-export": "off",
20
- "import/no-named-export": "off",
21
- "unicorn/filename-case": "off",
22
- "eslint/no-magic-numbers": "off",
23
- "eslint/max-lines-per-function": "off",
24
- "eslint/max-statements": "off",
25
- "eslint/max-params": "off",
26
- "eslint/max-lines": "off",
27
- "unicorn/no-zero-fractions": "off",
28
- "eslint/sort-keys": "off",
29
- "eslint/sort-imports": "off",
30
- "typescript/consistent-type-imports": "off",
31
- "jsdoc/require-param-type": "off",
32
- "jsdoc/require-returns-type": "off",
33
- "jsdoc/require-returns": "off",
34
- "typescript/no-inferrable-types": "off",
35
- "unicorn/prefer-top-level-await": "off",
36
- "unicorn/no-null": "off",
37
- "unicorn/prevent-abbreviations": "off",
38
- "eslint/id-length": "off"
39
- },
40
- "overrides": [
41
- {
42
- "files": ["tests/**/*.ts"],
43
- "rules": {
44
- "eslint/no-magic-numbers": "off"
45
- }
46
- }
47
- ],
48
- "settings": {
49
- "vitest": {
50
- "typecheck": true
51
- }
52
- },
53
- "env": {
54
- "builtin": true
55
- }
56
- }
package/INSTALL.md DELETED
@@ -1,107 +0,0 @@
1
- # Development Guide
2
-
3
- This guide is for developers who want to contribute to the `x32-simulator` project or build it from source.
4
-
5
- ## 📋 Prerequisites
6
-
7
- * **Node.js**: Version 20 or higher is required.
8
- * Verify with `node -v`
9
- * **npm**: Comes bundled with Node.js.
10
-
11
- ## 🛠️ Setup
12
-
13
- 1. **Clone the repository:**
14
- ```bash
15
- git clone https://github.com/djodjonx/x32-simulator.git
16
- cd x32-simulator
17
- ```
18
-
19
- 2. **Install dependencies:**
20
- We use `npm ci` for reliable builds based on `package-lock.json`.
21
- ```bash
22
- npm ci
23
- ```
24
-
25
- ## 💻 Development Workflow
26
-
27
- ### Running in Watch Mode
28
- For rapid development, use the dev script. It re-bundles the project on file changes.
29
- ```bash
30
- npm run dev
31
- ```
32
-
33
- ### Running Tests
34
- We use **Vitest** for testing.
35
-
36
- * **Run all tests:**
37
- ```bash
38
- npm test
39
- ```
40
- * **Run with coverage:**
41
- ```bash
42
- npm run test:coverage
43
- ```
44
- * **Watch mode (TDD):**
45
- ```bash
46
- npm run test:watch
47
- ```
48
-
49
- ### Code Quality
50
- Ensure your code meets the project standards before committing.
51
-
52
- * **Linting (Oxlint):**
53
- ```bash
54
- npm run lint
55
- ```
56
- * **Type Checking:**
57
- ```bash
58
- npm run type-check
59
- ```
60
-
61
- ## 🏗️ Building
62
-
63
- To build the project for production distribution:
64
-
65
- ```bash
66
- npm run build
67
- ```
68
-
69
- This uses `tsdown` to bundle the code into the `dist/` directory:
70
- * `dist/server.mjs`: The executable CLI.
71
- * `dist/index.mjs` / `.cjs`: The library entry points.
72
-
73
- ## 📂 Project Structure
74
-
75
- The project follows a **Clean Architecture** / **Hexagonal** structure:
76
-
77
- ```
78
- src/
79
- ├── application/ # Use Cases (Business Logic orchestration)
80
- ├── domain/ # Core Business Logic (Entities, Models, Ports)
81
- ├── infrastructure/ # External adapters (UDP, Logging, Repositories)
82
- └── presentation/ # Entry points
83
- ├── cli/ # CLI Server implementation
84
- └── library/ # Library exports
85
- ```
86
-
87
- ## 🚀 Releasing
88
-
89
- We use `standard-version` to automate versioning and changelog generation.
90
-
91
- 1. **Create a release:**
92
- ```bash
93
- npm run release
94
- ```
95
- This command will:
96
- * Bump the version in `package.json`.
97
- * Update `CHANGELOG.md`.
98
- * Commit these changes.
99
- * Create a git tag (e.g., `v1.1.0`).
100
-
101
- 2. **Push changes:**
102
- ```bash
103
- git push --follow-tags
104
- ```
105
-
106
- 3. **Publish:**
107
- The GitHub Action workflow will automatically detect the new tag, build the project, and publish it to NPM.
@@ -1,184 +0,0 @@
1
- # Protocol Analysis and Implementation Strategies regarding the Behringer X32 Digital Mixing Console Ecosystem
2
-
3
- ## 1. Introduction to Networked Audio Control Systems
4
- The transition from analog to digital mixing consoles has fundamentally altered the landscape of live sound reinforcement, studio recording, and broadcast audio. Among the myriad devices that have driven this paradigm shift, the **Behringer X32** and **Midas M32** families of digital consoles stand as preeminent examples of commercial success and technical ubiquity.
5
-
6
- A central feature of these ecosystems is their capability for remote control and telemetry via standard network protocols. Unlike their analog predecessors, which relied on voltage-controlled amplifiers and physical patching, modern digital consoles operate as sophisticated computers that process audio signals via **Digital Signal Processing (DSP)** algorithms. This architecture allows the control surface—the physical faders, knobs, and buttons—to be decoupled from the audio processing engine. Consequently, the manipulation of audio parameters can be achieved not only through the physical interface but also via external software applications and automated scripts communicating over a Local Area Network (LAN).
7
-
8
- The mechanism governing this external communication is the **Open Sound Control (OSC)** protocol. Optimized for modern networking technology, OSC provides a flexible, URL-style symbolic naming scheme (e.g., `/ch/01/mix/fader`) that is significantly more human-readable and granular than the legacy MIDI standard.
9
-
10
- For the X32 ecosystem, this protocol facilitates the operation of:
11
- * The official **X32-Edit** software (PC/Mac/Linux)
12
- * The **X32-Mix** app (iPad)
13
- * The **Mixing Station** app (Android)
14
- * A host of third-party integration tools
15
-
16
- ---
17
-
18
- ## 2. The Documentation Landscape
19
- A critical challenge for developers and integrators working with the X32 platform is the scarcity and incompleteness of official documentation provided by the manufacturer, Music Tribe. While Behringer released a preliminary OSC document in late 2012 (Version 1.01), it has not been officially updated to reflect substantial feature additions (Firmware 2.x, 3.x, and 4.x), such as new effects engines, extended routing options, and the "User" layer.
20
-
21
- ### 2.1 The "Unofficial" Standard
22
- To bridge this information gap, the user community—spearheaded by researcher and developer Patrick-Gilles Maillot—undertook a massive effort to reverse-engineer the complete protocol. The resulting document, **"Unofficial X32/M32 OSC Remote Protocol,"** is widely regarded as the definitive technical reference.
23
-
24
- > **Note:** This documentation distinguishes itself by detailing data types, value ranges, and context-dependent behaviors of the network stack, such as the critical distinction between the `/subscribe` command and the `/xremote` command.
25
-
26
- The documentation is maintained in a live repository, covering nuanced differences between hardware models (X32 Rack, Core, Compact) which share a common firmware core but report different hardware identifiers.
27
-
28
- ---
29
-
30
- ## 3. Network Transport and Architecture
31
- The foundation of the X32’s remote control capability is the **User Datagram Protocol (UDP)**.
32
-
33
- ### 3.1 UDP vs. TCP in Audio Control
34
- TCP is connection-oriented, guaranteeing packet delivery via handshakes and acknowledgments (ACKs). In live mixing, however, **latency is the enemy**. If a packet containing a fader move is dropped, pausing the stream for retransmission is undesirable. The X32 network stack is therefore **stateless** and "fire-and-forget." It listens for incoming UDP datagrams, processes valid OSC messages, and sends replies to the source address without maintaining a persistent socket connection.
35
-
36
- ### 3.2 Port Assignments and Addressing
37
- * **Target Port:** UDP Port **10023** (Hard-coded).
38
- * **Source Port:** Ephemeral (chosen by the client OS).
39
-
40
- **Critical Implementation Detail:** The X32 sends replies back to the *source IP* and *source port* of the incoming packet. Developers must bind to a specific local UDP socket for both sending and receiving. If the OS assigns a new port for the next message, the reply from the X32 will be sent to the original port and potentially discarded.
41
-
42
- ### 3.3 Endianness and Data Representation
43
- The OSC specification 1.0 mandates Big-Endian (network byte order).
44
- * **Integers:** 32-bit signed ($i$)
45
- * **Floats:** 32-bit IEEE 754 ($f$)
46
- * **Strings:** Null-terminated ASCII ($s$)
47
- * **Blobs:** Int32 size count + binary data ($b$)
48
-
49
- **The Deviation:** While OSC headers are Big-Endian, the internal content of binary blobs returned by the `/meters` command is encoded in **Little-Endian** format, reflecting the internal architecture of the DSP (likely Analog Devices SHARC).
50
-
51
- ---
52
-
53
- ## 4. Device Discovery and Enumeration
54
- Applications utilize the `/xinfo` mechanism to locate the console, as IP addresses may be dynamic (DHCP).
55
-
56
- ### 4.1 The `/xinfo` Handshake
57
- 1. **Query:** Client sends `/xinfo` (Broadcast or Unicast) on port 10023.
58
- 2. **Response:** X32 replies with ` /xinfo ,ssss`.
59
-
60
- **Response Arguments:**
61
- 1. **IP Address:** The console's self-reported IP (e.g., `192.168.1.50`).
62
- 2. **Console Name:** User-defined network name (e.g., `X32-FOH`).
63
- 3. **Model Identifier:** Hardware ID used to customize UI (e.g., `X32`, `X32RACK`, `X32CORE`).
64
- 4. **Firmware Version:** Critical for version control and compatibility checks (e.g., `4.06`).
65
-
66
- ### 4.2 Application Implementation
67
- A typical implementation creates a UDP socket with `SO_BROADCAST` permissions, sends the `/xinfo` packet, and employs a short timeout (e.g., 2 seconds) to listen for the "business card" response.
68
-
69
- ---
70
-
71
- ## 5. Session Persistence and State Synchronization
72
- Since UDP is stateless, the X32 does not inherently know if a client is "connected." To support real-time animation of faders, the protocol implements a subscription-based heartbeat.
73
-
74
- ### 5.1 The `/xremote` Command
75
- * **Function:** Acts as a subscription request.
76
- * **Behavior:** The X32 adds the sender to an internal list of "active remote clients" and mirrors **every** parameter change on the console to that client.
77
- * **Timeout:** A watchdog timer (approx. 10 seconds) purges clients if no further command is received.
78
- * **Keep-Alive:** Clients must resend `/xremote` in a background loop (every 7–9 seconds) to reset the watchdog.
79
-
80
- ### 5.2 `/xremote` vs. `/subscribe`
81
- * **`/xremote`**: The "firehose" command. Requests *all* console changes. Efficient for full desktop editors.
82
- * **`/subscribe`**: Requests updates for specific addresses or ranges. Efficient for mobile apps focusing on specific features.
83
-
84
- For intercepting active channel info, `/xremote` is superior as it guarantees any selection change is broadcast without a priori knowledge.
85
-
86
- ---
87
-
88
- ## 6. Intercepting Active Channel Information
89
- "Active Channel" refers to the channel currently selected by the **SEL** button on the hardware surface.
90
-
91
- ### 6.1 The `/-stat/selidx` Command
92
- The X32 broadcasts the selection state via:
93
- * **OSC Path:** `/-stat/selidx`
94
- * **Data Type:** 32-bit Integer (`,i`)
95
- * **Value Range:** 0 to 71
96
-
97
- ### 6.2 Decoding the Selection Index
98
- The integer corresponds to a fixed map of channel strips:
99
-
100
- | Index Range (Int) | Channel Type | Specific Channels | OSC Address Path |
101
- | :--- | :--- | :--- | :--- |
102
- | **0 – 31** | Input Channels | Channels 1 – 32 | `/ch/01` ... `/ch/32` |
103
- | **32 – 39** | Aux Inputs | Aux 1 – 6, USB L/R | `/auxin/01` ... |
104
- | **40 – 47** | FX Returns | FX 1L, 1R ... 4R | `/fxrtn/01` ... |
105
- | **48 – 63** | Mix Buses | Bus 1 – 16 | `/bus/01` ... |
106
- | **64 – 69** | Matrix Outputs | Matrix 1 – 6 | `/mtx/01` ... |
107
- | **70** | Main LR | Stereo Master Bus | `/main/st` |
108
- | **71** | Mono/Center | Mono Bus | `/main/m` |
109
-
110
- > **Important:** DCAs are absent from this range as they are control groups, not processing paths with full channel strips.
111
-
112
- ### 6.3 Implementation of Interception
113
- To intercept this data, a custom script acts as a parallel client:
114
- 1. **Subscription:** Send `/xremote` to register for updates.
115
- 2. **Listening:** Listen on the bound UDP port.
116
- 3. **Parsing:** When `/-stat/selidx` is received, parse the integer.
117
- 4. **Logic:** Map the integer (e.g., `0`) to the channel (`Channel 1`).
118
-
119
- ### 6.4 The `/-prefs/autosel` Variable
120
- * **autosel ON:** Touching a fader triggers `/-stat/selidx`.
121
- * **autosel OFF:** Only pressing the "Select" button triggers the message.
122
-
123
- ---
124
-
125
- ## 7. Information About Channels: Command Hierarchy
126
- The root address for inputs is `/ch/` using a two-digit string index (`01`–`32`).
127
-
128
- ### 7.1 Functional Blocks
129
-
130
- **Configuration (`/config`)**
131
- * `/ch/{n}/config/name`: String (User name)
132
- * `/ch/{n}/config/icon`: Integer (Icon index)
133
- * `/ch/{n}/config/color`: Integer (Color index)
134
-
135
- **Preamp (`/preamp`)**
136
- * `/ch/{n}/preamp/gain`: Float (0.0–1.0 mapping to -12dB to +60dB)
137
- * `/ch/{n}/preamp/rtnsw`: Integer (48V Phantom Power, 0/1)
138
-
139
- **Gate & Dynamics (`/gate`, `/dyn`)**
140
- * `/ch/{n}/gate/on`: Integer (Active/Bypass)
141
- * `/ch/{n}/dyn/ratio`: Enum (Compression ratio)
142
-
143
- **Equalizer (`/eq`)**
144
- * `/ch/{n}/eq/{b}/f`: Float (Frequency, log mapping 20Hz–20kHz)
145
- * `/ch/{n}/eq/{b}/g`: Float (Gain, -15dB to +15dB)
146
-
147
- **Mix & Fader (`/mix`)**
148
- * `/ch/{n}/mix/fader`: Float (Level, 0.75 ≈ 0dB)
149
- * `/ch/{n}/mix/on`: Integer (**Note:** 1 = Unmuted/On, 0 = Muted/Off)
150
- * `/ch/{n}/mix/pan`: Float (0.0 = Left, 1.0 = Right)
151
-
152
- ### 7.2 "Sends on Fader" Telemetry
153
- Scripts can monitor `/-stat/sendsonfader` (0/1) to detect this mode. If active, fader moves control bus sends rather than the main mix.
154
-
155
- ---
156
-
157
- ## 8. Metering and Bulk Data Transfer
158
- To avoid network flooding, metering is handled via OSC Blobs.
159
-
160
- ### 8.1 The `/meters` Command
161
- Request: `/meters ,s "/meters/1"` (where `/meters/1` covers input channels).
162
-
163
- ### 8.2 Blob Structure and Endianness
164
- The response uses ` /meters ,b <binary_data>`.
165
- 1. **Size (Int32):** Big-Endian
166
- 2. **Count (Int32):** **Little-Endian**
167
- 3. **Data (Float32 Array):** **Little-Endian**
168
-
169
- **Critical:** Developers must switch byte-parsing logic after extracting the blob header to avoid nonsensical numeric values.
170
-
171
- ---
172
-
173
- ## 9. Application Analysis: X32-Edit
174
- The official software follows this blueprint:
175
- 1. **Startup:** Broadcast `/xinfo`.
176
- 2. **Connect:** Establish unicast UDP session to port 10023.
177
- 3. **Sync:** Send `/xremote` and dump console state (via `/status` or node requests).
178
- 4. **Operation:** Loop `/xremote` every ~9s; process `/ch/...` and `/meters` updates.
179
- 5. **Termination:** Stop heartbeat; session times out.
180
-
181
- ---
182
-
183
- ## 10. Conclusion
184
- The Behringer X32 OSC protocol is a robust system for remote audio control. By utilizing **UDP port 10023**, initiating discovery via **/xinfo**, and maintaining session persistence via **/xremote**, developers can effectively communicate with the console. Furthermore, intercepting "Active Channel" information is achievable by monitoring the **`/-stat/selidx`** command within an active subscription, enabling the creation of sophisticated custom controllers and automated workflows.