bool set_metadata_ignore_all();
State get_state() const;
- FLAC::Decoder::SeekableStream::State get_FLAC_seekable_stream_decoder_state() const;
+ OggFLAC::Decoder::Stream::State get_stream_decoder_state() const;
FLAC::Decoder::Stream::State get_FLAC_stream_decoder_state() const;
bool get_md5_checking() const;
unsigned get_channels() const;
bool seek_absolute(FLAC__uint64 sample);
protected:
- virtual ::FLAC__SeekableStreamDecoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes) = 0;
- virtual ::FLAC__SeekableStreamDecoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset) = 0;
- virtual ::FLAC__SeekableStreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset) = 0;
- virtual ::FLAC__SeekableStreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length) = 0;
+ virtual ::OggFLAC__SeekableStreamDecoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes) = 0;
+ virtual ::OggFLAC__SeekableStreamDecoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset) = 0;
+ virtual ::OggFLAC__SeekableStreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset) = 0;
+ virtual ::OggFLAC__SeekableStreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length) = 0;
virtual bool eof_callback() = 0;
virtual ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]) = 0;
virtual void metadata_callback(const ::FLAC__StreamMetadata *metadata) = 0;
#endif
::OggFLAC__SeekableStreamDecoder *decoder_;
private:
- static ::FLAC__SeekableStreamDecoderReadStatus read_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
- static ::FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
- static ::FLAC__SeekableStreamDecoderTellStatus tell_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
- static ::FLAC__SeekableStreamDecoderLengthStatus length_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
+ static ::OggFLAC__SeekableStreamDecoderReadStatus read_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
+ static ::OggFLAC__SeekableStreamDecoderSeekStatus seek_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
+ static ::OggFLAC__SeekableStreamDecoderTellStatus tell_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
+ static ::OggFLAC__SeekableStreamDecoderLengthStatus length_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
static FLAC__bool eof_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, void *client_data);
static ::FLAC__StreamDecoderWriteStatus write_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
static void metadata_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, const ::FLAC__StreamMetadata *metadata, void *client_data);
State get_state() const;
OggFLAC::Decoder::SeekableStream::State get_seekable_stream_decoder_state() const;
- FLAC::Decoder::SeekableStream::State get_FLAC_seekable_stream_decoder_state() const;
+ OggFLAC::Decoder::Stream::State get_stream_decoder_state() const;
FLAC::Decoder::Stream::State get_FLAC_stream_decoder_state() const;
bool get_md5_checking() const;
unsigned get_channels() const;
/***********************************************************************
*
- * class OggFLAC__FileDecoder : public FLAC__FileDecoder
+ * class OggFLAC__FileDecoder : public OggFLAC__SeekableStreamDecoder
*
***********************************************************************/
*/
OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__file_decoder_get_seekable_stream_decoder_state(const OggFLAC__FileDecoder *decoder);
-/** Get the state of the underlying FLAC seekable stream decoder.
+/** Get the state of the underlying stream decoder.
* Useful when the file decoder state is
* \c OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR
* and the seekable stream decoder state is
- * \c OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR.
+ * \c OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR.
*
* \param decoder A decoder instance to query.
* \assert
* \code decoder != NULL \endcode
- * \retval FLAC__SeekableStreamDecoderState
- * The FLAC seekable stream decoder state.
+ * \retval OggFLAC__StreamDecoderState
+ * The stream decoder state.
*/
-OggFLAC_API FLAC__SeekableStreamDecoderState OggFLAC__file_decoder_get_FLAC_seekable_stream_decoder_state(const OggFLAC__FileDecoder *decoder);
+OggFLAC_API OggFLAC__StreamDecoderState OggFLAC__file_decoder_get_stream_decoder_state(const OggFLAC__FileDecoder *decoder);
/** Get the state of the underlying FLAC stream decoder.
* Useful when the file decoder state is
* \c OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR
* and the seekable stream decoder state is
- * \c OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR
- * and the * FLAC seekable stream decoder state is
- * \c FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR.
+ * \c OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR
+ * and the stream decoder state is
+ * \c OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR.
*
* \param decoder A decoder instance to query.
* \assert
*/
OggFLAC_API unsigned OggFLAC__file_decoder_get_blocksize(const OggFLAC__FileDecoder *decoder);
+#if 0
+@@@@@@ this can never be made to work without writing a custom Ogg decoder; remove for release
/** This is inherited from FLAC__FileDecoder; see
* FLAC__file_decoder_get_decode_position().
*
* the 'tell' callback.
*/
OggFLAC_API FLAC__bool OggFLAC__file_decoder_get_decode_position(const OggFLAC__FileDecoder *decoder, FLAC__uint64 *position);
+#endif
/** Initialize the decoder instance.
* Should be called after OggFLAC__file_decoder_new() and
*/
OggFLAC_API FLAC__bool OggFLAC__file_decoder_process_until_end_of_file(OggFLAC__FileDecoder *decoder);
-/** This is inherited from FLAC__FileDecoder; see
- * FLAC__file_decoder_seek_absolute().
+/** This is inherited from OggFLAC__SeekableStreamDecoder; see
+ * OggFLAC__seekable_stream_decoder_seek_absolute().
*
* \param decoder A decoder instance.
* \param sample The target sample number to seek to.
#define OggFLAC__SEEKABLE_STREAM_DECODER_H
#include "export.h"
-
-#include "FLAC/seekable_stream_decoder.h"
+#include "stream_decoder.h"
#ifdef __cplusplus
extern "C" {
OggFLAC__SEEKABLE_STREAM_DECODER_OK = 0,
/**< The decoder is in the normal OK state. */
+ OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING,
+ /**< The decoder is in the process of seeking. */
+
OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM,
/**< The decoder has reached the end of the stream. */
- OggFLAC__SEEKABLE_STREAM_DECODER_OGG_ERROR,
- /**< An error occurred in the underlying Ogg layer. */
+ OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR,
+ /**< Memory allocation failed. */
- OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR,
- /**< An error occurred in the underlying FLAC seekable stream decoder;
- * check OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state().
+ OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR,
+ /**< An error occurred in the underlying stream decoder;
+ * check OggFLAC__seekable_stream_decoder_get_stream_decoder_state().
*/
OggFLAC__SEEKABLE_STREAM_DECODER_READ_ERROR,
/**< The read callback returned an error. */
- OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR,
- /**< Memory allocation failed. */
+ OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR,
+ /**< An error occurred while seeking or the seek or tell
+ * callback returned an error.
+ */
OggFLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED,
/**< OggFLAC__seekable_stream_decoder_init() was called when the decoder was
extern OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderStateString[];
+/** Return values for the OggFLAC__SeekableStreamDecoder read callback.
+ */
+typedef enum {
+
+ OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK,
+ /**< The read was OK and decoding can continue. */
+
+ OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR
+ /**< An unrecoverable error occurred. The decoder will return from the process call. */
+
+} OggFLAC__SeekableStreamDecoderReadStatus;
+
+/** Maps a OggFLAC__SeekableStreamDecoderReadStatus to a C string.
+ *
+ * Using a OggFLAC__SeekableStreamDecoderReadStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderReadStatusString[];
+
+
+/** Return values for the OggFLAC__SeekableStreamDecoder seek callback.
+ */
+typedef enum {
+
+ OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK,
+ /**< The seek was OK and decoding can continue. */
+
+ OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR
+ /**< An unrecoverable error occurred. The decoder will return from the process call. */
+
+} OggFLAC__SeekableStreamDecoderSeekStatus;
+
+/** Maps a OggFLAC__SeekableStreamDecoderSeekStatus to a C string.
+ *
+ * Using a OggFLAC__SeekableStreamDecoderSeekStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderSeekStatusString[];
+
+
+/** Return values for the OggFLAC__SeekableStreamDecoder tell callback.
+ */
+typedef enum {
+
+ OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK,
+ /**< The tell was OK and decoding can continue. */
+
+ OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR
+ /**< An unrecoverable error occurred. The decoder will return from the process call. */
+
+} OggFLAC__SeekableStreamDecoderTellStatus;
+
+/** Maps a OggFLAC__SeekableStreamDecoderTellStatus to a C string.
+ *
+ * Using a OggFLAC__SeekableStreamDecoderTellStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderTellStatusString[];
+
+
+/** Return values for the OggFLAC__SeekableStreamDecoder length callback.
+ */
+typedef enum {
+
+ OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK,
+ /**< The length call was OK and decoding can continue. */
+
+ OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR
+ /**< An unrecoverable error occurred. The decoder will return from the process call. */
+
+} OggFLAC__SeekableStreamDecoderLengthStatus;
+
+/** Maps a OggFLAC__SeekableStreamDecoderLengthStatus to a C string.
+ *
+ * Using a OggFLAC__SeekableStreamDecoderLengthStatus as the index to this array
+ * will give the string equivalent. The contents should not be modified.
+ */
+extern OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderLengthStatusString[];
+
+
/***********************************************************************
*
* class OggFLAC__SeekableStreamDecoder : public FLAC__StreamDecoder
* \retval FLAC__SeekableStreamDecoderReadStatus
* The callee's return status.
*/
-typedef FLAC__SeekableStreamDecoderReadStatus (*OggFLAC__SeekableStreamDecoderReadCallback)(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
+typedef OggFLAC__SeekableStreamDecoderReadStatus (*OggFLAC__SeekableStreamDecoderReadCallback)(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
/** Signature for the seek callback.
* See OggFLAC__seekable_stream_decoder_set_seek_callback() for more info.
* \retval FLAC__SeekableStreamDecoderSeekStatus
* The callee's return status.
*/
-typedef FLAC__SeekableStreamDecoderSeekStatus (*OggFLAC__SeekableStreamDecoderSeekCallback)(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
+typedef OggFLAC__SeekableStreamDecoderSeekStatus (*OggFLAC__SeekableStreamDecoderSeekCallback)(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
/** Signature for the tell callback.
* See OggFLAC__seekable_stream_decoder_set_tell_callback() for more info.
* \retval FLAC__SeekableStreamDecoderTellStatus
* The callee's return status.
*/
-typedef FLAC__SeekableStreamDecoderTellStatus (*OggFLAC__SeekableStreamDecoderTellCallback)(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
+typedef OggFLAC__SeekableStreamDecoderTellStatus (*OggFLAC__SeekableStreamDecoderTellCallback)(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
/** Signature for the length callback.
* See OggFLAC__seekable_stream_decoder_set_length_callback() for more info.
* \retval FLAC__SeekableStreamDecoderLengthStatus
* The callee's return status.
*/
-typedef FLAC__SeekableStreamDecoderLengthStatus (*OggFLAC__SeekableStreamDecoderLengthCallback)(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
+typedef OggFLAC__SeekableStreamDecoderLengthStatus (*OggFLAC__SeekableStreamDecoderLengthCallback)(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
/** Signature for the EOF callback.
* See OggFLAC__seekable_stream_decoder_set_eof_callback() for more info.
*/
OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder_get_state(const OggFLAC__SeekableStreamDecoder *decoder);
-/** Get the state of the underlying FLAC seekable stream decoder.
+/** Get the state of the underlying stream decoder.
* Useful when the seekable stream decoder state is
- * \c OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR.
+ * \c OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR.
*
* \param decoder A decoder instance to query.
* \assert
* \code decoder != NULL \endcode
- * \retval FLAC__SeekableStreamDecoderState
- * The FLAC seekable stream decoder state.
+ * \retval OggFLAC__StreamDecoderState
+ * The stream decoder state.
*/
-OggFLAC_API FLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state(const OggFLAC__SeekableStreamDecoder *decoder);
+OggFLAC_API OggFLAC__StreamDecoderState OggFLAC__seekable_stream_decoder_get_stream_decoder_state(const OggFLAC__SeekableStreamDecoder *decoder);
-/** Get the state of the underlying FLAC seekable stream decoder's stream decoder.
+/** Get the state of the underlying stream decoder's FLAC stream decoder.
* Useful when the seekable stream decoder state is
- * \c OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR and the
- * FLAC seekable stream decoder state is \c FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR
+ * \c OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR and the
+ * stream decoder state is \c OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR
*
* \param decoder A decoder instance to query.
* \assert
/** Get the current decoder state as a C string.
* This version automatically resolves
- * \c OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR
- * by getting the FLAC seekable stream decoder's state.
+ * \c OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR
+ * by getting the stream decoder's state.
*
* \param decoder A decoder instance to query.
* \assert
*/
OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_blocksize(const OggFLAC__SeekableStreamDecoder *decoder);
+#if 0
+@@@@@@ this can never be made to work without writing a custom Ogg decoder; remove for release
/** Returns the decoder's current read position within the stream.
* This is inherited from FLAC__SeekableStreamDecoder; see
* FLAC__seekable_stream_decoder_get_decode_position().
* \c true if successful, \c false if there was an error from
* the 'tell' callback.
*/
+/*@@@@@@ probably does not work... is it used? */
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_get_decode_position(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *position);
+#endif
/** Initialize the decoder instance.
* Should be called after OggFLAC__seekable_stream_decoder_new() and
return OggFLAC::Decoder::SeekableStream::State(::OggFLAC__file_decoder_get_seekable_stream_decoder_state(decoder_));
}
- FLAC::Decoder::SeekableStream::State File::get_FLAC_seekable_stream_decoder_state() const
+ OggFLAC::Decoder::Stream::State File::get_stream_decoder_state() const
{
FLAC__ASSERT(is_valid());
- return FLAC::Decoder::SeekableStream::State(::OggFLAC__file_decoder_get_FLAC_seekable_stream_decoder_state(decoder_));
+ return OggFLAC::Decoder::Stream::State(::OggFLAC__file_decoder_get_stream_decoder_state(decoder_));
}
FLAC::Decoder::Stream::State File::get_FLAC_stream_decoder_state() const
return State(::OggFLAC__seekable_stream_decoder_get_state(decoder_));
}
- FLAC::Decoder::SeekableStream::State SeekableStream::get_FLAC_seekable_stream_decoder_state() const
+ OggFLAC::Decoder::Stream::State SeekableStream::get_stream_decoder_state() const
{
FLAC__ASSERT(is_valid());
- return FLAC::Decoder::SeekableStream::State(::OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state(decoder_));
+ return OggFLAC::Decoder::Stream::State(::OggFLAC__seekable_stream_decoder_get_stream_decoder_state(decoder_));
}
FLAC::Decoder::Stream::State SeekableStream::get_FLAC_stream_decoder_state() const
return (bool)::OggFLAC__seekable_stream_decoder_seek_absolute(decoder_, sample);
}
- ::FLAC__SeekableStreamDecoderReadStatus SeekableStream::read_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
+ ::OggFLAC__SeekableStreamDecoderReadStatus SeekableStream::read_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
{
(void) decoder;
FLAC__ASSERT(0 != client_data);
return instance->read_callback(buffer, bytes);
}
- ::FLAC__SeekableStreamDecoderSeekStatus SeekableStream::seek_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
+ ::OggFLAC__SeekableStreamDecoderSeekStatus SeekableStream::seek_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
{
(void) decoder;
FLAC__ASSERT(0 != client_data);
return instance->seek_callback(absolute_byte_offset);
}
- ::FLAC__SeekableStreamDecoderTellStatus SeekableStream::tell_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
+ ::OggFLAC__SeekableStreamDecoderTellStatus SeekableStream::tell_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
{
(void) decoder;
FLAC__ASSERT(0 != client_data);
return instance->tell_callback(absolute_byte_offset);
}
- ::FLAC__SeekableStreamDecoderLengthStatus SeekableStream::length_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
+ ::OggFLAC__SeekableStreamDecoderLengthStatus SeekableStream::length_callback_(const ::OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
{
(void) decoder;
FLAC__ASSERT(0 != client_data);
static void set_defaults_(OggFLAC__FileDecoder *decoder);
static FILE *get_binary_stdin_();
-static FLAC__SeekableStreamDecoderReadStatus read_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
-static FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
-static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
-static FLAC__SeekableStreamDecoderLengthStatus length_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
+static OggFLAC__SeekableStreamDecoderReadStatus read_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
+static OggFLAC__SeekableStreamDecoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
+static OggFLAC__SeekableStreamDecoderTellStatus tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
+static OggFLAC__SeekableStreamDecoderLengthStatus length_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
static FLAC__bool eof_callback_(const OggFLAC__SeekableStreamDecoder *decoder, void *client_data);
static FLAC__StreamDecoderWriteStatus write_callback_(const OggFLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
static void metadata_callback_(const OggFLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
return OggFLAC__seekable_stream_decoder_get_state(decoder->private_->seekable_stream_decoder);
}
-OggFLAC_API FLAC__SeekableStreamDecoderState OggFLAC__file_decoder_get_FLAC_seekable_stream_decoder_state(const OggFLAC__FileDecoder *decoder)
+OggFLAC_API OggFLAC__StreamDecoderState OggFLAC__file_decoder_get_stream_decoder_state(const OggFLAC__FileDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
- return OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state(decoder->private_->seekable_stream_decoder);
+ return OggFLAC__seekable_stream_decoder_get_stream_decoder_state(decoder->private_->seekable_stream_decoder);
}
OggFLAC_API FLAC__StreamDecoderState OggFLAC__file_decoder_get_FLAC_stream_decoder_state(const OggFLAC__FileDecoder *decoder)
return OggFLAC__seekable_stream_decoder_get_blocksize(decoder->private_->seekable_stream_decoder);
}
+#if 0
+@@@@@@ this can never be made to work without writing a custom Ogg decoder; remove for release
OggFLAC_API FLAC__bool OggFLAC__file_decoder_get_decode_position(const OggFLAC__FileDecoder *decoder, FLAC__uint64 *position)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
return OggFLAC__seekable_stream_decoder_get_decode_position(decoder->private_->seekable_stream_decoder, position);
}
+#endif
OggFLAC_API FLAC__bool OggFLAC__file_decoder_process_single(OggFLAC__FileDecoder *decoder)
{
return stdin;
}
-FLAC__SeekableStreamDecoderReadStatus read_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
+OggFLAC__SeekableStreamDecoderReadStatus read_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
{
OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
(void)decoder;
if(*bytes > 0) {
*bytes = (unsigned)fread(buffer, sizeof(FLAC__byte), *bytes, file_decoder->private_->file);
if(ferror(file_decoder->private_->file)) {
- return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
}
else {
- return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
}
}
else
- return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */
+ return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */
}
-FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
+OggFLAC__SeekableStreamDecoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
{
OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
(void)decoder;
if(fseek(file_decoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
- return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
else
- return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
}
-FLAC__SeekableStreamDecoderTellStatus tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
+OggFLAC__SeekableStreamDecoderTellStatus tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
{
OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
long pos;
(void)decoder;
if((pos = ftell(file_decoder->private_->file)) < 0)
- return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
else {
*absolute_byte_offset = (FLAC__uint64)pos;
- return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
}
}
-FLAC__SeekableStreamDecoderLengthStatus length_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
+OggFLAC__SeekableStreamDecoderLengthStatus length_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
{
OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
struct stat filestats;
(void)decoder;
if(0 == file_decoder->private_->filename || stat(file_decoder->private_->filename, &filestats) != 0)
- return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
else {
*stream_length = (FLAC__uint64)filestats.st_size;
- return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
}
}
#include "private/ogg_decoder_aspect.h"
typedef struct OggFLAC__SeekableStreamDecoderProtected {
+ FLAC__bool md5_checking; /* if true, generate MD5 signature of decoded data and compare against signature in the STREAMINFO metadata block */
OggFLAC__SeekableStreamDecoderState state;
OggFLAC__OggDecoderAspect ogg_decoder_aspect;
} OggFLAC__SeekableStreamDecoderProtected;
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <stdio.h>
#include <stdlib.h> /* for calloc() */
+#include <string.h> /* for memcpy()/memcmp() */
#include "FLAC/assert.h"
#include "protected/seekable_stream_decoder.h"
+#include "protected/stream_decoder.h"
+#include "../libFLAC/include/private/md5.h" /* @@@@@@ ugly hack, but how else to do? we need to reuse the md5 code but don't want to expose it */
/***********************************************************************
*
***********************************************************************/
static void set_defaults_(OggFLAC__SeekableStreamDecoder *decoder);
-static FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
-static FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
-static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
-static FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
-static FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data);
-static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
-static void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
-static void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
-static OggFLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
-
+static FLAC__StreamDecoderReadStatus read_callback_(const OggFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
+static FLAC__StreamDecoderWriteStatus write_callback_(const OggFLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
+static void metadata_callback_(const OggFLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
+static void error_callback_(const OggFLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
+static FLAC__bool seek_to_absolute_sample_(OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample);
/***********************************************************************
*
OggFLAC__SeekableStreamDecoderMetadataCallback metadata_callback;
OggFLAC__SeekableStreamDecoderErrorCallback error_callback;
void *client_data;
- FLAC__SeekableStreamDecoder *FLAC_seekable_stream_decoder;
+ OggFLAC__StreamDecoder *stream_decoder;
+ FLAC__bool do_md5_checking; /* initially gets protected_->md5_checking but is turned off after a seek */
+ struct MD5Context md5context;
+ FLAC__byte stored_md5sum[16]; /* this is what is stored in the metadata */
+ FLAC__byte computed_md5sum[16]; /* this is the sum we computed from the decoded data */
+ /* the rest of these are only used for seeking: */
+ FLAC__StreamMetadata_StreamInfo stream_info; /* we keep this around so we can figure out how to seek quickly */
+ const FLAC__StreamMetadata_SeekTable *seek_table; /* we hold a pointer to the stream decoder's seek table for the same reason */
+ /* Since we always want to see the STREAMINFO and SEEK_TABLE blocks at this level, we need some extra flags to keep track of whether they should be passed on up through the metadata_callback */
+ FLAC__bool ignore_stream_info_block;
+ FLAC__bool ignore_seek_table_block;
+ FLAC__Frame last_frame; /* holds the info of the last frame we seeked to */
+ FLAC__uint64 target_sample;
} OggFLAC__SeekableStreamDecoderPrivate;
/***********************************************************************
OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderStateString[] = {
"OggFLAC__SEEKABLE_STREAM_DECODER_OK",
+ "OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING",
"OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM",
- "OggFLAC__SEEKABLE_STREAM_DECODER_OGG_ERROR",
- "OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR",
- "OggFLAC__SEEKABLE_STREAM_DECODER_READ_ERROR",
"OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
+ "OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR",
+ "OggFLAC__SEEKABLE_STREAM_DECODER_READ_ERROR",
+ "OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR",
"OggFLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED",
"OggFLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK",
"OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED"
};
+OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderReadStatusString[] = {
+ "OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK",
+ "OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR"
+};
+
+OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderSeekStatusString[] = {
+ "OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK",
+ "OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR"
+};
+
+OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderTellStatusString[] = {
+ "OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK",
+ "OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR"
+};
+
+OggFLAC_API const char * const OggFLAC__SeekableStreamDecoderLengthStatusString[] = {
+ "OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK",
+ "OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR"
+};
+
/***********************************************************************
*
* Class constructor/destructor
*
***********************************************************************/
+
OggFLAC_API OggFLAC__SeekableStreamDecoder *OggFLAC__seekable_stream_decoder_new()
{
OggFLAC__SeekableStreamDecoder *decoder;
+ FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
+
decoder = (OggFLAC__SeekableStreamDecoder*)calloc(1, sizeof(OggFLAC__SeekableStreamDecoder));
if(decoder == 0) {
return 0;
return 0;
}
- decoder->private_->FLAC_seekable_stream_decoder = FLAC__seekable_stream_decoder_new();
- if(0 == decoder->private_->FLAC_seekable_stream_decoder) {
+ decoder->private_->stream_decoder = OggFLAC__stream_decoder_new();
+ if(0 == decoder->private_->stream_decoder) {
free(decoder->private_);
free(decoder->protected_);
free(decoder);
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->protected_);
FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->private_->FLAC_seekable_stream_decoder);
+ FLAC__ASSERT(0 != decoder->private_->stream_decoder);
- OggFLAC__seekable_stream_decoder_finish(decoder);
+ (void)OggFLAC__seekable_stream_decoder_finish(decoder);
- FLAC__seekable_stream_decoder_delete(decoder->private_->FLAC_seekable_stream_decoder);
+ OggFLAC__stream_decoder_delete(decoder->private_->stream_decoder);
free(decoder->private_);
free(decoder->protected_);
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED;
- if(0 == decoder->private_->read_callback || 0 == decoder->private_->seek_callback || 0 == decoder->private_->tell_callback || 0 == decoder->private_->length_callback || 0 == decoder->private_->eof_callback || 0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
+ if(0 == decoder->private_->read_callback || 0 == decoder->private_->seek_callback || 0 == decoder->private_->tell_callback || 0 == decoder->private_->length_callback || 0 == decoder->private_->eof_callback)
+ return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK;
+
+ if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK;
- if(!OggFLAC__ogg_decoder_aspect_init(&decoder->protected_->ogg_decoder_aspect))
- return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OGG_ERROR;
+ decoder->private_->seek_table = 0;
- FLAC__seekable_stream_decoder_set_read_callback(decoder->private_->FLAC_seekable_stream_decoder, read_callback_);
- FLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->FLAC_seekable_stream_decoder, seek_callback_);
- FLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->FLAC_seekable_stream_decoder, tell_callback_);
- FLAC__seekable_stream_decoder_set_length_callback(decoder->private_->FLAC_seekable_stream_decoder, length_callback_);
- FLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->FLAC_seekable_stream_decoder, eof_callback_);
- FLAC__seekable_stream_decoder_set_write_callback(decoder->private_->FLAC_seekable_stream_decoder, write_callback_);
- FLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->FLAC_seekable_stream_decoder, metadata_callback_);
- FLAC__seekable_stream_decoder_set_error_callback(decoder->private_->FLAC_seekable_stream_decoder, error_callback_);
- FLAC__seekable_stream_decoder_set_client_data(decoder->private_->FLAC_seekable_stream_decoder, decoder);
+ decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
- if(FLAC__seekable_stream_decoder_init(decoder->private_->FLAC_seekable_stream_decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK)
- return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
+ /* We initialize the MD5Context even though we may never use it. This is
+ * because md5 checking may be turned on to start and then turned off if a
+ * seek occurs. So we always init the context here and finalize it in
+ * OggFLAC__seekable_stream_decoder_finish() to make sure things are always
+ * cleaned up properly.
+ */
+ MD5Init(&decoder->private_->md5context);
+
+ OggFLAC__stream_decoder_set_read_callback(decoder->private_->stream_decoder, read_callback_);
+ OggFLAC__stream_decoder_set_write_callback(decoder->private_->stream_decoder, write_callback_);
+ OggFLAC__stream_decoder_set_metadata_callback(decoder->private_->stream_decoder, metadata_callback_);
+ OggFLAC__stream_decoder_set_error_callback(decoder->private_->stream_decoder, error_callback_);
+ OggFLAC__stream_decoder_set_client_data(decoder->private_->stream_decoder, decoder);
+
+ /* We always want to see these blocks. Whether or not we pass them up
+ * through the metadata callback will be determined by flags set in our
+ * implementation of ..._set_metadata_respond/ignore...()
+ */
+ OggFLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_STREAMINFO);
+ OggFLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_SEEKTABLE);
+
+ if(OggFLAC__stream_decoder_init(decoder->private_->stream_decoder) != OggFLAC__STREAM_DECODER_OK)
+ return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_finish(OggFLAC__SeekableStreamDecoder *decoder)
{
- FLAC__bool ok;
+ FLAC__bool md5_failed = false;
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return true;
- FLAC__ASSERT(0 != decoder->private_->FLAC_seekable_stream_decoder);
+ FLAC__ASSERT(0 != decoder->private_->stream_decoder);
- ok = FLAC__seekable_stream_decoder_finish(decoder->private_->FLAC_seekable_stream_decoder);
+ /* see the comment in OggFLAC__seekable_stream_decoder_init() as to why we
+ * always call MD5Final()
+ */
+ MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context);
- OggFLAC__ogg_decoder_aspect_finish(&decoder->protected_->ogg_decoder_aspect);
+ OggFLAC__stream_decoder_finish(decoder->private_->stream_decoder);
+
+ if(decoder->private_->do_md5_checking) {
+ if(memcmp(decoder->private_->stored_md5sum, decoder->private_->computed_md5sum, 16))
+ md5_failed = true;
+ }
set_defaults_(decoder);
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED;
- return ok;
+ return !md5_failed;
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_md5_checking(OggFLAC__SeekableStreamDecoder *decoder, FLAC__bool value)
{
FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return false;
- return FLAC__seekable_stream_decoder_set_md5_checking(decoder->private_->FLAC_seekable_stream_decoder, value);
+ decoder->protected_->md5_checking = value;
+ return true;
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_read_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderReadCallback value)
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
+ FLAC__ASSERT(0 != decoder->private_->stream_decoder);
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return false;
- return FLAC__seekable_stream_decoder_set_metadata_respond(decoder->private_->FLAC_seekable_stream_decoder, type);
+ if(type == FLAC__METADATA_TYPE_STREAMINFO)
+ decoder->private_->ignore_stream_info_block = false;
+ else if(type == FLAC__METADATA_TYPE_SEEKTABLE)
+ decoder->private_->ignore_seek_table_block = false;
+ return OggFLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, type);
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_respond_application(OggFLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4])
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
+ FLAC__ASSERT(0 != decoder->private_->stream_decoder);
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return false;
- return FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder->private_->FLAC_seekable_stream_decoder, id);
+ return OggFLAC__stream_decoder_set_metadata_respond_application(decoder->private_->stream_decoder, id);
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_respond_all(OggFLAC__SeekableStreamDecoder *decoder)
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
+ FLAC__ASSERT(0 != decoder->private_->stream_decoder);
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return false;
- return FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder->private_->FLAC_seekable_stream_decoder);
+ decoder->private_->ignore_stream_info_block = false;
+ decoder->private_->ignore_seek_table_block = false;
+ return OggFLAC__stream_decoder_set_metadata_respond_all(decoder->private_->stream_decoder);
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_ignore(OggFLAC__SeekableStreamDecoder *decoder, FLAC__MetadataType type)
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
+ FLAC__ASSERT(0 != decoder->private_->stream_decoder);
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return false;
- return FLAC__seekable_stream_decoder_set_metadata_ignore(decoder->private_->FLAC_seekable_stream_decoder, type);
+ if(type == FLAC__METADATA_TYPE_STREAMINFO) {
+ decoder->private_->ignore_stream_info_block = true;
+ return true;
+ }
+ else if(type == FLAC__METADATA_TYPE_SEEKTABLE) {
+ decoder->private_->ignore_seek_table_block = true;
+ return true;
+ }
+ else
+ return OggFLAC__stream_decoder_set_metadata_ignore(decoder->private_->stream_decoder, type);
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_ignore_application(OggFLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4])
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
+ FLAC__ASSERT(0 != decoder->private_->stream_decoder);
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return false;
- return FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder->private_->FLAC_seekable_stream_decoder, id);
+ return OggFLAC__stream_decoder_set_metadata_ignore_application(decoder->private_->stream_decoder, id);
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_ignore_all(OggFLAC__SeekableStreamDecoder *decoder)
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
+ FLAC__ASSERT(0 != decoder->private_->stream_decoder);
if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
return false;
- return FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder->private_->FLAC_seekable_stream_decoder);
+ decoder->private_->ignore_stream_info_block = true;
+ decoder->private_->ignore_seek_table_block = true;
+ return
+ OggFLAC__stream_decoder_set_metadata_ignore_all(decoder->private_->stream_decoder) &&
+ OggFLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_STREAMINFO) &&
+ OggFLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_SEEKTABLE);
}
OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder_get_state(const OggFLAC__SeekableStreamDecoder *decoder)
return decoder->protected_->state;
}
-OggFLAC_API FLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state(const OggFLAC__SeekableStreamDecoder *decoder)
+OggFLAC_API OggFLAC__StreamDecoderState OggFLAC__seekable_stream_decoder_get_stream_decoder_state(const OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
- return FLAC__seekable_stream_decoder_get_state(decoder->private_->FLAC_seekable_stream_decoder);
+ return OggFLAC__stream_decoder_get_state(decoder->private_->stream_decoder);
}
OggFLAC_API FLAC__StreamDecoderState OggFLAC__seekable_stream_decoder_get_FLAC_stream_decoder_state(const OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
- return FLAC__seekable_stream_decoder_get_stream_decoder_state(decoder->private_->FLAC_seekable_stream_decoder);
+ return OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(decoder->private_->stream_decoder);
}
OggFLAC_API const char *OggFLAC__seekable_stream_decoder_get_resolved_state_string(const OggFLAC__SeekableStreamDecoder *decoder)
{
- if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR)
+ if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR)
return OggFLAC__SeekableStreamDecoderStateString[decoder->protected_->state];
else
- return FLAC__seekable_stream_decoder_get_resolved_state_string(decoder->private_->FLAC_seekable_stream_decoder);
+ return OggFLAC__stream_decoder_get_resolved_state_string(decoder->private_->stream_decoder);
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_get_md5_checking(const OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- return FLAC__seekable_stream_decoder_get_md5_checking(decoder->private_->FLAC_seekable_stream_decoder);
+ FLAC__ASSERT(0 != decoder->protected_);
+ return decoder->protected_->md5_checking;
}
OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_channels(const OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
- return FLAC__seekable_stream_decoder_get_channels(decoder->private_->FLAC_seekable_stream_decoder);
+ return OggFLAC__stream_decoder_get_channels(decoder->private_->stream_decoder);
}
OggFLAC_API FLAC__ChannelAssignment OggFLAC__seekable_stream_decoder_get_channel_assignment(const OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
- return FLAC__seekable_stream_decoder_get_channel_assignment(decoder->private_->FLAC_seekable_stream_decoder);
+ return OggFLAC__stream_decoder_get_channel_assignment(decoder->private_->stream_decoder);
}
OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_bits_per_sample(const OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
- return FLAC__seekable_stream_decoder_get_bits_per_sample(decoder->private_->FLAC_seekable_stream_decoder);
+ return OggFLAC__stream_decoder_get_bits_per_sample(decoder->private_->stream_decoder);
}
OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_sample_rate(const OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
- return FLAC__seekable_stream_decoder_get_sample_rate(decoder->private_->FLAC_seekable_stream_decoder);
+ return OggFLAC__stream_decoder_get_sample_rate(decoder->private_->stream_decoder);
}
OggFLAC_API unsigned OggFLAC__seekable_stream_decoder_get_blocksize(const OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
- return FLAC__seekable_stream_decoder_get_blocksize(decoder->private_->FLAC_seekable_stream_decoder);
+ return OggFLAC__stream_decoder_get_blocksize(decoder->private_->stream_decoder);
}
+#if 0
+@@@@@@ this can never be made to work without writing a custom Ogg decoder; remove for release
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_get_decode_position(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *position)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
- return FLAC__seekable_stream_decoder_get_decode_position(decoder->private_->FLAC_seekable_stream_decoder, position);
+ FLAC__ASSERT(0 != position);
+
+ if(decoder->private_->tell_callback(decoder, position, decoder->private_->client_data) != OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK)
+ return false;
+ FLAC__ASSERT(*position >= OggFLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder));
+ *position -= OggFLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder);
+ return true;
}
+#endif
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_flush(OggFLAC__SeekableStreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
- OggFLAC__ogg_decoder_aspect_flush(&decoder->protected_->ogg_decoder_aspect);
+ decoder->private_->do_md5_checking = false;
- if(!FLAC__seekable_stream_decoder_flush(decoder->private_->FLAC_seekable_stream_decoder)) {
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
+ if(!OggFLAC__stream_decoder_flush(decoder->private_->stream_decoder)) {
+ decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return false;
}
FLAC__ASSERT(0 != decoder->protected_);
if(!OggFLAC__seekable_stream_decoder_flush(decoder)) {
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
+ decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return false;
}
- if(!FLAC__seekable_stream_decoder_reset(decoder->private_->FLAC_seekable_stream_decoder)) {
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
+ if(!OggFLAC__stream_decoder_reset(decoder->private_->stream_decoder)) {
+ decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return false;
}
+ decoder->private_->seek_table = 0;
+
+ decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
+
+ /* We initialize the MD5Context even though we may never use it. This is
+ * because md5 checking may be turned on to start and then turned off if a
+ * seek occurs. So we always init the context here and finalize it in
+ * OggFLAC__seekable_stream_decoder_finish() to make sure things are always
+ * cleaned up properly.
+ */
+ MD5Init(&decoder->private_->md5context);
+
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
return true;
FLAC__bool ret;
FLAC__ASSERT(0 != decoder);
- if(FLAC__seekable_stream_decoder_get_state(decoder->private_->FLAC_seekable_stream_decoder) == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
+ if(decoder->private_->stream_decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK);
- ret = FLAC__seekable_stream_decoder_process_single(decoder->private_->FLAC_seekable_stream_decoder);
+ ret = OggFLAC__stream_decoder_process_single(decoder->private_->stream_decoder);
if(!ret)
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
+ decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return ret;
}
FLAC__bool ret;
FLAC__ASSERT(0 != decoder);
- if(FLAC__seekable_stream_decoder_get_state(decoder->private_->FLAC_seekable_stream_decoder) == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
+ if(decoder->private_->stream_decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK);
- ret = FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder->private_->FLAC_seekable_stream_decoder);
+ ret = OggFLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder);
if(!ret)
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
+ decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return ret;
}
FLAC__bool ret;
FLAC__ASSERT(0 != decoder);
- if(FLAC__seekable_stream_decoder_get_state(decoder->private_->FLAC_seekable_stream_decoder) == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
+ if(decoder->private_->stream_decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK);
- ret = FLAC__seekable_stream_decoder_process_until_end_of_stream(decoder->private_->FLAC_seekable_stream_decoder);
+ ret = OggFLAC__stream_decoder_process_until_end_of_stream(decoder->private_->stream_decoder);
if(!ret)
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
+ decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return ret;
}
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_seek_absolute(OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 sample)
{
+ FLAC__uint64 length;
+
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK || decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM);
- if(!FLAC__seekable_stream_decoder_seek_absolute(decoder->private_->FLAC_seekable_stream_decoder, sample)) {
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR;
+ decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING;
+
+ /* turn off md5 checking if a seek is attempted */
+ decoder->private_->do_md5_checking = false;
+
+ if(!OggFLAC__stream_decoder_reset(decoder->private_->stream_decoder)) {
+ decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
return false;
}
- else {
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
- return true;
+ /* get the file length */
+ if(decoder->private_->length_callback(decoder, &length, decoder->private_->client_data) != OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK) {
+ decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
+ return false;
+ }
+ /* rewind */
+ if(decoder->private_->seek_callback(decoder, 0, decoder->private_->client_data) != OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK) {
+ decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
+ return false;
+ }
+ if(!OggFLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder)) {
+ decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
+ return false;
+ }
+ if(decoder->private_->stream_info.total_samples > 0 && sample >= decoder->private_->stream_info.total_samples) {
+ decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
+ return false;
}
-}
+ return seek_to_absolute_sample_(decoder, length, sample);
+}
/***********************************************************************
*
decoder->private_->metadata_callback = 0;
decoder->private_->error_callback = 0;
decoder->private_->client_data = 0;
- OggFLAC__ogg_decoder_aspect_set_defaults(&decoder->protected_->ogg_decoder_aspect);
-}
-
-FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *unused, FLAC__byte buffer[], unsigned *bytes, void *client_data)
-{
- OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
-
- (void)unused;
-
- switch(OggFLAC__ogg_decoder_aspect_read_callback_wrapper(&decoder->protected_->ogg_decoder_aspect, buffer, bytes, read_callback_proxy_, decoder, decoder->private_->client_data)) {
- case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_OK:
- return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
- /* we don't really have a way to handle lost sync via read
- * callback so we'll let it pass and let the underlying
- * FLAC decoder catch the error
- */
- case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC:
- return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
- case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM:
- return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
- case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT:
- case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR:
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_READ_ERROR;
- return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
- case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR:
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
- default:
- FLAC__ASSERT(0);
- /* double protection */
- return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
- }
-}
-
-FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *unused, FLAC__uint64 absolute_byte_offset, void *client_data)
-{
- OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
- (void)unused;
-
- /* need to flush the Ogg state */
- OggFLAC__ogg_decoder_aspect_flush(&decoder->protected_->ogg_decoder_aspect);
+ /* WATCHOUT: these should match the default behavior of OggFLAC__StreamDecoder */
+ decoder->private_->ignore_stream_info_block = false;
+ decoder->private_->ignore_seek_table_block = true;
- return decoder->private_->seek_callback(decoder, absolute_byte_offset, decoder->private_->client_data);
+ decoder->protected_->md5_checking = false;
}
-FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *unused, FLAC__uint64 *absolute_byte_offset, void *client_data)
+FLAC__StreamDecoderReadStatus read_callback_(const OggFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
{
- OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
- (void)unused;
- return decoder->private_->tell_callback(decoder, absolute_byte_offset, decoder->private_->client_data);
+ OggFLAC__SeekableStreamDecoder *seekable_stream_decoder = (OggFLAC__SeekableStreamDecoder *)client_data;
+ (void)decoder;
+ if(seekable_stream_decoder->private_->eof_callback(seekable_stream_decoder, seekable_stream_decoder->private_->client_data)) {
+ *bytes = 0;
+#if 0
+@@@@@@ verify that this is not needed:
+ seekable_stream_decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
+#endif
+ return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
+ }
+ else if(*bytes > 0) {
+ if(seekable_stream_decoder->private_->read_callback(seekable_stream_decoder, buffer, bytes, seekable_stream_decoder->private_->client_data) != OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK) {
+ seekable_stream_decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_READ_ERROR;
+ return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
+ }
+ if(*bytes == 0) {
+ if(seekable_stream_decoder->private_->eof_callback(seekable_stream_decoder, seekable_stream_decoder->private_->client_data)) {
+#if 0
+@@@@@@ verify that this is not needed:
+ seekable_stream_decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
+#endif
+ return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
+ }
+ else
+ return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
+ }
+ else {
+ return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
+ }
+ }
+ else
+ return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
+}
+
+FLAC__StreamDecoderWriteStatus write_callback_(const OggFLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
+{
+ OggFLAC__SeekableStreamDecoder *seekable_stream_decoder = (OggFLAC__SeekableStreamDecoder *)client_data;
+ (void)decoder;
+
+ if(seekable_stream_decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING) {
+ FLAC__uint64 this_frame_sample = frame->header.number.sample_number;
+ FLAC__uint64 next_frame_sample = this_frame_sample + (FLAC__uint64)frame->header.blocksize;
+ FLAC__uint64 target_sample = seekable_stream_decoder->private_->target_sample;
+
+ FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
+
+ seekable_stream_decoder->private_->last_frame = *frame; /* save the frame */
+ if(this_frame_sample <= target_sample && target_sample < next_frame_sample) { /* we hit our target frame */
+ unsigned delta = (unsigned)(target_sample - this_frame_sample);
+ /* kick out of seek mode */
+ seekable_stream_decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
+ /* shift out the samples before target_sample */
+ if(delta > 0) {
+ unsigned channel;
+ const FLAC__int32 *newbuffer[FLAC__MAX_CHANNELS];
+ for(channel = 0; channel < frame->header.channels; channel++)
+ newbuffer[channel] = buffer[channel] + delta;
+ seekable_stream_decoder->private_->last_frame.header.blocksize -= delta;
+ seekable_stream_decoder->private_->last_frame.header.number.sample_number += (FLAC__uint64)delta;
+ /* write the relevant samples */
+ return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, &seekable_stream_decoder->private_->last_frame, newbuffer, seekable_stream_decoder->private_->client_data);
+ }
+ else {
+ /* write the relevant samples */
+ return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, frame, buffer, seekable_stream_decoder->private_->client_data);
+ }
+ }
+ else {
+ return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+ }
+ }
+ else {
+ if(seekable_stream_decoder->private_->do_md5_checking) {
+ if(!FLAC__MD5Accumulate(&seekable_stream_decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8))
+ return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+ }
+ return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, frame, buffer, seekable_stream_decoder->private_->client_data);
+ }
}
-FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *unused, FLAC__uint64 *stream_length, void *client_data)
+void metadata_callback_(const OggFLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
{
- OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
- (void)unused;
- return decoder->private_->length_callback(decoder, stream_length, decoder->private_->client_data);
-}
+ OggFLAC__SeekableStreamDecoder *seekable_stream_decoder = (OggFLAC__SeekableStreamDecoder *)client_data;
+ (void)decoder;
-FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *unused, void *client_data)
-{
- OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
- (void)unused;
- return decoder->private_->eof_callback(decoder, decoder->private_->client_data);
-}
+ if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
+ seekable_stream_decoder->private_->stream_info = metadata->data.stream_info;
+ /* save the MD5 signature for comparison later */
+ memcpy(seekable_stream_decoder->private_->stored_md5sum, metadata->data.stream_info.md5sum, 16);
+ if(0 == memcmp(seekable_stream_decoder->private_->stored_md5sum, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16))
+ seekable_stream_decoder->private_->do_md5_checking = false;
+ }
+ else if(metadata->type == FLAC__METADATA_TYPE_SEEKTABLE) {
+ seekable_stream_decoder->private_->seek_table = &metadata->data.seek_table;
+ }
-FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *unused, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
-{
- OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
- (void)unused;
- return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
+ if(seekable_stream_decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING) {
+ FLAC__bool ignore_block = false;
+ if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO && seekable_stream_decoder->private_->ignore_stream_info_block)
+ ignore_block = true;
+ else if(metadata->type == FLAC__METADATA_TYPE_SEEKTABLE && seekable_stream_decoder->private_->ignore_seek_table_block)
+ ignore_block = true;
+ if(!ignore_block)
+ seekable_stream_decoder->private_->metadata_callback(seekable_stream_decoder, metadata, seekable_stream_decoder->private_->client_data);
+ }
}
-void metadata_callback_(const FLAC__SeekableStreamDecoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
+void error_callback_(const OggFLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
{
- OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
- (void)unused;
- decoder->private_->metadata_callback(decoder, metadata, decoder->private_->client_data);
-}
+ OggFLAC__SeekableStreamDecoder *seekable_stream_decoder = (OggFLAC__SeekableStreamDecoder *)client_data;
+ (void)decoder;
-void error_callback_(const FLAC__SeekableStreamDecoder *unused, FLAC__StreamDecoderErrorStatus status, void *client_data)
-{
- OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)client_data;
- (void)unused;
- decoder->private_->error_callback(decoder, status, decoder->private_->client_data);
+ if(seekable_stream_decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING)
+ seekable_stream_decoder->private_->error_callback(seekable_stream_decoder, status, seekable_stream_decoder->private_->client_data);
}
-OggFLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
+FLAC__bool seek_to_absolute_sample_(OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample)
{
- OggFLAC__SeekableStreamDecoder *decoder = (OggFLAC__SeekableStreamDecoder*)void_decoder;
+ FLAC__uint64 left_pos = 0, right_pos = stream_length;
+ FLAC__uint64 left_sample = 0, right_sample = decoder->private_->stream_info.total_samples;
+ unsigned iteration = 0;
- switch(decoder->private_->read_callback(decoder, buffer, bytes, client_data)) {
- case FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK:
- if (*bytes == 0)
- return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM;
- else
- return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_OK;
- case FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR:
- return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
- default:
- /* double protection: */
- FLAC__ASSERT(0);
- return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
+ /* In the first iterations, we will calculate the target byte position
+ * by the distance from the target sample to left_sample and
+ * right_sample. After that, we will switch to binary search.
+ */
+ static const unsigned BINARY_SEARCH_AFTER_ITERATION = 2;
+
+ /* We will switch to a linear search once our current sample is less
+ * that this number of samples ahead of the target sample
+ */
+ static const FLAC__uint64 LINEAR_SEARCH_WITHIN_SAMPLES = FLAC__MAX_BLOCK_SIZE * 2;
+
+ /* If the total number of samples is unknown, use a large value and
+ * increase 'iteration' to force binary search immediately.
+ */
+ if(right_sample == 0) {
+ right_sample = (FLAC__uint64)(-1);
+ iteration = BINARY_SEARCH_AFTER_ITERATION;
}
+
+ decoder->private_->target_sample = target_sample;
+ for( ; ; iteration++) {
+ if(!OggFLAC__stream_decoder_process_single(decoder->private_->stream_decoder)) {
+ decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
+ return false;
+ }
+ /* our write callback will change the state when it gets to the target frame */
+ if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING) {
+ break;
+ }
+ else {
+ const FLAC__uint64 this_frame_sample = decoder->private_->last_frame.header.number.sample_number;
+ FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
+
+ if (this_frame_sample > target_sample || target_sample - this_frame_sample > LINEAR_SEARCH_WITHIN_SAMPLES) {
+ FLAC__uint64 pos;
+
+ if (iteration >= BINARY_SEARCH_AFTER_ITERATION)
+ pos = (right_pos + left_pos) / 2;
+ else
+ pos = (FLAC__uint64)((double)(target_sample - left_sample) / (double)(right_pos - left_pos));
+
+ if (this_frame_sample <= target_sample) {
+ /* The 'equal' case should not happen, since
+ * OggFLAC__stream_decoder_process_single()
+ * should recognize that it has hit the
+ * target sample and we would exit through
+ * the 'break' above.
+ */
+ FLAC__ASSERT(this_frame_sample != target_sample);
+
+ left_sample = this_frame_sample;
+ left_pos = pos;
+ }
+ else if(this_frame_sample > target_sample) {
+ right_sample = this_frame_sample;
+ right_pos = pos;
+ }
+
+ /* physical seek */
+ if(decoder->private_->seek_callback(decoder, (FLAC__uint64)pos, decoder->private_->client_data) != OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK) {
+ decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
+ return false;
+ }
+ if(!OggFLAC__stream_decoder_flush(decoder->private_->stream_decoder)) {
+ decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
}
~SeekableStreamDecoder() { }
// from OggFLAC::Decoder::SeekableStream
- ::FLAC__SeekableStreamDecoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes);
- ::FLAC__SeekableStreamDecoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset);
- ::FLAC__SeekableStreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset);
- ::FLAC__SeekableStreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length);
+ ::OggFLAC__SeekableStreamDecoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes);
+ ::OggFLAC__SeekableStreamDecoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset);
+ ::OggFLAC__SeekableStreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset);
+ ::OggFLAC__SeekableStreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length);
bool eof_callback();
::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
void metadata_callback(const ::FLAC__StreamMetadata *metadata);
bool test_respond();
};
-::FLAC__SeekableStreamDecoderReadStatus SeekableStreamDecoder::read_callback(FLAC__byte buffer[], unsigned *bytes)
+::OggFLAC__SeekableStreamDecoderReadStatus SeekableStreamDecoder::read_callback(FLAC__byte buffer[], unsigned *bytes)
{
switch(common_read_callback_(buffer, bytes)) {
case ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE:
case ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM:
- return ::FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
+ return ::OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
case ::FLAC__STREAM_DECODER_READ_STATUS_ABORT:
- return ::FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
+ return ::OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
default:
FLAC__ASSERT(0);
- return ::FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
+ return ::OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
}
}
-::FLAC__SeekableStreamDecoderSeekStatus SeekableStreamDecoder::seek_callback(FLAC__uint64 absolute_byte_offset)
+::OggFLAC__SeekableStreamDecoderSeekStatus SeekableStreamDecoder::seek_callback(FLAC__uint64 absolute_byte_offset)
{
if(error_occurred_)
- return ::FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
+ return ::OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
if(::fseek(file_, (long)absolute_byte_offset, SEEK_SET) < 0) {
error_occurred_ = true;
- return ::FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
+ return ::OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
}
- return ::FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
+ return ::OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
}
-::FLAC__SeekableStreamDecoderTellStatus SeekableStreamDecoder::tell_callback(FLAC__uint64 *absolute_byte_offset)
+::OggFLAC__SeekableStreamDecoderTellStatus SeekableStreamDecoder::tell_callback(FLAC__uint64 *absolute_byte_offset)
{
if(error_occurred_)
- return ::FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
+ return ::OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
long offset = ::ftell(file_);
*absolute_byte_offset = (FLAC__uint64)offset;
if(offset < 0) {
error_occurred_ = true;
- return ::FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
+ return ::OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
}
- return ::FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
+ return ::OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
}
-::FLAC__SeekableStreamDecoderLengthStatus SeekableStreamDecoder::length_callback(FLAC__uint64 *stream_length)
+::OggFLAC__SeekableStreamDecoderLengthStatus SeekableStreamDecoder::length_callback(FLAC__uint64 *stream_length)
{
if(error_occurred_)
- return ::FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
+ return ::OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
*stream_length = (FLAC__uint64)oggflacfilesize_;
- return ::FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
+ return ::OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
}
bool SeekableStreamDecoder::eof_callback()
printf("FAILED");
printf(", state = %u (%s)\n", (unsigned)((::OggFLAC__SeekableStreamDecoderState)state), state.as_cstring());
- if(state == ::OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR) {
- FLAC::Decoder::SeekableStream::State state_ = get_FLAC_seekable_stream_decoder_state();
- printf(" FLAC seekable stream decoder state = %u (%s)\n", (unsigned)((::FLAC__SeekableStreamDecoderState)state_), state_.as_cstring());
- if(state_ == ::FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
+ if(state == ::OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
+ OggFLAC::Decoder::Stream::State state_ = get_stream_decoder_state();
+ printf(" stream decoder state = %u (%s)\n", (unsigned)((::OggFLAC__StreamDecoderState)state_), state_.as_cstring());
+ if(state_ == ::OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR) {
FLAC::Decoder::Stream::State state__ = get_FLAC_stream_decoder_state();
printf(" FLAC stream decoder state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state__), state__.as_cstring());
}
OggFLAC::Decoder::SeekableStream::State state = decoder->get_state();
printf("returned state = %u (%s)... OK\n", (unsigned)((::OggFLAC__SeekableStreamDecoderState)state), state.as_cstring());
- printf("testing get_FLAC_seekable_stream_decoder_state()... ");
- FLAC::Decoder::SeekableStream::State state_ = decoder->get_FLAC_seekable_stream_decoder_state();
- printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__SeekableStreamDecoderState)state_), state_.as_cstring());
+ printf("testing get_stream_decoder_state()... ");
+ OggFLAC::Decoder::Stream::State state_ = decoder->get_stream_decoder_state();
+ printf("returned state = %u (%s)... OK\n", (unsigned)((::OggFLAC__StreamDecoderState)state_), state_.as_cstring());
printf("testing get_FLAC_stream_decoder_state()... ");
FLAC::Decoder::Stream::State state__ = decoder->get_FLAC_stream_decoder_state();
if(state == ::OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR) {
OggFLAC::Decoder::SeekableStream::State state_ = get_seekable_stream_decoder_state();
printf(" seekable stream decoder state = %u (%s)\n", (unsigned)((::OggFLAC__SeekableStreamDecoderState)state_), state_.as_cstring());
- if(state_ == ::OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR) {
- FLAC::Decoder::SeekableStream::State state__ = get_FLAC_seekable_stream_decoder_state();
- printf(" FLAC seekable stream decoder state = %u (%s)\n", (unsigned)((::FLAC__SeekableStreamDecoderState)state__), state__.as_cstring());
- if(state__ == ::FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
+ if(state_ == ::OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
+ OggFLAC::Decoder::Stream::State state__ = get_stream_decoder_state();
+ printf(" stream decoder state = %u (%s)\n", (unsigned)((::OggFLAC__StreamDecoderState)state__), state__.as_cstring());
+ if(state__ == ::OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR) {
FLAC::Decoder::Stream::State state___ = get_FLAC_stream_decoder_state();
printf(" FLAC stream decoder state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state___), state___.as_cstring());
}
OggFLAC::Decoder::SeekableStream::State state_ = decoder->get_seekable_stream_decoder_state();
printf("returned state = %u (%s)... OK\n", (unsigned)((::OggFLAC__SeekableStreamDecoderState)state_), state_.as_cstring());
- printf("testing get_FLAC_seekable_stream_decoder_state()... ");
- FLAC::Decoder::SeekableStream::State state__ = decoder->get_FLAC_seekable_stream_decoder_state();
- printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__SeekableStreamDecoderState)state__), state__.as_cstring());
+ printf("testing get_stream_decoder_state()... ");
+ OggFLAC::Decoder::Stream::State state__ = decoder->get_stream_decoder_state();
+ printf("returned state = %u (%s)... OK\n", (unsigned)((::OggFLAC__StreamDecoderState)state__), state__.as_cstring());
printf("testing get_FLAC_stream_decoder_state()... ");
FLAC::Decoder::Stream::State state___ = decoder->get_FLAC_stream_decoder_state();
printf("FAILED");
printf(", state = %u (%s)\n", (unsigned)state, OggFLAC__SeekableStreamDecoderStateString[state]);
- if(state == OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR) {
- FLAC__SeekableStreamDecoderState state_ = OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state(decoder);
- printf(" FLAC seekable stream decoder state = %u (%s)\n", (unsigned)state_, FLAC__SeekableStreamDecoderStateString[state_]);
- if(state_ == FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
+ if(state == OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
+ OggFLAC__StreamDecoderState state_ = OggFLAC__seekable_stream_decoder_get_stream_decoder_state(decoder);
+ printf(" stream decoder state = %u (%s)\n", (unsigned)state_, OggFLAC__StreamDecoderStateString[state_]);
+ if(state_ == OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR) {
FLAC__StreamDecoderState state__ = OggFLAC__seekable_stream_decoder_get_FLAC_stream_decoder_state(decoder);
printf(" FLAC stream decoder state = %u (%s)\n", (unsigned)state__, FLAC__StreamDecoderStateString[state__]);
}
if(state == OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR) {
OggFLAC__SeekableStreamDecoderState state_ = OggFLAC__file_decoder_get_seekable_stream_decoder_state(decoder);
printf(" seekable stream decoder state = %u (%s)\n", (unsigned)state_, OggFLAC__SeekableStreamDecoderStateString[state_]);
- if(state_ == OggFLAC__SEEKABLE_STREAM_DECODER_FLAC_SEEKABLE_STREAM_DECODER_ERROR) {
- FLAC__SeekableStreamDecoderState state__ = OggFLAC__file_decoder_get_FLAC_seekable_stream_decoder_state(decoder);
- printf(" FLAC seekable stream decoder state = %u (%s)\n", (unsigned)state__, FLAC__SeekableStreamDecoderStateString[state__]);
- if(state__ == FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
+ if(state_ == OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) {
+ OggFLAC__StreamDecoderState state__ = OggFLAC__file_decoder_get_stream_decoder_state(decoder);
+ printf(" stream decoder state = %u (%s)\n", (unsigned)state__, OggFLAC__StreamDecoderStateString[state__]);
+ if(state__ == OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR) {
FLAC__StreamDecoderState state___ = OggFLAC__file_decoder_get_FLAC_stream_decoder_state(decoder);
printf(" FLAC stream decoder state = %u (%s)\n", (unsigned)state___, FLAC__StreamDecoderStateString[state___]);
}
return true;
}
-static FLAC__SeekableStreamDecoderReadStatus seekable_stream_decoder_read_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
+static OggFLAC__SeekableStreamDecoderReadStatus seekable_stream_decoder_read_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
{
(void)decoder;
switch(stream_decoder_read_callback_(0, buffer, bytes, client_data)) {
case FLAC__STREAM_DECODER_READ_STATUS_CONTINUE:
case FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM:
- return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
case FLAC__STREAM_DECODER_READ_STATUS_ABORT:
- return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
default:
FLAC__ASSERT(0);
- return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
}
}
-static FLAC__SeekableStreamDecoderSeekStatus seekable_stream_decoder_seek_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
+static OggFLAC__SeekableStreamDecoderSeekStatus seekable_stream_decoder_seek_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
{
seekable_stream_decoder_client_data_struct *dcd = (seekable_stream_decoder_client_data_struct*)client_data;
if(0 == dcd) {
printf("ERROR: client_data in seek callback is NULL\n");
- return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
}
if(dcd->error_occurred)
- return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
if(fseek(dcd->file, (long)absolute_byte_offset, SEEK_SET) < 0) {
dcd->error_occurred = true;
- return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
}
- return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
}
-static FLAC__SeekableStreamDecoderTellStatus seekable_stream_decoder_tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
+static OggFLAC__SeekableStreamDecoderTellStatus seekable_stream_decoder_tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
{
seekable_stream_decoder_client_data_struct *dcd = (seekable_stream_decoder_client_data_struct*)client_data;
long offset;
if(0 == dcd) {
printf("ERROR: client_data in tell callback is NULL\n");
- return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
}
if(dcd->error_occurred)
- return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
offset = ftell(dcd->file);
*absolute_byte_offset = (FLAC__uint64)offset;
if(offset < 0) {
dcd->error_occurred = true;
- return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
}
- return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
}
-static FLAC__SeekableStreamDecoderLengthStatus seekable_stream_decoder_length_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
+static OggFLAC__SeekableStreamDecoderLengthStatus seekable_stream_decoder_length_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
{
seekable_stream_decoder_client_data_struct *dcd = (seekable_stream_decoder_client_data_struct*)client_data;
if(0 == dcd) {
printf("ERROR: client_data in length callback is NULL\n");
- return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
}
if(dcd->error_occurred)
- return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
*stream_length = (FLAC__uint64)oggflacfilesize_;
- return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
+ return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
}
static FLAC__bool seekable_stream_decoder_eof_callback_(const OggFLAC__SeekableStreamDecoder *decoder, void *client_data)
{
OggFLAC__SeekableStreamDecoder *decoder;
OggFLAC__SeekableStreamDecoderState state;
- FLAC__SeekableStreamDecoderState fsstate;
+ OggFLAC__StreamDecoderState sstate;
FLAC__StreamDecoderState fstate;
seekable_stream_decoder_client_data_struct decoder_client_data;
state = OggFLAC__seekable_stream_decoder_get_state(decoder);
printf("returned state = %u (%s)... OK\n", state, OggFLAC__SeekableStreamDecoderStateString[state]);
- printf("testing OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state()... ");
- fsstate = OggFLAC__seekable_stream_decoder_get_FLAC_seekable_stream_decoder_state(decoder);
- printf("returned state = %u (%s)... OK\n", fsstate, FLAC__SeekableStreamDecoderStateString[fsstate]);
+ printf("testing OggFLAC__seekable_stream_decoder_get_stream_decoder_state()... ");
+ sstate = OggFLAC__seekable_stream_decoder_get_stream_decoder_state(decoder);
+ printf("returned state = %u (%s)... OK\n", sstate, OggFLAC__StreamDecoderStateString[sstate]);
printf("testing OggFLAC__seekable_stream_decoder_get_FLAC_stream_decoder_state()... ");
fstate = OggFLAC__seekable_stream_decoder_get_FLAC_stream_decoder_state(decoder);
{
OggFLAC__FileDecoder *decoder;
OggFLAC__FileDecoderState state;
- OggFLAC__SeekableStreamDecoderState sstate;
- FLAC__SeekableStreamDecoderState fsstate;
+ OggFLAC__SeekableStreamDecoderState ssstate;
+ OggFLAC__StreamDecoderState sstate;
FLAC__StreamDecoderState fstate;
seekable_stream_decoder_client_data_struct decoder_client_data;
printf("returned state = %u (%s)... OK\n", state, OggFLAC__FileDecoderStateString[state]);
printf("testing OggFLAC__file_decoder_get_seekable_stream_decoder_state()... ");
- sstate = OggFLAC__file_decoder_get_seekable_stream_decoder_state(decoder);
- printf("returned state = %u (%s)... OK\n", sstate, OggFLAC__SeekableStreamDecoderStateString[sstate]);
+ ssstate = OggFLAC__file_decoder_get_seekable_stream_decoder_state(decoder);
+ printf("returned state = %u (%s)... OK\n", ssstate, OggFLAC__SeekableStreamDecoderStateString[ssstate]);
- printf("testing OggFLAC__file_decoder_get_FLAC_seekable_stream_decoder_state()... ");
- fsstate = OggFLAC__file_decoder_get_FLAC_seekable_stream_decoder_state(decoder);
- printf("returned state = %u (%s)... OK\n", fsstate, FLAC__SeekableStreamDecoderStateString[fsstate]);
+ printf("testing OggFLAC__file_decoder_get_stream_decoder_state()... ");
+ sstate = OggFLAC__file_decoder_get_stream_decoder_state(decoder);
+ printf("returned state = %u (%s)... OK\n", sstate, OggFLAC__StreamDecoderStateString[sstate]);
printf("testing OggFLAC__file_decoder_get_FLAC_stream_decoder_state()... ");
fstate = OggFLAC__file_decoder_get_FLAC_stream_decoder_state(decoder);