mwg API
    Preparing search index...

    Class AudioCoreHost

    Runs a synthesis core on a worker and presents it as an endless BlockSource, so a StreamChannel plays it like any stream while the render cost stays off the frame. Messages go to the core stamped with an output frame and are applied at that frame; blocks come back transferred, not copied, and wait in a short queue that read drains. When the queue runs dry the missing frames are silence, the playhead moves on, and the underrun is counted and reported (onUnderrun, onAudioUnderrun), so timing never drifts. Where no worker exists, or one dies, the same runner runs on the main thread instead: slower for the frame, identical in sound.

    import { AudioCoreHost, StreamChannel, type AudioCore } from '@datamoc/mwg/audio';

    declare const context: AudioContext;

    const host = new AudioCoreHost({
    sampleRate: 44100,
    factory: (rate): AudioCore => ({
    sampleRate: rate,
    event() {},
    sysex() {},
    render() {},
    reset() {},
    }),
    });
    new StreamChannel(context).play(host);
    host.event(0x90, 60, 100);
    console.log(host.stats().mode);

    Implements

    Index
    onUnderrun: Signal<number> = ...

    fires when a read found the queue short, with the seconds of silence it had to put in

    sampleRate: number
    • get mode(): "worker" | "inline"

      'worker' while the core runs off the main thread, 'inline' otherwise

      Returns "worker" | "inline"

    • stops the worker and drops what is queued; the host cannot be used afterwards

      Returns void

    • sends a channel message; applied at atFrame, or at the start of the next block to be rendered when omitted

      Parameters

      • status: number
      • data1: number
      • data2: number
      • OptionalatFrame: number

      Returns void

    • sends many channel messages in one go, each at its own frame: one post to the worker instead of one per message

      Parameters

      • list: readonly TimedMessage[]

      Returns void

    • Asks the runner for whatever the queue is missing; called by every read and safe to call from a timer. A worker keeps queueSeconds rendered ahead of the playhead, hiding its latency from the game; the inline fallback renders just in time instead, since a queue on the thread that pays for it only moves the cost, and a message then lands on exactly its frame.

      Parameters

      • needed: number = 0

      Returns void

    • an endless source: fills count frames, with silence where the core was late, and always returns count

      Parameters

      • left: Float32Array
      • right: Float32Array
      • start: number
      • count: number

      Returns number

    • silences the core and discards everything rendered ahead of the playhead

      Returns void

    • moves the playhead; a different frame resets the core, the same frame leaves it playing

      Parameters

      • frame: number

      Returns void

    • Starts a piece: silences the core, drops what was rendered ahead, and queues list before any further audio is asked for. A host starts rendering ahead as soon as it exists, so messages sent afterwards with events would reach the core after the audio they belong to was already made and start late; this orders the reset, the messages and the rendering so they cannot.

      Parameters

      • list: readonly TimedMessage[]

      Returns void

    • Parameters

      • bytes: Uint8Array
      • OptionalatFrame: number

      Returns void