Commit Graph

465 Commits

Author SHA1 Message Date
Siavash Sameni
3f128936c4 feat: web bridge — browser-based voice calls via WebSocket
New wzp-web crate serves a web page with:
- Browser mic capture via Web Audio API (48kHz mono)
- WebSocket transport for raw PCM audio
- Server-side Opus encode/decode + FEC through wzp relay
- Real-time audio playback in browser
- Level meter and connection stats

Usage:
  wzp-relay --listen 0.0.0.0:4433    # start relay
  wzp-web --port 8080 --relay 127.0.0.1:4433  # start web bridge
  Open http://localhost:8080 in browser

Two browsers connected to the same relay get bridged for a call.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 18:23:39 +04:00
Siavash Sameni
bddcfb1440 fix: remove unused variable warning in cli.rs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 18:15:09 +04:00
Siavash Sameni
a04b8271cc fix: record mode decode-per-packet (same fix as live mode)
The --record recv loop was using while-drain which exhausted the jitter
buffer and stopped decoding after the first burst. Now decodes once per
source packet, matching the live mode fix.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 18:05:10 +04:00
Siavash Sameni
d5390db7af feat: --send-file for real audio testing + fix warnings
- --send-file <file.raw> sends a raw PCM file (48kHz mono s16le) through relay
- Combine with --record: --send-file talk.raw --record echo.raw <relay>
- Fixed all unused import warnings in echo_test.rs

Convert any audio to test format:
  ffmpeg -i input.mp3 -ar 48000 -ac 1 -f s16le input.raw

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:51:55 +04:00
Siavash Sameni
28d5a3a9ad feat: automated echo quality test with time-window analysis
New --echo-test <secs> flag sends a 440Hz tone through relay echo,
records the return, and analyzes quality in 5-second windows:
- Per-window: frames sent/received, loss %, SNR (dB), correlation
- Detects quality degradation over time (compares first vs second half)
- Reports jitter buffer stats (depth, lost, late packets)
- Diagnoses jitter buffer drift and packet loss accumulation

Also exposes jitter_stats() on CallDecoder for diagnostics.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:44:08 +04:00
Siavash Sameni
26ed015cca feat: relay bridge mode — pairs two clients for real calls
When no --remote is configured, the relay now operates in bridge mode:
- First client connects → echoes while waiting for a peer
- Second client connects → both clients are bridged bidirectionally
- A's packets go to B, B's packets go to A
- Stats logged every 5 seconds (a_to_b / b_to_a packet counts)
- Falls back to echo if only one client connects

This enables the core use case: two clients on different networks
calling each other through a single relay.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:21:12 +04:00
Siavash Sameni
0723f52d76 fix: live audio playback working — jitter buffer and decode loop fixes
- Reduced jitter buffer min_depth from 25 (500ms) to 3 (60ms) for fast start
- Fixed live recv loop: decode once per source packet instead of draining
  the jitter buffer dry (which advanced seq past future packets)
- Fixed Ok(None) handling: connection closed, not "no packet yet"

Live echo test confirmed working with continuous audio.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:09:33 +04:00
Siavash Sameni
b147de5ae9 fix: graceful Ctrl+C recording + relay echo mode
- --record now handles Ctrl+C: saves PCM file before exiting
- Relay without --remote runs in echo mode (loops packets back to sender)
  instead of sink mode, enabling single-relay audio testing
- recv task returns collected PCM via channel for clean file write

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:32:12 +04:00
Siavash Sameni
df80ad5343 fix: make cpal/ALSA optional — headless Linux builds work without libasound
- cpal is now behind an 'audio' feature flag (off by default)
- --live mode requires --features audio at build time
- --send-tone and --record work on headless servers without audio libs
- Linux build script no longer installs libasound2-dev

Build for headless: cargo build --release
Build with mic/speakers: cargo build --release --features audio

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:24:44 +04:00
Siavash Sameni
708fb268bc feat: file-based audio testing + Hetzner build scripts
CLI modes:
- --send-tone <secs>: send 440Hz test tone (no mic needed)
- --record <file.raw>: save received audio to raw PCM file
- --help: usage info
- Combine: --send-tone 10 --record out.raw

