Files
codex/codex-rs/voice-host/Cargo.toml
Benjamin Carlsson a9896da3fe Connect voice-host RTP audio to speaker playback (#43248)
## Why

The voice host drained incoming RTP packets without playing them. Route received audio through decoding and speaker output while preserving speaker suppression boundaries.

## What changed

- Add a GStreamer pipeline with RTP jitter buffering, Opus decoding, conversion, and resampling into the native speaker sink.
- Rebuild playout when the speaker is re-enabled, reject packets received before the new pipeline started, and discard queued audio and echo references on speaker transitions while preserving capture history.
- Limit each receive pass to 64 packets so incoming media cannot indefinitely delay audio controls.
- Prevent retired sink failures from failing a new speaker generation, and retain the last coherent playback delay estimate during callback contention.

## Testing

Add tests for real Opus playback and stale packet rejection, combined microphone mute and speaker suppression, retired sink failures, delay contention, and echo-reference reset without losing capture history.

GitOrigin-RevId: c91c94a2ba2347ac98af4e7fd1dc331ae766cc45
2026-09-06 16:40:33 +00:00

48 lines
1.5 KiB
TOML

[package]
name = "codex-voice-host"
version.workspace = true
edition.workspace = true
license.workspace = true
[[bin]]
name = "codex-voice-host"
path = "src/main.rs"
# These tests need a correctly linked helper and a matching prepared runtime.
# Bazel supplies declared runtime inputs and runs this target automatically.
# Cargo runs it explicitly with --test installed_client.
[[test]]
name = "installed_client"
test = false
[lints]
workspace = true
[dependencies]
codex-process-hardening = { workspace = true }
codex-realtime-webrtc = { workspace = true }
futures = { workspace = true }
libloading = "=0.8.9"
rand = { workspace = true }
rtc = "=0.20.3"
tokio = { workspace = true, features = ["rt-multi-thread", "sync", "time"] }
webrtc = "=0.20.3"
[target.'cfg(any(target_os = "macos", all(target_os = "linux", target_env = "gnu"), all(windows, target_env = "msvc")))'.dependencies]
cpal = "=0.18.2"
crossbeam-queue = "0.3.12"
gstreamer = { version = "=0.25.3", features = ["v1_28"] }
gstreamer-app = { version = "=0.25.2", features = ["v1_28"] }
gstreamer-audio = { version = "=0.25.3", features = ["v1_28"] }
opus = "=0.4.0"
rubato = { version = "=5.0.0", default-features = false }
sonora = { version = "=0.2.0", default-features = false }
[dev-dependencies]
anyhow = { workspace = true }
codex-install-context = { workspace = true }
codex-utils-cargo-bin = { workspace = true }
pretty_assertions = { workspace = true }
tempfile = { workspace = true }
tokio = { workspace = true, features = ["io-util", "macros", "process", "rt-multi-thread", "time"] }