Skip to content

OPM.js v1.13.1

Latest

Choose a tag to compare

@YueyuHoshizora YueyuHoshizora released this 24 Oct 01:06
· 10 commits to main since this release

Package version 1.13.1, a GitHub release (not on npm), CI-verified on Node 22/24/26, Chromium, Firefox and WebKit. Voice format v8. Explicit v1–v7 voices keep their original shapes and normalize to v8; voices that use none of the new fields render bit-identically (all 21 previous presets × eco/standard/high × MIDI 36/60/84 match v1.13.0 sample for sample). No worklet protocol changes beyond accepting the new fields through the existing validators.

Voice format v8

  • Sustain rate adsr.sr (optional, 0.01–100 s): after attack and decay, a held note keeps falling 96 dB per sr seconds (dB-linear), clamps at the −96 dB floor and then outputs exact zero until release; the release starts from the decayed level. Omitted holds the sustain level as before. Rate key scaling applies, capped at 100 s. Live operatorADSR edits and envelopeAt accept it. This is the held-note decay of OPM-style D2R, for pianos, plucks and bells that fade while held.
    • The renderer treats it as one more geometric envelope segment, with the same 64-frame exact re-anchoring and segment-end fast path as attack, decay and release, so output stays chunk independent.
  • LFO waveform: 'noise': sample-and-hold. Each LFO cycle holds one pseudo-random level in [−1, 1) from a stateless integer hash of the cycle index, so offline, chunked and sync: 'global' renders are reproducible; sync: 'note' restarts the same sequence per note. lfoValue(phase, 'noise') matches it.
  • Voice pan (optional, −1..1): a patch-level stereo offset added to each note's pan, clamped to −1..1 before the equal-power law. Canonical JSON places it between modIndex and lfo and omits it when absent.
  • v1–v7 inputs reject all three fields. Strict parsing rejects out-of-range values; bank parsing clamps them, as for every other field. The JSON Schema is now "canonical voice v8".

Importers

  • .opm: nonzero D2R now maps to adsr.sr on the same heuristic curve as the other rates (previously dropped), and LFO waveform 3 maps to the noise LFO (previously sine). PAN is still ignored: converters commonly write a fixed default (64) instead of the register L/R bits, so the field does not reliably encode placement.
  • DX7: the sample-and-hold LFO maps to the noise LFO (previously sine).

Presets and examples

  • Two original presets: struck_keys (held notes fade through sustain rates, modulators faster than carriers) and stepped_lead (7 Hz global noise-LFO AM on the modulators steps brightness). Existing presets carry version: 8 labels with unchanged parameters.
  • The sound-design page adds per-operator sustain rate, voice pan and the noise LFO; patch import/export is v8. The sequence page offers the noise LFO.
  • The sequence page exposes the v1.12 output-stage settings: an Output stage choice (saturation: 'tanh' | 'soft-knee') and a DC blocker checkbox (dcBlock), applied to live playback, offline WAV, chunked and Worker renders and recorded in its acceptance settings.

Documentation

  • README, the English and 繁體中文 usage guides now point installation and checkout at this release instead of the v1.10 archive. The Roadmap gains v1.12 and v1.13 entries.