Skip to content
acarteron edited this page May 29, 2026 · 4 revisions

Voicetastic Voice Protocol — Wiki

Practical, navigable documentation for the Voicetastic Voice Protocol — voice messaging over the Meshtastic mesh.

The normative wire-format spec lives in VOICE_PROTOCOL.md. This wiki is the implementer-friendly companion: it explains the why, walks through frames byte-by-byte, and provides recipes for senders and receivers.

Protocol version: 3 (wire byte 0x03)Reference impl: crates/voicetastic-core/src/voice/


Pages

Page Purpose
Overview What the protocol does, design goals, non-goals.
Frame Format Byte-level walkthrough of header + body for every type.
Reliability — FEC and NACK How loss recovery works, end-to-end.
Encryption Why this layer no longer carries an AEAD envelope (V3).
Sender Guide How to build a compatible transmitter.
Receiver Guide How to build a compatible reassembler.
Constants and Limits All numeric ceilings in one place, with rationale.
Error Catalogue Every VoiceError variant and when it fires.
Settings Client-side persisted settings (codec, bitrate, …).
Glossary Term definitions; read first if jargon trips you up.

Quick start

  1. Pick a codec. The protocol carries opaque bytes; any narrowband codec works. AMR-NB is the reference choice (see Sender Guide).
  2. Encode your audio. Strip codec container headers (e.g. #!AMR\n) — the wire only carries raw codec frames.
  3. Send. Build a VoiceSender once per MeshService, then call VoiceSender::send with a SendRequest. The sender owns build → burst → NACK → retransmit → linger; consume SendStatus events from the returned handle.
  4. Receive. On the other side, feed each PRIVATE_APP payload to VoiceAssembler::accept; call tick() every ~100 ms to drive timeouts and NACKs.

Status

  • ✅ Builder, assembler, FEC, NACK construction & parsing.
  • ✅ Receiver-driven NACK transmission.
  • ✅ Sender-side state machine: VoiceSender owns build → register → burst → NACK → retransmit → linger as a single shared pipeline; CLI / GUI / Android frontends just submit a SendRequest and consume SendStatus events. See the Sender Guide.

See TODO.md for the wider roadmap.

Clone this wiki locally