How to Use vorbis_synthesis_pcmout in libvorbis

This article explains the function and significance of vorbis_synthesis_pcmout within the libvorbis API. It covers how this function retrieves decoded Pulse Code Modulation (PCM) audio data from the decoder’s internal buffers, its role in the decoding pipeline, and how developers must handle the retrieved pointers to ensure successful audio playback.

The Role of vorbis_synthesis_pcmout

In the libvorbis decoding pipeline, compressed Ogg Vorbis packets are analyzed and synthesized into raw audio. After a packet has been submitted to the decoder using vorbis_synthesis and processed by vorbis_synthesis_blockin, the decoded audio is stored in the internal buffers of the vorbis_dsp_state structure.

The primary role of vorbis_synthesis_pcmout is to query the decoder for these decoded, floating-point PCM samples and retrieve pointers to the memory locations where they are stored.

Function Signature and Parameters

The function is declared in the vorbis/codec.h header with the following signature:

int vorbis_synthesis_pcmout(vorbis_dsp_state *v, float ***pcm);

Return Values and Buffer Management

When called, vorbis_synthesis_pcmout returns an integer indicating the status of the buffer:

It is important to understand that vorbis_synthesis_pcmout is a non-destructive read operation. Calling it does not remove the samples from the decoder’s internal buffer, nor does it advance the buffer pointers.

The Decoding Workflow

To properly retrieve and consume audio from libvorbis, developers must pair vorbis_synthesis_pcmout with vorbis_synthesis_read. The standard workflow is as follows:

  1. Submit Packet: Submit an audio packet using vorbis_synthesis and vorbis_synthesis_blockin.
  2. Check Buffer: Call vorbis_synthesis_pcmout to obtain a pointer to the decoded float PCM data and determine how many samples are available.
  3. Process Output: Convert the floating-point samples (which range from -1.0 to 1.0) into your desired output format (such as 16-bit signed integers) and copy them to your system’s audio playback buffer.
  4. Consume Samples: Call vorbis_synthesis_read with the number of samples you successfully processed. This function tells libvorbis to advance its internal pointers and release the memory occupied by those samples, making room for the next decoding cycle.