Skip to content

Fix sonicFlushStream understating duration at low speed - #11

Open
austek wants to merge 1 commit into
espeak-ng:masterfrom
ZirekHQ:fix/slowdown-duration-espeak
Open

Fix sonicFlushStream understating duration at low speed#11
austek wants to merge 1 commit into
espeak-ng:masterfrom
ZirekHQ:fix/slowdown-duration-espeak

Conversation

@austek

@austek austek commented Aug 23, 2026

Copy link
Copy Markdown

Summary

Same bug, same fix as waywardgeek/sonic#74 (which also fixes a second, related upstream report at a less extreme speed) — this repo's sonicFlushStream/processStreamInput are byte-identical to what those had upstream, so the fix ports directly.

sonicFlushStream appends 2*maxRequired samples of silence directly to stream->numInputSamples (giving the pitch-period algorithms enough lookahead to drain whatever's still buffered) but never advances stream->inputPlayTime to match. processStreamInput computes its actual working speed for insertPitchPeriod as numInputSamples * samplePeriod / inputPlayTime — so once the padding inflates numInputSamples without inputPlayTime keeping pace, that computed speed comes out well above the caller's requested speed for the rest of the flush, compressing the tail of real audio (and the silence padding after it) into a far shorter span than it should, and whatever's left over reads back as silence.

Fix

Advance inputPlayTime by the same formula updateNumInputSamples already uses for real writes (numSamples * samplePeriod / speed) when appending the flush padding. A one-line addition.

Tests

Adds tests/slowdown_flush_test.c, verified failing before this fix and passing after.

Test plan

  • cd tests && make runtests && ./runtests — passes, new test included
  • Same build under -fsanitize=address,undefined — no finding from this path; only the separate, already-known findSincCoefficient finding remains

sonicFlushStream appends 2*maxRequired samples of silence directly to
stream->numInputSamples (giving the pitch-period algorithms enough
lookahead to drain whatever's still buffered) but never advances
stream->inputPlayTime to match. processStreamInput computes its
actual working speed for insertPitchPeriod as
numInputSamples * samplePeriod / inputPlayTime -- so once the padding
inflates numInputSamples without inputPlayTime keeping pace, that
computed speed comes out well above the caller's requested speed for
the rest of the flush, compressing the tail of real audio (and the
silence padding after it) into a far shorter span than it should, and
whatever's left over reads back as silence.

Fix: advance inputPlayTime by the same formula
updateNumInputSamples already uses for real writes
(numSamples * samplePeriod / speed) when appending the flush padding.

Adds tests/slowdown_flush_test.c, verified failing before this fix
and passing after.

Ported from waywardgeek/sonic#74, which fixes the same bug (also
present here, byte-identical sonicFlushStream/processStreamInput)
upstream.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant