2.7 KiB
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::Encoderwith48,000 Hz,Mono, andApplication::Voip. Set the bitrate dynamically or hardcode to48,000 bpsfor testing. - Encoding Loop: Take the 960-sample
f32chunks from the DSP thread and callencoder.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
proptestto 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_fromthe socket. Parse the first 4 bytes asu32. Check theDashMapto ensure theSessionTokenis valid. - Echo Mode: Temporarily, immediately
send_tothe exact same&[u8]buffer back to the originating clientSocketAddrto 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). Calldecoder.decode_float()to retrieve the 960f32samples. - Playback: Push the 960 samples into a secondary
cpaloutput 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 (readreturns 0),tokio::time::sleep(2s)and attempt to reconnect. Send aReconnectRequestwith the existingSessionTokeninstead of a fullAuthRequest. - Chaos Simulator UI: In the
eguiDeveloper Settings, add a slider forPacket Loss %. Intercept outgoing UDP packets invoice.rs; userand::thread_rngto randomly drop packets based on the slider value before hitting the socket.