1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
package gui
import (
"context"
"math/rand"
"time"
)
// randomVoice picks a random voice from the provided list.
// Used by GenerationOrchestrator for both OpenAI and Gemini voice selection.
func randomVoice(voices []string) string {
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
return voices[rng.Intn(len(voices))]
}
// randomOpenAISpeed picks a random speed in [0.90, 1.00) for OpenAI TTS to
// add slight variation across generations.
func randomOpenAISpeed() float64 {
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
return 0.90 + rng.Float64()*0.10
}
// --- Application delegation methods ---
// Each method delegates to getOrchestrator() so tests that create Application
// directly (setting newAudioProvider / audioConfig / config) continue to work
// without modification, while production code uses the pre-built orchestrator.
// translateWord translates a Bulgarian word to English.
func (a *Application) translateWord(word string) (string, error) {
return a.getOrchestrator().TranslateWord(word)
}
// translateEnglishToBulgarian translates an English word to Bulgarian.
func (a *Application) translateEnglishToBulgarian(word string) (string, error) {
return a.getOrchestrator().TranslateEnglishToBulgarian(word)
}
// generateAudio generates audio for an en-bg card's single audio file.
func (a *Application) generateAudio(ctx context.Context, word, cardDir string) (string, error) {
return a.getOrchestrator().GenerateAudio(ctx, word, cardDir)
}
// generateAudioFront generates the front audio file for a bg-bg card.
func (a *Application) generateAudioFront(ctx context.Context, word, cardDir string) (string, error) {
return a.getOrchestrator().GenerateAudioFront(ctx, word, cardDir)
}
// generateAudioBack generates the back audio file for a bg-bg card.
func (a *Application) generateAudioBack(ctx context.Context, text, cardDir string) (string, error) {
return a.getOrchestrator().GenerateAudioBack(ctx, text, cardDir)
}
// generateAudioBgBg generates audio for both sides of a bg-bg card.
func (a *Application) generateAudioBgBg(ctx context.Context, front, back, cardDir string) (string, string, error) {
return a.getOrchestrator().GenerateAudioBgBg(ctx, front, back, cardDir)
}
// generateAudioFile generates a single audio file using the given voice/speed.
// Kept as a thin wrapper so the fallback tests in generator_test.go can call it.
func (a *Application) generateAudioFile(ctx context.Context, text, outputFile, voice string, speed float64) error {
return a.getOrchestrator().generateAudioFile(ctx, text, outputFile, voice, speed)
}
// generateImagesWithPrompt downloads a single image for a word with optional
// custom prompt and translation hint.
func (a *Application) generateImagesWithPrompt(ctx context.Context, word, customPrompt, translation, cardDir string) (string, error) {
o := a.getOrchestrator()
// Wrap with a UI update callback for the current word's image prompt entry.
promptUI := func(prompt string) {
a.mu.Lock()
isCurrentWord := a.currentWord == word
a.mu.Unlock()
if isCurrentWord && a.imagePromptEntry != nil {
a.imagePromptEntry.SetText(prompt)
}
}
return o.generateImagesWithPromptAndNotify(ctx, word, customPrompt, translation, cardDir, promptUI)
}
|