Beatglass API reference

These interfaces describe the current foundation and are provisional. Headers under include/beatglass are library interfaces, not a promise of an installed or stable public API. src/desktop/metadata.hpp is application private. Production headers under lib/ are likewise private and must be indexed here when introduced; documenting them does not install them or make them public. Callers must respect each interface’s ownership and threading rules. The implementation and the issue’s remaining product gates take precedence over aspirational behavior; see the repository README and progress notes.

Audio and capture

Source adapters report typed enumeration and start outcomes and deliver causally ordered notifications to the control owner. A sequence gap or delivery loss invalidates the active epoch. Clock anchors are optional and carry a clock domain and optional uncertainty and latency; absence is not zero. These interfaces require adapter integration and do not implement capture. One process-owned SourceEpochAllocator may serve concurrent control and worker requests; it must outlive those callers and is never called by an audio callback. Issuance does not order worker completion or install stream formats.

enum class beatglass::ChannelLayout

Declared channel arrangement; unknown is the default.

struct beatglass::AudioFormat

Audio format: frames per second, interleaved channel count and layout.

struct beatglass::AudioBlock

Borrowed interleaved normalized float PCM; the sample view is valid only during the call. first_frame counts frames from the epoch start. monotonic_ns records monotonic timing; its exact mapping is source-specific. A discontinuity marks a break in continuity.

enum class beatglass::AudioClockDomain

Identifies the clock used by a live anchor; unspecified must not be compared across sources.

struct beatglass::AudioClockAnchor

A point estimate relating one frame in an epoch to a clock. Absence is represented by an optional anchor, not a zero time.

inline std::optional<std::int64_t> beatglass::frame_to_monotonic_ns(std::optional<AudioClockAnchor> anchor, std::uint64_t epoch, std::uint64_t frame, std::uint32_t rate)

Map an optional anchor; absence is not interpreted as time zero.

inline std::optional<std::int64_t> beatglass::frame_to_monotonic_ns(AudioClockAnchor anchor, std::uint64_t epoch, std::uint64_t frame, std::uint32_t rate)

Map a frame in the same epoch to the source monotonic clock.

Integer arithmetic rounds the offset magnitude toward zero. The anchor is a point estimate and does not compensate for drift or capture latency. This stateless function is safe to call concurrently.

Parameters:
  • anchor – Source frame and monotonic-clock anchor.

  • epoch – Epoch containing the requested frame.

  • frame – Requested frame position within that epoch.

  • rate – Source sample rate in frames per second.

Returns:

Monotonic nanoseconds, or empty on an epoch mismatch, zero rate, or arithmetic overflow.

bool beatglass::reduce_loudest_channel(std::span<const float> input, std::size_t channels, std::span<float> output)

Reduce interleaved float PCM to mono in caller-owned storage.

Selects the channel with greatest block sum-square energy; the lowest index wins ties. This avoids anti-phase cancellation, but switching channels between blocks can produce artifacts. It does not resample or clip. The caller supplies non-overlapping input and output spans that remain valid for the call. Work belongs on an analysis worker, not a capture callback.

Parameters:
  • input – Interleaved frames in source channel order.

  • channels – Positive number of input channels.

  • output – Destination with exactly one element per input frame.

Returns:

False without modifying output for malformed sizes, zero channels, or non-finite input samples; true after copying otherwise.

enum class beatglass::StreamTransition

Result of inspecting a block against the previous accepted block.

class beatglass::StreamContinuity

Consumer-owned continuity state; not thread-safe or capture-callback work.

Each accepted block updates the expected next frame. Invalid input leaves the state unchanged. A format change within an epoch is invalid: the source must create a new epoch. Reset estimators when reacquisition is requested.

StreamTransition observe(const AudioBlock &block) noexcept

Inspect borrowed block metadata and update the expected frame position.

Parameters:

block – Interleaved PCM view valid for this call; it is not retained.

Returns:

The transition, or invalid for malformed geometry or overflow.

void stop(void) noexcept

Forget the active stream; the next accepted block starts acquisition.

template<std::size_t Slots, std::size_t MaxSamples>
class beatglass::AudioQueue

Bounded preallocated single-producer, single-consumer queue. One slot is reserved; the producer must not run concurrently, including shutdown. A rejected block is dropped and the next successful push marks a discontinuity. Atomics must be lock-free.

struct Block

Consumer-owned copy of one block, including sample count and timing.

bool push(const AudioBlock &input) noexcept

Copy a block on the producer thread. Reject invalid, oversized, or full-queue input; count its complete frames as dropped and mark the next accepted block discontinuous.

bool pop(Block &out) noexcept

Copy the next block into consumer-owned storage; return false if empty.

std::uint64_t dropped_frames(void) const noexcept

Return the cumulative number of complete frames counted in rejected blocks.

struct beatglass::pipewire::Sink

Private, provisional PipeWire object identity; serials are server-session scoped.

struct beatglass::pipewire::Discovery

A snapshot or a nonempty diagnostic; an error never carries partial sinks.

class beatglass::pipewire::RegistrySnapshot

Internal registry accumulator. Own and mutate on one control thread only.

void add(std::uint32_t id, const char *type, const char *media_class, const char *serial, const char *name, const char *description)

Accept an addressable Audio/Sink node; properties may be null.

void remove(std::uint32_t id)

Remove a disappeared registry global.

std::vector<Sink> sinks(void) const

Copy the current snapshot on its owning control thread.

Discovery beatglass::pipewire::discover_sinks(std::chrono::milliseconds timeout)

Enumerate sinks on the calling control thread, up to timeout. Success may be empty; errors include connection failures and timeouts. The serial is valid only during the current PipeWire server session. This provisional internal interface is not an installed API.

enum class beatglass::SourceState

Provisional source lifecycle states.

enum class beatglass::SourceError

Stable failure categories; backend diagnostics are supplemental.

struct beatglass::SourceAttempt

Identifies a start attempt within its control owner’s lifetime, not an audio epoch.

struct beatglass::SourceStatus

Source state and optional typed failure and backend diagnostic; read off the audio callback.

struct beatglass::SourceInfo

Provisional source identity, display name and live/seekable capabilities.

enum class beatglass::EnumerationOutcome

Enumeration result. An ok result can have no sources.

struct beatglass::EnumerationResult

Enumeration value; sources are meaningful only for ok and error for failure.

struct beatglass::SourceStartResult

Start request outcome; accepted only means startup was requested.

class beatglass::AudioSource

Provisional source interface owned by one control thread. Consumer receives borrowed PCM and must copy samples needed after the call. Start, enumeration, status and stop are not callback operations; stop quiesces callbacks.

using Consumer = std::function<void(const AudioBlock&)>

Callback receiving a borrowed block; real-time callback restrictions apply.

virtual EnumerationResult enumerate(void) = 0

Enumerate sources, distinguishing an empty list, cancellation and error.

virtual SourceStartResult start(const std::string &id, Consumer consumer) = 0

Request start; return either an attempt or a typed failure, never both.

virtual SourceStatus status(void) const = 0

Read status on the owning control thread.

Internal, provisional Core Audio discovery interface; not installed or stable. All calls run on the owning control thread and may allocate.

std::vector<SourceInfo> beatglass::coreaudio::enumerate_outputs(std::string &error)

Enumerate a point-in-time output-device list. On failure return an empty list and set error; a successful empty list clears error. Unreadable or disappearing devices are omitted.

using beatglass::coreaudio::detail::DeviceListQuery = std::function<int(std::uint32_t&, std::uint32_t*)>

Internal test seam for reading a volatile device list. The callback receives a byte count and either null for a size query or storage of that size. It updates the byte count as Core Audio does and returns zero on success. The callback and buffers are used synchronously on the caller’s control thread.

bool beatglass::coreaudio::detail::read_device_list(const DeviceListQuery &query, std::vector<std::uint32_t> &result, int &status)

Query and read the list, retrying size/read races at most three times. Return false on persistent failure or malformed sizes; no partial data is returned.

enum class beatglass::coreaudio::CallbackEntry

Result of one nonblocking callback gate entry attempt.

class beatglass::coreaudio::CallbackGate

Lock-free gate between the single native callback and its control owner. The callback attempts entry once and never waits; the owner closes the gate, then waits off the audio thread until drained before releasing callback-owned buffers. Closing does not unregister the native callback or guarantee that the operating system stopped invoking it. The gate itself must remain alive until the native callback is destroyed.

CallbackEntry try_enter(void) noexcept

Attempt entry once. Busy means concurrent entry or a race with closure; the caller must report a fault if still active.

void leave(void) noexcept

Leave exactly once after a successful entry.

void close(void) noexcept

Prevent future entries; safe to call repeatedly on the control owner.

bool drained(void) const noexcept

True once closed and all successful entries have left.

void reopen(void) noexcept

Reopen only after the old native callback has been destroyed and no callback can reference the gate.

struct beatglass::coreaudio::CleanupOps

Internal control-thread teardown operations. Each must be idempotent, nonthrowing, and return false if its resource remains live.

bool (*stop_io)(void*)

Stop native I/O.

bool (*destroy_io)(void*)

Destroy the IOProc.

bool (*destroy_aggregate)(void*)

Destroy the aggregate device.

bool (*destroy_tap)(void*)

Destroy the process tap.

bool beatglass::coreaudio::cleanup_in_order(void *context, const CleanupOps &operations)

Run teardown in dependency order, stopping at the first failure. Safe retry depends on each operation retaining its resource state until it succeeds. The callback gate must already be closed and drained.

struct beatglass::coreaudio::CaptureBlock

Provisional, non-installed Core Audio transfer format. One block owns its PCM. Host ticks are in the macOS host clock domain and are valid only when host_time_valid is true; they are not nanoseconds. source_sample_time is the native input timestamp and is meaningful only when source_sample_time_valid is true. first_frame counts frames since this capture epoch began, including whole frames rejected by the FIFO.

