Skip to content

テンポと BPM

テンポは音楽の感じる速さで、BPM(beats per minute、1 分あたりの拍数)で測ります — 120 BPM は 1 秒に 2 拍です。libsonare はビートを直接数えるのではなく、オンセット強度エンベロープ の周期性から推定します。本ページは MIR の全体像 のタイミングの節を掘り下げます。

オンセットからテンポへ

音楽に安定した拍があれば、そのオンセットエンベロープは周期的です — ピークが等間隔で繰り返されます。テンポ推定はその間隔を測ります。標準的な手段が 2 つあります。

  • 自己相関は、オンセットエンベロープを時間シフトした複製と突き合わせ、各ラグでどれだけ一致するかを測ります。曲線が自分自身とそろうラグが繰り返し周期を示し、その周期は直接 BPM に変換できます。
  • テンポグラムはそれを画像にします — 各時点での候補テンポの強さを示す、時間×テンポの地図です。強い水平の帯は安定したテンポ、ずれていく帯は加速・減速する曲を示します。

もっと単純に言うと、テンポ推定は「山と山の間隔がどれくらいか」を探しています。山が 0.5 秒ごとに来るなら 1 秒に 2 拍、つまり 120 BPM です。実際の曲では山が完全に等間隔ではないため、自己相関やテンポグラムで、もっとも説得力のある間隔を選びます。

DETECTOR · ONSET / BEATIDLE
オンセットとビート — 打点から拍へ

オンセット検出は音の打点をすべて捉え、ビート追跡はそこから手拍子を打つような一定の拍を導き出す。表示を切り替え、再生するとプレイヘッドが到達するたびにマーカーが光る。

検出

オクターブ誤り: テンポ推定の定番の罠

テンポ推定は「本当の」テンポの半分や 2 倍に着地することで有名です — 75 BPM が 150 と報告されたり、140 が 70 になったり。これはバグではなく、本当に曖昧なのです。同じグルーヴに合わせて手を叩くリスナーは、ハーフタイムでもダブルタイムでも妥当に叩けますし、周期性は両方を支持します。これらは(ピッチのオクターブになぞらえて)オクターブ誤りと呼ばれます。

実用的な対処: 素材に応じた妥当な BPM 範囲を選び(ポップスなら 70〜180 など)、推定値を正確な真実ではなく、半分/2 倍の相棒の中の 1 候補として扱います — 特にストリームの序盤、十分な音声がたまる前は注意します。

UI に表示する場合は、候補を 1 つだけ断定するより、「120 BPM 付近、または 60 BPM / 240 BPM の可能性」といった扱いが親切です。特にイントロだけ、ドラムなし、ライブ演奏、テンポが揺れる曲では、最初の数秒の値を確定値として使わないでください。

信頼度と安定性

単一の数値は、推定がどれだけ確かかを隠します。きっちり反復するグルーヴの曲は鋭いテンポグラムのピークと高い信頼度を生み、ルバート・アンビエント・まばらな素材は平坦なテンポグラムと低い信頼度を生みます。信頼度の値があるなら、BPM を表示するか、ぼかすか、隠すかの判断に使います。

libsonare がテンポをどう推定するか

BpmAnalyzer は STFT からオンセット強度エンベロープを計算し、そのエンベロープのテンポグラム(TempogramMode/TempogramConfig)と自己相関の解析によってテンポを推定します。支配的な周期を選び、それを BPM へ変換します。

項目内容
探索範囲bpm_min = 30bpm_max = 300
初期値フォールバックの start_bpm = 120
オンセット設定n_fft = 2048hop_length = 512
候補BpmCandidate により、半分/2 倍の候補も後段で扱える

ストリーミングアナライザーは、音声が届くにつれて精緻化する逐次的な BPM を公開するため、序盤の値は暫定として扱うべきです。BeatAnalyzer は個々のビートを置く際にテンポを事前情報として使うので、テンポとビートは独立にではなく同じオンセット情報から計算されます。

関連: オンセット検出, ビートとダウンビート, MIR の全体像, リアルタイムとストリーミング