AudioSink

An audio output device.

This is the most safety-critical interface in the library. It runs on a real-time thread that must never block, and the master clock is derived from what it reports.

The model is pull. The device asks the engine for samples; the engine does not push them. Some platforms are natively pull (CoreAudio AudioUnit, AAudio with a data callback, event-driven WASAPI, WebAudio) and some are natively push (ALSA read-write, PulseAudio, SourceDataLine, Android AudioTrack blocking write). A push platform is wrapped by one writer coroutine that turns "the device has room" into a pull. Standardising on one shape means the clock has one shape.

A sink never converts. No resampling, no channel remixing, no tempo change. Those live in the engine's filter chain where they are testable in commonMain and where their own latency is known. The only conversion a sink may do is trivial bit packing, for example 32-bit to packed 24-bit.

Inheritors

Properties

Link copied to clipboard

Whether stopping or pausing this device cuts the sound at whatever sample it reached (#486).

Link copied to clipboard
abstract val deviceBufferFrames: Int

The device's own buffer size in sample frames. Sizes the engine's ring.

Link copied to clipboard
abstract val events: Flow<AudioSinkEvent>

Device loss, underrun, format change. The sink reports; the engine decides what to do.

Link copied to clipboard

How far latencyNanos can be trusted.

Link copied to clipboard

A platform handle for effects that attach to this device's stream, or null when the platform has no such concept.

Functions

Link copied to clipboard
expect abstract fun close()
Link copied to clipboard
abstract suspend fun drain()

Plays out what is queued, then stops. This is the end-of-media path.

Link copied to clipboard
abstract fun latencyNanos(): Long

Nanoseconds of audio handed over but not yet audible, including everything inside the OS and the hardware.

Link copied to clipboard
abstract suspend fun open(request: AudioFormat, render: AudioRenderCallback): AudioFormat

Opens the device.

Link copied to clipboard
open fun setContent(content: AudioContent)

What the sound the next open plays is, for the platform's own sound processing (#446). The engine calls this before every open with the item's AudioContent, never AudioContent.Automatic, which it has already resolved. It takes effect at that open: a device already open keeps what it was opened with. A platform with no such setting ignores it, which is the default.

Link copied to clipboard
abstract suspend fun setPaused(paused: Boolean): Boolean

Pauses without discarding.

Link copied to clipboard
abstract suspend fun start()

Starts the device pulling samples through the render callback.

Link copied to clipboard
abstract suspend fun stop()

Stops and discards everything unplayed. This is the seek path.