Skip to content

ワープとテンポ同期

90 BPM で録ったドラムループを 120 BPM のプロジェクトに置くと、かみ合いません。グリッドのほうが速く進むのに、ループは自分のテンポで鳴り続けます。ワープ は、オーディオクリップをプロジェクトのテンポに合わせて曲げ、すべてをロックさせる機能です。

ひとことで言うと

ワープ = オーディオクリップを時間伸縮し、自分の元テンポではなくプロジェクトのテンポに追従させること。

テンポマップ — プロジェクトのグリッド

ワープを理解する前に、クリップが追従する 対象 が必要です。それがプロジェクトの テンポマップ です。

テンポマップは テンポセグメント のリストです。各セグメントは「タイムラインのこの地点以降、テンポは何 BPM」を表します。曲は単一の一定テンポでも、複数のセグメント — 遅いイントロ、速いバース、最後のリタルダンド — でもかまいません。セグメントは ランプ することもでき、BPM を急に切り替えるのではなく滑らかに変化させられます。

テンポマップと並んで 拍子(4/4、3/4、6/8 …)が、1 小節に何拍入るかを定めます。テンポマップと拍子が合わさって 音楽的なグリッドクリップとトラック で扱ったすべてのクリップ位置が基準とする、小節と拍の定規 — を作ります。

秒       0        2        4        6        8        10
テンポ   │ 90 BPM          │ ランプ 90→120   │ 120 BPM        │
小節     1        2        3        4        5        6
         └ このマップにワープしたクリップは、各区間に合わせて伸縮する

グリッドはクリップがワープする 対象 なので、テンポが音楽的な位置を秒へどう変換するかを見ておくと理解が進みます。下のテンポをドラッグすると、固定した秒の定規に対して小節が詰まったり広がったりします。クリップが追従するのは、まさにこの対応関係です。

TIMING · TEMPO GRIDIDLE
テンポとグリッド — BPM が音楽的な時間を秒へ写す仕組み

上の秒の目盛りは動きません。下の小節・拍のグリッドはテンポから計算されます。BPM をドラッグするとグリッドが動き、速いテンポは同じ 6 秒により多くの小節を詰め込み、遅いテンポは広げます。読み出しは、テンポをエンジンが実際に数える単位へ変換します。1 小節・1 拍、そして PPQ 480(libsonare が MIDI のタイミングに使う分解能)での 1 ティックです。1 小節の拍数を変えると、アクセントの付く強拍の位置が変わります。再生すると選んだテンポのメトロノームが鳴ります — 見えているグリッドが、そのまま聞こえるクリックです。

テンポ
120 BPM
1 小節の拍数

3 つのワープモード

すべてのオーディオクリップは ワープモード を持ち、グリッドに どう(あるいは追従するかどうか)を決めます。

off / repitch / tempo-sync の違い

  • off — 伸縮なし。クリップは元の速度と音程のまま、プロジェクトのテンポを無視して再生します。曲げたくないワンショットや効果音に使います。
  • repitch — テープの速度を変えるような挙動。テンポに合わせてクリップを速く / 遅くし、音程も一緒に動きます。速ければ高く、遅ければ低くなります。シンプルで CPU が軽く、あの懐かしいバリスピードの質感が 欲しい ときに音楽的に有効です。
  • tempo-sync元の音程を保ったまま テンポに追従。タイミングがグリッドに合うようクリップを時間伸縮しつつ、フェーズボコーダが音程を一定に保ちます。ボーカルやメロディックなループなど、ノートが音程を保たねばならないものに使います。
PARAM SWEEP · TIME STRETCHIDLE
タイムストレッチ — 音程はそのまま、長さを変える

タイムストレッチはピッチシフトのちょうど逆で、音程はそのままに、音の長さを変えます。レート(rate)をドラッグするとドラムの打点が広がったり詰まったりして波形がパネルを占める幅も変わりますが、下のスペクトルはほとんど動きません。1.0 より下では遅く長く、1.0 より上では速く短くなります。再生すると、チップマンク効果なしにグルーヴのテンポだけが変わるのが聴けます。

レート
1 ×
モードタイミングがテンポに追従?音程は同じまま?主な用途
offいいえはいワンショット、SFX
repitchはいいいえ(速度に連動)テープ / バリスピードの質感、ドラム
tempo-syncはいはいボーカル、メロディックなループ

ワープアンカー — オーディオをグリッドへ留める

テンポの変化はクリップに どれだけ速く 再生するかを伝えますが、実際の演奏は一様ではありません。ドラマーは前後にゆらし、フレーズはわずかに走ります。ワープアンカー は、オーディオ内の特定の点をタイムライン上の特定の点に留めさせてくれます。

各アンカーはソースオーディオ内の位置をプロジェクトのタイムライン上の位置に結び付けます。ループの頭が 1 小節目に、スネアの一打が 2 拍目にスナップし、アンカー間の伸縮は自動で計算されます。アンカーを十分に置けば、緩い演奏をグリッドへまっすぐにそろえたり、タイトな演奏を意図的にゆらしてグルーヴを出したりできます。

tempo-sync は限界のある本物の時間伸縮

tempo-sync は音程を保ったまま長さを変えるため、内部でフェーズボコーダを使います。これは フェーズボコーダによるストレッチ で説明しているアルゴリズムと同じ系統です。小さな伸縮は透明ですが、非常に大きな伸縮はトランジェントをにじませたり「位相っぽい」質感を加えたりします。ステレオやマルチチャンネルのクリップでは伸縮がチャンネル間で位相ロックされるため、左右のステレオイメージがずれることはありません。repitch にはそうしたアーティファクトはありません(単なるリサンプリングです)が、音程が動きます。2 つのモードは異なるコストをトレードします。

再生とバウンスの一貫性

地味ですが重要な保証があります。クリップは、ライブで試聴していてもファイナルをレンダリングしていても、同じように ワープします。テンポマップ、ワープモード、アンカーはプロジェクトの編集モデルの一部なので、リアルタイム再生とオフラインの バウンス は一致したタイミングと音程を生みます。編集中に聞こえるものが、レンダリングで得られるものです。

libsonare での実装

ワープは Project の編集モデルにあります。クリップのモードは setClipWarpMode(clipId, mode) で設定し、mode は 'off' | 'repitch' | 'tempo-sync' のいずれかです。ワープアンカーはファーストクラスのワープマップです。setWarpMap({ id, name?, anchors }) で各アンカーを { warpSample, sourceSample } として登録し、クリップは setClipWarpRef(clipId, warpRefId) で参照します(removeWarpMap でクリア)。グリッドは setTempoSegments(各 { startPpq, bpm, endBpm? }endBpm がランプを駆動)と setTimeSignatures(各 { startPpq, numerator, denominator })から来ます。tempo-sync では伸縮を StreamingPhaseVocoder が行って音程を保ち、リアルタイム再生とオフライン bounce()両方 で同じ経路を使います。一方 repitch はリサンプリングし、音程を速度に連動させます。ワープモード・アンカー・テンポ・拍子のすべては toJson() / Project.fromJson(json) で JSON を往復します。

関連: Project EditingフェーズボコーダによるストレッチProject Bounce