Make the first streaming audio packet configurable - #22
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #20.
QwenTTS.stream()now yields a four-frame first packet by default (320 ms of audio), configurable withfirst_chunk_frames=1,2,4, or8. Later packets independently usecodec_chunk_sec, rounded to codec frames, defaulting to 0.64 seconds / eight frames to match the native steady-state width. Explicit values remain configurable. The complete default sequence, including its short tail, has a regression test. Successful completion flushes a short tail; errors and cancellation discard unfinished packets.The pinned native decoder ignores streaming
codec_chunk_secand emits a fixed 1→2→4→8-frame ramp. This change assembles Python packets from those callbacks without changing the native revision or ctypes ABI. It does not change native callback scheduling: the four-frame first packet waits until seven native frames have arrived, and the eight-frame packet waits until fifteen. The README documents this latency limit and separate native-callback versus Python-packet profiling fields.Adds a repeatable local benchmark and focused tests for exact packet boundaries, independent later sizing, PCM preservation after native buffers are reused, short utterances, failure propagation, repeated streaming, and cancellation.
Validation on Apple M3 Pro / Metal, macOS 26.6.2, Python 3.12.13:
The actual API defaults were also tested on Metal without either packet-size argument: after warm-up, two default runs and two explicit
codec_chunk_sec=1.0runs produced identical PCM (220,800 samples / 115 frames). Per-packet arrival times gave largest calculated gaps of 65–85 ms with the default eight-frame later packets, versus 438–557 ms with thirteen-frame packets. Default first yields were 420–439 ms. This calculation assumes immediate continuous playback from the first packet; it is not a listening test or a guarantee of gap-free playback.No version bump, native libraries, model weights, or build artifacts are included.