-
Notifications
You must be signed in to change notification settings - Fork 0
Implement streaming converter with live latency metrics #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Implement streaming converter with live latency metrics #4
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements a StreamingConverter that eliminates per-chunk file I/O and adds comprehensive live latency monitoring across all interfaces, targeting sub-100ms end-to-end latency for real-time voice conversion.
Key changes:
- Replaces BatchConverter with StreamingConverter as the default backend for real-time conversion, with automatic fallback
- Integrates live latency meters displaying processing time, buffer latency, and total latency in CLI and PipeWire workflows
- Updates default chunk size from 4096 to 2048 samples (~43ms at 48kHz) and adjusts validation bounds to 256-16384 samples
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| rwc/webui.py | Updates UI messages to reflect sub-100ms streaming target and adds --chunk-size 2048 to generated CLI commands |
| rwc/streaming/streaming_backend.py | Implements chunk_duration_ms calculation, updates latency metrics to include capture time, removes unused soundfile import, and revises documentation for sub-100ms targets |
| rwc/streaming/pipeline.py | Enhances metrics aggregation to include buffer health latency in total_latency_ms calculation |
| rwc/streaming/init.py | Updates module documentation to reflect <100ms latency expectation with 2048-sample windows |
| rwc/core/init.py | Adds StreamingConverter as default backend with BatchConverter fallback, implements live latency meter callbacks, adds PipeWire routing flags, adjusts chunk size defaults and validation, and aligns device buffers with processing windows |
| rwc/cli/init.py | Reorganizes imports per style guide, adds --pipewire-source and --pipewire-sink options, updates default chunk size to 2048, and adjusts validation bounds to 256-16384 |
| README.md | Updates documentation to reflect PyAudio/PipeWire dual support, sub-100ms latency targets, live latency readouts, and measured 85-95ms end-to-end performance |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Leave a clean newline after live latency updates | ||
| sys.stdout.write("\n") | ||
| sys.stdout.flush() | ||
|
|
Copilot
AI
Nov 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate code block: Lines 462-464 and 466-468 are identical. Remove one of these duplicate blocks that writes a newline after live latency updates.
| # Leave a clean newline after live latency updates | |
| sys.stdout.write("\n") | |
| sys.stdout.flush() |
| processing_time = (time.perf_counter() - start_time) * 1000 | ||
| self.metrics.processing_time_ms = processing_time | ||
| self.metrics.chunk_latency_ms = processing_time | ||
| # Total chunk latency approximates capture → inference → render |
Copilot
AI
Nov 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential latency calculation issue: Line 260 adds processing_time + chunk_duration_ms to represent "capture → inference → render" latency. However, this may not accurately represent end-to-end latency because:
chunk_duration_msrepresents the time to capture/fill a chunkprocessing_timerepresents inference time- The render/playback time is not included
Adding buffer capture time to processing time is reasonable, but the comment should clarify that render latency is separate and handled by the buffer layer. Consider either:
- Updating the comment to clarify this only covers capture + inference
- Or ensuring the calculation accurately represents what the comment describes
| # Total chunk latency approximates capture → inference → render | |
| # Total chunk latency approximates capture + inference (render/playback latency is handled by the buffer layer) |
Summary
Testing
Codex Task