AudioFrame carries a single packet of voice — typically 20 ms of µ-law or PCM. It uses the same envelope as every other RPC, but it travels on uni-streams. Uni-streams keep latency low and do not pair every send with an ack.

AudioFrame schema

method_id for an audio frame is always 2991054320 (0xb241_b9b0).

Frame layout on the wire

This is the standard envelope format. Audio is not special.

Outbound (your mic → trunk)

Open exactly one client-initiated unidirectional stream per call. Write framed AudioFrames back-to-back on it. Do not open a stream per packet. That overwhelms the gateway’s flow-control budget within seconds.
After end_of_stream = true, close the stream. The gateway will not accept more frames on it.

Pacing

For µ-law @ 8 kHz with a 20 ms ptime, payload = 160 bytes. Send one frame every 20 ms (50 fps). If you pace faster, the trunk buffers the audio, and it arrives late on the far end. If you pace slower, audible gaps occur.

Inbound (trunk → your speaker)

The gateway opens server-initiated uni-streams. After your EventStreamRequest subscription, every uni-stream is multiplexed. Each frame’s method_id tells you whether the frame is audio (2991054320) or a CallEvent (959835745). A typical demuxer:

Codec choices

The gateway transcodes for you on ingress. On egress, it sends the codec that the far end negotiated. If you need a specific egress codec, set OriginateRequest.default_app_args accordingly.

Loss handling

Use sequence_number to detect dropped packets. The gateway does not retransmit audio, because retransmission defeats latency. For PSTN calls, each missing sequence number on egress is heard as 20 ms of silence. This is acceptable for voice but catastrophic for DTMF. Therefore, use INFO-method DTMF rather than in-band tones when possible.