From c5a24b2a3f30fe60888702b09e409647616c18d0 Mon Sep 17 00:00:00 2001 From: Grail Finder Date: Sat, 7 Mar 2026 16:37:09 +0300 Subject: [PATCH] Enha: google-tts replay speed --- extra/google_tts.go | 11 +++++++++-- extra/tts.go | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/extra/google_tts.go b/extra/google_tts.go index 5b46f34..782075d 100644 --- a/extra/google_tts.go +++ b/extra/google_tts.go @@ -27,6 +27,7 @@ type GoogleTranslateOrator struct { // text buffer and interrupt flag textBuffer strings.Builder interrupt bool + Speed float32 } func (o *GoogleTranslateOrator) stoproutine() { @@ -141,8 +142,14 @@ func (o *GoogleTranslateOrator) Speak(text string) error { // Wrap in io.NopCloser since GenerateSpeech returns io.Reader (no close needed) body := io.NopCloser(reader) defer body.Close() - // Exactly the same ffplay piping as KokoroOrator - cmd := exec.Command("ffplay", "-nodisp", "-autoexit", "-i", "pipe:0") + // Build ffplay command with optional speed filter + args := []string{"-nodisp", "-autoexit"} + if o.Speed > 0.1 && o.Speed != 1.0 { + // atempo range is 0.5 to 2.0; you might clamp it here + args = append(args, "-af", fmt.Sprintf("atempo=%.2f", o.Speed)) + } + args = append(args, "-i", "pipe:0") + cmd := exec.Command("ffplay", args...) stdin, err := cmd.StdinPipe() if err != nil { return fmt.Errorf("failed to get stdin pipe: %w", err) diff --git a/extra/tts.go b/extra/tts.go index 80085ab..2ddb0ae 100644 --- a/extra/tts.go +++ b/extra/tts.go @@ -60,6 +60,7 @@ func NewOrator(log *slog.Logger, cfg *config.Config) Orator { orator := &GoogleTranslateOrator{ logger: log, speech: speech, + Speed: cfg.TTS_SPEED, } go orator.readroutine() go orator.stoproutine()