Sounds and Music - smeagol44/MKMSZ-Randomizer GitHub Wiki

Audio system

New v05 selector-only audio origin constraint (2026-10-10): Complete guest PIF/AI/VI/RSP/phase/SDL capture identifies 299 recurring native PCM enqueue failures, including 169 before the first Fortress stage-9 sample; first t36.496, head/tail 1,600/1,472B, promoted tail ends 4,746 Count after next service. 5,860 SDL fragment pushes all succeed, zero SDL threshold drops. Synth surplus during rejection regime 105,248 = 299 × 352 sample frames, consistent with native producer advancing despite rejected PCM. Frontend initiator still Pending; no descriptor-0x1FC or palette accusation, no production correction. Audio owner.

Stress-run v05 audio negative 2026-10-10: An independently longer ~598s Fortress test with walk/combat/healing/box-switch/rapid cursor never accelerated continuously (maintainer observed occasional brief crunch), despite 612 combined Up/Down press edges. Lossless native AI has only 18 distinct FIFO-rejected PCM submissions; maximal cluster 5 over 0.266s. Retained SDL host queue has at least 59 drops (beginning overwritten; 23 occur >last user input). Three 368-frame-only healthy spans ~44.8s, 40.0s and 38.5s with zero buttons all show AI_LEN lower band 1344→1288. Even AI_LEN=1216 occurs 29 times and 1,600-byte PCM is accepted 30 times without sustained runaway. This refutes both cursor sweep and AI_LEN=1216 as sufficient causes; they may still affect eventual FIFO phase selection. In complete retained VI tail 32,768/32,768 active audio polls and 32,767/32,767 sample-clock steps match. Enemy Grunt update/aggro cannot be inferred from PIF/RSP/VI/phase streams; no guest actor tracer was run. See negative control.\n\nv05 input-aligned fast PCM dropout (2026-10-10) — user Runtime-observed, numeric trace-confirmed. The original PIF controller answers for 1,594 input polls prove Up/Down navigation (39 Down + 34 Up before first rejection) preceded the next rapid audio failure. Z response t38.786 probably entered Inventory; repeated navigation starts t39.711; first AI_LEN=1216 t62.093997, first 1,600B synthesis t62.111, first native FIFO FULL t62.544 (1,600B head/1,472B queued tail). Queued tail ends 4,056 Count after next native service (prior v04 fast −4,126), triggering 86 rejected PCM submissions over 5.734s, accepted interleaved among failures. No SDL host queue-threshold drop occurs; this recording demonstrates clipping with native PCM omission even without host queue overflow. Synth frames +23.54% vs 368-frame target over 345 services. Rejections continue 4.883s after all inputs release, so cursor motion is not required for maintenance of the feedback fault. An 8B lower-AI_LEN staircase advances every ~4.804s from 1,256 to 1,216 after Inventory activity, consistent with 15.29 Count/VI phase creep; nearest later Up edge cannot have caused the AI_LEN=1216 already sampled. No specific Inventory-open, cursor renderer/SFX, or producer-state writer is proven as original cause. See native event proof.\n\nPrecisely quantified RMG v04 deadline fork (2026-10-10): With pinned 551 Count/PCM byte and 811,092 Count/VI, 352/368/384-frame DMA durations are 775,808 / 811,072 / 846,336 Count; 368 frames finish only 20 Count before nominal next VI. Clean and slowdown runs had healthy ~40s 368-only plateaus; observed AI END spacing ~811,077.4/811,077.8 versus 811,092 for audio services naturally drives the 1,344→1,280-byte AI_LEN quantization staircase. Slow onset queued 1,408B finishes 35,580 Count before next service, leading to ~35,226 median empty-FIFO gap and 352-only generated outputs. Fast onset queued 1,472B finishes 4,126 Count after next service; counterfactual 1,408B would finish 31,138 Count before. These are timing-conditional native-feedback attractors, not established initial game bug or proven hardware-portable repair. The burst's 81 failed submission events recur approximately every fourth service, interspersed with accepted output. See full v04 fork proof.\n\nNew bidirectional audio feedback evidence, 2026-10-10 — three RMG v04 sessions: The same native AI_LEN-sampled buffer-size rule enters distinct output basins while clock and producer ownership remain intact. Slow audible episode: 2,303 consecutive accepted 352-frame buffers after a rejected service (plus one preceding accepted 352-frame output), spanning 38.4s overall, AI_LEN stays 1,400 bytes and SDL host queue falls to median 504B (threshold 17,637B); one AI END interrupts native FULL read after just 10 CP0 Count and the following FIFO-only-BUSY regime persists without repeated rejects. Fast audible episode: 81 rejected enqueues over 5.334s, interspersed among ~240 successful services, producer sample clock advances ~23.8% faster than nominal per-VI target while guest PCM gets skipped, with host queue median 16,600B and four threshold drops. A clean 6m20 run itself contains ~39.77s all-368-frame output without perceived acceleration, so that plateau is not a sufficient failure flag. Observed native sample-time rates do not directly measure audible pitch/tempo. All 52,316 new phase snapshots retain the same startup DAC/target constants and pointers; 52,313 synth clock increments exactly match prior Info frame sizes. This establishes opposing downstream low-/high-supply regimes, not the earliest triggering operation, nor a safe production fix. See full causal evidence and caveats.\n\nNative AI closed-loop phase audit (2026-10-09): full captured-event confirmation, root-cause correction Pending. Across 5 complete RMG traces (7–11), reproduced 59,489/59,489 AI_LEN reads from DMA head length/duration/CP0 deadline and 58,971/58,971 native PCM buffer sizes from the preceding AI_LEN; all 513 failed enqueue sizes infer 352 frames from the same native recurrence. Severe first-failure queued tail is ~3,784–4,486 Count late at the next audio service; isolated recoveries have >30,500 Count spare. Trace 11's 79th consecutive rejection is followed by audio recovery when AI END occurs 18 Count after the first FULL-status read, before diagnostic logger's second status read, changing subsequent AI_LEN to 1,464B. This establishes an exact FIFO deadline/feedback bifurcation in the observed pinned emulator, and makes a spontaneous corrupted AI_LEN unlikely as a necessary cause of those traces. It does not prove the earlier guest scheduling trigger or rule out other memory faults; logger timing impacts the exit. The proposed rational-duration observer experiment lengthens 368-frame DMA and could worsen FIFO occupancy, so is not a ready fix. See audio investigation.\n\nVanilla ROM audio control (2026-10-09): stock also produces FIFO FULL; repeated failure remains MKMSZR-composition-specific. Five genuine stock guest FIFO FULLs in ~321s and 40 host SDL queue drops were recorded without audible speed-up. Stock and mod run identical 551 Count/byte emulator DMA duration. One vanilla three-FULL cluster begins with the exact head/tail sizes of MKMSZR's 73-FULL runaway (1600/1472 then 2816/1472), but vanilla's third tail is 1408 rather than 1472 and it recovers. Vanilla has no long all-368-frame output streak (maximum four consecutive) compared to MKMSZR ~40s 368-only precursors. An early-truncated emulator DMA clock likely contributes to shared host clipping, but is not sufficient by itself for sustained mod-only runaway. Do not interpret the absence of an audible stock failure as zero stock FIFO rejections or as proof of corrupting guest RAM. See canonical audio investigation.\n\nRMG v0.9.0 AI DMA timing precision candidate (2026-10-09): emulator-static confirmed, production cause Pending. get_dma_duration uses AI_LEN*(cpu_counts_per_sec/(4*sample_rate)) with early integer truncation: observed duration 551 Count/byte for all accepted Trace (5)/(6)/(7)/normal-controls, whereas fractional Count/byte is ~551.838 at 22,047Hz. 368-frame DMA consumes 811,072 Count versus nominal VI 811,092; guest AI output rate is ~22,080.54 frames/s but host plays 22,047Hz, predicting ~134 bytes/second SDL queue buildup (~133 B/s observed). Trace (6)/(7) both show nearly 40 seconds of consecutive 368-frame outputs and AI_LEN 1,344→1,280 before the first rejected submission. This explains an RMG host clipping mechanism and strongly implicates slow phase feedback, but is not verified as the sole source of guest FIFO bursts or all historical corrupted audio. The ROM's native audio frame builder is byte-identical to clean; emulator-only controlled A/B is staged in draft PR #161, not a native production fix. See focused investigation.\n\nNative music upstream investigation (2026-10-09): head/tail FIFO feedback bifurcation reconstructed; initial trigger and permanent correction Pending. The diagnostic pair has +135 rejected outputs, +4,934 audio and VI services, and +47,616 synthesized samples beyond the nominal target. Native synthesis/WESS advance despite failed enqueue. The new paired host traces establish why the feedback loop sometimes runs away: the queued tail's drain deadline falls just after (Trace 5) or well before (Trace 6) the next service, causing the same 704-frame generation to be queued behind a busy head with AI_LEN=0, or started in an empty FIFO with AI_LEN≈2808. All accepted DMA durations use 551 Count/byte; 368 frames correspond to 811,072 Count against VI=811,092 Count. No responsible Inventory operation or original initial-phase perturbation is recovered. The inspected RMG v0.9.0 source distinguishes emulated AI consumption, ParaLLEl task timing and possible host audio fragment drops; the maintainer's installed build/audio plugin still need pinning. No retry correction is justified. See native schedule, quantitative limits and minimum observation.

