Skip to content

Release 2.2.0

Choose a tag to compare

@Gperez88 Gperez88 released this 29 Oct 02:58
· 11 commits to main since this release

🚀 What’s New in 2.2.0

Lets a note keep the noise period and the continuous pulse duty it authored, even when the Nes or Hybrid sound profile would otherwise overwrite them. Curated percussion and custom duty values stay expressible under any profile, and the default output remains byte-identical.

🔊 Note-Pinned Character

  • Noise Period Under NES Profiles: Adds InstrumentPreset::noisePeriodMode with NoisePeriodMode::Note. Nes and Hybrid arm the NES period LUT, which used to retune a noise voice to a one-sample clock; a note can now keep its own noisePeriod, so a kick authored with a 60-sample body stays a kick instead of becoming white hiss.
  • Continuous Pulse Duty: Adds InstrumentPreset::pulseDutyMode with PulseDutyMode::Continuous. A static duty is no longer snapped to one of the four NES patterns, so values a caller can already express, such as 30 % or 20 %, survive the profile.
  • Per Note, Not Per Slot: Both requests resolve on note-on and leave the slot clean, so the next note on that voice gets the profile character again. Neither writes a per-voice override.

🔧 Changed

  • Preset Layout: sizeof(InstrumentPreset) grows from 72 to 76 bytes, entirely from trailing padding. sizeof(AudioChannel), sizeof(AudioCommand), sizeof(AudioEvent) and both sizeof(ApuCore) figures (13,344 host and 13,368 test build) are unchanged, because the two requests reach the character hook as parameters instead of being stored per voice.

🧪 Testing & Tools

  • Character Regression Tests: Adds 13 cases covering the pinned period, the frequency-derived path, no leakage into the next note, a voice pin outranking the note, PULSE-only duty scope and Legacy inertness. test_apu_core moves from 210 to 223 cases.
  • Default-Path Matrix: A 15-scenario comparison against 2.1.0, covering three profiles, both duty and noise paths, nesAccurate and two-note sequences, reproduces identical PCM hashes and identical slot state.
  • Independent Verification: A separate review of the change reported no blockers; the two defects it found are fixed before this release.

📌 Compatibility Notes

  • Default Output Unchanged: With the new fields at their defaults, Legacy, Nes and Hybrid render byte-identical PCM. None of the reference fixtures was regenerated.
  • Source Compatible, Rebuild Required: The fields are appended after envelopeCurve, so existing 17-value positional InstrumentPreset literals keep their meaning. Consumers must rebuild against 2.2.0.
  • Voice Pins Still Win: setVoiceNesNoiseLutMode() and setVoicePulseDutyMode() outrank the note-level request, exactly as they already outrank an animated duty.
  • Consumer Pin: The engine's ^2.0.0 range already resolves 2.2.0 with no manifest change. The Tool Suite needs >= 2.2.0 to use the new fields.