summaryrefslogtreecommitdiff
path: root/internal/gui/voice_selector.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/gui/voice_selector.go')
-rw-r--r--internal/gui/voice_selector.go48
1 files changed, 48 insertions, 0 deletions
diff --git a/internal/gui/voice_selector.go b/internal/gui/voice_selector.go
new file mode 100644
index 0000000..7c7d4c7
--- /dev/null
+++ b/internal/gui/voice_selector.go
@@ -0,0 +1,48 @@
+package gui
+
+import (
+ "strings"
+
+ "codeberg.org/snonux/totalrecall/internal/audio"
+)
+
+// VoiceSelector picks voice and speed for a generation run from an
+// AudioConfigResolver. For Gemini with a pinned voice the configured voice is
+// used; otherwise a random voice is selected from the available list.
+type VoiceSelector struct {
+ resolver *AudioConfigResolver
+}
+
+// NewVoiceSelector constructs a VoiceSelector backed by the given resolver.
+func NewVoiceSelector(resolver *AudioConfigResolver) *VoiceSelector {
+ return &VoiceSelector{resolver: resolver}
+}
+
+// VoiceAndSpeed selects the voice and speed for a generation run.
+func (v *VoiceSelector) VoiceAndSpeed() (string, float64) {
+ switch v.resolver.ProviderName() {
+ case "gemini":
+ if v.resolver.audioConfig != nil {
+ if voice := strings.TrimSpace(v.resolver.audioConfig.GeminiVoice); voice != "" {
+ return voice, v.GeminiSpeed()
+ }
+ }
+ return randomVoice(v.resolver.Voices()), v.GeminiSpeed()
+ default:
+ return randomVoice(v.resolver.Voices()), randomOpenAISpeed()
+ }
+}
+
+// GeminiSpeed returns the configured Gemini TTS speed or the default.
+func (v *VoiceSelector) GeminiSpeed() float64 {
+ if v.resolver.audioConfig != nil && v.resolver.audioConfig.GeminiSpeed > 0 {
+ return v.resolver.audioConfig.GeminiSpeed
+ }
+ return audio.DefaultProviderConfig().GeminiSpeed
+}
+
+// GeminiVoicePinned reports whether a specific Gemini voice is locked in
+// config, meaning fallback voice selection should be skipped.
+func (v *VoiceSelector) GeminiVoicePinned() bool {
+ return v.resolver.audioConfig != nil && strings.TrimSpace(v.resolver.audioConfig.GeminiVoice) != ""
+}