SDVXとbeatmania IIDX INFINITASをWindowsからLinuxへ移した大きな理由の一つは、PipeWireなら低レイテンシの音声出力とOBSへの分岐を同時に実現できると見込んでいたからだった。実際にPipeASIOを導入し、両方のゲームを44.1 kHz、64 samplesで安定動作させられた。

PipeASIOとPipeWire graphが申告する構造レイテンシは約3.92 msである。ただし、この値にはSound Blaster GS3のUSB転送queueが含まれない。SDVXの実行中にALSA runtimeまで観測すると、OSから見える音声出力は平均約16.5 ms、約15.2〜17.6 msの範囲だった。

映像も同じ実行中に調べた。SDVXはDXVKからGamescope、Scrollを経て、Hisenseの4K TVへ119.88 Hzで出力されている。完成したframeのPresentからpanel表示までの見積もりは約19〜25 msになる。音声・映像ともcontroller入力から音や光までを外部測定器で測った値ではないが、一部のbufferだけでなく実際に通る経路を可能な範囲で含めている。

Linuxへ移した成果は、単純な最小値競争だけではなかった。低レイテンシ再生とOBS収録を両立しながら、どこにどれだけqueueがあるかを実行中のgraph、kernel、display pipelineから追えるようになったことだった。

Windowsでは低レイテンシと収録が衝突した

WASAPI exclusiveはWindows Audio Engineを迂回して小さいバッファを使える一方、デバイスを占有する。Microsoftの仕様でも、WASAPI loopback captureはshared modeでのみ利用でき、exclusive modeでは利用できない。そのため、ゲームをexclusive modeで出力しながら、同じ音を普通のOBS desktop audioとして取り込むことはできない。

ASIOも同様にWindows Audio Engineの外側を通る。OBSへ渡すには、オーディオドライバ固有のloopback、仮想ASIO、Voicemeeter、VB-Audio Cableなどを使い、ゲームから物理出力までの途中へ仮想デバイスを挿入する必要がある。

以前のWindowsでのINFINITAS ASIO構成では、VoicemeeterのASIO入力64 samples、仮想入力1024 samples、WDM出力128 samplesを直列に通していた。単純合計だけでも1216 samples、44.1 kHzで約27.57 msになる。

その後にさらに詰めた時期の記憶でも、VB-Audio側は512 samples前後が安定動作の限界だった。512 samplesだけで約11.61 msあり、さらに物理デバイスへ渡す後段のbufferが加わる。ただし、この11.61 msと現在の約16.5 msをそのまま比較することはできない。前者は仮想デバイスの1 bufferだけ、後者はLinux kernelが推定するUSB転送待ちまで含むからだ。

Windows時代の直列構成は、確認できるbufferを足しただけで約27.57 msあり、その後の物理device側は含んでいなかった。一方、現在のLinux音声出力経路はUSB転送待ちを含めて約15.2〜17.6 msだった。厳密に同じ境界の測定ではないが、Windows側に未算入の後段が残るため、以前実際に使っていた収録込み構成より現在のほうが短かった可能性は高い。Windows exclusiveやnative ASIOだけを単独で使えば、Linuxより短い構成もあり得る。しかし、それではOBS収録という同じ機能要件を満たさない。

PipeWireではOBSが再生経路の途中に入らない

LinuxではPipeASIOを使い、WineのASIO出力をPipeWire nodeとして公開した。概念的な接続は次のようになる。

SDVX / INFINITAS
        |
     PipeASIO
        |
        +----> Sound Blaster GS3
        |
        +----> OBS

OBSはゲームと物理出力の間に直列挿入されるのではなく、PipeWire graphから並列に音声を受け取る。OBS内部には録画や同期のためのバッファがあるが、それは録画側の遅延であり、GS3へ出る音を同じ長さだけ遅らせるものではない。

この構造によって、ゲームへは64-sample ASIO bufferを提示したまま、物理出力とOBSの両方へ接続できる。Windowsで仮想オーディオデバイスを挟んでいたときとは、録音機能のためのバッファを再生経路が直列に通らない点が本質的に違う。

64 samplesで安定するまで

両ゲームは44.1 kHzを前提としている。一方、使用しているSound Blaster GS3のALSA nodeは48 kHzで動作するため、PipeWireが44.1 kHzから48 kHzへ変換している。