Raw PCM format: 48kHz mono s16le
Play with: ffplay -f s16le -ar 48000 -ac 1 out.raw

Build scripts:
- scripts/build-linux.sh: Hetzner VPS build with auto-cleanup
- scripts/cleanup-builder.sh: kill stale builders

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:11:59 +04:00
Siavash Sameni
85f472d824 fix: scale FEC ratio with loss rate in benchmarks
The bench tool now auto-calculates the FEC ratio needed to survive
the requested loss percentage, matching how the adaptive quality
controller would behave in production.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:21:21 +04:00
Siavash Sameni
3c99503eb1 fix: IPv6 support, client address family matching, gitignore cleanup
- Client auto-detects IPv4/IPv6 from relay address and binds accordingly
- Relay defaults to 0.0.0.0:4433, use --listen [::]:4433 for IPv6
- .gitignore excludes .claude/, swap files
- Fix pipeline drain infinite loop in benchmarks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:17:49 +04:00
Siavash Sameni
79f9ff1596 feat: Phase 3 — crypto handshake, codec2, benchmarks, audio I/O, relay forwarding
E2E crypto handshake:
- Client/relay handshake via SignalMessage (CallOffer/CallAnswer)
- X25519 ephemeral key exchange with Ed25519 identity signatures
- Integration tests proving bidirectional encrypt/decrypt

Codec2 integration:
- Pure Rust codec2 crate (v0.3) — no C bindings needed
- MODE_3200 (160 samples/20ms, 8 bytes) and MODE_1200 (320 samples/40ms, 6 bytes)
- 11 new tests including encode/decode roundtrip and adaptive switching

Relay forwarding:
- Bidirectional client → remote forwarding with pipeline processing
- CLI args: --listen, --remote
- Periodic stats logging, clean shutdown via tokio::select!

Benchmark tool (wzp-bench):
- Codec roundtrip, FEC recovery, crypto throughput, full pipeline benchmarks
- Sine wave PCM generator for realistic testing

Audio I/O (cpal):
- AudioCapture (microphone) and AudioPlayback (speakers) at 48kHz mono
- CLI --live mode: mic → encode → send / recv → decode → speakers

120 tests passing, 0 failures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 13:43:22 +04:00
Siavash Sameni
43d7f70fe9 feat: Phase 2 — relay daemon and client library with integration pipelines
wzp-relay:
- RelayPipeline: ingest → FEC decode → jitter buffer → FEC encode → send
- SessionManager: tracks active calls, idle expiry
- RelayConfig: TOML-based configuration
- Binary: accepts QUIC connections, receives media packets

wzp-client:
- CallEncoder: mic PCM → Opus encode → FEC → MediaPackets
- CallDecoder: MediaPackets → FEC decode → jitter → Opus decode → PCM
- CLI binary: connects to relay, sends test silence frames

99 tests passing across all 7 crates.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 13:08:33 +04:00
Siavash Sameni
51e893590c feat: WarzonePhone lossy VoIP protocol — Phase 1 complete
Rust workspace with 7 crates implementing a custom VoIP protocol
designed for extremely lossy connections (5-70% loss, 100-500kbps,
300-800ms RTT). 89 tests passing across all crates.

Crates:
- wzp-proto: Wire format, traits, adaptive quality controller, jitter buffer, session FSM
- wzp-codec: Opus encoder/decoder (audiopus), Codec2 stubs, adaptive switching, resampling
- wzp-fec: RaptorQ fountain codes, interleaving, block management (proven 30-70% loss recovery)
- wzp-crypto: X25519+ChaCha20-Poly1305, Warzone identity compatible, anti-replay, rekeying
- wzp-transport: QUIC via quinn with DATAGRAM frames, path monitoring, signaling streams
- wzp-relay: Integration stub (Phase 2)
- wzp-client: Integration stub (Phase 2)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 12:45:07 +04:00