class beatglass::coreaudio::NativeTimeline

Producer-owned native sample-time continuity detector. It tracks only the input time supplied by Core Audio, not wall-clock time; no allocation or locking occurs. A timestamp jump, loss of previously valid time, or its return after missing time marks a discontinuity.

bool observe(double sample_time, bool valid, std::uint32_t frames) noexcept

Observe one callback’s first-frame timestamp and complete-frame count. Non-finite timestamps are treated as invalid. Returns whether this callback begins a discontinuity.

class beatglass::coreaudio::CaptureFifo

Private bounded single-producer/single-consumer PCM handoff. The callback is the only producer, the analysis worker is the only consumer, and neither may overlap reset/destruction. The producer copies only and performs no allocation or locks. Rejected whole blocks advance the frame timeline and cause the next accepted block to report discontinuity.

CaptureFifo(std::uint64_t epoch, std::uint32_t sample_rate, std::uint32_t channels) noexcept

Set immutable epoch/format before callbacks start. A new instance is required for each epoch.

bool push(std::span<const float> samples, std::uint64_t host_time, bool host_time_valid, bool discontinuity, double source_sample_time, bool source_sample_time_valid) noexcept

Copy complete interleaved float frames. Returns false on an oversized block, malformed input, full queue or timeline exhaustion; no memory is allocated.

bool pop(CaptureBlock &block) noexcept

Copy the next block into consumer-owned storage, or return false when empty.

std::uint64_t dropped_frames(void) const noexcept

Number of complete frames rejected by the producer (saturates at uint64 maximum).

bool exhausted(void) const noexcept

Return true after frame-position exhaustion; the stream must stop rather than wrap.

enum class beatglass::coreaudio::TapState

Provisional internal state for a selected-output tap. Interrupted means the owner must invalidate published analysis, stop, and create a fresh epoch before restarting.

enum class beatglass::coreaudio::TapFailure

Provisional internal failure categories. Permission denial is used only when Core Audio returns its explicit permission error; silence and successful start do not prove permission state.

struct beatglass::coreaudio::TapStatus

Control-thread status with a supplemental diagnostic and optional failure category.

TapFailure beatglass::coreaudio::classify_osstatus(std::int32_t status)

Classify an actual Core Audio OSStatus for a failed operation. Unknown values remain backend_error; this never infers permission denial from audio samples.

class beatglass::coreaudio::OutputTap

Private selected-output, first-stream tap. The owner serializes start, status, pop, and stop on one non-audio thread. A single Core Audio IOProc copies float PCM into a bounded SPSC FIFO; stop quiesces the IOProc before freeing it. This is not yet the shared AudioSource contract.

OutputTap(void)

Construct stopped.

~OutputTap(void)

Stop and release Core Audio resources; destruction must occur on the control owner.

bool start(const std::string &uid, std::uint64_t epoch)

Start the selected output UID’s first stream without muting it. Caller owns unique nonzero process-session epochs. Returns false on unsupported OS/format, setup failure, or invalid parameters; status gives a diagnostic. System audio permission may be prompted by macOS and a successful start does not prove permission or non-silent data.

TapStatus status(void)

Check device liveness and tap format on the control owner. A change/failure invalidates this stream and returns interrupted; stop and restart with a fresh epoch. Invoke regularly even while not popping.

std::optional<AudioFormat> format(void) const noexcept

Return the current epoch format after successful startup, otherwise empty.

bool pop(CaptureBlock &block)

Copy the next block only while status remains running. The returned block is caller-owned; the consumer must invalidate already-delivered data on interruption.

bool stop(void) noexcept

Attempt to stop and quiesce the callback; safe to call repeatedly. If Core Audio refuses, status becomes error and the still-live callback context is retained rather than freed; destroying the adapter in that state intentionally leaks its native resources.

std::uint64_t dropped_frames(void) const noexcept

Return dropped complete-frame count for the current stream on the control owner.

class beatglass::coreaudio::SourceBackend

Private control-thread backend seam. Implementations may allocate and are never called by the audio IOProc. The caller owns the backend and must stop it before destruction.

virtual EnumerationResult enumerate(void) = 0

Enumerate output sources or return a typed error.

virtual bool start(const std::string &uid, std::uint64_t epoch) = 0

Start the requested output using the coordinator-owned epoch; false leaves a diagnostic in status().

virtual std::optional<AudioFormat> format(void) const = 0

Return the format installed for the current epoch, absent until startup succeeds.

virtual TapStatus status(void) = 0

Poll control-thread health; failure must remain observable until stopped.

virtual bool pop(CaptureBlock &block) = 0

Copy a queued block to caller-owned storage.

struct beatglass::coreaudio::SourceEvent

Ordered control notification, delivered before any data of a newly running epoch. A running event owns its format; invalidations have no epoch or format.

class beatglass::coreaudio::SourceAdapter

Provisional serialized Core Audio source adapter. One owner calls every method on a non-audio control thread. The process-level epoch allocator must outlive this object and be shared across source recreation. Backend IOProc only copies PCM; pump calls the borrowed-block consumer synchronously on the owner. The consumer must not destroy this adapter; reentrant pump, stop, event handling and acknowledgement are rejected. Take the running event and install its format/reset boundary before pumping; after an interruption/error event invalidate analysis and stop/restart with a fresh epoch. This polling interface has no cross-thread notification queue and does not revoke previously delivered results.

SourceAdapter(SourceEpochAllocator &epochs, std::unique_ptr<SourceBackend> backend)

Take exclusive ownership of a backend; allocator remains borrowed.

~SourceAdapter(void)

Stop and quiesce on the owner thread.

EnumerationResult enumerate(void)

Enumerate through the backend; translate a backend exception to an error outcome.

SourceStartResult start(const std::string &id, AudioSource::Consumer consumer)

Start synchronously and return an attempt or typed failure. A backend exception triggers cleanup and an error. An accepted attempt has a pending running event; the consumer must remain safe for callback restrictions.

bool stop(void) noexcept

Invalidate the attempt and attempt to quiesce the backend. False reports an OS stop failure; this provisional adapter is not yet an AudioSource because that shared contract cannot express failed quiescence.

SourceStatus status(void) const

Return the last control-thread status; call take_event or pump regularly to poll backend health.

std::optional<SourceEvent> take_event(void)

Return the next causal event once; subsequent calls poll native health. Event loss by the caller is not recoverable and requires stop/restart.

bool acknowledge_running(SourceAttempt attempt, std::uint64_t sequence) noexcept

Confirm that the running event’s format and reset boundary have been installed. Reject a stale or mismatched attempt/sequence.

bool pump(void)

Deliver at most one borrowed PCM block after the running event was acknowledged. Returns false for no data or an event requiring handling. Unknown or unrepresentable host time and backend or consumer exceptions fail closed rather than publishing untrusted PCM.

std::optional<AudioClockAnchor> latest_anchor(void) const noexcept

Anchor for the most recently delivered block; absent before delivery or after interruption/stop. Uncertainty and latency are unknown.

std::unique_ptr<SourceBackend> beatglass::coreaudio::make_native_backend(void)

Create a native Core Audio backend on macOS. The returned object is owned by the caller and is not a stable or installed API.

enum class beatglass::SourceEventResult

Result of applying a backend notification.

class beatglass::SourceEpochAllocator

Process-session epoch allocator owned by the source coordinator. Construct exactly one allocator per process session and inject that same object into live and offline control/workers. Keep it alive until every caller has stopped and across source recreation. Calls to next() may be concurrent, but this object may use non-lock-free atomics and must never be called from the audio callback. Unique issuance alone does not synchronize audio, format installation or event delivery. Requests for one source still need serialized lifecycle transitions; a later-issued epoch may complete before an earlier request. A new process session needs a distinct session identity or a proven drain before epoch values can be reused.

SourceEpochAllocator(std::uint64_t last_issued) noexcept

Begin after last_issued, normally zero for a new drained session. A restored nonzero value is safe only if it is at least every issued epoch that can remain in flight for this session. Never construct independent allocators for concurrent streams in the same session.

std::optional<std::uint64_t> next(void) noexcept

Return a unique nonzero epoch, or empty on exhaustion without wrapping. Concurrent calls are linearized at issuance; do not infer completion order.

class beatglass::SourceLifecycle

Serial control-thread lifecycle; not thread-safe or callable from audio callbacks. An adapter-owned serial dispatcher must establish causal order before assigning consecutive numbers starting at one for each attempt. A delivery overflow or sequence gap fails closed: the owner must invalidate evidence, quiesce and restart as appropriate. Retain this helper across source recreation or drain all old notifications before replacing it. It does not perform those operations. Epochs are allocated by the process coordinator across object recreation and never reused while old publications can remain in flight. Session identity or a proven drain is required across process restarts.

SourceState state(void) const noexcept

Current control-thread state.

std::optional<std::uint64_t> epoch(void) const noexcept

Current epoch, absent unless running.

std::optional<SourceAttempt> start(void) noexcept

Begin an attempt from stopped or error; generation exhaustion fails.

SourceEventResult notify(SourceAttempt attempt, std::uint64_t sequence, SourceState next, std::optional<std::uint64_t> epoch) noexcept

Apply an ordered transition. Running requires a fresh epoch; other states require no epoch. Old attempts and duplicate numbers are stale. A gap or invalid transition invalidates the epoch and enters error; the owner must clear publication.

void delivery_lost(void) noexcept

Fail closed on a known control-delivery overflow.

void stop(void) noexcept

Invalidate the attempt and epoch; caller separately quiesces callbacks.

enum class beatglass::ByteReadStatus

Byte-read outcome for a worker-owned source.

struct beatglass::ByteReadResult

Read outcome and byte count; only data may have a nonzero count.

enum class beatglass::ByteSeekOrigin

Base for a signed relative seek.

class beatglass::ByteSource

