summaryrefslogtreecommitdiff
path: root/internal/processor
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-01 21:35:24 +0300
committerPaul Buetow <paul@buetow.org>2026-04-01 21:35:24 +0300
commitf1c9f1a6294033e859641c0b82537aeb2866c69a (patch)
treeb9de3fd006c67cf02d2fd4d3eba439baaf817ff5 /internal/processor
parent5a9e7b4795e08489cfaab264b92cac51bc275d1f (diff)
Honor config audio format for OpenAI
Diffstat (limited to 'internal/processor')
-rw-r--r--internal/processor/processor.go6
-rw-r--r--internal/processor/processor_test.go64
2 files changed, 70 insertions, 0 deletions
diff --git a/internal/processor/processor.go b/internal/processor/processor.go
index a3fc64b..66b975e 100644
--- a/internal/processor/processor.go
+++ b/internal/processor/processor.go
@@ -256,6 +256,12 @@ func (p *Processor) effectiveAudioFormat() string {
return "wav"
}
+ if viper.IsSet("audio.format") {
+ if format := strings.ToLower(strings.TrimSpace(viper.GetString("audio.format"))); format != "" {
+ return format
+ }
+ }
+
if p != nil && p.flags != nil {
if format := strings.ToLower(strings.TrimSpace(p.flags.AudioFormat)); format != "" {
return format
diff --git a/internal/processor/processor_test.go b/internal/processor/processor_test.go
index aa932e5..35ceb9b 100644
--- a/internal/processor/processor_test.go
+++ b/internal/processor/processor_test.go
@@ -471,6 +471,70 @@ func TestGenerateAudioUsesConfiguredGeminiVoiceAndModel(t *testing.T) {
}
}
+func TestGenerateAudioUsesConfiguredAudioFormatWhenOpenAIConfigIsSetOnly(t *testing.T) {
+ originalFactory := newAudioProvider
+ t.Cleanup(func() {
+ newAudioProvider = originalFactory
+ })
+
+ fakeProvider := &fakeAudioProvider{}
+ var capturedConfig *audio.Config
+ newAudioProvider = func(config *audio.Config) (audio.Provider, error) {
+ copyConfig := *config
+ capturedConfig = &copyConfig
+ return fakeProvider, nil
+ }
+
+ originalConfig := viper.New()
+ *originalConfig = *viper.GetViper()
+ defer func() {
+ *viper.GetViper() = *originalConfig
+ }()
+ viper.Reset()
+ viper.Set("audio.provider", "openai")
+ viper.Set("audio.format", "mp3")
+
+ flags := cli.NewFlags()
+ flags.OutputDir = t.TempDir()
+ flags.AudioProvider = "openai"
+ flags.AudioFormat = "wav"
+
+ p := NewProcessor(flags)
+ wordDir := p.findOrCreateWordDirectory("ябълка")
+ if err := p.generateAudioWithVoiceAndFilenameInDir("ябълка", "alloy", "audio", wordDir); err != nil {
+ t.Fatalf("generateAudioWithVoiceAndFilenameInDir() unexpected error: %v", err)
+ }
+
+ if capturedConfig == nil {
+ t.Fatal("expected audio provider config to be captured")
+ }
+ if capturedConfig.OutputFormat != "mp3" {
+ t.Fatalf("captured OutputFormat = %q, want %q", capturedConfig.OutputFormat, "mp3")
+ }
+ if fakeProvider.generateCalls != 1 {
+ t.Fatalf("GenerateAudio() calls = %d, want %d", fakeProvider.generateCalls, 1)
+ }
+ if !strings.HasSuffix(fakeProvider.lastOutputFile, "audio.mp3") {
+ t.Fatalf("GenerateAudio() output file = %q, want mp3 output", fakeProvider.lastOutputFile)
+ }
+
+ metadataData, err := os.ReadFile(filepath.Join(wordDir, "audio_metadata.txt"))
+ if err != nil {
+ t.Fatalf("expected metadata file: %v", err)
+ }
+ metadata := string(metadataData)
+ for _, want := range []string{
+ "provider=openai",
+ "model=gpt-4o-mini-tts",
+ "voice=alloy",
+ "format=mp3",
+ } {
+ if !strings.Contains(metadata, want) {
+ t.Fatalf("metadata = %q, missing %q", metadata, want)
+ }
+ }
+}
+
func TestGenerateAnkiFileUsesEffectiveAudioFormatForGemini(t *testing.T) {
originalConfig := viper.New()
*originalConfig = *viper.GetViper()