opusfile  0.12-12-gb23e611
Stand-alone decoder library for .opus files.
Decoding

Functions for decoding audio data

These functions retrieve actual decoded audio data from the stream.

The general functions, op_read() and op_read_float() return 16-bit or floating-point output, both using native endian ordering. The number of channels returned can change from link to link in a chained stream. There are special functions, op_read_stereo() and op_read_float_stereo(), which always output two channels, to simplify applications which do not wish to handle multichannel audio. These downmix multichannel files to two channels, so they can always return samples in the same format for every link in a chained file.

If the rest of your audio processing chain can handle floating point, the floating-point routines should be preferred, as they prevent clipping and other issues which might be avoided entirely if, e.g., you scale down the volume at some other stage. However, if you intend to consume 16-bit samples directly, the conversion in libopusfile provides noise-shaping dithering and, if compiled against libopus 1.1 or later, soft-clipping prevention.

libopusfile can also be configured at compile time to use the fixed-point libopus API. If so, libopusfile's floating-point API may also be disabled. In that configuration, nothing in libopusfile will use any floating-point operations, to simplify support on devices without an adequate FPU.

Warning
HTTPS streams may be be vulnerable to truncation attacks if you do not check the error return code from op_read_float() or its associated functions. If the remote peer does not close the connection gracefully (with a TLS "close notify" message), these functions will return OP_EREAD instead of 0 when they reach the end of the file. If you are reading from an <https:> URL (particularly if seeking is not supported), you should make sure to check for this error and warn the user appropriately.
typedef int(* op_decode_cb_func) (void *_ctx, OpusMSDecoder *_decoder, void *_pcm, const ogg_packet *_op, int _nsamples, int _nchannels, int _format, int _li)
 Called to decode an Opus packet. More...
 
void op_set_decode_callback (OggOpusFile *_of, op_decode_cb_func _decode_cb, void *_ctx) OP_ARG_NONNULL(1)
 Sets the packet decode callback function. More...
 
int op_set_gain_offset (OggOpusFile *_of, int _gain_type, opus_int32 _gain_offset_q8) OP_ARG_NONNULL(1)
 Sets the gain to be used for decoded output. More...
 
void op_set_dither_enabled (OggOpusFile *_of, int _enabled) OP_ARG_NONNULL(1)
 Sets whether or not dithering is enabled for 16-bit decoding. More...
 
OP_WARN_UNUSED_RESULT int op_read (OggOpusFile *_of, opus_int16 *_pcm, int _buf_size, int *_li) OP_ARG_NONNULL(1)
 Reads more samples from the stream. More...
 
OP_WARN_UNUSED_RESULT int op_read_float (OggOpusFile *_of, float *_pcm, int _buf_size, int *_li) OP_ARG_NONNULL(1)
 Reads more samples from the stream. More...
 
OP_WARN_UNUSED_RESULT int op_read_stereo (OggOpusFile *_of, opus_int16 *_pcm, int _buf_size) OP_ARG_NONNULL(1)
 Reads more samples from the stream and downmixes to stereo, if necessary. More...
 
OP_WARN_UNUSED_RESULT int op_read_float_stereo (OggOpusFile *_of, float *_pcm, int _buf_size) OP_ARG_NONNULL(1)
 Reads more samples from the stream and downmixes to stereo, if necessary. More...
 
#define OP_DEC_FORMAT_SHORT   (7008)
 Indicates that the decoding callback should produce signed 16-bit native-endian output samples.
 
#define OP_DEC_FORMAT_FLOAT   (7040)
 Indicates that the decoding callback should produce 32-bit native-endian float samples.
 
#define OP_DEC_USE_DEFAULT   (6720)
 Indicates that the decoding callback did not decode anything, and that libopusfile should decode normally instead.
 
#define OP_HEADER_GAIN   (0)
 Gain offset type that indicates that the provided offset is relative to the header gain. More...
 
