derive User Shruti
Compute the user's practice shruti from their natural speaking pitch (NSP) and most-recent vocal range, applying the policy from Musicmuni research synthesis (§B7).
If the vocal range span is below rangeThresholdSemitones (default 18), the formula isn't reliable enough — day-to-day range noise is 2–4 st (Bandhopadhyay 2019) and traditional placement needs 7 st floor + 17–19 st headroom (≈26 st ideal). Returns
nspHzwith NSP_NARROW_RANGE.If no vocal range is available at all, returns
nspHzwith NSP_NO_RANGE.At or above the threshold, returns the formula output:
Sa = max(rangeLow + 7, nspMidi − 2)clipped to[rangeHigh − 17, rangeHigh − 12]. Returns VOCAL_RANGE.
If nspHz is null but a wide vocal range is available, the formula degrades to Sa = (rangeLow + 7) clipped to the same headroom band — still produces a usable shruti. If both are null, returns 0 Hz; caller must guard.
Return
UserShrutiDerivation with the target frequency and the source that drove the derivation. Caller maps targetHz to the nearest valid shruti id in their shruti map.
Parameters
User's most-recent NSP measurement, in Hz. Nullable for the edge case where the user took a Range Check before any Speaking Pitch Check.
User's most-recent vocal-range low bound, in Hz.
User's most-recent vocal-range high bound, in Hz.
Span (high − low) in semitones below which the formula falls back to NSP. Default 18.