Provisional seekable read-only byte source, confined to one worker. A job may lend the same source to fingerprinting and a decoder sequentially. The owner keeps the source alive until all borrowers finish. Reads may block; no callback, GUI, or concurrent access is permitted. A source used for a cacheable analysis must denote the same immutable snapshot throughout both operations; this interface does not create or secure that snapshot. An opened mutable file and its path are not by themselves immutable evidence.

virtual std::uint64_t size(void) const = 0

Size of the fixed byte sequence; no I/O is implied.

virtual ByteReadResult read_at(std::uint64_t offset, std::span<std::byte> buffer, std::stop_token cancel) = 0

Read from an absolute offset into nonempty caller-owned storage. Cancellation already requested takes precedence over EOF and returns cancelled. Otherwise, at or after size return end; a data result contains 1..buffer.size() bytes and cannot extend beyond size. Interruption of a blocking operation is implementation-dependent. A cancelled/error read has zero bytes, but may have modified the output; discard its contents. No buffer is retained after return. Empty buffers are not passed by ByteCursor.

class beatglass::ByteCursor

Worker-local cursor borrowing a source; it does not extend source lifetime. It validates source responses and advances only after valid data. It is not thread-safe and cannot turn a mutable underlying source into a snapshot.

ByteCursor(ByteSource &source) noexcept

Borrow a source and begin at byte zero.

std::uint64_t position(void) const noexcept

Current byte offset.

bool seek(std::uint64_t offset)

Seek to an absolute byte offset through EOF; reject offsets beyond EOF.

bool seek_relative(std::int64_t displacement, ByteSeekOrigin origin)

Seek by a signed displacement from begin, current position or EOF. Reject underflow, overflow and positions past EOF without changing position.

ByteReadResult read(std::span<std::byte> buffer, std::stop_token cancel)

Read nonempty output, retaining position on cancellation or error. Cancellation already requested takes precedence over empty output and EOF; otherwise empty output is an error, including at EOF. On cancellation or error, the source may have modified output and the caller must discard it. Reject malformed source responses; successful EOF does not advance. Exceptions from the source propagate and leave position unchanged.

class beatglass::FileOpenCancelled : public std::runtime_error

Opening a borrowed source was cancelled.

FileOpenCancelled(void)

Construct a typed cancellation exception.

enum class beatglass::FileReadStatus

Result category for a pull-based file read.

enumerator data

A nonempty block was decoded.

enumerator end

The decoder reached end of file.

enumerator cancelled

Cancellation was observed before or during a borrowed-source read.

struct beatglass::FileReadResult

One read result. The block view borrows the caller’s output buffer.

FileReadStatus status

Result category; block is populated only for data.

AudioBlock block

Interleaved float PCM, valid until the caller reuses its output buffer.

class beatglass::FileReader

Worker-owned, pull-based decoded file source; not thread-safe.

This opens a local file read-only and does not write tags or audio. It does not pace reads or invoke hardware callbacks. All operations may block on decoder/filesystem I/O and must stay off GUI and capture threads. The caller provides an initial epoch unique within its session. A successful seek starts a new epoch; existing borrowed blocks must be discarded by the caller. Borrowed byte sources must remain alive through reader destruction and be confined to the same worker. Snapshot immutability is the caller’s duty.

FileReader(const std::filesystem::path &path, std::uint64_t initial_epoch)

Open a local file for reading.

Parameters:
  • path – File path; the file is not modified.

  • initial_epoch – Caller-owned unique epoch for this session.

Throws:

std::runtime_error for an unreadable file or invalid format.

FileReader(ByteSource &source, std::uint64_t initial_epoch, std::stop_token cancel)

Open a borrowed, seekable byte source synchronously on the worker.

Parameters:
  • source – Source that outlives this reader, including its destructor.

  • initial_epoch – Nonzero process-coordinator-issued epoch for this source.

  • cancel – Checked before and during reads; blocking I/O may not stop promptly.

Throws:

std::invalid_argument for zero epoch before accessing the source; FileOpenCancelled if cancellation is observed while opening; std::runtime_error on source or decoder errors. The source must be an immutable snapshot for cacheable analysis. No source is created, copied, verified or retained beyond the borrow by this class.

~FileReader(void)

Close the decoder. The destructor may block on filesystem work.

FileReader(const FileReader&) = delete

File readers cannot be copied.

FileReader &operator=(const FileReader&) = delete

File readers cannot be copy-assigned.

const FileMetadata &metadata(void) const noexcept

Read-only metadata, borrowed until this reader is destroyed.

FileReadResult read(std::span<float> buffer, std::stop_token cancel)

Pull normalized float frames into caller-owned interleaved storage.

Parameters:
  • buffer – Nonempty storage sized to a whole number of source frames.

  • cancel – Checked before I/O and during borrowed-source reads; blocking I/O may not be interruptible. An already-requested token leaves position unchanged. Mid-I/O cancellation invalidates the borrowed-source reader and may modify the output buffer.

Returns:

Data, end, or cancelled. File replay has no live monotonic anchor; its block’s monotonic_ns is zero and must not be used as one.

Throws:

std::invalid_argument on malformed buffer; std::runtime_error on decoder failure, after which this reader must be discarded.

void seek(std::uint64_t frame)

Legacy path-only seek increments a local epoch; not process-unique. Coordinated callers must use the explicit-epoch overload instead. Seek to a frame and begin a fresh epoch, including when seeking to EOF.

Parameters:

frame – Position from zero through the reported frame count.

Throws:

std::out_of_range for an invalid position; std::overflow_error if the epoch cannot advance; std::logic_error for borrowed sources; std::runtime_error on decoder failure, after which this reader must be discarded.

void seek(std::uint64_t frame, std::uint64_t new_epoch)

Seek with an externally allocated, strictly newer epoch.

Parameters:
  • frame – Position from zero through the reported frame count.

  • new_epoch – Coordinator-issued epoch greater than the current epoch.

Throws:

std::out_of_range for an invalid frame; std::invalid_argument for a reused or decreasing epoch, both before decoder I/O; std::runtime_error on decoder failure, after which this reader must be discarded. Epoch allocation and process-wide uniqueness remain the caller’s responsibility.

bool beatglass::coreaudio::SourceBackend::stop() noexcept

Attempt to quiesce capture. Return false and retain any callback context if the OS refuses to stop it. Call on the control owner, not the audio thread.

std::optional<std::int64_t> beatglass::coreaudio::SourceBackend::host_time_ns(std::uint64_t ticks) const noexcept

Convert valid host ticks to backend monotonic nanoseconds, or return empty on failure or overflow. This is called on the control owner.

AudioSource stop

void beatglass::AudioSource::stop() noexcept

Stop the source and quiesce all callbacks before returning. Call this on the owning control thread, not from a callback. The caller must stop the source before destruction. This manual entry preserves the declaration while working around Hawkmoth’s handling of pure virtual noexcept.

Analysis

Snapshot timelines use an exclusive observed-frame boundary. Beats precede that boundary, and chord segments are nonempty half-open intervals whose end may equal it. Producers using the former inclusive boundary must adjust.

enum class beatglass::TrackingState

Provisional tracking states; transition rules are not yet implemented here.

struct beatglass::EventTime

Sample-frame position within an epoch.

struct beatglass::Candidate

Label and uncalibrated algorithm strength; the score is not a probability.

struct beatglass::Beat

Beat event position and strength.

struct beatglass::ChordSegment

Chord candidate over the nonempty half-open interval [start, end), within one epoch.

struct beatglass::Snapshot

Value snapshot of provisional analysis results. observed_through is the exclusive audio-frame boundary: observed frames are [0, observed_through), beats precede it, and chord ends may equal it. publication_monotonic_ns is publication time, and analysis_delay_frames records delay in frames. Empty candidates and absent BPM express missing results. No synchronization or history bounds are imposed by this type.

class beatglass::Estimator

Provisional estimator interface. Implementations consume observed samples and reset on epoch changes; thread safety and error behavior are not specified.

virtual void reset(std::uint64_t epoch, AudioFormat format) = 0

Reset for an epoch and audio format.

virtual void process(const AudioBlock &block) = 0

Consume a borrowed audio block.

virtual Snapshot snapshot(void) const = 0

Return a snapshot by value.

class beatglass::TempoEstimator

Provisional worker-owned strategy. Reset discards evidence on a new epoch, format, seek, or gap; process consumes borrowed observed PCM.

virtual void reset(std::uint64_t epoch, AudioFormat format) = 0

Discard prior evidence and prepare for the given epoch and format.

virtual void process(const AudioBlock&) = 0

Consume observed PCM; the borrowed block and samples expire on return.

virtual std::vector<Candidate> candidates(void) const = 0

Return current candidates by value; scores are uncalibrated strengths.

virtual std::vector<Beat> take_beats(void) = 0

Take the beat events made available by the implementation. Buffering and empty-result semantics remain unspecified.

class beatglass::KeyEstimator

Provisional worker-owned key strategy with the same reset and borrowed PCM rules.

virtual void reset(std::uint64_t epoch, AudioFormat format) = 0

Discard prior evidence and prepare for the given epoch and format.

virtual void process(const AudioBlock&) = 0

Consume observed PCM; the borrowed block and samples expire on return.

virtual std::vector<Candidate> candidates(void) const = 0

Return current candidates by value; scores are uncalibrated strengths.

class beatglass::ChordEstimator

Provisional worker-owned chord strategy with the same reset and borrowed PCM rules.

virtual void reset(std::uint64_t epoch, AudioFormat format) = 0

Discard prior evidence and prepare for the given epoch and format.

virtual void process(const AudioBlock&) = 0

Consume observed PCM; the borrowed block and samples expire on return.

virtual std::vector<ChordSegment> take_segments(void) = 0

Take chord segments made available by the implementation. Buffering and empty-result semantics remain unspecified.

using beatglass::PublishedSnapshot = std::shared_ptr<const Snapshot>

Shared immutable snapshot; the publisher is responsible for bounding timeline lengths before publication.