Scope: This page is the canonical owner for MKMSZ host audio behavior: native gameplay SFX routing, descriptor and runtime-definition architecture, call-chain behavior, stable host-bank conclusions, audio safety rules, and current music status.

MKT Toasty donor identification, rejected candidates, source-to-retail mapping, and sound-proof v01-v03 chronology are canonical in Toasty audio research. Function semantics remain canonical in Function registry; addresses are named here only to explain the audio call chain.

Current conclusion

MKMSZ has a statically mapped native gameplay SFX path from a compact descriptor index through an event/raw-ID entry into runtime sound definitions and the lower voice allocator. The stock ordinary-pickup path is the best current control because its caller, descriptor, event namespace, and downstream patch/subpatch/waveform routing have all been traced.

The Toasty work additionally established a stable host-side compatibility result: MKMSZ can play imported MKT N64 ADPCM data with transplanted predictor metadata through the native audio engine when the event/patch/subpatch/waveform namespaces and pitch correction are translated correctly. That is a Runtime-confirmed proof, not a production allocation or final cosmetic trigger. See Toasty audio research.

Music remains Pending as a general subsystem: the project has not mapped the complete MKMSZ music sequence/control API. The Toasty proofs exposed SSEQ/event and instrument-liveness behavior relevant to safe SFX work, but they do not constitute a full music-engine map.

