libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
promeki::SDLAudioClock Class Reference

Clock driven by an SDL audio device's consumption rate. More...

#include <sdlaudioclock.h>

Inheritance diagram for promeki::SDLAudioClock:
Collaboration diagram for promeki::SDLAudioClock:

Classes

struct  Stats
 Runtime counters for the clock's smoothing machinery. More...
 

Public Member Functions

 SDLAudioClock (SDLAudioOutput *output)
 Constructs an SDL audio clock bound to output.
 
int64_t resolutionNs () const override
 
ClockJitter jitter () const override
 
double rateRatio () const override
 
Stats stats () const
 Returns a snapshot of the cumulative runtime counters.
 
void resetStats ()
 Resets all counters in stats to zero.
 

Protected Member Functions

Result< int64_t > raw () const override
 
Error sleepUntilNs (int64_t targetNs) const override
 
Error onPause (bool paused) override
 

Detailed Description

Clock driven by an SDL audio device's consumption rate.

SDLAudioClock derives its time from how many bytes the SDL audio device has consumed since the stream was opened. Video paced through this clock tracks the audio device's actual hardware rate rather than the OS wall clock, keeping A/V sync locked to the device.

Clock domain

The clock registers (or reuses) a per-device ClockDomain at construction. The domain name is "sdl.audio:<deviceName>" when a name is supplied, "sdl.audio" otherwise. The epoch is ClockEpoch::PerStream — two SDL audio clocks are independent time sources, not cross-stream comparable.

Time model

The clock's epoch is the moment the audio stream started (i.e. when totalBytesPushed was 0 and the device had consumed nothing). The current time in nanoseconds is:

consumed = output->totalBytesPushed() - output->queuedBytes()
nowNs = consumed * 1e9 / bytesPerSec
Rate ratio and drift

rateRatio returns the audio device's actual consumption rate divided by the nominal rate the stream was configured for, low-pass filtered over roughly a second. Values above 1.0 mean the device is consuming faster than nominal (clock runs fast); below 1.0 means it is consuming slower. Consumers that resample audio or correct for drift should feed this ratio into their resampler.

Monotonicity

nowNs is strictly monotonic: consecutive reads never produce a decreasing value. SDL's consumed-byte counter advances in chunks and its callback cadence jitters, so the raw phase that a new checkpoint implies can land behind the value interpolation has already driven the clock to. When that happens the algorithm back-dates the wall anchor instead of snapping the reported time backward, preserving monotonicity. A final clamp guards against sub-nanosecond floating-point rounding.

Jitter

The monotonicity guarantee costs a possible early bias: the reported time can lead the true playback position by up to one callback period during transients, until the rate filter converges on the device's actual drain rate. jitter reports a symmetric envelope {-callbackPeriod, callbackPeriod} so consumers that filter clock-derived rate estimates size their window correctly in both directions.

Sleep model

sleepUntilNs computes how many bytes need to drain to reach the target time, sleeps for 90% of the estimated drain duration, then polls the remainder at 250 us granularity.

Ownership

The clock does not own the SDLAudioOutput. The caller must keep the output alive for the clock's lifetime.

Thread Safety
Conditionally thread-safe. nowNs and sleepUntilNs are expected to be driven from a single thread (the consumer that the clock is pacing). Distinct instances may be used concurrently; readers that call stats / jitter from a different thread may see a slightly inconsistent snapshot — see the Stats documentation.

Constructor & Destructor Documentation

◆ SDLAudioClock()

promeki::SDLAudioClock::SDLAudioClock ( SDLAudioOutput output)
explicit

Constructs an SDL audio clock bound to output.

Derives the drain rate (bytes per second of float32 audio) from the output's AudioDesc, adopts the output's per-device ClockDomain, and tracks the output's lifetime via an ObjectBasePtr. The clock's pause mode is ClockPauseMode::PausesRawStops — pausing the clock pauses the SDL device, and the base-class pause accounting leaves the reported time frozen across the pause interval.

Typically constructed by SDLAudioOutput::createClock rather than directly.

Parameters
outputThe SDL audio output to derive time from. Must already be open.

Member Function Documentation

◆ resetStats()

void promeki::SDLAudioClock::resetStats ( )

Resets all counters in stats to zero.

Also resets the internal monitor snapshot so the next periodic report publishes deltas starting from fresh.

◆ stats()

Stats promeki::SDLAudioClock::stats ( ) const
inline

Returns a snapshot of the cumulative runtime counters.

The returned value is a copy; it can be safely held and compared to a later snapshot to derive per- interval deltas. See Stats for per-field semantics.


The documentation for this class was generated from the following file: