summaryrefslogtreecommitdiff
path: root/src/libOggFLAC
diff options
context:
space:
mode:
Diffstat (limited to 'src/libOggFLAC')
-rw-r--r--src/libOggFLAC/Makefile.am4
-rw-r--r--src/libOggFLAC/Makefile.lite4
-rw-r--r--src/libOggFLAC/file_decoder.c672
-rw-r--r--src/libOggFLAC/file_encoder.c835
-rw-r--r--src/libOggFLAC/include/private/ogg_decoder_aspect.h3
-rw-r--r--src/libOggFLAC/include/private/ogg_helper.h6
-rw-r--r--src/libOggFLAC/include/protected/Makefile.am4
-rw-r--r--src/libOggFLAC/include/protected/all.h4
-rw-r--r--src/libOggFLAC/include/protected/file_decoder.h41
-rw-r--r--src/libOggFLAC/include/protected/file_encoder.h41
-rw-r--r--src/libOggFLAC/include/protected/seekable_stream_decoder.h42
-rw-r--r--src/libOggFLAC/include/protected/seekable_stream_encoder.h44
-rw-r--r--src/libOggFLAC/include/protected/stream_encoder.h1
-rw-r--r--src/libOggFLAC/libOggFLAC_dynamic.dsp48
-rw-r--r--src/libOggFLAC/libOggFLAC_static.dsp48
-rw-r--r--src/libOggFLAC/ogg_decoder_aspect.c2
-rw-r--r--src/libOggFLAC/ogg_encoder_aspect.c2
-rw-r--r--src/libOggFLAC/ogg_helper.c53
-rw-r--r--src/libOggFLAC/seekable_stream_decoder.c982
-rw-r--r--src/libOggFLAC/seekable_stream_encoder.c1078
-rw-r--r--src/libOggFLAC/stream_decoder.c763
-rw-r--r--src/libOggFLAC/stream_encoder.c759
22 files changed, 1306 insertions, 4130 deletions
diff --git a/src/libOggFLAC/Makefile.am b/src/libOggFLAC/Makefile.am
index aa4eaf3c..7b198eb1 100644
--- a/src/libOggFLAC/Makefile.am
+++ b/src/libOggFLAC/Makefile.am
@@ -51,13 +51,9 @@ libOggFLAC_la_LIBADD = @OGG_LIBS@ ../libFLAC/libFLAC.la
libOggFLAC_la_LDFLAGS = -version-info 3:0:0
libOggFLAC_la_SOURCES = \
- file_decoder.c \
- file_encoder.c \
ogg_decoder_aspect.c \
ogg_encoder_aspect.c \
ogg_helper.c \
ogg_mapping.c \
- seekable_stream_decoder.c \
- seekable_stream_encoder.c \
stream_decoder.c \
stream_encoder.c
diff --git a/src/libOggFLAC/Makefile.lite b/src/libOggFLAC/Makefile.lite
index 9144a22f..1f10aed3 100644
--- a/src/libOggFLAC/Makefile.lite
+++ b/src/libOggFLAC/Makefile.lite
@@ -48,14 +48,10 @@ INCLUDES = -I./include -I$(topdir)/include -I$(OGG_INCLUDE_DIR)
DEBUG_CFLAGS =
SRCS_C = \
- file_decoder.c \
- file_encoder.c \
ogg_decoder_aspect.c \
ogg_encoder_aspect.c \
ogg_helper.c \
ogg_mapping.c \
- seekable_stream_decoder.c \
- seekable_stream_encoder.c \
stream_decoder.c \
stream_encoder.c
diff --git a/src/libOggFLAC/file_decoder.c b/src/libOggFLAC/file_decoder.c
deleted file mode 100644
index 926f6bc0..00000000
--- a/src/libOggFLAC/file_decoder.c
+++ /dev/null
@@ -1,672 +0,0 @@
-/* libOggFLAC - Free Lossless Audio Codec + Ogg library
- * Copyright (C) 2002,2003,2004,2005,2006 Josh Coalson
- *
- * 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.
- */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h> /* for malloc() */
-#include <string.h> /* for strcmp() */
-#include <sys/stat.h> /* for stat() */
-#if defined _MSC_VER || defined __MINGW32__
-#include <io.h> /* for _setmode() */
-#include <fcntl.h> /* for _O_BINARY */
-#include <sys/types.h> /* for off_t */
-//@@@ [2G limit] hacks for MSVC6
-#define fseeko fseek
-#define ftello ftell
-#elif defined __CYGWIN__
-#include <io.h> /* for setmode(), O_BINARY */
-#include <fcntl.h> /* for _O_BINARY */
-#endif
-#include "FLAC/assert.h"
-#include "protected/file_decoder.h"
-#include "protected/seekable_stream_decoder.h"
-
-/***********************************************************************
- *
- * Private class method prototypes
- *
- ***********************************************************************/
-
-static void set_defaults_(OggFLAC__FileDecoder *decoder);
-static FILE *get_binary_stdin_();
-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);
-static void error_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
-
-/***********************************************************************
- *
- * Private class data
- *
- ***********************************************************************/
-
-typedef struct OggFLAC__FileDecoderPrivate {
- OggFLAC__FileDecoderWriteCallback write_callback;
- OggFLAC__FileDecoderMetadataCallback metadata_callback;
- OggFLAC__FileDecoderErrorCallback error_callback;
- void *client_data;
- FILE *file;
- char *filename; /* == NULL if stdin */
- OggFLAC__SeekableStreamDecoder *seekable_stream_decoder;
-} OggFLAC__FileDecoderPrivate;
-
-/***********************************************************************
- *
- * Public static class data
- *
- ***********************************************************************/
-
-OggFLAC_API const char * const OggFLAC__FileDecoderStateString[] = {
- "OggFLAC__FILE_DECODER_OK",
- "OggFLAC__FILE_DECODER_END_OF_FILE",
- "OggFLAC__FILE_DECODER_ERROR_OPENING_FILE",
- "OggFLAC__FILE_DECODER_SEEK_ERROR",
- "OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR",
- "OggFLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR",
- "OggFLAC__FILE_DECODER_ALREADY_INITIALIZED",
- "OggFLAC__FILE_DECODER_INVALID_CALLBACK",
- "OggFLAC__FILE_DECODER_UNINITIALIZED"
-};
-
-/***********************************************************************
- *
- * Class constructor/destructor
- *
- ***********************************************************************/
-
-OggFLAC_API OggFLAC__FileDecoder *OggFLAC__file_decoder_new()
-{
- OggFLAC__FileDecoder *decoder;
-
- FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
-
- decoder = (OggFLAC__FileDecoder*)calloc(1, sizeof(OggFLAC__FileDecoder));
- if(decoder == 0) {
- return 0;
- }
-
- decoder->protected_ = (OggFLAC__FileDecoderProtected*)calloc(1, sizeof(OggFLAC__FileDecoderProtected));
- if(decoder->protected_ == 0) {
- free(decoder);
- return 0;
- }
-
- decoder->private_ = (OggFLAC__FileDecoderPrivate*)calloc(1, sizeof(OggFLAC__FileDecoderPrivate));
- if(decoder->private_ == 0) {
- free(decoder->protected_);
- free(decoder);
- return 0;
- }
-
- decoder->private_->seekable_stream_decoder = OggFLAC__seekable_stream_decoder_new();
- if(0 == decoder->private_->seekable_stream_decoder) {
- free(decoder->private_);
- free(decoder->protected_);
- free(decoder);
- return 0;
- }
-
- decoder->private_->file = 0;
-
- set_defaults_(decoder);
-
- decoder->protected_->state = OggFLAC__FILE_DECODER_UNINITIALIZED;
-
- return decoder;
-}
-
-OggFLAC_API void OggFLAC__file_decoder_delete(OggFLAC__FileDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
-
- (void)OggFLAC__file_decoder_finish(decoder);
-
- OggFLAC__seekable_stream_decoder_delete(decoder->private_->seekable_stream_decoder);
-
- free(decoder->private_);
- free(decoder->protected_);
- free(decoder);
-}
-
-/***********************************************************************
- *
- * Public class methods
- *
- ***********************************************************************/
-
-OggFLAC_API OggFLAC__FileDecoderState OggFLAC__file_decoder_init(OggFLAC__FileDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
-
- if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
- return decoder->protected_->state = OggFLAC__FILE_DECODER_ALREADY_INITIALIZED;
-
- if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
- return decoder->protected_->state = OggFLAC__FILE_DECODER_INVALID_CALLBACK;
-
- if(0 == decoder->private_->filename)
- decoder->private_->file = get_binary_stdin_();
- else
- decoder->private_->file = fopen(decoder->private_->filename, "rb");
-
- if(decoder->private_->file == 0)
- return decoder->protected_->state = OggFLAC__FILE_DECODER_ERROR_OPENING_FILE;
-
- OggFLAC__seekable_stream_decoder_set_read_callback(decoder->private_->seekable_stream_decoder, read_callback_);
- OggFLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->seekable_stream_decoder, seek_callback_);
- OggFLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->seekable_stream_decoder, tell_callback_);
- OggFLAC__seekable_stream_decoder_set_length_callback(decoder->private_->seekable_stream_decoder, length_callback_);
- OggFLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->seekable_stream_decoder, eof_callback_);
- OggFLAC__seekable_stream_decoder_set_write_callback(decoder->private_->seekable_stream_decoder, write_callback_);
- OggFLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->seekable_stream_decoder, metadata_callback_);
- OggFLAC__seekable_stream_decoder_set_error_callback(decoder->private_->seekable_stream_decoder, error_callback_);
- OggFLAC__seekable_stream_decoder_set_client_data(decoder->private_->seekable_stream_decoder, decoder);
-
- if(OggFLAC__seekable_stream_decoder_init(decoder->private_->seekable_stream_decoder) != OggFLAC__SEEKABLE_STREAM_DECODER_OK)
- return decoder->protected_->state = OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
-
- return decoder->protected_->state = OggFLAC__FILE_DECODER_OK;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_finish(OggFLAC__FileDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
-
- if(decoder->protected_->state == OggFLAC__FILE_DECODER_UNINITIALIZED)
- return true;
-
- FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
-
- if(0 != decoder->private_->file && decoder->private_->file != stdin) {
- fclose(decoder->private_->file);
- decoder->private_->file = 0;
- }
-
- if(0 != decoder->private_->filename) {
- free(decoder->private_->filename);
- decoder->private_->filename = 0;
- }
-
- set_defaults_(decoder);
-
- decoder->protected_->state = OggFLAC__FILE_DECODER_UNINITIALIZED;
-
- return OggFLAC__seekable_stream_decoder_finish(decoder->private_->seekable_stream_decoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_md5_checking(OggFLAC__FileDecoder *decoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
- if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_decoder_set_md5_checking(decoder->private_->seekable_stream_decoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_filename(OggFLAC__FileDecoder *decoder, const char *value)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- FLAC__ASSERT(0 != value);
- if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
- return false;
- if(0 != decoder->private_->filename) {
- free(decoder->private_->filename);
- decoder->private_->filename = 0;
- }
- if(0 != strcmp(value, "-")) {
- if(0 == (decoder->private_->filename = (char*)malloc(strlen(value)+1))) {
- decoder->protected_->state = OggFLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- strcpy(decoder->private_->filename, value);
- }
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_write_callback(OggFLAC__FileDecoder *decoder, OggFLAC__FileDecoderWriteCallback value)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
- return false;
- decoder->private_->write_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_callback(OggFLAC__FileDecoder *decoder, OggFLAC__FileDecoderMetadataCallback value)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
- return false;
- decoder->private_->metadata_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_error_callback(OggFLAC__FileDecoder *decoder, OggFLAC__FileDecoderErrorCallback value)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
- return false;
- decoder->private_->error_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_client_data(OggFLAC__FileDecoder *decoder, void *value)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
- return false;
- decoder->private_->client_data = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_serial_number(OggFLAC__FileDecoder *decoder, long value)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
- return false;
- OggFLAC__seekable_stream_decoder_set_serial_number(decoder->private_->seekable_stream_decoder, value);
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_respond(OggFLAC__FileDecoder *decoder, FLAC__MetadataType type)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
- if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_decoder_set_metadata_respond(decoder->private_->seekable_stream_decoder, type);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_respond_application(OggFLAC__FileDecoder *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_->seekable_stream_decoder);
- if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_decoder_set_metadata_respond_application(decoder->private_->seekable_stream_decoder, id);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_respond_all(OggFLAC__FileDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
- if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_decoder_set_metadata_respond_all(decoder->private_->seekable_stream_decoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_ignore(OggFLAC__FileDecoder *decoder, FLAC__MetadataType type)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
- if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_decoder_set_metadata_ignore(decoder->private_->seekable_stream_decoder, type);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_ignore_application(OggFLAC__FileDecoder *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_->seekable_stream_decoder);
- if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder->private_->seekable_stream_decoder, id);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_set_metadata_ignore_all(OggFLAC__FileDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder);
- if(decoder->protected_->state != OggFLAC__FILE_DECODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder->private_->seekable_stream_decoder);
-}
-
-OggFLAC_API OggFLAC__FileDecoderState OggFLAC__file_decoder_get_state(const OggFLAC__FileDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
- return decoder->protected_->state;
-}
-
-OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__file_decoder_get_seekable_stream_decoder_state(const OggFLAC__FileDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- return OggFLAC__seekable_stream_decoder_get_state(decoder->private_->seekable_stream_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_stream_decoder_state(decoder->private_->seekable_stream_decoder);
-}
-
-OggFLAC_API FLAC__StreamDecoderState OggFLAC__file_decoder_get_FLAC_stream_decoder_state(const OggFLAC__FileDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- return OggFLAC__seekable_stream_decoder_get_FLAC_stream_decoder_state(decoder->private_->seekable_stream_decoder);
-}
-
-OggFLAC_API const char *OggFLAC__file_decoder_get_resolved_state_string(const OggFLAC__FileDecoder *decoder)
-{
- if(decoder->protected_->state != OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR)
- return OggFLAC__FileDecoderStateString[decoder->protected_->state];
- else
- return OggFLAC__seekable_stream_decoder_get_resolved_state_string(decoder->private_->seekable_stream_decoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_get_md5_checking(const OggFLAC__FileDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- return OggFLAC__seekable_stream_decoder_get_md5_checking(decoder->private_->seekable_stream_decoder);
-}
-
-OggFLAC_API unsigned OggFLAC__file_decoder_get_channels(const OggFLAC__FileDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- return OggFLAC__seekable_stream_decoder_get_channels(decoder->private_->seekable_stream_decoder);
-}
-
-OggFLAC_API FLAC__ChannelAssignment OggFLAC__file_decoder_get_channel_assignment(const OggFLAC__FileDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- return OggFLAC__seekable_stream_decoder_get_channel_assignment(decoder->private_->seekable_stream_decoder);
-}
-
-OggFLAC_API unsigned OggFLAC__file_decoder_get_bits_per_sample(const OggFLAC__FileDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- return OggFLAC__seekable_stream_decoder_get_bits_per_sample(decoder->private_->seekable_stream_decoder);
-}
-
-OggFLAC_API unsigned OggFLAC__file_decoder_get_sample_rate(const OggFLAC__FileDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- return OggFLAC__seekable_stream_decoder_get_sample_rate(decoder->private_->seekable_stream_decoder);
-}
-
-OggFLAC_API unsigned OggFLAC__file_decoder_get_blocksize(const OggFLAC__FileDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- return OggFLAC__seekable_stream_decoder_get_blocksize(decoder->private_->seekable_stream_decoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_process_single(OggFLAC__FileDecoder *decoder)
-{
- FLAC__bool ret;
- FLAC__ASSERT(0 != decoder);
-
- if(decoder->private_->seekable_stream_decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
- decoder->protected_->state = OggFLAC__FILE_DECODER_END_OF_FILE;
-
- if(decoder->protected_->state == OggFLAC__FILE_DECODER_END_OF_FILE)
- return true;
-
- FLAC__ASSERT(decoder->protected_->state == OggFLAC__FILE_DECODER_OK);
-
- ret = OggFLAC__seekable_stream_decoder_process_single(decoder->private_->seekable_stream_decoder);
- if(!ret)
- decoder->protected_->state = OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
-
- return ret;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_process_until_end_of_metadata(OggFLAC__FileDecoder *decoder)
-{
- FLAC__bool ret;
- FLAC__ASSERT(0 != decoder);
-
- if(decoder->private_->seekable_stream_decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
- decoder->protected_->state = OggFLAC__FILE_DECODER_END_OF_FILE;
-
- if(decoder->protected_->state == OggFLAC__FILE_DECODER_END_OF_FILE)
- return true;
-
- FLAC__ASSERT(decoder->protected_->state == OggFLAC__FILE_DECODER_OK);
-
- ret = OggFLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder->private_->seekable_stream_decoder);
- if(!ret)
- decoder->protected_->state = OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
-
- return ret;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_process_until_end_of_file(OggFLAC__FileDecoder *decoder)
-{
- FLAC__bool ret;
- FLAC__ASSERT(0 != decoder);
-
- if(decoder->private_->seekable_stream_decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
- decoder->protected_->state = OggFLAC__FILE_DECODER_END_OF_FILE;
-
- if(decoder->protected_->state == OggFLAC__FILE_DECODER_END_OF_FILE)
- return true;
-
- FLAC__ASSERT(decoder->protected_->state == OggFLAC__FILE_DECODER_OK);
-
- ret = OggFLAC__seekable_stream_decoder_process_until_end_of_stream(decoder->private_->seekable_stream_decoder);
- if(!ret)
- decoder->protected_->state = OggFLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR;
-
- return ret;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_decoder_seek_absolute(OggFLAC__FileDecoder *decoder, FLAC__uint64 sample)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(decoder->protected_->state == OggFLAC__FILE_DECODER_OK || decoder->protected_->state == OggFLAC__FILE_DECODER_END_OF_FILE);
-
- if(decoder->private_->filename == 0) { /* means the file is stdin... */
- decoder->protected_->state = OggFLAC__FILE_DECODER_SEEK_ERROR;
- return false;
- }
-
- if(!OggFLAC__seekable_stream_decoder_seek_absolute(decoder->private_->seekable_stream_decoder, sample)) {
- decoder->protected_->state = OggFLAC__FILE_DECODER_SEEK_ERROR;
- return false;
- }
- else {
- decoder->protected_->state = OggFLAC__FILE_DECODER_OK;
- return true;
- }
-}
-
-
-/***********************************************************************
- *
- * Private class methods
- *
- ***********************************************************************/
-
-void set_defaults_(OggFLAC__FileDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
-
- decoder->private_->filename = 0;
- decoder->private_->write_callback = 0;
- decoder->private_->metadata_callback = 0;
- decoder->private_->error_callback = 0;
- decoder->private_->client_data = 0;
-}
-
-/*
- * This will forcibly set stdin to binary mode (for OSes that require it)
- */
-FILE *get_binary_stdin_()
-{
- /* if something breaks here it is probably due to the presence or
- * absence of an underscore before the identifiers 'setmode',
- * 'fileno', and/or 'O_BINARY'; check your system header files.
- */
-#if defined _MSC_VER || defined __MINGW32__
- _setmode(_fileno(stdin), _O_BINARY);
-#elif defined __CYGWIN__
- /* almost certainly not needed for any modern Cygwin, but let's be safe... */
- setmode(_fileno(stdin), _O_BINARY);
-#endif
-
- return stdin;
-}
-
-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 OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
- }
- else {
- return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
- }
- }
- else
- return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */
-}
-
-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(fseeko(file_decoder->private_->file, (off_t)absolute_byte_offset, SEEK_SET) < 0)
- return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
- else
- return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
-}
-
-OggFLAC__SeekableStreamDecoderTellStatus tell_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
-{
- OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
- off_t pos;
- (void)decoder;
-
- if((pos = ftello(file_decoder->private_->file)) < 0)
- return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR;
- else {
- *absolute_byte_offset = (FLAC__uint64)pos;
- return OggFLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
- }
-}
-
-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 OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR;
- else {
- *stream_length = (FLAC__uint64)filestats.st_size;
- return OggFLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
- }
-}
-
-FLAC__bool eof_callback_(const OggFLAC__SeekableStreamDecoder *decoder, void *client_data)
-{
- OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
- (void)decoder;
-
- return feof(file_decoder->private_->file)? true : false;
-}
-
-FLAC__StreamDecoderWriteStatus write_callback_(const OggFLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
-{
- OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
- (void)decoder;
-
- return file_decoder->private_->write_callback(file_decoder, frame, buffer, file_decoder->private_->client_data);
-}
-
-void metadata_callback_(const OggFLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
-{
- OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
- (void)decoder;
-
- file_decoder->private_->metadata_callback(file_decoder, metadata, file_decoder->private_->client_data);
-}
-
-void error_callback_(const OggFLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
-{
- OggFLAC__FileDecoder *file_decoder = (OggFLAC__FileDecoder *)client_data;
- (void)decoder;
-
- file_decoder->private_->error_callback(file_decoder, status, file_decoder->private_->client_data);
-}
diff --git a/src/libOggFLAC/file_encoder.c b/src/libOggFLAC/file_encoder.c
deleted file mode 100644
index e9e2821a..00000000
--- a/src/libOggFLAC/file_encoder.c
+++ /dev/null
@@ -1,835 +0,0 @@
-/* libOggFLAC - Free Lossless Audio Codec + Ogg library
- * Copyright (C) 2002,2003,2004,2005,2006 Josh Coalson
- *
- * 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.
- */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h> /* for malloc() */
-#include <string.h> /* for strlen(), strcpy() */
-#if defined _MSC_VER || defined __MINGW32__
-#include <sys/types.h> /* for off_t */
-//@@@ [2G limit] hacks for MSVC6
-#define fseeko fseek
-#define ftello ftell
-#endif
-#include "FLAC/assert.h"
-#include "OggFLAC/seekable_stream_encoder.h"
-#include "protected/file_encoder.h"
-
-#ifdef max
-#undef max
-#endif
-#define max(x,y) ((x)>(y)?(x):(y))
-
-/***********************************************************************
- *
- * Private class method prototypes
- *
- ***********************************************************************/
-
-/* unpublished debug routines */
-extern FLAC__bool OggFLAC__seekable_stream_encoder_disable_constant_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
-extern FLAC__bool OggFLAC__seekable_stream_encoder_disable_fixed_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
-extern FLAC__bool OggFLAC__seekable_stream_encoder_disable_verbatim_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
-
-static void set_defaults_(OggFLAC__FileEncoder *encoder);
-static OggFLAC__SeekableStreamEncoderReadStatus read_callback_(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
-static FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data);
-static FLAC__SeekableStreamEncoderTellStatus tell_callback_(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
-static FLAC__StreamEncoderWriteStatus write_callback_(const OggFLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
-
-/***********************************************************************
- *
- * Private class data
- *
- ***********************************************************************/
-
-typedef struct OggFLAC__FileEncoderPrivate {
- OggFLAC__FileEncoderProgressCallback progress_callback;
- void *client_data;
- char *filename;
- FLAC__uint64 bytes_written;
- FLAC__uint64 samples_written;
- unsigned frames_written;
- unsigned total_frames_estimate;
- OggFLAC__SeekableStreamEncoder *seekable_stream_encoder;
- FILE *file;
-} OggFLAC__FileEncoderPrivate;
-
-/***********************************************************************
- *
- * Public static class data
- *
- ***********************************************************************/
-
-OggFLAC_API const char * const OggFLAC__FileEncoderStateString[] = {
- "OggFLAC__FILE_ENCODER_OK",
- "OggFLAC__FILE_ENCODER_NO_FILENAME",
- "OggFLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR",
- "OggFLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING",
- "OggFLAC__FILE_ENCODER_ERROR_OPENING_FILE",
- "OggFLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR",
- "OggFLAC__FILE_ENCODER_ALREADY_INITIALIZED",
- "OggFLAC__FILE_ENCODER_UNINITIALIZED"
-};
-
-
-/***********************************************************************
- *
- * Class constructor/destructor
- *
- ***********************************************************************/
-
-OggFLAC_API OggFLAC__FileEncoder *OggFLAC__file_encoder_new()
-{
- OggFLAC__FileEncoder *encoder;
-
- FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
-
- encoder = (OggFLAC__FileEncoder*)calloc(1, sizeof(OggFLAC__FileEncoder));
- if(encoder == 0) {
- return 0;
- }
-
- encoder->protected_ = (OggFLAC__FileEncoderProtected*)calloc(1, sizeof(OggFLAC__FileEncoderProtected));
- if(encoder->protected_ == 0) {
- free(encoder);
- return 0;
- }
-
- encoder->private_ = (OggFLAC__FileEncoderPrivate*)calloc(1, sizeof(OggFLAC__FileEncoderPrivate));
- if(encoder->private_ == 0) {
- free(encoder->protected_);
- free(encoder);
- return 0;
- }
-
- encoder->private_->seekable_stream_encoder = OggFLAC__seekable_stream_encoder_new();
- if(0 == encoder->private_->seekable_stream_encoder) {
- free(encoder->private_);
- free(encoder->protected_);
- free(encoder);
- return 0;
- }
-
- encoder->private_->file = 0;
-
- set_defaults_(encoder);
-
- encoder->protected_->state = OggFLAC__FILE_ENCODER_UNINITIALIZED;
-
- return encoder;
-}
-
-OggFLAC_API void OggFLAC__file_encoder_delete(OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
-
- (void)OggFLAC__file_encoder_finish(encoder);
-
- OggFLAC__seekable_stream_encoder_delete(encoder->private_->seekable_stream_encoder);
-
- free(encoder->private_);
- free(encoder->protected_);
- free(encoder);
-}
-
-/***********************************************************************
- *
- * Public class methods
- *
- ***********************************************************************/
-
-OggFLAC_API OggFLAC__FileEncoderState OggFLAC__file_encoder_init(OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
-
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return encoder->protected_->state = OggFLAC__FILE_ENCODER_ALREADY_INITIALIZED;
-
- if(0 == encoder->private_->filename)
- return encoder->protected_->state = OggFLAC__FILE_ENCODER_NO_FILENAME;
-
- encoder->private_->file = fopen(encoder->private_->filename, "w+b");
-
- if(encoder->private_->file == 0)
- return encoder->protected_->state = OggFLAC__FILE_ENCODER_ERROR_OPENING_FILE;
-
- encoder->private_->bytes_written = 0;
- encoder->private_->samples_written = 0;
- encoder->private_->frames_written = 0;
-
- OggFLAC__seekable_stream_encoder_set_read_callback(encoder->private_->seekable_stream_encoder, read_callback_);
- OggFLAC__seekable_stream_encoder_set_seek_callback(encoder->private_->seekable_stream_encoder, seek_callback_);
- OggFLAC__seekable_stream_encoder_set_tell_callback(encoder->private_->seekable_stream_encoder, tell_callback_);
- OggFLAC__seekable_stream_encoder_set_write_callback(encoder->private_->seekable_stream_encoder, write_callback_);
- OggFLAC__seekable_stream_encoder_set_client_data(encoder->private_->seekable_stream_encoder, encoder);
-
- if(OggFLAC__seekable_stream_encoder_init(encoder->private_->seekable_stream_encoder) != OggFLAC__SEEKABLE_STREAM_ENCODER_OK)
- return encoder->protected_->state = OggFLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
-
- {
- unsigned blocksize = OggFLAC__file_encoder_get_blocksize(encoder);
-
- FLAC__ASSERT(blocksize != 0);
- encoder->private_->total_frames_estimate = (unsigned)((OggFLAC__file_encoder_get_total_samples_estimate(encoder) + blocksize - 1) / blocksize);
- }
-
- return encoder->protected_->state = OggFLAC__FILE_ENCODER_OK;
-}
-
-OggFLAC_API void OggFLAC__file_encoder_finish(OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
-
- if(encoder->protected_->state == OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return;
-
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
-
- /* OggFLAC__seekable_stream_encoder_finish() might write data so we must close the file after it. */
-
- OggFLAC__seekable_stream_encoder_finish(encoder->private_->seekable_stream_encoder);
-
- if(0 != encoder->private_->file) {
- fclose(encoder->private_->file);
- encoder->private_->file = 0;
- }
-
- if(0 != encoder->private_->filename) {
- free(encoder->private_->filename);
- encoder->private_->filename = 0;
- }
-
- set_defaults_(encoder);
-
- encoder->protected_->state = OggFLAC__FILE_ENCODER_UNINITIALIZED;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_serial_number(OggFLAC__FileEncoder *encoder, long serial_number)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_serial_number(encoder->private_->seekable_stream_encoder, serial_number);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_verify(OggFLAC__FileEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_verify(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_streamable_subset(OggFLAC__FileEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_streamable_subset(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_do_mid_side_stereo(OggFLAC__FileEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_do_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_loose_mid_side_stereo(OggFLAC__FileEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_channels(OggFLAC__FileEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_channels(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_bits_per_sample(OggFLAC__FileEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_bits_per_sample(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_sample_rate(OggFLAC__FileEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_sample_rate(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_blocksize(OggFLAC__FileEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_blocksize(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_apodization(OggFLAC__FileEncoder *encoder, const char *specification)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_apodization(encoder->private_->seekable_stream_encoder, specification);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_max_lpc_order(OggFLAC__FileEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_max_lpc_order(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_qlp_coeff_precision(OggFLAC__FileEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_qlp_coeff_precision(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_do_qlp_coeff_prec_search(OggFLAC__FileEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_do_escape_coding(OggFLAC__FileEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_do_escape_coding(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_do_exhaustive_model_search(OggFLAC__FileEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_min_residual_partition_order(OggFLAC__FileEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_min_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_max_residual_partition_order(OggFLAC__FileEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_max_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_rice_parameter_search_dist(OggFLAC__FileEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_total_samples_estimate(OggFLAC__FileEncoder *encoder, FLAC__uint64 value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_total_samples_estimate(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_metadata(OggFLAC__FileEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_set_metadata(encoder->private_->seekable_stream_encoder, metadata, num_blocks);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_filename(OggFLAC__FileEncoder *encoder, const char *value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != value);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- if(0 != encoder->private_->filename) {
- free(encoder->private_->filename);
- encoder->private_->filename = 0;
- }
- if(0 == (encoder->private_->filename = (char*)malloc(strlen(value)+1))) {
- encoder->protected_->state = OggFLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR;
- return false;
- }
- strcpy(encoder->private_->filename, value);
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_progress_callback(OggFLAC__FileEncoder *encoder, OggFLAC__FileEncoderProgressCallback value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- encoder->private_->progress_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_client_data(OggFLAC__FileEncoder *encoder, void *value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- encoder->private_->client_data = value;
- return true;
-}
-
-/*
- * These three functions are not static, but not publically exposed in
- * include/OggFLAC/ either. They are used by the test suite.
- */
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_disable_constant_subframes(OggFLAC__FileEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_disable_constant_subframes(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_disable_fixed_subframes(OggFLAC__FileEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_disable_fixed_subframes(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_disable_verbatim_subframes(OggFLAC__FileEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
- return false;
- return OggFLAC__seekable_stream_encoder_disable_verbatim_subframes(encoder->private_->seekable_stream_encoder, value);
-}
-
-OggFLAC_API OggFLAC__FileEncoderState OggFLAC__file_encoder_get_state(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->state;
-}
-
-OggFLAC_API OggFLAC__SeekableStreamEncoderState OggFLAC__file_encoder_get_seekable_stream_encoder_state(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_state(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API FLAC__StreamEncoderState OggFLAC__file_encoder_get_FLAC_stream_encoder_state(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_FLAC_stream_encoder_state(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API FLAC__StreamDecoderState OggFLAC__file_encoder_get_verify_decoder_state(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_verify_decoder_state(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API const char *OggFLAC__file_encoder_get_resolved_state_string(const OggFLAC__FileEncoder *encoder)
-{
- if(encoder->protected_->state != OggFLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR)
- return OggFLAC__FileEncoderStateString[encoder->protected_->state];
- else
- return OggFLAC__seekable_stream_encoder_get_resolved_state_string(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API void OggFLAC__file_encoder_get_verify_decoder_error_stats(const OggFLAC__FileEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- OggFLAC__seekable_stream_encoder_get_verify_decoder_error_stats(encoder->private_->seekable_stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_get_verify(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_verify(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_get_streamable_subset(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_streamable_subset(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_get_do_mid_side_stereo(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_do_mid_side_stereo(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_get_loose_mid_side_stereo(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__file_encoder_get_channels(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_channels(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__file_encoder_get_bits_per_sample(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_bits_per_sample(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__file_encoder_get_sample_rate(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_sample_rate(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__file_encoder_get_blocksize(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_blocksize(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__file_encoder_get_max_lpc_order(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_max_lpc_order(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__file_encoder_get_qlp_coeff_precision(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_qlp_coeff_precision(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_get_do_qlp_coeff_prec_search(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_get_do_escape_coding(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_do_escape_coding(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_get_do_exhaustive_model_search(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__file_encoder_get_min_residual_partition_order(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_min_residual_partition_order(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__file_encoder_get_max_residual_partition_order(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_max_residual_partition_order(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__file_encoder_get_rice_parameter_search_dist(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API FLAC__uint64 OggFLAC__file_encoder_get_total_samples_estimate(const OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- return OggFLAC__seekable_stream_encoder_get_total_samples_estimate(encoder->private_->seekable_stream_encoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_process(OggFLAC__FileEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- if(!OggFLAC__seekable_stream_encoder_process(encoder->private_->seekable_stream_encoder, buffer, samples)) {
- encoder->protected_->state = OggFLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
- return false;
- }
- else
- return true;
-}
-
-/* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
-OggFLAC_API FLAC__bool OggFLAC__file_encoder_process_interleaved(OggFLAC__FileEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- if(!OggFLAC__seekable_stream_encoder_process_interleaved(encoder->private_->seekable_stream_encoder, buffer, samples)) {
- encoder->protected_->state = OggFLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
- return false;
- }
- else
- return true;
-}
-
-
-/***********************************************************************
- *
- * Private class methods
- *
- ***********************************************************************/
-
-void set_defaults_(OggFLAC__FileEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
-
- encoder->private_->progress_callback = 0;
- encoder->private_->client_data = 0;
- encoder->private_->total_frames_estimate = 0;
- encoder->private_->filename = 0;
-}
-
-OggFLAC__SeekableStreamEncoderReadStatus read_callback_(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
-{
- OggFLAC__FileEncoder *file_encoder = (OggFLAC__FileEncoder*)client_data;
-
- (void)encoder;
-
- FLAC__ASSERT(0 != file_encoder);
-
- *bytes = (unsigned)fread(buffer, 1, *bytes, file_encoder->private_->file);
- if (*bytes == 0) {
- if (feof(file_encoder->private_->file))
- return OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_END_OF_STREAM;
- else if (ferror(file_encoder->private_->file))
- return OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_ABORT;
- }
- return OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_CONTINUE;
-}
-
-FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
-{
- OggFLAC__FileEncoder *file_encoder = (OggFLAC__FileEncoder*)client_data;
-
- (void)encoder;
-
- FLAC__ASSERT(0 != file_encoder);
-
- if(fseeko(file_encoder->private_->file, (off_t)absolute_byte_offset, SEEK_SET) < 0)
- return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR;
- else
- return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK;
-}
-
-FLAC__SeekableStreamEncoderTellStatus tell_callback_(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
-{
- OggFLAC__FileEncoder *file_encoder = (OggFLAC__FileEncoder*)client_data;
- off_t offset;
-
- (void)encoder;
-
- FLAC__ASSERT(0 != file_encoder);
-
- offset = ftello(file_encoder->private_->file);
-
- if(offset < 0) {
- return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_ERROR;
- }
- else {
- *absolute_byte_offset = (FLAC__uint64)offset;
- return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK;
- }
-}
-
-#ifdef FLAC__VALGRIND_TESTING
-static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
-{
- size_t ret = fwrite(ptr, size, nmemb, stream);
- if(!ferror(stream))
- fflush(stream);
- return ret;
-}
-#else
-#define local__fwrite fwrite
-#endif
-
-FLAC__StreamEncoderWriteStatus write_callback_(const OggFLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
-{
- OggFLAC__FileEncoder *file_encoder = (OggFLAC__FileEncoder*)client_data;
-
- (void)encoder;
-
- FLAC__ASSERT(0 != file_encoder);
-
- if(local__fwrite(buffer, sizeof(FLAC__byte), bytes, file_encoder->private_->file) == bytes) {
- file_encoder->private_->bytes_written += bytes;
- file_encoder->private_->samples_written += samples;
- /* we keep a high watermark on the number of frames written
- * because when the encoder goes back to write metadata,
- * 'current_frame' will drop back to 0.
- */
- file_encoder->private_->frames_written = max(file_encoder->private_->frames_written, current_frame+1);
- /*@@@ We would like to add an '&& samples > 0' to the if
- * clause here but currently because of the nature of our Ogg
- * writing implementation, 'samples' is always 0 (see
- * ogg_encoder_aspect.c). The downside is extra progress
- * callbacks.
- */
- if(0 != file_encoder->private_->progress_callback)
- file_encoder->private_->progress_callback(file_encoder, file_encoder->private_->bytes_written, file_encoder->private_->samples_written, file_encoder->private_->frames_written, file_encoder->private_->total_frames_estimate, file_encoder->private_->client_data);
- return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
- }
- else
- return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
-}
diff --git a/src/libOggFLAC/include/private/ogg_decoder_aspect.h b/src/libOggFLAC/include/private/ogg_decoder_aspect.h
index fab57d9d..ba5c3d22 100644
--- a/src/libOggFLAC/include/private/ogg_decoder_aspect.h
+++ b/src/libOggFLAC/include/private/ogg_decoder_aspect.h
@@ -36,6 +36,7 @@
#include "FLAC/ordinals.h"
#include "FLAC/stream_decoder.h" /* for FLAC__StreamDecoderReadStatus */
+#include "OggFLAC/stream_decoder.h"
typedef struct OggFLAC__OggDecoderAspect {
/* these are storage for values that can be set through the API */
@@ -74,6 +75,6 @@ typedef enum {
typedef OggFLAC__OggDecoderAspectReadStatus (*OggFLAC__OggDecoderAspectReadCallbackProxy)(const void *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
-OggFLAC__OggDecoderAspectReadStatus OggFLAC__ogg_decoder_aspect_read_callback_wrapper(OggFLAC__OggDecoderAspect *aspect, FLAC__byte buffer[], unsigned *bytes, OggFLAC__OggDecoderAspectReadCallbackProxy read_callback, void *decoder, void *client_data);
+OggFLAC__OggDecoderAspectReadStatus OggFLAC__ogg_decoder_aspect_read_callback_wrapper(OggFLAC__OggDecoderAspect *aspect, FLAC__byte buffer[], unsigned *bytes, OggFLAC__OggDecoderAspectReadCallbackProxy read_callback, const OggFLAC__StreamDecoder *decoder, void *client_data);
#endif
diff --git a/src/libOggFLAC/include/private/ogg_helper.h b/src/libOggFLAC/include/private/ogg_helper.h
index 49f30969..5a0cfafd 100644
--- a/src/libOggFLAC/include/private/ogg_helper.h
+++ b/src/libOggFLAC/include/private/ogg_helper.h
@@ -33,11 +33,11 @@
#define OggFLAC__PRIVATE__OGG_HELPER_H
#include <ogg/ogg.h>
-#include "OggFLAC/seekable_stream_encoder.h" /* for OggFLAC__SeekableStreamEncoder */
+#include "OggFLAC/stream_encoder.h" /* for OggFLAC__StreamEncoder */
void simple_ogg_page__init(ogg_page *page);
void simple_ogg_page__clear(ogg_page *page);
-FLAC__bool simple_ogg_page__get_at(OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, OggFLAC__SeekableStreamEncoderSeekCallback seek_callback, OggFLAC__SeekableStreamEncoderReadCallback read_callback, void *client_data);
-FLAC__bool simple_ogg_page__set_at(OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, OggFLAC__SeekableStreamEncoderSeekCallback seek_callback, OggFLAC__SeekableStreamEncoderWriteCallback write_callback, void *client_data);
+FLAC__bool simple_ogg_page__get_at(OggFLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, OggFLAC__StreamEncoderReadCallback read_callback, void *client_data);
+FLAC__bool simple_ogg_page__set_at(OggFLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderWriteCallback write_callback, void *client_data);
#endif
diff --git a/src/libOggFLAC/include/protected/Makefile.am b/src/libOggFLAC/include/protected/Makefile.am
index 552461df..fd7b6f91 100644
--- a/src/libOggFLAC/include/protected/Makefile.am
+++ b/src/libOggFLAC/include/protected/Makefile.am
@@ -30,9 +30,5 @@
noinst_HEADERS = \
all.h \
- file_decoder.h \
- file_encoder.h \
- seekable_stream_decoder.h \
- seekable_stream_encoder.h \
stream_decoder.h \
stream_encoder.h
diff --git a/src/libOggFLAC/include/protected/all.h b/src/libOggFLAC/include/protected/all.h
index ebbb2701..35940791 100644
--- a/src/libOggFLAC/include/protected/all.h
+++ b/src/libOggFLAC/include/protected/all.h
@@ -32,10 +32,6 @@
#ifndef OggFLAC__PROTECTED__ALL_H
#define OggFLAC__PROTECTED__ALL_H
-#include "file_decoder.h"
-#include "file_encoder.h"
-#include "seekable_stream_decoder.h"
-#include "seekable_stream_encoder.h"
#include "stream_decoder.h"
#include "stream_encoder.h"
diff --git a/src/libOggFLAC/include/protected/file_decoder.h b/src/libOggFLAC/include/protected/file_decoder.h
deleted file mode 100644
index ba130a17..00000000
--- a/src/libOggFLAC/include/protected/file_decoder.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* libOggFLAC - Free Lossless Audio Codec + Ogg library
- * Copyright (C) 2002,2003,2004,2005,2006 Josh Coalson
- *
- * 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 OggFLAC__PROTECTED__FILE_DECODER_H
-#define OggFLAC__PROTECTED__FILE_DECODER_H
-
-#include "OggFLAC/file_decoder.h"
-
-typedef struct OggFLAC__FileDecoderProtected {
- OggFLAC__FileDecoderState state;
-} OggFLAC__FileDecoderProtected;
-
-#endif
diff --git a/src/libOggFLAC/include/protected/file_encoder.h b/src/libOggFLAC/include/protected/file_encoder.h
deleted file mode 100644
index 0d850fd0..00000000
--- a/src/libOggFLAC/include/protected/file_encoder.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* libOggFLAC - Free Lossless Audio Codec + Ogg library
- * Copyright (C) 2002,2003,2004,2005,2006 Josh Coalson
- *
- * 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 OggFLAC__PROTECTED__FILE_ENCODER_H
-#define OggFLAC__PROTECTED__FILE_ENCODER_H
-
-#include "OggFLAC/file_encoder.h"
-
-typedef struct OggFLAC__FileEncoderProtected {
- OggFLAC__FileEncoderState state;
-} OggFLAC__FileEncoderProtected;
-
-#endif
diff --git a/src/libOggFLAC/include/protected/seekable_stream_decoder.h b/src/libOggFLAC/include/protected/seekable_stream_decoder.h
deleted file mode 100644
index 92393237..00000000
--- a/src/libOggFLAC/include/protected/seekable_stream_decoder.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* libOggFLAC - Free Lossless Audio Codec + Ogg library
- * Copyright (C) 2002,2003,2004,2005,2006 Josh Coalson
- *
- * 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 OggFLAC__PROTECTED__SEEKABLE_STREAM_DECODER_H
-#define OggFLAC__PROTECTED__SEEKABLE_STREAM_DECODER_H
-
-#include "OggFLAC/seekable_stream_decoder.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__SeekableStreamDecoderProtected;
-
-#endif
diff --git a/src/libOggFLAC/include/protected/seekable_stream_encoder.h b/src/libOggFLAC/include/protected/seekable_stream_encoder.h
deleted file mode 100644
index 0f2f3b93..00000000
--- a/src/libOggFLAC/include/protected/seekable_stream_encoder.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* libOggFLAC - Free Lossless Audio Codec + Ogg library
- * Copyright (C) 2002,2003,2004,2005,2006 Josh Coalson
- *
- * 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 OggFLAC__PROTECTED__SEEKABLE_STREAM_ENCODER_H
-#define OggFLAC__PROTECTED__SEEKABLE_STREAM_ENCODER_H
-
-#include "OggFLAC/seekable_stream_encoder.h"
-#include "private/ogg_encoder_aspect.h"
-
-typedef struct OggFLAC__SeekableStreamEncoderProtected {
- OggFLAC__SeekableStreamEncoderState state;
- OggFLAC__OggEncoderAspect ogg_encoder_aspect;
- FLAC__uint64 streaminfo_offset, seektable_offset, audio_offset;
-} OggFLAC__SeekableStreamEncoderProtected;
-
-#endif
diff --git a/src/libOggFLAC/include/protected/stream_encoder.h b/src/libOggFLAC/include/protected/stream_encoder.h
index e737c368..a47a4674 100644
--- a/src/libOggFLAC/include/protected/stream_encoder.h
+++ b/src/libOggFLAC/include/protected/stream_encoder.h
@@ -38,6 +38,7 @@
typedef struct OggFLAC__StreamEncoderProtected {
OggFLAC__StreamEncoderState state;
OggFLAC__OggEncoderAspect ogg_encoder_aspect;
+ FLAC__uint64 streaminfo_offset, seektable_offset, audio_offset;
} OggFLAC__StreamEncoderProtected;
#endif
diff --git a/src/libOggFLAC/libOggFLAC_dynamic.dsp b/src/libOggFLAC/libOggFLAC_dynamic.dsp
index 944d7c4e..0f630d63 100644
--- a/src/libOggFLAC/libOggFLAC_dynamic.dsp
+++ b/src/libOggFLAC/libOggFLAC_dynamic.dsp
@@ -92,14 +92,6 @@ LINK32=link.exe
# PROP Default_Filter "c"
# Begin Source File
-SOURCE=.\file_decoder.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\file_encoder.c
-# End Source File
-# Begin Source File
-
SOURCE=.\ogg_decoder_aspect.c
# End Source File
# Begin Source File
@@ -116,14 +108,6 @@ SOURCE=.\ogg_mapping.c
# End Source File
# Begin Source File
-SOURCE=.\seekable_stream_decoder.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\seekable_stream_encoder.c
-# End Source File
-# Begin Source File
-
SOURCE=.\stream_decoder.c
# End Source File
# Begin Source File
@@ -164,22 +148,6 @@ SOURCE=.\include\protected\all.h
# End Source File
# Begin Source File
-SOURCE=.\include\protected\file_decoder.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\include\protected\file_encoder.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\include\protected\seekable_stream_decoder.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\include\protected\seekable_stream_encoder.h
-# End Source File
-# Begin Source File
-
SOURCE=.\include\protected\stream_decoder.h
# End Source File
# Begin Source File
@@ -200,22 +168,6 @@ SOURCE=..\..\include\OggFLAC\export.h
# End Source File
# Begin Source File
-SOURCE=..\..\include\OggFLAC\file_decoder.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\OggFLAC\file_encoder.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\OggFLAC\seekable_stream_decoder.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\OggFLAC\seekable_stream_encoder.h
-# End Source File
-# Begin Source File
-
SOURCE=..\..\include\OggFLAC\stream_decoder.h
# End Source File
# Begin Source File
diff --git a/src/libOggFLAC/libOggFLAC_static.dsp b/src/libOggFLAC/libOggFLAC_static.dsp
index 3cf1c22c..466512af 100644
--- a/src/libOggFLAC/libOggFLAC_static.dsp
+++ b/src/libOggFLAC/libOggFLAC_static.dsp
@@ -85,14 +85,6 @@ LIB32=link.exe -lib
# PROP Default_Filter "c"
# Begin Source File
-SOURCE=.\file_decoder.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\file_encoder.c
-# End Source File
-# Begin Source File
-
SOURCE=.\ogg_decoder_aspect.c
# End Source File
# Begin Source File
@@ -109,14 +101,6 @@ SOURCE=.\ogg_mapping.c
# End Source File
# Begin Source File
-SOURCE=.\seekable_stream_decoder.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\seekable_stream_encoder.c
-# End Source File
-# Begin Source File
-
SOURCE=.\stream_decoder.c
# End Source File
# Begin Source File
@@ -157,22 +141,6 @@ SOURCE=.\include\protected\all.h
# End Source File
# Begin Source File
-SOURCE=.\include\protected\file_decoder.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\include\protected\file_encoder.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\include\protected\seekable_stream_decoder.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\include\protected\seekable_stream_encoder.h
-# End Source File
-# Begin Source File
-
SOURCE=.\include\protected\stream_decoder.h
# End Source File
# Begin Source File
@@ -193,22 +161,6 @@ SOURCE=..\..\include\OggFLAC\export.h
# End Source File
# Begin Source File
-SOURCE=..\..\include\OggFLAC\file_decoder.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\OggFLAC\file_encoder.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\OggFLAC\seekable_stream_decoder.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\include\OggFLAC\seekable_stream_encoder.h
-# End Source File
-# Begin Source File
-
SOURCE=..\..\include\OggFLAC\stream_decoder.h
# End Source File
# Begin Source File
diff --git a/src/libOggFLAC/ogg_decoder_aspect.c b/src/libOggFLAC/ogg_decoder_aspect.c
index 06e2852e..a85dd723 100644
--- a/src/libOggFLAC/ogg_decoder_aspect.c
+++ b/src/libOggFLAC/ogg_decoder_aspect.c
@@ -102,7 +102,7 @@ void OggFLAC__ogg_decoder_aspect_reset(OggFLAC__OggDecoderAspect *aspect)
aspect->need_serial_number = true;
}
-OggFLAC__OggDecoderAspectReadStatus OggFLAC__ogg_decoder_aspect_read_callback_wrapper(OggFLAC__OggDecoderAspect *aspect, FLAC__byte buffer[], unsigned *bytes, OggFLAC__OggDecoderAspectReadCallbackProxy read_callback, void *decoder, void *client_data)
+OggFLAC__OggDecoderAspectReadStatus OggFLAC__ogg_decoder_aspect_read_callback_wrapper(OggFLAC__OggDecoderAspect *aspect, FLAC__byte buffer[], unsigned *bytes, OggFLAC__OggDecoderAspectReadCallbackProxy read_callback, const OggFLAC__StreamDecoder *decoder, void *client_data)
{
static const unsigned OGG_BYTES_CHUNK = 8192;
const unsigned bytes_requested = *bytes;
diff --git a/src/libOggFLAC/ogg_encoder_aspect.c b/src/libOggFLAC/ogg_encoder_aspect.c
index 0ca9eed6..29796d39 100644
--- a/src/libOggFLAC/ogg_encoder_aspect.c
+++ b/src/libOggFLAC/ogg_encoder_aspect.c
@@ -141,7 +141,7 @@ FLAC__StreamEncoderWriteStatus OggFLAC__ogg_encoder_aspect_write_callback_wrappe
if(bytes != FLAC__STREAM_METADATA_HEADER_LENGTH + FLAC__STREAM_METADATA_STREAMINFO_LENGTH) {
/*
* If we get here, our assumption about the way write callbacks happen
- * explained above is wrong
+ * (explained above) is wrong
*/
FLAC__ASSERT(0);
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
diff --git a/src/libOggFLAC/ogg_helper.c b/src/libOggFLAC/ogg_helper.c
index bebd7f06..ca985553 100644
--- a/src/libOggFLAC/ogg_helper.c
+++ b/src/libOggFLAC/ogg_helper.c
@@ -37,33 +37,35 @@
#include <string.h> /* for memcmp(), memcpy() */
#include "FLAC/assert.h"
#include "private/ogg_helper.h"
-#include "protected/seekable_stream_encoder.h"
+#include "protected/stream_encoder.h"
-static FLAC__bool full_read_(OggFLAC__SeekableStreamEncoder *encoder, FLAC__byte *buffer, unsigned bytes, OggFLAC__SeekableStreamEncoderReadCallback read_callback, void *client_data)
+static FLAC__bool full_read_(OggFLAC__StreamEncoder *encoder, FLAC__byte *buffer, unsigned bytes, OggFLAC__StreamEncoderReadCallback read_callback, void *client_data)
{
while(bytes > 0) {
unsigned bytes_read = bytes;
switch(read_callback(encoder, buffer, &bytes_read, client_data)) {
- case OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_CONTINUE:
+ case OggFLAC__STREAM_ENCODER_READ_STATUS_CONTINUE:
bytes -= bytes_read;
buffer += bytes_read;
break;
- case OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_END_OF_STREAM:
+ case OggFLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM:
if(bytes_read == 0) {
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_OGG_ERROR;
return false;
}
bytes -= bytes_read;
buffer += bytes_read;
break;
- case OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_ABORT:
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR;
+ case OggFLAC__STREAM_ENCODER_READ_STATUS_ABORT:
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_CLIENT_ERROR;
+ return false;
+ case OggFLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED:
return false;
default:
/* double protection: */
FLAC__ASSERT(0);
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR;
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_CLIENT_ERROR;
return false;
}
}
@@ -88,11 +90,12 @@ void simple_ogg_page__clear(ogg_page *page)
simple_ogg_page__init(page);
}
-FLAC__bool simple_ogg_page__get_at(OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, OggFLAC__SeekableStreamEncoderSeekCallback seek_callback, OggFLAC__SeekableStreamEncoderReadCallback read_callback, void *client_data)
+FLAC__bool simple_ogg_page__get_at(OggFLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, OggFLAC__StreamEncoderReadCallback read_callback, void *client_data)
{
static const unsigned OGG_HEADER_FIXED_PORTION_LEN = 27;
static const unsigned OGG_MAX_HEADER_LEN = 27/*OGG_HEADER_FIXED_PORTION_LEN*/ + 255;
FLAC__byte crc[4];
+ FLAC__StreamEncoderSeekStatus seek_status;
FLAC__ASSERT(page->header == 0);
FLAC__ASSERT(page->header_len == 0);
@@ -100,14 +103,17 @@ FLAC__bool simple_ogg_page__get_at(OggFLAC__SeekableStreamEncoder *encoder, FLAC
FLAC__ASSERT(page->body_len == 0);
/* move the stream pointer to the supposed beginning of the page */
- if(seek_callback(encoder, position, client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
+ if(0 == seek_callback)
+ return false;
+ if((seek_status = seek_callback((FLAC__StreamEncoder*)encoder, position, client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) {
+ if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR)
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_CLIENT_ERROR;
return false;
}
/* allocate space for the page header */
if(0 == (page->header = (unsigned char *)malloc(OGG_MAX_HEADER_LEN))) {
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -125,7 +131,7 @@ FLAC__bool simple_ogg_page__get_at(OggFLAC__SeekableStreamEncoder *encoder, FLAC
memcmp(page->header+6, "\0\0\0\0\0\0\0\0", 8) || /* granulepos is non-zero */
page->header[26] == 0 /* packet is 0-size */
) {
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_OGG_ERROR;
return false;
}
@@ -139,7 +145,7 @@ FLAC__bool simple_ogg_page__get_at(OggFLAC__SeekableStreamEncoder *encoder, FLAC
/* check to see that it specifies a single packet */
for(i = 0; i < (unsigned)page->header[26] - 1; i++) {
if(page->header[i + OGG_HEADER_FIXED_PORTION_LEN] != 255) {
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_OGG_ERROR;
return false;
}
}
@@ -149,7 +155,7 @@ FLAC__bool simple_ogg_page__get_at(OggFLAC__SeekableStreamEncoder *encoder, FLAC
/* allocate space for the page body */
if(0 == (page->body = (unsigned char *)malloc(page->body_len))) {
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -161,31 +167,36 @@ FLAC__bool simple_ogg_page__get_at(OggFLAC__SeekableStreamEncoder *encoder, FLAC
memcpy(crc, page->header+22, 4);
ogg_page_checksum_set(page);
if(memcmp(crc, page->header+22, 4)) {
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_OGG_ERROR;
return false;
}
return true;
}
-FLAC__bool simple_ogg_page__set_at(OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, OggFLAC__SeekableStreamEncoderSeekCallback seek_callback, OggFLAC__SeekableStreamEncoderWriteCallback write_callback, void *client_data)
+FLAC__bool simple_ogg_page__set_at(OggFLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderWriteCallback write_callback, void *client_data)
{
+ FLAC__StreamEncoderSeekStatus seek_status;
+
FLAC__ASSERT(page->header != 0);
FLAC__ASSERT(page->header_len != 0);
FLAC__ASSERT(page->body != 0);
FLAC__ASSERT(page->body_len != 0);
/* move the stream pointer to the supposed beginning of the page */
- if(seek_callback(encoder, position, client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
+ if(0 == seek_callback)
+ return false;
+ if((seek_status = seek_callback((FLAC__StreamEncoder*)encoder, position, client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) {
+ if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR)
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_CLIENT_ERROR;
return false;
}
ogg_page_checksum_set(page);
/* re-write the page */
- if(write_callback(encoder, page->header, page->header_len, 0, 0, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
+ if(write_callback((FLAC__StreamEncoder*)encoder, page->header, page->header_len, 0, 0, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_CLIENT_ERROR;
return false;
}
diff --git a/src/libOggFLAC/seekable_stream_decoder.c b/src/libOggFLAC/seekable_stream_decoder.c
deleted file mode 100644
index 9721ef88..00000000
--- a/src/libOggFLAC/seekable_stream_decoder.c
+++ /dev/null
@@ -1,982 +0,0 @@
-/* libOggFLAC - Free Lossless Audio Codec + Ogg library
- * Copyright (C) 2002,2003,2004,2005,2006 Josh Coalson
- *
- * 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.
- */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#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/float.h" /* @@@ ugly hack, but how else to do? we need to reuse the float formats but don't want to expose it */
-#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 */
-
-/***********************************************************************
- *
- * Private class method prototypes
- *
- ***********************************************************************/
-
-static void set_defaults_(OggFLAC__SeekableStreamDecoder *decoder);
-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);
-
-/***********************************************************************
- *
- * Private class data
- *
- ***********************************************************************/
-
-typedef struct OggFLAC__SeekableStreamDecoderPrivate {
- OggFLAC__SeekableStreamDecoderReadCallback read_callback;
- OggFLAC__SeekableStreamDecoderSeekCallback seek_callback;
- OggFLAC__SeekableStreamDecoderTellCallback tell_callback;
- OggFLAC__SeekableStreamDecoderLengthCallback length_callback;
- OggFLAC__SeekableStreamDecoderEofCallback eof_callback;
- OggFLAC__SeekableStreamDecoderWriteCallback write_callback;
- OggFLAC__SeekableStreamDecoderMetadataCallback metadata_callback;
- OggFLAC__SeekableStreamDecoderErrorCallback error_callback;
- void *client_data;
- OggFLAC__StreamDecoder *stream_decoder;
- FLAC__bool do_md5_checking; /* initially gets protected_->md5_checking but is turned off after a seek */
- struct FLAC__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;
- FLAC__bool got_a_frame; /* hack needed in seek routine to check when process_single() actually writes a frame */
-} OggFLAC__SeekableStreamDecoderPrivate;
-
-/***********************************************************************
- *
- * Public static class data
- *
- ***********************************************************************/
-
-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_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;
- }
-
- decoder->protected_ = (OggFLAC__SeekableStreamDecoderProtected*)calloc(1, sizeof(OggFLAC__SeekableStreamDecoderProtected));
- if(decoder->protected_ == 0) {
- free(decoder);
- return 0;
- }
-
- decoder->private_ = (OggFLAC__SeekableStreamDecoderPrivate*)calloc(1, sizeof(OggFLAC__SeekableStreamDecoderPrivate));
- if(decoder->private_ == 0) {
- free(decoder->protected_);
- free(decoder);
- return 0;
- }
-
- decoder->private_->stream_decoder = OggFLAC__stream_decoder_new();
- if(0 == decoder->private_->stream_decoder) {
- free(decoder->private_);
- free(decoder->protected_);
- free(decoder);
- return 0;
- }
-
- set_defaults_(decoder);
-
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED;
-
- return decoder;
-}
-
-OggFLAC_API void OggFLAC__seekable_stream_decoder_delete(OggFLAC__SeekableStreamDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->private_->stream_decoder);
-
- (void)OggFLAC__seekable_stream_decoder_finish(decoder);
-
- OggFLAC__stream_decoder_delete(decoder->private_->stream_decoder);
-
- free(decoder->private_);
- free(decoder->protected_);
- free(decoder);
-}
-
-/***********************************************************************
- *
- * Public class methods
- *
- ***********************************************************************/
-
-OggFLAC_API OggFLAC__SeekableStreamDecoderState OggFLAC__seekable_stream_decoder_init(OggFLAC__SeekableStreamDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
-
- 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)
- 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;
-
- decoder->private_->seek_table = 0;
-
- decoder->private_->do_md5_checking = decoder->protected_->md5_checking;
-
- /* We initialize the FLAC__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.
- */
- FLAC__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 md5_failed = false;
-
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
-
- if(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
- return true;
-
- FLAC__ASSERT(0 != decoder->private_->stream_decoder);
-
- /* see the comment in OggFLAC__seekable_stream_decoder_init() as to why we
- * always call FLAC__MD5Final()
- */
- FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context);
-
- 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 !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->protected_);
- if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
- return false;
- 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_);
- if(decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED)
- return false;
- decoder->private_->read_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_seek_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderSeekCallback 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;
- decoder->private_->seek_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_tell_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderTellCallback 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;
- decoder->private_->tell_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_length_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderLengthCallback 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;
- decoder->private_->length_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_eof_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderEofCallback 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;
- decoder->private_->eof_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_write_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderWriteCallback 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;
- decoder->private_->write_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderMetadataCallback 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;
- decoder->private_->metadata_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_error_callback(OggFLAC__SeekableStreamDecoder *decoder, OggFLAC__SeekableStreamDecoderErrorCallback 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;
- decoder->private_->error_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_client_data(OggFLAC__SeekableStreamDecoder *decoder, void *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;
- decoder->private_->client_data = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_serial_number(OggFLAC__SeekableStreamDecoder *decoder, long 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;
- OggFLAC__stream_decoder_set_serial_number(decoder->private_->stream_decoder, value);
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_set_metadata_respond(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;
- 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 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;
- 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;
- 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 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;
- 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)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->protected_);
- return decoder->protected_->state;
-}
-
-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 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 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_STREAM_DECODER_ERROR)
- return OggFLAC__SeekableStreamDecoderStateString[decoder->protected_->state];
- else
- 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->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 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 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 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 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 OggFLAC__stream_decoder_get_blocksize(decoder->private_->stream_decoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_flush(OggFLAC__SeekableStreamDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
-
- decoder->private_->do_md5_checking = false;
-
- if(!OggFLAC__stream_decoder_flush(decoder->private_->stream_decoder)) {
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
- return false;
- }
-
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
-
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_reset(OggFLAC__SeekableStreamDecoder *decoder)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
-
- if(!OggFLAC__seekable_stream_decoder_flush(decoder)) {
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
- return false;
- }
-
- 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 FLAC__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.
- */
- FLAC__MD5Init(&decoder->private_->md5context);
-
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_OK;
-
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_process_single(OggFLAC__SeekableStreamDecoder *decoder)
-{
- FLAC__bool ret;
- FLAC__ASSERT(0 != decoder);
-
- 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)
- return true;
-
- FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK);
-
- ret = OggFLAC__stream_decoder_process_single(decoder->private_->stream_decoder);
- if(!ret)
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
-
- return ret;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_process_until_end_of_metadata(OggFLAC__SeekableStreamDecoder *decoder)
-{
- FLAC__bool ret;
- FLAC__ASSERT(0 != decoder);
-
- 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)
- return true;
-
- FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK);
-
- ret = OggFLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder);
- if(!ret)
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR;
-
- return ret;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_decoder_process_until_end_of_stream(OggFLAC__SeekableStreamDecoder *decoder)
-{
- FLAC__bool ret;
- FLAC__ASSERT(0 != decoder);
-
- 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)
- return true;
-
- FLAC__ASSERT(decoder->protected_->state == OggFLAC__SEEKABLE_STREAM_DECODER_OK);
-
- ret = OggFLAC__stream_decoder_process_until_end_of_stream(decoder->private_->stream_decoder);
- if(!ret)
- 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);
-
- 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;
- }
- /* 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);
-}
-
-/***********************************************************************
- *
- * Private class methods
- *
- ***********************************************************************/
-
-void set_defaults_(OggFLAC__SeekableStreamDecoder *decoder)
-{
- 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 = 0;
- decoder->private_->client_data = 0;
- /* WATCHOUT: these should match the default behavior of OggFLAC__StreamDecoder */
- decoder->private_->ignore_stream_info_block = false;
- decoder->private_->ignore_seek_table_block = true;
-
- decoder->protected_->md5_checking = false;
-}
-
-FLAC__StreamDecoderReadStatus read_callback_(const OggFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *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
- /*@@@@@@ we used to do this: */
- seekable_stream_decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
- /* but it causes a problem because the Ogg decoding layer reads as much as it can to get pages, so the state will get to end-of-stream before the bitbuffer does */
-#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
- /*@@@@@@ we used to do this: */
- seekable_stream_decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM;
- /* but it causes a problem because the Ogg decoding layer reads as much as it can to get pages, so the state will get to end-of-stream before the bitbuffer does */
-#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_->got_a_frame = true;
- 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);
- }
-}
-
-void metadata_callback_(const OggFLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
-{
- OggFLAC__SeekableStreamDecoder *seekable_stream_decoder = (OggFLAC__SeekableStreamDecoder *)client_data;
- (void)decoder;
-
- 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;
- }
-
- 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 error_callback_(const OggFLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, 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)
- seekable_stream_decoder->private_->error_callback(seekable_stream_decoder, status, seekable_stream_decoder->private_->client_data);
-}
-
-FLAC__bool seek_to_absolute_sample_(OggFLAC__SeekableStreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample)
-{
- FLAC__uint64 left_pos = 0, right_pos = stream_length;
- FLAC__uint64 left_sample = 0, right_sample = decoder->private_->stream_info.total_samples;
- FLAC__uint64 this_frame_sample = 0; /* only initialized to avoid compiler warning */
- FLAC__uint64 pos = 0; /* only initialized to avoid compiler warning */
- FLAC__bool did_a_seek;
- unsigned iteration = 0;
-
- /* In the first iterations, we will calculate the target byte position
- * by the distance from the target sample to left_sample and
- * right_sample (let's call it "proportional search"). After that, we
- * will switch to binary search.
- */
- 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);
- BINARY_SEARCH_AFTER_ITERATION = 0;
- }
-
- decoder->private_->target_sample = target_sample;
- for( ; ; iteration++) {
- if (iteration == 0 || this_frame_sample > target_sample || target_sample - this_frame_sample > LINEAR_SEARCH_WITHIN_SAMPLES) {
- if (iteration >= BINARY_SEARCH_AFTER_ITERATION) {
- pos = (right_pos + left_pos) / 2;
- }
- else {
-#ifndef FLAC__INTEGER_ONLY_LIBRARY
-#if defined _MSC_VER || defined __MINGW32__
- /* with MSVC you have to spoon feed it the casting */
- pos = (FLAC__uint64)((FLAC__double)(FLAC__int64)(target_sample - left_sample) / (FLAC__double)(FLAC__int64)(right_sample - left_sample) * (FLAC__double)(FLAC__int64)(right_pos - left_pos));
-#else
- pos = (FLAC__uint64)((FLAC__double)(target_sample - left_sample) / (FLAC__double)(right_sample - left_sample) * (FLAC__double)(right_pos - left_pos));
-#endif
-#else
- /* a little less accurate: */
- if ((target_sample-left_sample <= 0xffffffff) && (right_pos-left_pos <= 0xffffffff))
- pos = (FLAC__int64)(((target_sample-left_sample) * (right_pos-left_pos)) / (right_sample-left_sample));
- else /* @@@ WATCHOUT, ~2TB limit */
- pos = (FLAC__int64)((((target_sample-left_sample)>>8) * ((right_pos-left_pos)>>8)) / ((right_sample-left_sample)>>16));
-#endif
- /* @@@ TODO: might want to limit pos to some distance
- * before EOF, to make sure we land before the last frame,
- * thereby getting a this_fram_sample and so having a better
- * estimate. this would also mostly (or totally if we could
- * be sure to land before the last frame) avoid the
- * end-of-stream case we have to check later.
- */
- }
-
- /* 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;
- }
- did_a_seek = true;
- }
- else
- did_a_seek = false;
-
- decoder->private_->got_a_frame = false;
- if(!OggFLAC__stream_decoder_process_single(decoder->private_->stream_decoder)) {
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
- return false;
- }
- if(!decoder->private_->got_a_frame) {
- if(did_a_seek) {
- /* this can happen if we seek to a point after the last frame; we drop
- * to binary search right away in this case to avoid any wasted
- * iterations of proportional search.
- */
- right_pos = pos;
- BINARY_SEARCH_AFTER_ITERATION = 0;
- }
- else {
- /* this can probably only happen if total_samples is unknown and the
- * target_sample is past the end of the stream
- */
- 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 */
- else if(
- decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_SEEKING &&
- decoder->protected_->state != OggFLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM
- ) {
- break;
- }
- else {
- 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 (did_a_seek) {
- 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;
- /* sanity check to avoid infinite loop */
- if (left_pos == pos) {
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
- return false;
- }
- left_pos = pos;
- }
- else if(this_frame_sample > target_sample) {
- right_sample = this_frame_sample;
- /* sanity check to avoid infinite loop */
- if (right_pos == pos) {
- decoder->protected_->state = OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR;
- return false;
- }
- right_pos = pos;
- }
- }
- }
- }
-
- return true;
-}
diff --git a/src/libOggFLAC/seekable_stream_encoder.c b/src/libOggFLAC/seekable_stream_encoder.c
deleted file mode 100644
index b222905e..00000000
--- a/src/libOggFLAC/seekable_stream_encoder.c
+++ /dev/null
@@ -1,1078 +0,0 @@
-/* libOggFLAC - Free Lossless Audio Codec + Ogg library
- * Copyright (C) 2002,2003,2004,2005,2006 Josh Coalson
- *
- * 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.
- */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h> /* for calloc() */
-#include <string.h> /* for memcpy() */
-#include "FLAC/assert.h"
-#include "OggFLAC/seekable_stream_encoder.h"
-#include "protected/seekable_stream_encoder.h"
-#include "private/ogg_helper.h"
-
-#ifdef max
-#undef max
-#endif
-#define max(a,b) ((a)>(b)?(a):(b))
-
-/***********************************************************************
- *
- * Private class method prototypes
- *
- ***********************************************************************/
-
-/* unpublished debug routines */
-extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
-extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
-extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
-
-static void set_defaults_(OggFLAC__SeekableStreamEncoder *encoder);
-static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
-static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
-
-
-/***********************************************************************
- *
- * Private class data
- *
- ***********************************************************************/
-
-typedef struct OggFLAC__SeekableStreamEncoderPrivate {
- OggFLAC__SeekableStreamEncoderReadCallback read_callback;
- OggFLAC__SeekableStreamEncoderSeekCallback seek_callback;
- OggFLAC__SeekableStreamEncoderTellCallback tell_callback;
- OggFLAC__SeekableStreamEncoderWriteCallback write_callback;
- void *client_data;
- FLAC__StreamEncoder *FLAC_stream_encoder;
- FLAC__StreamMetadata_SeekTable *seek_table;
- /* internal vars (all the above are class settings) */
- unsigned first_seekpoint_to_check;
- FLAC__uint64 samples_written;
-} OggFLAC__SeekableStreamEncoderPrivate;
-
-
-/***********************************************************************
- *
- * Public static class data
- *
- ***********************************************************************/
-
-OggFLAC_API const char * const OggFLAC__SeekableStreamEncoderStateString[] = {
- "OggFLAC__SEEKABLE_STREAM_ENCODER_OK",
- "OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR",
- "OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR",
- "OggFLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR",
- "OggFLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR",
- "OggFLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR",
- "OggFLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR",
- "OggFLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR",
- "OggFLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR",
- "OggFLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED",
- "OggFLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK",
- "OggFLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE",
- "OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED"
-};
-
-OggFLAC_API const char * const OggFLAC__SeekableStreamEncoderReadStatusString[] = {
- "OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_CONTINUE",
- "OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_END_OF_STREAM",
- "OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_ABORT"
-};
-
-
-/***********************************************************************
- *
- * Class constructor/destructor
- *
- */
-OggFLAC_API OggFLAC__SeekableStreamEncoder *OggFLAC__seekable_stream_encoder_new()
-{
- OggFLAC__SeekableStreamEncoder *encoder;
-
- encoder = (OggFLAC__SeekableStreamEncoder*)calloc(1, sizeof(OggFLAC__SeekableStreamEncoder));
- if(encoder == 0) {
- return 0;
- }
-
- encoder->protected_ = (OggFLAC__SeekableStreamEncoderProtected*)calloc(1, sizeof(OggFLAC__SeekableStreamEncoderProtected));
- if(encoder->protected_ == 0) {
- free(encoder);
- return 0;
- }
-
- encoder->private_ = (OggFLAC__SeekableStreamEncoderPrivate*)calloc(1, sizeof(OggFLAC__SeekableStreamEncoderPrivate));
- if(encoder->private_ == 0) {
- free(encoder->protected_);
- free(encoder);
- return 0;
- }
-
- encoder->private_->FLAC_stream_encoder = FLAC__stream_encoder_new();
- if(0 == encoder->private_->FLAC_stream_encoder) {
- free(encoder->private_);
- free(encoder->protected_);
- free(encoder);
- return 0;
- }
-
- set_defaults_(encoder);
-
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
-
- return encoder;
-}
-
-OggFLAC_API void OggFLAC__seekable_stream_encoder_delete(OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
-
- (void)OggFLAC__seekable_stream_encoder_finish(encoder);
-
- FLAC__stream_encoder_delete(encoder->private_->FLAC_stream_encoder);
-
- free(encoder->private_);
- free(encoder->protected_);
- free(encoder);
-}
-
-
-/***********************************************************************
- *
- * Public class methods
- *
- ***********************************************************************/
-
-OggFLAC_API OggFLAC__SeekableStreamEncoderState OggFLAC__seekable_stream_encoder_init(OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
-
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED;
-
- if(0 == encoder->private_->seek_callback || 0 == encoder->private_->tell_callback || 0 == encoder->private_->write_callback)
- return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK;
-
- if(!OggFLAC__ogg_encoder_aspect_init(&encoder->protected_->ogg_encoder_aspect))
- return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
-
- if(0 != encoder->private_->seek_table && !FLAC__format_seektable_is_legal(encoder->private_->seek_table))
- return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE;
-
- /*
- * These must be done before we init the stream encoder because that
- * calls the write_callback, which uses these values.
- */
- encoder->private_->first_seekpoint_to_check = 0;
- encoder->private_->samples_written = 0;
- encoder->protected_->streaminfo_offset = 0;
- encoder->protected_->seektable_offset = 0;
- encoder->protected_->audio_offset = 0;
-
- FLAC__stream_encoder_set_write_callback(encoder->private_->FLAC_stream_encoder, write_callback_);
- FLAC__stream_encoder_set_metadata_callback(encoder->private_->FLAC_stream_encoder, metadata_callback_);
- FLAC__stream_encoder_set_client_data(encoder->private_->FLAC_stream_encoder, encoder);
-
- if(FLAC__stream_encoder_init(encoder->private_->FLAC_stream_encoder) != FLAC__STREAM_ENCODER_OK)
- return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
-
- /*
- * Initializing the stream encoder writes all the metadata, so we
- * save the stream offset now.
- */
- if(encoder->private_->tell_callback(encoder, &encoder->protected_->audio_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK)
- return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR;
-
- return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OK;
-}
-
-OggFLAC_API void OggFLAC__seekable_stream_encoder_finish(OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
-
- if(encoder->protected_->state == OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return;
-
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
-
- FLAC__stream_encoder_finish(encoder->private_->FLAC_stream_encoder);
-
- OggFLAC__ogg_encoder_aspect_finish(&encoder->protected_->ogg_encoder_aspect);
-
- set_defaults_(encoder);
-
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_serial_number(OggFLAC__SeekableStreamEncoder *encoder, long value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- OggFLAC__ogg_encoder_aspect_set_serial_number(&encoder->protected_->ogg_encoder_aspect, value);
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_verify(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_verify(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_streamable_subset(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_streamable_subset(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_do_mid_side_stereo(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_do_mid_side_stereo(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_loose_mid_side_stereo(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_loose_mid_side_stereo(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_channels(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_channels(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_bits_per_sample(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_bits_per_sample(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_sample_rate(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_sample_rate(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_blocksize(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_blocksize(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_apodization(OggFLAC__SeekableStreamEncoder *encoder, const char *specification)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_apodization(encoder->private_->FLAC_stream_encoder, specification);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_max_lpc_order(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_max_lpc_order(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_qlp_coeff_precision(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_qlp_coeff_precision(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_do_escape_coding(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_do_escape_coding(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_do_exhaustive_model_search(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_do_exhaustive_model_search(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_min_residual_partition_order(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_min_residual_partition_order(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_max_residual_partition_order(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_rice_parameter_search_dist(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_total_samples_estimate(OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_metadata(OggFLAC__SeekableStreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- /* reorder metadata if necessary to ensure that any VORBIS_COMMENT is the first, according to the mapping spec */
- if(0 != metadata && num_blocks > 1) {
- unsigned i;
- for(i = 1; i < num_blocks; i++) {
- if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
- FLAC__StreamMetadata *vc = metadata[i];
- for( ; i > 0; i--)
- metadata[i] = metadata[i-1];
- metadata[0] = vc;
- break;
- }
- }
- }
- if(0 != metadata && num_blocks > 0) {
- unsigned i;
- for(i = 0; i < num_blocks; i++) {
- /* keep track of any SEEKTABLE block */
- if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) {
- encoder->private_->seek_table = &metadata[i]->data.seek_table;
- break; /* take only the first one */
- }
- }
- }
- if(!OggFLAC__ogg_encoder_aspect_set_num_metadata(&encoder->protected_->ogg_encoder_aspect, num_blocks))
- return false;
- return FLAC__stream_encoder_set_metadata(encoder->private_->FLAC_stream_encoder, metadata, num_blocks);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_read_callback(OggFLAC__SeekableStreamEncoder *encoder, OggFLAC__SeekableStreamEncoderReadCallback value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != value);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->private_->read_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_seek_callback(OggFLAC__SeekableStreamEncoder *encoder, OggFLAC__SeekableStreamEncoderSeekCallback value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != value);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->private_->seek_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_tell_callback(OggFLAC__SeekableStreamEncoder *encoder, OggFLAC__SeekableStreamEncoderTellCallback value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != value);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->private_->tell_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_write_callback(OggFLAC__SeekableStreamEncoder *encoder, OggFLAC__SeekableStreamEncoderWriteCallback value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != value);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->private_->write_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_client_data(OggFLAC__SeekableStreamEncoder *encoder, void *value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->private_->client_data = value;
- return true;
-}
-
-/*
- * These three functions are not static, but not publically exposed in
- * include/FLAC/ either. They are used by the test suite.
- */
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_disable_constant_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_disable_constant_subframes(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_disable_fixed_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_disable_fixed_subframes(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_disable_verbatim_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
- return false;
- return FLAC__stream_encoder_disable_verbatim_subframes(encoder->private_->FLAC_stream_encoder, value);
-}
-
-OggFLAC_API OggFLAC__SeekableStreamEncoderState OggFLAC__seekable_stream_encoder_get_state(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- return encoder->protected_->state;
-}
-
-OggFLAC_API FLAC__StreamEncoderState OggFLAC__seekable_stream_encoder_get_FLAC_stream_encoder_state(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_state(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API FLAC__StreamDecoderState OggFLAC__seekable_stream_encoder_get_verify_decoder_state(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_verify_decoder_state(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API const char *OggFLAC__seekable_stream_encoder_get_resolved_state_string(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR)
- return OggFLAC__SeekableStreamEncoderStateString[encoder->protected_->state];
- else
- return FLAC__stream_encoder_get_resolved_state_string(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API void OggFLAC__seekable_stream_encoder_get_verify_decoder_error_stats(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- FLAC__stream_encoder_get_verify_decoder_error_stats(encoder->private_->FLAC_stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_verify(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_verify(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_streamable_subset(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_streamable_subset(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_do_mid_side_stereo(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_do_mid_side_stereo(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_loose_mid_side_stereo(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_loose_mid_side_stereo(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_channels(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_channels(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_bits_per_sample(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_bits_per_sample(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_sample_rate(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_sample_rate(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_blocksize(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_blocksize(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_max_lpc_order(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_max_lpc_order(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_qlp_coeff_precision(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_qlp_coeff_precision(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_do_escape_coding(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_do_escape_coding(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_do_exhaustive_model_search(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_do_exhaustive_model_search(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_min_residual_partition_order(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_min_residual_partition_order(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_max_residual_partition_order(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_max_residual_partition_order(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_rice_parameter_search_dist(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_rice_parameter_search_dist(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API FLAC__uint64 OggFLAC__seekable_stream_encoder_get_total_samples_estimate(const OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- return FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->FLAC_stream_encoder);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_process(OggFLAC__SeekableStreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(!FLAC__stream_encoder_process(encoder->private_->FLAC_stream_encoder, buffer, samples)) {
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
- return false;
- }
- else
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_process_interleaved(OggFLAC__SeekableStreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- if(!FLAC__stream_encoder_process_interleaved(encoder->private_->FLAC_stream_encoder, buffer, samples)) {
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
- return false;
- }
- else
- return true;
-}
-
-/***********************************************************************
- *
- * Private class methods
- *
- ***********************************************************************/
-
-void set_defaults_(OggFLAC__SeekableStreamEncoder *encoder)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
-
- encoder->private_->seek_callback = 0;
- encoder->private_->tell_callback = 0;
- encoder->private_->write_callback = 0;
- encoder->private_->client_data = 0;
-
- encoder->private_->seek_table = 0;
-
- OggFLAC__ogg_encoder_aspect_set_defaults(&encoder->protected_->ogg_encoder_aspect);
-}
-
-FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *unused, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
-{
- OggFLAC__SeekableStreamEncoder *encoder = (OggFLAC__SeekableStreamEncoder*)client_data;
- FLAC__StreamEncoderWriteStatus status;
- FLAC__uint64 output_position;
-
- (void)unused; /* silence compiler warning about unused parameter */
- FLAC__ASSERT(encoder->private_->FLAC_stream_encoder == unused);
-
- if(encoder->private_->tell_callback(encoder, &output_position, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK)
- return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR;
-
- /*
- * Watch for the STREAMINFO block and first SEEKTABLE block to go by and store their offsets.
- */
- if(samples == 0) {
- FLAC__MetadataType type = (buffer[0] & 0x7f);
- if(type == FLAC__METADATA_TYPE_STREAMINFO)
- encoder->protected_->streaminfo_offset = output_position;
- else if(type == FLAC__METADATA_TYPE_SEEKTABLE && encoder->protected_->seektable_offset == 0)
- encoder->protected_->seektable_offset = output_position;
- }
-
- /*
- * Mark the current seek point if hit (if audio_offset == 0 that
- * means we're still writing metadata and haven't hit the first
- * frame yet)
- */
- if(0 != encoder->private_->seek_table && encoder->protected_->audio_offset > 0 && encoder->private_->seek_table->num_points > 0) {
- const unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder->private_->FLAC_stream_encoder);
- const FLAC__uint64 frame_first_sample = encoder->private_->samples_written;
- const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1;
- FLAC__uint64 test_sample;
- unsigned i;
- for(i = encoder->private_->first_seekpoint_to_check; i < encoder->private_->seek_table->num_points; i++) {
- test_sample = encoder->private_->seek_table->points[i].sample_number;
- if(test_sample > frame_last_sample) {
- break;
- }
- else if(test_sample >= frame_first_sample) {
- encoder->private_->seek_table->points[i].sample_number = frame_first_sample;
- encoder->private_->seek_table->points[i].stream_offset = output_position - encoder->protected_->audio_offset;
- encoder->private_->seek_table->points[i].frame_samples = blocksize;
- encoder->private_->first_seekpoint_to_check++;
- /* DO NOT: "break;" and here's why:
- * The seektable template may contain more than one target
- * sample for any given frame; we will keep looping, generating
- * duplicate seekpoints for them, and we'll clean it up later,
- * just before writing the seektable back to the metadata.
- */
- }
- else {
- encoder->private_->first_seekpoint_to_check++;
- }
- }
- }
-
- status = OggFLAC__ogg_encoder_aspect_write_callback_wrapper(&encoder->protected_->ogg_encoder_aspect, FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->FLAC_stream_encoder), buffer, bytes, samples, current_frame, (OggFLAC__OggEncoderAspectWriteCallbackProxy)encoder->private_->write_callback, encoder, encoder->private_->client_data);
-
- if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
- encoder->private_->samples_written += samples;
- }
- else
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
-
- return status;
-}
-
-void metadata_callback_(const FLAC__StreamEncoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
-{
- OggFLAC__SeekableStreamEncoder *encoder = (OggFLAC__SeekableStreamEncoder*)client_data;
- FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
- const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
- const unsigned min_framesize = metadata->data.stream_info.min_framesize;
- const unsigned max_framesize = metadata->data.stream_info.max_framesize;
- ogg_page page;
-
- FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
-
- /* We get called by the stream encoder when the encoding process
- * has finished so that we can update the STREAMINFO and SEEKTABLE
- * blocks.
- */
-
- (void)unused; /* silence compiler warning about unused parameter */
- FLAC__ASSERT(encoder->private_->FLAC_stream_encoder == unused);
-
- /*@@@ reopen callback here? The docs currently require user to open files in update mode from the start */
-
- /* All this is based on intimate knowledge of the stream header
- * layout, but a change to the header format that would break this
- * would also break all streams encoded in the previous format.
- */
-
- /*
- * Write STREAMINFO stats
- */
- simple_ogg_page__init(&page);
- if(!simple_ogg_page__get_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) {
- simple_ogg_page__clear(&page);
- return; /* state already set */
- }
- /*
- * MD5 signature
- */
- {
- const unsigned md5_offset =
- FLAC__STREAM_METADATA_HEADER_LENGTH +
- (
- FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN
- ) / 8;
-
- if(md5_offset + 16 > (unsigned)page.body_len) {
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
- simple_ogg_page__clear(&page);
- return;
- }
- memcpy(page.body + md5_offset, metadata->data.stream_info.md5sum, 16);
- }
- /*
- * total samples
- */
- {
- const unsigned total_samples_byte_offset =
- FLAC__STREAM_METADATA_HEADER_LENGTH +
- (
- FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN
- - 4
- ) / 8;
-
- if(total_samples_byte_offset + 5 > (unsigned)page.body_len) {
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
- simple_ogg_page__clear(&page);
- return;
- }
- b[0] = (FLAC__byte)page.body[total_samples_byte_offset] & 0xF0;
- b[0] |= (FLAC__byte)((samples >> 32) & 0x0F);
- b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
- b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
- b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
- b[4] = (FLAC__byte)(samples & 0xFF);
- memcpy(page.body + total_samples_byte_offset, b, 5);
- }
- /*
- * min/max framesize
- */
- {
- const unsigned min_framesize_offset =
- FLAC__STREAM_METADATA_HEADER_LENGTH +
- (
- FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
- FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN
- ) / 8;
-
- if(min_framesize_offset + 6 > (unsigned)page.body_len) {
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
- simple_ogg_page__clear(&page);
- return;
- }
- b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
- b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
- b[2] = (FLAC__byte)(min_framesize & 0xFF);
- b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
- b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
- b[5] = (FLAC__byte)(max_framesize & 0xFF);
- memcpy(page.body + min_framesize_offset, b, 6);
- }
- if(!simple_ogg_page__set_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) {
- simple_ogg_page__clear(&page);
- return; /* state already set */
- }
- simple_ogg_page__clear(&page);
-
- /*
- * Write seektable
- */
- if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) {
- unsigned i;
- FLAC__byte *p;
-
- FLAC__format_seektable_sort(encoder->private_->seek_table);
-
- FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table));
-
- simple_ogg_page__init(&page);
- if(!simple_ogg_page__get_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) {
- simple_ogg_page__clear(&page);
- return; /* state already set */
- }
-
- if(FLAC__STREAM_METADATA_HEADER_LENGTH + (18*encoder->private_->seek_table->num_points) > (unsigned)page.body_len) {
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
- simple_ogg_page__clear(&page);
- return;
- }
-
- for(i = 0, p = page.body + FLAC__STREAM_METADATA_HEADER_LENGTH; i < encoder->private_->seek_table->num_points; i++, p += 18) {
- FLAC__uint64 xx;
- unsigned x;
- xx = encoder->private_->seek_table->points[i].sample_number;
- b[7] = (FLAC__byte)xx; xx >>= 8;
- b[6] = (FLAC__byte)xx; xx >>= 8;
- b[5] = (FLAC__byte)xx; xx >>= 8;
- b[4] = (FLAC__byte)xx; xx >>= 8;
- b[3] = (FLAC__byte)xx; xx >>= 8;
- b[2] = (FLAC__byte)xx; xx >>= 8;
- b[1] = (FLAC__byte)xx; xx >>= 8;
- b[0] = (FLAC__byte)xx; xx >>= 8;
- xx = encoder->private_->seek_table->points[i].stream_offset;
- b[15] = (FLAC__byte)xx; xx >>= 8;
- b[14] = (FLAC__byte)xx; xx >>= 8;
- b[13] = (FLAC__byte)xx; xx >>= 8;
- b[12] = (FLAC__byte)xx; xx >>= 8;
- b[11] = (FLAC__byte)xx; xx >>= 8;
- b[10] = (FLAC__byte)xx; xx >>= 8;
- b[9] = (FLAC__byte)xx; xx >>= 8;
- b[8] = (FLAC__byte)xx; xx >>= 8;
- x = encoder->private_->seek_table->points[i].frame_samples;
- b[17] = (FLAC__byte)x; x >>= 8;
- b[16] = (FLAC__byte)x; x >>= 8;
- if(encoder->private_->write_callback(encoder, b, 18, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
- encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
- simple_ogg_page__clear(&page);
- return;
- }
- memcpy(p, b, 18);
- }
-
- if(!simple_ogg_page__set_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) {
- simple_ogg_page__clear(&page);
- return; /* state already set */
- }
- simple_ogg_page__clear(&page);
- }
-}
diff --git a/src/libOggFLAC/stream_decoder.c b/src/libOggFLAC/stream_decoder.c
index 21557c6c..aec61463 100644
--- a/src/libOggFLAC/stream_decoder.c
+++ b/src/libOggFLAC/stream_decoder.c
@@ -33,9 +33,26 @@
# include <config.h>
#endif
+#if defined _MSC_VER || defined __MINGW32__
+#include <io.h> /* for _setmode() */
+#include <fcntl.h> /* for _O_BINARY */
+#endif
+#if defined __CYGWIN__ || defined __EMX__
+#include <io.h> /* for setmode(), O_BINARY */
+#include <fcntl.h> /* for _O_BINARY */
+#endif
+#include <stdio.h>
#include <stdlib.h> /* for calloc() */
+#include <sys/stat.h> /* for stat() */
+#include <sys/types.h> /* for off_t */
+#if defined _MSC_VER || defined __MINGW32__
+/*@@@ [2G limit] hacks for MSVC6 */
+#define fseeko fseek
+#define ftello ftell
+#endif
#include "FLAC/assert.h"
#include "protected/stream_decoder.h"
+#include "../libFLAC/include/private/float.h" /* @@@ ugly hack, but how else to do? we need to reuse the float formats but don't want to expose it */
/***********************************************************************
*
@@ -44,11 +61,19 @@
***********************************************************************/
static void set_defaults_(OggFLAC__StreamDecoder *decoder);
-static FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
+static FILE *get_binary_stdin_();
+static FLAC__StreamDecoderReadStatus read_callback2_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
+static FLAC__StreamDecoderReadStatus read_callback_ogg_aspect_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
+static OggFLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
static void error_callback_(const FLAC__StreamDecoder *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__bool seek_to_absolute_sample_(OggFLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample);
+static FLAC__StreamDecoderReadStatus file_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
+static FLAC__StreamDecoderSeekStatus file_seek_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
+static FLAC__StreamDecoderTellStatus file_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
+static FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
+static FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data);
/***********************************************************************
@@ -58,12 +83,21 @@ static OggFLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void
***********************************************************************/
typedef struct OggFLAC__StreamDecoderPrivate {
- OggFLAC__StreamDecoderReadCallback read_callback;
- OggFLAC__StreamDecoderWriteCallback write_callback;
- OggFLAC__StreamDecoderMetadataCallback metadata_callback;
- OggFLAC__StreamDecoderErrorCallback error_callback;
+ FLAC__StreamDecoderReadCallback read_callback;
+ FLAC__StreamDecoderSeekCallback seek_callback;
+ FLAC__StreamDecoderTellCallback tell_callback;
+ FLAC__StreamDecoderLengthCallback length_callback;
+ FLAC__StreamDecoderEofCallback eof_callback;
+ FLAC__StreamDecoderWriteCallback write_callback;
+ FLAC__StreamDecoderMetadataCallback metadata_callback;
+ FLAC__StreamDecoderErrorCallback error_callback;
void *client_data;
- FLAC__StreamDecoder *FLAC_stream_decoder;
+ FILE *file; /* only used if OggFLAC__stream_decoder_init_file()/OggFLAC__stream_decoder_init_file() called, else NULL */
+ /* the rest of these are only used for seeking: */
+ FLAC__bool is_seeking;
+ FLAC__Frame last_frame; /* holds the info of the last frame we seeked to */
+ FLAC__uint64 target_sample;
+ FLAC__bool got_a_frame; /* hack needed in seek routine to check when process_single() actually writes a frame */
} OggFLAC__StreamDecoderPrivate;
/***********************************************************************
@@ -76,12 +110,12 @@ OggFLAC_API const char * const OggFLAC__StreamDecoderStateString[] = {
"OggFLAC__STREAM_DECODER_OK",
"OggFLAC__STREAM_DECODER_END_OF_STREAM",
"OggFLAC__STREAM_DECODER_OGG_ERROR",
- "OggFLAC__STREAM_DECODER_READ_ERROR",
"OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR",
+ "OggFLAC__STREAM_DECODER_SEEK_ERROR",
+ "OggFLAC__STREAM_DECODER_READ_ERROR",
"OggFLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
- "OggFLAC__STREAM_DECODER_ALREADY_INITIALIZED",
- "OggFLAC__STREAM_DECODER_INVALID_CALLBACK",
"OggFLAC__STREAM_DECODER_UNINITIALIZED"
+ //@@@@@@
};
@@ -93,6 +127,9 @@ OggFLAC_API const char * const OggFLAC__StreamDecoderStateString[] = {
OggFLAC_API OggFLAC__StreamDecoder *OggFLAC__stream_decoder_new()
{
OggFLAC__StreamDecoder *decoder;
+ FLAC__StreamDecoder *parent;
+
+ FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
decoder = (OggFLAC__StreamDecoder*)calloc(1, sizeof(OggFLAC__StreamDecoder));
if(decoder == 0) {
@@ -112,13 +149,16 @@ OggFLAC_API OggFLAC__StreamDecoder *OggFLAC__stream_decoder_new()
return 0;
}
- decoder->private_->FLAC_stream_decoder = FLAC__stream_decoder_new();
- if(0 == decoder->private_->FLAC_stream_decoder) {
+ parent = FLAC__stream_decoder_new();
+ if(0 == parent) {
free(decoder->private_);
free(decoder->protected_);
free(decoder);
return 0;
}
+ decoder->super_ = *parent;
+
+ decoder->private_->file = 0;
set_defaults_(decoder);
@@ -132,15 +172,15 @@ OggFLAC_API void OggFLAC__stream_decoder_delete(OggFLAC__StreamDecoder *decoder)
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->protected_);
FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->private_->FLAC_stream_decoder);
OggFLAC__stream_decoder_finish(decoder);
- FLAC__stream_decoder_delete(decoder->private_->FLAC_stream_decoder);
-
free(decoder->private_);
free(decoder->protected_);
- free(decoder);
+ /* don't free(decoder) because FLAC__stream_decoder_delete() will do it */
+
+ /* call superclass destructor last */
+ FLAC__stream_decoder_delete((FLAC__StreamDecoder*)decoder);
}
/***********************************************************************
@@ -149,104 +189,192 @@ OggFLAC_API void OggFLAC__stream_decoder_delete(OggFLAC__StreamDecoder *decoder)
*
***********************************************************************/
-OggFLAC_API OggFLAC__StreamDecoderState OggFLAC__stream_decoder_init(OggFLAC__StreamDecoder *decoder)
+OggFLAC_API FLAC__StreamDecoderInitStatus OggFLAC__stream_decoder_init_stream(
+ OggFLAC__StreamDecoder *decoder,
+ FLAC__StreamDecoderReadCallback read_callback,
+ FLAC__StreamDecoderSeekCallback seek_callback,
+ FLAC__StreamDecoderTellCallback tell_callback,
+ FLAC__StreamDecoderLengthCallback length_callback,
+ FLAC__StreamDecoderEofCallback eof_callback,
+ FLAC__StreamDecoderWriteCallback write_callback,
+ FLAC__StreamDecoderMetadataCallback metadata_callback,
+ FLAC__StreamDecoderErrorCallback error_callback,
+ void *client_data
+)
{
FLAC__ASSERT(0 != decoder);
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
- return decoder->protected_->state = OggFLAC__STREAM_DECODER_ALREADY_INITIALIZED;
+ return decoder->protected_->state = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED;
- if(0 == decoder->private_->read_callback || 0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
- return decoder->protected_->state = OggFLAC__STREAM_DECODER_INVALID_CALLBACK;
+ if(
+ 0 == read_callback ||
+ 0 == write_callback ||
+ 0 == error_callback ||
+ (seek_callback && (0 == tell_callback || 0 == length_callback || 0 == eof_callback))
+ )
+ return FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS;
if(!OggFLAC__ogg_decoder_aspect_init(&decoder->protected_->ogg_decoder_aspect))
return decoder->protected_->state = OggFLAC__STREAM_DECODER_OGG_ERROR;
- FLAC__stream_decoder_set_read_callback(decoder->private_->FLAC_stream_decoder, read_callback_);
- FLAC__stream_decoder_set_write_callback(decoder->private_->FLAC_stream_decoder, write_callback_);
- FLAC__stream_decoder_set_metadata_callback(decoder->private_->FLAC_stream_decoder, metadata_callback_);
- FLAC__stream_decoder_set_error_callback(decoder->private_->FLAC_stream_decoder, error_callback_);
- FLAC__stream_decoder_set_client_data(decoder->private_->FLAC_stream_decoder, decoder);
+ /* from here on, errors are fatal */
+
+ decoder->private_->read_callback = read_callback;
+ decoder->private_->seek_callback = seek_callback;
+ decoder->private_->tell_callback = tell_callback;
+ decoder->private_->length_callback = length_callback;
+ decoder->private_->eof_callback = eof_callback;
+ decoder->private_->write_callback = write_callback;
+ decoder->private_->metadata_callback = metadata_callback;
+ decoder->private_->error_callback = error_callback;
+ decoder->private_->client_data = client_data;
+
+ decoder->private_->is_seeking = false;
- if(FLAC__stream_decoder_init(decoder->private_->FLAC_stream_decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
+ if(FLAC__stream_decoder_init_stream((FLAC__StreamDecoder*)decoder, read_callback_ogg_aspect_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, write_callback_, metadata_callback_, error_callback_, /*client_data=*/decoder) != FLAC__STREAM_DECODER_INIT_STATUS_OK) \
return decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
- return decoder->protected_->state = OggFLAC__STREAM_DECODER_OK;
+ decoder->protected_->state = OggFLAC__STREAM_DECODER_OK;
+ return FLAC__STREAM_DECODER_INIT_STATUS_OK;
}
-OggFLAC_API void OggFLAC__stream_decoder_finish(OggFLAC__StreamDecoder *decoder)
+OggFLAC_API FLAC__StreamDecoderInitStatus OggFLAC__stream_decoder_init_FILE(
+ OggFLAC__StreamDecoder *decoder,
+ FILE *file,
+ FLAC__StreamDecoderWriteCallback write_callback,
+ FLAC__StreamDecoderMetadataCallback metadata_callback,
+ FLAC__StreamDecoderErrorCallback error_callback,
+ void *client_data
+)
{
FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
+ FLAC__ASSERT(0 != file);
- if(decoder->protected_->state == OggFLAC__STREAM_DECODER_UNINITIALIZED)
- return;
+ if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
+ return decoder->protected_->state = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED;
- FLAC__ASSERT(0 != decoder->private_->FLAC_stream_decoder);
+ if(0 == write_callback || 0 == error_callback)
+ return decoder->protected_->state = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS;
- FLAC__stream_decoder_finish(decoder->private_->FLAC_stream_decoder);
+ /*
+ * To make sure that our file does not go unclosed after an error, we
+ * must assign the FILE pointer before any further error can occur in
+ * this routine.
+ */
+ if(file == stdin)
+ file = get_binary_stdin_(); /* just to be safe */
- OggFLAC__ogg_decoder_aspect_finish(&decoder->protected_->ogg_decoder_aspect);
+ decoder->private_->file = file;
- set_defaults_(decoder);
+#ifdef OLD_STAT_WAY //@@@@@@
+ if(0 != decoder->private_->filename) {
+ free(decoder->private_->filename);
+ decoder->private_->filename = 0;
+ }
+ if(filename) {
+ if(0 == (decoder->private_->filename = strdup(filename))) {
+ decoder->protected_->state = OggFLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
+ return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR;
+ }
+ }
+#endif
- decoder->protected_->state = OggFLAC__STREAM_DECODER_UNINITIALIZED;
+ return OggFLAC__stream_decoder_init_stream(
+ decoder,
+ file_read_callback_,
+ decoder->private_->file == stdin? 0: file_seek_callback_,
+ decoder->private_->file == stdin? 0: file_tell_callback_,/*@@@@@@ might work for stdin*/
+ decoder->private_->file == stdin? 0: file_length_callback_,
+ decoder->private_->file == stdin? 0: file_eof_callback_,/*@@@@@@ might work for stdin*/
+ write_callback,
+ metadata_callback,
+ error_callback,
+ client_data
+ );
}
-OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_read_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderReadCallback value)
+OggFLAC_API FLAC__StreamDecoderInitStatus OggFLAC__stream_decoder_init_file(
+ OggFLAC__StreamDecoder *decoder,
+ const char *filename,
+ FLAC__StreamDecoderWriteCallback write_callback,
+ FLAC__StreamDecoderMetadataCallback metadata_callback,
+ FLAC__StreamDecoderErrorCallback error_callback,
+ void *client_data
+)
{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
- return false;
- decoder->private_->read_callback = value;
- return true;
-}
+ FILE *file;
-OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_write_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderWriteCallback value)
-{
FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
- if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
- return false;
- decoder->private_->write_callback = value;
- return true;
-}
-OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderMetadataCallback value)
-{
- FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
- FLAC__ASSERT(0 != decoder->protected_);
+ /*
+ * To make sure that our file does not go unclosed after an error, we
+ * have to do the same entrance checks here that are later performed
+ * in OggFLAC__stream_decoder_init_FILE() before the FILE* is assigned.
+ */
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
- return false;
- decoder->private_->metadata_callback = value;
- return true;
+ return decoder->protected_->state = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED;
+
+ if(0 == write_callback || 0 == error_callback)
+ return decoder->protected_->state = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS;
+
+ file = filename? fopen(filename, "rb") : stdin;
+
+ if(0 == file)
+ return FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE;
+
+#ifdef OLD_STAT_WAY //@@@@@@
+ if(0 != decoder->private_->filename) {
+ free(decoder->private_->filename);
+ decoder->private_->filename = 0;
+ }
+ if(filename) {
+ if(0 == (decoder->private_->filename = strdup(filename))) {
+ decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
+ return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR;
+ }
+ }
+#endif
+
+ return OggFLAC__stream_decoder_init_FILE(decoder, file, write_callback, metadata_callback, error_callback, client_data);
}
-OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_error_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderErrorCallback value)
+OggFLAC_API FLAC__bool OggFLAC__stream_decoder_finish(OggFLAC__StreamDecoder *decoder)
{
+ FLAC__bool md5_ok;
+
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
- if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
- return false;
- decoder->private_->error_callback = value;
- return true;
+
+ if(decoder->protected_->state == OggFLAC__STREAM_DECODER_UNINITIALIZED)
+ return true;
+
+ md5_ok = FLAC__stream_decoder_finish((FLAC__StreamDecoder*)decoder);
+
+ OggFLAC__ogg_decoder_aspect_finish(&decoder->protected_->ogg_decoder_aspect);
+
+ if(0 != decoder->private_->file && decoder->private_->file != stdin) {
+ fclose(decoder->private_->file);
+ decoder->private_->file = 0;
+ }
+
+ decoder->private_->is_seeking = false;
+
+ set_defaults_(decoder);
+
+ decoder->protected_->state = OggFLAC__STREAM_DECODER_UNINITIALIZED;
+
+ return md5_ok;
}
-OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_client_data(OggFLAC__StreamDecoder *decoder, void *value)
+OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_md5_checking(OggFLAC__StreamDecoder *decoder, FLAC__bool value)
{
FLAC__ASSERT(0 != decoder);
- FLAC__ASSERT(0 != decoder->private_);
FLAC__ASSERT(0 != decoder->protected_);
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
return false;
- decoder->private_->client_data = value;
- return true;
+ return FLAC__stream_decoder_set_md5_checking((FLAC__StreamDecoder*)decoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_serial_number(OggFLAC__StreamDecoder *decoder, long value)
@@ -267,7 +395,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_respond(OggFLAC__Str
FLAC__ASSERT(0 != decoder->protected_);
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
return false;
- return FLAC__stream_decoder_set_metadata_respond(decoder->private_->FLAC_stream_decoder, type);
+ return FLAC__stream_decoder_set_metadata_respond((FLAC__StreamDecoder*)decoder, type);
}
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_respond_application(OggFLAC__StreamDecoder *decoder, const FLAC__byte id[4])
@@ -277,7 +405,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_respond_application(
FLAC__ASSERT(0 != decoder->protected_);
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
return false;
- return FLAC__stream_decoder_set_metadata_respond_application(decoder->private_->FLAC_stream_decoder, id);
+ return FLAC__stream_decoder_set_metadata_respond_application((FLAC__StreamDecoder*)decoder, id);
}
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_respond_all(OggFLAC__StreamDecoder *decoder)
@@ -287,7 +415,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_respond_all(OggFLAC_
FLAC__ASSERT(0 != decoder->protected_);
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
return false;
- return FLAC__stream_decoder_set_metadata_respond_all(decoder->private_->FLAC_stream_decoder);
+ return FLAC__stream_decoder_set_metadata_respond_all((FLAC__StreamDecoder*)decoder);
}
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore(OggFLAC__StreamDecoder *decoder, FLAC__MetadataType type)
@@ -297,7 +425,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore(OggFLAC__Stre
FLAC__ASSERT(0 != decoder->protected_);
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
return false;
- return FLAC__stream_decoder_set_metadata_ignore(decoder->private_->FLAC_stream_decoder, type);
+ return FLAC__stream_decoder_set_metadata_ignore((FLAC__StreamDecoder*)decoder, type);
}
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore_application(OggFLAC__StreamDecoder *decoder, const FLAC__byte id[4])
@@ -307,7 +435,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore_application(O
FLAC__ASSERT(0 != decoder->protected_);
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
return false;
- return FLAC__stream_decoder_set_metadata_ignore_application(decoder->private_->FLAC_stream_decoder, id);
+ return FLAC__stream_decoder_set_metadata_ignore_application((FLAC__StreamDecoder*)decoder, id);
}
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore_all(OggFLAC__StreamDecoder *decoder)
@@ -317,7 +445,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore_all(OggFLAC__
FLAC__ASSERT(0 != decoder->protected_);
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
return false;
- return FLAC__stream_decoder_set_metadata_ignore_all(decoder->private_->FLAC_stream_decoder);
+ return FLAC__stream_decoder_set_metadata_ignore_all((FLAC__StreamDecoder*)decoder);
}
OggFLAC_API OggFLAC__StreamDecoderState OggFLAC__stream_decoder_get_state(const OggFLAC__StreamDecoder *decoder)
@@ -331,7 +459,7 @@ OggFLAC_API FLAC__StreamDecoderState OggFLAC__stream_decoder_get_FLAC_stream_dec
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
- return FLAC__stream_decoder_get_state(decoder->private_->FLAC_stream_decoder);
+ return FLAC__stream_decoder_get_state((FLAC__StreamDecoder*)decoder);
}
OggFLAC_API const char *OggFLAC__stream_decoder_get_resolved_state_string(const OggFLAC__StreamDecoder *decoder)
@@ -339,42 +467,56 @@ OggFLAC_API const char *OggFLAC__stream_decoder_get_resolved_state_string(const
if(decoder->protected_->state != OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR)
return OggFLAC__StreamDecoderStateString[decoder->protected_->state];
else
- return FLAC__stream_decoder_get_resolved_state_string(decoder->private_->FLAC_stream_decoder);
+ return FLAC__stream_decoder_get_resolved_state_string((FLAC__StreamDecoder*)decoder);
+}
+
+OggFLAC_API FLAC__bool OggFLAC__stream_decoder_get_md5_checking(const OggFLAC__StreamDecoder *decoder)
+{
+ FLAC__ASSERT(0 != decoder);
+ FLAC__ASSERT(0 != decoder->private_);
+ return FLAC__stream_decoder_get_md5_checking((FLAC__StreamDecoder*)decoder);
+}
+
+OggFLAC_API FLAC__uint64 OggFLAC__stream_decoder_get_total_samples(const OggFLAC__StreamDecoder *decoder)
+{
+ FLAC__ASSERT(0 != decoder);
+ FLAC__ASSERT(0 != decoder->private_);
+ return FLAC__stream_decoder_get_total_samples((FLAC__StreamDecoder*)decoder);
}
OggFLAC_API unsigned OggFLAC__stream_decoder_get_channels(const OggFLAC__StreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
- return FLAC__stream_decoder_get_channels(decoder->private_->FLAC_stream_decoder);
+ return FLAC__stream_decoder_get_channels((FLAC__StreamDecoder*)decoder);
}
OggFLAC_API FLAC__ChannelAssignment OggFLAC__stream_decoder_get_channel_assignment(const OggFLAC__StreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
- return FLAC__stream_decoder_get_channel_assignment(decoder->private_->FLAC_stream_decoder);
+ return FLAC__stream_decoder_get_channel_assignment((FLAC__StreamDecoder*)decoder);
}
OggFLAC_API unsigned OggFLAC__stream_decoder_get_bits_per_sample(const OggFLAC__StreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
- return FLAC__stream_decoder_get_bits_per_sample(decoder->private_->FLAC_stream_decoder);
+ return FLAC__stream_decoder_get_bits_per_sample((FLAC__StreamDecoder*)decoder);
}
OggFLAC_API unsigned OggFLAC__stream_decoder_get_sample_rate(const OggFLAC__StreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
- return FLAC__stream_decoder_get_sample_rate(decoder->private_->FLAC_stream_decoder);
+ return FLAC__stream_decoder_get_sample_rate((FLAC__StreamDecoder*)decoder);
}
OggFLAC_API unsigned OggFLAC__stream_decoder_get_blocksize(const OggFLAC__StreamDecoder *decoder)
{
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
- return FLAC__stream_decoder_get_blocksize(decoder->private_->FLAC_stream_decoder);
+ return FLAC__stream_decoder_get_blocksize((FLAC__StreamDecoder*)decoder);
}
OggFLAC_API FLAC__bool OggFLAC__stream_decoder_flush(OggFLAC__StreamDecoder *decoder)
@@ -385,7 +527,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_decoder_flush(OggFLAC__StreamDecoder *dec
OggFLAC__ogg_decoder_aspect_flush(&decoder->protected_->ogg_decoder_aspect);
- if(!FLAC__stream_decoder_flush(decoder->private_->FLAC_stream_decoder)) {
+ if(!FLAC__stream_decoder_flush((FLAC__StreamDecoder*)decoder)) {
decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
return false;
}
@@ -408,7 +550,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_decoder_reset(OggFLAC__StreamDecoder *dec
OggFLAC__ogg_decoder_aspect_reset(&decoder->protected_->ogg_decoder_aspect);
- if(!FLAC__stream_decoder_reset(decoder->private_->FLAC_stream_decoder)) {
+ if(!FLAC__stream_decoder_reset((FLAC__StreamDecoder*)decoder)) {
decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
return false;
}
@@ -423,7 +565,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_decoder_process_single(OggFLAC__StreamDec
FLAC__bool ret;
FLAC__ASSERT(0 != decoder);
- if(FLAC__stream_decoder_get_state(decoder->private_->FLAC_stream_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
+ if(FLAC__stream_decoder_get_state((FLAC__StreamDecoder*)decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
decoder->protected_->state = OggFLAC__STREAM_DECODER_END_OF_STREAM;
if(decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
@@ -431,7 +573,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_decoder_process_single(OggFLAC__StreamDec
FLAC__ASSERT(decoder->protected_->state == OggFLAC__STREAM_DECODER_OK);
- ret = FLAC__stream_decoder_process_single(decoder->private_->FLAC_stream_decoder);
+ ret = FLAC__stream_decoder_process_single((FLAC__StreamDecoder*)decoder);
if(!ret)
decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
@@ -443,7 +585,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_decoder_process_until_end_of_metadata(Ogg
FLAC__bool ret;
FLAC__ASSERT(0 != decoder);
- if(FLAC__stream_decoder_get_state(decoder->private_->FLAC_stream_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
+ if(FLAC__stream_decoder_get_state((FLAC__StreamDecoder*)decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
decoder->protected_->state = OggFLAC__STREAM_DECODER_END_OF_STREAM;
if(decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
@@ -451,7 +593,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_decoder_process_until_end_of_metadata(Ogg
FLAC__ASSERT(decoder->protected_->state == OggFLAC__STREAM_DECODER_OK);
- ret = FLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->FLAC_stream_decoder);
+ ret = FLAC__stream_decoder_process_until_end_of_metadata((FLAC__StreamDecoder*)decoder);
if(!ret)
decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
@@ -463,7 +605,27 @@ OggFLAC_API FLAC__bool OggFLAC__stream_decoder_process_until_end_of_stream(OggFL
FLAC__bool ret;
FLAC__ASSERT(0 != decoder);
- if(FLAC__stream_decoder_get_state(decoder->private_->FLAC_stream_decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
+ if(FLAC__stream_decoder_get_state((FLAC__StreamDecoder*)decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
+ decoder->protected_->state = OggFLAC__STREAM_DECODER_END_OF_STREAM;
+
+ if(decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
+ return true;
+
+ FLAC__ASSERT(decoder->protected_->state == OggFLAC__STREAM_DECODER_OK);
+
+ ret = FLAC__stream_decoder_process_until_end_of_stream((FLAC__StreamDecoder*)decoder);
+ if(!ret)
+ decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
+
+ return ret;
+}
+
+OggFLAC_API FLAC__bool OggFLAC__stream_decoder_skip_single_frame(OggFLAC__StreamDecoder *decoder)
+{
+ FLAC__bool ret;
+ FLAC__ASSERT(0 != decoder);
+
+ if(FLAC__stream_decoder_get_state((FLAC__StreamDecoder*)decoder) == FLAC__STREAM_DECODER_END_OF_STREAM)
decoder->protected_->state = OggFLAC__STREAM_DECODER_END_OF_STREAM;
if(decoder->protected_->state == OggFLAC__STREAM_DECODER_END_OF_STREAM)
@@ -471,13 +633,66 @@ OggFLAC_API FLAC__bool OggFLAC__stream_decoder_process_until_end_of_stream(OggFL
FLAC__ASSERT(decoder->protected_->state == OggFLAC__STREAM_DECODER_OK);
- ret = FLAC__stream_decoder_process_until_end_of_stream(decoder->private_->FLAC_stream_decoder);
+ ret = FLAC__stream_decoder_skip_single_frame((FLAC__StreamDecoder*)decoder);
if(!ret)
decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
return ret;
}
+OggFLAC_API FLAC__bool OggFLAC__stream_decoder_seek_absolute(OggFLAC__StreamDecoder *decoder, FLAC__uint64 sample)
+{
+ FLAC__uint64 length;
+
+ FLAC__ASSERT(0 != decoder);
+
+ if(decoder->protected_->state != OggFLAC__STREAM_DECODER_OK && decoder->protected_->state != OggFLAC__STREAM_DECODER_END_OF_STREAM)
+ return false;
+
+ if(0 == decoder->private_->seek_callback)
+ return false;
+
+ FLAC__ASSERT(decoder->private_->seek_callback);
+ FLAC__ASSERT(decoder->private_->tell_callback);
+ FLAC__ASSERT(decoder->private_->length_callback);
+ FLAC__ASSERT(decoder->private_->eof_callback);
+
+ if(OggFLAC__stream_decoder_get_total_samples(decoder) > 0 && sample >= OggFLAC__stream_decoder_get_total_samples(decoder))
+ return false;
+
+ decoder->private_->is_seeking = true;
+
+ /* get the file length (currently our algorithm needs to know the length so it's also an error to get FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED) */
+ if(decoder->private_->length_callback((FLAC__StreamDecoder*)decoder, &length, decoder->private_->client_data) != FLAC__STREAM_DECODER_LENGTH_STATUS_OK) {
+ decoder->private_->is_seeking = false;
+ return false;
+ }
+
+ /* if we haven't finished processing the metadata yet, do that so we have the STREAMINFO */
+ if(
+ FLAC__stream_decoder_get_state((FLAC__StreamDecoder*)decoder) == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA ||
+ FLAC__stream_decoder_get_state((FLAC__StreamDecoder*)decoder) == FLAC__STREAM_DECODER_READ_METADATA
+ ) {
+ if(!OggFLAC__stream_decoder_process_until_end_of_metadata(decoder)) {
+ /* above call sets the state for us */
+ decoder->private_->is_seeking = false;
+ return false;
+ }
+ /* check this again in case we didn't know total_samples the first time */
+ if(OggFLAC__stream_decoder_get_total_samples(decoder) > 0 && sample >= OggFLAC__stream_decoder_get_total_samples(decoder)) {
+ decoder->protected_->state = OggFLAC__STREAM_DECODER_SEEK_ERROR;
+ decoder->private_->is_seeking = false;
+ return false;
+ }
+ }
+
+ {
+ FLAC__bool ok = seek_to_absolute_sample_(decoder, length, sample);
+ decoder->private_->is_seeking = false;
+ return ok;
+ }
+}
+
/***********************************************************************
*
@@ -488,6 +703,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_decoder_process_until_end_of_stream(OggFL
void set_defaults_(OggFLAC__StreamDecoder *decoder)
{
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 = 0;
@@ -495,11 +714,67 @@ void set_defaults_(OggFLAC__StreamDecoder *decoder)
OggFLAC__ogg_decoder_aspect_set_defaults(&decoder->protected_->ogg_decoder_aspect);
}
-FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *unused, FLAC__byte buffer[], unsigned *bytes, void *client_data)
+/*
+ * This will forcibly set stdin to binary mode (for OSes that require it)
+ */
+FILE *get_binary_stdin_()
{
- OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
+ /* if something breaks here it is probably due to the presence or
+ * absence of an underscore before the identifiers 'setmode',
+ * 'fileno', and/or 'O_BINARY'; check your system header files.
+ */
+#if defined _MSC_VER || defined __MINGW32__
+ _setmode(_fileno(stdin), _O_BINARY);
+#elif defined __CYGWIN__ || defined __EMX__
+ /* almost certainly not needed for any modern Cygwin, but let's be safe... */
+ setmode(_fileno(stdin), _O_BINARY);
+#endif
- (void)unused;
+ return stdin;
+}
+
+FLAC__StreamDecoderReadStatus read_callback2_(const FLAC__StreamDecoder *super, FLAC__byte buffer[], unsigned *bytes, void *client_data)
+{
+ const OggFLAC__StreamDecoder *decoder = (const OggFLAC__StreamDecoder *)super;
+ (void)client_data;
+ if(decoder->private_->eof_callback && decoder->private_->eof_callback((FLAC__StreamDecoder*)decoder, decoder->private_->client_data)) {
+ *bytes = 0;
+#if 0
+ /*@@@@@@ we used to do this: */
+ stream_decoder->protected_->state = OggFLAC__STREAM_DECODER_END_OF_STREAM;
+ /* but it causes a problem because the Ogg decoding layer reads as much as it can to get pages, so the state will get to end-of-stream before the bitbuffer does */
+#endif
+ return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
+ }
+ else if(*bytes > 0) {
+ const FLAC__StreamDecoderReadStatus status = decoder->private_->read_callback(super, buffer, bytes, decoder->private_->client_data);
+ if(status == FLAC__STREAM_DECODER_READ_STATUS_ABORT) {
+ decoder->protected_->state = OggFLAC__STREAM_DECODER_READ_ERROR;
+ return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
+ }
+ else if(*bytes == 0) {
+ if(status == FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM || (decoder->private_->eof_callback && decoder->private_->eof_callback((FLAC__StreamDecoder*)decoder, decoder->private_->client_data))) {
+#if 0
+ /*@@@@@@ we used to do this: */
+ stream_decoder->protected_->state = OggFLAC__STREAM_DECODER_END_OF_STREAM;
+ /* but it causes a problem because the Ogg decoding layer reads as much as it can to get pages, so the state will get to end-of-stream before the bitbuffer does */
+#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__StreamDecoderReadStatus read_callback_ogg_aspect_(const FLAC__StreamDecoder *super, FLAC__byte buffer[], unsigned *bytes, void *client_data)
+{
+ const OggFLAC__StreamDecoder *decoder = (const OggFLAC__StreamDecoder *)super;
+ (void)client_data;
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:
@@ -528,32 +803,11 @@ FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *unused,
}
}
-FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *unused, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
-{
- OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
- (void)unused;
- return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
-}
-
-void metadata_callback_(const FLAC__StreamDecoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
-{
- OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
- (void)unused;
- decoder->private_->metadata_callback(decoder, metadata, decoder->private_->client_data);
-}
-
-void error_callback_(const FLAC__StreamDecoder *unused, FLAC__StreamDecoderErrorStatus status, void *client_data)
-{
- OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
- (void)unused;
- decoder->private_->error_callback(decoder, status, decoder->private_->client_data);
-}
-
OggFLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
{
OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)void_decoder;
- switch(decoder->private_->read_callback(decoder, buffer, bytes, client_data)) {
+ switch(read_callback2_((FLAC__StreamDecoder*)decoder, buffer, bytes, client_data)) {
case FLAC__STREAM_DECODER_READ_STATUS_CONTINUE:
return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_OK;
case FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM:
@@ -566,3 +820,276 @@ OggFLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decode
return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
}
}
+
+FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *super, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
+{
+ OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder *)super;
+ (void)client_data;
+
+ if(decoder->private_->is_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 = decoder->private_->target_sample;
+
+ FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
+
+ decoder->private_->got_a_frame = true;
+ 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 */
+ decoder->private_->is_seeking = false;
+ /* 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;
+ decoder->private_->last_frame.header.blocksize -= delta;
+ decoder->private_->last_frame.header.number.sample_number += (FLAC__uint64)delta;
+ /* write the relevant samples */
+ return decoder->private_->write_callback((FLAC__StreamDecoder*)decoder, &decoder->private_->last_frame, newbuffer, decoder->private_->client_data);
+ }
+ else {
+ /* write the relevant samples */
+ return decoder->private_->write_callback((FLAC__StreamDecoder*)decoder, frame, buffer, decoder->private_->client_data);
+ }
+ }
+ else {
+ return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+ }
+ }
+ else
+ return decoder->private_->write_callback((FLAC__StreamDecoder*)decoder, frame, buffer, decoder->private_->client_data);
+}
+
+void metadata_callback_(const FLAC__StreamDecoder *super, const FLAC__StreamMetadata *metadata, void *client_data)
+{
+ OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder *)super;
+ (void)client_data;
+
+ if(!decoder->private_->is_seeking)
+ decoder->private_->metadata_callback((FLAC__StreamDecoder*)decoder, metadata, decoder->private_->client_data);
+}
+
+void error_callback_(const FLAC__StreamDecoder *super, FLAC__StreamDecoderErrorStatus status, void *client_data)
+{
+ OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder *)super;
+ (void)client_data;
+
+ if(!decoder->private_->is_seeking)
+ decoder->private_->error_callback((FLAC__StreamDecoder*)decoder, status, decoder->private_->client_data);
+}
+
+FLAC__bool seek_to_absolute_sample_(OggFLAC__StreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample)
+{
+ FLAC__uint64 left_pos = 0, right_pos = stream_length;
+ FLAC__uint64 left_sample = 0, right_sample = OggFLAC__stream_decoder_get_total_samples(decoder);
+ FLAC__uint64 this_frame_sample = 0; /* only initialized to avoid compiler warning */
+ FLAC__uint64 pos = 0; /* only initialized to avoid compiler warning */
+ FLAC__bool did_a_seek;
+ unsigned iteration = 0;
+
+ /* In the first iterations, we will calculate the target byte position
+ * by the distance from the target sample to left_sample and
+ * right_sample (let's call it "proportional search"). After that, we
+ * will switch to binary search.
+ */
+ unsigned BINARY_SEARCH_AFTER_ITERATION = 2;
+
+ /* We will switch to a linear search once our current sample is less
+ * than 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
+ * force binary search immediately.
+ */
+ if(right_sample == 0) {
+ right_sample = (FLAC__uint64)(-1);
+ BINARY_SEARCH_AFTER_ITERATION = 0;
+ }
+
+ decoder->private_->target_sample = target_sample;
+ for( ; ; iteration++) {
+ if (iteration == 0 || this_frame_sample > target_sample || target_sample - this_frame_sample > LINEAR_SEARCH_WITHIN_SAMPLES) {
+ if (iteration >= BINARY_SEARCH_AFTER_ITERATION) {
+ pos = (right_pos + left_pos) / 2;
+ }
+ else {
+#ifndef FLAC__INTEGER_ONLY_LIBRARY
+#if defined _MSC_VER || defined __MINGW32__
+ /* with MSVC you have to spoon feed it the casting */
+ pos = (FLAC__uint64)((FLAC__double)(FLAC__int64)(target_sample - left_sample) / (FLAC__double)(FLAC__int64)(right_sample - left_sample) * (FLAC__double)(FLAC__int64)(right_pos - left_pos));
+#else
+ pos = (FLAC__uint64)((FLAC__double)(target_sample - left_sample) / (FLAC__double)(right_sample - left_sample) * (FLAC__double)(right_pos - left_pos));
+#endif
+#else
+ /* a little less accurate: */
+ if ((target_sample-left_sample <= 0xffffffff) && (right_pos-left_pos <= 0xffffffff))
+ pos = (FLAC__int64)(((target_sample-left_sample) * (right_pos-left_pos)) / (right_sample-left_sample));
+ else /* @@@ WATCHOUT, ~2TB limit */
+ pos = (FLAC__int64)((((target_sample-left_sample)>>8) * ((right_pos-left_pos)>>8)) / ((right_sample-left_sample)>>16));
+#endif
+ /* @@@ TODO: might want to limit pos to some distance
+ * before EOF, to make sure we land before the last frame,
+ * thereby getting a this_fram_sample and so having a better
+ * estimate. @@@@@@DELETE:this would also mostly (or totally if we could
+ * be sure to land before the last frame) avoid the
+ * end-of-stream case we have to check later.
+ */
+ }
+
+ /* physical seek */
+ if(decoder->private_->seek_callback((FLAC__StreamDecoder*)decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__STREAM_DECODER_SEEK_STATUS_OK) {
+ decoder->protected_->state = OggFLAC__STREAM_DECODER_SEEK_ERROR;
+ return false;
+ }
+ if(!OggFLAC__stream_decoder_flush(decoder)) {
+ /* above call sets the state for us */
+ return false;
+ }
+ did_a_seek = true;
+ }
+ else
+ did_a_seek = false;
+
+ decoder->private_->got_a_frame = false;
+ if(!OggFLAC__stream_decoder_process_single(decoder)) {
+ decoder->protected_->state = OggFLAC__STREAM_DECODER_SEEK_ERROR;
+ return false;
+ }
+ if(!decoder->private_->got_a_frame) {
+ if(did_a_seek) {
+ /* this can happen if we seek to a point after the last frame; we drop
+ * to binary search right away in this case to avoid any wasted
+ * iterations of proportional search.
+ */
+ right_pos = pos;
+ BINARY_SEARCH_AFTER_ITERATION = 0;
+ }
+ else {
+ /* this can probably only happen if total_samples is unknown and the
+ * target_sample is past the end of the stream
+ */
+ decoder->protected_->state = OggFLAC__STREAM_DECODER_SEEK_ERROR;
+ return false;
+ }
+ }
+ /* our write callback will change the state when it gets to the target frame */
+ else if(!decoder->private_->is_seeking/*@@@@@@ && decoder->protected_->state != OggFLAC__STREAM_DECODER_END_OF_STREAM*/) {
+ break;
+ }
+ else {
+ 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 (did_a_seek) {
+ 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;
+ /* sanity check to avoid infinite loop */
+ if (left_pos == pos) {
+ decoder->protected_->state = OggFLAC__STREAM_DECODER_SEEK_ERROR;
+ return false;
+ }
+ left_pos = pos;
+ }
+ else if(this_frame_sample > target_sample) {
+ right_sample = this_frame_sample;
+ /* sanity check to avoid infinite loop */
+ if (right_pos == pos) {
+ decoder->protected_->state = OggFLAC__STREAM_DECODER_SEEK_ERROR;
+ return false;
+ }
+ right_pos = pos;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+FLAC__StreamDecoderReadStatus file_read_callback_(const FLAC__StreamDecoder *super, FLAC__byte buffer[], unsigned *bytes, void *client_data)
+{
+ OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder *)super;
+ (void)client_data;
+
+ if(*bytes > 0) {
+ *bytes = (unsigned)fread(buffer, sizeof(FLAC__byte), *bytes, decoder->private_->file);
+ if(ferror(decoder->private_->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
+ return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
+}
+
+FLAC__StreamDecoderSeekStatus file_seek_callback_(const FLAC__StreamDecoder *super, FLAC__uint64 absolute_byte_offset, void *client_data)
+{
+ OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder *)super;
+ (void)client_data;
+
+ if(decoder->private_->file == stdin)
+ return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
+ else if(fseeko(decoder->private_->file, (off_t)absolute_byte_offset, SEEK_SET) < 0)
+ return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
+ else
+ return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
+}
+
+FLAC__StreamDecoderTellStatus file_tell_callback_(const FLAC__StreamDecoder *super, FLAC__uint64 *absolute_byte_offset, void *client_data)
+{
+ OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder *)super;
+ off_t pos;
+ (void)client_data;
+
+ if(decoder->private_->file == stdin) /*@@@@@@ may work for stdin */
+ return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
+ else if((pos = ftello(decoder->private_->file)) < 0)
+ return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
+ else {
+ *absolute_byte_offset = (FLAC__uint64)pos;
+ return FLAC__STREAM_DECODER_TELL_STATUS_OK;
+ }
+}
+
+FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *super, FLAC__uint64 *stream_length, void *client_data)
+{
+ OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder *)super;
+ struct stat filestats;
+ (void)client_data;
+
+ if(decoder->private_->file == stdin)
+ return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
+#ifdef OLD_STAT_WAY //@@@@@@
+ else if(0 == decoder->private_->filename || fstat(fileno(decoder->private_->file), &filestats) != 0)
+#endif
+ else if(fstat(fileno(decoder->private_->file), &filestats) != 0)
+ return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
+ else {
+ *stream_length = (FLAC__uint64)filestats.st_size;
+ return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
+ }
+}
+
+FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *super, void *client_data)
+{
+ OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder *)super;
+ (void)client_data;
+
+ if(decoder->private_->file == stdin) /*@@@@@@ feof() may work for stdin */
+ return false;
+ return feof(decoder->private_->file)? true : false;
+}
diff --git a/src/libOggFLAC/stream_encoder.c b/src/libOggFLAC/stream_encoder.c
index 1c7c95a8..53e35b62 100644
--- a/src/libOggFLAC/stream_encoder.c
+++ b/src/libOggFLAC/stream_encoder.c
@@ -33,11 +33,32 @@
# include <config.h>
#endif
+#if defined _MSC_VER || defined __MINGW32__
+#include <io.h> /* for _setmode() */
+#include <fcntl.h> /* for _O_BINARY */
+#endif
+#if defined __CYGWIN__ || defined __EMX__
+#include <io.h> /* for setmode(), O_BINARY */
+#include <fcntl.h> /* for _O_BINARY */
+#endif
#include <stdio.h>
#include <stdlib.h> /* for calloc() */
+#include <string.h> /* for memcpy() */
+#include <sys/types.h> /* for off_t */
+#if defined _MSC_VER || defined __MINGW32__
+/*@@@ [2G limit] hacks for MSVC6 */
+#define fseeko fseek
+#define ftello ftell
+#endif
#include "FLAC/assert.h"
#include "OggFLAC/stream_encoder.h"
#include "protected/stream_encoder.h"
+#include "private/ogg_helper.h"
+
+#ifdef max
+#undef max
+#endif
+#define max(a,b) ((a)>(b)?(a):(b))
/***********************************************************************
*
@@ -53,6 +74,11 @@ extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEn
static void set_defaults_(OggFLAC__StreamEncoder *encoder);
static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
+static OggFLAC__StreamEncoderReadStatus file_read_callback_(const OggFLAC__StreamEncoder *encoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
+static FLAC__StreamEncoderSeekStatus file_seek_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data);
+static FLAC__StreamEncoderTellStatus file_tell_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
+static FLAC__StreamEncoderWriteStatus file_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
+static FILE *get_binary_stdout_();
/***********************************************************************
@@ -62,10 +88,24 @@ static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__S
***********************************************************************/
typedef struct OggFLAC__StreamEncoderPrivate {
- OggFLAC__StreamEncoderWriteCallback write_callback;
- OggFLAC__StreamEncoderMetadataCallback metadata_callback;
+ OggFLAC__StreamEncoderReadCallback read_callback;
+ FLAC__StreamEncoderWriteCallback write_callback;
+ FLAC__StreamEncoderSeekCallback seek_callback;
+ FLAC__StreamEncoderTellCallback tell_callback;
+ FLAC__StreamEncoderMetadataCallback metadata_callback;
+ FLAC__StreamEncoderProgressCallback progress_callback;
void *client_data;
+#if 0 //@@@@@@
FLAC__StreamEncoder *FLAC_stream_encoder;
+#endif
+ FLAC__StreamMetadata_SeekTable *seek_table;
+ /* internal vars (all the above are class settings) */
+ unsigned first_seekpoint_to_check;
+ FILE *file; /* only used when encoding to a file */
+ FLAC__uint64 bytes_written;
+ FLAC__uint64 samples_written;
+ unsigned frames_written;
+ unsigned total_frames_estimate;
} OggFLAC__StreamEncoderPrivate;
@@ -77,12 +117,19 @@ typedef struct OggFLAC__StreamEncoderPrivate {
OggFLAC_API const char * const OggFLAC__StreamEncoderStateString[] = {
"OggFLAC__STREAM_ENCODER_OK",
+ "OggFLAC__STREAM_ENCODER_UNINITIALIZED",
"OggFLAC__STREAM_ENCODER_OGG_ERROR",
"OggFLAC__STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR",
- "OggFLAC__STREAM_ENCODER_INVALID_CALLBACK",
- "OggFLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR",
- "OggFLAC__STREAM_ENCODER_ALREADY_INITIALIZED",
- "OggFLAC__STREAM_ENCODER_UNINITIALIZED"
+ "OggFLAC__STREAM_ENCODER_CLIENT_ERROR",
+ "OggFLAC__STREAM_ENCODER_IO_ERROR",
+ "OggFLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR"
+};
+
+OggFLAC_API const char * const OggFLAC__treamEncoderReadStatusString[] = {
+ "OggFLAC__STREAM_ENCODER_READ_STATUS_CONTINUE",
+ "OggFLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM",
+ "OggFLAC__STREAM_ENCODER_READ_STATUS_ABORT",
+ "OggFLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED"
};
@@ -94,6 +141,9 @@ OggFLAC_API const char * const OggFLAC__StreamEncoderStateString[] = {
OggFLAC_API OggFLAC__StreamEncoder *OggFLAC__stream_encoder_new()
{
OggFLAC__StreamEncoder *encoder;
+ FLAC__StreamEncoder *parent;
+
+ FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
encoder = (OggFLAC__StreamEncoder*)calloc(1, sizeof(OggFLAC__StreamEncoder));
if(encoder == 0) {
@@ -113,13 +163,16 @@ OggFLAC_API OggFLAC__StreamEncoder *OggFLAC__stream_encoder_new()
return 0;
}
- encoder->private_->FLAC_stream_encoder = FLAC__stream_encoder_new();
- if(0 == encoder->private_->FLAC_stream_encoder) {
+ parent = FLAC__stream_encoder_new();
+ if(0 == parent) {
free(encoder->private_);
free(encoder->protected_);
free(encoder);
return 0;
}
+ encoder->super_ = *parent;
+
+ encoder->private_->file = 0;
set_defaults_(encoder);
@@ -133,15 +186,15 @@ OggFLAC_API void OggFLAC__stream_encoder_delete(OggFLAC__StreamEncoder *encoder)
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->protected_);
FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
(void)OggFLAC__stream_encoder_finish(encoder);
- FLAC__stream_encoder_delete(encoder->private_->FLAC_stream_encoder);
-
free(encoder->private_);
free(encoder->protected_);
- free(encoder);
+ /* don't free(encoder) because FLAC__stream_encoder_delete() will do it */
+
+ /* call superclass destructor last */
+ FLAC__stream_encoder_delete((FLAC__StreamEncoder*)encoder);
}
@@ -151,27 +204,126 @@ OggFLAC_API void OggFLAC__stream_encoder_delete(OggFLAC__StreamEncoder *encoder)
*
***********************************************************************/
-OggFLAC_API OggFLAC__StreamEncoderState OggFLAC__stream_encoder_init(OggFLAC__StreamEncoder *encoder)
+OggFLAC_API FLAC__StreamEncoderInitStatus OggFLAC__stream_encoder_init_stream(OggFLAC__StreamEncoder *encoder, OggFLAC__StreamEncoderReadCallback read_callback, FLAC__StreamEncoderWriteCallback write_callback, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderTellCallback tell_callback, FLAC__StreamEncoderMetadataCallback metadata_callback, void *client_data)
{
FLAC__ASSERT(0 != encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
- return encoder->protected_->state = OggFLAC__STREAM_ENCODER_ALREADY_INITIALIZED;
+ return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED;
+
+ if(0 == write_callback || (seek_callback && (0 == read_callback || 0 == tell_callback)))
+ return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS;
- if(0 == encoder->private_->write_callback || 0 == encoder->private_->metadata_callback)
- return encoder->protected_->state = OggFLAC__STREAM_ENCODER_INVALID_CALLBACK;
+ /* check seek table before FLAC__stream_encoder_init_stream() does, just to avoid messing up the encoder state for a trivial error */
+ if(0 != encoder->private_->seek_table && !FLAC__format_seektable_is_legal(encoder->private_->seek_table))
+ return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
- if(!OggFLAC__ogg_encoder_aspect_init(&encoder->protected_->ogg_encoder_aspect))
- return encoder->protected_->state = OggFLAC__STREAM_ENCODER_OGG_ERROR;
+ /* set state to OK; from here on, errors are fatal and we'll override the state then */
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_OK;
+
+ if(!OggFLAC__ogg_encoder_aspect_init(&encoder->protected_->ogg_encoder_aspect)) {
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_OGG_ERROR;
+ return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
+ }
- FLAC__stream_encoder_set_write_callback(encoder->private_->FLAC_stream_encoder, write_callback_);
- FLAC__stream_encoder_set_metadata_callback(encoder->private_->FLAC_stream_encoder, metadata_callback_);
- FLAC__stream_encoder_set_client_data(encoder->private_->FLAC_stream_encoder, encoder);
+ encoder->private_->read_callback = read_callback;
+ encoder->private_->write_callback = write_callback;
+ encoder->private_->seek_callback = seek_callback;
+ encoder->private_->tell_callback = tell_callback;
+ encoder->private_->metadata_callback = metadata_callback;
+ encoder->private_->client_data = client_data;
+
+ /*
+ * These must be done before we init the stream encoder because that
+ * calls the write_callback, which uses these values.
+ */
+ encoder->private_->first_seekpoint_to_check = 0;
+ encoder->private_->samples_written = 0;
+ encoder->protected_->streaminfo_offset = 0;
+ encoder->protected_->seektable_offset = 0;
+ encoder->protected_->audio_offset = 0;
+
+ /* we do our own special metadata updating inside Ogg here, so we don't pass in our seek/tell callbacks */
+ if(FLAC__stream_encoder_init_stream((FLAC__StreamEncoder*)encoder, write_callback_, /*seek_callback=*/0, /*tell_callback=*/0, metadata_callback_, /*client_data=*/encoder) != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
+ return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
+ }
- if(FLAC__stream_encoder_init(encoder->private_->FLAC_stream_encoder) != FLAC__STREAM_ENCODER_OK)
- return encoder->protected_->state = OggFLAC__STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
+ /*
+ * Initializing the stream encoder writes all the metadata, so we
+ * save the stream offset now.
+ */
+ if(encoder->private_->tell_callback && encoder->private_->tell_callback((FLAC__StreamEncoder*)encoder, &encoder->protected_->audio_offset, encoder->private_->client_data) == FLAC__STREAM_ENCODER_TELL_STATUS_ERROR) { /* FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED just means we didn't get the offset; no error */
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_CLIENT_ERROR;
+ return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
+ }
- return encoder->protected_->state = OggFLAC__STREAM_ENCODER_OK;
+ return FLAC__STREAM_ENCODER_INIT_STATUS_OK;
+}
+
+OggFLAC_API FLAC__StreamEncoderInitStatus OggFLAC__stream_encoder_init_FILE(OggFLAC__StreamEncoder *encoder, FILE *file, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data)
+{
+ FLAC__StreamEncoderInitStatus init_status;
+
+ FLAC__ASSERT(0 != encoder);
+ FLAC__ASSERT(0 != file);
+
+ if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
+ return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED;
+
+ /*
+ * To make sure that our file does not go unclosed after an error, we
+ * must assign the FILE pointer before any further error can occur in
+ * this routine.
+ */
+ if(file == stdout)
+ file = get_binary_stdout_(); /* just to be safe */
+
+ encoder->private_->file = file;
+
+ encoder->private_->progress_callback = progress_callback;
+ encoder->private_->bytes_written = 0;
+ encoder->private_->samples_written = 0;
+ encoder->private_->frames_written = 0;
+
+ init_status = OggFLAC__stream_encoder_init_stream(encoder, file_read_callback_, file_write_callback_, file_seek_callback_, file_tell_callback_, /*metadata_callback=*/0, client_data);
+ if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
+ /* the above function sets the state for us in case of an error */
+ return init_status;
+ }
+
+ {
+ unsigned blocksize = OggFLAC__stream_encoder_get_blocksize(encoder);
+
+ FLAC__ASSERT(blocksize != 0);
+ encoder->private_->total_frames_estimate = (unsigned)((OggFLAC__stream_encoder_get_total_samples_estimate(encoder) + blocksize - 1) / blocksize);
+ }
+
+ return init_status;
+}
+
+OggFLAC_API FLAC__StreamEncoderInitStatus OggFLAC__stream_encoder_init_file(OggFLAC__StreamEncoder *encoder, const char *filename, FLAC__StreamEncoderProgressCallback progress_callback, void *client_data)
+{
+ FILE *file;
+
+ FLAC__ASSERT(0 != encoder);
+
+ /*
+ * To make sure that our file does not go unclosed after an error, we
+ * have to do the same entrance checks here that are later performed
+ * in FLAC__stream_encoder_init_FILE() before the FILE* is assigned.
+ */
+ if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
+ return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED;
+
+ file = filename? fopen(filename, "w+b") : stdout;
+
+ if(file == 0) {
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_IO_ERROR;
+ return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
+ }
+
+ return OggFLAC__stream_encoder_init_FILE(encoder, file, progress_callback, client_data);
}
OggFLAC_API void OggFLAC__stream_encoder_finish(OggFLAC__StreamEncoder *encoder)
@@ -183,9 +335,9 @@ OggFLAC_API void OggFLAC__stream_encoder_finish(OggFLAC__StreamEncoder *encoder)
if(encoder->protected_->state == OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return;
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
- FLAC__stream_encoder_finish(encoder->private_->FLAC_stream_encoder);
+ FLAC__stream_encoder_finish((FLAC__StreamEncoder*)encoder);
OggFLAC__ogg_encoder_aspect_finish(&encoder->protected_->ogg_encoder_aspect);
@@ -199,7 +351,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_serial_number(OggFLAC__Stream
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
OggFLAC__ogg_encoder_aspect_set_serial_number(&encoder->protected_->ogg_encoder_aspect, value);
@@ -211,10 +363,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_verify(OggFLAC__StreamEncoder
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_verify(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_verify((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_streamable_subset(OggFLAC__StreamEncoder *encoder, FLAC__bool value)
@@ -222,10 +374,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_streamable_subset(OggFLAC__St
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_streamable_subset(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_streamable_subset((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_do_mid_side_stereo(OggFLAC__StreamEncoder *encoder, FLAC__bool value)
@@ -233,10 +385,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_do_mid_side_stereo(OggFLAC__S
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_do_mid_side_stereo(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_do_mid_side_stereo((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_loose_mid_side_stereo(OggFLAC__StreamEncoder *encoder, FLAC__bool value)
@@ -244,10 +396,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_loose_mid_side_stereo(OggFLAC
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_loose_mid_side_stereo(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_loose_mid_side_stereo((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_channels(OggFLAC__StreamEncoder *encoder, unsigned value)
@@ -255,10 +407,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_channels(OggFLAC__StreamEncod
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_channels(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_channels((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_bits_per_sample(OggFLAC__StreamEncoder *encoder, unsigned value)
@@ -266,10 +418,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_bits_per_sample(OggFLAC__Stre
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_bits_per_sample(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_bits_per_sample((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_sample_rate(OggFLAC__StreamEncoder *encoder, unsigned value)
@@ -277,10 +429,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_sample_rate(OggFLAC__StreamEn
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_sample_rate(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_sample_rate((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_blocksize(OggFLAC__StreamEncoder *encoder, unsigned value)
@@ -288,10 +440,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_blocksize(OggFLAC__StreamEnco
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_blocksize(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_blocksize((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_apodization(OggFLAC__StreamEncoder *encoder, const char *specification)
@@ -299,10 +451,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_apodization(OggFLAC__StreamEn
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_apodization(encoder->private_->FLAC_stream_encoder, specification);
+ return FLAC__stream_encoder_set_apodization((FLAC__StreamEncoder*)encoder, specification);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_max_lpc_order(OggFLAC__StreamEncoder *encoder, unsigned value)
@@ -310,10 +462,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_max_lpc_order(OggFLAC__Stream
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_max_lpc_order(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_max_lpc_order((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_qlp_coeff_precision(OggFLAC__StreamEncoder *encoder, unsigned value)
@@ -321,10 +473,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_qlp_coeff_precision(OggFLAC__
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_qlp_coeff_precision(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_qlp_coeff_precision((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_do_qlp_coeff_prec_search(OggFLAC__StreamEncoder *encoder, FLAC__bool value)
@@ -332,10 +484,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_do_qlp_coeff_prec_search(OggF
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_do_qlp_coeff_prec_search((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_do_escape_coding(OggFLAC__StreamEncoder *encoder, FLAC__bool value)
@@ -343,10 +495,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_do_escape_coding(OggFLAC__Str
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_do_escape_coding(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_do_escape_coding((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_do_exhaustive_model_search(OggFLAC__StreamEncoder *encoder, FLAC__bool value)
@@ -354,10 +506,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_do_exhaustive_model_search(Og
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_do_exhaustive_model_search(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_do_exhaustive_model_search((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_min_residual_partition_order(OggFLAC__StreamEncoder *encoder, unsigned value)
@@ -365,10 +517,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_min_residual_partition_order(
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_min_residual_partition_order(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_min_residual_partition_order((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_max_residual_partition_order(OggFLAC__StreamEncoder *encoder, unsigned value)
@@ -376,10 +528,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_max_residual_partition_order(
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_max_residual_partition_order((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_rice_parameter_search_dist(OggFLAC__StreamEncoder *encoder, unsigned value)
@@ -387,10 +539,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_rice_parameter_search_dist(Og
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_rice_parameter_search_dist((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_total_samples_estimate(OggFLAC__StreamEncoder *encoder, FLAC__uint64 value)
@@ -398,10 +550,10 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_total_samples_estimate(OggFLA
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_set_total_samples_estimate((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_metadata(OggFLAC__StreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
@@ -409,7 +561,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_metadata(OggFLAC__StreamEncod
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
+ //@@@@@@superclass;FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
/* reorder metadata if necessary to ensure that any VORBIS_COMMENT is the first, according to the mapping spec */
@@ -425,49 +577,24 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_metadata(OggFLAC__StreamEncod
}
}
}
+ if(0 != metadata && num_blocks > 0) {
+ unsigned i;
+ for(i = 0; i < num_blocks; i++) {
+ /* keep track of any SEEKTABLE block */
+ if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) {
+ encoder->private_->seek_table = &metadata[i]->data.seek_table;
+ break; /* take only the first one */
+ }
+ }
+ }
if(!OggFLAC__ogg_encoder_aspect_set_num_metadata(&encoder->protected_->ogg_encoder_aspect, num_blocks))
return false;
- return FLAC__stream_encoder_set_metadata(encoder->private_->FLAC_stream_encoder, metadata, num_blocks);
-}
-
-OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_write_callback(OggFLAC__StreamEncoder *encoder, OggFLAC__StreamEncoderWriteCallback value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != value);
- if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->private_->write_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_metadata_callback(OggFLAC__StreamEncoder *encoder, OggFLAC__StreamEncoderMetadataCallback value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- FLAC__ASSERT(0 != value);
- if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->private_->metadata_callback = value;
- return true;
-}
-
-OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_client_data(OggFLAC__StreamEncoder *encoder, void *value)
-{
- FLAC__ASSERT(0 != encoder);
- FLAC__ASSERT(0 != encoder->private_);
- FLAC__ASSERT(0 != encoder->protected_);
- if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
- return false;
- encoder->private_->client_data = value;
- return true;
+ return FLAC__stream_encoder_set_metadata((FLAC__StreamEncoder*)encoder, metadata, num_blocks);
}
/*
* These three functions are not static, but not publically exposed in
- * include/FLAC/ either. They are used by the test suite.
+ * include/OggFLAC/ either. They are used by the test suite.
*/
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_disable_constant_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value)
{
@@ -476,7 +603,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_disable_constant_subframes(OggFLA
FLAC__ASSERT(0 != encoder->protected_);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_disable_constant_subframes(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_disable_constant_subframes((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_disable_fixed_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value)
@@ -486,7 +613,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_disable_fixed_subframes(OggFLAC__
FLAC__ASSERT(0 != encoder->protected_);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_disable_fixed_subframes(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_disable_fixed_subframes((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_disable_verbatim_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value)
@@ -496,7 +623,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_disable_verbatim_subframes(OggFLA
FLAC__ASSERT(0 != encoder->protected_);
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
return false;
- return FLAC__stream_encoder_disable_verbatim_subframes(encoder->private_->FLAC_stream_encoder, value);
+ return FLAC__stream_encoder_disable_verbatim_subframes((FLAC__StreamEncoder*)encoder, value);
}
OggFLAC_API OggFLAC__StreamEncoderState OggFLAC__stream_encoder_get_state(const OggFLAC__StreamEncoder *encoder)
@@ -512,7 +639,7 @@ OggFLAC_API FLAC__StreamEncoderState OggFLAC__stream_encoder_get_FLAC_stream_enc
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_state(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_state((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API FLAC__StreamDecoderState OggFLAC__stream_encoder_get_verify_decoder_state(const OggFLAC__StreamEncoder *encoder)
@@ -520,7 +647,7 @@ OggFLAC_API FLAC__StreamDecoderState OggFLAC__stream_encoder_get_verify_decoder_
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_verify_decoder_state(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_verify_decoder_state((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API const char *OggFLAC__stream_encoder_get_resolved_state_string(const OggFLAC__StreamEncoder *encoder)
@@ -528,14 +655,14 @@ OggFLAC_API const char *OggFLAC__stream_encoder_get_resolved_state_string(const
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR)
return OggFLAC__StreamEncoderStateString[encoder->protected_->state];
else
- return FLAC__stream_encoder_get_resolved_state_string(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_resolved_state_string((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API void OggFLAC__stream_encoder_get_verify_decoder_error_stats(const OggFLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
{
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
- FLAC__stream_encoder_get_verify_decoder_error_stats(encoder->private_->FLAC_stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
+ FLAC__stream_encoder_get_verify_decoder_error_stats((FLAC__StreamEncoder*)encoder, absolute_sample, frame_number, channel, sample, expected, got);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_get_verify(const OggFLAC__StreamEncoder *encoder)
@@ -543,7 +670,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_get_verify(const OggFLAC__StreamE
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_verify(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_verify((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_get_streamable_subset(const OggFLAC__StreamEncoder *encoder)
@@ -551,7 +678,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_get_streamable_subset(const OggFL
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_streamable_subset(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_streamable_subset((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_get_do_mid_side_stereo(const OggFLAC__StreamEncoder *encoder)
@@ -559,7 +686,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_get_do_mid_side_stereo(const OggF
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_do_mid_side_stereo(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_do_mid_side_stereo((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_get_loose_mid_side_stereo(const OggFLAC__StreamEncoder *encoder)
@@ -567,7 +694,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_get_loose_mid_side_stereo(const O
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_loose_mid_side_stereo(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_loose_mid_side_stereo((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API unsigned OggFLAC__stream_encoder_get_channels(const OggFLAC__StreamEncoder *encoder)
@@ -575,7 +702,7 @@ OggFLAC_API unsigned OggFLAC__stream_encoder_get_channels(const OggFLAC__StreamE
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_channels(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_channels((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API unsigned OggFLAC__stream_encoder_get_bits_per_sample(const OggFLAC__StreamEncoder *encoder)
@@ -583,7 +710,7 @@ OggFLAC_API unsigned OggFLAC__stream_encoder_get_bits_per_sample(const OggFLAC__
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_bits_per_sample(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_bits_per_sample((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API unsigned OggFLAC__stream_encoder_get_sample_rate(const OggFLAC__StreamEncoder *encoder)
@@ -591,7 +718,7 @@ OggFLAC_API unsigned OggFLAC__stream_encoder_get_sample_rate(const OggFLAC__Stre
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_sample_rate(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_sample_rate((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API unsigned OggFLAC__stream_encoder_get_blocksize(const OggFLAC__StreamEncoder *encoder)
@@ -599,7 +726,7 @@ OggFLAC_API unsigned OggFLAC__stream_encoder_get_blocksize(const OggFLAC__Stream
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_blocksize(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_blocksize((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API unsigned OggFLAC__stream_encoder_get_max_lpc_order(const OggFLAC__StreamEncoder *encoder)
@@ -607,7 +734,7 @@ OggFLAC_API unsigned OggFLAC__stream_encoder_get_max_lpc_order(const OggFLAC__St
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_max_lpc_order(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_max_lpc_order((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API unsigned OggFLAC__stream_encoder_get_qlp_coeff_precision(const OggFLAC__StreamEncoder *encoder)
@@ -615,7 +742,7 @@ OggFLAC_API unsigned OggFLAC__stream_encoder_get_qlp_coeff_precision(const OggFL
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_qlp_coeff_precision(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_qlp_coeff_precision((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_get_do_qlp_coeff_prec_search(const OggFLAC__StreamEncoder *encoder)
@@ -623,7 +750,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_get_do_qlp_coeff_prec_search(cons
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_do_qlp_coeff_prec_search((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_get_do_escape_coding(const OggFLAC__StreamEncoder *encoder)
@@ -631,7 +758,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_get_do_escape_coding(const OggFLA
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_do_escape_coding(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_do_escape_coding((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_get_do_exhaustive_model_search(const OggFLAC__StreamEncoder *encoder)
@@ -639,7 +766,7 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_get_do_exhaustive_model_search(co
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_do_exhaustive_model_search(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_do_exhaustive_model_search((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API unsigned OggFLAC__stream_encoder_get_min_residual_partition_order(const OggFLAC__StreamEncoder *encoder)
@@ -647,7 +774,7 @@ OggFLAC_API unsigned OggFLAC__stream_encoder_get_min_residual_partition_order(co
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_min_residual_partition_order(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_min_residual_partition_order((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API unsigned OggFLAC__stream_encoder_get_max_residual_partition_order(const OggFLAC__StreamEncoder *encoder)
@@ -655,7 +782,7 @@ OggFLAC_API unsigned OggFLAC__stream_encoder_get_max_residual_partition_order(co
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_max_residual_partition_order(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_max_residual_partition_order((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API unsigned OggFLAC__stream_encoder_get_rice_parameter_search_dist(const OggFLAC__StreamEncoder *encoder)
@@ -663,7 +790,7 @@ OggFLAC_API unsigned OggFLAC__stream_encoder_get_rice_parameter_search_dist(cons
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_rice_parameter_search_dist(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_rice_parameter_search_dist((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API FLAC__uint64 OggFLAC__stream_encoder_get_total_samples_estimate(const OggFLAC__StreamEncoder *encoder)
@@ -671,7 +798,7 @@ OggFLAC_API FLAC__uint64 OggFLAC__stream_encoder_get_total_samples_estimate(cons
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->FLAC_stream_encoder);
+ return FLAC__stream_encoder_get_total_samples_estimate((FLAC__StreamEncoder*)encoder);
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_process(OggFLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
@@ -679,7 +806,12 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_process(OggFLAC__StreamEncoder *e
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_process(encoder->private_->FLAC_stream_encoder, buffer, samples);
+ if(!FLAC__stream_encoder_process((FLAC__StreamEncoder*)encoder, buffer, samples)) {
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
+ return false;
+ }
+ else
+ return true;
}
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_process_interleaved(OggFLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
@@ -687,7 +819,12 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_process_interleaved(OggFLAC__Stre
FLAC__ASSERT(0 != encoder);
FLAC__ASSERT(0 != encoder->private_);
FLAC__ASSERT(0 != encoder->protected_);
- return FLAC__stream_encoder_process_interleaved(encoder->private_->FLAC_stream_encoder, buffer, samples);
+ if(!FLAC__stream_encoder_process_interleaved((FLAC__StreamEncoder*)encoder, buffer, samples)) {
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
+ return false;
+ }
+ else
+ return true;
}
/***********************************************************************
@@ -699,30 +836,376 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_process_interleaved(OggFLAC__Stre
void set_defaults_(OggFLAC__StreamEncoder *encoder)
{
FLAC__ASSERT(0 != encoder);
+ FLAC__ASSERT(0 != encoder->private_);
+ FLAC__ASSERT(0 != encoder->protected_);
+ encoder->private_->read_callback = 0;
encoder->private_->write_callback = 0;
+ encoder->private_->seek_callback = 0;
+ encoder->private_->tell_callback = 0;
encoder->private_->metadata_callback = 0;
+ encoder->private_->progress_callback = 0;
encoder->private_->client_data = 0;
+
+ encoder->private_->seek_table = 0;
+
OggFLAC__ogg_encoder_aspect_set_defaults(&encoder->protected_->ogg_encoder_aspect);
}
-FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *unused, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
+FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *super, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
{
- OggFLAC__StreamEncoder *encoder = (OggFLAC__StreamEncoder*)client_data;
- const FLAC__uint64 total_samples_estimate = FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->FLAC_stream_encoder);
+ OggFLAC__StreamEncoder *encoder = (OggFLAC__StreamEncoder*)super;
+ FLAC__StreamEncoderWriteStatus status;
+ FLAC__uint64 output_position;
+
+ (void)client_data; /* silence compiler warning about unused parameter */
+
+ /* FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED just means we didn't get the offset; no error */
+ if(encoder->private_->tell_callback && encoder->private_->tell_callback((FLAC__StreamEncoder*)encoder, &output_position, encoder->private_->client_data) == FLAC__STREAM_ENCODER_TELL_STATUS_ERROR) {
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_CLIENT_ERROR;
+ return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
+ }
+
+ /*
+ * Watch for the STREAMINFO block and first SEEKTABLE block to go by and store their offsets.
+ */
+ if(samples == 0) {
+ FLAC__MetadataType type = (buffer[0] & 0x7f);
+ if(type == FLAC__METADATA_TYPE_STREAMINFO)
+ encoder->protected_->streaminfo_offset = output_position;
+ else if(type == FLAC__METADATA_TYPE_SEEKTABLE && encoder->protected_->seektable_offset == 0)
+ encoder->protected_->seektable_offset = output_position;
+ }
+
+ /*
+ * Mark the current seek point if hit (if audio_offset == 0 that
+ * means we're still writing metadata and haven't hit the first
+ * frame yet)
+ */
+ if(0 != encoder->private_->seek_table && encoder->protected_->audio_offset > 0 && encoder->private_->seek_table->num_points > 0) {
+ const unsigned blocksize = FLAC__stream_encoder_get_blocksize((FLAC__StreamEncoder*)encoder);
+ const FLAC__uint64 frame_first_sample = encoder->private_->samples_written;
+ const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1;
+ FLAC__uint64 test_sample;
+ unsigned i;
+ for(i = encoder->private_->first_seekpoint_to_check; i < encoder->private_->seek_table->num_points; i++) {
+ test_sample = encoder->private_->seek_table->points[i].sample_number;
+ if(test_sample > frame_last_sample) {
+ break;
+ }
+ else if(test_sample >= frame_first_sample) {
+ encoder->private_->seek_table->points[i].sample_number = frame_first_sample;
+ encoder->private_->seek_table->points[i].stream_offset = output_position - encoder->protected_->audio_offset;
+ encoder->private_->seek_table->points[i].frame_samples = blocksize;
+ encoder->private_->first_seekpoint_to_check++;
+ /* DO NOT: "break;" and here's why:
+ * The seektable template may contain more than one target
+ * sample for any given frame; we will keep looping, generating
+ * duplicate seekpoints for them, and we'll clean it up later,
+ * just before writing the seektable back to the metadata.
+ */
+ }
+ else {
+ encoder->private_->first_seekpoint_to_check++;
+ }
+ }
+ }
- (void)unused;
- FLAC__ASSERT(encoder->private_->FLAC_stream_encoder == unused);
+ status = OggFLAC__ogg_encoder_aspect_write_callback_wrapper(&encoder->protected_->ogg_encoder_aspect, FLAC__stream_encoder_get_total_samples_estimate((FLAC__StreamEncoder*)encoder), buffer, bytes, samples, current_frame, (OggFLAC__OggEncoderAspectWriteCallbackProxy)encoder->private_->write_callback, encoder, encoder->private_->client_data);
- return OggFLAC__ogg_encoder_aspect_write_callback_wrapper(&encoder->protected_->ogg_encoder_aspect, total_samples_estimate, buffer, bytes, samples, current_frame, (OggFLAC__OggEncoderAspectWriteCallbackProxy)encoder->private_->write_callback, encoder, encoder->private_->client_data);
+ if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
+ encoder->private_->samples_written += samples;
+ else
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_CLIENT_ERROR;
+
+ return status;
}
-void metadata_callback_(const FLAC__StreamEncoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
+void metadata_callback_(const FLAC__StreamEncoder *super, const FLAC__StreamMetadata *metadata, void *client_data)
{
- OggFLAC__StreamEncoder *encoder = (OggFLAC__StreamEncoder*)client_data;
+ OggFLAC__StreamEncoder *encoder = (OggFLAC__StreamEncoder*)super;
+ FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
+ const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
+ const unsigned min_framesize = metadata->data.stream_info.min_framesize;
+ const unsigned max_framesize = metadata->data.stream_info.max_framesize;
+ ogg_page page;
+
+ FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
+
+ /* We get called by the stream encoder when the encoding process
+ * has finished so that we can update the STREAMINFO and SEEKTABLE
+ * blocks.
+ */
+
+ (void)client_data; /* silence compiler warning about unused parameter */
+
+ /* All this is based on intimate knowledge of the stream header
+ * layout, but a change to the header format that would break this
+ * would also break all streams encoded in the previous format.
+ */
+
+ /**
+ ** Write STREAMINFO stats
+ **/
+ simple_ogg_page__init(&page);
+ if(!simple_ogg_page__get_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) {
+ simple_ogg_page__clear(&page);
+ return; /* state already set */
+ }
- (void)unused;
- FLAC__ASSERT(encoder->private_->FLAC_stream_encoder == unused);
+ /*
+ * Write MD5 signature
+ */
+ {
+ const unsigned md5_offset =
+ FLAC__STREAM_METADATA_HEADER_LENGTH +
+ (
+ FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
+ FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
+ FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
+ FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
+ FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
+ FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
+ FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN +
+ FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN
+ ) / 8;
+
+ if(md5_offset + 16 > (unsigned)page.body_len) {
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_OGG_ERROR;
+ simple_ogg_page__clear(&page);
+ return;
+ }
+ memcpy(page.body + md5_offset, metadata->data.stream_info.md5sum, 16);
+ }
+
+ /*
+ * Write total samples
+ */
+ {
+ const unsigned total_samples_byte_offset =
+ FLAC__STREAM_METADATA_HEADER_LENGTH +
+ (
+ FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
+ FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
+ FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
+ FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
+ FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
+ FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
+ FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN
+ - 4
+ ) / 8;
+
+ if(total_samples_byte_offset + 5 > (unsigned)page.body_len) {
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_OGG_ERROR;
+ simple_ogg_page__clear(&page);
+ return;
+ }
+ b[0] = (FLAC__byte)page.body[total_samples_byte_offset] & 0xF0;
+ b[0] |= (FLAC__byte)((samples >> 32) & 0x0F);
+ b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
+ b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
+ b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
+ b[4] = (FLAC__byte)(samples & 0xFF);
+ memcpy(page.body + total_samples_byte_offset, b, 5);
+ }
+
+ /*
+ * Write min/max framesize
+ */
+ {
+ const unsigned min_framesize_offset =
+ FLAC__STREAM_METADATA_HEADER_LENGTH +
+ (
+ FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
+ FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN
+ ) / 8;
+
+ if(min_framesize_offset + 6 > (unsigned)page.body_len) {
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_OGG_ERROR;
+ simple_ogg_page__clear(&page);
+ return;
+ }
+ b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
+ b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
+ b[2] = (FLAC__byte)(min_framesize & 0xFF);
+ b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
+ b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
+ b[5] = (FLAC__byte)(max_framesize & 0xFF);
+ memcpy(page.body + min_framesize_offset, b, 6);
+ }
+ if(!simple_ogg_page__set_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) {
+ simple_ogg_page__clear(&page);
+ return; /* state already set */
+ }
+ simple_ogg_page__clear(&page);
+
+ /*
+ * Write seektable
+ */
+ if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) {
+ unsigned i;
+ FLAC__byte *p;
+
+ FLAC__format_seektable_sort(encoder->private_->seek_table);
+
+ FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table));
+
+ simple_ogg_page__init(&page);
+ if(!simple_ogg_page__get_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) {
+ simple_ogg_page__clear(&page);
+ return; /* state already set */
+ }
+
+ if(FLAC__STREAM_METADATA_HEADER_LENGTH + (18*encoder->private_->seek_table->num_points) > (unsigned)page.body_len) {
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_OGG_ERROR;
+ simple_ogg_page__clear(&page);
+ return;
+ }
+
+ for(i = 0, p = page.body + FLAC__STREAM_METADATA_HEADER_LENGTH; i < encoder->private_->seek_table->num_points; i++, p += 18) {
+ FLAC__uint64 xx;
+ unsigned x;
+ xx = encoder->private_->seek_table->points[i].sample_number;
+ b[7] = (FLAC__byte)xx; xx >>= 8;
+ b[6] = (FLAC__byte)xx; xx >>= 8;
+ b[5] = (FLAC__byte)xx; xx >>= 8;
+ b[4] = (FLAC__byte)xx; xx >>= 8;
+ b[3] = (FLAC__byte)xx; xx >>= 8;
+ b[2] = (FLAC__byte)xx; xx >>= 8;
+ b[1] = (FLAC__byte)xx; xx >>= 8;
+ b[0] = (FLAC__byte)xx; xx >>= 8;
+ xx = encoder->private_->seek_table->points[i].stream_offset;
+ b[15] = (FLAC__byte)xx; xx >>= 8;
+ b[14] = (FLAC__byte)xx; xx >>= 8;
+ b[13] = (FLAC__byte)xx; xx >>= 8;
+ b[12] = (FLAC__byte)xx; xx >>= 8;
+ b[11] = (FLAC__byte)xx; xx >>= 8;
+ b[10] = (FLAC__byte)xx; xx >>= 8;
+ b[9] = (FLAC__byte)xx; xx >>= 8;
+ b[8] = (FLAC__byte)xx; xx >>= 8;
+ x = encoder->private_->seek_table->points[i].frame_samples;
+ b[17] = (FLAC__byte)x; x >>= 8;
+ b[16] = (FLAC__byte)x; x >>= 8;
+ if(encoder->private_->write_callback((FLAC__StreamEncoder*)encoder, b, 18, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
+ encoder->protected_->state = OggFLAC__STREAM_ENCODER_CLIENT_ERROR;
+ simple_ogg_page__clear(&page);
+ return;
+ }
+ memcpy(p, b, 18);
+ }
+
+ if(!simple_ogg_page__set_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) {
+ simple_ogg_page__clear(&page);
+ return; /* state already set */
+ }
+ simple_ogg_page__clear(&page);
+ }
+
+ if(encoder->private_->metadata_callback)
+ encoder->private_->metadata_callback((FLAC__StreamEncoder*)encoder, metadata, client_data);
+}
+
+OggFLAC__StreamEncoderReadStatus file_read_callback_(const OggFLAC__StreamEncoder *encoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
+{
+ (void)client_data;
+
+ *bytes = (unsigned)fread(buffer, 1, *bytes, encoder->private_->file);
+ if (*bytes == 0) {
+ if (feof(encoder->private_->file))
+ return OggFLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM;
+ else if (ferror(encoder->private_->file))
+ return OggFLAC__STREAM_ENCODER_READ_STATUS_ABORT;
+ }
+ return OggFLAC__STREAM_ENCODER_READ_STATUS_CONTINUE;
+}
+
+FLAC__StreamEncoderSeekStatus file_seek_callback_(const FLAC__StreamEncoder *super, FLAC__uint64 absolute_byte_offset, void *client_data)
+{
+ OggFLAC__StreamEncoder *encoder = (OggFLAC__StreamEncoder*)super;
+
+ (void)client_data;
+
+ if(fseeko(encoder->private_->file, (off_t)absolute_byte_offset, SEEK_SET) < 0)
+ return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR;
+ else
+ return FLAC__STREAM_ENCODER_SEEK_STATUS_OK;
+}
+
+FLAC__StreamEncoderTellStatus file_tell_callback_(const FLAC__StreamEncoder *super, FLAC__uint64 *absolute_byte_offset, void *client_data)
+{
+ OggFLAC__StreamEncoder *encoder = (OggFLAC__StreamEncoder*)super;
+ off_t offset;
+
+ (void)client_data;
+
+ offset = ftello(encoder->private_->file);
+
+ if(offset < 0) {
+ return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR;
+ }
+ else {
+ *absolute_byte_offset = (FLAC__uint64)offset;
+ return FLAC__STREAM_ENCODER_TELL_STATUS_OK;
+ }
+}
+
+#ifdef FLAC__VALGRIND_TESTING
+static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t ret = fwrite(ptr, size, nmemb, stream);
+ if(!ferror(stream))
+ fflush(stream);
+ return ret;
+}
+#else
+#define local__fwrite fwrite
+#endif
+
+FLAC__StreamEncoderWriteStatus file_write_callback_(const FLAC__StreamEncoder *super, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
+{
+ OggFLAC__StreamEncoder *encoder = (OggFLAC__StreamEncoder*)super;
+
+ (void)client_data;
+
+ if(local__fwrite(buffer, sizeof(FLAC__byte), bytes, encoder->private_->file) == bytes) {
+ encoder->private_->bytes_written += bytes;
+ encoder->private_->samples_written += samples;
+ /* we keep a high watermark on the number of frames written because
+ * when the encoder goes back to write metadata, 'current_frame'
+ * will drop back to 0.
+ */
+ encoder->private_->frames_written = max(encoder->private_->frames_written, current_frame+1);
+ /*@@@ We would like to add an '&& samples > 0' to the if
+ * clause here but currently because of the nature of our Ogg
+ * writing implementation, 'samples' is always 0 (see
+ * ogg_encoder_aspect.c). The downside is extra progress
+ * callbacks.
+ */
+ if(0 != encoder->private_->progress_callback /*@@@ && samples > 0 */)
+ encoder->private_->progress_callback((FLAC__StreamEncoder*)encoder, encoder->private_->bytes_written, encoder->private_->samples_written, encoder->private_->frames_written, encoder->private_->total_frames_estimate, encoder->private_->client_data);
+ return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
+ }
+ else
+ return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
+}
+
+/*
+ * This will forcibly set stdout to binary mode (for OSes that require it)
+ */
+FILE *get_binary_stdout_()
+{
+ /* if something breaks here it is probably due to the presence or
+ * absence of an underscore before the identifiers 'setmode',
+ * 'fileno', and/or 'O_BINARY'; check your system header files.
+ */
+#if defined _MSC_VER || defined __MINGW32__
+ _setmode(_fileno(stdout), _O_BINARY);
+#elif defined __CYGWIN__
+ /* almost certainly not needed for any modern Cygwin, but let's be safe... */
+ setmode(_fileno(stdout), _O_BINARY);
+#elif defined __EMX__
+ setmode(fileno(stdout), O_BINARY);
+#endif
- encoder->private_->metadata_callback(encoder, metadata, encoder->private_->client_data);
+ return stdout;
}