Music(调音器 / 节拍器 / 鼓机)
音乐实用工具应用。7 个选项卡涵盖从学习吉他调音到为耳机校准生成纯音,中间还有 TR-808 风格的合成鼓机。

与 Tablatura 的区别: Music 是"独立工具"。Tablatura 是多轨编辑器。它们共享音频原语(useAudioContext、鼓机合成器、声音),但 UI 和流程完全不同。
7 个选项卡
| 选项卡 | 功能 | 身份颜色 |
|---|---|---|
| Tuner | YIN ±1 cent 半音调音器 | 绿色 #00d97e |
| Metronome | 高精度节拍器(25ms 预读取调度器) | 橙色 #ff9500 |
| Frequency | 纯音发生器(50Hz–20kHz)+ 双耳节拍 | 紫色 #af52de |
| Drums | 合成鼓机(16 个 pad × 3 个套件)+ 序列器 | 红色 #ff453a |
| Piano | 虚拟钢琴 2 个八度 + 延音踏板 | 蓝色 #5ac8fa |
| Chords | 识别器 + 带图表的和弦库 | 黄色 #ffd60a |
| Scales | 音阶可视化(12 根音 × 12 类型) | 青色 #5ee3ff |
Tuner
使用 YIN(Cheveigne & Kawahara 2002)的半音调音器 — ~250 行代码,无依赖,~1 cent 精度。50-2000Hz 范围涵盖所有常见乐器。
3 种视图模式:
- Needle(默认): 物理调音器样式的复古指针,带过去 10 秒的计时图
- Spectrum: FFT 条形图(经典舞台调音器样式)
- VU: 带弹道阻尼的复古 VU 仪表
可配置参考 A(415-466 Hz,默认 440)。适用于巴洛克音乐(415)或复古爵士乐(442)。
录音会话: 点击"录制" → 记录最多 60 秒的音频 + 时间线 { t, freq, cents, note },最后变成图表。适合查看某处是否走调。
Metronome
高精度调度器(100ms 预读取,在 AudioContext.currentTime 上调度事件)。setInterval 会漂移 — 这个不会。
- BPM: 40-240
- 拍号: 4/4(默认)、3/4、6/8、5/4、7/8、12/8
- 细分: 四分音符、八分音符、三连音、十六分音符
- 4 种声音(click / woodblock / cowbell / beep)— 每种都有第一拍上音调更高的"重音"变体
- BPM Detector: 按"检测 BPM",用相机/麦克风敲打节拍。算法结合起始检测 + 自相关。适合在没有乐谱的情况下翻唱歌曲
- Practice Timer: 集成倒计时。播放 X 分钟节拍器,然后一起暂停
Frequency Generator
纯 OscillatorNode,带 4 种波形(sine / square / triangle / sawtooth)。50Hz 到 20kHz。音量滑块 0-100%,对数曲线(非线性匹配感知)。
双耳节拍(切换): 在左耳播放一个频率,在右耳播放略有不同的频率。大脑将差异(1-30Hz)感知为第三个幻影频率。在冥想/专注应用中使用。不能替代临床耳朵,是实验性的。
效果链(开/关切换): 可选的混响 + 延迟。无混音器 UI — 仅切换 + 混音滑块。
Drums
16 个 pad × 3 个套件(Acoustic / Electronic / Latin)。每次击打是 OscillatorNode + GainNode + BiquadFilterNode 合成包络 — 零样本文件。TR-808 风格的标志性声音,不会膨胀包。
Sequencer: 基于网格的步进,每步单音。最多 4 小节。点击"保存模式"以保存到 Firestore(users/{uid}/roqueos/music.drums.sequencerPattern)。
Presets: ~25 种精选节奏(rock basic、funk shuffle、bossa nova、jazz swing、latin clave)。应用预设会替换当前模式 — 如果已经记录了音符则会有确认对话框。
重要的 iOS 怪癖
iPhone 上的 Web Audio 应用有记录的解决方法:
- 静音开关错误: iPhone 的物理静音按钮即使在高音量下也会使 Web Audio 静音。Apple Music/Spotify 解决了,因为它们是原生应用。
- 部分解决方法: 应用程序创建一个不可见的
HTMLAudioElement,带有playsInline+MediaSession metadata,在第一次用户手势时触发。这部分"声明"音频会话为media playback。 - 结果: 大多数情况下有效。某些特定的 iPhone(旧型号、旧 iOS)仍然静音。
检测到 iOS 时自动出现琥珀色横幅,带有"了解"按钮,该按钮在 localStorage 中保留解除。这不是阻止程序 — 只是解释行为。
最终解决方案(通过 Capacitor 在 App Store 中发货时): 原生 Swift 插件在 WebView 挂载之前配置 AVAudioSessionCategoryPlayback。记录在 87-music-system.md 部分"iOS 静音开关 — 当前限制 + 未来 Capacitor"。
持久性
Firestore 路径: users/{uid}/roqueos/music
持久化:
{
"tuner": { "referenceA": 440, "viewMode": "needle" },
"metronome": { "lastBPM": 120, "lastTimeSignature": "4/4", "practiceTimerMinutes": 15 },
"frequency": { "lastHz": 440, "lastWave": "sine", "binauralEnabled": false, "delayEnabled": false },
"drums": { "lastKit": "acoustic", "masterVolume": 0.8, "sequencerPattern": {...} },
"scales": { "lastRoot": "C", "lastType": "major" },
"chords": { "capoFret": 0 }
}去抖保存 800ms。不会冻结 UI。
视觉身份
每个选项卡都注入了 --tab-accent(hex)作为内联 CSS 变量。根上的环境网格 ::before + 通过 rgba(var(--tab-accent-rgb), alpha) 的组件中的发光。
结果: 活动选项卡平滑地"染色"整个面板,无需更改屏幕。
接受的权衡
- 合成 > 样本: 合成套件有自己的身份(TR-808)。不是 Battery 4。适合学习和制作休闲节拍。
- 每步单音序列器: 每步开或关。无力度/swing。不是 DAW。
- 起始类型 BPM 检测器: 适合稳定节奏(鼓掌、kick)。不适合复杂的具有重切分音的音乐。
- Capo 仅重命名和弦: 不播放完整的转调进行。涵盖"我用 E 调记谱,想用 capo 2 的 D 看"的情况。
参考
- 在
src/config/apps.js注册的应用(id: 'music') - 组件:
src/components/roqueos/apps/ROSMusic.vue - 可组合项:
src/composables/useAudioContext.js(单例)、src/composables/useAudioScheduler.js(精确调度器) - YIN 算法:
src/utils/music/pitchAlgorithms.js - 鼓合成:
src/utils/music/drumSynth.js - 完整规则在
.claude/rules/87-music-system.md - 并行应用: Tablatura(多轨编辑器) — 使用相同的音频原语