Skip to content

v1.5.0 — Audio sprites

Choose a tag to compare

@ozgesolidkey ozgesolidkey released this 19 Sep 21:53
· 17 commits to main since this release

KMPMedia 1.5.0 — Audio sprites 🔊

Adds audio sprites — trigger slices of a single audio file on demand. Pack many short sounds (a "collect" chime, a "hit" thud, a "powerup" sweep) into one asset and fire any of them by id on an event, with a small voice pool so they can overlap instead of cutting each other off.

Purely additive: a brand-new primitive alongside the existing OGAudioPlayer, which is unchanged.

val sprite = OGAudioSprite.create()
sprite.load(
    source = OGSource.Resource("sfx"),
    clips = listOf(
        OGAudioClip("collect", startMs = 0,   endMs = 280),
        OGAudioClip("hit",     startMs = 400, endMs = 750),
        OGAudioClip("levelup", startMs = 900),           // plays to end
    ),
    config = OGAudioSpriteConfig(voices = 4, volume = 1f),
)
sprite.play("collect")   // fires on the next free voice

Added

  • OGAudioClip(id, startMs, endMs = END) in com.solidkey.painpoints.audio.playing — a named, time-bounded window inside one audio file (the audio equivalent of a texture atlas). endMs = OGAudioClip.END (default) plays from startMs to the end of the file; otherwise endMs must be > startMs. Exposes playsToEnd / durationMs; validates its inputs.
  • OGAudioSprite (expect/actual) — loads one OGSource plus a list of OGAudioClips, then play("hit") fires a clip on the next free voice. Also stop(clipId), stopAll(), setVolume(0f..1f), release(), and clipIds. Created with OGAudioSprite.create() (Composable factory).
  • OGAudioSpriteConfig(voices = 4, volume = 1f) — sizes the round-robin voice pool (how many clips may sound at once) and sets master volume.

Notes

  • Android plays each window via media3/ExoPlayer MediaItem.ClippingConfiguration (the same media3 stack the video player already uses); iOS via AVPlayer seek + AVPlayerItem.forwardPlaybackEndTime, one player per voice. Overlap is handled by a shared, unit-tested round-robin allocator (OGVoiceRotor) — the (voices+1)-th simultaneous trigger reuses the oldest voice.
  • Short SFX deliberately do not grab Android audio focus.
  • Backward-compatible — OGAudioPlayer (whole-file playback) is untouched. See docs/AUDIO_SPRITE.md. The demo's UFO Dodge game uses it for collect/hit/level-up SFX.

Install

implementation("se.solidkey:kmpmedia-lib:1.5.0")