ワープとテンポ同期
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
└ このマップにワープしたクリップは、各区間に合わせて伸縮するグリッドはクリップがワープする 対象 なので、テンポが音楽的な位置を秒へどう変換するかを見ておくと理解が進みます。下のテンポをドラッグすると、固定した秒の定規に対して小節が詰まったり広がったりします。クリップが追従するのは、まさにこの対応関係です。
3 つのワープモード
すべてのオーディオクリップは ワープモード を持ち、グリッドに どう(あるいは追従するかどうか)を決めます。
off / repitch / tempo-sync の違い
- off — 伸縮なし。クリップは元の速度と音程のまま、プロジェクトのテンポを無視して再生します。曲げたくないワンショットや効果音に使います。
- repitch — テープの速度を変えるような挙動。テンポに合わせてクリップを速く / 遅くし、音程も一緒に動きます。速ければ高く、遅ければ低くなります。シンプルで CPU が軽く、あの懐かしいバリスピードの質感が 欲しい ときに音楽的に有効です。
- tempo-sync — 元の音程を保ったまま テンポに追従。タイミングがグリッドに合うようクリップを時間伸縮しつつ、フェーズボコーダが音程を一定に保ちます。ボーカルやメロディックなループなど、ノートが音程を保たねばならないものに使います。
| モード | タイミングがテンポに追従? | 音程は同じまま? | 主な用途 |
|---|---|---|---|
| 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 を往復します。