struct beatglass::PresentationState

Application-facing labels and stale flag.

class beatglass::PresentationAdapter

Provisional presentation interface; GUI types remain local to the application.

virtual PresentationState present(const Snapshot&) const = 0

Convert a borrowed snapshot into presentation labels and stale status. Threading and error behavior depend on the implementation.

struct beatglass::PresentationUpdate

A sequenced presentation update; an empty snapshot invalidates the display.

std::uint64_t revision

Strictly increasing revision assigned by the single producer.

PublishedSnapshot snapshot

Immutable value or empty to clear the current display.

class beatglass::PresentationGate

Presentation-thread filter for delayed or reordered update delivery.

The producer assigns a strictly increasing revision to every snapshot and invalidation in production order, and must stop before revision overflow. It transfers immutable updates to the presentation thread through an appropriate queue. The presentation thread owns this object; no method is thread-safe. Recreating it while old updates are queued requires an external session guard or a queue drain. An invalidation only takes effect after it is delivered; this filter cannot cancel already rendered pixels. Readers holding earlier shared copies must not treat them as current.

bool apply(PresentationUpdate update) noexcept

Apply a newer update. Duplicate or older revisions leave state unchanged.

PublishedSnapshot current(void) const noexcept

Current immutable snapshot, or empty before publication or after clear.

struct beatglass::TempoEstimate

Optional estimated BPM and count of detected beats since acquisition/reset.

class beatglass::TempoTracker

Worker-thread-only aubio baseline for mono float PCM at the configured rate. Gaps, epoch changes, and explicit discontinuities discard partial windows and restart acquisition. No thread synchronization is provided.

TempoTracker(std::uint32_t sample_rate)

Create a tracker; zero rate throws std::invalid_argument and aubio initialization failure throws std::runtime_error.

void process(std::span<const float> samples, std::uint64_t epoch, std::uint64_t first_frame, bool discontinuity)

Process samples at the given epoch and first frame. Frame position overflow throws std::overflow_error; reset failure throws std::runtime_error.

TempoEstimate estimate(void) const

Return the current estimate by value; BPM can be absent while acquiring.

struct beatglass::CausalTempoState

Owned, provisional state of one causal tempo acquisition.

std::uint64_t epoch

Source epoch of the most recently accepted block.

std::uint64_t observed_through

Exclusive end of all accepted input, including buffered partial hops.

std::uint64_t analyzed_through

Exclusive end of complete hops fed to aubio in this epoch.

std::optional<float> bpm

Positive aubio BPM while tracking, otherwise absent.

std::uint64_t beats

Detected beats in the current acquisition, not timestamped events.

TrackingState state

Current signal and acquisition state.

struct beatglass::CausalMonoHop

Borrowed mono hop, valid only during its synchronous worker callback.

std::uint64_t epoch

Epoch and first frame of this hop.

std::uint32_t sample_rate

Sample rate in frames per second.

bool reset

True when downstream evidence must be reset before consuming this hop.

std::span<const float> samples

Borrowed mono samples; never retain this view.

class beatglass::CausalTempoReplay

Provisional worker-owned incremental tempo engine shared by file and live callers. The caller serializes access; this class allocates and runs DSP, so it must never run on a capture callback or GUI thread. It consumes borrowed PCM synchronously and stores only owned, bounded partial-hop data. It does not publish UI state, own a source, pace input, or perform cancellation. Gaps, explicit discontinuities and epoch changes discard buffered samples and reacquire; old epochs, overlapping blocks and same-epoch format changes are rejected and fail the engine closed. Epochs are coordinator-issued. An incomplete hop remains buffered and is not analyzed, including at end of a stream.

using HopObserver = std::function<void(const CausalMonoHop&, TrackingState)>

Called synchronously after each complete mono hop. The block and samples are borrowed until return; reset marks a new acquisition or resume. The state is the tempo lifecycle after that hop. The observer is not retained and must not reenter or destroy the engine. A nested process call is rejected and fails the outer operation even if its exception is caught. Destroying the engine in a callback remains invalid. No clock anchor is implied.

CausalTempoReplay(void)

Construct an inactive engine; the first valid block starts acquisition.

~CausalTempoReplay(void)

Release estimator state after worker calls have stopped.

CausalTempoState process(const AudioBlock &block, const HopObserver &observer)

Consume one observed block; samples are borrowed for this call only.

Parameters:
  • block – Nonempty, finite interleaved PCM with a valid epoch and format.

  • observer – Optional synchronous worker callback for complete mono hops.

Returns:

An owned state; observed and analyzed positions are exclusive.

Throws:

std::exception for malformed PCM, continuity or estimator errors. After any exception the engine is failed and must be discarded.

CausalTempoState state(void) const noexcept

Return the most recent state by value, initially stopped.

struct beatglass::CausalMusicBeat

One aubio beat position emitted after the exclusive observed boundary passes it.

std::uint64_t epoch

Coordinator-issued epoch and event frame.

std::uint64_t observed_through

Exclusive input frame observed when the beat was emitted.

std::uint32_t sample_rate

Sample rate of this epoch, for converting frame positions to time.

std::optional<float> strength

Beat strength, absent when the estimator does not provide one.

struct beatglass::CausalTonalFrame

One analysis window, not a chord segment; its interval is half-open.

std::uint64_t epoch

Epoch and half-open chord-analysis window.

std::optional<std::uint64_t> rolling_key_from

First frame contributing to the key estimate, when a key is available.

std::optional<std::string> rolling_key

Rolling key and local major/minor chord, if available.

std::optional<float> rolling_key_strength

Uncalibrated strengths, absent when unavailable; not probabilities.

std::uint32_t sample_rate

Sample rate of this epoch, for converting frame positions to time.

struct beatglass::CausalMusicState

Owned experimental tempo and tonal state; strengths are not probabilities.

CausalTempoState tempo

Causal tempo and source boundaries.

std::uint32_t sample_rate

Source sample rate, or zero before a source has been opened.

std::optional<std::string> rolling_key

Rolling key and local major/minor triad, absent when unavailable.

std::optional<std::uint64_t> rolling_key_from

First frame contributing to the current key estimate, if any.

std::optional<std::uint64_t> tonal_from

First frame of the most recent chord window, if any.

std::optional<std::uint64_t> tonal_through

Exclusive end of the most recent tonal window, if any.

std::optional<float> rolling_key_strength

Raw strengths, absent when unavailable; not probabilities.

class beatglass::CausalMusicReplay

Experimental worker-owned composition of real aubio and Essentia trackers. This allocates and runs DSP synchronously and is not thread-safe. Never call it on a capture callback or GUI thread. It borrows PCM only during process, bounds internal windows and does not own or pace a source. Callers must clear retained UI state immediately on source interruption, stop or failure. No chord segments, calibrated confidence, or release-quality accuracy is implied. Serialize Essentia tracker creation across workers until its factory is qualified.

using BeatObserver = std::function<void(const CausalMusicBeat&)>

Called synchronously on the worker; the callback is not retained.

using TonalObserver = std::function<void(const CausalTonalFrame&)>

Called synchronously for each new tonal window; copy values retained after return.

using StateObserver = std::function<void(const CausalMusicState&)>

Called synchronously after a decoded block; copy retained values.

CausalMusicReplay(void)

Construct an inactive engine; Essentia must be available in this build.

~CausalMusicReplay(void)

Destroy after worker calls and callbacks have completed.

CausalMusicState process(const AudioBlock &block, const BeatObserver &observer, const TonalObserver &tonal_observer)

Consume borrowed PCM, emit eligible beats, and return an owned state.

Parameters:
  • block – Source PCM with nonzero coordinator-issued epoch and frame positions.

  • observer – Optional callback for beats; events are not retained.

  • tonal_observer – Optional callback for tonal windows; not retained.

Throws:

std::exception on invalid input, callback or estimator failure; discard the object after an exception and clear any published result. Callbacks must not reenter or destroy this engine.

void interrupt(void) noexcept

Clear all evidence after stop or interruption on the owning worker. The next accepted source must have a strictly newer coordinator epoch. This does not revoke copies already delivered to other threads.

CausalMusicState state(void) const

Return the latest owned state, initially stopped.

class beatglass::MusicReplayCancelled : public std::runtime_error

File replay was cancelled before decoding finished.

MusicReplayCancelled(void)

Construct the cancellation exception.

CausalMusicState beatglass::replay_music_file(const std::filesystem::path &path, std::uint64_t epoch, const CausalMusicReplay::BeatObserver &observer, std::stop_token cancel, const CausalMusicReplay::TonalObserver &tonal_observer, const CausalMusicReplay::StateObserver &state_observer)

Decode and replay a local file with the same causal block engine. This is synchronous worker-thread work and does not modify the input file.

Parameters:
  • path – Local audio file supported by the configured libsndfile build.

  • epoch – Nonzero coordinator-allocated epoch for this opened source.

  • observer – Optional beat callback, invoked synchronously and not retained.

  • cancel – Checked before decoder reads; it cannot interrupt blocking I/O.

  • tonal_observer – Optional synchronous callback for tonal windows.

  • state_observer – Optional synchronous callback after each decoded block.

Returns:

The latest owned state; an incomplete final hop is not analyzed.

Throws:

std::invalid_argument for zero epoch before opening the file; MusicReplayCancelled for cancellation; std::exception for I/O, estimator or callback failure. No cached or shared result is published.

struct beatglass::FileMetadata

Decoded file properties; no reference to the open file is retained.

std::uint32_t sample_rate

Frames per second.

std::uint32_t channels

Number of interleaved channels.

std::uint64_t frames

Number of frames reported by the decoder.

std::string format

Decoder container label.

struct beatglass::TempoResult

Snapshot of preliminary file tempo analysis, owned by the caller.

FileMetadata metadata

Source format and duration.

std::optional<float> bpm

Current uncalibrated estimate, if available.

unsigned int beats

Detected beats in the current acquisition.

TrackingState state