#define OP_ALBUM_GAIN   (3007)
 Gain offset type that indicates that the provided offset is relative to the R128_ALBUM_GAIN value (if any), in addition to the header gain.
 
#define OP_TRACK_GAIN   (3008)
 Gain offset type that indicates that the provided offset is relative to the R128_TRACK_GAIN value (if any), in addition to the header gain.
 
#define OP_ABSOLUTE_GAIN   (3009)
 Gain offset type that indicates that the provided offset should be used as the gain directly, without applying any the header or track gains.
 

Detailed Description

Macro Definition Documentation

◆ OP_HEADER_GAIN

#define OP_HEADER_GAIN   (0)

Gain offset type that indicates that the provided offset is relative to the header gain.

This is the default.

Typedef Documentation

◆ op_decode_cb_func

typedef int(* op_decode_cb_func) (void *_ctx, OpusMSDecoder *_decoder, void *_pcm, const ogg_packet *_op, int _nsamples, int _nchannels, int _format, int _li)

Called to decode an Opus packet.

This should invoke the functional equivalent of opus_multistream_decode() or opus_multistream_decode_float(), except that it returns 0 on success instead of the number of decoded samples (which is known a priori).

Parameters
_ctxThe application-provided callback context.
_decoderThe decoder to use to decode the packet.
[out]_pcmThe buffer to decode into. This will always have enough room for _nchannels of _nsamples samples, which should be placed into this buffer interleaved.
_opThe packet to decode. This will always have its granule position set to a valid value.
_nsamplesThe number of samples expected from the packet.
_nchannelsThe number of channels expected from the packet.
_formatThe desired sample output format. This is either OP_DEC_FORMAT_SHORT or OP_DEC_FORMAT_FLOAT.
_liThe index of the link from which this packet was decoded.
Returns
A non-negative value on success, or a negative value on error. Any error codes should be the same as those returned by opus_multistream_decode() or opus_multistream_decode_float(). Success codes are as follows:
Return values
0Decoding was successful. The application has filled the buffer with exactly _nsamples*_nchannels samples in the requested format.
OP_DEC_USE_DEFAULTNo decoding was done. libopusfile should do the decoding by itself instead.

Function Documentation

◆ op_set_decode_callback()

void op_set_decode_callback ( OggOpusFile *  _of,
op_decode_cb_func  _decode_cb,
void *  _ctx 
)

Sets the packet decode callback function.

If set, this is called once for each packet that needs to be decoded. This can be used by advanced applications to do additional processing on the compressed or uncompressed data. For example, an application might save the final entropy coder state for debugging and testing purposes, or it might apply additional filters before the downmixing, dithering, or soft-clipping performed by libopusfile, so long as these filters do not introduce any latency.

A call to this function is no guarantee that the audio will eventually be delivered to the application. libopusfile may discard some or all of the decoded audio data (i.e., at the beginning or end of a link, or after a seek), however the callback is still required to provide all of it.

Parameters
_ofThe OggOpusFile on which to set the decode callback.
_decode_cbThe callback function to call. This may be NULL to disable calling the callback.
_ctxThe application-provided context pointer to pass to the callback on each call.

◆ op_set_gain_offset()

int op_set_gain_offset ( OggOpusFile *  _of,
int  _gain_type,
opus_int32  _gain_offset_q8 
)

Sets the gain to be used for decoded output.

By default, the gain in the header is applied with no additional offset. The total gain (including header gain and/or track gain, if applicable, and this offset), will be clamped to [-32768,32767]/256 dB. This is more than enough to saturate or underflow 16-bit PCM.

Note
The new gain will not be applied to any already buffered, decoded output. This means you cannot change it sample-by-sample, as at best it will be updated packet-by-packet. It is meant for setting a target volume level, rather than applying smooth fades, etc.
Parameters
_ofThe OggOpusFile on which to set the gain offset.
_gain_typeOne of OP_HEADER_GAIN, OP_ALBUM_GAIN, OP_TRACK_GAIN, or OP_ABSOLUTE_GAIN.
_gain_offset_q8The gain offset to apply, in 1/256ths of a dB.
Returns
0 on success or a negative value on error.
Return values
OP_EINVALThe _gain_type was unrecognized.