Current status

Area Status Evidence and limit
Gameplay SFX wrapper Static-confirmed 0x80064C18 is widely called by stock gameplay code and resolves a descriptor before native playback
SFX descriptor table Static-confirmed 10-byte entries begin at VA 0x800A1730 / ROM 0x000A2330
Raw/event playback entry Static-confirmed 0x80080A88 receives the resolved ID and selects a 16-byte runtime sound definition
Low-level voice allocation/start Static-confirmed 0x8007EC4C consumes the resolved runtime definition
Ordinary-pickup control Static-confirmed descriptor 0x3B resolves to event/raw ID 0x020C; its SSEQ route reaches patch 681 / subpatch 524 / waveform 133
Main MKMSZ SN64 bank grammar Static-confirmed control bank and waveform-table structure are parsed; exact host counts and bases are recorded below
Foreign MKT N64-ADPCM compatibility Runtime-confirmed proof Toasty v02 proves one-shot imported donor-sample playback; v03 proves the accepted Toasty voice and pitch metadata
Music engine / complete sequence-control API Pending only the bounded SSEQ/event behavior needed by the audio proofs is mapped
Production Toasty audio route Runtime-confirmed production composition Dedicated event 52 -> 68 -> 608 -> 533 is integrated; stock pickup audio remains untouched

Native gameplay SFX path

The currently mapped host path is:

gameplay caller
    |
    | descriptor index
    v
0x80064C18  native gameplay SFX wrapper
    |
    | 10-byte descriptor from 0x800A1730
    v
0x80080A88  raw sound-ID playback entry
    |
    | resolved 16-byte runtime sound definition
    v
