@maruaudio/dsp/math/scale snaps a fractional MIDI pitch to the nearest note of a key and scale. Fourteen scales are static 12-bit interval masks (chromatic, major, the three minors, two pentatonics, blues, the four other church modes and whole tone) mirroring @maruaudio/music-theory. A key rotates the mask to absolute pitch classes, an absolute enable mask removes notes, and a reference A sets the Hz conversion 69 + 12 × log2(hz / ref). The stateful quantizer holds its note with midpoint hysteresis; an empty allowed set passes the pitch through.
Parameters
configureScaleQuantizer(state, key, scale, enableMask, referenceHz, hysteresisCents) sets all five at once, at control rate.
| Argument | Range as coded | Default from init | Unit |
|---|---|---|---|
key | Rounded, wrapped to 0..11 (0 = C) | 0 | pitch class |
scale | Rounded; outside 0..13 or NaN → chromatic | SCALE_CHROMATIC | scale id |
enableMask | Rounded, & 4095 | 4095 (all) | absolute pitch-class bits |
referenceHz | Below 400 → 400, above 480 → 480, NaN → 440 | 440 | Hz |
hysteresisCents | 0 to 50; NaN → 0 | 20 | cents |
Lifecycle
initScaleQuantizer() → configureScaleQuantizer → quantizeScaleMidi or quantizeScaleHz, normally once per detector hop → resetScaleQuantizer, which forgets the held note. Stateless helpers (scaleIntervalMask, scalePitchClassMask, nearestAllowedMidi, hzToMidi, midiToHz, isNoteAllowed, pitchClassOf) need no state.
When to use it
Pitch correction and automatic carriers, where a detected voice pitch should land on a scale note without flickering between two neighbours. @maru/modulation-retune, @maru/voices-chord-voicing, @maru/voices-chord-colour and @maru/math-ring-stack build on it (pitch and harmony).
Limits
- A held note stays until another allowed note is closer by more than twice the hysteresis; a held note the new mask disallows is dropped on the next call.
- A negative or NaN MIDI pitch, or 0 Hz or less, is unvoiced: it releases the held note and returns −1 (or 0 Hz).
nearestAllowedMidisearches ±6 semitones from the rounded pitch; a tie goes to the rounded note when allowed, otherwise downward.- Unknown ids passed to
scaleIntervalMaskreturn the chromatic mask.