/* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2011-2022 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of the Xiph.org Foundation nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef FLAC__STREAM_DECODER_H#define FLAC__STREAM_DECODER_H #include <stdio.h> /* for FILE */#include "export.h"#include "format.h" #ifdef __cplusplusextern "C" {#endif /** \file include/FLAC/stream_decoder.h * * \brief * This module contains the functions which implement the stream * decoder. * * See the detailed documentation in the * \link flac_stream_decoder stream decoder \endlink module. */ /** \defgroup flac_decoder FLAC/ \*_decoder.h: decoder interfaces * \ingroup flac * * \brief * This module describes the decoder layers provided by libFLAC. * * The stream decoder can be used to decode complete streams either from * the client via callbacks, or directly from a file, depending on how * it is initialized. When decoding via callbacks, the client provides * callbacks for reading FLAC data and writing decoded samples, and * handling metadata and errors. If the client also supplies seek-related * callback, the decoder function for sample-accurate seeking within the * FLAC input is also available. When decoding from a file, the client * needs only supply a filename or open \c FILE* and write/metadata/error * callbacks; the rest of the callbacks are supplied internally. For more * info see the \link flac_stream_decoder stream decoder \endlink module. */ /** \defgroup flac_stream_decoder FLAC/stream_decoder.h: stream decoder interface * \ingroup flac_decoder * * \brief * This module contains the functions which implement the stream * decoder. * * The stream decoder can decode native FLAC, and optionally Ogg FLAC * (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files. * * The basic usage of this decoder is as follows: * - The program creates an instance of a decoder using * FLAC__stream_decoder_new(). * - The program overrides the default settings using * FLAC__stream_decoder_set_*() functions. * - The program initializes the instance to validate the settings and * prepare for decoding using * - FLAC__stream_decoder_init_stream() or FLAC__stream_decoder_init_FILE() * or FLAC__stream_decoder_init_file() for native FLAC, * - FLAC__stream_decoder_init_ogg_stream() or FLAC__stream_decoder_init_ogg_FILE() * or FLAC__stream_decoder_init_ogg_file() for Ogg FLAC * - The program calls the FLAC__stream_decoder_process_*() functions * to decode data, which subsequently calls the callbacks. * - The program finishes the decoding with FLAC__stream_decoder_finish(), * which flushes the input and output and resets the decoder to the * uninitialized state. * - The instance may be used again or deleted with * FLAC__stream_decoder_delete(). * * In more detail, the program will create a new instance by calling * FLAC__stream_decoder_new(), then call FLAC__stream_decoder_set_*() * functions to override the default decoder options, and call * one of the FLAC__stream_decoder_init_*() functions. * * There are three initialization functions for native FLAC, one for * setting up the decoder to decode FLAC data from the client via * callbacks, and two for decoding directly from a FLAC file. * * For decoding via callbacks, use FLAC__stream_decoder_init_stream(). * You must also supply several callbacks for handling I/O. Some (like * seeking) are optional, depending on the capabilities of the input. * * For decoding directly from a file, use FLAC__stream_decoder_init_FILE() * or FLAC__stream_decoder_init_file(). Then you must only supply an open * \c FILE* or filename and fewer callbacks; the decoder will handle * the other callbacks internally. * * There are three similarly-named init functions for decoding from Ogg * FLAC streams. Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the * library has been built with Ogg support. * * Once the decoder is initialized, your program will call one of several * functions to start the decoding process: * * - FLAC__stream_decoder_process_single() - Tells the decoder to process at * most one metadata block or audio frame and return, calling either the * metadata callback or write callback, respectively, once. If the decoder * loses sync it will return with only the error callback being called. * - FLAC__stream_decoder_process_until_end_of_metadata() - Tells the decoder * to process the stream from the current location and stop upon reaching * the first audio frame. The client will get one metadata, write, or error * callback per metadata block, audio frame, or sync error, respectively. * - FLAC__stream_decoder_process_until_end_of_stream() - Tells the decoder * to process the stream from the current location until the read callback * returns FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM or * FLAC__STREAM_DECODER_READ_STATUS_ABORT. The client will get one metadata, * write, or error callback per metadata block, audio frame, or sync error, * respectively. * * When the decoder has finished decoding (normally or through an abort), * the instance is finished by calling FLAC__stream_decoder_finish(), which * ensures the decoder is in the correct state and frees memory. Then the * instance may be deleted with FLAC__stream_decoder_delete() or initialized * again to decode another stream. * * Seeking is exposed through the FLAC__stream_decoder_seek_absolute() method. * At any point after the stream decoder has been initialized, the client can * call this function to seek to an exact sample within the stream. * Subsequently, the first time the write callback is called it will be * passed a (possibly partial) block starting at that sample. * * If the client cannot seek via the callback interface provided, but still * has another way of seeking, it can flush the decoder using * FLAC__stream_decoder_flush() and start feeding data from the new position * through the read callback. * * The stream decoder also provides MD5 signature checking. If this is * turned on before initialization, FLAC__stream_decoder_finish() will * report when the decoded MD5 signature does not match the one stored * in the STREAMINFO block. MD5 checking is automatically turned off * (until the next FLAC__stream_decoder_reset()) if there is no signature * in the STREAMINFO block or when a seek is attempted. * * The FLAC__stream_decoder_set_metadata_*() functions deserve special * attention. By default, the decoder only calls the metadata_callback for * the STREAMINFO block. These functions allow you to tell the decoder * explicitly which blocks to parse and return via the metadata_callback * and/or which to skip. Use a FLAC__stream_decoder_set_metadata_respond_all(), * FLAC__stream_decoder_set_metadata_ignore() ... or FLAC__stream_decoder_set_metadata_ignore_all(), * FLAC__stream_decoder_set_metadata_respond() ... sequence to exactly specify * which blocks to return. Remember that metadata blocks can potentially * be big (for example, cover art) so filtering out the ones you don't * use can reduce the memory requirements of the decoder. Also note the * special forms FLAC__stream_decoder_set_metadata_respond_application(id) * and FLAC__stream_decoder_set_metadata_ignore_application(id) for * filtering APPLICATION blocks based on the application ID. * * STREAMINFO and SEEKTABLE blocks are always parsed and used internally, but * they still can legally be filtered from the metadata_callback. * * \note * The "set" functions may only be called when the decoder is in the * state FLAC__STREAM_DECODER_UNINITIALIZED, i.e. after * FLAC__stream_decoder_new() or FLAC__stream_decoder_finish(), but * before FLAC__stream_decoder_init_*(). If this is the case they will * return \c true, otherwise \c false. * * \note * FLAC__stream_decoder_finish() resets all settings to the constructor * defaults, including the callbacks. * * \{ */ /** State values for a FLAC__StreamDecoder * * The decoder's state can be obtained by calling FLAC__stream_decoder_get_state(). */typedef enum { FLAC__STREAM_DECODER_SEARCH_FOR_METADATA = 0, /**< The decoder is ready to search for metadata. */ FLAC__STREAM_DECODER_READ_METADATA, /**< The decoder is ready to or is in the process of reading metadata. */ FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC, /**< The decoder is ready to or is in the process of searching for the * frame sync code. */ FLAC__STREAM_DECODER_READ_FRAME, /**< The decoder is ready to or is in the process of reading a frame. */ FLAC__STREAM_DECODER_END_OF_STREAM, /**< The decoder has reached the end of the stream. */ FLAC__STREAM_DECODER_OGG_ERROR, /**< An error occurred in the underlying Ogg layer. */ FLAC__STREAM_DECODER_SEEK_ERROR, /**< An error occurred while seeking. The decoder must be flushed * with FLAC__stream_decoder_flush() or reset with * FLAC__stream_decoder_reset() before decoding can continue. */ FLAC__STREAM_DECODER_ABORTED, /**< The decoder was aborted by the read or write callback. */ FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR, /**< An error occurred allocating memory. The decoder is in an invalid * state and can no longer be used. */ FLAC__STREAM_DECODER_UNINITIALIZED /**< The decoder is in the uninitialized state; one of the * FLAC__stream_decoder_init_*() functions must be called before samples * can be processed. */ } FLAC__StreamDecoderState; /** Maps a FLAC__StreamDecoderState to a C string. * * Using a FLAC__StreamDecoderState as the index to this array * will give the string equivalent. The contents should not be modified. */extern FLAC_API const char * const FLAC__StreamDecoderStateString[]; /** Possible return values for the FLAC__stream_decoder_init_*() functions. */typedef enum { FLAC__STREAM_DECODER_INIT_STATUS_OK = 0, /**< Initialization was successful. */ FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER, /**< The library was not compiled with support for the given container * format. */ FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS, /**< A required callback was not supplied. */ FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR, /**< An error occurred allocating memory. */ FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE, /**< fopen() failed in FLAC__stream_decoder_init_file() or * FLAC__stream_decoder_init_ogg_file(). */ FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED /**< FLAC__stream_decoder_init_*() was called when the decoder was * already initialized, usually because * FLAC__stream_decoder_finish() was not called. */ } FLAC__StreamDecoderInitStatus; /** Maps a FLAC__StreamDecoderInitStatus to a C string. * * Using a FLAC__StreamDecoderInitStatus as the index to this array * will give the string equivalent. The contents should not be modified. */extern FLAC_API const char * const FLAC__StreamDecoderInitStatusString[]; /** Return values for the FLAC__StreamDecoder read callback. */typedef enum { FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, /**< The read was OK and decoding can continue. */ FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM, /**< The read was attempted while at the end of the stream. Note that * the client must only return this value when the read callback was * called when already at the end of the stream. Otherwise, if the read * itself moves to the end of the stream, the client should still return * the data and \c FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, and then on * the next read callback it should return * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM with a byte count * of \c 0. */ FLAC__STREAM_DECODER_READ_STATUS_ABORT /**< An unrecoverable error occurred. The decoder will return from the process call. */ } FLAC__StreamDecoderReadStatus; /** Maps a FLAC__StreamDecoderReadStatus to a C string. * * Using a FLAC__StreamDecoderReadStatus as the index to this array * will give the string equivalent. The contents should not be modified. */extern FLAC_API const char * const FLAC__StreamDecoderReadStatusString[]; /** Return values for the FLAC__StreamDecoder seek callback. */typedef enum { FLAC__STREAM_DECODER_SEEK_STATUS_OK, /**< The seek was OK and decoding can continue. */ FLAC__STREAM_DECODER_SEEK_STATUS_ERROR, /**< An unrecoverable error occurred. The decoder will return from the process call. */ FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED /**< Client does not support seeking. */ } FLAC__StreamDecoderSeekStatus; /** Maps a FLAC__StreamDecoderSeekStatus to a C string. * * Using a FLAC__StreamDecoderSeekStatus as the index to this array * will give the string equivalent. The contents should not be modified. */extern FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[]; /** Return values for the FLAC__StreamDecoder tell callback. */typedef enum { FLAC__STREAM_DECODER_TELL_STATUS_OK, /**< The tell was OK and decoding can continue. */ FLAC__STREAM_DECODER_TELL_STATUS_ERROR, /**< An unrecoverable error occurred. The decoder will return from the process call. */ FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED /**< Client does not support telling the position. */ } FLAC__StreamDecoderTellStatus; /** Maps a FLAC__StreamDecoderTellStatus to a C string. * * Using a FLAC__StreamDecoderTellStatus as the index to this array * will give the string equivalent. The contents should not be modified. */extern FLAC_API const char * const FLAC__StreamDecoderTellStatusString[]; /** Return values for the FLAC__StreamDecoder length callback. */typedef enum { FLAC__STREAM_DECODER_LENGTH_STATUS_OK, /**< The length call was OK and decoding can continue. */ FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR, /**< An unrecoverable error occurred. The decoder will return from the process call. */ FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED /**< Client does not support reporting the length. */ } FLAC__StreamDecoderLengthStatus; /** Maps a FLAC__StreamDecoderLengthStatus to a C string. * * Using a FLAC__StreamDecoderLengthStatus as the index to this array * will give the string equivalent. The contents should not be modified. */extern FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[]; /** Return values for the FLAC__StreamDecoder write callback. */typedef enum { FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE, /**< The write was OK and decoding can continue. */ FLAC__STREAM_DECODER_WRITE_STATUS_ABORT /**< An unrecoverable error occurred. The decoder will return from the process call. */ } FLAC__StreamDecoderWriteStatus; /** Maps a FLAC__StreamDecoderWriteStatus to a C string. * * Using a FLAC__StreamDecoderWriteStatus as the index to this array * will give the string equivalent. The contents should not be modified. */extern FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[]; /** Possible values passed back to the FLAC__StreamDecoder error callback. * \c FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC is the generic catch- * all. The rest could be caused by bad sync (false synchronization on * data that is not the start of a frame) or corrupted data. The error * itself is the decoder's best guess at what happened assuming a correct * sync. For example \c FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER * could be caused by a correct sync on the start of a frame, but some * data in the frame header was corrupted. Or it could be the result of * syncing on a point the stream that looked like the starting of a frame * but was not. \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM * could be because the decoder encountered a valid frame made by a future * version of the encoder which it cannot parse, or because of a false * sync making it appear as though an encountered frame was generated by * a future encoder. \c FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA is * caused by finding data that doesn't fit a metadata block (too large * or too small) or finding inconsistencies in the metadata, for example * a PICTURE block with an image that exceeds the size of the metadata * block. */typedef enum { FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, /**< An error in the stream caused the decoder to lose synchronization. */ FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, /**< The decoder encountered a corrupted frame header. */ FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH, /**< The frame's data did not match the CRC in the footer. */ FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM, /**< The decoder encountered reserved fields in use in the stream. */ FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA /**< The decoder encountered a corrupted metadata block. */ } FLAC__StreamDecoderErrorStatus; /** Maps a FLAC__StreamDecoderErrorStatus to a C string. * * Using a FLAC__StreamDecoderErrorStatus as the index to this array * will give the string equivalent. The contents should not be modified. */extern FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[]; /*********************************************************************** * * class FLAC__StreamDecoder * ***********************************************************************/ struct FLAC__StreamDecoderProtected;struct FLAC__StreamDecoderPrivate;/** The opaque structure definition for the stream decoder type. * See the \link flac_stream_decoder stream decoder module \endlink * for a detailed description. */typedef struct { struct FLAC__StreamDecoderProtected *protected_; /* avoid the C++ keyword 'protected' */ struct FLAC__StreamDecoderPrivate *private_; /* avoid the C++ keyword 'private' */} FLAC__StreamDecoder; /** Signature for the read callback. * * A function pointer matching this signature must be passed to * FLAC__stream_decoder_init*_stream(). The supplied function will be * called when the decoder needs more input data. The address of the * buffer to be filled is supplied, along with the number of bytes the * buffer can hold. The callback may choose to supply less data and * modify the byte count but must be careful not to overflow the buffer. * The callback then returns a status code chosen from * FLAC__StreamDecoderReadStatus. * * Here is an example of a read callback for stdio streams: * \code * FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) * { * FILE *file = ((MyClientData*)client_data)->file; * if(*bytes > 0) { * *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, file); * if(ferror(file)) * return FLAC__STREAM_DECODER_READ_STATUS_ABORT; * else if(*bytes == 0) * return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; * else * return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; * } * elseLines 1–500 of 1584. Load more
/* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson * Copyright (C) 2011-2022 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of the Xiph.org Foundation nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef FLAC__STREAM_DECODER_H #define FLAC__STREAM_DECODER_H #include <stdio.h> /* for FILE */ #include "export.h" #include "format.h" #ifdef __cplusplus extern "C" { #endif /** \file include/FLAC/stream_decoder.h * * \brief * This module contains the functions which implement the stream * decoder. * * See the detailed documentation in the * \link flac_stream_decoder stream decoder \endlink module. */ /** \defgroup flac_decoder FLAC/ \*_decoder.h: decoder interfaces * \ingroup flac * * \brief * This module describes the decoder layers provided by libFLAC. * * The stream decoder can be used to decode complete streams either from * the client via callbacks, or directly from a file, depending on how * it is initialized. When decoding via callbacks, the client provides * callbacks for reading FLAC data and writing decoded samples, and * handling metadata and errors. If the client also supplies seek-related * callback, the decoder function for sample-accurate seeking within the * FLAC input is also available. When decoding from a file, the client * needs only supply a filename or open \c FILE* and write/metadata/error * callbacks; the rest of the callbacks are supplied internally. For more * info see the \link flac_stream_decoder stream decoder \endlink module. */ /** \defgroup flac_stream_decoder FLAC/stream_decoder.h: stream decoder interface * \ingroup flac_decoder * * \brief * This module contains the functions which implement the stream * decoder. * * The stream decoder can decode native FLAC, and optionally Ogg FLAC * (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files. * * The basic usage of this decoder is as follows: * - The program creates an instance of a decoder using * FLAC__stream_decoder_new(). * - The program overrides the default settings using * FLAC__stream_decoder_set_*() functions. * - The program initializes the instance to validate the settings and * prepare for decoding using * - FLAC__stream_decoder_init_stream() or FLAC__stream_decoder_init_FILE() * or FLAC__stream_decoder_init_file() for native FLAC, * - FLAC__stream_decoder_init_ogg_stream() or FLAC__stream_decoder_init_ogg_FILE() * or FLAC__stream_decoder_init_ogg_file() for Ogg FLAC * - The program calls the FLAC__stream_decoder_process_*() functions * to decode data, which subsequently calls the callbacks. * - The program finishes the decoding with FLAC__stream_decoder_finish(), * which flushes the input and output and resets the decoder to the * uninitialized state. * - The instance may be used again or deleted with * FLAC__stream_decoder_delete(). * * In more detail, the program will create a new instance by calling * FLAC__stream_decoder_new(), then call FLAC__stream_decoder_set_*() * functions to override the default decoder options, and call * one of the FLAC__stream_decoder_init_*() functions. * * There are three initialization functions for native FLAC, one for * setting up the decoder to decode FLAC data from the client via * callbacks, and two for decoding directly from a FLAC file. * * For decoding via callbacks, use FLAC__stream_decoder_init_stream(). * You must also supply several callbacks for handling I/O. Some (like * seeking) are optional, depending on the capabilities of the input. * * For decoding directly from a file, use FLAC__stream_decoder_init_FILE() * or FLAC__stream_decoder_init_file(). Then you must only supply an open * \c FILE* or filename and fewer callbacks; the decoder will handle * the other callbacks internally. * * There are three similarly-named init functions for decoding from Ogg * FLAC streams. Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the * library has been built with Ogg support. * * Once the decoder is initialized, your program will call one of several * functions to start the decoding process: * * - FLAC__stream_decoder_process_single() - Tells the decoder to process at * most one metadata block or audio frame and return, calling either the * metadata callback or write callback, respectively, once. If the decoder * loses sync it will return with only the error callback being called. * - FLAC__stream_decoder_process_until_end_of_metadata() - Tells the decoder * to process the stream from the current location and stop upon reaching * the first audio frame. The client will get one metadata, write, or error * callback per metadata block, audio frame, or sync error, respectively. * - FLAC__stream_decoder_process_until_end_of_stream() - Tells the decoder * to process the stream from the current location until the read callback * returns FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM or * FLAC__STREAM_DECODER_READ_STATUS_ABORT. The client will get one metadata, * write, or error callback per metadata block, audio frame, or sync error, * respectively. * * When the decoder has finished decoding (normally or through an abort), * the instance is finished by calling FLAC__stream_decoder_finish(), which * ensures the decoder is in the correct state and frees memory. Then the * instance may be deleted with FLAC__stream_decoder_delete() or initialized * again to decode another stream. * * Seeking is exposed through the FLAC__stream_decoder_seek_absolute() method. * At any point after the stream decoder has been initialized, the client can * call this function to seek to an exact sample within the stream. * Subsequently, the first time the write callback is called it will be * passed a (possibly partial) block starting at that sample. * * If the client cannot seek via the callback interface provided, but still * has another way of seeking, it can flush the decoder using * FLAC__stream_decoder_flush() and start feeding data from the new position * through the read callback. * * The stream decoder also provides MD5 signature checking. If this is * turned on before initialization, FLAC__stream_decoder_finish() will * report when the decoded MD5 signature does not match the one stored * in the STREAMINFO block. MD5 checking is automatically turned off * (until the next FLAC__stream_decoder_reset()) if there is no signature * in the STREAMINFO block or when a seek is attempted. * * The FLAC__stream_decoder_set_metadata_*() functions deserve special * attention. By default, the decoder only calls the metadata_callback for * the STREAMINFO block. These functions allow you to tell the decoder * explicitly which blocks to parse and return via the metadata_callback * and/or which to skip. Use a FLAC__stream_decoder_set_metadata_respond_all(), * FLAC__stream_decoder_set_metadata_ignore() ... or FLAC__stream_decoder_set_metadata_ignore_all(), * FLAC__stream_decoder_set_metadata_respond() ... sequence to exactly specify * which blocks to return. Remember that metadata blocks can potentially * be big (for example, cover art) so filtering out the ones you don't * use can reduce the memory requirements of the decoder. Also note the * special forms FLAC__stream_decoder_set_metadata_respond_application(id) * and FLAC__stream_decoder_set_metadata_ignore_application(id) for * filtering APPLICATION blocks based on the application ID. * * STREAMINFO and SEEKTABLE blocks are always parsed and used internally, but * they still can legally be filtered from the metadata_callback. * * \note * The "set" functions may only be called when the decoder is in the * state FLAC__STREAM_DECODER_UNINITIALIZED, i.e. after * FLAC__stream_decoder_new() or FLAC__stream_decoder_finish(), but * before FLAC__stream_decoder_init_*(). If this is the case they will * return \c true, otherwise \c false. * * \note * FLAC__stream_decoder_finish() resets all settings to the constructor * defaults, including the callbacks. * * \{ */ /** State values for a FLAC__StreamDecoder * * The decoder's state can be obtained by calling FLAC__stream_decoder_get_state(). */ typedef enum { FLAC__STREAM_DECODER_SEARCH_FOR_METADATA = 0, /**< The decoder is ready to search for metadata. */ FLAC__STREAM_DECODER_READ_METADATA, /**< The decoder is ready to or is in the process of reading metadata. */ FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC, /**< The decoder is ready to or is in the process of searching for the * frame sync code. */ FLAC__STREAM_DECODER_READ_FRAME, /**< The decoder is ready to or is in the process of reading a frame. */ FLAC__STREAM_DECODER_END_OF_STREAM, /**< The decoder has reached the end of the stream. */ FLAC__STREAM_DECODER_OGG_ERROR, /**< An error occurred in the underlying Ogg layer. */ FLAC__STREAM_DECODER_SEEK_ERROR, /**< An error occurred while seeking. The decoder must be flushed * with FLAC__stream_decoder_flush() or reset with * FLAC__stream_decoder_reset() before decoding can continue. */ FLAC__STREAM_DECODER_ABORTED, /**< The decoder was aborted by the read or write callback. */ FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR, /**< An error occurred allocating memory. The decoder is in an invalid * state and can no longer be used. */ FLAC__STREAM_DECODER_UNINITIALIZED /**< The decoder is in the uninitialized state; one of the * FLAC__stream_decoder_init_*() functions must be called before samples * can be processed. */ } FLAC__StreamDecoderState; /** Maps a FLAC__StreamDecoderState to a C string. * * Using a FLAC__StreamDecoderState as the index to this array * will give the string equivalent. The contents should not be modified. */ extern FLAC_API const char * const FLAC__StreamDecoderStateString[]; /** Possible return values for the FLAC__stream_decoder_init_*() functions. */ typedef enum { FLAC__STREAM_DECODER_INIT_STATUS_OK = 0, /**< Initialization was successful. */ FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER, /**< The library was not compiled with support for the given container * format. */ FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS, /**< A required callback was not supplied. */ FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR, /**< An error occurred allocating memory. */ FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE, /**< fopen() failed in FLAC__stream_decoder_init_file() or * FLAC__stream_decoder_init_ogg_file(). */ FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED /**< FLAC__stream_decoder_init_*() was called when the decoder was * already initialized, usually because * FLAC__stream_decoder_finish() was not called. */ } FLAC__StreamDecoderInitStatus; /** Maps a FLAC__StreamDecoderInitStatus to a C string. * * Using a FLAC__StreamDecoderInitStatus as the index to this array * will give the string equivalent. The contents should not be modified. */ extern FLAC_API const char * const FLAC__StreamDecoderInitStatusString[]; /** Return values for the FLAC__StreamDecoder read callback. */ typedef enum { FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, /**< The read was OK and decoding can continue. */ FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM, /**< The read was attempted while at the end of the stream. Note that * the client must only return this value when the read callback was * called when already at the end of the stream. Otherwise, if the read * itself moves to the end of the stream, the client should still return * the data and \c FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, and then on * the next read callback it should return * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM with a byte count * of \c 0. */ FLAC__STREAM_DECODER_READ_STATUS_ABORT /**< An unrecoverable error occurred. The decoder will return from the process call. */ } FLAC__StreamDecoderReadStatus; /** Maps a FLAC__StreamDecoderReadStatus to a C string. * * Using a FLAC__StreamDecoderReadStatus as the index to this array * will give the string equivalent. The contents should not be modified. */ extern FLAC_API const char * const FLAC__StreamDecoderReadStatusString[]; /** Return values for the FLAC__StreamDecoder seek callback. */ typedef enum { FLAC__STREAM_DECODER_SEEK_STATUS_OK, /**< The seek was OK and decoding can continue. */ FLAC__STREAM_DECODER_SEEK_STATUS_ERROR, /**< An unrecoverable error occurred. The decoder will return from the process call. */ FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED /**< Client does not support seeking. */ } FLAC__StreamDecoderSeekStatus; /** Maps a FLAC__StreamDecoderSeekStatus to a C string. * * Using a FLAC__StreamDecoderSeekStatus as the index to this array * will give the string equivalent. The contents should not be modified. */ extern FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[]; /** Return values for the FLAC__StreamDecoder tell callback. */ typedef enum { FLAC__STREAM_DECODER_TELL_STATUS_OK, /**< The tell was OK and decoding can continue. */ FLAC__STREAM_DECODER_TELL_STATUS_ERROR, /**< An unrecoverable error occurred. The decoder will return from the process call. */ FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED /**< Client does not support telling the position. */ } FLAC__StreamDecoderTellStatus; /** Maps a FLAC__StreamDecoderTellStatus to a C string. * * Using a FLAC__StreamDecoderTellStatus as the index to this array * will give the string equivalent. The contents should not be modified. */ extern FLAC_API const char * const FLAC__StreamDecoderTellStatusString[]; /** Return values for the FLAC__StreamDecoder length callback. */ typedef enum { FLAC__STREAM_DECODER_LENGTH_STATUS_OK, /**< The length call was OK and decoding can continue. */ FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR, /**< An unrecoverable error occurred. The decoder will return from the process call. */ FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED /**< Client does not support reporting the length. */ } FLAC__StreamDecoderLengthStatus; /** Maps a FLAC__StreamDecoderLengthStatus to a C string. * * Using a FLAC__StreamDecoderLengthStatus as the index to this array * will give the string equivalent. The contents should not be modified. */ extern FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[]; /** Return values for the FLAC__StreamDecoder write callback. */ typedef enum { FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE, /**< The write was OK and decoding can continue. */ FLAC__STREAM_DECODER_WRITE_STATUS_ABORT /**< An unrecoverable error occurred. The decoder will return from the process call. */ } FLAC__StreamDecoderWriteStatus; /** Maps a FLAC__StreamDecoderWriteStatus to a C string. * * Using a FLAC__StreamDecoderWriteStatus as the index to this array * will give the string equivalent. The contents should not be modified. */ extern FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[]; /** Possible values passed back to the FLAC__StreamDecoder error callback. * \c FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC is the generic catch- * all. The rest could be caused by bad sync (false synchronization on * data that is not the start of a frame) or corrupted data. The error * itself is the decoder's best guess at what happened assuming a correct * sync. For example \c FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER * could be caused by a correct sync on the start of a frame, but some * data in the frame header was corrupted. Or it could be the result of * syncing on a point the stream that looked like the starting of a frame * but was not. \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM * could be because the decoder encountered a valid frame made by a future * version of the encoder which it cannot parse, or because of a false * sync making it appear as though an encountered frame was generated by * a future encoder. \c FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA is * caused by finding data that doesn't fit a metadata block (too large * or too small) or finding inconsistencies in the metadata, for example * a PICTURE block with an image that exceeds the size of the metadata * block. */ typedef enum { FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, /**< An error in the stream caused the decoder to lose synchronization. */ FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, /**< The decoder encountered a corrupted frame header. */ FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH, /**< The frame's data did not match the CRC in the footer. */ FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM, /**< The decoder encountered reserved fields in use in the stream. */ FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA /**< The decoder encountered a corrupted metadata block. */ } FLAC__StreamDecoderErrorStatus; /** Maps a FLAC__StreamDecoderErrorStatus to a C string. * * Using a FLAC__StreamDecoderErrorStatus as the index to this array * will give the string equivalent. The contents should not be modified. */ extern FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[]; /*********************************************************************** * * class FLAC__StreamDecoder * ***********************************************************************/ struct FLAC__StreamDecoderProtected; struct FLAC__StreamDecoderPrivate; /** The opaque structure definition for the stream decoder type. * See the \link flac_stream_decoder stream decoder module \endlink * for a detailed description. */ typedef struct { struct FLAC__StreamDecoderProtected *protected_; /* avoid the C++ keyword 'protected' */ struct FLAC__StreamDecoderPrivate *private_; /* avoid the C++ keyword 'private' */ } FLAC__StreamDecoder; /** Signature for the read callback. * * A function pointer matching this signature must be passed to * FLAC__stream_decoder_init*_stream(). The supplied function will be * called when the decoder needs more input data. The address of the * buffer to be filled is supplied, along with the number of bytes the * buffer can hold. The callback may choose to supply less data and * modify the byte count but must be careful not to overflow the buffer. * The callback then returns a status code chosen from * FLAC__StreamDecoderReadStatus. * * Here is an example of a read callback for stdio streams: * \code * FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) * { * FILE *file = ((MyClientData*)client_data)->file; * if(*bytes > 0) { * *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, file); * if(ferror(file)) * return FLAC__STREAM_DECODER_READ_STATUS_ABORT; * else if(*bytes == 0) * return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; * else * return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; * } * else