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,16 +97,20 @@ 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() {
<-TTSDoneChan for {
o.logger.Debug("orator got done signal") <-TTSDoneChan
o.Stop() o.logger.Debug("orator got done signal")
// drain the channel o.Stop()
for len(TTSTextChan) > 0 { // drain the channel
<-TTSTextChan for len(TTSTextChan) > 0 {
<-TTSTextChan
}
o.currentDone <- true
} }
} }
@@ -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,12 +302,15 @@ func (o *KokoroOrator) Stop() {
} }
func (o *GoogleTranslateOrator) stoproutine() { func (o *GoogleTranslateOrator) stoproutine() {
<-TTSDoneChan for {
o.logger.Debug("orator got done signal") <-TTSDoneChan
o.Stop() o.logger.Debug("orator got done signal")
// drain the channel o.Stop()
for len(TTSTextChan) > 0 { o.currentDone <- true
<-TTSTextChan // drain the channel
for len(TTSTextChan) > 0 {
<-TTSTextChan
}
} }
} }
@@ -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
} }