summaryrefslogtreecommitdiff
path: root/internal/audio
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-01 20:20:04 +0300
committerPaul Buetow <paul@buetow.org>2026-04-01 20:20:04 +0300
commit4f1d809b83c373aa27cd453bd7b3e04ab9719878 (patch)
treeda49fd3c9a73079eaf41d8fcefee24d16b85e8dc /internal/audio
parent4727a188102d8166e4acabc4fd62863245e6cdce (diff)
zg: extract shared audio voice lists
Diffstat (limited to 'internal/audio')
-rw-r--r--internal/audio/provider.go4
-rw-r--r--internal/audio/voices.go46
-rw-r--r--internal/audio/voices_test.go36
3 files changed, 84 insertions, 2 deletions
diff --git a/internal/audio/provider.go b/internal/audio/provider.go
index b961482..334e709 100644
--- a/internal/audio/provider.go
+++ b/internal/audio/provider.go
@@ -26,14 +26,14 @@ type Config struct {
// OpenAI-specific settings
OpenAIKey string
OpenAIModel string // "tts-1", "tts-1-hd", or "gpt-4o-mini-tts"
- OpenAIVoice string // "alloy", "ash", "ballad", "coral", "echo", "fable", "onyx", "nova", "sage", "shimmer", "verse"
+ OpenAIVoice string // One of OpenAIVoices.
OpenAISpeed float64 // 0.25 to 4.0
OpenAIInstruction string // Voice instructions for gpt-4o-mini-tts model
// Gemini-specific settings
GoogleAPIKey string
GeminiTTSModel string // "gemini-2.5-flash-preview-tts"
- GeminiVoice string // Prebuilt Gemini TTS voice name, or empty for the model default
+ GeminiVoice string // One of GeminiVoices, or empty for the model default.
GeminiSpeed float64 // Prompt hint for desired speech speed
}
diff --git a/internal/audio/voices.go b/internal/audio/voices.go
new file mode 100644
index 0000000..9a96c76
--- /dev/null
+++ b/internal/audio/voices.go
@@ -0,0 +1,46 @@
+package audio
+
+// OpenAIVoices lists the OpenAI voices supported by the app.
+var OpenAIVoices = []string{
+ "alloy",
+ "ash",
+ "ballad",
+ "coral",
+ "echo",
+ "fable",
+ "onyx",
+ "nova",
+ "sage",
+ "shimmer",
+ "verse",
+}
+
+// GeminiVoices lists the Gemini prebuilt voices supported by the app.
+var GeminiVoices = []string{
+ "Zephyr",
+ "Puck",
+ "Charon",
+ "Kore",
+ "Fenrir",
+ "Leda",
+ "Orus",
+ "Aoede",
+ "Callirrhoe",
+ "Autonoe",
+ "Enceladus",
+ "Iapetus",
+ "Umbriel",
+ "Algieba",
+ "Despina",
+ "Erinome",
+ "Gacrux",
+ "Pulcherrima",
+ "Achernar",
+ "Rasalgethi",
+ "Laomedeia",
+ "Sadachbia",
+ "Schedar",
+ "Sulafat",
+ "Vindemiatrix",
+ "Zubenelgenubi",
+}
diff --git a/internal/audio/voices_test.go b/internal/audio/voices_test.go
new file mode 100644
index 0000000..121f328
--- /dev/null
+++ b/internal/audio/voices_test.go
@@ -0,0 +1,36 @@
+package audio
+
+import (
+ "reflect"
+ "testing"
+)
+
+func TestVoiceLists(t *testing.T) {
+ t.Parallel()
+
+ tests := []struct {
+ name string
+ got []string
+ want []string
+ }{
+ {
+ name: "openai",
+ got: OpenAIVoices,
+ want: []string{"alloy", "ash", "ballad", "coral", "echo", "fable", "onyx", "nova", "sage", "shimmer", "verse"},
+ },
+ {
+ name: "gemini",
+ got: GeminiVoices,
+ want: []string{"Zephyr", "Puck", "Charon", "Kore", "Fenrir", "Leda", "Orus", "Aoede", "Callirrhoe", "Autonoe", "Enceladus", "Iapetus", "Umbriel", "Algieba", "Despina", "Erinome", "Gacrux", "Pulcherrima", "Achernar", "Rasalgethi", "Laomedeia", "Sadachbia", "Schedar", "Sulafat", "Vindemiatrix", "Zubenelgenubi"},
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
+ if !reflect.DeepEqual(tt.got, tt.want) {
+ t.Fatalf("%s voice list mismatch\nwant: %#v\ngot: %#v", tt.name, tt.want, tt.got)
+ }
+ })
+ }
+}