Skip to content

RustyN64 v0.5.0

Choose a tag to compare

@github-actions github-actions released this 24 Jul 05:55
d6a94c4

v0.5.0 "Resonance" — AI audio (Phase 4)

Sound, from the buffer the RSP audio microcode produces. Phase 4 is complete: the
Audio Interface is implemented, the real libdragon audio-mixer microcode runs its
DSP on the LLE RSP and produces verified PCM, and the frontend resamples that
stream to the host device. There is no per-game audio HLE (ADR 0002) — the same
LLE RSP that runs graphics microcode mixes the audio, so audio "falls out free".

Exit criteria (both met by oracle, committed runners)

  • The real RSP audio microcode produces PCM: the vendored libdragon mixer
    (rsp_mixer.S, Unlicense) runs its resampling / volume-filter / mixing DSP on the
    LLE RSP, driven through the rspq overlay path with a hand-built channel table +
    sample bank, and DMAs back a golden-pinned, deterministic mixed 16-bit stereo
    PCM buffer. No RSP gaps surfaced — the VU/DMA path runs the real audio microcode
    as-is. Reproduce: cargo test -p rustyn64-test-harness --test mixer_microcode.
  • A real ROM plays audio through the AI: a committed license-clean bare-metal ROM
    (audio_play.z64) CPU-feeds a PCM buffer and programs the AI, which DMAs it out;
    the emitted stream matches byte-for-byte, deterministically, with the AI
    interrupt firing. Reproduce: cargo test -p rustyn64-test-harness --test audio_play_rom.

The real-game-through-the-frontend-ring variant is honestly carried to Phase 5/6:
it needs cartridge boot and the playable shell (the libdragon mixertest ROM cannot
boot in Phase 4 — it needs DFS/wav64/display/joypad).

What landed

  • rustyn64-audio implements the AI: the register block at 0x0450_0000, the two-deep
    DMA FIFO, derived-timing emission off the canonical master_ticks (ADR 0006),
    interrupt-on-start (not on drain), the AI_LENGTH mirror on write-only registers,
    the region-derived DAC rate (VIDEO_CLOCK_NTSC/PAL, documented provenance), the
    delayed-carry hardware bug (reproduced, with a guard test), and observable underrun.
  • The libdragon mixer microcode vendored + assembled (rsp_mixer.bin), booting on the
    RSP and driven to produce PCM through command_exec.
  • The frontend drains the AI stream and resamples it to the host device rate
    (resample_stereo, carried-phase linear, frontend-side per ADR 0004); the cpal
    device is opened and fed by the emu thread.
  • Ledgered residuals R-16 (AI_STATUS COUNT/WC/BC best-effort, no oracle) and R-17
    (no DMA setup latency; defined-but-unpinned underrun decay).

Earlier phases remain met

Phase 3 (v0.4.0): RDP conformance bit-matches Angrylion across 164 vectors; a real
ROM renders a golden frame. Phase 2 (v0.3.0): RSP-category n64-systemtest Failed: 0;
rdpq microcode emits an RDP command list. Phase 1 (v0.2.0): CPU Failed: 0; a 0-diff
golden trace against ares. v0.4.1 was a documentation-only patch over v0.4.0.

Verification

Full gates green: fmt, clippy (-D warnings), workspace test, rustdoc (-D warnings),
the thumbv7em-none-eabihf no_std cross-build, markdownlint, the two-blob sha256
microcode-integrity check, and the full macOS/Windows/Ubuntu + test-roms CI matrix.

Install: download the per-target archive, verify against SHA256SUMS, and extract.
Each archive carries both licences (MIT OR Apache-2.0), NOTICE, README, and CHANGELOG.