Fix: ctrl+a to not get stuck waiting on done

This commit is contained in:
Grail Finder
2026-01-11 11:32:55 +03:00
parent fbf4fe1b44
commit 1c818cce86

View File

@@ -87,6 +87,7 @@ type KokoroOrator struct {
Language string Language string
Voice string Voice string
currentStream *beep.Ctrl // Added for playback control currentStream *beep.Ctrl // Added for playback control
currentDone chan bool
textBuffer strings.Builder textBuffer strings.Builder
// textBuffer bytes.Buffer // textBuffer bytes.Buffer
} }
@@ -96,10 +97,12 @@ type GoogleTranslateOrator struct {
logger *slog.Logger logger *slog.Logger
speech *google_translate_tts.Speech speech *google_translate_tts.Speech
currentStream *beep.Ctrl currentStream *beep.Ctrl
currentDone chan bool
textBuffer strings.Builder textBuffer strings.Builder
} }
func (o *KokoroOrator) stoproutine() { func (o *KokoroOrator) stoproutine() {
for {
<-TTSDoneChan <-TTSDoneChan
o.logger.Debug("orator got done signal") o.logger.Debug("orator got done signal")
o.Stop() o.Stop()
@@ -107,6 +110,8 @@ func (o *KokoroOrator) stoproutine() {
for len(TTSTextChan) > 0 { for len(TTSTextChan) > 0 {
<-TTSTextChan <-TTSTextChan
} }
o.currentDone <- true
}
} }
func (o *KokoroOrator) readroutine() { func (o *KokoroOrator) readroutine() {
@@ -274,13 +279,14 @@ func (o *KokoroOrator) Speak(text string) error {
o.logger.Debug("failed to init speaker", "error", err) o.logger.Debug("failed to init speaker", "error", err)
} }
done := make(chan bool) done := make(chan bool)
o.currentDone = done
// Create controllable stream and store reference // Create controllable stream and store reference
o.currentStream = &beep.Ctrl{Streamer: beep.Seq(streamer, beep.Callback(func() { o.currentStream = &beep.Ctrl{Streamer: beep.Seq(streamer, beep.Callback(func() {
close(done) close(done)
o.currentStream = nil o.currentStream = nil
})), Paused: false} })), Paused: false}
speaker.Play(o.currentStream) speaker.Play(o.currentStream)
<-done // we hang in this routine; <-o.currentDone
return nil return nil
} }
@@ -296,14 +302,17 @@ func (o *KokoroOrator) Stop() {
} }
func (o *GoogleTranslateOrator) stoproutine() { func (o *GoogleTranslateOrator) stoproutine() {
for {
<-TTSDoneChan <-TTSDoneChan
o.logger.Debug("orator got done signal") o.logger.Debug("orator got done signal")
o.Stop() o.Stop()
o.currentDone <- true
// drain the channel // drain the channel
for len(TTSTextChan) > 0 { for len(TTSTextChan) > 0 {
<-TTSTextChan <-TTSTextChan
} }
} }
}
func (o *GoogleTranslateOrator) readroutine() { func (o *GoogleTranslateOrator) readroutine() {
tokenizer, _ := english.NewSentenceTokenizer(nil) tokenizer, _ := english.NewSentenceTokenizer(nil)
@@ -397,13 +406,14 @@ func (o *GoogleTranslateOrator) Speak(text string) error {
o.logger.Debug("failed to init speaker", "error", err) o.logger.Debug("failed to init speaker", "error", err)
} }
done := make(chan bool) done := make(chan bool)
o.currentDone = done
// Create controllable stream and store reference // Create controllable stream and store reference
o.currentStream = &beep.Ctrl{Streamer: beep.Seq(playbackStreamer, beep.Callback(func() { o.currentStream = &beep.Ctrl{Streamer: beep.Seq(playbackStreamer, beep.Callback(func() {
close(done) close(done)
o.currentStream = nil o.currentStream = nil
})), Paused: false} })), Paused: false}
speaker.Play(o.currentStream) speaker.Play(o.currentStream)
<-done // wait for playback to complete <-o.currentDone // wait for playback to complete
return nil return nil
} }