Files
TS3-vibed/Documentation/Mile_Stones/Milestone_3.md
2026-05-03 10:50:25 +02:00

2.7 KiB

Milestone 3: The First Voice Call (The Connection)

Goal: Successfully transmit compressed voice data to the server and back.

1. Opus Encoder (client_node/audio/codec.rs)

  • Dependencies: Add audiopus.
  • Initialization: Create an audiopus::coder::Encoder with 48,000 Hz, Mono, and Application::Voip. Set the bitrate dynamically or hardcode to 48,000 bps for testing.
  • Encoding Loop: Take the 960-sample f32 chunks from the DSP thread and call encoder.encode_float(). This will output a &[u8] payload of variable length.

2. UDP Transport & Formatting (client_node/network/voice.rs)

  • Packet Assembly: Construct the UDP binary packet. Byte 0-3: SessionToken (from TCP handshake). Byte 4-11: SequenceNumber (incremented every chunk). Byte 12-19: Timestamp (u64). Byte 20+: The Opus payload.
  • Fuzz Testing: Use proptest to aggressively throw random, garbage byte arrays at the UDP packet parser to guarantee it never panics.
  • Socket Binding: Use tokio::net::UdpSocket::bind("0.0.0.0:0").
  • Transmission: Send the assembled binary packet to the server's UDP port at 127.0.0.1:8080.

3. Server Echo Relay (server_node/udp_relay.rs)

  • Socket Setup: tokio::net::UdpSocket::bind("0.0.0.0:8080").
  • Validation Loop: recv_from the socket. Parse the first 4 bytes as u32. Check the DashMap to ensure the SessionToken is valid.
  • Echo Mode: Temporarily, immediately send_to the exact same &[u8] buffer back to the originating client SocketAddr to test the round-trip.
  • Zero-Byte Keep-Alives: Implement client logic to send an empty 0-byte UDP packet every 5 seconds. Server strictly ignores them (used for NAT traversal).

4. Opus Decoder & Playback (client_node/audio/playback.rs)

  • Receiving: Client UDP socket receives the echoed packet. Extract the Opus payload bytes.
  • Decoding: Initialize audiopus::coder::Decoder (48,000 Hz, Mono). Call decoder.decode_float() to retrieve the 960 f32 samples.
  • Playback: Push the 960 samples into a secondary cpal output ringbuffer (The Speaker thread).

5. TCP Auto-Reconnect & UDP Chaos Simulator

  • Auto-Reconnect Logic: Wrap the TCP connection logic in a loop. If the socket drops (read returns 0), tokio::time::sleep(2s) and attempt to reconnect. Send a ReconnectRequest with the existing SessionToken instead of a full AuthRequest.
  • Chaos Simulator UI: In the egui Developer Settings, add a slider for Packet Loss %. Intercept outgoing UDP packets in voice.rs; use rand::thread_rng to randomly drop packets based on the slider value before hitting the socket.