0x8007EC4C  low-level definition / voice allocator

The wrapper at 0x80064C18 is a general gameplay facility rather than a one-off effect path. Static call-site scanning finds hundreds of direct uses in the clean USA Rev. 0 ROM, including ordinary pickup callbacks.

SFX descriptor table

The descriptor table begins at:

  • VA 0x800A1730
  • ROM 0x000A2330

Each entry is exactly 10 bytes:

Offset Size Meaning Status
+0x00 2 native raw sound/sample ID Static-confirmed
+0x02 1 high byte not consumed by the mapped wrapper path Static-confirmed observation; semantic meaning pending
+0x03 1 base primary sound parameter Static-confirmed
+0x04 2 random variation magnitude for the primary parameter Static-confirmed
+0x06 2 base secondary parameter Static-confirmed
+0x08 2 random variation magnitude for the secondary parameter Static-confirmed

The random-variation helper used by this path is 0x80015FD8. Static analysis shows it produces a roughly symmetric signed variation around the supplied base value. Exact gameplay semantics for the two parameters are not yet named; do not label them as volume, pitch, pan, or another conventional audio property until caller/runtime evidence establishes that meaning.

Worked stock example: ordinary pickup sound

Several stock pickup callbacks call:

a0 = 0x3B
a1 = 0
a2 = 0x40
jal 0x80064C18

Descriptor 0x3B is located at ROM 0x000A257E and contains:

02 0C 00 7F 00 00 00 00 00 00

Decoded through the currently mapped structure:

  • raw sound ID: 0x020C
  • primary base parameter: 0x7F
  • primary variation: 0
  • secondary base parameter: 0
  • secondary variation: 0

This is the current reference control for future custom-SFX experiments because the full stock route from gameplay event to native playback is known.

Runtime definition and bank architecture

Static-confirmed host facts established during the Toasty investigation:

  • MKMSZ main SN64 control bank: ROM 0x947C80, control payload at 0x947CB8, size 0x2F088.
  • MKMSZ waveform-data/TBL base: ROM 0x9B0650.
  • Parsed host bank: 683 event/raw IDs, 740 intermediate/subpatch records, and 598 waveform records.
  • The runtime sound-definition records selected by 0x80080A88 are 16 bytes each before the lower voice path consumes them.
  • For the stock ordinary-pickup control, descriptor 0x3B selects event/SSEQ entry 0x020C (524), whose single track starts on patch 681; patch 681 owns subpatch 524, which selects waveform 133.

The proof history also established an important namespace/liveness rule: an event/SSEQ index is not the same namespace as an SN64 patch number. Safe liveness analysis must include gameplay event references, every SSEQ track-header initial patch ID, in-stream program changes, and patch -> subpatch -> waveform sharing. A patch or waveform is not disposable merely because it is absent from descriptor tables or explicit in-stream program changes.

These are host-side architectural conclusions. Donor-specific selectors, MKT bank addresses, waveform identities, and v01-v03 chronology belong to Toasty audio research.

Function-semantics ownership

The audio chain above names 0x80064C18, 0x80080A88, 0x8007EC4C, and 0x80015FD8 because their composition matters to the audio explanation. Their canonical meanings, evidence labels, and future semantic corrections are maintained only in Function registry; this page intentionally does not maintain a competing function table.

Seeded Temple intro audio

The Temple intro has two independently validated audio positions. The opening spoken position chooses stock descriptor 0x41 (“You will fail”) or 0x42 (“I will succeed”) through the stock persistent alternation at 0x800AA8A4; the later position uses descriptor 0x43 for Scorpion's laugh. The relevant Temple-overlay immediates are ROM 0xCB274, 0xCB280, and 0xCB2F8.

Bounded manual proofs established both replacement seams:

  • Audio 2: v02 replaced only the Temple 0x43 call with an imported MKT Shao Kahn laugh while forcing a known stock first line; runtime playback was accepted. Later Raiden and robot-run donor clips were auditioned and the same Audio-2 route was accepted.
  • Audio 1: v05 redirected both stock first-line branches to an imported Raiden BBB clip while leaving 0x43 completely stock; runtime playback was accepted.

