オンラインメトロノーム(タップテンポ)
サンプル精度のタイミング、調整可能な拍子、アクセント付きの視覚的パルス、耳でBPMを見つけるためのタップテンポボタンを備えた無料のオンラインメトロノームです。
221回閲覧
リズムに合わせてタップしてください — 最低2回のタップが必要です
サンプル精度のタイミングを実現するため、Web Audio API のルックアヘッド・スケジューラー(AudioContext.currentTime)を使用しています — 単純な setInterval ではないため、ページに高い負荷がかかってもずれが生じません。
ほとんどのブラウザ製メトロノームがずれる理由
JavaScriptでメトロノームを作る最も分かりやすい方法はsetInterval(playClick, 60000 / bpm)です。これは数秒間はうまく動きますが、そのうち動かなくなります。setIntervalが保証しているのは、コールバックが要求された遅延時間より早く発火しないということだけで、実際にどれだけ遅く発火する可能性があるかについては何も保証しません。JavaScriptのメインスレッドは、ページが行うあらゆること — DOMの更新、レイアウト計算、ガベージコレクション — と共有されており、そのどれもが保留中のタイマーを数十ミリ秒遅らせる可能性があります。ほとんどのUIコードにとってこれは気づかれることのない問題ですが、メトロノームにとっては致命的です。あるビートで40ミリ秒遅れ、次のビートで10ミリ秒遅れるクリック音は、単に「ずれている」だけでなく耳で分かるほど揺らぎ、それを頼りに練習しているミュージシャンを積極的に誤らせてしまいます。
ミュージシャンがメトロノームに頼るのは、まさに人間の一定時間に対する感覚が、外部の基準なしでは信頼できないからです — これは1815年にJohann Maelzelがぜんまい式のバージョンを特許取得して以来、この装置の存在意義そのものです。それ自体がずれるソフトウェア製メトロノームは、その目的を台無しにしてしまいます。そして解決策は、より賢いタイマーを使うことではありません。requestAnimationFrameを含め、すべてのJSタイマーは同じメインスレッドのボトルネックを共有しているからです。本当の解決策は、JavaScriptに正しい瞬間に音を出すよう求めること自体をやめることです。
先読みスケジューリング: このメトロノームが正確さを保つ仕組み
このツールは、かつてGoogle ChromeのWeb Audioチームに所属していたChris Wilson氏が、広く引用されている記事「A Tale of Two Clocks」で広めたパターンを使用しています。スケジューリングのロジックを音のタイミングから完全に切り離すという考え方です。Web Audio APIのAudioContextは、サンプル精度のクロックを持つ専用のオーディオスレッド上で動作し、それはAudioContext.currentTimeとしてJavaScriptに公開されています。そのクロックから得た未来のタイムスタンプを使ってosc.start(t)を呼び出すと、オーディオエンジンはその瞬間にメインスレッドが何をしていようと関係なく、正確にtの時点で音を再生します — ビートちょうどのタイミングで「目を覚ます」必要は一切なかったのです。
メインスレッドの仕事は帳簿付けだけです。およそ25ミリ秒ごとに、スケジューラーが今後100ミリ秒以内に来るビートがないかを確認し、それぞれについて正確な未来のcurrentTimeを指定してosc.start()を呼び出します。このループはおおよそ時間通りであればよいため、通常のジッターが耳で分かる問題を引き起こすことはありません — 音自体は依然としてサンプル精度でスケジュールされているからです。各クリック音は約30ミリ秒のオシレーターのバーストで、各小節の1拍目は耳で分かるアクセントとして高い音程になり、対応する視覚的なパルスと同期しています。
タップテンポは別の問題を解決します。それは、読み取るための譜面がない音楽のBPMを見つけることです。ビートに合わせてタップすると、このツールはタップ間の間隔を測定し、60000 / averageIntervalMsで変換します。少なくとも2回のタップが必要で、直近のタップの平均を取ることで小さなタイミングの誤差が平滑化されます。2秒を超える間隔があると、それは通常ビートを見失ったことを意味するため、シーケンスがリセットされます。
よくある質問
単純なsetIntervalメトロノームは、なぜ時間の経過とともに不揃いに聞こえるのですか?
setIntervalが約束しているのは、コールバックが要求された遅延より早く発火しないということだけです — メインスレッドがレイアウト計算やガベージコレクション、他のタブの活動で忙しいときには、もっと遅く発火することがあります。こうした小さく不規則な遅延がビートごとに積み重なるため、クリック音はテンポに固定されたままではなく、耳で分かるほどずれていきます。このツールは、JSタイマーが正しい瞬間に発火することに頼る代わりに、実際の音のタイミングをWeb Audio API自身のオーディオスレッドのクロックに委ねることで、この問題を回避しています。
「先読みスケジューリング」とは何で、なぜそれがずれを解消するのですか?
これは、JavaScriptが音を鳴らすべき瞬間にそれを再生しようとすることが決してないパターンです。ループがおよそ25ミリ秒ごとに、今後100ミリ秒以内に来るビートがあるかを確認し、それぞれについてAudioContext.currentTimeに正確なオフセットを加えた値を使い、osc.start(preciseFutureTime)によってオシレーターを事前にスケジュールします。オーディオエンジンは、メインスレッドから独立した専用のスレッド上で、そのオシレーターをサンプル精度で発火させます — つまり、スケジューリングのループは多少いい加減でも、実際のビートは正確なままです。
タップテンポはどのようにBPMを計算しているのですか?
タップテンポボタンをクリックするたびにタイムスタンプが記録されます。2回目のタップ以降、このツールは直前のタップからの間隔を測定し、直近の間隔の短い履歴を保持して、その平均をミリ秒単位の平均間隔で60000を割ることでテンポに変換します。少なくとも2回のタップが必要で、2秒を超える間隔があるとシーケンスがリセットされます。これはほとんどの場合、極端に遅いテンポでタップし続けているのではなく、タップが止まったことを意味するためです。
なぜ各小節の最初のビートだけ音の高さが違うのですか?
これはアクセントであり、機械式・デジタル式を問わずメトロノームの標準的な仕様です。1拍目(ダウンビート)は残りの拍よりも高い周波数で鳴り、異なる色の視覚的パルスと組み合わされます。これにより、3/4拍子や6/8拍子のパターンの中で「1」がどこに来るかを一目で、あるいは耳だけで判断できるようになります。これは特に、そうしなければすべての拍が同じように聞こえてしまう拍子で、小節を正確に数えるうえで重要です。
このメトロノームはどのBPMの範囲をカバーしていますか、またBPMとは何を意味しますか?
BPMはbeats per minute(1分あたりの拍数)の略で、60秒間に何回パルスが発生するかを表します。このツールは30から300までのBPMに対応しており、楽譜で使われるほぼ全ての範囲をカバーしています。Graveの表示はおよそ25-45BPM、歩く速さのAndanteはおよそ76-108BPM、Prestoの楽節は200BPMを超えることもあります。120BPMがデフォルトになっているのは、これが一般的で練習しやすいテンポであり、古典的なModeratoの表示でもあるためです。
関連ツール
問題を報告
オンラインメトロノーム(タップテンポ)
コメント
まだコメントはありません — 最初のコメントを書いてみましょう!