Skip to content

Add Randomize Music Instruments to Audio Options#6799

Open
jdperos wants to merge 12 commits into
HarbourMasters:developfrom
jdperos:randomize-music-layers
Open

Add Randomize Music Instruments to Audio Options#6799
jdperos wants to merge 12 commits into
HarbourMasters:developfrom
jdperos:randomize-music-layers

Conversation

@jdperos

@jdperos jdperos commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Summary

This adds a new Randomize Music Instruments option to the Audio Editor.

When enabled, music sequence instruments are shuffled within the currently playing song’s sound font. The idea is to make the music sound cursed without going fully off the rails into SFX, drums, or other special sequence modes.

What it does

  • Adds a new Audio Editor checkbox: Randomize Music Instruments
  • Hooks into sequence instrument assignment and swaps normal melodic instruments with other valid instruments from the same sound font.
  • Keeps the shuffle scoped to the main BGM sequence player, so fanfares and other sequence players should not get randomly messed with.
  • Resets the shuffle state when a new main BGM sequence starts.

Implementation notes

The randomizer only remaps normal instrument IDs from 0x00 through 0x7D. IDs 0x7E and above are left alone because those are special sequence modes like drums, etc.

Each sound font gets its own remap table. When an instrument is first used, it lazily picks a replacement from the same font and remembers that choice for the rest of the sequence. This keeps a song internally consistent instead of changing the same instrument every time it appears.

The replacement selection tries to behave more like a shuffle than pure random:

  • It prefers valid instruments from the same font.
  • It avoids reusing the same replacement until all valid replacements are exhausted.
  • It prefers not mapping an instrument to itself.
  • If there are no good candidates, it safely falls back to the original instrument.

There is also a range override hook for sample selection. When instrument A is replaced by instrument B, the replacement still uses A’s pitch range boundaries when choosing low / normal / high samples. This helps avoid cases where the replacement instrument’s native split points cause notes to get routed into weird or missing sample ranges.

Hook changes

This adds two new audio hooks:

  • OnSeqInstrumentSet
  • OnSeqInstrumentGetSound

OnSeqInstrumentSet lets enhancements modify the instrument ID before the audio system resolves it.

OnSeqInstrumentGetSound lets enhancements override which SoundFontSound gets used for a given instrument/semitone pair. The instrument randomizer uses this to preserve the original instrument’s range behavior after remapping.

Memory note

The remap table is static and per-font. Replacement tracking uses a bitset so the “already used” state stays relatively small. No runtime allocation is used in the randomizer path.

Why

Mostly because chaotic music randomization is funny, but keeping it constrained to valid instruments in the same song makes it way more usable than total random noise.

Build Artifacts

@jdperos

jdperos commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author
RandomMusicLayers_Small.mp4

@jdperos

jdperos commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

Note: this option sounds more musical when used together with Experimental Octave Drop

Because instruments are remapped to other sounds in the same sound font, some notes can end up outside the usable pitch range of the replacement sample. When that happens, the audio system can hit the 4x pitch multiplier limit and effectively clamp very high notes instead of playing them at the intended pitch. Experimental Octave Drop helps by pulling those notes back into a playable range while maintaining their musical function.

@jdperos jdperos changed the title Randomize music layers Add Randomize Music Instruments to Audio Options Jun 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant