From b2d34475013f7d0d1267d2972066b607d7f9e799 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 3 Oct 2026 14:48:13 +0000 Subject: [PATCH] test(voice): judge pipelined synthesis by what was heard, not by the player's state TestVoiceSpeaksTheFirstSentenceWhileTheRestRenders asked whether the player was busy the moment the second synthesis request arrived. That request leaves as the first piece's audio arrives, before the piece is cleaned and handed to the player, so the answer was a race. clear_voice put a band-pass and a leveller in that gap, and under -race it was wide enough to lose every time on CI. The test now checks that the speakers had not yet heard the whole first piece, which is the claim it exists to make, and it still fails against a speak that renders serially. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01KGraEtxbWFphuCAfsNSYNb --- internal/channel/voice/voice_test.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/internal/channel/voice/voice_test.go b/internal/channel/voice/voice_test.go index 05371ab..ef6cd91 100644 --- a/internal/channel/voice/voice_test.go +++ b/internal/channel/voice/voice_test.go @@ -1550,14 +1550,18 @@ func TestVoiceSpeaksTheFirstSentenceWhileTheRestRenders(t *testing.T) { h.mu.Lock() h.reply = "Claro que sí, ahora mismo lo veo. La respuesta es que mañana llueve por la tarde. Llevá paraguas." h.mu.Unlock() - h.setReplyPCM(make([]byte, playbackRate*2)) // a second of audio per piece, paced in real time + piece := playbackRate * 2 + h.setReplyPCM(make([]byte, piece)) // a second of audio per piece, paced in real time h.start() h.say() h.turn(10 * time.Second) + // The second request leaves as the first piece arrives, before it is + // cleaned and handed to the player, so whether the player has started + // yet is a race; what the speakers had heard of the first piece is not. waitUntil(t, func() bool { return len(h.synthesized()) >= 2 }) - if !h.v.player.busy() { - t.Error("the second piece was requested only after the first had been heard out") + if heard := len(h.speaker.heard()); heard >= piece { + t.Errorf("the second piece was requested only after the first had been heard out (%d of %d bytes)", heard, piece) } want := []string{ "Claro que sí, ahora mismo lo veo.",