Querying libopus Algorithmic Delay
This article explains how software developers can programmatically query the algorithmic delay, also known as lookahead, introduced by the libopus audio codec. It covers the specific control code used in the Opus C API, provides a practical code example, and details how to convert the retrieved sample count into milliseconds for real-time audio synchronization.
Understanding libopus Algorithmic Delay
Like most modern transform-based audio codecs, Opus requires a small amount of “lookahead” data to perform its analysis, windowing, and Modified Discrete Cosine Transform (MDCT) calculations. This lookahead introduces an inherent algorithmic delay that must be accounted for to ensure proper synchronization between audio streams, or between audio and video (lip-sync).
The exact delay depends on the configuration of the encoder, such as the application mode (VoIP, Audio, or Low Delay) and the frame size.
Using the OPUS_GET_LOOKAHEAD Control Code
To retrieve the current algorithmic delay from an active Opus
encoder, developers must use the opus_encoder_ctl function
with the OPUS_GET_LOOKAHEAD control parameter.
The function populates a 32-bit signed integer with the delay measured in samples at 48 kHz, regardless of the sampling rate configured during the encoder’s initialization.
C Implementation Example
The following code snippet demonstrates how to initialize an encoder, query the lookahead value, and calculate the delay in milliseconds.
#include <stdio.h>
#include <opus.h>
void print_encoder_delay(OpusEncoder *enc) {
opus_int32 lookahead;
int error;
// Query the encoder for the algorithmic delay (lookahead)
error = opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&lookahead));
if (error == OPUS_OK) {
// Since OPUS_GET_LOOKAHEAD always returns the sample count at 48 kHz:
double delay_ms = ((double)lookahead / 48000.0) * 1000.0;
printf("Algorithmic Delay: %d samples\n", lookahead);
printf("Time Delay: %.2f ms\n", delay_ms);
} else {
fprintf(stderr, "Failed to retrieve lookahead: %s\n", opus_strerror(error));
}
}Calculating the Delay in Milliseconds
To convert the lookahead value into milliseconds, use the following formula:
\[\text{Delay (ms)} = \left( \frac{\text{Lookahead Samples}}{48000} \right) \times 1000\]
For example, if OPUS_GET_LOOKAHEAD returns
312 samples:
\[\text{Delay} = \left( \frac{312}{48000} \right) \times 1000 = 6.5\text{ ms}\]
Developers must compensate for this delay by discarding the corresponding number of output samples at the decoder’s side when starting playback, or by shifting accompanying video tracks forward by the calculated millisecond value.