Also known as: AMBE-3000 packet, DVSI vocoder packet, AMBE-3003 wire format
The AMBE-3003 packet is the serial wire format that carries data to and from a
DVSI AMBE-3000/3003 hardware vocoder chip — the physical DSP device that
encodes and decodes AMBE+2 speech. When GopherTrunk is built to offload
vocoding to such a dongle (behind the dvsi build tag), it speaks this framing over the chip’s
serial link: a fixed sync byte, a length, a type, and a payload.1 The packet framing is the
only part of the hardware path that is pure protocol — no MBE math — so it compiles
unconditionally, while the code that actually drives the chip is gated behind the build tag.
Wire format
The header is four bytes: the sync byte 0x61, a two-byte big-endian length, and a one-byte type.
The length field covers the type byte plus the payload, so a packet with no payload has
length 1, and the full packet on the wire is three header bytes plus the declared length. A decoder
validates the sync byte first, then checks that the buffer length matches the declared length
exactly — trailing bytes are rejected rather than silently accepted, which keeps a byte-stream
resync honest. A SplitPackets helper walks a stream of back-to-back packets and returns the
leftover trailing bytes of an incomplete packet for buffering across the next read, stopping on the
first bad sync so the caller can resync upstream.
Packet types
The one-byte type field names the packet’s purpose:
| Type | Value | Payload |
|---|---|---|
PktControl |
0x00 | configuration / status exchange (sample rate, channel format) |
PktChannelData |
0x01 | one 49-bit AMBE+2 frame, packed in 7 bytes |
PktSpeechData |
0x02 | 160 samples of 16-bit signed PCM (320 bytes, little-endian, 8 kHz) |
PktAck |
0x06 | the chip’s response to a control request |
The two data types are the working pair. A PktChannelData packet carries the compressed
49-bit AMBE+2 frame — from host to chip for synthesis, or from
chip to host for encoding. A PktSpeechData packet carries the decompressed side: one 20 ms voice
frame as 160 samples of little-endian 16-bit PCM at 8 kHz
mono, 320 bytes. Control packets configure the chip and draw an ack in reply.
Why the framing is unconditional
The framing primitives — encode, decode, split — carry no patent surface, because describing a
chip’s serial wire protocol is not the same as implementing the proprietary vocoder algorithm. So
GopherTrunk compiles them into every build, unconditionally, and keeps them unit-testable without
any hardware present. Only the Vocoder that opens the FTDI serial link and streams packets to the
physical chip sits behind //go:build dvsi. This split lets the packet format be reasoned about,
fuzzed, and round-tripped in ordinary CI while the hardware-dependent transport stays optional.
Relevance to SDR
Most GopherTrunk deployments decode AMBE+2 in pure Go and never touch a chip. The AMBE-3003 packet
path exists for the cases where an operator has a DVSI dongle and prefers to offload vocoding to it
— for throughput, for bit-exact conformance against DVSI’s own silicon, or because a build cannot
use the software decoder. In that mode GopherTrunk becomes a packet pump: it pulls 49-bit
AMBE+2 frames out of the P25 Phase 2, DMR, or NXDN bitstream, wraps each
in a PktChannelData packet, and reads back PktSpeechData PCM to feed the audio pipeline. The
framing is small, but it is the contract between GopherTrunk and the hardware, so its length and
sync handling have to be exact.
Sources
-
Digital Voice Systems — Wikipedia, on DVSI, the AMBE vocoder family, and its hardware vocoder products. ↩