BridgeDevs EN
Journal 技術ノート · VoluBridge

Zero Added Latency

仮想オーディオなのに、バッファを足さない。

VoluBridgeRTは、物理デバイス直結時に元々必要だった時間幅を、 Saf Offset と Render quantum に分割して使います。 条件が成立している限り、VBRTを通したことによる追加レイテンシは 0 samples に近づけられます。

VBRTは物理デバイスの遅延を消すのではなく、ハード直結に対して増える差分遅延を作らないことを狙います。

Direct

SH + BV

VBRT

SH + Osaf + D

where

Osaf = D = BV / 2

Therefore: VBRT = Direct

Definition

Zero Added Latency は「物理遅延ゼロ」ではありません。

DAC、HDMI、モニター内部処理、物理Safetyはそのまま存在します。 ここで主張するのは、VBRTを挟んだことでハード直結より余分に増える timeline距離を 0 samples に近づける、という意味です。

Fixed Target = 0 Saf Offset = D Callback = D = B_V / 2 Missing = 0

Direct Path

ハード直結でも、アプリは「今鳴る音」を今渡しているわけではありません。

CoreAudioで物理デバイスへ直接出力するときも、アプリは出音時刻より少し前にsampleを用意します。 物理デバイスにはSafetyがあり、さらにI/O bufferやRender quantumの単位で音声が処理されるためです。 つまりハード直結とは、アプリが S_H + B_V ぶん先を見越してsampleを渡し、 CoreAudioと物理デバイスがその時間幅の中で安定して出音する経路です。

重要なのは、ハード直結にも元々timeline leadが存在することです。 VBRTのZero Added Latencyは、この既存の時間幅を消す主張ではありません。 VBRTを挟んでも、このDirect pathと同じ合計時間幅に収める、という比較です。

1

App prepares samples

DAW、動画アプリ、ゲームなどが、報告されたLatency / Safetyに従って少し先のsampleを用意します。

2

CoreAudio schedules I/O

CoreAudioがI/O cycleごとにRender callbackを呼び、必要なフレームを物理デバイスへ渡します。

3

Hardware consumes buffer

DAC、HDMI、モニターなどの出力機器が、Safetyとbufferの範囲内でsampleを消費して出音します。

App
samples prepared ahead S_H + B_V
CoreAudio
I/O cycle render callback
Hardware
consume DAC / HDMI / monitor
Sound
now
Hardware Safety Buffer width
output time

アプリが渡しているのは、現在時刻のsampleではなく、物理出力で鳴る予定時刻に間に合わせるための先読みsampleです。

Example Buf = 512, Hardware Safety = 14
T_direct = 14 + 512 = 526 samples

つまりアプリは、約526 samples後に物理出力から鳴る予定の音を先に渡しています。 48kHzなら約10.96msぶんのtimeline leadです。

ハード直結は「遅延がない」のではなく、CoreAudioと物理デバイスが必要とする先読み幅の中で 安定して再生している状態です。VBRTの比較対象は、このDirect pathの先読み幅です。

Direct path lead = Hardware Safety + Buffer width = S_H + B_V VBRTが比較対象にするのは、このハード直結時にすでに存在している先読み幅です。

Core Idea

VBRTはバッファを足しません。すでに存在するバッファを、2つの役割に分けて使います。

一般的な仮想オーディオは、安定化のために追加の待ち時間を持ちやすくなります。 VoluBridgeRTでは、ハード直結時に必要だった時間幅をそのまま使い、 前半をアプリへ報告するSafety、後半を物理Render callback quantumとして扱います。

ここでの D は、物理デバイス側を動かすCallback Sample数です。 たとえば一般的にBufferが32 samplesなら物理デバイスも32 samplesのcallbackで動かしますが、 VBRTでは物理Callbackを16 samplesにし、残りの16 samplesをSaf Offsetとしてアプリへ報告します。 そのSaf Offsetの時間幅の中に Producer → Render の受け渡しを入れる、という考え方です。

Direct
S_H B_V
VBRT
S_H Saf Offset (=D) Callback (=D)

where Saf Offset = D = B_V / 2. Dは物理デバイスのCallback Sample数です。同じ幅をSafetyへ足すことで、 Producer → Renderの受け渡しを追加バッファではなく既存timeline内に収めます。

Traditional FIFO

従来型FIFOは、音切れを避けるために時間を貯めます。

一般的なFIFO型の仮想オーディオ設計では、Producerが書いたsampleを一度キューに貯め、 Render側がその在庫を後から読みます。これはUnderflowを避けるうえでは分かりやすい方法ですが、 安定化のために追加の先行在庫 Q_fifo を持ちやすくなります。

その場合、Direct pathで元々必要だった S_H + B_V に加えて、 FIFO在庫ぶんのtimeline距離が上乗せされます。VoluBridgeRTは、この追加在庫を厚くするのではなく、 既存の時間幅をSaf Offsetと物理Callbackに分割して使います。

Direct

Tdirect = SH + BV

物理デバイス直結で元々必要な先読み幅。

VBRT

Tvbrt = SH + Osaf + D

O_saf = D = B_V / 2 として、Directと同じ合計に揃える。

Traditional FIFO

Tfifo = SH + BV + Qfifo

安定化のためのFIFO在庫が、Directより後ろに追加されやすい。

Direct
S_H B_V
VBRT
S_H Saf Offset (=D) Callback (=D)
FIFO
S_H B_V + Q_fifo

