Sign in

    dsp

    Numeric kernel of atools: FFT, STFT codec and phase reconstruction, compiled to WASM for direct browser use

    wasm
    fft
    stft
    phase-retrieval
    simd
    Download zip
    Author
    Version
    0.1.4
    License
    GPL-3.0
    Last updated
    last month
    Downloads
    45

    No dependencies

    #dsp

    A spectral DSP kernel written in MoonBit and compiled to WebAssembly. It is the numeric core of atools' audio ↔ spectrogram conversion: FFT analysis and synthesis of audio, and reconstruction of audio from a magnitude-only spectrum.

    The full documentation is available at github.com/HK-SHAO/atools.

    #Functionality

    FileRole
    engine.mbtABI version and host-memory handshake
    plan.mbtCached FFT tables
    session.mbtFixed FFT workspace pool
    pair.mbtTwo real transforms in one complex transform
    fft.mbtComplex FFT and one-sided real inverse
    arena.mbtVariable-size job memory
    pghi.mbtPGHI phase initialization
    rtisi.mbtRTISI-LA phase reconstruction
    stub.mbtImage metadata strip codec

    White-box tests live in *_wbtest.mbt, benchmarks in *_bench_wbtest.mbt.

    #Host ABI

    Exports are stable dsp_* functions; bump dsp_abi whenever an export or its semantics changes. Failures cross the boundary as values: 0 rejects a request, -1 marks an invalid handle, booleans are 1/0.

    An exported FixedArray reaches the host as the address of its data. The startup probe verifies this convention in both directions before useful work begins, and the host checks WebAssembly.Module.exports against its kernel interface, so a stale module fails before processing user data.

    #Memory

    StorageLifetimeRule
    PlanProcess, per window sizeRead-only and cached
    SlotOne transform sessionPool of six; always release
    ArenaOne PGHI, RTISI, or stub jobOwns one double and one byte segment

    Opening any of these may grow linear memory and detach existing host views: obtain views after each allocation, and again after every await. Hot loops use unchecked access only where Plan, Slot, or Arena capacity proves the index range — in release builds, checked indexing on the kernel's non-provable index patterns measures 2–3× slower (reads and writes alike), and every unchecked loop is covered by white-box tests.

    #Rules

    • Keep the source on the MoonBit standard library alone: no extern, no host fallback, one numeric implementation.
    • Preserve operation order around PGHI and short-window RTISI; tiny floating-point changes may select a different valid phase solution. Compare exact paths bitwise, and phase reconstruction over a distribution of inputs.
    • Add or change exports only together with an ABI bump, a doc comment, and a boundary test.

    #Build and verify

    In this directory:

    moon build --release --deny-warn --target wasm moon test --release --deny-warn --target wasm moon bench --release --deny-warn --target wasm moon check --deny-warn --target js moon check --deny-warn --target native moon fmt --check

    abi

    fn abi() -> Int

    Returns the host ABI version expected by the JavaScript loader.

    forward

    fn forward(s : Int) -> Unit

    Transforms the complex buffers in an open FFT slot in place.

    inverse

    fn inverse(s : Int) -> Unit

    Inverts the complex buffers in an open FFT slot in place.

    job_b

    fn job_b(h : Int) -> FixedArray[Byte]

    Returns the byte arena for an open job, or an empty array.

    job_bytes_of

    fn job_bytes_of(h : Int) -> Int

    Returns the byte capacity of an open job.

    job_close

    fn job_close(h : Int) -> Unit

    Releases a job arena; invalid handles are ignored.

    job_d

    fn job_d(h : Int) -> FixedArray[Double]

    Returns the double arena for an open job, or an empty array.

    job_live_count

    fn job_live_count() -> Int

    Returns the number of open job arenas.

    job_open

    fn job_open(dwords : Int, bytes : Int) -> Int

    Opens a zeroed job arena, returning zero when the request cannot be served.

    job_words_of

    fn job_words_of(h : Int) -> Int

    Returns the double capacity of an open job.

    pair_forward

    fn pair_forward(s : Int) -> Unit

    Computes two real spectra with one complex transform.

    pair_half_of

    fn pair_half_of(s : Int) -> Int

    Returns the one-sided spectrum length of an open slot.

    pair_inverse

    fn pair_inverse(s : Int) -> Unit

    Inverts two real spectra with one complex transform.

    pair_off_of

    fn pair_off_of(s : Int, which : Int) -> Int

    Returns a paired-transform buffer offset, or -1.

    pair_size_of

    fn pair_size_of(s : Int) -> Int

    Returns the transform size of an open slot.

    pghi_close

    fn pghi_close(h : Int) -> Unit

    Releases a PGHI job and its arena.

    pghi_off

    fn pghi_off(h : Int, which : Int) -> Int

    Returns the magnitude or phase offset of an open PGHI job.

    pghi_open

    fn pghi_open(frames : Int, bins : Int, win : Int, hop : Int, gamma : Double, tol_hi : Double, tol_lo : Double) -> Int

    Opens a PGHI job, returning zero when its shape or allocation is invalid.

    pghi_run

    fn pghi_run(h : Int) -> Int

    Reconstructs phase from the magnitude stored in an open PGHI job.

    plan

    fn plan(win : Int) -> Int

    Returns the cached plan for a supported window, or -1.

    plan_cos_of

    fn plan_cos_of(i : Int) -> FixedArray[Double]

    Returns a plan's cosine table, or an empty array.

    plan_hann_of

    fn plan_hann_of(i : Int) -> FixedArray[Double]

    Returns a plan's Hann window, or an empty array.

    plan_rev_of

    fn plan_rev_of(i : Int) -> FixedArray[Int]

    Returns a plan's bit-reversal table, or an empty array.

    plan_sin_of

    fn plan_sin_of(i : Int) -> FixedArray[Double]

    Returns a plan's sine table, or an empty array.

    probe_check

    fn probe_check(h : Int, want_d : Int, want_b : Int) -> Int

    Checks that the kernel can read a probe pattern written by the host.

    probe_stamp

    fn probe_stamp(h : Int) -> Int

    Writes the kernel probe pattern into an open job arena.

    probe_want

    fn probe_want(which : Int) -> Int

    Returns a probe seed or the required probe length.

    real_ifft

    fn real_ifft(s : Int, bins : Int) -> Int

    Reconstructs and inverts a one-sided real spectrum in place.

    rtisi_close

    fn rtisi_close(h : Int) -> Unit

    Releases an RTISI-LA job, its FFT slot, and its arena.

    rtisi_finish

    fn rtisi_finish(h : Int) -> Unit

    Normalizes and crops the completed RTISI-LA waveform.

    rtisi_levels

    fn rtisi_levels(h : Int, which : Int) -> Int

    Returns a byte-buffer offset of an open RTISI-LA job.

    rtisi_off

    fn rtisi_off(h : Int, which : Int) -> Int

    Returns a double-buffer offset of an open RTISI-LA job.

    rtisi_open

    fn rtisi_open(frames : Int, bins : Int, win : Int, hop : Int, samples : Int, iters : Int, has_warm : Int, has_band : Int, budget : Double) -> Int

    Opens an RTISI-LA job, adapting its workload to the supplied budget.

    rtisi_run

    fn rtisi_run(h : Int, from : Int, to : Int) -> Int

    Reconstructs a bounded range of frames for an open RTISI-LA job.

    slot_close

    fn slot_close(s : Int) -> Unit

    Releases an FFT slot; invalid slot IDs are ignored.

    slot_mem_of

    fn slot_mem_of(s : Int) -> FixedArray[Double]

    Returns the memory of an open FFT slot, or an empty array.

    slot_open

    fn slot_open(win : Int) -> Int

    Opens a zeroed FFT slot for a supported window size.

    slot_words_of

    fn slot_words_of(s : Int) -> Int

    Returns the double capacity of an open FFT slot.

    stub_decode

    fn stub_decode(h : Int, n : Int) -> Int

    Decodes a luma metadata profile in an open job arena.

    stub_decode_words

    fn stub_decode_words(n : Int) -> Int

    Returns the double capacity needed to decode a luma profile.

    stub_fits

    fn stub_fits(w : Int) -> Int

    Reports whether an image width can hold the metadata strip.

    stub_luma

    fn stub_luma(h : Int, w : Int, sr : Int, win : Int, exact : Int) -> Int

    Writes a luma metadata profile into an open job arena.

    stub_luma_bytes

    fn stub_luma_bytes(w : Int) -> Int

    Returns the byte capacity needed for a luma metadata profile.

    stub_paint

    fn stub_paint(h : Int, w : Int, sr : Int, win : Int, exact : Int) -> Int

    Paints an RGBA metadata strip into an open job arena.

    stub_paint_bytes

    fn stub_paint_bytes(w : Int) -> Int

    Returns the byte capacity needed to paint an RGBA metadata strip.

    stub_rows_of

    fn stub_rows_of() -> Int

    Returns the number of metadata rows reserved in an image.

    stub_sr_at

    fn stub_sr_at(i : Int) -> Int

    Returns a supported sample rate by index, or zero.

    stub_win_at

    fn stub_win_at(i : Int) -> Int

    Returns a supported window size by index, or zero.