Current lifecycle state.

FileMetadata beatglass::read_metadata(const std::filesystem::path &path)

Read file properties on a worker thread; this may block on filesystem I/O.

Parameters:

path – Local file path; the source file is not modified.

Returns:

A value independent of the decoder’s lifetime.

Throws:

std::runtime_error if the file cannot be opened or has invalid format.

TempoResult beatglass::analyze_file(const std::filesystem::path &path)

Analyze a file incrementally on the caller’s worker thread, without pacing.

Parameters:

path – Local audio file; the source file is not modified.

Returns:

The latest state and uncalibrated tempo estimate.

Throws:

std::exception on decoder, invalid PCM or estimator errors.

using beatglass::ReplayObserver = std::function<void(std::uint64_t, const TempoResult&)>

Observer called synchronously after each fully observed decoded block. The first argument is the exclusive frame position within the file’s epoch; the second is borrowed only for the call. Observers must copy retained data.

TempoResult beatglass::replay_file(const std::filesystem::path &path, const ReplayObserver &observer)

Replay a file causally, faster than real time, on the caller’s worker thread.

Parameters:
  • path – Local audio file; no source tags or content are modified.

  • observer – Optional synchronous progress observer; it is not retained.

Returns:

The final state after all complete decoded blocks.

Throws:

std::exception on decoder, invalid PCM, estimator or observer errors.

struct beatglass::AcquisitionToken

Identifies one acquisition attempt and its source epoch.

std::uint64_t epoch

Epoch whose samples feed the attempt.

std::uint64_t generation

Monotonically increasing attempt identifier.

class beatglass::TrackingMachine

Worker-owned musical tracking lifecycle; not thread-safe.

This class does not classify silence or estimate music: its caller supplies those observations. Tokens prevent results from a prior attempt from reviving state after silence, discontinuity, expiry, stop or failure. The caller must separately clear displayed estimates whenever a transition invalidates evidence. No method allocates, blocks or invokes callbacks.

TrackingState state(void) const noexcept

Current lifecycle state. Initially stopped.

AcquisitionToken token(void) const noexcept
Current token, valid only during an active nonsilent acquisition and
  • until a later transition invalidates it.

bool start(std::uint64_t epoch) noexcept

Start or restart after stop/error on the worker thread.

Parameters:

epoch – Source epoch of the new session.

Returns:

False if already active or generation space is exhausted.

void stop(void) noexcept

End the session; pending results are rejected until a new start.

void fail(void) noexcept

Record a source or estimator error; pending results are rejected.

bool discontinuity(std::uint64_t epoch) noexcept

Invalidate evidence on a gap, reset, format change or source interruption.

Parameters:

epoch – Epoch of the next accepted samples.

Returns:

False if inactive or generation space is exhausted.

bool silence(void) noexcept

Mark silence and invalidate prior estimates once per period.

bool signal(void) noexcept

Signal resumption after silence; other active states remain unchanged.

bool expire(void) noexcept

Expire stale evidence, requiring a fresh acquisition attempt.

bool accept(AcquisitionToken result_token) noexcept

Accept evidence from the current attempt if it is still current.

Parameters:

result_token – Epoch and generation captured when work was started.

Returns:

True if accepted; false for stale tokens or inactive/silent state.

class beatglass::SnapshotPublisher

Worker-owned latest-snapshot publisher with bounded item counts.

One producer calls begin_acquisition/publish; any number of readers may call latest. Methods may allocate and the shared-pointer atomic may lock: this class must not be used by the real-time capture callback. Readers own an immutable shared copy; replacing the latest snapshot does not invalidate copies already held by a reader. Producers provide ordered event histories, including any prior events they intend to retain.

SnapshotPublisher(std::size_t history_limit, std::size_t candidate_limit)

Set maximum retained beats/chords and tempo/key candidates per list. Text fields are limited to 128 bytes. A zero limit is permitted.

void begin_acquisition(AcquisitionToken token) noexcept

Begin an acquisition and clear the latest publication.

Parameters:

token – Current token from the worker-owned tracking machine. Each new acquisition must use its new generation.

void clear(void) noexcept

Invalidate pending publications and clear latest on stop, silence or error.

bool publish(AcquisitionToken token, Snapshot snapshot)

Publish an observed, ordered snapshot on the producer thread.

Parameters:
  • token – Acquisition token captured when this result was produced.

  • snapshot – A value owned by the caller; moved into immutable storage.

Returns:

False for inactive, mismatched or stale tokens/epochs/frames, events outside the exclusive observed boundary, empty chord intervals, unordered events or text over 128 bytes. Beats must be strictly before the boundary; nonempty half-open chords may end at it. Invalid snapshots leave the previous publication unchanged.

Throws:

std::bad_alloc if allocation for the bounded copy fails.

PublishedSnapshot latest(void) const noexcept

Obtain an immutable latest snapshot on any reader thread.

Returns:

Empty before publication, after clear, or immediately after begin_acquisition.

Offline results preserve overlapping local tonal evidence separately from an optional validated track-level key. Missing windows and scores remain unknown; the value type does not itself provide database paging or persistence.

enum class beatglass::OfflineMode

Offline analysis mode, part of cache identity; refined may use future audio.

struct beatglass::OfflineAlgorithmVersion

Named algorithm and version; actual dependency/configuration policy is provisional.

struct beatglass::OfflineEstimate

Owned label with optional uncalibrated strength, never a probability.

struct beatglass::OfflineBeat

Beat frame and its exclusive observed-at-emission boundary within the result epoch.

struct beatglass::OfflineTonalWindow

Local analysis evidence, not a chord segment; windows may overlap. Both the chord window and rolling-key evidence end at end_frame, exclusively. A gap between windows is unknown, including silence; do not extend a label.

struct beatglass::OfflineAnalysis

Owned provisional offline value; no decoder or callback memory is retained. All positions count frames in this result’s nonzero coordinator-issued epoch; sample_rate converts them to time. Zero is invalid, including for persisted results. The epoch is process-session scoped: persistence must rebind to a new nonzero epoch or otherwise distinguish sessions. observed_through is exclusive and may include a final partial hop beyond analyzed_through. Empty lists and absent estimates mean unknown; gaps do not inherit preceding labels. validated_track_key must only be populated by a separately validated track-level estimator; a final rolling window is insufficient. Producers own vectors and strings; synchronize publication and never use on an audio callback. This value does not implement persistence, paging or cache identity: storage must key validated content, mode, algorithm versions and the full configuration (including profile, windows, hop and downmix), bound materialized event counts and offer paging for long files. No stable wire format is implied. Version and configuration identifiers must reflect the actual run; when they cannot be established, do not invent them or reuse a cached result.

struct beatglass::OfflineLimits

Caller-selected maximum counts and bytes per text field; no global policy is implied.

enum class beatglass::OfflineValidation

Structural validation outcome; no musical accuracy or cache identity is established.

OfflineValidation beatglass::validate_offline_analysis(const OfflineAnalysis &result, OfflineLimits limits)

Validate metadata, event bounds/order and caller-selected limits without allocation. Must run off the capture callback. This stateless operation is safe for concurrent calls on immutable inputs. Invalid values do not mutate the input. A valid result is not proof of source identity, calibrated scores or successful persistence. Storage must separately validate identity and publication.

Library jobs

The provisional storage interface distinguishes a cache miss, cancellation, stale input and storage error. Its worker owns the cancellation-versus-commit decision; file verification accepts cooperative cancellation before that decision. The interface and helper do not implement SQLite transactions.

enum class beatglass::JobStatus

Provisional job states; transitions and cancellation behavior are not implemented by this type.

struct beatglass::AnalysisIdentity

Provisional cache identity fields; hash and version semantics are not yet specified.

struct beatglass::JobProgress

Provisional frame counts and job status; synchronization and unknown total semantics are unspecified.

struct beatglass::JobSnapshot

A worker-owned job state and frame progress with an optionally known total.

JobStatus status

Current state; terminal states cannot be changed.

std::uint64_t frames_processed

Number of complete input frames processed.

std::optional<std::uint64_t> total_frames

Expected input frames, or absent if the total is unknown.

class beatglass::JobLifecycle

Serial job lifecycle for one worker; not thread-safe and not a scheduler.

Cancellation requests must be delivered to the worker before cancel() is called. The worker arbitrates completion versus cancellation in order: a terminal transition wins and later operations fail. In a persistence job, the owner may call complete only after the storage transaction commits; this object itself neither commits nor rolls back storage. Progress counts complete frames and never regresses or exceeds a known total.

JobLifecycle(std::optional<std::uint64_t> total) noexcept

Create a queued job with an optional known total, including zero.

JobSnapshot snapshot(void) const noexcept

Copy the current state on the owning worker thread.

bool start(void) noexcept

Transition a queued job to running.

bool progress(std::uint64_t frames) noexcept

Update running progress; reject regression or counts beyond a known total.

bool cancel(void) noexcept

Cancel queued or running work after the worker observes a request.

bool fail(void) noexcept

Fail queued or running work.

bool complete(void) noexcept

Mark a running job complete; a known total must have been fully processed.

struct beatglass::FileVersion

File identity evidence; hash policy and platform-specific version proof remain implementation decisions.

struct beatglass::CachedAnalysis

Cached identity and value snapshot.

enum class beatglass::FindOutcome

Lookup outcomes; a miss and cancellation are not storage errors.

struct beatglass::FindResult

Lookup value: result is present only for hit; diagnostic describes errors.

enum class beatglass::PublishOutcome

Publication outcomes. An indeterminate commit is an error, not committed or cancelled.

struct beatglass::PublishResult

Publication result; diagnostic describes errors including an indeterminate commit.

enum class beatglass::FileVerificationOutcome

Result of checking the same opened input used by analysis against its original evidence.

struct beatglass::FileVerificationResult

Verification result; diagnostic describes an error or inability to verify.