最終的なPipeASIO設定の要点は次のとおり。

  • 入力0、出力2 channels
  • hardwareへ自動接続
  • fixed buffer sizeを有効化
  • preferred buffer sizeを64 samplesに設定
  • sample rateを44.1 kHzに固定
  • follow_device_clockを無効化
  • PipeASIOのRT priorityを無効化
  • PipeWire graphも64-sample quantumで動作
  • PipeASIOからGS3へ直接接続

INFINITASはASIOデバイスの名称を限定しているため、PipeASIOのCLSIDを保ったまま、Wine registry上でXONAR SOUND CARD(64)として見せる設定も必要だった。

SDVXでは当初PipeASIO 1.5.0を使ったところ、約3秒ごとに一瞬の音飛びが発生し、その瞬間に画面も引っかかった。debug logとPipeWire graphを照合すると、接続先device chainのlatencyを検出するたびにkAsioLatenciesChangedをhostへ通知し、SDVXがPipeASIO driverを再ロードしていた。

この挙動はバッファ不足ではなかった。PipeASIO 1.4.3へ戻すと周期的なlatency通知とdriver再ロードがなくなり、最終的には64 samplesで実際にプレイしても音切れせず安定した。切り替え直後の128-sample動作を繰り返し監視した際には、pw-top上のエラーカウンタは増加せず、process callbackの最大処理時間も約173 usで、2.90 msのdeadlineに対して十分な余裕があった。

graph上の4 msと実行中の16 ms

64 samples、44.1 kHzの1 periodは次の長さになる。

64 / 44100 * 1000 = 1.451 ms

2026年8月30日の64-sample runでは、PipeWireのport latencyは1 quantum + 45 samplesだった。PipeASIO自身の1 quantumを加えると、graphが表現している構造は次のようになる。

内訳samples時間
PipeASIO buffer641.45 ms
PipeWire/device chainの1 quantum641.45 ms
device chainの追加分451.02 ms
graph上の合計173約3.92 ms

一方、GS3のALSA PCM statusを読むと、48 kHzで662〜773 frames、平均720.27 framesのdelayが存在した。

観測値frames @ 48 kHz時間
ALSA/USB delay 最小66213.79 ms
ALSA/USB delay 平均720.2715.01 ms
ALSA/USB delay 最大77316.10 ms

LinuxのUSB Audio driverは、USBへ送信中のbytesとUSB frame counterから再生delayを推定している。kernelのsnd_usb_pcm_delay()が計算しているのは、単なる設定値ではなく、USB endpointへ向かってin-flightになっている音声である。

ゲームがASIO bufferへ音を書いてからの待ちとしてPipeASIOの64 samples、約1.45 msを加えると、現在のOS-observableな片道出力は次の範囲になる。

最小: 13.79 + 1.45 = 15.24 ms
平均: 15.01 + 1.45 = 16.46 ms
最大: 16.10 + 1.45 = 17.55 ms

これはGS3内部のDSP、DAC、アンプ、スピーカーから耳までの音響伝搬を含まない。また、controller入力を受けてからゲームが発音を決めるまでの時間も含まない。約15.2〜17.6 msは、現在OSから観測できる範囲の片道出力レイテンシである。

測定中、PipeASIOとGS3のerror counterは10秒間増加せず、nodeも同じIDのままrunningだった。約16.5 msはxrun中の異常値ではなく、安定動作中のqueueだった。

GamescopeからTVまでの表示遅延

SDVXの映像経路も、音声と同じrunで確認した。

SDVX / DXVK D3D9
  1080×1920 @ 119.97 Hz
        |
Gamescope Wayland backend
  nested refresh 120 Hz
  2160×3840 output
        |
Scroll Wayland compositor
  fullscreen / scale 1.5 / transform 90°
        |
NVIDIA DRM / HDMI
  3840×2160 @ 119.88 Hz
        |
Hisense 43U7Nまたは43E7N相当

DXVKはd3d9.presentInterval=1、Gamescopeのframerate limiterは無効、--immediate-flipsも無効だった。Gamescope内部と物理出力の1 refreshは、どちらも約8.34 msである。

完成したframeがDXVKからPresentされた後の待ちを、各同期境界の位相が一様だと仮定すると次のようになる。