◆ op_set_dither_enabled()

void op_set_dither_enabled ( OggOpusFile *  _of,
int  _enabled 
)

Sets whether or not dithering is enabled for 16-bit decoding.

By default, when libopusfile is compiled to use floating-point internally, calling op_read() or op_read_stereo() will first decode to float, and then convert to fixed-point using noise-shaping dithering. This flag can be used to disable that dithering. When the application uses op_read_float() or op_read_float_stereo(), or when the library has been compiled to decode directly to fixed point, this flag has no effect.

Parameters
_ofThe OggOpusFile on which to enable or disable dithering.
_enabledA non-zero value to enable dithering, or 0 to disable it.

◆ op_read()

OP_WARN_UNUSED_RESULT int op_read ( OggOpusFile *  _of,
opus_int16 *  _pcm,
int  _buf_size,
int *  _li 
)

Reads more samples from the stream.

Note
Although _buf_size must indicate the total number of values that can be stored in _pcm, the return value is the number of samples per channel. This is done because
  1. The channel count cannot be known a priori (reading more samples might advance us into the next link, with a different channel count), so _buf_size cannot also be in units of samples per channel,
  2. Returning the samples per channel matches the libopus API as closely as we're able,
  3. Returning the total number of values instead of samples per channel would mean the caller would need a division to compute the samples per channel, and might worry about the possibility of getting back samples for some channels and not others, and
  4. This approach is relatively fool-proof: if an application passes too small a value to _buf_size, they will simply get fewer samples back, and if they assume the return value is the total number of values, then they will simply read too few (rather than reading too many and going off the end of the buffer).
Parameters
_ofThe OggOpusFile from which to read.
[out]_pcmA buffer in which to store the output PCM samples, as signed native-endian 16-bit values at 48 kHz with a nominal range of [-32768,32767). Multiple channels are interleaved using the Vorbis channel ordering. This must have room for at least _buf_size values.
_buf_sizeThe number of values that can be stored in _pcm. It is recommended that this be large enough for at least 120 ms of data at 48 kHz per channel (5760 values per channel). Smaller buffers will simply return less data, possibly consuming more memory to buffer the data internally. libopusfile may return less data than requested. If so, there is no guarantee that the remaining data in _pcm will be unmodified.
[out]_liThe index of the link this data was decoded from. You may pass NULL if you do not need this information. If this function fails (returning a negative value), this parameter is left unset.
Returns
The number of samples read per channel on success, or a negative value on failure. The channel count can be retrieved on success by calling op_head(_of,*_li). The number of samples returned may be 0 if the buffer was too small to store even a single sample for all channels, or if end-of-file was reached. The list of possible failure codes follows. Most of them can only be returned by unseekable, chained streams that encounter a new link.
Return values
OP_HOLEThere was a hole in the data, and some samples may have been skipped. Call this function again to continue decoding past the hole.
OP_EREADAn underlying read operation failed. This may signal a truncation attack from an <https:> source.
OP_EFAULTAn internal memory allocation failed.
OP_EIMPLAn unseekable stream encountered a new link that used a feature that is not implemented, such as an unsupported channel family.
OP_EINVALThe stream was only partially open.
OP_ENOTFORMATAn unseekable stream encountered a new link that did not have any logical Opus streams in it.
OP_EBADHEADERAn unseekable stream encountered a new link with a required header packet that was not properly formatted, contained illegal values, or was missing altogether.
OP_EVERSIONAn unseekable stream encountered a new link with an ID header that contained an unrecognized version number.
OP_EBADPACKETFailed to properly decode the next packet.
OP_EBADLINKWe failed to find data we had seen before.
OP_EBADTIMESTAMPAn unseekable stream encountered a new link with a starting timestamp that failed basic validity checks.

