# Native WebRTC voice validation The `libremetaverse-voice-webrtc` native API owns the complete WebRTC voice path. `WebRtcVoiceSession::connect` binds a caller-selected interface, creates an Opus send/receive m-line and ordered `SLData` channel, posts the grid's provision body through a `VoiceSignaling` implementation, applies the SDP answer, and drives ICE, DTLS, SRTP, RTP, and SCTP from a single async run loop. There is no CLR, C# process, RPC bridge, proprietary SDK, or platform-specific fallback. The grid wire shapes match the viewer protocol: - Initial provisioning uses `jsep.type=offer`, `channel_type=local`, and `voice_server_type=webrtc`, with an optional top-level `parcel_local_id`. - ICE completion uses the singular `candidate: { completed: true }` field and the opaque viewer-session ID. - Teardown sends `logout=true`, then disconnects and joins the local peer loop. Capability URLs, SDP, channel credentials, login secrets, and viewer-session credentials are not printed. `VoiceSecret` always formats as ``. Incoming SDP and `SLData` messages are bounded and validated before use. ## Deterministic validation `webrtc-test --fake` is the CI path. `LoopbackSignaling` accepts the real offer, creates a second native peer, and exchanges UDP ICE checks, DTLS, encrypted Opus RTP, and SCTP `SLData` on loopback. It publishes peer audio/position and mute/gain maps; the client replies with join, mute, clamped gain, position, ping/pong, and leave. A generated virtual 48 kHz tone is encoded with libopus, echoed by the remote peer, decoded into the virtual sink, and counted. Shutdown awaits both peers and reports zero peer/audio tasks. WAV playback accepts bounded integer or float PCM, downmixes all channels, linearly resamples to 48 kHz mono, encodes 20 ms Opus frames, and paces them on the same peer loop. This keeps virtual-audio tests deterministic and prevents orphan playback tasks. ## Native prerequisites The default virtual path requires native libopus development files at build time. Typical packages are: - Ubuntu/Debian: `libopus-dev` (and `pkg-config`). - Fedora: `opus-devel`. - Windows MSVC: `audiopus` supplies supported prebuilt Opus libraries; a custom libopus can be selected with `OPUS_LIB_DIR`/`LIBOPUS_LIB_DIR`. - macOS: install `opus` with the system package manager when it is not already discoverable by `pkg-config`. Real hardware is separately opt-in. Build the program with `--features real-audio`; CPAL uses ALSA on Linux, WASAPI on Windows, and CoreAudio on macOS. Linux builders need ALSA development headers (for example `libasound2-dev`). List stable endpoint IDs with `webrtc-test --list-devices`, then pass `--input-device cpal:input:...` and/or `--output-device cpal:output:...`. Selected capture and render streams are opened only during the session and dropped after the peer loop is joined. ## Live grid gate Credential-only capability validation: ```sh webrtc-test --allow-live-login --confirm-live-login LOGIN ``` The command reads `GRID_USER="First Last"`, `GRID_PASSWORD`, and `GRID_LOGIN_URL` from the process environment or the workspace `.env`, matching the compatibility-test convention. Positional names/password and the legacy `GRID_FIRST_NAME`/`GRID_LAST_NAME` pair remain supported. Merely having a credential file never permits a login: both command-line confirmations above are still mandatory. Creating a live voice session and sending/receiving media requires the separate `--allow-session-audio` flag. `--bind-ip` can select the concrete interface advertised in the host ICE candidate; otherwise the program discovers the preferred route without sending a packet. `--wav FILE` starts looping microphone playback. Interactive commands preserve the upstream tool's `peers`, `mute`, `gain`, `playwav`, `stopwav`, and `quit` controls; `--commands FILE` supplies the same commands non-interactively. Grid logout and voice teardown run even when the validation body fails.