mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-08-12 11:49:28 +00:00
Merge pull request #926 from got-feedBack/feat/tuning-midis-followups
tuningMidis follow-ups: NaN/Inf guard in freqs_to_midis + v3 badge adopts exact midis
This commit is contained in:
+4
-2
@@ -101,14 +101,16 @@ def open_midis_to_freqs(midis: list[int], reference_pitch: float = DEFAULT_REFER
|
|||||||
def freqs_to_midis(freqs: list[float], reference_pitch: float = DEFAULT_REFERENCE_PITCH) -> list[int] | None:
|
def freqs_to_midis(freqs: list[float], reference_pitch: float = DEFAULT_REFERENCE_PITCH) -> list[int] | None:
|
||||||
"""Return absolute open-string MIDI notes for frequencies at the supplied
|
"""Return absolute open-string MIDI notes for frequencies at the supplied
|
||||||
A4 reference — the inverse of open_midis_to_freqs. None if any entry is
|
A4 reference — the inverse of open_midis_to_freqs. None if any entry is
|
||||||
non-numeric or non-positive (a provider could hand us anything)."""
|
non-numeric, non-finite, or non-positive (a provider could hand us
|
||||||
|
anything; NaN/Infinity would otherwise raise inside int(round(...)) and
|
||||||
|
500 the /api/tunings endpoint)."""
|
||||||
out: list[int] = []
|
out: list[int] = []
|
||||||
for f in freqs:
|
for f in freqs:
|
||||||
try:
|
try:
|
||||||
f = float(f)
|
f = float(f)
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
return None
|
return None
|
||||||
if f <= 0:
|
if not math.isfinite(f) or f <= 0:
|
||||||
return None
|
return None
|
||||||
out.append(int(round(69 + 12 * math.log2(f / reference_pitch))))
|
out.append(int(round(69 + 12 * math.log2(f / reference_pitch))))
|
||||||
return out
|
return out
|
||||||
|
|||||||
+11
-2
@@ -120,11 +120,20 @@
|
|||||||
if (!r.ok) return;
|
if (!r.ok) return;
|
||||||
const data = await r.json();
|
const data = await r.json();
|
||||||
_tuningsByKey = data.tunings || {};
|
_tuningsByKey = data.tunings || {};
|
||||||
// Build TUNING_NOTE from the first (lowest) string frequency of each tuning.
|
// Build TUNING_NOTE from the lowest string of each tuning. Prefer the
|
||||||
|
// exact integer midis the server now sends (tuningMidis, #829) — the
|
||||||
|
// frequency path reconstructs the note via log2 against a hardcoded
|
||||||
|
// 440 and can land a semitone off at non-440 reference pitches.
|
||||||
|
// Frequencies remain the fallback for older cached responses.
|
||||||
|
const midisByKey = data.tuningMidis || {};
|
||||||
TUNING_NOTE = {};
|
TUNING_NOTE = {};
|
||||||
for (const key of Object.keys(_tuningsByKey)) {
|
for (const key of Object.keys(_tuningsByKey)) {
|
||||||
for (const [name, freqs] of Object.entries(_tuningsByKey[key])) {
|
for (const [name, freqs] of Object.entries(_tuningsByKey[key])) {
|
||||||
if (!(name in TUNING_NOTE) && Array.isArray(freqs) && freqs.length > 0) {
|
if (name in TUNING_NOTE) continue;
|
||||||
|
const midis = midisByKey[key] && midisByKey[key][name];
|
||||||
|
if (Array.isArray(midis) && midis.length > 0 && Number.isFinite(midis[0])) {
|
||||||
|
TUNING_NOTE[name] = NOTE_NAMES[((midis[0] % 12) + 12) % 12];
|
||||||
|
} else if (Array.isArray(freqs) && freqs.length > 0) {
|
||||||
TUNING_NOTE[name] = _freqToNote(freqs[0]);
|
TUNING_NOTE[name] = _freqToNote(freqs[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -275,4 +275,7 @@ def test_freqs_to_midis_rejects_garbage():
|
|||||||
from tunings import freqs_to_midis
|
from tunings import freqs_to_midis
|
||||||
assert freqs_to_midis([82.41, 0]) is None # non-positive
|
assert freqs_to_midis([82.41, 0]) is None # non-positive
|
||||||
assert freqs_to_midis([82.41, "x"]) is None # non-numeric
|
assert freqs_to_midis([82.41, "x"]) is None # non-numeric
|
||||||
|
assert freqs_to_midis([float("nan")]) is None # non-finite (would raise in int(round(...)))
|
||||||
|
assert freqs_to_midis([float("inf")]) is None # non-finite
|
||||||
|
assert freqs_to_midis([float("-inf")]) is None # non-finite
|
||||||
assert freqs_to_midis([]) == [] # vacuously fine
|
assert freqs_to_midis([]) == [] # vacuously fine
|
||||||
|
|||||||
Reference in New Issue
Block a user