Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
buffered_content_source.hpp File Reference

A ring-backed source for content produced ahead of the playhead, with starvation counted against what the content declared rather than against what its producer conceded. More...

#include <algorithm>
#include <atomic>
#include <cstdint>
#include <functional>
#include <thread>
#include <utility>
#include <pulp/audio/buffer.hpp>
#include <pulp/audio/streaming_sample_source.hpp>
#include <pulp/timeline/production_mode.hpp>

Go to the source code of this file.

Classes

struct  pulp::playback::BufferedContentSourceConfig
class  pulp::playback::BufferedContentSource
struct  pulp::playback::BufferedContentSource::Stats

Namespaces

namespace  pulp
namespace  pulp::playback

Typedefs

using pulp::playback::BufferedContentEpoch = std::uint64_t
 Identifies one continuous production interval.
using pulp::playback::BufferedContentProducer
 Caller-supplied producer of buffered content.

Detailed Description

A ring-backed source for content produced ahead of the playhead, with starvation counted against what the content declared rather than against what its producer conceded.

This is the buffering half of timeline::ProductionMode::Buffered and nothing else: it owns a ring, a producer callback, and counters. It does not schedule, does not follow a transport, and does not know what a producer computes. Pulp supplies timing and buffering on the audio side of Producer; everything on the other side of that call belongs to whoever wrote the producer, including any dependency it needs. Pulp ships no inference runtime, no model weights, and no producer that performs inference.

The ring, the RT pull contract, the background-refill pump, and the cooperative stop token are audio::StreamingSampleSource's, reused rather than restated. What this adds is the declaration it is prepared against, an honest starvation count against the declaration, and repositioning that stays honest under concurrency: a seek or loop wrap begins a strictly newer production epoch, any producer call still in flight is stopped within one chunk, and frames it produced for the superseded epoch are discarded before they can reach the new ring. The underlying stream's underrun count describes ring delivery; it does not carry the production declaration or distinguish content that permanently missed its deadline.

Thread model:

  • prepare()/release() — control thread, allocates.
  • seek()/loop_wrap() — control thread, reallocates. No pull() may be in flight; an in-flight producer call is tolerated and stopped within one chunk.
  • cancel_production() — control thread, waits at most one chunk.
  • pull() — audio thread, RT-safe after prepare: allocation-free, lock-free, wait-free, zero-fills whatever the producer did not supply.
  • pump_background() — background or host thread. The producer runs here and may allocate, lock, block, and decode.