inline std::optional<PublishOutcome> beatglass::verification_failure(FileVerificationOutcome outcome)

Map verification to a terminal publication outcome; a match permits publication to continue. This does not start or commit a transaction; call on the database worker before the commit decision. Cancellation after commit starts is too late.

class beatglass::FileVersionVerifier

Synchronous, worker-invoked revalidation of the opened analysis source. The caller keeps this object and its source evidence alive until publish returns. Its implementation must be safe on the database worker; no decoder or file handle may be accessed concurrently unless its owner permits it. A successful match is limited by the platform’s documented filesystem races.

virtual FileVerificationResult verify(std::stop_token cancel) = 0

Recheck retained pre-analysis evidence; observe cancellation cooperatively. A blocking filesystem call may not be interruptible. Return cancelled if cancellation is observed before verification completes, not stale_input.

enum class beatglass::RecoveryOutcome

Recovery result after reopening storage: committed, absent, or still indeterminate due to error.

struct beatglass::RecoveryResult

Recovery status and optional diagnostic for errors.

class beatglass::AnalysisStore

Worker-owned storage boundary, not a database implementation. Connections and writes belong to a database worker, never the GUI or audio callback. Keys include validated content identity, engine and algorithm versions, configuration and mode. Recheck opened-file identity and version during publication; unreliable or changed evidence returns stale_input and preserves the previous completed result. Stat/hash checks alone cannot close every filesystem race; implementations must document their remaining race. Stage and atomically replace within a transaction. Cancellation observed by the worker before commit begins rolls back and returns cancelled; once commit begins, resolve as committed or error, even if cancellation is later requested. Never mark a job complete before successful commit. If commit outcome is unknown, return an indeterminate error and recover by unique run ID after reopening. This interface does not itself enforce transaction semantics.

virtual FindResult find(const FileVersion&, const AnalysisIdentity&, std::stop_token) = 0

Find a validated cached result, miss, cancellation or error.

virtual PublishResult publish(const FileVersion &before, const CachedAnalysis&, const std::string &run_id, FileVersionVerifier &verifier, std::stop_token) = 0

Stage, invoke verifier on this worker, then publish at the serialized commit point. Pass the token to verification. Changed or unverifiable evidence returns stale_input, observed cancellation returns cancelled, and verification errors return error. run_id must be unique and durable across retries/reopening. The caller retains verifier and source evidence until this call returns.

virtual RecoveryResult recover(const std::string &run_id) = 0

Query a unique run ID after reopening; not_found means no committed run with that ID.

class beatglass::CommitDecision

Worker-local commit decision; neither a transaction nor a cross-thread arbiter. Deliver cancellation to the worker and call begin_commit at its commit point.

bool begin_commit(bool cancellation_requested) noexcept

Choose cancellation if requested before commit; otherwise enter commit. Only the first decision succeeds.

std::optional<PublishOutcome> finish(bool success) noexcept

Resolve a begun commit; later cancellation cannot change the outcome.

bool cancelled(void) const noexcept

Whether cancellation won before commit.

enum class beatglass::library_detail::FingerprintStatus

Outcome of computing provisional file-content evidence.

enumerator ok

All bytes were read and pre/post attributes agreed.

enumerator cancelled

Cancellation was observed while reading.

enumerator changed

File size or modification time changed during the read.

enumerator error

The file could not be read or the digest failed.

struct beatglass::library_detail::FileFingerprint

SHA-256 evidence for the bytes observed by one read, with file attributes around that read. It is not an opened-decoder identity or immunity to concurrent mutation.

FingerprintStatus status

Outcome; only ok permits use of remaining fields.

std::uintmax_t size

Number of bytes hashed.

std::filesystem::file_time_type modified

Filesystem modification time on the implementation’s file clock.

std::string digest

Lowercase SHA-256 hex, prefixed with sha256:.

std::string diagnostic

Diagnostic when the operation fails.

FileFingerprint beatglass::library_detail::fingerprint_file(const std::filesystem::path &path, std::stop_token stop, const std::function<void(std::uintmax_t)> &observer)

Hash a file on the calling worker using a bounded buffer; never writes the file. The observer, if present, runs synchronously after each nonempty chunk and may request stop; cancellation is cooperative and cannot interrupt blocking I/O. Observer and filesystem exceptions derived from std::exception return error with a diagnostic; other exceptions propagate. Input longer than the initial size, a short input, or changed attributes return changed; I/O errors return error. Attributes and digest cannot exclude all replacement, mutation, or ABA races; they do not prove that a separately opened decoder analyzed these bytes.

class beatglass::library_detail::JobExecutor

Provisional single-worker queue; no stable public API. Calls to shutdown and destruction must be serialized on a control thread, never from a job. Jobs must cooperate with stop requests.

using Work = std::function<void(std::stop_token)>

A job invoked on the worker with a cooperative shutdown token.

JobExecutor(std::size_t capacity)

Start one worker; capacity bounds queued jobs, excluding the running job.

~JobExecutor(void)

Request shutdown, discard queued jobs, and join the worker.

bool submit(int priority, Work work)

Queue a nonempty job if space is available. Higher priority runs first, with FIFO for equal priority. Thread-safe until shutdown begins.

void shutdown(void)

Reject and discard queued jobs, request active cancellation, and join. May block until active work returns.

bool beatglass::library_detail::sqlite_length_representable(std::size_t size)

Return whether a byte length fits SQLite’s signed-int binding APIs.

struct beatglass::library_detail::CacheKey

Provisional caller-supplied cache identity. The caller must establish a validated content hash and stable algorithm/configuration versions.

std::string content

Validated content identity.

std::string engine

Engine version.

std::string config

Configuration identity.

std::string mode

Analysis mode.

enum class beatglass::library_detail::Publish

Provisional publication outcome; error may include an indeterminate commit.

enumerator committed

Active result was replaced.

enumerator cancelled

Cancellation was observed before commit.

enumerator stale_input

The caller’s revalidation rejected the input.

enumerator error

A storage operation failed; a failed commit may require recovery by run ID.

class beatglass::library_detail::SqliteCache

Provisional worker-owned SQLite cache. Not thread-safe; construct, use, and destroy on one worker. A file-backed instance holds an exclusive SQLite lock for its lifetime, so other connections fail rather than misclassifying active runs as interrupted. No input files are modified.

SqliteCache(const std::string &path)

Open or migrate a database and recover unfinished runs; throws on errors or unsupported schema.

~SqliteCache(void)

Close the connection.

void begin(const std::string &id, const CacheKey &key)

Insert a uniquely identified running job; throws on SQLite error or duplicate ID.

bool find(const CacheKey &key, std::string &result)

Copy a completed cached blob into result; return false on miss, throw on storage error.

Publish publish(const std::string &id, const CacheKey &key, const std::string &result, std::stop_token stop, const std::function<bool()> &revalidate)

Revalidate and atomically publish. Cancellation before commit rolls back; cancellation after commit begins does not override its outcome. A callback must validate the opened source version; stat/hash checks have filesystem races.

Desktop application internals

class Metadata : public QObject

Application-private Qt metadata bridge. Call inspect on its owning Qt thread. Reads run in the global thread pool; only the latest request result is published, with at most one pending request retained. Destruction suppresses later delivery but does not cancel a running reader.

using Reader = std::function<QString(const QUrl&)>

Injectable reader called on a worker thread; exceptions become status text.

Metadata(QObject *parent, Reader reader)

Create the bridge with an optional QObject parent and worker reader.

void inspect(const QUrl &url)

Request inspection and emit a reading status; a newer request replaces any pending request.

void statusChanged(const QString &status)

Emit progress, result, or error text on the object thread.

class LivePresentation : public QObject

GUI-thread-owned presentation of revisioned immutable live snapshots.

A producer must deliver updates to this object’s thread in accordance with PresentationGate’s revision and lifetime contract. apply() does not queue across threads. A clear removes all displayed estimates; recreating this object requires draining old updates or guarding them with a session ID. Only tracking snapshots expose estimates; all other states clear labels. This provisional adapter does not start capture or expire stale data itself.

LivePresentation(QObject *parent)

Construct on the owning GUI thread; parent, if any, has the same thread.

bool apply(beatglass::PresentationUpdate update)

Apply a newer value or clear. Returns false for an older or duplicate revision.

QString status(void) const

Current tracking state label; initially and after clear, “Stopped”.

QString tempo(void) const

Current BPM, or an em dash if unavailable.

QString key(void) const

First key candidate label, or an em dash if unavailable.

QString chord(void) const

Most recent chord label, or an em dash if unavailable.

void changed(void)

Emitted on the owning thread when a newer update is applied.

struct beatglass::windows::RenderEndpoint

A currently active render endpoint. IDs are opaque UTF-8 Windows endpoint IDs; the name is for display and need not be unique.

struct beatglass::windows::EndpointResult

Result of endpoint discovery. An empty list with no error is valid. An error contains a diagnostic and the list must not be treated as complete.

EndpointResult beatglass::windows::enumerate_render_endpoints(void)

Enumerate active Windows render endpoints and mark the multimedia default. Call from a non-audio thread; this initializes COM on that thread, retains no interfaces, and returns owned values. A concurrent device change can make the snapshot stale. Failures are returned as diagnostics.

struct beatglass::windows::LoopbackPacket

< True on a WASAPI discontinuity, timestamp error or preceding queue drop; downstream must reset and reacquire.

static constexpr unsigned int max_samples

Maximum interleaved sample values in one packet.

std::array<float, max_samples> samples

Owned interleaved float PCM; only the first sample_count values are valid.

std::uint32_t sample_rate

< Number of interleaved sample values, not frames.

std::uint32_t channels

< Frames per second.

std::uint64_t epoch

< Interleaved values per frame.

std::uint64_t first_frame

< Caller-allocated stream epoch, never reused while evidence can remain in flight.

std::uint64_t qpc_100ns

< Epoch-relative count of frames processed by the backend, including queue drops but excluding unknown device gaps.

