fix(audio): a cancelled announcement really stops; oto's Close is a no-op
Clicking Cancel reached the daemon and the queue cancelled the item, but the sound played on to the end: oto v3's Player.Close only relies on the garbage collector's finalizer, so the player stayed in the mix. Pause takes it out immediately; only the device buffer (about 100 ms) drains. Same fix covers talk cancel and daemon shutdown. Direct speech via spd-say: killing the waiting client did not stop speech-dispatcher either; on cancel it now sends `spd-say -S`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
00eb76128b
commit
a0f91c2d64
2 files changed
+12
-1
No files matched your search
@@ -91,7 +91,12 @@ func (OtoSink) Play(ctx context.Context, data []byte) error {
|
||||
player.Play()
|
||||
for player.IsPlaying() {
|
||||
if err := ctx.Err(); err != nil {
|
||||
player.Close()
|
||||
// Cancel: stop the sound NOW. oto's Close is a no-op that
|
||||
// relies on the garbage collector's finalizer, so a cancelled
|
||||
// announcement would play on to its end; Pause takes the
|
||||
// player out of the mix immediately (only the device buffer,
|
||||
// about 100 ms, drains).
|
||||
player.Pause()
|
||||
return err
|
||||
}
|
||||
if err := player.Err(); err != nil {
|
||||
|
||||
@@ -122,6 +122,12 @@ func (p OSBuiltin) SpeakDirect(ctx context.Context, text, lang string) error {
|
||||
}
|
||||
cmd := exec.CommandContext(ctx, "spd-say", "-w", "-l", lang, text)
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
if ctx.Err() != nil {
|
||||
// Cancelled: killing the waiting client does not stop
|
||||
// speech-dispatcher's output; tell it to stop explicitly.
|
||||
_ = exec.Command("spd-say", "-S").Run()
|
||||
return ctx.Err()
|
||||
}
|
||||
return fmt.Errorf("osbuiltin: spd-say failed: %w: %s", err, bytes.TrimSpace(out))
|
||||
}
|
||||
return nil
|
||||
|
||||
Reference in new issue
Block a user