和弦色块实时推进:节拍时钟是怎么保证灯光和曲谱同步的
为什么同步精度重要
弹唱是一种时间敏感的体验:
- 和弦色块推到末尾、LED 亮下一个 → 这两个动作必须同时发生
- 你按指板 → 扫弦桨发声 → 这两个也必须几乎同时发生
- 鼓机节奏要和扫弦桨的物理触发严格对齐
如果有 100 毫秒以上的延迟,人耳就能感觉到"灯光亮了但音乐慢半拍"或者"扫弦按下去了声音晚出来"。这也是为什么传统蓝牙音频(有 100~200 毫秒延迟)完全不适用于弹唱实时交互。
LiberLive 用什么时钟
节拍时钟的精度决定了所有同步的基础。LiberLive App 用的是:
- iOS:
AVAudioEngine的音频时钟(hostTime),微秒级精度,和音频输出硬同步 - Android:
AudioTrack的时间戳 +Choreographer,虽然不如 iOS 完美但也远高于Handler.postDelayed()
这个时钟和曲谱里每个和弦块的节拍时间戳做差,就能精确知道"现在应该推进到和弦块的哪一部分了"。
和弦色块推进的三种模式
根据 3.4.5 版本和多维曲谱 2.0 的特性,和弦色块的推进有三种可能模式:
| 模式 | 触发方式 | 适用场景 |
|---|---|---|
| 自动推进 | App 节拍时钟驱动,和歌曲 BPM 严格同步 | 初学者、跟着曲谱练歌时 |
| 扫弦触发 | 你每拨一下扫弦桨,曲谱色块推进一格 | 想自己控制速度、想停顿重练某段时 |
| 鼓机跟奏(C2 / U1 特有) | 鼓机跟随你的扫弦推进,你停鼓机也停 | 3.8.0 版本新增,弹唱自由度更高 |
默认是自动推进模式——新手最友好,因为你只需要跟着灯光按指板,不需要自己控制速度。
BLE 推送到硬件的时机
这是保证同步的关键一步。App 推"下一个和弦位亮灯"指令给 C1 / C2 / U1 的时机是:
(下一个和弦的节拍时间戳) - (BLE 延迟缓冲 30ms) - (LED 响应时间 1ms)
其中 30 毫秒的缓冲值不是拍脑袋的——它是官方根据大量实测得到的平均值:BLE 数据包从 App 发出 → C1 MCU 收到 → MCU 控制 LED 亮起来,这个过程在理想环境下是 10~20 毫秒,留 30 毫秒缓冲是为了在网络微波动时也不误触发。
如果蓝牙有卡顿怎么办
BLE 虽然低功耗但不保证 100% 稳定——当附近有大量蓝牙设备或电磁干扰时,偶尔会出现丢包。App 有两层兜底:
- 节拍时钟不中断:哪怕 BLE 暂时没连上,App 内部的节拍时钟继续跑、曲谱色块继续推、内置音色继续发声。等 BLE 恢复后自动重发当前和弦的 LED 指令
- 重连后状态同步:BLE 重连成功时,App 先把"当前应该亮哪个和弦"推给硬件,而不是从第一个和弦开始。这是一个很重要的设计——不会让你弹到一半被拉回开头
实测延迟体验
根据官方 FAQ 和社区用户反馈,在理想环境下(C1 + iPhone + 附近蓝牙设备 < 5 个):
- 灯光延迟:< 30 毫秒(人眼感觉不到)
- 扫弦桨发声延迟:< 50 毫秒(和传统吉他手感接近)
- 鼓机同步精度:几乎听不出偏差
但如果附近有大量蓝牙设备干扰(比如展会、办公室),延迟可能升到 100 毫秒以上——这也是官方 FAQ 建议"附近蓝牙设备太多就换个位置"的原因。
和扫弦桨的关系
扫弦桨的发声逻辑有两种:
- 自动扫弦:鼓机跟随节拍时钟自动推进扫弦节奏 → 扫弦桨变成"静音开关"(按一下开、再按一下关)
- 手动扫弦:扫弦桨每按一下触发一次发声 → App 记录你按扫弦桨的时间戳,用它反推和弦色块推进速度(扫弦触发模式)
新手推荐先用自动扫弦模式,练熟之后再切手动扫弦——能更精细地控制每一下扫弦。