Skip to content

Release 2.3.0

Latest

Choose a tag to compare

@Gperez88 Gperez88 released this 06 Nov 06:29

🚀 What's New in 2.3.0

Gives drums and bass their body back under the NES-derived profiles. Profile value 2 becomes Famicom: the Nes character with the Famicom's output stage, which keeps the low end that the NES 440 Hz high-pass removes. Kick and snare keep the noise period they were authored with, and a new triangle kick brings the classic NES "thump". Legacy and Nes output stays byte-identical.

🎛️ Famicom Profile

  • SoundProfile::Famicom: Replaces Hybrid at value 2. It has the same character as Nes: linear default envelope, ideal saw, the four NES duty patterns, unipolar noise and the NES-weighted mix.
  • Famicom Output Stage: A single 37 Hz high-pass into the same Butterworth low-pass (min(14 kHz, 0.45 fs)), instead of the NES chain's 90 Hz → 440 Hz → LPF.
    • At 65 Hz, Nes attenuates −21.1 dB and Famicom only −1.2 dB.
    • The 440 Hz section is bypassed with a unity pole, so Nes pays nothing extra per sample.
  • Level Trim: Recalibrated with the crest-weighted heuristic: 31765 (−0.27 dB). W lands within 0.001 dB of Legacy, and the RMS is now only 0.31 dB below it, instead of 2.4 dB.

🥁 Drums and Bass

  • Kick and Snare Keep Their Body: INSTR_KICK and INSTR_SNARE use NoisePeriodMode::Note, so under Nes/Famicom they keep periods 60 and 15 instead of collapsing to the one-sample hiss of NES LUT index 0.
  • Authentic NES Hi-Hat: INSTR_HIHAT keeps the profile default and takes NES LUT index 0, the bright hat NES games use.
  • INSTR_KICK_TRI: A new triangle kick. On a TRIANGLE track it sweeps from 196 Hz (G3, the default octave) to 50 Hz in 45 ms, with a short decay. Double it with a NOISE hit on the same beat for the attack.

🔧 Changed

  • Linear Default Envelope Everywhere: No profile defaults to the exponential curve any more. A note can still ask for EnvelopeCurve::Exponential.
  • Band-Limited Saw Is Dormant: No profile selects the mipmapped saw now. AudioOscMipLUT.h and its read path are kept until a decision is made: remove it, or expose it as a per-voice option.
  • Fixtures: apu_famicom_canonical and apu_famicom_wavetable replace the apu_hybrid_* pair.

🧪 Testing & Tools

  • New Coverage:
    • The Famicom output-stage response at 8 kHz, 22.05 kHz, 44.1 kHz and 48 kHz.
    • Low-end attenuation for Nes and Famicom.
    • Character parity between Nes and Famicom.
    • Drum periods under every profile.
    • The triangle-kick sweep.
    • test_apu_hybrid_wavetable becomes test_apu_famicom_saw.
    • 616 cases across 16 targets.
  • Tools: golden_gen and profiles_ab accept famicom, with hybrid kept as an alias.
  • Hardware Listening: The engine's apu_profiles example was built for esp32dev against this release and compared by ear on the board.

📌 Compatibility Notes

  • Hybrid Is Deprecated, Not Removed: SoundProfile::Hybrid is an alias of Famicom (same value 2). Existing code compiles with a deprecation warning.

  • Profile 2 Sounds Different: Content authored for Hybrid now gets:

    • a linear envelope;
    • the ideal saw;
    • the 37 Hz output stage;
    • a lower trim: +1.90 dB → −0.27 dB.

    Use Nes for the old NES output stage, or set EnvelopeCurve::Exponential on a note for the exponential curve.

  • Default Output Unchanged for Legacy and Nes: Their fixtures were not regenerated and reproduce byte for byte.

  • Not Measured on Boards: Famicom's CPU cost was not measured on hardware. It is expected to match Nes, because the per-sample work is identical.

  • Consumer Pin:

    • The engine's ^2.0.0 range already resolves 2.3.0.
    • Code that names SoundProfile::Famicom or INSTR_KICK_TRI needs >= 2.3.0.