Skip to content

リアルタイムエンジン ​

StreamAnalyzer が聴くのに対し、RealtimeEngine は再生する側です。

libsonare のリアルタイム機能のうち、トランスポートと再生を担います。テンポ、クリップのスケジュール、メトロノーム、オートメーション、レーンミキサー、録音、UI 向けのメーター/スコープ情報を扱います。

ライブアナライザーではなく再生エンジンを作るときに使います。アプリに再生ヘッド、クリップ、MIDI、再生中に動くミキサーが必要なら、この層の担当です。API は リアルタイムエンジン を、AudioWorklet ブリッジは リアルタイムとストリーミング を参照してください。

トランスポート: 再生ヘッドとテンポ ​

トランスポートは再生クロックで、再生/停止/シーク、現在位置、ループ点、そして他のすべてが基準にするテンポを持ちます。「5 小節目で」スケジュールされたクリップや「2 拍目の」オートメーション点はトランスポートに対してのみ意味を持つので、トランスポートはエンジン全体が読む共有タイムラインです。ループの折り返し、シーク、停止のあと、エンジンは新しい位置より前にクリップが設定したコントローラー、プログラム、ピッチベンドの値を再送するので、再生は正しい状態で再開します。

エンジンは 3 つの位置を並べて持ちます。前にしか進まないレンダーフレームの数、再生ヘッドのタイムラインサンプル、そして再生ヘッドの音楽的な位置を表す PPQ です。下の図は、停止・テンポ変更・ループの折り返しを通して 3 つの動きを追います。

同じ 8 秒間を 3 つの時計で見る
停止中再生テンポ 120 → 80 BPMループ終端レンダーフレーム0384k飛ばず、停止中も進むタイムラインサンプル0240kループ開始へ折り返すPPQ(4 分音符)048テンポが遅いと拍の間隔が広がる拍048k96k144k192k240k288k336k384kレンダーフレーム(48 kHz)
  • レンダーフレーム
  • タイムラインサンプル
  • PPQ(4 分音符)
48 kHz のエンジンが 1 秒停止したあと、PPQ 0〜8 のループを再生します。2 小節目のテンポは 120 ではなく 80 BPM です。レンダーフレームは停止中もテンポ変更もループの折り返しも区別せずに数え続けます。タイムラインサンプルは停止中は止まり、ループ終端で折り返します。シークしたときも同じように飛びます。PPQ はタイムラインに従うので、テンポ変更のあとは 1 拍がより多くのサンプルにまたがります。

クリップとスケジューリング ​

エンジンが再生するのはクリップ、つまりタイムライン上のスケジュール位置に置かれた音声バッファや MIDI イベント列です。スケジューリングとは、トランスポートに対してクリップがいつ始まり止まるかを決めることで、1 つの連続ストリームではなく多数の断片から再生を組み立てられます。アレンジ、バックトラック、リズムゲームの譜面はこの仕組みで再生されます。

ENGINE · LANE MIXERIDLE
エンジンのレーンミキサー — 再生エンジン内のフェーダーとミュート

3 つの MIDI クリップがリアルタイムエンジンでループします。各トラックはレーンを 1 つ占有し、専用のチャンネルストリップを持ち、レーンの合計はエンジンの True Peak リミッターを載せたマスターストリップへ送られます。フェーダーはストリップのセッターを、ミュートは setSoloMute を呼びます。下の各バンドは各レーンをソロにしてマスターチェーンを通した個別の試聴結果で、操作のたびに renderOffline で描き直されます。

リードのフェーダー
0 dB
ベースのフェーダー
3 dB
ドラムのフェーダー
-8 dB
リードをミュート
ベースをミュート
ドラムをミュート

このデモは同じ考え方の縮図です。複数のレーンが同時に鳴り、ミキサーがまとめ、メーターがその出力を反映します。

メトロノーム ​

メトロノームは、トランスポートのテンポと拍子にロックしたクリックイベントを生成し、モニタリング、録音、演奏の整合に使います。同じトランスポートクロックから導かれるため、クリップやオートメーションと自動的に同期します。

メーター情報: リアルタイムグラフを見る ​

リアルタイムの音声コールバックは、タイミングを壊さずにデバッガで覗けません。代わりにエンジンは、メーターと状態の定期的なスナップショット(テレメトリ)を出力し、UI が通常の(音声でない)スレッドで読みます。音声経路に手を触れずに、レベルメーター、ゴニオメーター(左右の位相関係を表示するステレオスコープ)、トランスポート状態を描けます。

libsonare がエンジンをどうモデル化するか

RealtimeEngine は EngineController と連携してトランスポートを管理し、ClipAudioBuffer ストレージ上で ClipPlayer/ClipSchedule によりクリップをスケジュールし、Metronome(MetronomeConfig → MetronomeEvent)でクリックを生成し、ミキサーグラフ上でオートメーションを再生します。メーターは MeterTelemetryRecord を生む MeterTelemetryTap と、UI が音声スレッド外で読む汎用 Telemetry チャンネル(TelemetryType/TelemetryErrorCode)で公開されます。エンジン全体はリアルタイム安全で、オフライン(バウンス)でも AudioWorklet 内でも、フリーズやキャプチャの経路を含めて同じく動きます。

ホストが待つべき量は、2 つの読み出し値で見積もれます。tailSamples はエンジンの最も長い可聴テールのサンプル数を表す保守的な上限で、graphLatencySamplesQ8 は処理レイテンシを固定小数点の値で表したもので、256 で割るとサンプル数になります(33,280 なら 130 サンプル)。オフラインのバウンスやフリーズの前に、エンジンはレンダリングせずに自分をプライムし、2 回目のバウンスが 1 回目と一致するようにします。手順はオフラインレンダー、バウンス、フリーズを参照してください。

関連: リアルタイムエンジン、リアルタイムとストリーミング、ストリーミング解析、リアルタイム安全性、オートメーションとメーター