Fixed-latency real-time transport between the audio thread and a non-RT worker that runs a GpuAudioNode.
More...
#include <gpu_audio_transport.hpp>
Fixed-latency real-time transport between the audio thread and a non-RT worker that runs a GpuAudioNode.
The audio thread calls process(): it writes the input block into a lock-free ring and reads a block that was produced latency_blocks ago from a second ring — it never waits on, allocates for, or synchronizes with the GPU. A separate non-RT context calls pump() to drain the input ring, run the node, and fill the output ring. Config::run_worker_thread can drive pump() from an internal non-RT worker; exposing pump() directly keeps the scheduling logic deterministically testable and supports an externally owned service worker.
Latency is established by priming the output ring with latency_blocks of silence at prepare(); the host is told latency_samples() for PDC.
◆ GpuAudioTransport() [1/2]
| pulp::gpu_audio::GpuAudioTransport::GpuAudioTransport |
( |
| ) |
|
◆ ~GpuAudioTransport()
| pulp::gpu_audio::GpuAudioTransport::~GpuAudioTransport |
( |
| ) |
|
◆ GpuAudioTransport() [2/2]
| pulp::gpu_audio::GpuAudioTransport::GpuAudioTransport |
( |
const GpuAudioTransport & | | ) |
|
|
delete |
◆ capability_report()
Host/UI-only snapshot of the prepared integration path.
This is allocation-free and does not touch the callback timeline. Provider identity is Unknown when a generic staged node cannot establish it. Like status_snapshot(), it reads a copy taken at prepare() and never the node.
◆ delivery_snapshot()
| DeliverySnapshot pulp::gpu_audio::GpuAudioTransport::delivery_snapshot |
( |
| ) |
const |
|
noexcept |
Allocation-free independent atomic loads: approximate while process() runs, exact once its caller has stopped.
No coherent multi-field instant is promised. Successful prepare() resets counters; release() and a false prepare() result preserve them, although failed preparation leaves the transport unprepared. Preparation/destruction must not race readers.
◆ is_prepared()
| bool pulp::gpu_audio::GpuAudioTransport::is_prepared |
( |
| ) |
const |
|
inlinenoexcept |
◆ latency_samples()
| uint32_t pulp::gpu_audio::GpuAudioTransport::latency_samples |
( |
| ) |
const |
|
inlinenoexcept |
◆ operator=()
◆ prepare()
| bool pulp::gpu_audio::GpuAudioTransport::prepare |
( |
GpuAudioNode * | node, |
|
|
const Config & | config ) |
Non-RT.
node must outlive the transport and already be prepared. The node's descriptor supplies channels/block-size/latency; config only carries transport knobs. Returns false if the descriptor is invalid (zero channels/block, input!=output channels), ring_blocks is too small for the latency, or the miss policy is CpuFallback without both supports_cpu_fallback and a true cpu_fallback_prepared() witness. The witness must describe the allocation-free, latency-aligned fallback built by the node's host-thread preparation. Callback and external pump callers must be stopped before preparation; an already-prepared shared node retains its sequence and fallback history across transport preparation.
◆ process()
Real-time-safe.
Writes n input frames to the worker and reads the latency_blocks-delayed output. n must equal block_size. On a miss (worker not ready) the node's MissPolicy fills output. No allocation, locking, or blocking. Calls to process() and process_offline() share one callback timeline and must never overlap. A rejected view emits silence and advances one zero-input position through the prepared fallback and delay state, preserving the due position of subsequent valid audio.
◆ process_offline()
Offline / faster-than-real-time render path.
NOT real-time-safe — it drives the node SYNCHRONOUSLY on the calling thread (blocking GPU readback is fine here: an offline bounce has no real-time deadline) so the actual node output is captured instead of the async misses that an offline render would otherwise hit (the host calls process faster than the wall-clock-paced worker can keep up). Preserves the SAME fixed latency as process() (the primed output ring), so a host that compensates for latency_samples() stays sample-aligned between realtime playback and an offline bounce. While this is in use the background worker yields (a shared mutex serializes node access); switch back to process() to resume async realtime operation. n must equal block_size. The experimental shared provider is fenced into continuously primed CPU fallback here; a new host preparation is required before it may admit GPU work again. The callback must already be stopped before crossing this non-RT boundary.
◆ pump()
| void pulp::gpu_audio::GpuAudioTransport::pump |
( |
uint32_t | max_blocks = 0 | ) |
|
|
noexcept |
Non-RT worker step: drain ready input blocks, run the node, fill output.
Processes at most max_blocks blocks (0 == as many as are ready).
◆ release()
| void pulp::gpu_audio::GpuAudioTransport::release |
( |
| ) |
|
|
noexcept |
◆ stats()
| Stats pulp::gpu_audio::GpuAudioTransport::stats |
( |
| ) |
const |
|
noexcept |
◆ status_snapshot()
| GpuAudioStatus pulp::gpu_audio::GpuAudioTransport::status_snapshot |
( |
| ) |
const |
|
noexcept |
Allocation-free host/UI snapshot with stable, versioned field semantics.
This is a projection of the transport and capability snapshots; it does not claim that a GPU result met an audio deadline.
Node health is folded in: a fenced or provider-lost node reports Degraded or Unavailable with its first latched recovery reason, sequence, epoch and terminal counts. The serialized worker samples the node after every pump (a realtime node after its service step, a staged node through its own status_snapshot()), and prepare() and the offline fence sample it too. This call reads only the transport's coherent copies of that sample and of the prepared configuration, never the node, so it stays safe from any host or UI thread even while the node is re-prepared or destroyed. It may trail the node by at most one pump.
◆ configure_gpu_audio_transport_trial_observer
| bool configure_gpu_audio_transport_trial_observer |
( |
GpuAudioTransport & | , |
|
|
void * | , |
|
|
TrialDeliveryFn | ) |
|
friend |
The documentation for this class was generated from the following file: