Music(チューナー / メトロノーム / ドラム)
音楽ユーティリティアプリ。7つのタブで、ギターのチューニングの学習から、ヘッドフォンのキャリブレーション用のピュアトーン生成、その中にTR-808スタイルの合成ドラムまでカバーします。

Tablaturaとの違い: Musicは「独立したツール」です。Tablaturaはマルチトラックエディタです。それらは音声プリミティブ(useAudioContext、ドラムシンセ、ボイス)を共有しますが、UIとフローは完全に異なります。
7つのタブ
| タブ | 機能 | アイデンティティ色 |
|---|---|---|
| Tuner | YIN ±1セントの半音階チューナー | 緑 #00d97e |
| Metronome | 高精度メトロノーム(25msルックアヘッドスケジューラ) | オレンジ #ff9500 |
| Frequency | ピュアトーンジェネレーター(50Hz–20kHz)+ バイノーラルビート | 紫 #af52de |
| Drums | 合成ドラム(16パッド × 3キット)+ シーケンサー | 赤 #ff453a |
| Piano | 仮想ピアノ2オクターブ + サスティンペダル | 青 #5ac8fa |
| Chords | 認識器 + 図付きコードライブラリ | 黄 #ffd60a |
| Scales | スケール可視化(12ルート × 12タイプ) | ターコイズ #5ee3ff |
Tuner
YIN(Cheveigne & Kawahara 2002)を使った半音階チューナー — ~250行のコード、依存関係なし、~1セント精度。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
4つの波形(sine / square / triangle / sawtooth)でピュアOscillatorNode。50Hzから20kHz。ボリュームスライダー0-100% でログカーブ(知覚マッチング用の非線形)。
バイノーラルビート(トグル): 左耳に1つの周波数、右耳にわずかに異なるものを再生。脳は差(1-30Hz)を第3の幽霊周波数として認識します。瞑想/集中アプリで使用。臨床耳の代わりにはならず、実験的です。
エフェクトチェーン(オン/オフトグル): オプションのリバーブ + ディレイ。ミキサーUIなし — トグル + ミックススライダーのみ。
Drums
16パッド × 3キット(Acoustic / Electronic / Latin)。各ヒットはOscillatorNode + GainNode + BiquadFilterNodeで合成的にエンベロープされます — サンプルファイルゼロ。バンドルを膨らませることなくTR-808スタイルのアイコニックなサウンド。
Sequencer: グリッドステップベース、ステップごとにモノフォニック。最大4小節。「Save pattern」をタップして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は、ネイティブアプリだからこそ解決しています。
- 部分的な回避策: アプリは
playsInline+MediaSession metadataで非表示のHTMLAudioElementを作成し、最初のユーザージェスチャでトリガーします。これは、音声セッションを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ではありません。学習とカジュアルなビート作成にOK。
- ステップごとにモノフォニックシーケンサー: 各ステップはオンかオフ。ベロシティ/スイングなし。DAWではありません。
- オンセットタイプのBPM検出器: 安定したテンポ(パーム、キック)には良い。重いシンコペーションを伴う複雑な音楽には悪い。
- Capoはコードの名前を変えるだけ: 完全な転調進行を演奏しません。「Eでタブを取ったけど、カポ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(マルチトラックエディタ) — 同じ音声プリミティブを使用