区間位相による範囲平均モデル
DXVK FIFOからGamescope0〜8.34 ms約4.17 ms
GamescopeからScroll/DRM pageflip0〜8.34 ms約4.17 ms
scanout開始から対象画素0〜8.34 ms約4.17 ms
software表示経路0〜約25 ms約12.5 ms

接続中のTVはEDIDの画面寸法、contrast、対応modeから、日本向けの43U7Nまたは43E7Nと判断できる。Hisenseは120/144 Hz入力時のゲームモードProについて、映像処理遅延を約0.83 msと公称している。日本向け仕様にはpixel responseがないが、同じ43型、VA、DLED、4K/144 Hz classの43E7 Proは6 msを公称しているため、panel responseは6 ms級と推定した。

この公称値をsoftware側の平均モデルへ加えると、Presentから画素の変化が収束するまでの目安は約19〜25 msになる。ただし、これは高速度cameraやphotodiodeによる実測ではない。VA panelは暗色遷移が公称値より遅いことがあり、TV側の画質modeによっても変わる。TV本体が測定時にゲームモードProだったかはOS側から確認できないため、0.83 msが現在の入力へ適用されていることも未確認である。

Gamescope surfaceはScroll上でfullscreenだったが、実際にdirect scanoutされているかは確認できなかった。出力にはscale 1.5と90°transformがあり、remote userからDRM plane stateを読めなかったためである。したがって、表示側の値はdirect scanoutを確認した実測値ではなく、現在の同期境界から作ったmodelである。

また、DXVKのd3d9.maxFrameLatencyは固定していない。観測中のGPU使用率はおおむね2〜12%で、GPU飽和による長いqueueは見えなかったが、ゲーム内部で追加1 frameが積まれる可能性は排除できない。その場合はさらに約8.34 ms増える。

設定を詰めれば無限に短くなるわけではない

PipeWireのrealtime priorityやCPUのperformance profileも調べたが、これらは処理落ちを防ぐための余裕には影響しても、音声が通るbufferやUSB転送queueを直接短くするものではなかった。効果が確認できなかった追加のPipeWire RT設定は削除した。

現在はPipeASIOとPipeWireの両方が64 samplesで動き、ゲームからGS3へ直接接続されている。それでも実行時delayの大半はGS3のUSB転送側にあった。sample-rate conversionだけを削っても、約12 msあるUSB/device側の成分は消えない。

別の44.1 kHz native対応かつUSB queueの短いaudio interfaceを使えば、さらに短くできる可能性がある。一方、PipeASIO bufferを64より小さくすることだけでは改善幅が限られる。GS3を使う現在の構成では、64 samplesは安定性とレイテンシの妥当な折衷点だと思う。

Linuxへ移行した意味

Windowsはゲームの動作環境としては当然に近く、Linuxでコナステ音ゲーを動かすまでには多くの問題があった。INFINITASではWineのMedia FoundationとWMA再生を修正し、Gamescopeや画面キャプチャも調べ、ASIO driverの組み込みとゲーム固有registryまで用意した。SDVXではPipeASIO自体のversion差による周期的な再初期化も追うことになった。

それでもLinuxへ移したのは、単にWindowsを避けたかったからではない。PipeWireのgraphなら、低レイテンシ再生、OBS収録、アプリごとの分岐や監視を同じ音声基盤で扱える可能性があったからだ。映像をPipeWireで扱おうとした試行と同じく、ゲームを遊ぶ経路と観測・収録する経路を分離しつつ接続できることに価値を感じていた。

今回、SDVXとINFINITASの両方で64 samplesが安定し、OBSを利用するために大きな仮想bufferを再生経路へ挟む必要もなくなった。以前のWindows直列構成の約27.57 msより、現在のLinux音声経路の約15.2〜17.6 msは短い。一方で、Windows native ASIOの最短構成より常にLinuxが速い、とまでは言えない。

PipeWire graphだけでなく、ALSA、USB、Gamescope、Wayland、DRM、TVまで境界を広げて観測することで、何を測れていて何を測れていないかが明確になった。

苦労してでもLinuxへ移行したことで得たかったのは、低レイテンシと収録の両立だけではなく、その経路を自分で観測し、判断できることだった。