audio

    audio encoder for wav/ogg

    moonbit
    audio
    mixer
    wav
    ogg
    Download zip
    Author
    Version
    0.1.1
    License
    Apache-2.0
    Last updated
    5 months ago
    Downloads
    2K

    #mizchi/audio-mpt

    WIP audio library for MoonBit.

    #Goal

    • Provide mixer/decoder/playback primitives for games
    • Keep API backend-agnostic for js/native/wasm

    #Package

    • mizchi/audio-mpt

    #Status

    • Boilerplate only
    • See TODO.md for the implementation plan

    AudioError

    pub suberror AudioError {
    InvalidFormat(String)
    DecodeFailed(String)
    }

    Audio subsystem errors.
    impl Show for AudioError

    AssetCache

    pub(all) struct AssetCache {
    entries : Map[String, CacheEntry]
    total_bytes : Int
    max_bytes : Int
    max_entries : Int
    access_counter : Int
    } derive(Show)

    LRU asset cache for audio buffers.

    AudioBackendHooks

    pub(all) struct AudioBackendHooks {
    initialize : (Int, Int) -> Unit
    write : (FixedArray[Float], Int) -> Unit
    suspend : () -> Unit
    resume_playback : () -> Unit
    close : () -> Unit
    report_consumed : () -> Int
    }

    Backend hooks for platform-specific audio output.

    AudioBuffer

    pub(all) struct AudioBuffer {
    channels : Int
    sample_rate : Int
    data : FixedArray[Float]
    } derive(Eq, Show)

    PCM audio buffer with interleaved sample data.

    AudioCommand

    pub(all) enum AudioCommand {
    PlaySource(AudioSource, Float, Float, Bool)
    PauseVoice(VoiceId)
    ResumeVoice(VoiceId)
    StopVoice(VoiceId)
    SeekVoice(VoiceId, Int)
    SetVoiceGain(VoiceId, Float)
    SetVoicePan(VoiceId, Float)
    SetMasterGain(Float)
    } derive(Show)

    Commands for controlling the audio mixer from any thread.

    AudioRuntime

    pub(all) struct AudioRuntime {
    mixer : Mixer
    output_buffer : FixedArray[Float]
    frames_per_tick : Int
    tick_count : Int
    initialized : Bool
    command_queue : CommandQueue
    latency_monitor : LatencyMonitor
    }

    High-level audio runtime that integrates the mixer with backend hooks.

    AudioSource

    pub(all) enum AudioSource {
    Buffer(AudioBuffer)
    Stream(StreamingSource)
    } derive(Show)

    Audio source: either a complete buffer or a streaming source.

    BiquadState

    pub(all) struct BiquadState {
    b0 : Float
    b1 : Float
    b2 : Float
    a1 : Float
    a2 : Float
    z1 : Float
    z2 : Float
    } derive(Show)

    Biquad filter state (Direct Form II Transposed).

    BitReader

    type BitReader derive(Show)

    LSB-first bit reader for Vorbis bitstream parsing.

    CacheEntry

    pub(all) struct CacheEntry {
    buffer : AudioBuffer
    policy : CachePolicy
    byte_size : Int
    last_access : Int
    } derive(Show)

    Single entry in the asset cache.

    CachePolicy

    pub(all) enum CachePolicy {
    AlwaysCache
    Normal
    StreamPrefer
    } derive(Eq, Show)

    Cache eviction policy for audio assets.

    CommandQueue

    pub(all) struct CommandQueue {
    commands : Array[AudioCommand]
    pending_ids : Array[VoiceId]
    }

    Queue of audio commands to be flushed on the mixer thread.

    DelayState

    pub(all) struct DelayState {
    buffer : FixedArray[Float]
    write_pos : Int
    delay_samples : Int
    feedback : Float
    mix : Float
    } derive(Show)

    Delay effect state.

    EffectNode

    pub(all) enum EffectNode {
    Lowpass(BiquadState)
    Highpass(BiquadState)
    Delay(DelayState)
    } derive(Show)

    Effect node in the processing chain.

    Envelope

    pub(all) struct Envelope {
    config : EnvelopeConfig
    sample_rate : Int
    phase : EnvelopePhase
    level : Float
    phase_position : Int
    release_start_level : Float
    } derive(Show)

    ADSR envelope state machine.

    EnvelopeConfig

    pub(all) struct EnvelopeConfig {
    attack : Float
    decay : Float
    sustain : Float
    release_time : Float
    } derive(Eq, Show)

    ADSR envelope configuration.

    EnvelopePhase

    pub(all) enum EnvelopePhase {
    Attack
    Decay
    Sustain
    Release
    Done
    } derive(Eq, Show)

    Envelope phase in ADSR state machine.

    LatencyMonitor

    pub(all) struct LatencyMonitor {
    frames_written : Int
    ticks_elapsed : Int
    drift_frames_val : Int
    underrun_count : Int
    max_drift : Int
    }

    Monitors audio latency and drift between producer and consumer.

    Mixer

    pub(all) struct Mixer {
    voices : Array[Voice]
    master_gain : Float
    channels : Int
    sample_rate : Int
    resample_quality : ResampleQuality
    next_voice_id : Int
    }

    Multi-voice mixer with master gain.

    OggDemuxer

    type OggDemuxer derive(Show)

    OGG container demuxer.

    OggPage

    type OggPage derive(Show)

    OGG page header.

    PullCallback

    pub(all) struct PullCallback((FixedArray[Float], Int) -> Int)

    Callback that pulls audio data into a buffer. Returns frames actually written.

    ResampleQuality

    pub(all) enum ResampleQuality {
    Nearest
    Linear
    Cubic
    } derive(Eq, Show)

    Resampling quality presets.

    RingBuffer

    pub(all) struct RingBuffer {
    data : FixedArray[Float]
    capacity : Int
    channels : Int
    write_pos : Int
    read_pos : Int
    frames_available : Int
    } derive(Show)

    Ring buffer for streaming audio data.

    StreamingSource

    pub(all) struct StreamingSource {
    ring : RingBuffer
    pull : PullCallback
    channels : Int
    sample_rate : Int
    ended : Bool
    total_pulled : Int
    }

    Streaming audio source backed by a ring buffer.

    Voice

    pub(all) struct Voice {
    id : VoiceId
    source : AudioSource
    position : Float
    gain : Float
    pan : Float
    state : VoiceState
    looping : Bool
    sample_rate : Int
    loop_start : Int
    loop_end : Int
    envelope : Envelope?
    effects : Array[EffectNode]
    } derive(Show)

    A single voice playing an audio source.

    VoiceId

    pub(all) struct VoiceId(Int) derive(Compare, Eq, Hash, Show)

    Stable voice identifier.

    VoiceState

    pub(all) enum VoiceState {
    Playing
    Paused
    Stopped
    } derive(Eq, Show)

    Voice playback state.

    VorbisCodebook

    type VorbisCodebook derive(Show)

    A Vorbis codebook for Huffman decoding and VQ lookup.

    VorbisFloorConfig

    type VorbisFloorConfig derive(Show)

    Vorbis floor type 1 configuration.

    VorbisInfo

    type VorbisInfo derive(Show)

    Vorbis stream configuration parsed from headers.

    VorbisMapping

    type VorbisMapping derive(Show)

    Vorbis channel mapping.

    VorbisMode

    type VorbisMode derive(Show)

    Vorbis mode configuration.

    VorbisResidueConfig

    type VorbisResidueConfig derive(Show)

    Vorbis residue configuration.

    add_voice

    fn add_voice(mixer : Mixer, voice : Voice) -> VoiceId

    Add a voice to the mixer. Returns the voice ID.

    audio_tick

    fn audio_tick(rt : AudioRuntime) -> Unit

    Run one game tick: flush commands, mix audio, write to backend, track latency.

    biquad_process

    fn biquad_process(state : BiquadState, input : Float) -> Float

    Process one sample through a biquad filter (Direct Form II Transposed).

    cache_clear

    fn cache_clear(cache : AssetCache) -> Unit

    Clear all entries from the cache.

    cache_evict

    fn cache_evict(cache : AssetCache, key : String) -> Bool

    Evict a specific key from the cache. Returns true if found and removed.

    cache_get

    fn cache_get(cache : AssetCache, key : String) -> AudioBuffer?

    Get a cached audio buffer by key. Returns None if not found.

    cache_put

    fn cache_put(cache : AssetCache, key : String, buffer : AudioBuffer, policy? : CachePolicy) -> Unit

    Put an audio buffer into the cache. Evicts entries if needed.

    collect_stopped

    fn collect_stopped(mixer : Mixer) -> Unit

    Remove stopped voices from the mixer.

    decode_ogg

    fn decode_ogg(raw : Bytes) -> AudioBuffer raise AudioError

    Top-level OGG/Vorbis decode function. Decodes an OGG/Vorbis file from raw bytes into an AudioBuffer.

    decode_wav

    fn decode_wav(raw : Bytes) -> AudioBuffer raise AudioError

    Decode a WAV file from raw bytes into an AudioBuffer. Supports PCM format (format=1), 8-bit and 16-bit.

    delay_process

    fn delay_process(state : DelayState, input : Float) -> Float

    Process one sample through the delay effect. Ring buffer: write_pos always points to the oldest sample (delay_samples ago).

    drift_frames

    fn drift_frames(monitor : LatencyMonitor) -> Int

    Get current drift in frames.

    drift_secs

    fn drift_secs(monitor : LatencyMonitor, sample_rate : Int) -> Float

    Get current drift in seconds.

    duration_secs

    fn duration_secs(buf : AudioBuffer) -> Float

    Duration of the buffer in seconds.

    effect_process

    fn effect_process(node : EffectNode, sample : Float) -> Float

    Process one sample through an effect node.

    effects_chain_process

    fn effects_chain_process(effects : Array[EffectNode], sample : Float) -> Float

    Process one sample through an entire effects chain.

    enqueue

    fn enqueue(queue : CommandQueue, cmd : AudioCommand, mixer : Mixer) -> VoiceId?

    Enqueue a command. For PlaySource, returns the pre-allocated VoiceId.

    envelope_release

    fn envelope_release(env : Envelope) -> Unit

    Trigger the release phase of the envelope.

    envelope_reset

    fn envelope_reset(env : Envelope) -> Unit

    Reset the envelope to the beginning of the attack phase.

    envelope_tick

    fn envelope_tick(env : Envelope) -> Float

    Advance envelope by one sample and return the current gain level.

    find_voice

    fn find_voice(mixer : Mixer, id : VoiceId) -> Voice?

    Find a voice by its ID. Returns None if not found.

    flush_commands

    fn flush_commands(queue : CommandQueue, mixer : Mixer) -> Unit

    Flush all commands to the mixer. Processes in FIFO order.

    frame_count

    fn frame_count(buf : AudioBuffer) -> Int

    Number of frames in the buffer.

    get_audio_backend_hooks

    fn get_audio_backend_hooks() -> AudioBackendHooks

    Get a reference to the current backend hooks.

    get_sample

    fn get_sample(buf : AudioBuffer, frame : Int, channel : Int) -> Float

    Get sample value at (frame, channel). Interleaved layout.

    highpass_coefficients

    fn highpass_coefficients(cutoff_hz : Float, sample_rate : Int, q? : Float) -> BiquadState

    Compute highpass biquad filter coefficients (RBJ Audio EQ Cookbook).

    lowpass_coefficients

    fn lowpass_coefficients(cutoff_hz : Float, sample_rate : Int, q? : Float) -> BiquadState

    Compute lowpass biquad filter coefficients (RBJ Audio EQ Cookbook).

    new_asset_cache

    fn new_asset_cache(max_bytes : Int, max_entries : Int) -> AssetCache

    Create a new asset cache with given limits.

    new_audio_buffer

    fn new_audio_buffer(channels : Int, sample_rate : Int, frames : Int) -> AudioBuffer

    Create a new AudioBuffer with zeroed samples.

    new_audio_runtime

    fn new_audio_runtime(sample_rate : Int, tps : Int) -> AudioRuntime

    Create a new audio runtime. sample_rate: output sample rate (e.g. 44100) tps: ticks per second (e.g. 60 for 60fps game loop)

    new_command_queue

    fn new_command_queue() -> CommandQueue

    Create a new empty command queue.

    new_delay

    fn new_delay(delay_ms : Float, sample_rate : Int, feedback? : Float, mix? : Float) -> DelayState

    Create a new delay effect.

    new_envelope

    fn new_envelope(config : EnvelopeConfig, sample_rate : Int) -> Envelope

    Create a new ADSR envelope.

    new_latency_monitor

    fn new_latency_monitor() -> LatencyMonitor

    Create a new latency monitor.

    new_mixer

    fn new_mixer(sample_rate : Int, resample_quality? : ResampleQuality) -> Mixer

    Create a new stereo mixer at the given sample rate.

    new_ring_buffer

    fn new_ring_buffer(capacity : Int, channels : Int) -> RingBuffer

    Create a new ring buffer with the given capacity in frames.

    new_streaming_source

    fn new_streaming_source(pull : PullCallback, channels : Int, sample_rate : Int, buffer_frames? : Int) -> StreamingSource

    Create a new streaming audio source.

    new_voice

    fn new_voice(mixer : Mixer, source : AudioSource, gain? : Float, pan? : Float, looping? : Bool, envelope? : Envelope?) -> Voice

    Create a new voice from an audio source.

    new_voice_from_buffer

    fn new_voice_from_buffer(mixer : Mixer, buffer : AudioBuffer, gain? : Float, pan? : Float, looping? : Bool, envelope? : Envelope?) -> Voice

    Create a new voice from an AudioBuffer (convenience wrapper).

    new_voice_with_loop

    fn new_voice_with_loop(mixer : Mixer, source : AudioSource, loop_start : Int, loop_end : Int, gain? : Float, pan? : Float, looping? : Bool) -> Voice

    Create a new voice with loop points from an audio source.

    pan_gains

    fn pan_gains(pan : Float) -> (Float, Float)

    Compute constant-power pan gains for left and right channels. pan: -1.0 (full left) to 1.0 (full right), 0.0 = center.

    pause_voice

    fn pause_voice(mixer : Mixer, id : VoiceId) -> Bool

    Pause a playing voice. Returns true if state changed.

    play_sound

    fn play_sound(rt : AudioRuntime, buffer : AudioBuffer, gain? : Float, pan? : Float, looping? : Bool) -> VoiceId

    Play a sound buffer through the runtime. Returns voice ID.

    queue_length

    fn queue_length(queue : CommandQueue) -> Int

    Number of pending commands.

    read_source_sample

    fn read_source_sample(source : AudioSource, frame : Int, channel : Int) -> Float

    Read a sample from an audio source at the given frame and channel.

    reset_audio_backend_hooks

    fn reset_audio_backend_hooks() -> Unit

    Reset hooks to no-op defaults.

    reset_latency_monitor

    fn reset_latency_monitor(monitor : LatencyMonitor) -> Unit

    Reset all counters.

    resume_voice

    fn resume_voice(mixer : Mixer, id : VoiceId) -> Bool

    Resume a paused voice. Returns true if state changed.

    ring_available

    fn ring_available(rb : RingBuffer) -> Int

    Number of frames available for reading.

    ring_consume

    fn ring_consume(rb : RingBuffer, frames : Int) -> Unit

    Consume (advance read_pos) the given number of frames.

    ring_free

    fn ring_free(rb : RingBuffer) -> Int

    Number of frames of free space for writing.

    ring_peek

    fn ring_peek(rb : RingBuffer, frame_offset : Int, channel : Int) -> Float

    Peek at a sample at the given frame offset from read_pos.

    ring_reset

    fn ring_reset(rb : RingBuffer) -> Unit

    Reset the ring buffer to empty state.

    ring_write

    fn ring_write(rb : RingBuffer, src : FixedArray[Float], frames : Int) -> Int

    Write frames into the ring buffer. Returns number of frames actually written.

    seek_voice

    fn seek_voice(mixer : Mixer, id : VoiceId, frame : Int) -> Bool

    Seek a voice to a given frame position. Returns true if voice was found.

    set_audio_backend_hooks

    fn set_audio_backend_hooks(hooks : AudioBackendHooks) -> Unit

    Set the audio backend hooks.

    set_sample

    fn set_sample(buf : AudioBuffer, frame : Int, channel : Int, value : Float) -> Unit

    Set sample value at (frame, channel). Interleaved layout.

    source_channels

    fn source_channels(source : AudioSource) -> Int

    Get the channel count of an audio source.

    source_frame_count

    fn source_frame_count(source : AudioSource) -> Int

    Get the frame count of an audio source.

    source_sample_rate

    fn source_sample_rate(source : AudioSource) -> Int

    Get the sample rate of an audio source.

    stop_voice

    fn stop_voice(mixer : Mixer, id : VoiceId) -> Bool

    Stop a voice. Returns true if voice was found.

    streaming_available

    fn streaming_available(source : StreamingSource) -> Int

    Number of frames available in the streaming source.

    streaming_fill

    fn streaming_fill(source : StreamingSource, min_frames : Int) -> Unit

    Fill the streaming source's ring buffer until at least min_frames are available.

    tick

    fn tick(mixer : Mixer, frames : Int, output : FixedArray[Float]) -> Unit

    Mix all playing voices into the output buffer for the given number of frames. Output is interleaved stereo (2 channels). Buffer must have length >= frames * 2.

    underrun_count

    fn underrun_count(monitor : LatencyMonitor) -> Int

    Get underrun count.

    update_latency

    fn update_latency(monitor : LatencyMonitor, frames_this_tick : Int, consumed : Int) -> Unit

    Update latency tracking after a tick. frames_this_tick: frames produced this tick. consumed: frames consumed by backend since last update.

    voice_position

    fn voice_position(mixer : Mixer, id : VoiceId) -> Float?

    Get the current position of a voice in frames.

    voice_state

    fn voice_state(mixer : Mixer, id : VoiceId) -> VoiceState?

    Get the current state of a voice.

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io