CreativeInquiry/GameTrak-Liberation

GitHub: CreativeInquiry/GameTrak-Liberation

该项目为 GameTrak 六轴手势控制器提供 OSC、MIDI、WebSocket 等多协议桥接,使其能够在 p5.js、Processing、Python 等创意编程环境中作为姿态输入设备使用。

Stars: 2 | Forks: 0

# GameTrak 解放 作者:Golan Levin,2026年7月 ![gametrak_overview_demo](https://static.pigsec.cn/wp-content/uploads/repos/cas/bd/bd825ba08f554363a0d4b6ecad81bb0d439dce78641aadfa75d9a4900f2b04c0.gif) ## 概述 本项目使 In2Games [Gametrak](https://en.wikipedia.org/wiki/Gametrak) PlayStation 控制器能够通过 [OSC](https://en.wikipedia.org/wiki/Open_Sound_Control)、[MIDI](https://en.wikipedia.org/wiki/MIDI)、[WebMIDI](https://www.w3.org/TR/webmidi/)、[WebSockets](https://en.wikipedia.org/wiki/WebSocket)、[stdout](https://en.wikipedia.org/wiki/Standard_streams) 及其他工作流,作为六轴 [HID](https://en.wikipedia.org/wiki/Human_interface_device)(人机接口设备)使用。我们为流行的创意编程环境提供了可运行的示例,包括 [Processing](https://processing.org/) (Java)、[p5.js](https://p5js.org/) 和 Python。 这项工作建立在 Géry Casiez ([@casiez](https://github.com/casiez/)) 开发的 [libgametrak](https://github.com/casiez/libgametrak) C 语言库的基础之上 —— 尤其是他对 Gametrak 特殊 USB 初始化消息的发现。在 macOS 上,Gametrak 控制器会作为标准的 USB HID 摇杆类设备显示。*然而*,在收到 `libgametrak` 的 PS2 模式所使用的初始化消息之前,GameTrak 不会开始传输有用的数据。有关本项目中分发的第三方代码的更多信息,请访问[此处](THIRD_PARTY.md);有关使用 Gametrak 进行创意研究的一些参考资料,请参见[此处](docs/prior_art.md)。 这项工作已在 macOS 15.6 环境下使用 Python 3.10 和 3.14、Processing 4.5.5 和 4.3,以及 p5.js 1.11.13 和 2.3.0 进行了测试。此处测试的具体设备在其底部的物理标签为 *GameTrak V2.0*,而 USB 报告显示其为来自 *In2Games Ltd* 的 *Game-Trak V1.3*;它使用 VID `0x14B7` 和 PID `0x0982`。 **目录:** * [关于 Gametrak 控制器](#about-the-gametrak-controller) * [支持的工作流](#supported-workflows) * [快速开始](#quick-start) * [Python 命令](#python-commands) * [Processing 与 p5.js](#processing-and-p5js) * [设备与协议事实](#device-and-protocol-facts) * [校准边界](#calibration-boundary) * [开发](#development) * [故障排除](#troubleshooting) * [致谢](#acknowledgments) ## 关于 Gametrak 控制器 ![gametrak.jpg](https://static.pigsec.cn/wp-content/uploads/repos/cas/16/16a2f9bf49a26ffb2318fd9f5ba1ad164e692544208b23fce2adb3713c7065f0.jpg) Gametrak 最初由 In2Games Ltd. 制造,作为 PlayStation 2 的高尔夫游戏《*Real World Golf*》的控制器。其独特的界面包含两个摇杆组件,每个摇杆具有 X/Y 运动加上可伸缩的系绳,从而以 75 Hz 的频率产生六个位于 `0..4095` 范围内的 12 位位置数据流。因为二手设备在 [eBay 上相当便宜](https://www.ebay.com/sch/i.html?_nkw=Gametrak+controller+PS2)(大约 20-40 美元),而且这种系绳式摇杆富有表现力,且作为物理上可读的三维位置追踪器,该设备已成为实验性界面的流行平台,特别是在电子音乐和如 [Wekinator](https://doc.gold.ac.uk/~mas01rf/Wekinator/) 等机器学习工作流中。使用 Gametrak 的一些创意艺术研究项目示例可以在[此处](docs/prior_art.md)找到。 ## 支持的工作流 [![mcreynolds_nicholson_dance.jpg](https://static.pigsec.cn/wp-content/uploads/repos/cas/01/01ce3df85ba346f737d071b4c8dc6321a2b426dd5c0de9abe44193bf16dba273.jpg)](https://www.youtube.com/watch?v=HdFHGbpswag&t=189s)
*选自 Richard McReynolds 创作、Jodi Ann Nicholson 表演的《"[在声音中捕捉动作](https://richardmcreynolds.com/blog/2024/1/8/yx7md3hbz8mngcy14oat54rgljgknf)"》(2024)。[查看更多使用 GameTrak 的创意项目](docs/prior_art.md)。* 本仓库提供了几种获取、转换和使用 Gametrak 控制器数据的方法: | 路径 | 它是什么,以及何时使用 | |---|---| | `gametrak-stdout` | **HID 到 stdout**。这是一个用 Python 构建的命令行程序,它将 Gametrak 控制器数据输出到终端的 `stdout`。它适用于快速诊断、日志记录、通过管道将数据传递给其他程序以及其他 Unix 风格的脚本。 | | `gametrak-record` | **HID 到 JSONL**。这是一个用 Python 构建的命令行程序,它将完整的原始 HID 报告记录为 [JSONL](https://scrapfly.io/blog/posts/jsonl-vs-json) 文件。它适用于协议研究、官方采样捕获、错误报告和可复现的测试数据。 | | `gametrak-playback` | **JSONL 到 stdout/OSC/MIDI/WebSocket**。这是一个用 Python 构建的离线命令行程序,它通过一种选定的输出协议重放 `gametrak-record` 的捕获内容。它适用于在没有物理控制器的情况下进行接收端开发。 | | `gametrak-osc` | **HID 到 OSC**。这是一个用 Python 构建的命令行程序,它通过 OSC 将 Gametrak 控制器数据传输给其他软件(如 Processing、TouchDesigner、Max/MSP 等)。同时还提供了一个 Processing (Java) 的 OSC 接收器。 | | `gametrak-midi` | **HID 到 MIDI**。这是一个用 Python 构建的命令行程序,它将 Gametrak 控制器数据作为 MIDI 弯音信号进行传输。它可用于任何能够读取虚拟 MIDI 端口的 MIDI 软件(Max/MSP、Ableton Live、Logic、VCV Rack、MIDI Monitor),以及支持 WebMIDI 的浏览器中的 Web 应用程序。同时还提供了一个 p5.js 接收器。 | | `gametrak-ws` | **HID 到 WebSocket JSON**。这是一个用 Python 构建的命令行程序,它通过原生 WebSocket 将 Gametrak 数据流传输到浏览器草图。它对 p5.js 和其他 JavaScript 项目非常有用,且不需要 Node.js 或 WebMIDI。同时还提供了一个 p5.js 接收器。 | | [gametrak_midi_receiver_p5v2](p5js/gametrak_midi_receiver_p5v2/README.md) | **MIDI 到 p5**。这是一个 p5.js (v.2.3.0) 草图,通过 WebMIDI 接收并可视化来自 `gametrak-midi` 的 MIDI 数据。六个 12 位数据流作为弯音信号在 MIDI 通道 1-6 上发送。同时支持 p5.js 的 v1 和 v2 版本。使用 [webmidi.js](https://webmidijs.org/)。 | | [gametrak_ws_receiver_p5v2](p5js/gametrak_ws_receiver_p5v2/README.md) | **WebSocket 到 p5**。这是一个 p5.js (v.2.3.0) 草图,通过浏览器原生 WebSocket 接收并可视化来自 `gametrak-ws` 的 JSON 消息。同时支持 p5.js 的 v1 和 v2 版本。 | | [gametrak_osc_receiver](processing/gametrak_osc_receiver/) | **OSC 到 Processing**。这是一个 Processing (v.4.5.5) 应用程序,用于接收并可视化来自 `gametrak-osc` 的 OSC 数据。默认情况下,OSC 接收器应在 UDP 端口 2434 上监听。 | | [gametrak_standalone](processing/gametrak_standalone/) | **HID 到 Processing**。这是一个独立的 Processing (v.4.5.5) 草图,直接作为 HID 设备连接到 Gametrak。不需要其他软件。使用 [hid4java](https://github.com/gary-rowe/hid4java)。 | | [gametrak_osc_transmitter](processing/gametrak_osc_transmitter/) | **HID 到 OSC**。这是一个独立的 Processing (v.4.5.5) 草图,直接作为 HID 设备连接到 Gametrak 并通过 OSC 传输 `/gametrak/raw` 数据包。不需要其他软件,但可以与 [gametrak_osc_receiver](processing/gametrak_osc_receiver/) 配合使用。 | 所有路径都公开相同的语义通道顺序: ``` left_x left_y left_r right_x right_y right_r ``` * 原始值的范围是 `0..4095`。 * 摇杆 X/Y 值是居中的控制值。 * 系绳 `R` 值相对于其“伸展长度”是反转的(系绳较短/收缩时读数较高,而向外拉出会使原始值下降)。 * Gametrak 踏板开关无法进行测试,目前尚不支持。 ## 快速开始 ![charles_lootd](https://static.pigsec.cn/wp-content/uploads/repos/cas/fa/fac84a36090668319d24f9a33091e6ee939e05bc4f589205572e8b0d430c6f9f.jpg) 使用 `pipx` 从源码检出版本**安装** Python 命令: ``` cd python pipx install --python python3.10 . ``` 如果您已经安装了较早的检出版本,请强制重新安装,以便应用新命令和依赖项: ``` cd python pipx install --force --python python3.10 . ``` 如果 `pipx install .` 报告 Python 3.9 版本过旧,请继续使用上面显式的 `--python python3.10` 形式,或者将 `pipx` 指向另一个已安装的 Python 3.10+ 解释器。 运行其中一个 Python “桥接”应用程序: * `gametrak-stdout` —— 将数据打印到终端 * `gametrak-record` —— 记录 JSONL 文件 * `gametrak-playback` —— 在没有设备的情况下重放 JSONL 文件 * `gametrak-osc` —— 传输 OSC * `gametrak-midi` —— 传输 MIDI * `gametrak-ws` —— 为浏览器草图传输 WebSocket JSON 不要同时运行多个占用 HID 的桥接程序。例如,在启动 `gametrak-midi`、`gametrak-ws`、`gametrak-record` 或独立的 Processing HID 草图之前,您应该先退出 `gametrak-osc`。`gametrak-playback` 不会打开 Gametrak 设备,因此可以在未连接控制器时使用它。 *(图片来自 Charles Lootd 的 GameTrak [评测](https://www.youtube.com/watch?v=0VzQ3KgV5Gc)视频)* ## Python 命令 占用硬件的 Python 命令支持: ``` --diagnose ``` 诊断模式会打印一份技术 HID/USB 报告,并在不进行流式传输的情况下退出。它包括预期的 VID/PID、匹配的 hidapi 设备、制造商/产品字符串、使用页面/用途、接口编号、hidapi 路径、简短的开/关探测,以及当 `system_profiler` 暴露时的 macOS USB 拓扑结构。 ### gametrak-stdout `gametrak-stdout` 每行准确打印六个值: ``` left_x left_y left_r right_x right_y right_r ``` 示例: ``` gametrak-stdout gametrak-stdout --rate 30 gametrak-stdout --normalized --precision 4 gametrak-stdout --hex gametrak-stdout --0dec gametrak-stdout --diagnose ``` 模式: | 选项 | 输出 | 示例值 | |---|---|---| | 默认 / `--raw` | 原始十进制 `0..4095` | `26` | | `--0dec` | 原始十进制,4位零填充 | `0026` | | `--hex` | 原始十六进制,3位大写零填充 | `01A` | | `--normalized` | 描述符比例的便利浮点数 | `-0.125` | 由于 stdout 仅包含数据行,而诊断信息发送至 stderr,因此正常的 Unix 管道可以正常工作: ``` gametrak-stdout --rate 30 > capture.txt gametrak-stdout --rate 30 | awk '{ print $1, $2 }' gametrak-stdout --rate 30 | ./my-gametrak-consumer ``` ### gametrak-record `gametrak-record` 将完整的 HID 输入报告写入 JSONL 捕获文件。每一行都是一个 JSON 对象。第一行是会话元数据,每个报告行保留原始报告字节以及解码后的轴数据,最后一行是摘要。 ``` gametrak-record --seconds 10 --out sample_reports/official_001.jsonl gametrak-record --seconds 10 --label official --note "short movement sample" --out sample_reports/official_001.jsonl gametrak-record --seconds 5 --print gametrak-record --diagnose ``` 使用 JSONL 而不是一个大型的 JSON 文件,是因为 GameTrak 数据是一个流:如果录制被中断,部分捕获的内容仍然有用;可以在录制期间使用 `tail` 检查文件;并且该格式对 Unix 管道保持友好。 ### gametrak-playback `gametrak-playback` 重放由 `gametrak-record` 生成的 JSONL 捕获内容。它不会打开 Gametrak 设备。相反,它根据存储的 `raw_bytes_hex` 行重建解码后的报告,并通过选定的协议输出它们。官方示例录音在[此处](sample_reports/README.md)。 ``` gametrak-playback sample_reports/gametrak_sample_10_second_recording.jsonl --stdout gametrak-playback sample_reports/gametrak_sample_10_second_recording.jsonl --stdout --rate 30 gametrak-playback sample_reports/gametrak_sample_10_second_recording.jsonl --osc --loop gametrak-playback sample_reports/gametrak_sample_10_second_recording.jsonl --ws --loop gametrak-playback sample_reports/gametrak_sample_10_second_recording.jsonl --midi --port-name "GameTrak Playback" ``` 准确选择一个输出协议: | 选项 | 输出 | |---|---| | `--stdout` | 与 `gametrak-stdout` 匹配的终端行 | | `--osc` | 与 `gametrak-osc` 匹配的 OSC 消息 | | `--midi` | 与 `gametrak-midi` 匹配的 MIDI 弯音 | | `--ws` | 与 `gametrak-ws` 匹配的 WebSocket JSON | 默认情况下,回放会遵循录制时的 `elapsed_ns` 计时。使用 `--rate` 可强制设定固定输出速率,使用 `speed` 可缩放录制的时间,使用 `--loop` 可在开发接收器时无限期重复播放捕获内容。 在适用的地方,输出模式标志与实时工具相匹配: ``` gametrak-playback sample_reports/gametrak_sample_10_second_recording.jsonl --stdout --hex gametrak-playback sample_reports/gametrak_sample_10_second_recording.jsonl --stdout --normalized gametrak-playback sample_reports/gametrak_sample_10_second_recording.jsonl --osc --normalized gametrak-playback sample_reports/gametrak_sample_10_second_recording.jsonl --ws --normalized gametrak-playback sample_reports/gametrak_sample_10_second_recording.jsonl --osc --wekinator ``` `--hex` 和 `--0dec` 仅适用于 stdout。MIDI 回放使用原始的 Gametrak 值,就像 `gametrak-midi` 一样。 ### gametrak-osc `gametrak-osc` 通过 HID 读取 GameTrak,发送所需的初始化/保活序列,解码报告,并广播 OSC。您可以使用提供的 Processing 程序 [gametrak_osc_receiver](processing/gametrak_osc_receiver/) 对其进行测试。 ``` gametrak-osc gametrak-osc --host 127.0.0.1 --port 2434 gametrak-osc --raw --normalized --rate 60 --print gametrak-osc --diagnose gametrak-osc --wekinator ``` 默认输出为原始数据(即 `0...4095` 范围内的 12 位值): ``` /gametrak/raw int left_x left_y left_r right_x right_y right_r buttons ``` 可选的归一化输出(摇杆 X/Y 值在 `-1..1` 之间;系绳伸展值在 `0..1` 之间): ``` /gametrak/normalized float left_x left_y left_r right_x right_y right_r ``` 对于归一化值,摇杆 X/Y 轴是描述符比例的 `-1..1`;系绳 R 轴是描述符比例的 `0..1`,其中 `0` 表示收缩/较短,`1` 表示伸展。这些值是为方便而提供的,并非每个设备的校准值。 “[Wekinator](https://doc.gold.ac.uk/~mas01rf/Wekinator/)”模式发送: ``` /wekinator/control/inputs float left_x left_y left_r right_x right_y right_r ``` OSC 桥接器默认还会监听控制消息: ``` 127.0.0.1:2435 /gametrak/init Resend the init sequence on the current HID handle. /gametrak/reconnect Close/reopen the HID handle, then resend init. ``` 仅当需要将输出限制在设备的原始报告速率以下时,才使用 `--rate`。省略 `--rate` 将发送每一个有效的 HID 报告。 ### gametrak-midi `gametrak-midi` 会创建一个名为 `GameTrak MIDI` 的虚拟 MIDI 输出。Chrome 会将该虚拟输出视为 WebMIDI 输入。您可以使用提供的 p5 WebMIDI 草图 [gametrak_midi_receiver_p5v2](p5js/gametrak_midi_receiver_p5v2/README.md) 对此进行测试。 ``` gametrak-midi gametrak-midi --rate 60 gametrak-midi --print gametrak-midi --port-name "GameTrak MIDI" gametrak-midi --diagnose ``` 桥接器将原始 GameTrak 值直接作为有符号的 MIDI 弯音值发送,范围在通道 1-6 上为 `0..4095`: | MIDI 通道 | GameTrak 值 | |---:|---| | 1 | `left_x` | | 2 | `left_y` | | 3 | `left_r` | | 4 | `right_x` | | 5 | `right_y` | | 6 | `right_r` | WebMIDI 将弯音的无符号传输值暴露为 `event.rawValue`,因此浏览器接收器会减去 `8192` 以恢复有符号的值: ``` const rawGameTrakValue = event.rawValue - 8192; ``` ### gametrak-ws `gametrak-ws` 通过 HID 打开 Gametrak,并在 `ws://127.0.0.1:2436` 上提供浏览器原生的 WebSocket JSON。它专为 p5.js 以及其他无法接收 UDP OSC 且不需要 WebMIDI 的浏览器应用程序而设计。 ``` gametrak-ws gametrak-ws --host 127.0.0.1 --port 2436 gametrak-ws --normalized gametrak-ws --rate 60 gametrak-ws --print gametrak-ws --diagnose ``` 每个 WebSocket 文本消息都是紧凑的 JSON: ``` {"address":"/gametrak/raw","args":[123,2048,4095,500,900,3900,0]} ``` 前六个 `args` 值是: ``` left_x left_y left_r right_x right_y right_r ``` 第七个值是解码后的按钮位域。 使用 `--normalized` 时,`gametrak-ws` 会发送带有六个描述符比例的归一化浮点数且没有按钮位域的 `/gametrak/normalized`: ``` {"address":"/gametrak/normalized","args":[0.0,0.0,0.0,1.0,-1.0,1.0]} ``` ## Processing 与 p5.js ![gametrak_osc_in_processing.gif](https://static.pigsec.cn/wp-content/uploads/repos/cas/0b/0b2bd552411965fa5a5719d6dd851121998664bdc8425bfbf47a1ab911f0f61e.gif) ### Processing 独立 HID 路径: ``` processing/gametrak_standalone/ ``` [**此 Processing 草图**](processing/gametrak_standalone/gametrak_standalone.pde) 通过 `hid4java` 直接与 Gametrak 通信。它不需要 Python、OSC、WebMIDI 或本地服务器。它已在 macOS 15.6 上的 Processing 4.3 和 Processing 4.5.5 中进行了测试。 捆绑的 Java 依赖项: ``` processing/gametrak_standalone/code/hid4java-0.8.0.jar processing/gametrak_standalone/code/jna-5.14.0.jar ``` 源码布局: ``` processing/gametrak_standalone/gametrak_standalone.pde processing/gametrak_standalone/GameTrakDirectHid.java ``` `.pde` 文件拥有 Processing UI。`.java` 助手负责所有直接的 HID 工作,这样 Processing 的 PDE 预处理器就不必解析外部的 `hid4java` 类型。 在运行此草图之前,请退出任何 Gametrak Python 桥接器,以免两个程序争夺同一个 HID 句柄。 ### Processing OSC 发射器 路径: ``` processing/gametrak_osc_transmitter/ ``` [**此 Processing 草图**](processing/gametrak_osc_transmitter/gametrak_osc_transmitter.pde) 通过 `hid4java` 直接与 Gametrak 通信,并将每个有效的 HID 报告作为 OSC `/gametrak/raw` 发送到 `127.0.0.1:2434`。它不需要 `gametrak-osc` 或任何其他 Python 工具。它还在 `127.0.0.1:2435` 上监听 OSC 控制消息。 OSC 有效负载: ``` /gametrak/raw int left_x left_y left_r right_x right_y right_r buttons ``` 在运行此草图之前,请退出任何其他 Gametrak HID 客户端。它直接拥有 HID 句柄。 控制消息: ``` /gametrak/init /gametrak/reconnect ``` ### Processing OSC 接收器 路径: ``` processing/gametrak_osc_receiver/ ``` [**此 Processing 草图**](processing/gametrak_osc_receiver/gametrak_osc_receiver.pde) 使用基于 `java.net.DatagramSocket` 构建的轻量级无依赖 OSC 解析器,在 UDP 端口 `2434` 上接收 `/gametrak/raw` OSC 数据。它将六个原始值可视化为条形图,并显示左/右 X/Y 的时间轴。它可以与 `gametrak-osc` 或基于 Processing 的 [gametrak_osc_transmitter](processing/gametrak_osc_transmitter/) 配合使用。例如,运行: ``` gametrak-osc ``` 然后打开 Processing 草图。 该草图包含一个重置按钮,它将 `/gametrak/reconnect` 发送到 Python OSC 桥接器的控制端口,即 UDP `2434`。之所以选择数据端口 `2434`,是因为它是 Gametrak 的 HID 产品 ID;控制端口使用下一个端口号。 ### p5.js MIDI 接收器 [**此 p5.js 草图**](p5js/gametrak_midi_receiver_p5v2/README.md) 使用 WebMIDI 接收来自 `gametrak-midi` Python 桥接器的 MIDI 信号。 路径: ``` p5js/gametrak_midi_receiver_p5v2/ ``` 运行 MIDI 桥接器: ``` gametrak-midi ``` 通过 localhost 提供该代码仓库的服务,即[在本地服务器上](https://dev.to/kardelio/3-different-ways-to-start-a-http-web-server-from-the-terminal-4am3): ``` cd path/to/GameTrak-Liberation python3 -m http.server 8000 ``` 在 Chrome 中打开: ``` http://127.0.0.1:8000/p5js/gametrak_midi_receiver_p5v2/ ``` 点击 `Enable MIDI` 并允许 Chrome 的 MIDI 权限提示。该草图优先选择名为 `GameTrak MIDI` 的输入。p5 草图的版本同时支持 p5.js 的 v1 和 v2: * [gametrak_midi_receiver_p5v1](p5js/gametrak_midi_receiver_p5v1/README.md) (v.1.11.13) * [gametrak_midi_receiver_p5v2](p5js/gametrak_midi_receiver_p5v2/README.md) (v.2.3.0) ### p5.js WebSocket 接收器 [**此 p5.js 草图**](p5js/gametrak_ws_receiver_p5v2/README.md) 使用浏览器的原生 WebSocket API 接收来自 `gametrak-ws` 的 JSON 消息。 路径: ``` p5js/gametrak_ws_receiver_p5v2/ ``` 运行 WebSocket 桥接器: ``` gametrak-ws ``` 直接在 Chrome 中打开该草图: ``` file:///path/to/GameTrak-Liberation/p5js/gametrak_ws_receiver_p5v2/index.html ``` 草图连接到 `gametrak-ws` 的地址为: ``` ws://127.0.0.1:2436 ``` 此 WebSocket 接收器不需要本地 HTTP 服务器。如果您倾向于使用 `python3 -m http.server` 提供静态文件服务,那也没问题,但是(例如)端口 `8000` 仅是页面服务器;GameTrak 数据仍然通过 WebSocket 端口 `2436` 到达。 WebSocket 草图的版本同时支持 p5.js 的 v1 和 v2: * [gametrak_ws_receiver_p5v1](p5js/gametrak_ws_receiver_p5v1/README.md) (v.1.11.13) * [gametrak_ws_receiver_p5v2](p5js/gametrak_ws_receiver_p5v2/README.md) (v.2.3.0) ## 设备与协议事实 * 有关 Gametrak 通信协议的更多信息,请访问[此处](docs/protocol.md)。 * Gametrak 数据的示例录音可以在[此处](sample_reports/README.md)找到。 经过验证的 USB 标识: | 属性 | 值 | |---|---| | 物理底部标签 | `GameTrak V2.0` PlayStation 高尔夫接口设备 | | USB 产品字符串 | `Game-Trak V1.3` | | USB 制造商字符串 | `In2Games Ltd.` | | 供应商 ID (VID) | `0x14B7` 十进制 `5303` | | 产品 ID (PID) | `0x0982` 十进制 `2434` | | USB 速度 | 全速 USB,12 Mbps | | HID 使用页面 | `0x01`,通用桌面 | | HID 主要用途 | `0x04`,摇杆 | | 最大输入报告大小 | 16 字节 | | 最大输出报告大小 | 4 字节 | HID 描述符公开了六个绝对轴: ``` X, Y, Z, Rx, Ry, Rz ``` 每个轴都是一个逻辑范围为 `0..4095` 的 16 位小端序字段。 经验性的语义映射: | HID 字段 | 语义值 | 方向说明 | |---|---|---| | `X` | `left_x` | 低 = 左,高 = 右 | | `Y` | `left_y` | 低 = 朝向用户,高 = 远离 | | `Z` | `left_r` | 高 = 收缩/较短,低 = 伸展 | | `Rx` | `right_x` | 低 = 左,高 = 右 | | `Ry` | `right_y` | 低 = 朝向用户,高 = 远离 | | `Rz` | `right_r` | 高 = 收缩/较短,低 = 伸展 | ![gametrak_joystick_diagram](https://static.pigsec.cn/wp-content/uploads/repos/cas/ec/ec4f86ad108cec211b0357f43e5c906419a976537f9f1ae34f2d062da37177f4.png) 已知报告注意事项: ``` bytes 0-11: six uint16_le axes byte 12 bits 0-3: hat switch per descriptor byte 12 bits 4-7 plus byte 13: 12 buttons per descriptor bytes 14-15: descriptor padding, but live captures show right-tether-related movement ``` 用于测试的可用硬件不包含外部脚踏开关。描述符公开了按钮位,但是踏板开关的位索引和极性尚未经过测试。 完整的协议注意事项位于: ``` docs/protocol.md ``` ## 校准边界 Python 工具和 Processing 草图不执行针对特定设备的校准。 它们负责: ``` - opening the HID device - sending init/keepalive writes - decoding reports - applying the fixed semantic channel order - emitting or displaying raw values ``` 应用程序代码应负责处理: ``` - per-device min/max calibration - deadband - smoothing/filtering - coordinate transforms - gesture interpretation - application-specific scaling ``` 描述符比例的归一化值仅在明确请求时作为便利输出存在。 ## 开发 对于 Python 开发: ``` cd python python -m pip install -e ".[dev]" python -m pytest ``` 仓库布局: ``` python/ Python package, CLIs, tools, tests processing/ Processing OSC and standalone HID sketches p5js/ Browser MIDI sketches docs/ Protocol and prior-art documentation sample_reports/ Captured sample reports ``` 有用的源码文档: ``` docs/protocol.md docs/prior_art.md THIRD_PARTY.md sample_reports/README.md ``` ## 故障排除 如果没有收到报告,请确保设备直接连接或通过可靠的供电路径连接。在 macOS 上,从集线器更换到直接适配器会导致系统提示请求对该测试设备进行 USB 配件权限许可。 如果桥接器无法打开 HID 设备,请先退出其他 HID 客户端。Chrome WebMIDI、独立的 Processing HID 草图和 Python 桥接器可能会争夺同一个设备。 如果 `pipx install .` 使用的是 Python 3.9,请重新安装: ``` pipx install --force --python python3.10 . ``` 如果 Chrome 没有显示 WebMIDI 输入,请保持 `gametrak-midi` 运行,并从 `http://127.0.0.1` 而不是 `file://` 重新加载 p5 页面。 使用诊断功能获取快速设备报告: ``` gametrak-osc --diagnose gametrak-stdout --diagnose gametrak-record --diagnose gametrak-midi --diagnose ``` ## 致谢 * Gametrak 于 2000 年[由 Elliott Myers](https://en.wikipedia.org/wiki/Gametrak) 发明。 * 感谢 [Rebecca Fiebrink](https://researchers.arts.ac.uk/1594-rebecca-fiebrink) 在 STUDIO 的 Wekinator 研讨会上向我介绍了 Gametrak。Rebecca 为展示像 Gametrak 这样的富有表现力的控制器如何与机器学习相结合,从而服务于音乐的包容性和探索,开辟了道路。 * 感谢 Géry Casiez,他在 14 多年前完成的 `libgametrak` 逆向工程项目为此奠定了坚实的基础,才使这一切成为可能。 * 重新分发的第三方代码索引可以在[此处](THIRD_PARTY.md)找到。 * 此代码仓库由 Codex 协助开发。
标签:Blue Team, MIDI, OSC, p5.js, Python, WebSocket, 人机交互设备, 依赖分析, 创意编程, 无后门, 逆向工具