
2026/06/27 8:29
Waveloop:Fable が私に残したもの
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
中心的な成果は「Waveloop」という、2 日間の開発で Fable フレームワークを用いて作成された高度な音楽可視化ツールです。Waveloop はファイルからまたはライブマイクロフォンからのオーディオを分析し、音程を周期的な 12-TET ピッチクラス円環上の角度としてマッピングする(半音ごとに 30°)、和弦の質を図形で表現し、八度は Oklch 空間で色を用いて表現することで、調和的・旋律的な構造を視覚的に明らかにします。これを支える技術的な実装には、周波数分析のための FFT が採用され、安定性を確保するために事前に計算された CQT が用いられています。また、Terry Davis のような高密度なコーディングスタイル(例:アルファ値のプリマルチプライ)も見られます。プロジェクトには、コード名や和弦の質を表すための配列を使った特定のロジックが含まれており、
detectChord() というスコアリングベースの関数が採用されており、ウクレールのボイシングのような和弦を特定可能です。開発プロセスは反復的であり、最初に「ひどい音声吹き込み」付きの乱雑な草稿として始まり、AI のサポートを受けつつ最終的には磨き上げられた説明ビデオへと進化しました。フィードバックにより会話を基調としたトーン(3blue1brown スタイル)およびより正確な音・視覚の対応関係が求められ、最終的なクリーンアップによって数学表現の適切な活字付け、一貫した音声、重ね合わされない図表が実現しました。全体として、Waveloop は、現代の AI が複雑なオーディオ分析と手続的生成を効率化する方法を示しており、特定のコーディングスタイルと新たなツールを組み合わせることで急速なプロトタイピングを実現しています。なお、プロジェクトには「Claude が SVG を生成し、著者が散文を書いた」という免責事項が記載されています。本文
Fable と Waveloop:音楽理論を視覚化する探求
Fable の機能を 2 日間テストする機会がありましたが、その間に「Waveloop(ウェーブループ)」という音楽ビジュアライザの開発を行いました。これは、私が記憶のある限りずっと夢想してきたアイデアの実現です。
Waveloop の核となるコンセプト
このアイデアの核は、音楽ビジュアライザが視覚的な感覚を通じて、楽曲の調性構造と旋律構造を直感的に明らかにするべきだという点にあります。
しかし、多くの既存のビジュアライザはこの目的を失敗しています:
- 単に音の強さ(音量)しか示さない。
- ベースとトゥーブル(分離度)の情報くらいしか提供しない。
- 調性や構造そのものの情報を欠いている。
西洋音楽理論に基づく設計思想
Waveloop は**十二平均律(12-TET)**の循環構造を基盤としています。
- 半音間隔: $12\sqrt{2}$(正確には十二平均律における半音間隔)
- オクターブ: この単位を 12 回繰り返すことで到達する。
- ピッチクラス: オクターブ整数倍離れている音符は同一とみなされる。
Waveloop はこの構造を**「円形スケール」**として表現します:
- 半音あたり $30^\circ$ の回転を描画。
- オクターブごとに一周を描画。
- 楽曲の任意の瞬間は、各ピッチクラスの出現度合いを示す螺旋状のスタックヒストグラムとして可視化される。
- 色の使い分け:
- ベース: 消えたような青緑色
- 中音域: 燃えるような橙赤紫
- ハイハット: キラキラしたゴールドとスカイブルー
- これらをoklch 色彩空間に沿って螺旋を描画。
優れた特性:音程と和音の直感的理解
この表現形式には以下のような優れた特性があります。
1. 音程は単に角度として読み取れる
ピッチクラスの出現位置から、即座に音程を把握できます。主な音程とその対応角度です:
- 小二度(m2): $30^\circ$
- 大二度(M2): $60^\circ$
- 小三度(m3): $90^\circ$
- 大三度(M3): $120^\circ$
- 完全四度(P4): $150^\circ$
- 増四度(TT): $180^\circ$
- 完全五度(P5): $210^\circ$
- 小六度(m6): $240^\circ$
- 大六度(M6): $270^\circ$
- 小七度(m7): $300^\circ$
- 大七度(M7): $330^\circ$
2. 和音の性質は形状から判断できる
転調は図形を回転させ、転回(インバージョン)は図形の形状そのものを変えません。一般的な和音の構成比率(ivs)を示します:
- メジャー・トライアド: $0 \cdot 4 \cdot 7$
- マイナー・トライアド: $0 \cdot 3 \cdot 7$
- 減三和音: $0 \cdot 3 \cdot 6$
- 増三和音: $0 \cdot 4 \cdot 8$
- サス 4 和音: $0 \cdot 5 \cdot 7$
- サス 2 和音: $0 \cdot 2 \cdot 7$
- ドミナントセブンス: $0 \cdot 4 \cdot 7 \cdot 10$
- メジャーセブンス: $0 \cdot 4 \cdot 7 \cdot 11$
- マイナーセブンス: $0 \cdot 3 \cdot 7 \cdot 10$
動作モードとコードの特徴
フレキシブルな動作モード
Waveloop は主にオフラインで動作し、CQT(常対周波数分解)を事前計算します。しかし、Fable の機能により**「ライブマイクモード」**も可能になっています:
- 効果: ウクレレコードを非常に迅速かつ信頼性高く特定できます。
コードの密度と深遠さ
現在開発から約 1 週間経過しており、コードを眺めた結果、以下の特徴が浮かび上がりました:
- 「密度が高く凝縮されている」: FAANG 系で昇進しようとするエンジニアが書くような平明なコードではありません。
- テリー・デイビス氏のような深遠さ: 自室で単独開発したかのような、意図を高密度に記録した「ロックファイル」的な雰囲気があります。
技術的かつ文学的なコメント
ファイル上部のコメントは、コードの内容を明快に説明しつつ、意図を高情報密度で記述しています:
ビジュアライザはピッチクラスホイールです。角度 = fract(log2(f / 440) なので、各音符のオクターブ分が同じスポークにマッピングされます...
- 技術性: アルファプリマルチプライプや Fundamental Frequency などの専門用語を気安く使用。
- 文学性: 「音楽的ピッチクラスと時計の刻印とのアナロジー」を描出。「ノイズは滲み残る」「物質が縁から飛び出す」といった表現で、Fable が意図するものを緊密かつ鮮明に捉えます。
堅牢なコード検知関数
以下は非常に堅牢であり、少ない行数で実装されたコード検知関数です:
const NOTE_NAMES = ['A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#']; const QUALITIES = [ { name: '', ivs: [0, 4, 7] }, { name: 'm', ivs: [0, 3, 7] }, { name: 'dim', ivs: [0, 3, 6] }, { name: 'aug', ivs: [0, 4, 8] }, { name: 'sus4', ivs: [0, 5, 7] }, { name: 'sus2', ivs: [0, 2, 7] }, { name: '7', ivs: [0, 4, 7, 10] }, { name: 'maj7', ivs: [0, 4, 7, 11] }, { name: 'm7', ivs: [0, 3, 7, 10] }, ]; function detectChord() { let total = 0; for (let i = 0; i < 12; i++) total += chroma[i]; chromaAgc = Math.max(chromaAgc * 0.995, total, 1e-6); if (total < 0.15 * chromaAgc || chromaAgc < 1e-3) return null; const c = new Array(12); for (let i = 0; i < 12; i++) c[i] = chroma[i] / total; let best = null, bestScore = 0; for (let root = 0; root < 12; root++) { for (const q of QUALITIES) { let inS = 0; for (let k = 0; k < q.ivs.length; k++) { inS += c[(root + q.ivs[k]) % 12] * (k === 0 ? 1.15 : 1); } const score = inS / Math.pow(q.ivs.length, 0.55); if (score > bestScore) { bestScore = score; best = { root, q }; } } } if (!best) return null; let frac = 0; for (const iv of best.q.ivs) frac += c[(best.root + iv) % 12]; if (frac < 0.5) return null; // 和音音以外のエネルギーが多すぎます return { name: NOTE_NAMES[best.root] + best.q.name, root: best.root, pcs: best.q.ivs.map((iv) => (best.root + iv) % 12), }; }
マニムによる解説動画の制作過程
Fable に解説動画の作成を依頼し、以下のプロセスで改善を重ねました。
1. 初期プロンプト
最初の指示は以下のようなものでした:
「とにかくやろう。Waveloop の背後にある数学的原理を説明するマニム(Manim)ベースのビデオを作りましょう。「音楽理論からの第一原理」から始めて、FFT や CQT、円形スタックヒストグラム、oklch などへと段階的に発展させます。TTS プラグインを入れても良いでしょう。」
結果は**「熱いゴミ(hot garbage)」**でした。
2. 改善のためのフィードバック
以下の変更指示を与えてから、質が劇的に向上しました:
- 音質の改善:
の TTS サーバーで適切な声質を使用するよう指示。toebeans - ノイズ除去: ナレーションを断ち切る大きなノイズを排除するよう指示。
- 視覚と音声の同期: スクリーン上のビジュアルに一致する音を多用するよう指示。
- 内容の深掘り: 初歩的な部分を短くし、高度な数学の詳細に掘り下げるよう指示。
- 対話的なトーン: 友人との会話や
のような動画を見ている感覚にするよう指示。3blue1brown - 発見型学習: 事実を詰め込むのではなく、視聴者が自分で発見したように感じさせるよう指示。
- テキストの削減: 映像内のテキストを大幅に削減し、示唆的なビジュアルで補うよう指示。
3. 後処理による最終調整
さらに以下のリクエストを追加:
「大幅に良くなりましたね。数学式には適切な Typesetting を使用し、Qwen TTS で VoiceDesign サンプルを一つ生成して条件付けすることで話者の声を統一させ、図同士が重ならないようにしてください。」
これにより、ほぼ完璧なビデオが生成されました。完璧ではありませんでしたが、初めて見た時点で少なくとも10 分間私の注意を引き付けるには十分でした。
免責事項: 図面のための SVG は Claude を使って生成しましたが、本文のすべては私の手で記述したものです。