DirectとVBRTは同じ終端に揃います。FIFOはその右側に追加在庫 Q_fifo が伸びるため、差分レイテンシとして見えやすくなります。

Long-run behavior

VBRTは、FIFO在庫が積み上がる形で全体のレイテンシが増え続ける設計ではありません。

FIFO型では、安定化のために持つ在庫量や復帰処理によって、 長時間の再生中に実効的なtimeline距離が増えたように見えることがあります。 VoluBridgeRTは音声データの在庫を厚くして安定化するのではなく、 Producer / Render のtimeline位置を基準に制御します。

そのため正常状態では、FIFO在庫が後ろへ積み上がっていく形で 全体のレイテンシが増え続ける設計ではありません。 この性質は、Zero Added Latencyの根拠そのものではなく、 Direct equivalent timelineを維持する設計からくる補助的な違いです。

Variables

変数定義

記号 名前 意味
S_HHardware Safety物理デバイスが必要とするSafety。
B_VVirtual Bufferアプリ側が前提にする仮想バッファ幅。
DPhysical Callback SamplesVBRTが物理デバイス側を駆動するRender callback sample数。
O_safSaf OffsetDと同じ幅を、アプリへ報告するSafetyへ追加する値。
S_VReported Virtual SafetyVBRTがアプリへ報告するSafety。
FFixed TargetVBRT内部でProducer timelineを何samples後ろから読むか。
T_directDirect timeline leadハード直結時に必要な先読み幅。
T_vbrtVBRT timeline leadVBRT経由時に必要な先読み幅。
D = B_V / 2    O_saf = D    S_V = S_H + O_saf    F = 0 現在の標準設計では、物理Callbackを仮想バッファの半分にし、同じ幅をSaf OffsetとしてReported Safetyへ加えます。

Equation

ハード直結とVBRT経由のtimeline leadは一致します。

Direct

Tdirect = SH + BV

例: S_H = 14, B_V = 32 の場合、 T_direct = 14 + 32 = 46 samples

VBRT

Tvbrt = SV + D

Tvbrt = (SH + Osaf) + D

Tvbrt = SH + 2D

同じ例では D = 16, O_saf = 16, S_V = 14 + 16 = 30。 したがって T_vbrt = 30 + 16 = 46 samples

Identity

Osaf = D = BV / 2

Tvbrt = SH + Osaf + D

Tvbrt = SH + BV = Tdirect

Conclusion

ΔLatency = Tvbrt - Tdirect = 0 samples

これがVoluBridgeRTの「Zero Added Latency」の意味です。

Fixed Target

Fixed Target = 0 は、Producer timeline上の古い位置を余分に読まないという意味です。

Saf Offsetと物理Callbackで必要なsampleが十分早く届く条件を作ったうえで、 VBRT内部ではFixed Targetを0にします。

sourceSample = renderSample - F    F = 0 つまり sourceSample = renderSample。VBRTは古い位置を余分に読まず、Fixed Cursor missing=0を目指します。

Fixed Cursor

target=0 actual=0.000

Copied

copied=full または callback frames。

Missing

missing=0 が成立条件です。

Router

fixed-target 経路で動作。

Diagnostic Proof

診断値では、Real Add Latency と Fixed Cursor を確認します。

Webページ上の主張を単なるコピーにしないため、実際のRT診断値と対応づけます。 見るべきポイントは、Virtual Saf が Physical Saf + D になっていること、 Callback が D であること、そして Fixed Cursor missing=0 です。

[Latency]
Real Add Latency: avg 0.00 / p95 0.00 Sample

[Driver]
IO Buffer: VTarget:Auto  Push:32
           Physical:16  Callback:16
Virtual Lat/Saf: 0/28
Physical Lat/Saf: 20/12

[Sync]
Router: fixed-target
Fixed Cursor: target=0 actual=0.000 copied=full missing=0

Caveat

成立条件を明確にします。

Zero Added Latency は、物理デバイスのLatency、Safety、DAC、HDMI、モニター内部処理が 0になるという意味ではありません。VBRTが主張するのは、ハード直結と比較したときに、 仮想経路として余計なtimeline距離を追加しないという意味です。

  • Fixed Cursor missing=0
  • 出力デバイスが安定している
  • アプリが報告Safetyに従って十分早くsampleを渡す
  • Saf Offset = D、Callback = D の関係が維持されている
  • FAQ

    よくある質問

    物理デバイスの遅延も0になりますか?

    いいえ。物理デバイスのLatency、Safety、DAC、HDMI、モニター内部処理は残ります。0になるのは、VBRTを挟んだことで増える差分です。

    なぜSafetyを増やしているのに遅延が増えないのですか?

    Safetyはアプリへ「早めにsampleを渡してほしい」と伝えるための値です。VBRTではその早出し分を、後段の物理Callbackと噛み合わせます。合計がDirectと同じになるため、差分遅延は増えません。

    すべてのアプリで成立しますか?

    アプリが報告Safetyに従い、必要sampleを十分早く渡す場合に成立します。診断では Fixed Cursor missing=0 を確認します。

    なぜDは仮想バッファの半分なのですか?

    D = B_V / 2 にすると、VBRT経由の時間幅が S_H + D + D になり、Directの S_H + B_V と一致します。この一致がZero Added Latencyの中心です。

    ← Journalの記事一覧へ