一个笔记本转轴,被人用 Rust 写代码调教成会“吱呀”叫的老木门——这就是 GitHub 上小项目 creakwork12 干的事。作者标题里埋了个双关:hinge rusty(转轴生锈)也是 written in Rust(用 Rust 写的)。目标机型是 Framework Laptop 12,一款主打模块化、可维修的独立品牌笔记本。

16 颗星,功能极其无用又极其有趣:开合笔记本,扬声器就配出老木门的吱呀声,角度决定音高,开合速度决定音量。作者写得很直白,why 那一栏就一个词:funny。

但拆开它的实现逻辑,会看到一个比“恶搞”更值得琢磨的问题。

声音是怎么做出来的

程序每 75 毫秒读一次转轴角度传感器的数值,算出角度变化的速度,再用 One Euro 滤波算法做平滑处理——这是交互设计里常用来处理带噪声实时运动数据的低延迟算法,触控屏、姿态识别都在用。

滤波之后是一套状态机:过滤掉 0-360 度之外的异常读数,区分“开合中 / 静止”两种状态,避免声音在临界点反复闪烁触发。最后一步是映射——角度决定音高开合速度决定音量,通过 rodio 库播放。整条链路简单,但工程上算干净。

转轴吱呀声怎么合成 75ms 轮询角度 计算 移动速度 One Euro 滤波平滑 状态机防抖 角度→音高 速度→音量 依赖: industrial-io 0.6.1 / one-euro-rs 0.2.0 / rodio 0.22.2, Rust 2024 edition

依赖版本写得很实在:industrial-io 0.6.1one-euro-rs 0.2.0rodio 0.22.2,用 Rust 2024 edition。Fedora 上编译要装 libiio-develalsa-lib-devel,Debian/Ubuntu 换成 libasound2-dev。Releases 里的预编译二进制是在 Fedora 上构建的——作者自己承认,其他发行版可能踩到动态链接的坑。这是一个只在自己机器上验证过的项目,跨发行版兼容性目前没有第三方确认。

真正的疑点:角度从哪来

Framework 长期靠“开放、可维修”经营 Linux 社区好感,嵌入式控制器代码开源。但 Linux 下暴露硬件传感器数据,走的是 Industrial I/O 子系统,对折叠类设备,历史上更常见的做法是只给一个二元的 tablet-mode 开关(SW_TABLET_MODE),而不是连续角度值。

这个项目的 README 说自己“读取转轴角度”,代码逻辑也确实按连续角度设计——滤波、状态机、音高映射,全建立在“角度是个连续变量”这个前提上。问题是,没有独立信息能证实 Framework 12 真的在 Linux 下给出了这样一个连续角度接口。

声音效果做得再顺滑,也掩盖不了它建立在一个未经证实的传感器假设上。

如果实际读到的只是二元开关状态,或者是靠加速度计反推出来的近似角度,那这套“音高跟随位置、音量跟随速度”的效果,成色就要打折扣——加速度计推算角度在设备被快速移动时精度和延迟本来就不稳定,恰恰是这个项目最想展示的“快速开合更响”的场景。

  • 提醒.Framework 12 的转轴到底暴露连续角度还是二元开关,目前没有权威资料证实,感兴趣的读者可以自己用 evtestmonitor-sensor 在实机上查一遍。

这类项目在 Show HN 上不是第一次出现,也不会是最后一次——给硬件加点声音反馈,一直是黑客文化里“没用但好玩”的经典操作。但一个笔记本厂商标榜开放,具体到“转轴角度精度是多少”这种细节文档是否透明,往往比营销话术更能说明问题。目前也没有可靠的 Hacker News 讨论区反馈能证实这个项目在其他机型或发行版上的真实表现,社区验证这一环,还是空的。

一个 16 星的整活项目,顺手把这个问题摆到了台面上:Framework 说自己开放,但开放到什么颗粒度,可能连它自己的转轴角度都没讲清楚。