Overview
概要
2D物理演算のMatter.jsと音合成のTone.jsを組み合わせた『触れる音の実験室』です。中核は、落下するボールが障害物に当たるたびに音階を鳴らす『音のピタゴラ装置(マーブルマシン)』。衝突から音への対応をスケール量子化で設計しているため、障害物をどこに置いても音楽的に破綻しません。障害物を自由配置できるサンドボックスと、構成をURL1本で共有する仕組み、Matter.js/Tone.js単体の基礎デモも備えます。音源ファイルは使わず、全音色をブラウザ内で生成します。
How to use
遊び方・使い方
マーブルマシンではプリセット(階段・ピンボール・鉄琴坂)を選ぶかサンドボックスで障害物(peg・bar・bell等)を配置し、スポナーからボールを落として音を鳴らします。障害物は種類ごとに音色が異なり、選んだスケールに沿って音程が量子化されるので、自由に組んでも心地よく響きます。組んだ構成はURLに圧縮エンコードされ、そのままリンクで共有可能。Matter.js/Tone.jsの基礎デモタブで、制約・複合ボディやシンセ・エフェクト・シーケンサーも試せます。
Tech stack
技術スタック
TypeScriptNext.js 16React 19Matter.jsTone.jslz-stringTailwind CSS v4
matter-js 0.20とtone 15、共有用にlz-stringを利用。Tone.startはユーザー操作起点(SoundGate)で初期化し、低スペック端末(hardwareConcurrency<=4)ではボール数上限を下げます。OG画像はImageResponseで生成、JSON-LDはWebApplication。
Highlights
工夫した点
- 衝突はcollisionStartで相対速度が閾値以上のときのみ発音し、同一障害物は60ms以内の再発音を抑制(チャタリング防止)。同時最大12ボイスで、障害物タイプごとにPluck/Metal/Membrane/FMなどシンセを割り当て
- 各障害物のnoteIndexを選択スケール(五音・長調・短調・琉球)に量子化し、ベロシティは相対速度から正規化。マスターはLimiterとReverbを通して音の破綻を防止
- 構成JSONはlz-stringで圧縮しlocation.hashへ格納(基準解像度で正規化し障害物60個でも数百文字)。描画はMatter.Renderを使わず自前Canvas 2D、物理は固定タイムステップの自前ループ
To improve
改善したい点
- 障害物の種類・音色プリセットや、スケール・音域のバリエーションを増やしたい
- 多数のボール・障害物同時発音時の負荷と発音優先度の調整に伸びしろ
- サンドボックスの編集操作(スナップ・整列)の使い勝手に課題
What's next
今後の展望
- 録音・書き出しや、作った装置のギャラリー共有
- 小節同期(テンポグリッド)による楽曲的な組み立て
- MIDI出力や外部音源との連携