◆ op_read_float()

OP_WARN_UNUSED_RESULT int op_read_float ( OggOpusFile *  _of,
float *  _pcm,
int  _buf_size,
int *  _li 
)

Reads more samples from the stream.

Note
Although _buf_size must indicate the total number of values that can be stored in _pcm, the return value is the number of samples per channel.
  1. The channel count cannot be known a priori (reading more samples might advance us into the next link, with a different channel count), so _buf_size cannot also be in units of samples per channel,
  2. Returning the samples per channel matches the libopus API as closely as we're able,
  3. Returning the total number of values instead of samples per channel would mean the caller would need a division to compute the samples per channel, and might worry about the possibility of getting back samples for some channels and not others, and
  4. This approach is relatively fool-proof: if an application passes too small a value to _buf_size, they will simply get fewer samples back, and if they assume the return value is the total number of values, then they will simply read too few (rather than reading too many and going off the end of the buffer).
Parameters
_ofThe OggOpusFile from which to read.
[out]_pcmA buffer in which to store the output PCM samples as signed floats at 48 kHz with a nominal range of [-1.0,1.0]. Multiple channels are interleaved using the Vorbis channel ordering. This must have room for at least _buf_size floats.
_buf_sizeThe number of floats that can be stored in _pcm. It is recommended that this be large enough for at least 120 ms of data at 48 kHz per channel (5760 samples per channel). Smaller buffers will simply return less data, possibly consuming more memory to buffer the data internally. If less than _buf_size values are returned, libopusfile makes no guarantee that the remaining data in _pcm will be unmodified.
[out]_liThe index of the link this data was decoded from. You may pass NULL if you do not need this information. If this function fails (returning a negative value), this parameter is left unset.
Returns
The number of samples read per channel on success, or a negative value on failure. The channel count can be retrieved on success by calling op_head(_of,*_li). The number of samples returned may be 0 if the buffer was too small to store even a single sample for all channels, or if end-of-file was reached. The list of possible failure codes follows. Most of them can only be returned by unseekable, chained streams that encounter a new link.
Return values
OP_HOLEThere was a hole in the data, and some samples may have been skipped. Call this function again to continue decoding past the hole.
OP_EREADAn underlying read operation failed. This may signal a truncation attack from an <https:> source.
OP_EFAULTAn internal memory allocation failed.
OP_EIMPLAn unseekable stream encountered a new link that used a feature that is not implemented, such as an unsupported channel family.
OP_EINVALThe stream was only partially open.
OP_ENOTFORMATAn unseekable stream encountered a new link that did not have any logical Opus streams in it.
OP_EBADHEADERAn unseekable stream encountered a new link with a required header packet that was not properly formatted, contained illegal values, or was missing altogether.
OP_EVERSIONAn unseekable stream encountered a new link with an ID header that contained an unrecognized version number.
OP_EBADPACKETFailed to properly decode the next packet.
OP_EBADLINKWe failed to find data we had seen before.
OP_EBADTIMESTAMPAn unseekable stream encountered a new link with a starting timestamp that failed basic validity checks.

◆ op_read_stereo()

OP_WARN_UNUSED_RESULT int op_read_stereo ( OggOpusFile *  _of,
opus_int16 *  _pcm,
int  _buf_size 
)

Reads more samples from the stream and downmixes to stereo, if necessary.

This function is intended for simple players that want a uniform output format, even if the channel count changes between links in a chained stream.

