Audio ownership and playback
The public audio contracts belong
to Engine and contain no SDK, device or graphics types. Applications own an audio
system independently of CE::Runtime::Context and compose a selected audio module through
its public CMake target. Engine has no reverse dependency on that module.
Clips and voices
CE::Audio::Clip::from_samples takes owned interleaved float PCM, with mono/stereo
channels and a sample rate between 8 and 192 kHz. Data is nonempty, frames are
complete, and every sample is finite. The nominal sample range is [-1, 1];
storage does not clamp samples or change their rate. Copies share immutable
storage. Moving preserves the original valid snapshot. Clip creation does not
open a device. Its frame count and duration describe source audio, independently
of a mixer’s output rate.
CE::Audio::System::play creates a voice with an independent cursor. Voices can share
a clip without sharing playback progress. stream opens file-backed playback for
music; the file must remain available until playback ends. Decode and initial file
opening are synchronous preparation operations, so applications perform them at
loading boundaries or dispatch owned decode requests through their worker groups.
Voice and master volumes are normalized linear gains in [0, 1], with zero as
mute. Invalid/non-finite gains throw. Multiple voices are mixed; overlapping loud
sources can exceed nominal PCM amplitude and applications manage their mix levels.
Operation/state |
Behavior |
|---|---|
Initial playback |
Starts immediately, or starts |
|
Pauses a playing voice and preserves progress. |
|
Resumes a paused voice; other live states are unchanged. |
|
Leaves the voice |
Natural end |
Reports |
|
Requests source frame zero and starts playback. |
|
Changes the loop policy without restarting stopped/finished playback. |
System closure |
Surviving handles report |
Snapshots copy playback state, volume, loop policy and known source duration. They are observations, not an atomic freeze of native playback. Live decoder cursors are outside the initial API; reading them concurrently with mixing needs additional synchronization. No game callback runs on the mixing thread.
Lifetime and scheduling
Controls, submissions, snapshots and maintenance are synchronized across application producers. Their order follows control admission, rather than a deterministic simulation clock. Device playback progresses on its own clock without render or simulation admission. Offline processing is explicitly selected; an unavailable native device must not silently produce inaudible success.
The system retains active playback after the application releases its voice
handle. Call maintain regularly to reclaim completed/stopped/paused voices that
have no application handles. Maintenance does not advance playback. Discarded
looping voices remain active until system closure; retain their handles when they
need individual control.
Create the system before playback. Settle all producers before destroying it.
close is idempotent, stops output, retires native voices before their mixer/device,
and leaves surviving handles safe. A system cannot reopen; construct another
system for a new session. Audio need not share the graphics owner’s thread, and
this contract does not add audio to the runtime’s existing adapter teardown.
Backends and limits
The miniaudio module supplies CPU decode, explicit device/offline output and streamed playback. Its independent consumer provides native observation without a game, window or graphics module. Linux root-assembly native stereo output and sustained WAV streaming are accepted; the module guide owns reusable validation and compressed-stream, composition and platform coverage limits.
World, entity and collision organization belongs to the game or its application-selected modules. FMOD is a later optional backend; Studio authoring formats/capabilities require a separate contract.