bool timestamp_valid

< Windows QPC timestamp for the first frame, in 100-nanosecond units, meaningful only when timestamp_valid is true.

bool discontinuity

< False when WASAPI flags a timestamp error; qpc_100ns must then be ignored.

class beatglass::windows::Loopback

Provisional selected-endpoint capture, independent of the shared source contract. Virtual control methods allow deterministic adapter tests; production capture callbacks do not dispatch through this interface.

enum class State

State is published atomically by the capture thread. Interrupted means the stream has stopped and buffered packets must be discarded.

struct Event

< HRESULT on interruption, zero when running.

std::uint64_t sequence

< Running or interrupted transition.

std::uint64_t epoch

< Consecutive number starting at one for each start attempt.

std::int32_t error_code

< Caller-provided epoch for that attempt.

Loopback(void)

Construct a stopped source; the caller owns it.

virtual ~Loopback(void)

Stop and join before releasing buffers. Never destroy on the capture thread.

virtual bool start(const std::string &endpoint_id, std::uint64_t epoch)

Start the opaque UTF-8 render endpoint ID using a caller-allocated, never-reused epoch. Call on the control thread while stopped; errors are observable through state and error_code.

virtual void stop(void)

Stop and join the capture thread. Call on the control thread; queued packets are discarded.

virtual State state(void) const

Read current state from any non-capture thread.

std::int32_t error_code(void) const

Native HRESULT from a failed stream; meaningful only after interruption.

virtual bool pop_event(Event &event)

Read the next ordered running or interrupted transition on the sole control consumer. Start and stop must not run concurrently with this call. The owner must apply running before consuming PCM and clear evidence on interruption. PCM and event queues have no shared ordering; retained or in-flight packets require external invalidation. Startup failure produces interrupted as the first event and maps to an error in the proposed shared lifecycle. Stop discards pending events.

virtual bool pop(LoopbackPacket &packet)

Copy the next packet on one consumer thread. Do not call concurrently with start or stop.

virtual std::uint64_t dropped_frames(void) const

Count frames rejected because the queue was full.

class beatglass::windows::LoopbackSession

Provisional single-control-thread adapter from WASAPI transitions to the reviewed source lifecycle. The owner must retain the process epoch allocator and invalidate callback across source recreation.

LoopbackSession(SourceEpochAllocator &epochs, std::function<void()> invalidate)

Borrow the process epoch allocator and retain an invalidation callback. The callback runs synchronously on the control thread, must not throw, and must clear publication and reject in-flight work. An empty callback prevents start.

LoopbackSession(SourceEpochAllocator &epochs, std::function<void()> invalidate, std::unique_ptr<Loopback> backend)

Test seam: take exclusive ownership of an injected backend. A null backend prevents start. All methods are called on the sole control thread.

bool start(const std::string &endpoint)

Start a selected endpoint with a fresh epoch. True means accepted, not running. Call on the control thread while stopped; stop after an error before retrying.

void poll(void)

Apply pending transitions and synchronously invalidate on interruption, error, ordering failure or queue loss. Queue loss fails the attempt and stops capture, discarding the complete backlog; call stop before a fresh-epoch restart. Call on the control thread.

bool pop(LoopbackPacket &packet)

Apply pending transitions and copy a packet only for the currently running epoch. A discontinuous or untimed packet first triggers invalidation. Any previously returned packet remains subject to the owner’s invalidation token. Call on the control thread.

void stop(void)

Invalidate evidence, join capture, discard queued messages and stop the lifecycle. Call on the control thread.

SourceState state(void) const

Read lifecycle state on the control thread.

class beatglass::windows::LiveTempo

Experimental worker-owned WASAPI-to-aubio tempo path. This is not a UI model and does not estimate key or chords. Every method runs on one analysis/control thread.

LiveTempo(SourceEpochAllocator &epochs)

Borrow the process epoch allocator, which must outlive this object.

bool start(const std::string &endpoint)

Request capture of a selected endpoint. True means requested, not running. Stop before retrying a failed attempt.

bool pump(void)

Drain pending capture, update the real tempo tracker, and clear stale evidence on silence, interruption, loss, format changes or errors. Call regularly on the owning worker. Returns false on a source or analysis error.

std::optional<float> bpm(void) const

Return the latest tempo in BPM, or empty while stopped, silent, stale or acquiring. The caller must not retain a displayed value across invalidation.

std::optional<EventTime> observedThrough(void) const

Exclusive frame boundary and epoch of the latest analyzed packet, or empty after invalidation.

std::uint64_t invalidationGeneration(void) const

Monotonic invalidation generation; changes whenever retained evidence is cleared. Exhaustion stops analysis rather than wrapping.

SourceState state(void) const

Return the source lifecycle state on the owning thread.

void stop(void)

Clear tempo and stop/join capture on the owning thread.

class beatglass::windows::DefaultTempoFollower

Worker-owned default-render-endpoint follower and provisional revisioned tempo producer. All methods run on one worker/control thread; the GUI must transfer and apply updates on its own thread. Call stop and deliver its clear before destroying the follower.

enum class Status

Control status; running does not imply that a BPM has been acquired.

DefaultTempoFollower(SourceEpochAllocator &epochs, std::function<EndpointResult()> discovery, std::function<bool(const std::function<bool()>&)> startGuard)

Borrow a process epoch allocator. An empty discovery function uses Windows discovery. An optional start guard synchronously decides whether to invoke a capture start on this worker; it must not retain the callable.

bool start(void)

Enable default following; the next tick performs discovery. Return false after fatal revision exhaustion.

bool tick(std::chrono::steady_clock::time_point now)

Poll capture and periodically rediscover the multimedia default. now must be monotonic. On a new or lost endpoint, clear old evidence before stopping and restarting with a fresh epoch. False means a fatal failure or revision exhaustion; the owner must stop and clear the GUI using an external session boundary.

std::optional<PresentationUpdate> takeUpdate(void)

Return and remove the newest coalesced update, including clears. Transfer it to the GUI using an ordered/coalescing mechanism that retains clears.

void stop(void)

Disable following, invalidate the current value and stop capture. A later start is required before tick can capture again.

const std::string &endpoint(void) const

Current selected endpoint ID; empty while waiting or recovering.

Status status(void) const

Current worker-owned status; transfer it to the GUI through the owner’s delivery mechanism.

const std::string &diagnostic(void) const

Most recent status diagnostic, empty outside an error.

class beatglass::windows::DjBridge : public QObject

Provisional GUI-thread bridge for the default-output tempo worker. It does not create controls or an overlay.

DjBridge(SourceEpochAllocator &epochs, QObject *parent, std::function<EndpointResult()> discovery)

Construct on the GUI thread with the process-session allocator. The caller retains ownership and must keep it alive until after this bridge is destroyed and its worker has joined. Issuance happens on the worker, never the capture callback. The optional discovery function is a test seam.

void start(void)

Request default-output capture; it starts asynchronously on the owned worker.

void stop(void)

Request stop and a revisioned clear; delivery is asynchronous. A later start cannot bypass that stop even when both are requested before the worker wakes. Capture start is serialized with this request; stop may wait for the short start request, which does not wait for WASAPI startup.

bool active(void) const

Whether capture is requested. Read on the GUI thread.

QString status(void) const

Most recently delivered status. Read on the GUI thread.

void presentationUpdate(beatglass::PresentationUpdate update)

Emitted on the GUI thread with a revisioned snapshot or clear. The receiver must apply it on that thread and handle its own lifetime.

void stateChanged(void)

Emitted on the GUI thread when request or delivered status changes.

class beatglass::windows::OverlayController : public QObject

GUI-thread-only provisional window controller. The shared UI owns both windows and must provide visible unlock/hide controls. The controller never creates overlay content.

OverlayController(QQuickWindow *overlay, QWindow *control, QObject *parent, QSettings *settings)

Configure the overlay as transparent, frameless and always on top. The control window is the escape path and must outlive this controller or trigger automatic unlock. Optional settings are caller-owned, must outlive the controller and are read and written only on the GUI thread. Saved position and opacity are restored; visibility remains caller-controlled and click-through starts disabled.

void setOpacity(qreal opacity)

Set whole-window opacity, clamped to the range zero through one.

qreal opacity(void) const

Return the current whole-window opacity, or one if the overlay no longer exists.

bool setClickThrough(bool enabled)

Enable click-through only while the distinct control window is visible and not minimized; return whether the requested state was applied. Hiding, minimizing, closing or destroying the control window unlocks the overlay.

bool clickThrough(void) const

Return the current click-through state.

void keepOnScreen(void)

Move and resize an overlay into an available screen’s logical-pixel geometry. No action occurs if no screen is available.

bool beginDrag(void)

Begin a GUI-thread drag using the current native cursor and window positions. A GUI timer follows the cursor until button release, hide or explicit end. Returns false when either position is unavailable.

void dragToCursor(void)

Move an active drag to the current native cursor position, including across mixed-DPI monitors.

void endDrag(void)

End a GUI-thread drag.

void clickThroughChanged(bool enabled)

Emitted on the GUI thread when click-through changes, including automatic unlock.

void opacityChanged(qreal opacity)

Emitted on the GUI thread when the controller changes opacity.

protected virtual bool eventFilter(QObject *watched, QEvent *event) override

Unlock if the control window is hidden, minimized or closed.

class beatglass::macos::OverlayNative

Private GUI-thread native-window operations. The implementation never owns the Qt window. A false result means native behavior was not applied.

virtual bool apply(QQuickWindow *window, bool clickThrough) = 0

Configure the native window, including its requested input mode.

std::unique_ptr<OverlayNative> beatglass::macos::makeOverlayNative(void)

Create the AppKit implementation on macOS. Caller owns the result.

class beatglass::macos::OverlayController : public QObject