Note
_buf_size indicates the total number of values that can be stored in _pcm, while the return value is the number of samples per channel, even though the channel count is known, for consistency with op_read().
Parameters
_ofThe OggOpusFile from which to read.
[out]_pcmA buffer in which to store the output PCM samples, as signed native-endian 16-bit values at 48 kHz with a nominal range of [-32768,32767). The left and right channels are interleaved in the buffer. This must have room for at least _buf_size values.
_buf_sizeThe number of values that can be stored in _pcm. It is recommended that this be large enough for at least 120 ms of data at 48 kHz per channel (11520 values total). Smaller buffers will simply return less data, possibly consuming more memory to buffer the data internally. If less than _buf_size values are returned, libopusfile makes no guarantee that the remaining data in _pcm will be unmodified.
Returns
The number of samples read per channel on success, or a negative value on failure. The number of samples returned may be 0 if the buffer was too small to store even a single sample for both channels, or if end-of-file was reached. The list of possible failure codes follows. Most of them can only be returned by unseekable, chained streams that encounter a new link.
Return values
OP_HOLEThere was a hole in the data, and some samples may have been skipped. Call this function again to continue decoding past the hole.
OP_EREADAn underlying read operation failed. This may signal a truncation attack from an <https:> source.
OP_EFAULTAn internal memory allocation failed.
OP_EIMPLAn unseekable stream encountered a new link that used a feature that is not implemented, such as an unsupported channel family.
OP_EINVALThe stream was only partially open.
OP_ENOTFORMATAn unseekable stream encountered a new link that did not have any logical Opus streams in it.
OP_EBADHEADERAn unseekable stream encountered a new link with a required header packet that was not properly formatted, contained illegal values, or was missing altogether.
OP_EVERSIONAn unseekable stream encountered a new link with an ID header that contained an unrecognized version number.
OP_EBADPACKETFailed to properly decode the next packet.
OP_EBADLINKWe failed to find data we had seen before.
OP_EBADTIMESTAMPAn unseekable stream encountered a new link with a starting timestamp that failed basic validity checks.

◆ op_read_float_stereo()

OP_WARN_UNUSED_RESULT int op_read_float_stereo ( OggOpusFile *  _of,
float *  _pcm,
int  _buf_size 
)

Reads more samples from the stream and downmixes to stereo, if necessary.

This function is intended for simple players that want a uniform output format, even if the channel count changes between links in a chained stream.

Note
_buf_size indicates the total number of values that can be stored in _pcm, while the return value is the number of samples per channel, even though the channel count is known, for consistency with op_read_float().
Parameters
_ofThe OggOpusFile from which to read.
[out]_pcmA buffer in which to store the output PCM samples, as signed floats at 48 kHz with a nominal range of [-1.0,1.0]. The left and right channels are interleaved in the buffer. This must have room for at least _buf_size values.
_buf_sizeThe number of values that can be stored in _pcm. It is recommended that this be large enough for at least 120 ms of data at 48 kHz per channel (11520 values total). Smaller buffers will simply return less data, possibly consuming more memory to buffer the data internally. If less than _buf_size values are returned, libopusfile makes no guarantee that the remaining data in _pcm will be unmodified.
Returns
The number of samples read per channel on success, or a negative value on failure. The number of samples returned may be 0 if the buffer was too small to store even a single sample for both channels, or if end-of-file was reached. The list of possible failure codes follows. Most of them can only be returned by unseekable, chained streams that encounter a new link.
Return values
OP_HOLEThere was a hole in the data, and some samples may have been skipped. Call this function again to continue decoding past the hole.
OP_EREADAn underlying read operation failed. This may signal a truncation attack from an <https:> source.
OP_EFAULTAn internal memory allocation failed.
OP_EIMPLAn unseekable stream encountered a new link that used a feature that is not implemented, such as an unsupported channel family.
OP_EINVALThe stream was only partially open.
OP_ENOTFORMATAn unseekable stream encountered a new link that that did not have any logical Opus streams in it.
OP_EBADHEADERAn unseekable stream encountered a new link with a required header packet that was not properly formatted, contained illegal values, or was missing altogether.
OP_EVERSIONAn unseekable stream encountered a new link with an ID header that contained an unrecognized version number.
OP_EBADPACKETFailed to properly decode the next packet.
OP_EBADLINKWe failed to find data we had seen before.
OP_EBADTIMESTAMPAn unseekable stream encountered a new link with a starting timestamp that failed basic validity checks.