Skip to content

Jitter

Per-SSRC jitter buffer for the voice receive pipeline.

Holds incoming Opus packets indexed by RTP sequence number and replays them at a steady 20ms rate after an initial four-frame delay. Gaps in the sequence are filled via FEC (if the next packet is already buffered) or Opus PLC, so the consumer always receives a continuous PCM stream.

The tick loop uses clock-anchored absolute deadlines to prevent timing drift over long calls. If the speaker stops talking and resumes (VAD silence gap), the buffer detects the discontinuity and resyncs automatically.

Jitter.packets  :: {
{ [number]: buffer } }
Jitter.nextSequence  :: number
Jitter.stopped  :: boolean
Jitter.clockAnchor  :: number
Jitter.tickCount  :: number
Jitter.thread  :: thread?
Jitter.decoder  :: Decoder
Jitter : push ( sequence packet )  -> ()

Inserts an Opus packet for the given RTP sequence number. Packets that have already been played or are implausibly far ahead are silently discarded. Detects VAD silence gaps and resyncs the buffer.

Parameters

sequence: number
packet: buffer
Jitter : start ( onRawFrame onPcmFrame )  -> ()

Starts the 20ms tick loop. Fires onRawFrame(sequence, packet) when a packet was present in the buffer, and onPcmFrame(pcm) for every slot whether a packet was present or not, filling gaps with FEC from the next buffered packet or Opus PLC.

Parameters

onRawFrame: (sequence: number, packet: buffer) -> ()
onPcmFrame: (pcm: buffer) -> ()
Jitter : destroy ( )  -> ()

Stops the tick loop and frees the Opus decoder. Must not be called more than once.

Jitter . new ( firstSequence )  -> Jitter

Responsible for constructing this class.

Parameters

firstSequence: number

Returns

Jitter