Provisional GUI-thread-only overlay controller. The caller owns both distinct windows and supplies a separate visible control-window escape path. An optional owned QSettings store records geometry and opacity on the GUI thread; write failures are not currently surfaced, and click-through is never restored. AppKit hints do not guarantee visibility over other applications or fullscreen Spaces.

OverlayController(std::unique_ptr<OverlayNative> native, QObject *parent, std::unique_ptr<QSettings> settings)

Own the native adapter and optional settings store; the Qt parent, if any, owns this controller. All methods run on the GUI thread.

bool attach(QQuickWindow *overlay, QWindow *control)

Attach distinct caller-owned windows. Returns false on invalid arguments or failed native setup.

bool showOverlay(void)

Show without requesting focus; false indicates setup failure.

void hideOverlay(void)

Hide and attempt to unlock the overlay.

void setOpacity(qreal value)

Set whole-window opacity, clamped to [0,1]; ignore non-finite input.

qreal opacity(void) const

Return the current overlay opacity or the default before attachment.

bool setClickThrough(bool enabled)

Apply input transparency only when a separate control window is visible and not minimized. A failed unlock hides the overlay.

bool clickThrough(void) const

True if click-through was successfully requested and remains active.

bool available(void) const

True while attached to valid windows and native setup succeeded.

void keepOnScreen(void)

Clamp the overlay to an available display in Qt logical coordinates, if a display exists.

QStringList screenNames(void) const

Return current display labels in Qt’s screen order; names are presentation labels, not persistent identifiers.

bool moveToScreen(int index)

Move the overlay to the selected current display and clamp it to its available geometry. Return false if the display or overlay is unavailable.

bool resizeOverlay(int width, int height)

Request a positive logical-pixel size, then clamp to the current display. Qt minimum-size constraints still apply.

void clickThroughChanged(void)

Emitted when requested input mode changes, including automatic unlock.

void availableChanged(void)

Emitted when native availability changes.

void screensChanged(void)

Emitted on display addition or removal; callers must refresh any selected index.

void opacityChanged(void)

Emitted when the overlay opacity changes.

protected virtual bool eventFilter(QObject *watched, QEvent *event) override

Reconfigure on surface recreation and unlock on control hide, close or minimization.

beatglass::windows::LoopbackSession::~LoopbackSession()

Invalidate and stop the session on its control thread before destruction. The retained invalidation callback must not throw.

beatglass::windows::LiveTempo::~LiveTempo()

Stop capture and clear the estimate on the owning worker thread.

beatglass::windows::DjBridge::~DjBridge()

Stop and join the worker before destruction. Call on the GUI thread; an OS device operation that stalls can delay destruction.

beatglass::windows::OverlayController::~OverlayController()

Unlock the overlay and remove event filters. The caller retains ownership of both windows. Call on the GUI thread.

beatglass::macos::OverlayController::~OverlayController()

Unlock and hide the overlay and release the native adapter. The caller owns both windows. Call on the GUI thread.

beatglass::macos::OverlayNative::~OverlayNative()

Destroy the private native adapter on the GUI thread. It never owns the Qt window passed to its operations.

Experimental tonal worker internals

struct beatglass::detail::TonalEstimate

Provisional worker-local tonal estimate; strengths are not probabilities.

std::uint64_t key_from

First frame contributing to the current key estimate.

std::uint64_t observed_from

First frame in the most recent chord analysis window.

std::uint64_t observed_through

End of observed PCM, exclusive; values use frames in the current epoch.

std::optional<std::string> key

Track key from recent HPCP evidence, or absent when unknown.

std::optional<std::string> chord

Local major/minor triad, or absent when unknown.

float key_strength

Uncalibrated Essentia key correlation.

float chord_strength

Uncalibrated Essentia chord correlation.

class beatglass::detail::TonalTracker

Incremental, unpaced experimental Essentia analyzer, owned by one worker. PCM is borrowed only during process(); internal windows are bounded and owned. A new epoch, a gap or explicit reset discards all previous tonal evidence. Every result uses observed samples only. Not safe for concurrent calls and not for use on an audio callback or as a calibrated production estimator. Essentia is initialized once for process lifetime; create instances serially until concurrent factory use has been qualified.

TonalTracker(std::uint32_t sample_rate)

Create at the source sample rate. Rates below 12 kHz are unsupported.

Throws:

std::exception if the rate is invalid or Essentia initialization fails.

~TonalTracker(void)

Destroy on the owning worker, after all calls have stopped.

void process(std::span<const float> samples, std::uint64_t epoch, std::uint64_t first, bool discontinuity)

Consume contiguous mono PCM and retain at most the bounded analysis window.

Parameters:
  • samples – Finite mono float PCM, borrowed for this call only.

  • epoch – Source epoch; a change resets prior evidence.

  • first – Frame position of the first sample within the epoch.

  • discontinuity – Reset even when epoch and position match.

Throws:

std::exception on invalid samples, position overflow or DSP failure. Invalid PCM, position overflow and DSP failures clear estimates; discard the object after a DSP failure.

TonalEstimate estimate(void) const

Return an owned copy of the last completed analysis window, or unknown.

Experimental virtual file I/O

enum class beatglass::detail::VirtualIoStatus

Sticky virtual-I/O state; cancellation and errors invalidate the decoder.

class beatglass::detail::VirtualIo

Synchronous worker-only virtual I/O over a borrowed fixed-size byte source. The source must outlive this object and any decoder using it. Calls may block; the caller serializes access and must not call from audio or GUI threads. Exceptions are caught and become sticky errors. No bytes are retained.

VirtualIo(ByteSource &source)

Borrow the source; its immutable size must fit signed 64-bit offsets.

void set_cancel(std::stop_token cancel) noexcept

Set the token used by subsequent operations; does not clear sticky state.

std::int64_t length(void) noexcept

Return byte length or -1 on failure, recording the failure.

std::int64_t seek(std::int64_t offset, int origin) noexcept

Apply SEEK_SET, SEEK_CUR or SEEK_END with checked signed arithmetic.

Returns:

Absolute position, or -1 for invalid/out-of-range positions.

std::int64_t tell(void) noexcept

Return current position, or -1 after a failure.

std::int64_t read(void *output, std::int64_t count) noexcept

Fill up to count bytes, accumulating short reads; zero count is a no-op. Return bytes copied (possibly partial) and retain any terminal failure in status(). If status is non-ok, discard the entire output: the source may have modified bytes beyond the reported prefix before failing.

std::int64_t reject_write(void) noexcept

Reject a write attempt and record a sticky error.

VirtualIoStatus status(void) const noexcept

Return sticky status; it remains non-ok until destruction.

class beatglass::detail::VirtualFileReader

Experimental worker-owned libsndfile decoder over borrowed virtual I/O. The source outlives this reader, including its destructor. It must denote an immutable snapshot for cacheable work; this class does not create one. No product path uses this decoder yet. Cancellation during I/O invalidates it.

VirtualFileReader(ByteSource &source, std::uint64_t epoch, std::stop_token cancel)
Open with a coordinator-allocated initial epoch; throws FileOpenCancelled
  • for cancellation and std::runtime_error for failure.

~VirtualFileReader(void)

Close the decoder before releasing the borrowed source.

const FileMetadata &metadata(void) const noexcept

Metadata borrowed until destruction.

FileReadResult read(std::span<float> buffer, std::stop_token cancel)

Decode into caller storage; mid-I/O cancellation returns cancelled and makes this reader unusable.

Throws:

std::exception on malformed buffers or I/O/decode errors. Borrowed output is valid only until the caller reuses its buffer. A cancelled or failed read may have modified the caller buffer, but publishes no samples.

void seek(std::uint64_t frame, std::uint64_t new_epoch)

Seek using an externally allocated, strictly increasing epoch. Reject an invalid frame or reused/non-increasing epoch before decoder I/O; a decoder failure invalidates the reader. The coordinator must guarantee process-wide uniqueness, including across recreated readers.

Experimental beat-event worker

struct beatglass::detail::BeatEvent

Aubio beat event in the source epoch, published only after observation.

std::uint64_t epoch

Epoch supplied with the source PCM.

std::uint64_t frame

Aubio’s estimated event frame within the epoch; timing accuracy is uncalibrated.

std::uint64_t observed_through

Exclusive PCM boundary at delivery; frame is strictly below this.

class beatglass::detail::BeatTracker

Synchronous worker-owned aubio beat tracker; not safe on capture callbacks. PCM is borrowed only for each call; partial hops are stored internally. An epoch change, gap or explicit discontinuity discards previous evidence. The caller must serialize calls and destroy the object on the owning worker. An event exactly on the current exclusive boundary is held until another sample arrives; if the stream ends there it is not emitted.

using Observer = std::function<void(const BeatEvent&)>

Called synchronously on the owning worker; the callback is never retained.

BeatTracker(std::uint32_t sample_rate)

Create with a positive sample rate; throws on invalid rate or aubio failure.

~BeatTracker(void)

Release aubio state after processing has stopped.

void process(std::span<const float> samples, std::uint64_t epoch, std::uint64_t first, const Observer &observer, bool discontinuity)

Consume finite mono PCM; no future samples are accessed.

Parameters:
  • samples – Borrowed mono PCM in frame order.

  • epoch – Source epoch, changed when source timing resets.

  • first – Frame position of the first sample within the epoch.

  • observer – Optional callback for eligible events; not retained. Events eligible during a call without an observer are discarded.

  • discontinuity – Force reacquisition even for contiguous PCM.

Throws:

std::exception on invalid PCM, overflow, initialization or observer failure. Discard the tracker after any exception. The aubio counter is 32-bit; after its maximum safe span is exhausted, create a new tracker with a new epoch rather than wrapping time.

CLI application internals

inline const char *beatglass::cli::state_label(TrackingState state)

Return a stable text label for a tracking state for the provisional CLI. This pure function owns no state and is safe to call from any thread. Unrecognized enum values return “unknown”, never an active state.

Parameters:

state – State to serialize.

Returns:

A pointer to a static, null-terminated string; never null.