Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
pulp::gpu_audio::GpuAudioTransport Class Reference

Fixed-latency real-time transport between the audio thread and a non-RT worker that runs a GpuAudioNode. More...

#include <gpu_audio_transport.hpp>

Classes

struct  Config
struct  Stats
struct  DeliverySnapshot
 Selected output for prepared process() calls, not worker completions or GPU admissions. More...

Public Member Functions

 GpuAudioTransport ()
 ~GpuAudioTransport ()
 GpuAudioTransport (const GpuAudioTransport &)=delete
GpuAudioTransport & operator= (const GpuAudioTransport &)=delete
bool prepare (GpuAudioNode *node, const Config &config)
 Non-RT.
void release () noexcept
bool is_prepared () const noexcept
uint32_t latency_samples () const noexcept
void process (const audio::BufferView< const float > &input, audio::BufferView< float > &output, uint32_t n) noexcept
 Real-time-safe.
void process_offline (const audio::BufferView< const float > &input, audio::BufferView< float > &output, uint32_t n) noexcept
 Offline / faster-than-real-time render path.
void pump (uint32_t max_blocks=0) noexcept
 Non-RT worker step: drain ready input blocks, run the node, fill output.
Stats stats () const noexcept
GpuAudioStatus status_snapshot () const noexcept
 Allocation-free host/UI snapshot with stable, versioned field semantics.
DeliverySnapshot delivery_snapshot () const noexcept
 Allocation-free independent atomic loads: approximate while process() runs, exact once its caller has stopped.
GpuAudioCapabilityReport capability_report () const noexcept
 Host/UI-only snapshot of the prepared integration path.

Friends

bool configure_gpu_audio_transport_trial_observer (GpuAudioTransport &, void *, TrialDeliveryFn) noexcept

Detailed Description

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.

Constructor & Destructor Documentation

◆ 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

Member Function Documentation

◆ capability_report()

GpuAudioCapabilityReport pulp::gpu_audio::GpuAudioTransport::capability_report ( ) const
noexcept

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=()

GpuAudioTransport & pulp::gpu_audio::GpuAudioTransport::operator= ( const GpuAudioTransport & )
delete

◆ 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()

void pulp::gpu_audio::GpuAudioTransport::process ( const audio::BufferView< const float > & input,
audio::BufferView< float > & output,
uint32_t n )
noexcept

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()

void pulp::gpu_audio::GpuAudioTransport::process_offline ( const audio::BufferView< const float > & input,
audio::BufferView< float > & output,
uint32_t n )
noexcept

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: