Files

49 lines
1.5 KiB
Go

// Copyright (c) 2026 Storm Dragon
// Authors: Storm Dragon, Angus Kola
// SPDX-License-Identifier: GPL-3.0-or-later
package config
import "math"
// RoundSpeechValues keeps speech controls and persisted voices at one decimal
// place without changing the caller's values or turning inheritance into values.
func RoundSpeechValues(settings Settings) Settings {
for _, voice := range []*Voice{&settings.DefaultVoice, &settings.UppercaseVoice, &settings.HyperlinkVoice, &settings.SystemVoice, &settings.EchoVoice} {
for _, field := range []**float64{&voice.Rate, &voice.AveragePitch, &voice.Gain} {
if *field != nil {
value := math.Round(**field*10) / 10
*field = &value
}
}
}
return settings
}
// EffectiveVoice resolves a sparse voice over Default. Uppercase retains the
// established automatic pitch unless overridden or capital pitch is disabled.
func EffectiveVoice(settings Settings, kind string) Voice {
voice := cloneVoice(settings.DefaultVoice)
var override Voice
switch kind {
case "uppercase":
pitch := 7.0
if voice.AveragePitch != nil {
pitch = min(9, max(pitch, *voice.AveragePitch+2))
}
if settings.RaisePitchForCapitals {
voice.AveragePitch = &pitch
}
override = settings.UppercaseVoice
if !settings.RaisePitchForCapitals {
override.AveragePitch = nil
}
case "hyperlink":
override = settings.HyperlinkVoice
case "system":
override = settings.SystemVoice
}
mergeVoice(&voice, cloneVoice(override))
return voice
}