The production contract is seed/build-time deterministic rather than runtime-random. When a valid MKT USA Rev. 2 N64 donor is supplied, the isolated domain MKMSZR:TEMPLE-INTRO-AUDIO:V1\0 chooses exactly one position and then one clip from that position's pool. The other position stays stock. With no MKT donor, the Temple-audio patch is omitted entirely.

Approved Audio 1 pool:

  • Shao Kahn “Friendship!” (TS_SK_FRIEND; the alternate Friendship take is intentionally excluded)
  • Shao Kahn “Choose Your Destiny” (TS_SK_CHOOSE)
  • Shao Kahn “Excellent” (TS_SK_EXCELLENT)
  • Shao Kahn “Superb” (TS_SK_SUBERB)
  • Shao Kahn “Well Done” (TS_SK_WELL_DONE)
  • Liu Kang bicycle-kick vocal (ST_LK_BIKE)

Approved Audio 2 pool:

  • Raiden torpedo BBB / SSS / TTT (ST_RD_BBB, ST_RD_SSS, ST_RD_TTT)
  • robot run (GS_RUN_ROBO)
  • Shao Kahn laugh

Only the selected encoded sample is materialized into the output ROM; the complete pool is never copied into one build.

Production carrier and proof-carrier correction

The early Temple proofs used descriptor 0x220 -> event 0x1B8 -> patch 597 -> subpatch 440 -> wave 430. That route is proof-only: a later whole-ROM audit found live stock callers loading descriptor 0x220 around ROM 0xBE744/0xBE750/0xBFACC, including calls into 0x80064C18. Reusing it in production could therefore alter unrelated stock audio.

Production instead uses the statically isolated chain:

descriptor 0x20A -> event 0x1A6 -> patch 579 -> subpatch 422 -> wave 412.

Clean-ROM analysis found no direct descriptor/event immediates for 0x20A/0x1A6, and the event -> patch -> subpatch -> waveform ownership is unique. The selected donor event/subpatch/wave/predictor metadata is rebased into that chain. The selected ADPCM sample owns conditional high-ROM reservation [0xF6BDF0,0xF6D810), immediately after the production Toasty sample region. v06 Runtime-confirms this production carrier/allocation composition: seed TEMPLE-PROD-CARRIER selected Audio 1 / Friendship and the user observed the expected “Friendship!” followed by the untouched stock Scorpion laugh. Proof ROM SHA-256 is 9460d923b9c1cecf2d481e36719f7249231944eeecc7e2c300dd95a4809085c6; builder SHA-256 is d529e212f667ebd6f4724b03d7cb828e726b4f9c9d4ab897856db46ae5f6a102. This is bounded confirmation of the production carrier and one Audio-1 pool member, not exhaustive runtime coverage of all 11 approved clips.

The attempted MKT retail TS_SK_ITS_OFFICIAL / skyousuk lookup is excluded from the pool. User audition showed the retail waveform reached through that surviving identity is an unrelated short impact-like sound. Older Midway sources show the complete phrase was assembled from separate skofficl then skyousuk material; recovering that phrase remains optional future pool work.

Music

Partially mapped, broader behavior Pending. The 2026-10-08 production Inventory investigation statically/snapshot-confirms bounded WESS track/voice structures, current Fortress sequence data, bank/sample-cache ownership, and the synthesis-to-AI call path. It does not establish the complete sequence/control API, all sequence command semantics, or the accelerated-music cause. Preserve the distinction between bounded native evidence and a general subsystem closure.

Safety and implementation boundary

For a future custom-sound proof:

  • keep the clean ROM untouched and build a separate guarded output;
  • guard all edited table entries and storage ranges;
  • do not overwrite an existing sound/sample solely because its numeric ID looks unused;
  • resolve ROM offsets versus runtime pointers and any bank-relative addressing before patching;
  • preserve existing voice/channel behavior unless the experiment specifically targets it;
  • treat donor IDs and definitions as semantic references, not binary-compatible records;
  • perform a bounded manual runtime test before integrating any new audio path into the normal pipeline.

A successful call to an existing MKMSZ sound does not by itself prove that foreign-sample import is safe; the sample/bank format and lifetime must be validated separately.

Related canonical owners