feat(tracker): panic synth if Inf or NaN, and handle these in detectors

Closes #210.
This commit is contained in:
5684185+vsariola@users.noreply.github.com
2025-10-08 08:53:46 +03:00
parent 167f541a52
commit bdfe2d37bf
3 changed files with 34 additions and 4 deletions

View File

@ -128,7 +128,12 @@ func (p *Player) Process(buffer sointu.AudioBuffer, context PlayerProcessContext
rendered, timeAdvanced, err = p.synth.Render(buffer[:framesUntilEvent], timeUntilRowAdvance)
if err != nil {
p.synth = nil
p.send(Alert{Message: fmt.Sprintf("synth.Render: %s", err.Error()), Priority: Error, Name: "PlayerCrash"})
p.send(Alert{Message: fmt.Sprintf("synth.Render: %s", err.Error()), Priority: Error, Name: "PlayerCrash", Duration: defaultAlertDuration})
}
// for performance, we don't check for NaN of every sample, because typically NaNs propagate
if rendered > 0 && (isNaN(buffer[0][0]) || isNaN(buffer[0][1]) || isInf(buffer[0][0]) || isInf(buffer[0][1])) {
p.synth = nil
p.send(Alert{Message: "Inf or NaN detected in synth output", Priority: Error, Name: "PlayerCrash", Duration: defaultAlertDuration})
}
} else {
rendered = min(framesUntilEvent, timeUntilRowAdvance)
@ -206,6 +211,14 @@ func (p NullPlayerProcessContext) BPM() (bpm float64, ok bool) {
return 0, false // no BPM available
}
func isNaN(f float32) bool {
return f != f
}
func isInf(f float32) bool {
return f > math.MaxFloat32 || f < -math.MaxFloat32
}
func (p *Player) processMessages(context PlayerProcessContext) {
loop:
for { // process new message