Initial revision
diff --git a/src/libFLAC/Makefile b/src/libFLAC/Makefile
new file mode 100644
index 0000000..f6662a3
--- /dev/null
+++ b/src/libFLAC/Makefile
@@ -0,0 +1,22 @@
+#
+# GNU makefile
+#
+
+LIB_NAME = libFLAC
+INCLUDES = -I./include -I../../include
+DEBUG_CFLAGS = -DFLAC_OVERFLOW_DETECT
+
+OBJS = \
+ bitbuffer.o \
+ crc.o \
+ encoder.o \
+ encoder_framing.o \
+ file_decoder.o \
+ fixed.o \
+ format.o \
+ lpc.o \
+ stream_decoder.o
+
+include ../../build/lib.mk
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/src/libFLAC/Makefile.vc b/src/libFLAC/Makefile.vc
new file mode 100644
index 0000000..5bccf54
--- /dev/null
+++ b/src/libFLAC/Makefile.vc
@@ -0,0 +1,31 @@
+!include <win32.mak>
+
+!IFDEF DEBUG
+.c.obj:
+ $(cc) /D FLAC_OVERFLOW_DETECT /GX $(cdebug) $(cflags) /I "..\..\include" /I ".\include" -DSTRICT -YX /Od /D "_DEBUG" $<
+!else
+.c.obj:
+ $(cc) $(cdebug) $(cflags) /O2 /I "..\..\include" /I ".\include" -DSTRICT -YX -DNODEBUG $<
+!endif
+
+C_FILES= \
+ bitbuffer.c \
+ crc.c \
+ encoder.c \
+ encoder_framing.c \
+ file_decoder.c \
+ fixed.c \
+ format.c \
+ lpc.c \
+ stream_decoder.c
+
+OBJS= $(C_FILES:.c=.obj)
+
+all: libFLAC.lib
+
+libFLAC.lib: $(OBJS)
+ link.exe -lib -out:../../obj/lib/$*.lib $(OBJS)
+
+clean:
+ -del *.obj *.pch
+ -del ..\..\obj\lib\libFLAC.lib ..\..\obj\lib\libFLAC.pdb
diff --git a/src/libFLAC/bitbuffer.c b/src/libFLAC/bitbuffer.c
new file mode 100644
index 0000000..5f618a9
--- /dev/null
+++ b/src/libFLAC/bitbuffer.c
@@ -0,0 +1,962 @@
+/* libFLAC - Free Lossless Audio Coder library
+ * Copyright (C) 2000 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <assert.h>
+#include <stdlib.h> /* for malloc() */
+#include <string.h> /* for memcpy(), memset() */
+#include "private/bitbuffer.h"
+
+static const unsigned FLAC__BITBUFFER_DEFAULT_CAPACITY = 65536; /* bytes */
+
+#ifdef min
+#undef min
+#endif
+#define min(x,y) ((x)<(y)?(x):(y))
+#ifdef max
+#undef max
+#endif
+#define max(x,y) ((x)>(y)?(x):(y))
+
+static bool bitbuffer_resize_(FLAC__BitBuffer *bb, unsigned new_capacity)
+{
+ byte *new_buffer;
+
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+
+ if(bb->capacity == new_capacity)
+ return true;
+
+ new_buffer = (byte*)malloc(sizeof(byte) * new_capacity);
+ if(new_buffer == 0)
+ return false;
+ memset(new_buffer, 0, new_capacity);
+ memcpy(new_buffer, bb->buffer, sizeof(byte)*min(bb->bytes+(bb->bits?1:0), new_capacity));
+ if(new_capacity < bb->bytes+(bb->bits?1:0)) {
+ bb->bytes = new_capacity;
+ bb->bits = 0;
+ bb->total_bits = (new_capacity<<3);
+ }
+ if(new_capacity < bb->consumed_bytes+(bb->consumed_bits?1:0)) {
+ bb->consumed_bytes = new_capacity;
+ bb->consumed_bits = 0;
+ bb->total_consumed_bits = (new_capacity<<3);
+ }
+ bb->buffer = new_buffer;
+ bb->capacity = new_capacity;
+ return true;
+}
+
+static bool bitbuffer_grow_(FLAC__BitBuffer *bb, unsigned min_bytes_to_add)
+{
+ unsigned new_capacity;
+
+ assert(min_bytes_to_add > 0);
+
+ new_capacity = max(bb->capacity * 4, bb->capacity + min_bytes_to_add);
+ return bitbuffer_resize_(bb, new_capacity);
+}
+
+static bool bitbuffer_ensure_size_(FLAC__BitBuffer *bb, unsigned bits_to_add)
+{
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+ if((bb->capacity<<3) < bb->total_bits + bits_to_add)
+ return bitbuffer_grow_(bb, (bits_to_add>>3)+2);
+ else
+ return true;
+}
+
+static bool bitbuffer_read_from_client_(FLAC__BitBuffer *bb, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data)
+{
+ unsigned bytes;
+
+ /* first shift the unconsumed buffer data toward the front as much as possible */
+ if(bb->total_consumed_bits >= 8) {
+ unsigned l = 0, r = bb->consumed_bytes, r_end = bb->bytes;
+ for( ; r < r_end; l++, r++)
+ bb->buffer[l] = bb->buffer[r];
+ for( ; l < r_end; l++)
+ bb->buffer[l] = 0;
+ bb->bytes -= bb->consumed_bytes;
+ bb->total_bits -= (bb->consumed_bytes<<3);
+ bb->consumed_bytes = 0;
+ bb->total_consumed_bits = bb->consumed_bits;
+ }
+ /* grow if we need to */
+ if(bb->capacity <= 1) {
+ if(!bitbuffer_resize_(bb, 16))
+ return false;
+ }
+ /* finally, read in some data; if OK, go back to read_bit_, else fail */
+ bytes = bb->capacity - bb->bytes;
+ if(!read_callback(bb->buffer+bb->bytes, &bytes, client_data))
+ return false;
+ bb->bytes += bytes;
+ bb->total_bits += (bytes<<3);
+ return true;
+}
+
+void FLAC__bitbuffer_init(FLAC__BitBuffer *bb)
+{
+ assert(bb != 0);
+ bb->buffer = 0;
+ bb->capacity = 0;
+ bb->bytes = bb->bits = bb->total_bits = 0;
+ bb->consumed_bytes = bb->consumed_bits = bb->total_consumed_bits = 0;
+}
+
+bool FLAC__bitbuffer_init_from(FLAC__BitBuffer *bb, const byte buffer[], unsigned bytes)
+{
+ assert(bb != 0);
+ FLAC__bitbuffer_init(bb);
+ if(bytes == 0)
+ return true;
+ else {
+ assert(buffer != 0);
+ bb->buffer = (byte*)malloc(sizeof(byte)*bytes);
+ if(bb->buffer == 0)
+ return false;
+ memcpy(bb->buffer, buffer, sizeof(byte)*bytes);
+ bb->capacity = bb->bytes = bytes;
+ bb->bits = 0;
+ bb->total_bits = (bytes<<3);
+ bb->consumed_bytes = bb->consumed_bits = bb->total_consumed_bits = 0;
+ return true;
+ }
+}
+
+bool FLAC__bitbuffer_concatenate_aligned(FLAC__BitBuffer *dest, const FLAC__BitBuffer *src)
+{
+ static byte mask_[9] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
+ unsigned bits_to_add = src->total_bits - src->total_consumed_bits;
+ assert(dest != 0);
+ assert(src != 0);
+
+ if(bits_to_add == 0)
+ return true;
+ if(dest->bits != src->consumed_bits)
+ return false;
+ if(!bitbuffer_ensure_size_(dest, bits_to_add))
+ return false;
+ if(dest->bits == 0) {
+ memcpy(dest->buffer+dest->bytes, src->buffer+src->consumed_bytes, src->bytes-src->consumed_bytes + ((src->bits)? 1:0));
+ }
+ else if(dest->bits + bits_to_add > 8) {
+ dest->buffer[dest->bytes] <<= (8 - dest->bits);
+ dest->buffer[dest->bytes] |= (src->buffer[src->consumed_bytes] & mask_[8-dest->bits]);
+ memcpy(dest->buffer+dest->bytes+1, src->buffer+src->consumed_bytes+1, src->bytes-src->consumed_bytes-1 + ((src->bits)? 1:0));
+ }
+ else {
+ dest->buffer[dest->bytes] <<= bits_to_add;
+ dest->buffer[dest->bytes] |= (src->buffer[src->consumed_bytes] & mask_[bits_to_add]);
+ }
+ dest->bits = src->bits;
+ dest->total_bits += bits_to_add;
+ dest->bytes = dest->total_bits / 8;
+
+ return true;
+}
+
+void FLAC__bitbuffer_free(FLAC__BitBuffer *bb)
+{
+ assert(bb != 0);
+ if(bb->buffer != 0)
+ free(bb->buffer);
+ bb->buffer = 0;
+ bb->capacity = 0;
+ bb->bytes = bb->bits = bb->total_bits = 0;
+ bb->consumed_bytes = bb->consumed_bits = bb->total_consumed_bits = 0;
+}
+
+bool FLAC__bitbuffer_clear(FLAC__BitBuffer *bb)
+{
+ if(bb->buffer == 0) {
+ bb->capacity = FLAC__BITBUFFER_DEFAULT_CAPACITY;
+ bb->buffer = (byte*)malloc(sizeof(byte) * bb->capacity);
+ if(bb->buffer == 0)
+ return false;
+ memset(bb->buffer, 0, bb->capacity);
+ }
+ else {
+ memset(bb->buffer, 0, bb->bytes + (bb->bits?1:0));
+ }
+ bb->bytes = bb->bits = bb->total_bits = 0;
+ bb->consumed_bytes = bb->consumed_bits = bb->total_consumed_bits = 0;
+ return true;
+}
+
+bool FLAC__bitbuffer_clone(FLAC__BitBuffer *dest, const FLAC__BitBuffer *src)
+{
+ if(dest->capacity < src->capacity)
+ if(!bitbuffer_resize_(dest, src->capacity))
+ return false;
+ memcpy(dest->buffer, src->buffer, sizeof(byte)*min(src->capacity, src->bytes+1));
+ dest->bytes = src->bytes;
+ dest->bits = src->bits;
+ dest->total_bits = src->total_bits;
+ dest->consumed_bytes = src->consumed_bytes;
+ dest->consumed_bits = src->consumed_bits;
+ dest->total_consumed_bits = src->total_consumed_bits;
+ return true;
+}
+
+bool FLAC__bitbuffer_write_zeroes(FLAC__BitBuffer *bb, unsigned bits)
+{
+ unsigned n, k;
+
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+
+ if(bits == 0)
+ return true;
+ if(!bitbuffer_ensure_size_(bb, bits))
+ return false;
+ bb->total_bits += bits;
+ while(bits > 0) {
+ n = min(8 - bb->bits, bits);
+ k = bits - n;
+ bb->buffer[bb->bytes] <<= n;
+ bits -= n;
+ bb->bits += n;
+ if(bb->bits == 8) {
+ bb->bytes++;
+ bb->bits = 0;
+ }
+ }
+ return true;
+}
+
+bool FLAC__bitbuffer_write_raw_uint32(FLAC__BitBuffer *bb, uint32 val, unsigned bits)
+{
+ static uint32 mask[] = {
+ 0,
+ 0x00000001, 0x00000003, 0x00000007, 0x0000000F,
+ 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
+ 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
+ 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
+ 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
+ 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
+ 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
+ 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
+ };
+ unsigned n, k;
+
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+
+ assert(bits <= 32);
+ if(bits == 0)
+ return true;
+ if(!bitbuffer_ensure_size_(bb, bits))
+ return false;
+ val &= mask[bits];
+ bb->total_bits += bits;
+ while(bits > 0) {
+ n = 8 - bb->bits;
+ if(n == 8) { /* i.e. bb->bits == 0 */
+ if(bits < 8) {
+ bb->buffer[bb->bytes] = val;
+ bb->bits = bits;
+ break;
+ }
+ else if(bits == 8) {
+ bb->buffer[bb->bytes++] = val;
+ break;
+ }
+ else {
+ k = bits - 8;
+ bb->buffer[bb->bytes++] = val >> k;
+ val &= (~(0xffffffff << k));
+ bits -= 8;
+ }
+ }
+ else if(bits <= n) {
+ bb->buffer[bb->bytes] <<= bits;
+ bb->buffer[bb->bytes] |= val;
+ if(bits == n) {
+ bb->bytes++;
+ bb->bits = 0;
+ }
+ else
+ bb->bits += bits;
+ break;
+ }
+ else {
+ k = bits - n;
+ bb->buffer[bb->bytes] <<= n;
+ bb->buffer[bb->bytes] |= (val>>k);
+ val &= (~(0xffffffff << k));
+ bits -= n;
+ bb->bytes++;
+ bb->bits = 0;
+ }
+ }
+
+ return true;
+}
+
+bool FLAC__bitbuffer_write_raw_int32(FLAC__BitBuffer *bb, int32 val, unsigned bits)
+{
+ return FLAC__bitbuffer_write_raw_uint32(bb, (uint32)val, bits);
+}
+
+bool FLAC__bitbuffer_write_raw_uint64(FLAC__BitBuffer *bb, uint64 val, unsigned bits)
+{
+ static uint64 mask[] = {
+ 0,
+ 0x0000000000000001, 0x0000000000000003, 0x0000000000000007, 0x000000000000000F,
+ 0x000000000000001F, 0x000000000000003F, 0x000000000000007F, 0x00000000000000FF,
+ 0x00000000000001FF, 0x00000000000003FF, 0x00000000000007FF, 0x0000000000000FFF,
+ 0x0000000000001FFF, 0x0000000000003FFF, 0x0000000000007FFF, 0x000000000000FFFF,
+ 0x000000000001FFFF, 0x000000000003FFFF, 0x000000000007FFFF, 0x00000000000FFFFF,
+ 0x00000000001FFFFF, 0x00000000003FFFFF, 0x00000000007FFFFF, 0x0000000000FFFFFF,
+ 0x0000000001FFFFFF, 0x0000000003FFFFFF, 0x0000000007FFFFFF, 0x000000000FFFFFFF,
+ 0x000000001FFFFFFF, 0x000000003FFFFFFF, 0x000000007FFFFFFF, 0x00000000FFFFFFFF,
+ 0x00000001FFFFFFFF, 0x00000003FFFFFFFF, 0x00000007FFFFFFFF, 0x0000000FFFFFFFFF,
+ 0x0000001FFFFFFFFF, 0x0000003FFFFFFFFF, 0x0000007FFFFFFFFF, 0x000000FFFFFFFFFF,
+ 0x000001FFFFFFFFFF, 0x000003FFFFFFFFFF, 0x000007FFFFFFFFFF, 0x00000FFFFFFFFFFF,
+ 0x00001FFFFFFFFFFF, 0x00003FFFFFFFFFFF, 0x00007FFFFFFFFFFF, 0x0000FFFFFFFFFFFF,
+ 0x0001FFFFFFFFFFFF, 0x0003FFFFFFFFFFFF, 0x0007FFFFFFFFFFFF, 0x000FFFFFFFFFFFFF,
+ 0x001FFFFFFFFFFFFF, 0x003FFFFFFFFFFFFF, 0x007FFFFFFFFFFFFF, 0x00FFFFFFFFFFFFFF,
+ 0x01FFFFFFFFFFFFFF, 0x03FFFFFFFFFFFFFF, 0x07FFFFFFFFFFFFFF, 0x0FFFFFFFFFFFFFFF,
+ 0x1FFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF
+ };
+ unsigned n, k;
+
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+
+ assert(bits <= 64);
+ if(bits == 0)
+ return true;
+ if(!bitbuffer_ensure_size_(bb, bits))
+ return false;
+ val &= mask[bits];
+ bb->total_bits += bits;
+ while(bits > 0) {
+ if(bb->bits == 0) {
+ if(bits < 8) {
+ bb->buffer[bb->bytes] = val;
+ bb->bits = bits;
+ break;
+ }
+ else if(bits == 8) {
+ bb->buffer[bb->bytes++] = val;
+ break;
+ }
+ else {
+ k = bits - 8;
+ bb->buffer[bb->bytes++] = val >> k;
+ val &= (~(0xffffffffffffffff << k));
+ bits -= 8;
+ }
+ }
+ else {
+ n = min(8 - bb->bits, bits);
+ k = bits - n;
+ bb->buffer[bb->bytes] <<= n;
+ bb->buffer[bb->bytes] |= (val>>k);
+ val &= (~(0xffffffffffffffff << k));
+ bits -= n;
+ bb->bits += n;
+ if(bb->bits == 8) {
+ bb->bytes++;
+ bb->bits = 0;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool FLAC__bitbuffer_write_raw_int64(FLAC__BitBuffer *bb, int64 val, unsigned bits)
+{
+ return FLAC__bitbuffer_write_raw_uint64(bb, (uint64)val, bits);
+}
+
+bool FLAC__bitbuffer_write_rice_signed(FLAC__BitBuffer *bb, int val, unsigned parameter)
+{
+ unsigned bits, msbs;
+ uint32 pattern;
+
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+
+ /* init pattern with sign bit */
+ if(val < 0) {
+ pattern = 1;
+ val = -val;
+ }
+ else
+ pattern = 0;
+
+ msbs = val >> parameter;
+ bits = 2 + parameter + msbs;
+
+ if(bits <= 32) {
+ pattern = (pattern << parameter) | (val & ((1<<parameter)-1));
+ pattern = (pattern << (msbs+1)) | 1;
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, bits))
+ return false;
+ }
+ else {
+ /* write the sign bit */
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, 1))
+ return false;
+ /* write the binary LSBs */
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, val & ((1<<parameter)-1), parameter))
+ return false;
+ /* write the unary MSBs */
+ if(!FLAC__bitbuffer_write_zeroes(bb, msbs))
+ return false;
+ /* write the end bit */
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, 1, 1))
+ return false;
+ }
+ return true;
+}
+
+bool FLAC__bitbuffer_write_rice_signed_guarded(FLAC__BitBuffer *bb, int val, unsigned parameter, unsigned max_bits, bool *overflow)
+{
+ unsigned bits, msbs;
+ uint32 pattern;
+
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+
+ *overflow = false;
+
+ /* init pattern with sign bit */
+ if(val < 0) {
+ pattern = 1;
+ val = -val;
+ }
+ else
+ pattern = 0;
+
+ msbs = val >> parameter;
+ bits = 2 + parameter + msbs;
+
+ if(bits <= 32) {
+ pattern = (pattern << parameter) | (val & ((1<<parameter)-1));
+ pattern = (pattern << (msbs+1)) | 1;
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, bits))
+ return false;
+ }
+ else if(bits > max_bits) {
+ *overflow = true;
+ return true;
+ }
+ else {
+ /* write the sign bit */
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, 1))
+ return false;
+ /* write the binary LSBs */
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, val & ((1<<parameter)-1), parameter))
+ return false;
+ /* write the unary MSBs */
+ if(!FLAC__bitbuffer_write_zeroes(bb, msbs))
+ return false;
+ /* write the end bit */
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, 1, 1))
+ return false;
+ }
+ return true;
+}
+
+bool FLAC__bitbuffer_write_utf8_uint32(FLAC__BitBuffer *bb, uint32 val)
+{
+ bool ok = 1;
+
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+
+ assert(!(val & 0x80000000)); /* this version only handles 31 bits */
+
+ if(val < 0x80) {
+ return FLAC__bitbuffer_write_raw_uint32(bb, val, 8);
+ }
+ else if(val < 0x800) {
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xC0 | (val>>6), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (val&0x3F), 8);
+ }
+ else if(val < 0x10000) {
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xE0 | (val>>12), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>6)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (val&0x3F), 8);
+ }
+ else if(val < 0x200000) {
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xF0 | (val>>18), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>12)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>6)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (val&0x3F), 8);
+ }
+ else if(val < 0x4000000) {
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xF8 | (val>>24), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>18)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>12)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>6)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (val&0x3F), 8);
+ }
+ else {
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xFC | (val>>30), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>24)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>18)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>12)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>6)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (val&0x3F), 8);
+ }
+
+ return ok;
+}
+
+bool FLAC__bitbuffer_write_utf8_uint64(FLAC__BitBuffer *bb, uint64 val)
+{
+ bool ok = 1;
+
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+
+ assert(!(val & 0xFFFFFFF000000000)); /* this version only handles 36 bits */
+
+ if(val < 0x80) {
+ return FLAC__bitbuffer_write_raw_uint32(bb, (uint32)val, 8);
+ }
+ else if(val < 0x800) {
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xC0 | (uint32)(val>>6), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)(val&0x3F), 8);
+ }
+ else if(val < 0x10000) {
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xE0 | (uint32)(val>>12), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>6)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)(val&0x3F), 8);
+ }
+ else if(val < 0x200000) {
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xF0 | (uint32)(val>>18), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>12)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>6)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)(val&0x3F), 8);
+ }
+ else if(val < 0x4000000) {
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xF8 | (uint32)(val>>24), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>18)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>12)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>6)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)(val&0x3F), 8);
+ }
+ else if(val < 0x80000000) {
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xFC | (uint32)(val>>30), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>24)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>18)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>12)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>6)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)(val&0x3F), 8);
+ }
+ else {
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xFE, 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>30)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>24)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>18)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>12)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>6)&0x3F), 8);
+ ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)(val&0x3F), 8);
+ }
+
+ return ok;
+}
+
+bool FLAC__bitbuffer_zero_pad_to_byte_boundary(FLAC__BitBuffer *bb)
+{
+ /* 0-pad to byte boundary */
+ if(bb->bits != 0)
+ return FLAC__bitbuffer_write_zeroes(bb, 8 - bb->bits);
+ else
+ return true;
+}
+
+bool FLAC__bitbuffer_peek_bit(FLAC__BitBuffer *bb, unsigned *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data)
+{
+ static byte mask[] = { 128, 64, 32, 16, 8, 4, 2, 1 };
+
+ /* to avoid a drastic speed penalty we don't:
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+ assert(bb->bits == 0);
+ */
+
+read_bit_:
+ if(bb->total_consumed_bits < bb->total_bits) {
+ *val = (bb->buffer[bb->consumed_bytes] & mask[bb->consumed_bits])? 1 : 0;
+ return true;
+ }
+ else {
+ if(!bitbuffer_read_from_client_(bb, read_callback, client_data))
+ return false;
+ goto read_bit_;
+ }
+}
+
+bool FLAC__bitbuffer_read_bit(FLAC__BitBuffer *bb, unsigned *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data)
+{
+ static byte mask[] = { 128, 64, 32, 16, 8, 4, 2, 1 };
+
+ /* to avoid a drastic speed penalty we don't:
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+ assert(bb->bits == 0);
+ */
+
+read_bit_:
+ if(bb->total_consumed_bits < bb->total_bits) {
+ *val = (bb->buffer[bb->consumed_bytes] & mask[bb->consumed_bits])? 1 : 0;
+ bb->consumed_bits++;
+ if(bb->consumed_bits == 8) {
+ bb->consumed_bytes++;
+ bb->consumed_bits = 0;
+ }
+ bb->total_consumed_bits++;
+ return true;
+ }
+ else {
+ if(!bitbuffer_read_from_client_(bb, read_callback, client_data))
+ return false;
+ goto read_bit_;
+ }
+}
+
+bool FLAC__bitbuffer_read_bit_to_uint32(FLAC__BitBuffer *bb, uint32 *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data)
+{
+ static byte mask[] = { 128, 64, 32, 16, 8, 4, 2, 1 };
+
+ /* to avoid a drastic speed penalty we don't:
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+ assert(bb->bits == 0);
+ */
+
+read_bit_:
+ if(bb->total_consumed_bits < bb->total_bits) {
+ *val <<= 1;
+ *val |= (bb->buffer[bb->consumed_bytes] & mask[bb->consumed_bits])? 1 : 0;
+ bb->consumed_bits++;
+ if(bb->consumed_bits == 8) {
+ bb->consumed_bytes++;
+ bb->consumed_bits = 0;
+ }
+ bb->total_consumed_bits++;
+ return true;
+ }
+ else {
+ if(!bitbuffer_read_from_client_(bb, read_callback, client_data))
+ return false;
+ goto read_bit_;
+ }
+}
+
+bool FLAC__bitbuffer_read_bit_to_uint64(FLAC__BitBuffer *bb, uint64 *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data)
+{
+ static byte mask[] = { 128, 64, 32, 16, 8, 4, 2, 1 };
+
+ /* to avoid a drastic speed penalty we don't:
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+ assert(bb->bits == 0);
+ */
+
+read_bit_:
+ if(bb->total_consumed_bits < bb->total_bits) {
+ *val <<= 1;
+ *val |= (bb->buffer[bb->consumed_bytes] & mask[bb->consumed_bits])? 1 : 0;
+ bb->consumed_bits++;
+ if(bb->consumed_bits == 8) {
+ bb->consumed_bytes++;
+ bb->consumed_bits = 0;
+ }
+ bb->total_consumed_bits++;
+ return true;
+ }
+ else {
+ if(!bitbuffer_read_from_client_(bb, read_callback, client_data))
+ return false;
+ goto read_bit_;
+ }
+}
+
+bool FLAC__bitbuffer_read_raw_uint32(FLAC__BitBuffer *bb, uint32 *val, unsigned bits, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data)
+{
+ unsigned i;
+
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+
+ assert(bits <= 32);
+
+ *val = 0;
+ for(i = 0; i < bits; i++) {
+ if(!FLAC__bitbuffer_read_bit_to_uint32(bb, val, read_callback, client_data))
+ return false;
+ }
+ return true;
+}
+
+bool FLAC__bitbuffer_read_raw_int32(FLAC__BitBuffer *bb, int32 *val, unsigned bits, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data)
+{
+ unsigned i;
+ uint32 x;
+
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+
+ assert(bits <= 32);
+
+ x = 0;
+ for(i = 0; i < bits; i++) {
+ if(!FLAC__bitbuffer_read_bit_to_uint32(bb, &x, read_callback, client_data))
+ return false;
+ }
+ /* fix the sign */
+ i = 32 - bits;
+ if(i) {
+ x <<= i;
+ *val = (int32)x;
+ *val >>= i;
+ }
+ else
+ *val = (int32)x;
+
+ return true;
+}
+
+bool FLAC__bitbuffer_read_raw_uint64(FLAC__BitBuffer *bb, uint64 *val, unsigned bits, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data)
+{
+ unsigned i;
+
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+
+ assert(bits <= 64);
+
+ *val = 0;
+ for(i = 0; i < bits; i++) {
+ if(!FLAC__bitbuffer_read_bit_to_uint64(bb, val, read_callback, client_data))
+ return false;
+ }
+ return true;
+}
+
+bool FLAC__bitbuffer_read_raw_int64(FLAC__BitBuffer *bb, int64 *val, unsigned bits, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data)
+{
+ unsigned i;
+ uint64 x;
+
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+
+ assert(bits <= 64);
+
+ x = 0;
+ for(i = 0; i < bits; i++) {
+ if(!FLAC__bitbuffer_read_bit_to_uint64(bb, &x, read_callback, client_data))
+ return false;
+ }
+ /* fix the sign */
+ i = 64 - bits;
+ if(i) {
+ x <<= i;
+ *val = (int64)x;
+ *val >>= i;
+ }
+ else
+ *val = (int64)x;
+
+ return true;
+}
+
+bool FLAC__bitbuffer_read_rice_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data)
+{
+ uint32 sign = 0, lsbs, msbs = 0;
+ unsigned bit;
+
+ assert(bb != 0);
+ assert(bb->buffer != 0);
+
+ /* read the sign bit */
+ if(!FLAC__bitbuffer_read_bit_to_uint32(bb, &sign, read_callback, client_data))
+ return false;
+ /* read the binary LSBs */
+ if(!FLAC__bitbuffer_read_raw_uint32(bb, &lsbs, parameter, read_callback, client_data))
+ return false;
+ /* read the unary MSBs and end bit */
+ while(1) {
+ if(!FLAC__bitbuffer_read_bit(bb, &bit, read_callback, client_data))
+ return false;
+ if(bit)
+ break;
+ else
+ msbs++;
+ }
+ /* compose the value */
+ *val = (msbs << parameter) | lsbs;
+ if(sign)
+ *val = -(*val);
+
+ return true;
+}
+
+/* on return, if *val == 0xffffffff then the utf-8 sequence was invalid, but the return value will be true */
+bool FLAC__bitbuffer_read_utf8_uint32(FLAC__BitBuffer *bb, uint32 *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data, byte *raw, unsigned *rawlen)
+{
+ uint32 v = 0;
+ uint32 x;
+ unsigned i;
+
+ if(!FLAC__bitbuffer_read_raw_uint32(bb, &x, 8, read_callback, client_data))
+ return false;
+ if(raw)
+ raw[(*rawlen)++] = (byte)x;
+ if(!(x & 0x80)) { /* 0xxxxxxx */
+ v = x;
+ i = 0;
+ }
+ else if(x & 0xC0 && !(x & 0x20)) { /* 110xxxxx */
+ v = x & 0x1F;
+ i = 1;
+ }
+ else if(x & 0xE0 && !(x & 0x10)) { /* 1110xxxx */
+ v = x & 0x0F;
+ i = 2;
+ }
+ else if(x & 0xF0 && !(x & 0x08)) { /* 11110xxx */
+ v = x & 0x07;
+ i = 3;
+ }
+ else if(x & 0xF8 && !(x & 0x04)) { /* 111110xx */
+ v = x & 0x03;
+ i = 4;
+ }
+ else if(x & 0xFC && !(x & 0x02)) { /* 1111110x */
+ v = x & 0x01;
+ i = 5;
+ }
+ else
+ goto invalid_;
+ for( ; i; i--) {
+ if(!FLAC__bitbuffer_read_raw_uint32(bb, &x, 8, read_callback, client_data))
+ return false;
+ if(raw)
+ raw[(*rawlen)++] = (byte)x;
+ if(!(x & 0x80) || (x & 0x40)) /* 10xxxxxx */
+ goto invalid_;
+ v <<= 6;
+ v |= (x & 0x3F);
+ }
+ *val = v;
+ return true;
+invalid_:
+ *val = 0xffffffff;
+ return true;
+}
+
+/* on return, if *val == 0xffffffffffffffff then the utf-8 sequence was invalid, but the return value will be true */
+bool FLAC__bitbuffer_read_utf8_uint64(FLAC__BitBuffer *bb, uint64 *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data, byte *raw, unsigned *rawlen)
+{
+ uint64 v = 0;
+ uint32 x;
+ unsigned i;
+
+ if(!FLAC__bitbuffer_read_raw_uint32(bb, &x, 8, read_callback, client_data))
+ return false;
+ if(raw)
+ raw[(*rawlen)++] = (byte)x;
+ if(!(x & 0x80)) { /* 0xxxxxxx */
+ v = x;
+ i = 0;
+ }
+ else if(x & 0xC0 && !(x & 0x20)) { /* 110xxxxx */
+ v = x & 0x1F;
+ i = 1;
+ }
+ else if(x & 0xE0 && !(x & 0x10)) { /* 1110xxxx */
+ v = x & 0x0F;
+ i = 2;
+ }
+ else if(x & 0xF0 && !(x & 0x08)) { /* 11110xxx */
+ v = x & 0x07;
+ i = 3;
+ }
+ else if(x & 0xF8 && !(x & 0x04)) { /* 111110xx */
+ v = x & 0x03;
+ i = 4;
+ }
+ else if(x & 0xFC && !(x & 0x02)) { /* 1111110x */
+ v = x & 0x01;
+ i = 5;
+ }
+ else if(x & 0xFE && !(x & 0x01)) { /* 11111110 */
+ v = 0;
+ i = 6;
+ }
+ else
+ goto invalid_;
+ for( ; i; i--) {
+ if(!FLAC__bitbuffer_read_raw_uint32(bb, &x, 8, read_callback, client_data))
+ return false;
+ if(raw)
+ raw[(*rawlen)++] = (byte)x;
+ if(!(x & 0x80) || (x & 0x40)) /* 10xxxxxx */
+ goto invalid_;
+ v <<= 6;
+ v |= (x & 0x3F);
+ }
+ *val = v;
+ return true;
+invalid_:
+ *val = 0xffffffff;
+ return true;
+}
+
+void FLAC__bitbuffer_dump(const FLAC__BitBuffer *bb, FILE *out)
+{
+ unsigned i, j;
+ if(bb == 0) {
+ fprintf(out, "bitbuffer is NULL\n");
+ }
+ else {
+ fprintf(out, "bitbuffer: capacity=%u bytes=%u bits=%u total_bits=%u consumed: bytes=%u, bits=%u, total_bits=%u\n", bb->capacity, bb->bytes, bb->bits, bb->total_bits, bb->consumed_bytes, bb->consumed_bits, bb->total_consumed_bits);
+ for(i = 0; i < bb->bytes; i++) {
+ fprintf(out, "%08X: ", i);
+ for(j = 0; j < 8; j++)
+ if(i*8+j < bb->total_consumed_bits)
+ fprintf(out, ".");
+ else
+ fprintf(out, "%01u", bb->buffer[i] & (1 << (8-j-1)) ? 1:0);
+ fprintf(out, "\n");
+ }
+ if(bb->bits > 0) {
+ fprintf(out, "%08X: ", i);
+ for(j = 0; j < bb->bits; j++)
+ if(i*8+j < bb->total_consumed_bits)
+ fprintf(out, ".");
+ else
+ fprintf(out, "%01u", bb->buffer[i] & (1 << (bb->bits-j-1)) ? 1:0);
+ fprintf(out, "\n");
+ }
+ }
+}
diff --git a/src/libFLAC/crc.c b/src/libFLAC/crc.c
new file mode 100644
index 0000000..7f6cbd2
--- /dev/null
+++ b/src/libFLAC/crc.c
@@ -0,0 +1,65 @@
+/* libFLAC - Free Lossless Audio Coder library
+ * Copyright (C) 2000 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "private/crc.h"
+
+byte FLAC__crc8(const byte *data, const unsigned len)
+{
+ static byte const crc8_table_[256] = {
+ 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
+ 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
+ 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
+ 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
+ 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
+ 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
+ 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
+ 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
+ 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
+ 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
+ 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
+ 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
+ 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
+ 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
+ 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
+ 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
+ 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
+ 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
+ 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
+ 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
+ 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
+ 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
+ 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
+ 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
+ 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
+ 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
+ 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
+ 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
+ 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
+ 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
+ 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
+ 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
+ };
+ unsigned i;
+ byte crc = 0;
+
+ for(i = 0; i < len; i++)
+ crc = crc8_table_[crc ^ *data++];
+
+ return crc;
+}
diff --git a/src/libFLAC/encoder.c b/src/libFLAC/encoder.c
new file mode 100644
index 0000000..2a6fffa
--- /dev/null
+++ b/src/libFLAC/encoder.c
@@ -0,0 +1,900 @@
+/* libFLAC - Free Lossless Audio Coder library
+ * Copyright (C) 2000 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h> /* for malloc() */
+#include <string.h> /* for memcpy() */
+#include "FLAC/encoder.h"
+#include "private/bitbuffer.h"
+#include "private/encoder_framing.h"
+#include "private/fixed.h"
+#include "private/lpc.h"
+
+#ifdef min
+#undef min
+#endif
+#define min(x,y) ((x)<(y)?(x):(y))
+
+#ifdef max
+#undef max
+#endif
+#define max(x,y) ((x)>(y)?(x):(y))
+
+#ifdef RICE_BITS
+#undef RICE_BITS
+#endif
+#define RICE_BITS(value, parameter) (2 + (parameter) + (((unsigned)((value) < 0? -(value) : (value))) >> (parameter)))
+
+typedef struct FLAC__EncoderPrivate {
+ unsigned input_capacity; /* current size (in samples) of the signal and residual buffers */
+ int32 *integer_signal[FLAC__MAX_CHANNELS]; /* the integer version of the input signal */
+ int32 *integer_signal_mid_side[2]; /* the integer version of the mid-side input signal (stereo only) */
+ real *real_signal[FLAC__MAX_CHANNELS]; /* the floating-point version of the input signal */
+ real *real_signal_mid_side[2]; /* the floating-point version of the mid-side input signal (stereo only) */
+ int32 *residual[2]; /* where the candidate and best subframe residual signals will be stored */
+ unsigned best_residual; /* index into the above */
+ FLAC__BitBuffer frame; /* the current frame being worked on */
+ FLAC__BitBuffer frame_mid_side; /* special parallel workspace for the mid-side coded version of the current frame */
+ FLAC__BitBuffer frame_left_side; /* special parallel workspace for the left-side coded version of the current frame */
+ FLAC__BitBuffer frame_right_side; /* special parallel workspace for the right-side coded version of the current frame */
+ FLAC__SubframeHeader best_subframe, candidate_subframe;
+ bool current_frame_can_do_mid_side; /* encoder sets this false when any given sample of a frame's side channel exceeds 16 bits */
+ FLAC__StreamMetaData metadata;
+ unsigned current_sample_number;
+ unsigned current_frame_number;
+ FLAC__EncoderWriteStatus (*write_callback)(const FLAC__Encoder *encoder, const byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
+ void (*metadata_callback)(const FLAC__Encoder *encoder, const FLAC__StreamMetaData *metadata, void *client_data);
+ void *client_data;
+} FLAC__EncoderPrivate;
+
+static bool encoder_resize_buffers_(FLAC__Encoder *encoder, unsigned new_size);
+static bool encoder_process_frame_(FLAC__Encoder *encoder, bool is_last_frame);
+static bool encoder_process_subframes_(FLAC__Encoder *encoder, bool is_last_frame, const FLAC__FrameHeader *frame_header, unsigned channels, const int32 *integer_signal[], const real *real_signal[], FLAC__BitBuffer *bitbuffer);
+static unsigned encoder_evaluate_constant_subframe_(const int32 signal, unsigned bits_per_sample, FLAC__SubframeHeader *subframe);
+static unsigned encoder_evaluate_fixed_subframe_(const int32 signal[], int32 residual[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned rice_parameter, unsigned max_partition_order, FLAC__SubframeHeader *subframe);
+static unsigned encoder_evaluate_lpc_subframe_(const int32 signal[], int32 residual[], const real lp_coeff[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, unsigned max_partition_order, FLAC__SubframeHeader *subframe);
+static unsigned encoder_evaluate_verbatim_subframe_(unsigned blocksize, unsigned bits_per_sample, FLAC__SubframeHeader *subframe);
+static unsigned encoder_find_best_partition_order_(int32 residual[], unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, unsigned max_partition_order, unsigned *best_partition_order, unsigned best_parameters[]);
+static bool encoder_generate_constant_subframe_(const FLAC__SubframeHeader *header, unsigned bits_per_sample, FLAC__BitBuffer *bitbuffer);
+static bool encoder_generate_fixed_subframe_(const FLAC__SubframeHeader *header, int32 residual[], unsigned blocksize, unsigned bits_per_sample, FLAC__BitBuffer *bitbuffer);
+static bool encoder_generate_lpc_subframe_(const FLAC__SubframeHeader *header, int32 residual[], unsigned blocksize, unsigned bits_per_sample, FLAC__BitBuffer *bitbuffer);
+static bool encoder_generate_verbatim_subframe_(const FLAC__SubframeHeader *header, const int32 signal[], unsigned blocksize, unsigned bits_per_sample, FLAC__BitBuffer *bitbuffer);
+static void encoder_promote_candidate_subframe_(FLAC__Encoder *encoder);
+static bool encoder_set_partitioned_rice_(const int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameter, const unsigned partition_order, unsigned parameters[], unsigned *bits);
+
+
+bool encoder_resize_buffers_(FLAC__Encoder *encoder, unsigned new_size)
+{
+ bool ok;
+ unsigned i;
+ int32 *previous_is, *current_is;
+ real *previous_rs, *current_rs;
+ int32 *residual;
+
+ assert(new_size > 0);
+ assert(encoder->state == FLAC__ENCODER_OK);
+ assert(encoder->guts->current_sample_number == 0);
+
+ /* To avoid excessive malloc'ing, we only grow the buffer; no shrinking. */
+ if(new_size <= encoder->guts->input_capacity)
+ return true;
+
+ ok = 1;
+ if(ok) {
+ for(i = 0; ok && i < encoder->channels; i++) {
+ /* integer version of the signal */
+ previous_is = encoder->guts->integer_signal[i];
+ current_is = (int32*)malloc(sizeof(int32) * new_size);
+ if(0 == current_is) {
+ encoder->state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR;
+ ok = 0;
+ }
+ else {
+ encoder->guts->integer_signal[i] = current_is;
+ if(previous_is != 0)
+ free(previous_is);
+ }
+ /* real version of the signal */
+ previous_rs = encoder->guts->real_signal[i];
+ current_rs = (real*)malloc(sizeof(real) * new_size);
+ if(0 == current_rs) {
+ encoder->state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR;
+ ok = 0;
+ }
+ else {
+ encoder->guts->real_signal[i] = current_rs;
+ if(previous_rs != 0)
+ free(previous_rs);
+ }
+ }
+ }
+ if(ok) {
+ for(i = 0; ok && i < 2; i++) {
+ /* integer version of the signal */
+ previous_is = encoder->guts->integer_signal_mid_side[i];
+ current_is = (int32*)malloc(sizeof(int32) * new_size);
+ if(0 == current_is) {
+ encoder->state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR;
+ ok = 0;
+ }
+ else {
+ encoder->guts->integer_signal_mid_side[i] = current_is;
+ if(previous_is != 0)
+ free(previous_is);
+ }
+ /* real version of the signal */
+ previous_rs = encoder->guts->real_signal_mid_side[i];
+ current_rs = (real*)malloc(sizeof(real) * new_size);
+ if(0 == current_rs) {
+ encoder->state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR;
+ ok = 0;
+ }
+ else {
+ encoder->guts->real_signal_mid_side[i] = current_rs;
+ if(previous_rs != 0)
+ free(previous_rs);
+ }
+ }
+ }
+ if(ok) {
+ for(i = 0; i < 2; i++) {
+ residual = (int32*)malloc(sizeof(int32) * new_size);
+ if(0 == residual) {
+ encoder->state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR;
+ ok = 0;
+ }
+ else {
+ if(encoder->guts->residual[i] != 0)
+ free(encoder->guts->residual[i]);
+ encoder->guts->residual[i] = residual;
+ }
+ }
+ }
+ if(ok)
+ encoder->guts->input_capacity = new_size;
+
+ return ok;
+}
+
+FLAC__Encoder *FLAC__encoder_get_new_instance()
+{
+ FLAC__Encoder *encoder = (FLAC__Encoder*)malloc(sizeof(FLAC__Encoder));
+ if(encoder != 0) {
+ encoder->state = FLAC__ENCODER_UNINITIALIZED;
+ encoder->guts = 0;
+ }
+ return encoder;
+}
+
+void FLAC__encoder_free_instance(FLAC__Encoder *encoder)
+{
+ assert(encoder != 0);
+ free(encoder);
+}
+
+FLAC__EncoderState FLAC__encoder_init(FLAC__Encoder *encoder, FLAC__EncoderWriteStatus (*write_callback)(const FLAC__Encoder *encoder, const byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data), void (*metadata_callback)(const FLAC__Encoder *encoder, const FLAC__StreamMetaData *metadata, void *client_data), void *client_data)
+{
+ unsigned i;
+
+ assert(sizeof(int) >= 4); /* we want to die right away if this is not true */
+ assert(encoder != 0);
+ assert(write_callback != 0);
+ assert(metadata_callback != 0);
+ assert(encoder->state == FLAC__ENCODER_UNINITIALIZED);
+ assert(encoder->guts == 0);
+
+ encoder->state = FLAC__ENCODER_OK;
+
+ if(encoder->channels == 0 || encoder->channels > FLAC__MAX_CHANNELS)
+ return encoder->state = FLAC__ENCODER_INVALID_NUMBER_OF_CHANNELS;
+
+ if(encoder->do_mid_side_stereo && encoder->channels != 2)
+ return encoder->state = FLAC__ENCODER_MID_SIDE_CHANNELS_MISMATCH;
+
+ if(encoder->do_mid_side_stereo && encoder->bits_per_sample > 16)
+ return encoder->state = FLAC__ENCODER_MID_SIDE_SAMPLE_SIZE_MISMATCH;
+
+ if(encoder->bits_per_sample == 0 || encoder->bits_per_sample > FLAC__MAX_BITS_PER_SAMPLE)
+ return encoder->state = FLAC__ENCODER_INVALID_BITS_PER_SAMPLE;
+
+ if(encoder->sample_rate == 0 || encoder->sample_rate > FLAC__MAX_SAMPLE_RATE)
+ return encoder->state = FLAC__ENCODER_INVALID_SAMPLE_RATE;
+
+ if(encoder->blocksize < FLAC__MIN_BLOCK_SIZE || encoder->blocksize > FLAC__MAX_BLOCK_SIZE)
+ return encoder->state = FLAC__ENCODER_INVALID_BLOCK_SIZE;
+
+ if(encoder->blocksize < encoder->max_lpc_order)
+ return encoder->state = FLAC__ENCODER_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER;
+
+ if(encoder->qlp_coeff_precision == 0) {
+ if(encoder->bits_per_sample < 16) {
+ /* @@@ need some data about how to set this here w.r.t. blocksize and sample rate */
+ /* @@@ until then we'll make a guess */
+ encoder->qlp_coeff_precision = max(5, 2 + encoder->bits_per_sample / 2);
+ }
+ else if(encoder->bits_per_sample == 16) {
+ if(encoder->blocksize <= 192)
+ encoder->qlp_coeff_precision = 7;
+ else if(encoder->blocksize <= 384)
+ encoder->qlp_coeff_precision = 8;
+ else if(encoder->blocksize <= 576)
+ encoder->qlp_coeff_precision = 9;
+ else if(encoder->blocksize <= 1152)
+ encoder->qlp_coeff_precision = 10;
+ else if(encoder->blocksize <= 2304)
+ encoder->qlp_coeff_precision = 11;
+ else if(encoder->blocksize <= 4608)
+ encoder->qlp_coeff_precision = 12;
+ else
+ encoder->qlp_coeff_precision = 13;
+ }
+ else {
+ encoder->qlp_coeff_precision = min(13, 8*sizeof(int32) - encoder->bits_per_sample - 1);
+ }
+ }
+ else if(encoder->qlp_coeff_precision < FLAC__MIN_QLP_COEFF_PRECISION || encoder->qlp_coeff_precision + encoder->bits_per_sample >= 8*sizeof(uint32))
+ return encoder->state = FLAC__ENCODER_INVALID_QLP_COEFF_PRECISION;
+
+ if(encoder->streamable_subset) {
+ if(encoder->bits_per_sample != 8 && encoder->bits_per_sample != 12 && encoder->bits_per_sample != 16 && encoder->bits_per_sample != 20 && encoder->bits_per_sample != 24)
+ return encoder->state = FLAC__ENCODER_NOT_STREAMABLE;
+ if(encoder->sample_rate > 655350)
+ return encoder->state = FLAC__ENCODER_NOT_STREAMABLE;
+ }
+
+ if(encoder->rice_optimization_level >= (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
+ encoder->rice_optimization_level = (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN) - 1;
+
+ encoder->guts = (FLAC__EncoderPrivate*)malloc(sizeof(FLAC__EncoderPrivate));
+ if(encoder->guts == 0)
+ return encoder->state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR;
+
+ encoder->guts->input_capacity = 0;
+ for(i = 0; i < encoder->channels; i++) {
+ encoder->guts->integer_signal[i] = 0;
+ encoder->guts->real_signal[i] = 0;
+ }
+ for(i = 0; i < 2; i++) {
+ encoder->guts->integer_signal_mid_side[i] = 0;
+ encoder->guts->real_signal_mid_side[i] = 0;
+ }
+ encoder->guts->residual[0] = 0;
+ encoder->guts->residual[1] = 0;
+ encoder->guts->best_residual = 0;
+ encoder->guts->current_frame_can_do_mid_side = true;
+ encoder->guts->current_sample_number = 0;
+ encoder->guts->current_frame_number = 0;
+
+ if(!encoder_resize_buffers_(encoder, encoder->blocksize)) {
+ /* the above function sets the state for us in case of an error */
+ return encoder->state;
+ }
+ FLAC__bitbuffer_init(&encoder->guts->frame);
+ encoder->guts->write_callback = write_callback;
+ encoder->guts->metadata_callback = metadata_callback;
+ encoder->guts->client_data = client_data;
+
+ /*
+ * write the stream header
+ */
+ if(!FLAC__bitbuffer_clear(&encoder->guts->frame))
+ return encoder->state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR;
+
+ if(!FLAC__bitbuffer_write_raw_uint32(&encoder->guts->frame, FLAC__STREAM_SYNC, FLAC__STREAM_SYNC_LEN))
+ return encoder->state = FLAC__ENCODER_FRAMING_ERROR;
+
+ encoder->guts->metadata.type = FLAC__METADATA_TYPE_ENCODING;
+ encoder->guts->metadata.is_last = true;
+ encoder->guts->metadata.length = FLAC__STREAM_METADATA_ENCODING_LENGTH;
+ encoder->guts->metadata.data.encoding.min_blocksize = encoder->blocksize; /* this encoder uses the same blocksize for the whole stream */
+ encoder->guts->metadata.data.encoding.max_blocksize = encoder->blocksize;
+ encoder->guts->metadata.data.encoding.min_framesize = 0; /* we don't know this yet; have to fill it in later */
+ encoder->guts->metadata.data.encoding.max_framesize = 0; /* we don't know this yet; have to fill it in later */
+ encoder->guts->metadata.data.encoding.sample_rate = encoder->sample_rate;
+ encoder->guts->metadata.data.encoding.channels = encoder->channels;
+ encoder->guts->metadata.data.encoding.bits_per_sample = encoder->bits_per_sample;
+ encoder->guts->metadata.data.encoding.total_samples = 0; /* we don't know this yet; have to fill it in later */
+ if(!FLAC__add_metadata_block(&encoder->guts->metadata, &encoder->guts->frame))
+ return encoder->state = FLAC__ENCODER_FRAMING_ERROR;
+
+ assert(encoder->guts->frame.bits == 0); /* assert that we're byte-aligned before writing */
+ assert(encoder->guts->frame.total_consumed_bits == 0); /* assert that no reading of the buffer was done */
+ if(encoder->guts->write_callback(encoder, encoder->guts->frame.buffer, encoder->guts->frame.bytes, 0, encoder->guts->current_frame_number, encoder->guts->client_data) != FLAC__ENCODER_WRITE_OK)
+ return encoder->state = FLAC__ENCODER_FATAL_ERROR_WHILE_WRITING;
+
+ /* now that the metadata block is written, we can init this to an absurdly-high value */
+ encoder->guts->metadata.data.encoding.min_framesize = (1u << FLAC__STREAM_METADATA_ENCODING_MIN_FRAME_SIZE_LEN) - 1;
+
+ return encoder->state;
+}
+
+void FLAC__encoder_finish(FLAC__Encoder *encoder)
+{
+ unsigned i;
+
+ assert(encoder != 0);
+ if(encoder->state == FLAC__ENCODER_UNINITIALIZED)
+ return;
+ if(encoder->guts->current_sample_number != 0) {
+ encoder->blocksize = encoder->guts->current_sample_number;
+ encoder_process_frame_(encoder, true); /* true => is last frame */
+ }
+ encoder->guts->metadata_callback(encoder, &encoder->guts->metadata, encoder->guts->client_data);
+ if(encoder->guts != 0) {
+ for(i = 0; i < encoder->channels; i++) {
+ if(encoder->guts->integer_signal[i] != 0) {
+ free(encoder->guts->integer_signal[i]);
+ encoder->guts->integer_signal[i] = 0;
+ }
+ if(encoder->guts->real_signal[i] != 0) {
+ free(encoder->guts->real_signal[i]);
+ encoder->guts->real_signal[i] = 0;
+ }
+ }
+ for(i = 0; i < 2; i++) {
+ if(encoder->guts->integer_signal_mid_side[i] != 0) {
+ free(encoder->guts->integer_signal_mid_side[i]);
+ encoder->guts->integer_signal_mid_side[i] = 0;
+ }
+ if(encoder->guts->real_signal_mid_side[i] != 0) {
+ free(encoder->guts->real_signal_mid_side[i]);
+ encoder->guts->real_signal_mid_side[i] = 0;
+ }
+ }
+ for(i = 0; i < 2; i++) {
+ if(encoder->guts->residual[i] != 0) {
+ free(encoder->guts->residual[i]);
+ encoder->guts->residual[i] = 0;
+ }
+ }
+ FLAC__bitbuffer_free(&encoder->guts->frame);
+ free(encoder->guts);
+ encoder->guts = 0;
+ }
+ encoder->state = FLAC__ENCODER_UNINITIALIZED;
+}
+
+bool FLAC__encoder_process(FLAC__Encoder *encoder, const int32 *buf[], unsigned samples)
+{
+ unsigned i, j, channel;
+ int32 x, mid, side;
+ const bool ms = encoder->do_mid_side_stereo && encoder->channels == 2;
+ const int32 min_side = -((int64)1 << (encoder->bits_per_sample-1));
+ const int32 max_side = ((int64)1 << (encoder->bits_per_sample-1)) - 1;
+
+ assert(encoder != 0);
+ assert(encoder->state == FLAC__ENCODER_OK);
+
+ j = 0;
+ do {
+ for(i = encoder->guts->current_sample_number; i < encoder->blocksize && j < samples; i++, j++) {
+ for(channel = 0; channel < encoder->channels; channel++) {
+ x = buf[channel][j];
+ encoder->guts->integer_signal[channel][i] = x;
+ encoder->guts->real_signal[channel][i] = (real)x;
+ }
+ if(ms && encoder->guts->current_frame_can_do_mid_side) {
+ side = buf[0][j] - buf[1][j];
+ if(side < min_side || side > max_side) {
+ encoder->guts->current_frame_can_do_mid_side = false;
+ }
+ else {
+ mid = (buf[0][j] + buf[1][j]) >> 1; /* NOTE: not the same as divide-by-two ! */
+ encoder->guts->integer_signal_mid_side[0][i] = mid;
+ encoder->guts->integer_signal_mid_side[1][i] = side;
+ encoder->guts->real_signal_mid_side[0][i] = (real)mid;
+ encoder->guts->real_signal_mid_side[1][i] = (real)side;
+ }
+ }
+ encoder->guts->current_sample_number++;
+ }
+ if(i == encoder->blocksize) {
+ if(!encoder_process_frame_(encoder, false)) /* false => not last frame */
+ return false;
+ }
+ } while(j < samples);
+
+ return true;
+}
+
+/* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
+bool FLAC__encoder_process_interleaved(FLAC__Encoder *encoder, const int32 buf[], unsigned samples)
+{
+ unsigned i, j, k, channel;
+ int32 x, left = 0, mid, side;
+ const bool ms = encoder->do_mid_side_stereo && encoder->channels == 2;
+ const int32 min_side = -((int64)1 << (encoder->bits_per_sample-1));
+ const int32 max_side = ((int64)1 << (encoder->bits_per_sample-1)) - 1;
+
+ assert(encoder != 0);
+ assert(encoder->state == FLAC__ENCODER_OK);
+
+ j = k = 0;
+ do {
+ for(i = encoder->guts->current_sample_number; i < encoder->blocksize && j < samples; i++, j++, k++) {
+ for(channel = 0; channel < encoder->channels; channel++, k++) {
+ x = buf[k];
+ encoder->guts->integer_signal[channel][i] = x;
+ encoder->guts->real_signal[channel][i] = (real)x;
+ if(ms && encoder->guts->current_frame_can_do_mid_side) {
+ if(channel == 0) {
+ left = x;
+ }
+ else {
+ side = left - x;
+ if(side < min_side || side > max_side) {
+ encoder->guts->current_frame_can_do_mid_side = false;
+ }
+ else {
+ mid = (left + x) >> 1; /* NOTE: not the same as divide-by-two ! */
+ encoder->guts->integer_signal_mid_side[0][i] = mid;
+ encoder->guts->integer_signal_mid_side[1][i] = side;
+ encoder->guts->real_signal_mid_side[0][i] = (real)mid;
+ encoder->guts->real_signal_mid_side[1][i] = (real)side;
+ }
+ }
+ }
+ }
+ encoder->guts->current_sample_number++;
+ }
+ if(i == encoder->blocksize) {
+ if(!encoder_process_frame_(encoder, false)) /* false => not last frame */
+ return false;
+ }
+ } while(j < samples);
+
+ return true;
+}
+
+bool encoder_process_frame_(FLAC__Encoder *encoder, bool is_last_frame)
+{
+ FLAC__FrameHeader frame_header;
+ FLAC__BitBuffer *smallest_frame;
+
+ assert(encoder->state == FLAC__ENCODER_OK);
+
+ /*
+ * First do a normal encoding pass
+ */
+ frame_header.blocksize = encoder->blocksize;
+ frame_header.sample_rate = encoder->sample_rate;
+ frame_header.channels = encoder->channels;
+ frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT; /* the default unless the encoder determines otherwise */
+ frame_header.bits_per_sample = encoder->bits_per_sample;
+ frame_header.number.frame_number = encoder->guts->current_frame_number;
+
+ if(!FLAC__bitbuffer_clear(&encoder->guts->frame)) {
+ encoder->state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR;
+ return false;
+ }
+ if(!FLAC__frame_add_header(&frame_header, encoder->streamable_subset, is_last_frame, &encoder->guts->frame)) {
+ encoder->state = FLAC__ENCODER_FRAMING_ERROR;
+ return false;
+ }
+
+ if(!encoder_process_subframes_(encoder, is_last_frame, &frame_header, encoder->channels, encoder->guts->integer_signal, encoder->guts->real_signal, &encoder->guts->frame))
+ return false;
+
+ smallest_frame = &encoder->guts->frame;
+
+ /*
+ * Now try a mid-side version if necessary; otherwise, just use the previous step's frame
+ */
+ if(encoder->do_mid_side_stereo && encoder->guts->current_frame_can_do_mid_side) {
+ int32 *integer_signal[2];
+ real *real_signal[2];
+
+ assert(encoder->channels == 2);
+
+ /* mid-side */
+ frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_MID_SIDE;
+ if(!FLAC__bitbuffer_clear(&encoder->guts->frame_mid_side)) {
+ encoder->state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR;
+ return false;
+ }
+ if(!FLAC__frame_add_header(&frame_header, encoder->streamable_subset, is_last_frame, &encoder->guts->frame_mid_side)) {
+ encoder->state = FLAC__ENCODER_FRAMING_ERROR;
+ return false;
+ }
+ integer_signal[0] = encoder->guts->integer_signal_mid_side[0]; /* mid channel */
+ integer_signal[1] = encoder->guts->integer_signal_mid_side[1]; /* side channel */
+ real_signal[0] = encoder->guts->real_signal_mid_side[0]; /* mid channel */
+ real_signal[1] = encoder->guts->real_signal_mid_side[1]; /* side channel */
+ if(!encoder_process_subframes_(encoder, is_last_frame, &frame_header, encoder->channels, integer_signal, real_signal, &encoder->guts->frame_mid_side))
+ return false;
+ if(encoder->guts->frame_mid_side.total_bits < smallest_frame->total_bits)
+ smallest_frame = &encoder->guts->frame_mid_side;
+
+ /* left-side */
+ frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE;
+ if(!FLAC__bitbuffer_clear(&encoder->guts->frame_left_side)) {
+ encoder->state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR;
+ return false;
+ }
+ if(!FLAC__frame_add_header(&frame_header, encoder->streamable_subset, is_last_frame, &encoder->guts->frame_left_side)) {
+ encoder->state = FLAC__ENCODER_FRAMING_ERROR;
+ return false;
+ }
+ integer_signal[0] = encoder->guts->integer_signal[0]; /* left channel */
+ integer_signal[1] = encoder->guts->integer_signal_mid_side[1]; /* side channel */
+ real_signal[0] = encoder->guts->real_signal[0]; /* left channel */
+ real_signal[1] = encoder->guts->real_signal_mid_side[1]; /* side channel */
+ if(!encoder_process_subframes_(encoder, is_last_frame, &frame_header, encoder->channels, integer_signal, real_signal, &encoder->guts->frame_left_side))
+ return false;
+ if(encoder->guts->frame_left_side.total_bits < smallest_frame->total_bits)
+ smallest_frame = &encoder->guts->frame_left_side;
+
+ /* right-side */
+ frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE;
+ if(!FLAC__bitbuffer_clear(&encoder->guts->frame_right_side)) {
+ encoder->state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR;
+ return false;
+ }
+ if(!FLAC__frame_add_header(&frame_header, encoder->streamable_subset, is_last_frame, &encoder->guts->frame_right_side)) {
+ encoder->state = FLAC__ENCODER_FRAMING_ERROR;
+ return false;
+ }
+ integer_signal[0] = encoder->guts->integer_signal_mid_side[1]; /* side channel */
+ integer_signal[1] = encoder->guts->integer_signal[1]; /* right channel */
+ real_signal[0] = encoder->guts->real_signal_mid_side[1]; /* side channel */
+ real_signal[1] = encoder->guts->real_signal[1]; /* right channel */
+ if(!encoder_process_subframes_(encoder, is_last_frame, &frame_header, encoder->channels, integer_signal, real_signal, &encoder->guts->frame_right_side))
+ return false;
+ if(encoder->guts->frame_right_side.total_bits < smallest_frame->total_bits)
+ smallest_frame = &encoder->guts->frame_right_side;
+ }
+
+ /*
+ * Zero-pad the frame to a byte_boundary
+ */
+ if(!FLAC__bitbuffer_zero_pad_to_byte_boundary(smallest_frame)) {
+ encoder->state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR;
+ return false;
+ }
+
+ /*
+ * Write it
+ */
+ assert(smallest_frame->bits == 0); /* assert that we're byte-aligned before writing */
+ assert(smallest_frame->total_consumed_bits == 0); /* assert that no reading of the buffer was done */
+ if(encoder->guts->write_callback(encoder, smallest_frame->buffer, smallest_frame->bytes, encoder->blocksize, encoder->guts->current_frame_number, encoder->guts->client_data) != FLAC__ENCODER_WRITE_OK) {
+ encoder->state = FLAC__ENCODER_FATAL_ERROR_WHILE_WRITING;
+ return false;
+ }
+
+ /*
+ * Get ready for the next frame
+ */
+ encoder->guts->current_frame_can_do_mid_side = true;
+ encoder->guts->current_sample_number = 0;
+ encoder->guts->current_frame_number++;
+ encoder->guts->metadata.data.encoding.total_samples += (uint64)encoder->blocksize;
+ encoder->guts->metadata.data.encoding.min_framesize = min(smallest_frame->bytes, encoder->guts->metadata.data.encoding.min_framesize);
+ encoder->guts->metadata.data.encoding.max_framesize = max(smallest_frame->bytes, encoder->guts->metadata.data.encoding.max_framesize);
+
+ return true;
+}
+
+bool encoder_process_subframes_(FLAC__Encoder *encoder, bool is_last_frame, const FLAC__FrameHeader *frame_header, unsigned channels, const int32 *integer_signal[], const real *real_signal[], FLAC__BitBuffer *frame)
+{
+ real fixed_residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1];
+ real lpc_residual_bits_per_sample;
+ real autoc[FLAC__MAX_LPC_ORDER+1];
+ real lp_coeff[FLAC__MAX_LPC_ORDER][FLAC__MAX_LPC_ORDER];
+ real lpc_error[FLAC__MAX_LPC_ORDER];
+ unsigned channel;
+ unsigned min_lpc_order, max_lpc_order, lpc_order;
+ unsigned min_fixed_order, max_fixed_order, guess_fixed_order, fixed_order;
+ unsigned max_partition_order;
+ unsigned min_qlp_coeff_precision, max_qlp_coeff_precision, qlp_coeff_precision;
+ unsigned rice_parameter;
+ unsigned candidate_bits, best_bits;
+
+ if(is_last_frame) {
+ max_partition_order = 0;
+ }
+ else {
+ unsigned limit = 0, b = encoder->blocksize;
+ while(!(b & 1)) {
+ limit++;
+ b >>= 1;
+ }
+ max_partition_order = min(encoder->rice_optimization_level, limit);
+ }
+
+ for(channel = 0; channel < channels; channel++) {
+ /* verbatim subframe is the baseline against which we measure other compressed subframes */
+ best_bits = encoder_evaluate_verbatim_subframe_(frame_header->blocksize, frame_header->bits_per_sample, &(encoder->guts->best_subframe));
+
+ if(frame_header->blocksize >= FLAC__MAX_FIXED_ORDER) {
+ /* check for constant subframe */
+ guess_fixed_order = FLAC__fixed_compute_best_predictor(integer_signal[channel]+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample);
+ if(fixed_residual_bits_per_sample[1] == 0.0) {
+ candidate_bits = encoder_evaluate_constant_subframe_(integer_signal[channel][0], frame_header->bits_per_sample, &(encoder->guts->candidate_subframe));
+ if(candidate_bits < best_bits) {
+ encoder_promote_candidate_subframe_(encoder);
+ best_bits = candidate_bits;
+ }
+ }
+ else {
+ /* encode fixed */
+ if(encoder->do_exhaustive_model_search) {
+ min_fixed_order = 0;
+ max_fixed_order = FLAC__MAX_FIXED_ORDER;
+ }
+ else {
+ min_fixed_order = max_fixed_order = guess_fixed_order;
+ }
+ for(fixed_order = min_fixed_order; fixed_order <= max_fixed_order; fixed_order++) {
+ if(fixed_residual_bits_per_sample[fixed_order] >= (real)frame_header->bits_per_sample)
+ continue; /* don't even try */
+ rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > 0.0)? (unsigned)(fixed_residual_bits_per_sample[fixed_order]+0.5) : 0;
+ if(rice_parameter >= (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN))
+ rice_parameter = (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN) - 1;
+ candidate_bits = encoder_evaluate_fixed_subframe_(integer_signal[channel], encoder->guts->residual[!encoder->guts->best_residual], frame_header->blocksize, frame_header->bits_per_sample, fixed_order, rice_parameter, max_partition_order, &(encoder->guts->candidate_subframe));
+ if(candidate_bits < best_bits) {
+ encoder_promote_candidate_subframe_(encoder);
+ best_bits = candidate_bits;
+ }
+ }
+
+ /* encode lpc */
+ if(encoder->max_lpc_order > 0) {
+ if(encoder->max_lpc_order >= frame_header->blocksize)
+ max_lpc_order = frame_header->blocksize-1;
+ else
+ max_lpc_order = encoder->max_lpc_order;
+ if(max_lpc_order > 0) {
+ FLAC__lpc_compute_autocorrelation(real_signal[channel], frame_header->blocksize, max_lpc_order+1, autoc);
+ FLAC__lpc_compute_lp_coefficients(autoc, max_lpc_order, lp_coeff, lpc_error);
+ if(encoder->do_exhaustive_model_search) {
+ min_lpc_order = 1;
+ }
+ else {
+ unsigned guess_lpc_order = FLAC__lpc_compute_best_order(lpc_error, max_lpc_order, frame_header->blocksize, frame_header->bits_per_sample);
+ min_lpc_order = max_lpc_order = guess_lpc_order;
+ }
+ if(encoder->do_qlp_coeff_prec_search) {
+ min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION;
+ max_qlp_coeff_precision = 32 - frame_header->bits_per_sample - 1;
+ }
+ else {
+ min_qlp_coeff_precision = max_qlp_coeff_precision = encoder->qlp_coeff_precision;
+ }
+ for(lpc_order = min_lpc_order; lpc_order <= max_lpc_order; lpc_order++) {
+ lpc_residual_bits_per_sample = FLAC__lpc_compute_expected_bits_per_residual_sample(lpc_error[lpc_order-1], frame_header->blocksize);
+ if(lpc_residual_bits_per_sample >= (real)frame_header->bits_per_sample)
+ continue; /* don't even try */
+ rice_parameter = (lpc_residual_bits_per_sample > 0.0)? (unsigned)(lpc_residual_bits_per_sample+0.5) : 0;
+ if(rice_parameter >= (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN))
+ rice_parameter = (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN) - 1;
+ for(qlp_coeff_precision = min_qlp_coeff_precision; qlp_coeff_precision <= max_qlp_coeff_precision; qlp_coeff_precision++) {
+ candidate_bits = encoder_evaluate_lpc_subframe_(integer_signal[channel], encoder->guts->residual[!encoder->guts->best_residual], lp_coeff[lpc_order-1], frame_header->blocksize, frame_header->bits_per_sample, lpc_order, qlp_coeff_precision, rice_parameter, max_partition_order, &(encoder->guts->candidate_subframe));
+ if(candidate_bits > 0) { /* if == 0, there was a problem quantizing the lpcoeffs */
+ if(candidate_bits < best_bits) {
+ encoder_promote_candidate_subframe_(encoder);
+ best_bits = candidate_bits;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* add the best subframe */
+ switch(encoder->guts->best_subframe.type) {
+ case FLAC__SUBFRAME_TYPE_CONSTANT:
+ if(!encoder_generate_constant_subframe_(&(encoder->guts->best_subframe), frame_header->bits_per_sample, frame)) {
+ encoder->state = FLAC__ENCODER_FATAL_ERROR_WHILE_ENCODING;
+ return false;
+ }
+ break;
+ case FLAC__SUBFRAME_TYPE_FIXED:
+ if(!encoder_generate_fixed_subframe_(&(encoder->guts->best_subframe), encoder->guts->residual[encoder->guts->best_residual], frame_header->blocksize, frame_header->bits_per_sample, frame)) {
+ encoder->state = FLAC__ENCODER_FATAL_ERROR_WHILE_ENCODING;
+ return false;
+ }
+ break;
+ case FLAC__SUBFRAME_TYPE_LPC:
+ if(!encoder_generate_lpc_subframe_(&(encoder->guts->best_subframe), encoder->guts->residual[encoder->guts->best_residual], frame_header->blocksize, frame_header->bits_per_sample, frame)) {
+ encoder->state = FLAC__ENCODER_FATAL_ERROR_WHILE_ENCODING;
+ return false;
+ }
+ break;
+ case FLAC__SUBFRAME_TYPE_VERBATIM:
+ if(!encoder_generate_verbatim_subframe_(&(encoder->guts->best_subframe), integer_signal[channel], frame_header->blocksize, frame_header->bits_per_sample, frame)) {
+ encoder->state = FLAC__ENCODER_FATAL_ERROR_WHILE_ENCODING;
+ return false;
+ }
+ break;
+ }
+ }
+
+ return true;
+}
+
+unsigned encoder_evaluate_constant_subframe_(const int32 signal, unsigned bits_per_sample, FLAC__SubframeHeader *subframe)
+{
+ subframe->type = FLAC__SUBFRAME_TYPE_CONSTANT;
+ subframe->data.constant.value = signal;
+
+ return 8 + bits_per_sample;
+}
+
+unsigned encoder_evaluate_fixed_subframe_(const int32 signal[], int32 residual[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned rice_parameter, unsigned max_partition_order, FLAC__SubframeHeader *subframe)
+{
+ unsigned i, residual_bits;
+ const unsigned residual_samples = blocksize - order;
+
+ FLAC__fixed_compute_residual(signal+order, residual_samples, order, residual);
+
+ subframe->type = FLAC__SUBFRAME_TYPE_FIXED;
+
+ subframe->data.fixed.entropy_coding_method.type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE;
+
+ residual_bits = encoder_find_best_partition_order_(residual, residual_samples, order, rice_parameter, max_partition_order, &subframe->data.fixed.entropy_coding_method.data.partitioned_rice.order, subframe->data.fixed.entropy_coding_method.data.partitioned_rice.parameters);
+
+ subframe->data.fixed.order = order;
+ for(i = 0; i < order; i++)
+ subframe->data.fixed.warmup[i] = signal[i];
+
+ return 8 + (order * bits_per_sample) + residual_bits;
+}
+
+unsigned encoder_evaluate_lpc_subframe_(const int32 signal[], int32 residual[], const real lp_coeff[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, unsigned max_partition_order, FLAC__SubframeHeader *subframe)
+{
+ int32 qlp_coeff[FLAC__MAX_LPC_ORDER];
+ unsigned i, residual_bits;
+ int quantization, ret;
+ const unsigned residual_samples = blocksize - order;
+
+ ret = FLAC__lpc_quantize_coefficients(lp_coeff, order, qlp_coeff_precision, bits_per_sample, qlp_coeff, &quantization);
+ if(ret != 0)
+ return 0; /* this is a hack to indicate to the caller that we can't do lp at this order on this subframe */
+
+ FLAC__lpc_compute_residual_from_qlp_coefficients(signal+order, residual_samples, qlp_coeff, order, quantization, residual);
+
+ subframe->type = FLAC__SUBFRAME_TYPE_LPC;
+
+ subframe->data.lpc.entropy_coding_method.type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE;
+
+ residual_bits = encoder_find_best_partition_order_(residual, residual_samples, order, rice_parameter, max_partition_order, &subframe->data.lpc.entropy_coding_method.data.partitioned_rice.order, subframe->data.lpc.entropy_coding_method.data.partitioned_rice.parameters);
+
+ subframe->data.lpc.order = order;
+ subframe->data.lpc.qlp_coeff_precision = qlp_coeff_precision;
+ subframe->data.lpc.quantization_level = quantization;
+ memcpy(subframe->data.lpc.qlp_coeff, qlp_coeff, sizeof(int32)*FLAC__MAX_LPC_ORDER);
+ for(i = 0; i < order; i++)
+ subframe->data.lpc.warmup[i] = signal[i];
+
+ return 8 + 9 + (order * (qlp_coeff_precision + bits_per_sample)) + residual_bits;
+}
+
+unsigned encoder_evaluate_verbatim_subframe_(unsigned blocksize, unsigned bits_per_sample, FLAC__SubframeHeader *subframe)
+{
+ subframe->type = FLAC__SUBFRAME_TYPE_VERBATIM;
+
+ return 8 + (blocksize * bits_per_sample);
+}
+
+unsigned encoder_find_best_partition_order_(int32 residual[], unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, unsigned max_partition_order, unsigned *best_partition_order, unsigned best_parameters[])
+{
+ unsigned residual_bits, best_residual_bits = 0;
+ unsigned partition_order;
+ unsigned best_parameters_index = 0, parameters[2][1 << FLAC__MAX_RICE_PARTITION_ORDER];
+
+ for(partition_order = 0; partition_order <= max_partition_order; partition_order++) {
+ if(!encoder_set_partitioned_rice_(residual, residual_samples, predictor_order, rice_parameter, partition_order, parameters[!best_parameters_index], &residual_bits)) {
+ assert(best_residual_bits != 0);
+ break;
+ }
+ if(best_residual_bits == 0 || residual_bits < best_residual_bits) {
+ best_residual_bits = residual_bits;
+ *best_partition_order = partition_order;
+ best_parameters_index = !best_parameters_index;
+ }
+ }
+ memcpy(best_parameters, parameters[best_parameters_index], sizeof(unsigned)*(1<<(*best_partition_order)));
+
+ return best_residual_bits;
+}
+
+bool encoder_generate_constant_subframe_(const FLAC__SubframeHeader *header, unsigned bits_per_sample, FLAC__BitBuffer *bitbuffer)
+{
+ assert(header->type == FLAC__SUBFRAME_TYPE_CONSTANT);
+ return FLAC__subframe_add_constant(bits_per_sample, header, bitbuffer);
+}
+
+bool encoder_generate_fixed_subframe_(const FLAC__SubframeHeader *header, int32 residual[], unsigned blocksize, unsigned bits_per_sample, FLAC__BitBuffer *bitbuffer)
+{
+ assert(header->type == FLAC__SUBFRAME_TYPE_FIXED);
+ return FLAC__subframe_add_fixed(residual, blocksize - header->data.fixed.order, bits_per_sample, header, bitbuffer);
+}
+
+bool encoder_generate_lpc_subframe_(const FLAC__SubframeHeader *header, int32 residual[], unsigned blocksize, unsigned bits_per_sample, FLAC__BitBuffer *bitbuffer)
+{
+ assert(header->type == FLAC__SUBFRAME_TYPE_LPC);
+ return FLAC__subframe_add_lpc(residual, blocksize - header->data.lpc.order, bits_per_sample, header, bitbuffer);
+}
+
+bool encoder_generate_verbatim_subframe_(const FLAC__SubframeHeader *header, const int32 signal[], unsigned blocksize, unsigned bits_per_sample, FLAC__BitBuffer *bitbuffer)
+{
+ assert(header->type == FLAC__SUBFRAME_TYPE_VERBATIM);
+#ifdef NDEBUG
+ (void)header; /* silence compiler warning about unused parameter */
+#endif
+ return FLAC__subframe_add_verbatim(signal, blocksize, bits_per_sample, bitbuffer);
+}
+
+void encoder_promote_candidate_subframe_(FLAC__Encoder *encoder)
+{
+ assert(encoder->state == FLAC__ENCODER_OK);
+ encoder->guts->best_subframe = encoder->guts->candidate_subframe;
+ encoder->guts->best_residual = !encoder->guts->best_residual;
+}
+
+bool encoder_set_partitioned_rice_(const int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameter, const unsigned partition_order, unsigned parameters[], unsigned *bits)
+{
+ unsigned bits_ = 2 + 3;
+
+ if(partition_order == 0) {
+ unsigned i;
+ parameters[0] = rice_parameter;
+ bits_ += FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN;
+ for(i = 0; i < residual_samples; i++)
+ bits_ += RICE_BITS(residual[i], rice_parameter);
+ }
+ else {
+ unsigned i, j, k = 0, k_last = 0, z;
+ unsigned mean;
+ unsigned parameter, partition_samples;
+ const unsigned max_parameter = (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN) - 1;
+ for(i = 0; i < (1u<<partition_order); i++) {
+ partition_samples = (residual_samples+predictor_order) >> partition_order;
+ if(i == 0) {
+ if(partition_samples <= predictor_order)
+ return false;
+ else
+ partition_samples -= predictor_order;
+ }
+ mean = partition_samples >> 1;
+ for(j = 0; j < partition_samples; j++, k++)
+ mean += ((residual[k] < 0)? (unsigned)(-residual[k]) : (unsigned)residual[k]);
+ mean /= partition_samples;
+ z = 0x80000000;
+ for(j = 0; j < 32; j++, z >>= 1)
+ if(mean & z)
+ break;
+ parameter = j > 31? 0 : 32 - j - 1;
+ if(parameter > max_parameter)
+ parameter = max_parameter;
+ parameters[i] = parameter;
+ bits_ += FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN;
+ for(j = k_last; j < k; j++)
+ bits_ += RICE_BITS(residual[j], parameter);
+ k_last = k;
+ }
+ }
+
+ *bits = bits_;
+ return true;
+}
diff --git a/src/libFLAC/encoder_framing.c b/src/libFLAC/encoder_framing.c
new file mode 100644
index 0000000..69201d7
--- /dev/null
+++ b/src/libFLAC/encoder_framing.c
@@ -0,0 +1,340 @@
+/* libFLAC - Free Lossless Audio Coder library
+ * Copyright (C) 2000 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include "private/encoder_framing.h"
+#include "private/crc.h"
+
+#ifdef max
+#undef max
+#endif
+#define max(x,y) ((x)>(y)?(x):(y))
+
+static bool subframe_add_entropy_coding_method_(FLAC__BitBuffer *bb, const FLAC__EntropyCodingMethod *method);
+static bool subframe_add_residual_partitioned_rice_(FLAC__BitBuffer *bb, const int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned partition_order);
+
+bool FLAC__add_metadata_block(const FLAC__StreamMetaData *metadata, FLAC__BitBuffer *bb)
+{
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->is_last, FLAC__STREAM_METADATA_IS_LAST_LEN))
+ return false;
+
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->type, FLAC__STREAM_METADATA_TYPE_LEN))
+ return false;
+
+ assert(metadata->length < (1u << FLAC__STREAM_METADATA_LENGTH_LEN));
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->length, FLAC__STREAM_METADATA_LENGTH_LEN))
+ return false;
+
+ switch(metadata->type) {
+ case FLAC__METADATA_TYPE_ENCODING:
+ assert(metadata->data.encoding.min_blocksize < (1u << FLAC__STREAM_METADATA_ENCODING_MIN_BLOCK_SIZE_LEN));
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.encoding.min_blocksize, FLAC__STREAM_METADATA_ENCODING_MIN_BLOCK_SIZE_LEN))
+ return false;
+ assert(metadata->data.encoding.max_blocksize < (1u << FLAC__STREAM_METADATA_ENCODING_MAX_BLOCK_SIZE_LEN));
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.encoding.max_blocksize, FLAC__STREAM_METADATA_ENCODING_MAX_BLOCK_SIZE_LEN))
+ return false;
+ assert(metadata->data.encoding.min_framesize < (1u << FLAC__STREAM_METADATA_ENCODING_MIN_FRAME_SIZE_LEN));
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.encoding.min_framesize, FLAC__STREAM_METADATA_ENCODING_MIN_FRAME_SIZE_LEN))
+ return false;
+ assert(metadata->data.encoding.max_framesize < (1u << FLAC__STREAM_METADATA_ENCODING_MAX_FRAME_SIZE_LEN));
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.encoding.max_framesize, FLAC__STREAM_METADATA_ENCODING_MAX_FRAME_SIZE_LEN))
+ return false;
+ assert(metadata->data.encoding.sample_rate > 0);
+ assert(metadata->data.encoding.sample_rate < (1u << FLAC__STREAM_METADATA_ENCODING_SAMPLE_RATE_LEN));
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.encoding.sample_rate, FLAC__STREAM_METADATA_ENCODING_SAMPLE_RATE_LEN))
+ return false;
+ assert(metadata->data.encoding.channels > 0);
+ assert(metadata->data.encoding.channels <= (1u << FLAC__STREAM_METADATA_ENCODING_CHANNELS_LEN));
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.encoding.channels-1, FLAC__STREAM_METADATA_ENCODING_CHANNELS_LEN))
+ return false;
+ assert(metadata->data.encoding.bits_per_sample > 0);
+ assert(metadata->data.encoding.bits_per_sample <= (1u << FLAC__STREAM_METADATA_ENCODING_BITS_PER_SAMPLE_LEN));
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.encoding.bits_per_sample-1, FLAC__STREAM_METADATA_ENCODING_BITS_PER_SAMPLE_LEN))
+ return false;
+ if(!FLAC__bitbuffer_write_raw_uint64(bb, metadata->data.encoding.total_samples, FLAC__STREAM_METADATA_ENCODING_TOTAL_SAMPLES_LEN))
+ return false;
+ break;
+ default:
+ assert(0);
+ }
+
+ return true;
+}
+
+bool FLAC__frame_add_header(const FLAC__FrameHeader *header, bool streamable_subset, bool is_last_block, FLAC__BitBuffer *bb)
+{
+ unsigned u, crc_start, blocksize_hint, sample_rate_hint;
+ byte crc;
+
+ assert(bb->bits == 0); /* assert that we're byte-aligned before writing */
+
+ crc_start = bb->bytes;
+
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__FRAME_HEADER_SYNC, FLAC__FRAME_HEADER_SYNC_LEN))
+ return false;
+
+ assert(header->blocksize > 0 && header->blocksize <= FLAC__MAX_BLOCK_SIZE);
+ blocksize_hint = 0;
+ switch(header->blocksize) {
+ case 192: u = 1; break;
+ case 576: u = 2; break;
+ case 1152: u = 3; break;
+ case 2304: u = 4; break;
+ case 4608: u = 5; break;
+ default:
+ if(streamable_subset || is_last_block) {
+ if(header->blocksize <= 0x100)
+ blocksize_hint = u = 6;
+ else
+ blocksize_hint = u = 7;
+ }
+ else
+ u = 0;
+ break;
+ }
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, u, FLAC__FRAME_HEADER_BLOCK_SIZE_LEN))
+ return false;
+
+ assert(header->sample_rate > 0 && header->sample_rate < (1u << FLAC__STREAM_METADATA_ENCODING_SAMPLE_RATE_LEN));
+ sample_rate_hint = 0;
+ switch(header->sample_rate) {
+ case 8000: u = 4; break;
+ case 16000: u = 5; break;
+ case 22050: u = 6; break;
+ case 24000: u = 7; break;
+ case 32000: u = 8; break;
+ case 44100: u = 9; break;
+ case 48000: u = 10; break;
+ case 96000: u = 11; break;
+ default:
+ if(streamable_subset) {
+ if(header->sample_rate % 1000 == 0)
+ sample_rate_hint = u = 12;
+ else if(header->sample_rate % 10 == 0)
+ sample_rate_hint = u = 14;
+ else
+ sample_rate_hint = u = 13;
+ }
+ else
+ u = 0;
+ break;
+ }
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, u, FLAC__FRAME_HEADER_SAMPLE_RATE_LEN))
+ return false;
+
+ assert(header->channels > 0 && header->channels <= (1u << FLAC__STREAM_METADATA_ENCODING_CHANNELS_LEN) && header->channels <= FLAC__MAX_CHANNELS);
+ switch(header->channel_assignment) {
+ case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
+ u = header->channels - 1;
+ break;
+ case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
+ assert(header->channels == 2);
+ u = 8;
+ break;
+ case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
+ assert(header->channels == 2);
+ u = 9;
+ break;
+ case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
+ assert(header->channels == 2);
+ u = 10;
+ break;
+ default:
+ assert(0);
+ }
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, u, FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN))
+ return false;
+
+ assert(header->bits_per_sample > 0 && header->bits_per_sample <= (1u << FLAC__STREAM_METADATA_ENCODING_BITS_PER_SAMPLE_LEN));
+ switch(header->bits_per_sample) {
+ case 8 : u = 1; break;
+ case 12: u = 2; break;
+ case 16: u = 4; break;
+ case 20: u = 5; break;
+ case 24: u = 6; break;
+ default: u = 0; break;
+ }
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, u, FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN))
+ return false;
+
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, 0, FLAC__FRAME_HEADER_ZERO_PAD_LEN))
+ return false;
+
+ if(!FLAC__bitbuffer_write_utf8_uint32(bb, header->number.frame_number))
+ return false;
+
+ if(blocksize_hint)
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, header->blocksize-1, (blocksize_hint==6)? 8:16))
+ return false;
+
+ switch(sample_rate_hint) {
+ case 12:
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, header->sample_rate / 1000, 8))
+ return false;
+ break;
+ case 13:
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, header->sample_rate, 16))
+ return false;
+ break;
+ case 14:
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, header->sample_rate / 10, 16))
+ return false;
+ break;
+ }
+
+ /* write the CRC */
+ assert(bb->buffer[crc_start] == 0xff); /* MAGIC NUMBER for the first byte of the sync code */
+ assert(bb->bits == 0); /* assert that we're byte-aligned */
+ crc = FLAC__crc8(bb->buffer+crc_start, bb->bytes-crc_start);
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, crc, FLAC__FRAME_HEADER_CRC8_LEN))
+ return false;
+
+ return true;
+}
+
+bool FLAC__subframe_add_constant(unsigned bits_per_sample, const FLAC__SubframeHeader *subframe, FLAC__BitBuffer *bb)
+{
+ bool ok;
+
+ ok =
+ FLAC__bitbuffer_write_raw_uint32(bb, FLAC__SUBFRAME_HEADER_TYPE_CONSTANT, FLAC__SUBFRAME_HEADER_TYPE_LEN) &&
+ FLAC__bitbuffer_write_raw_int32(bb, subframe->data.constant.value, bits_per_sample)
+ ;
+
+ return ok;
+}
+
+bool FLAC__subframe_add_fixed(const int32 residual[], unsigned residual_samples, unsigned bits_per_sample, const FLAC__SubframeHeader *subframe, FLAC__BitBuffer *bb)
+{
+ unsigned i;
+
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__SUBFRAME_HEADER_TYPE_FIXED | (subframe->data.fixed.order<<1), FLAC__SUBFRAME_HEADER_TYPE_LEN))
+ return false;
+
+ for(i = 0; i < subframe->data.fixed.order; i++)
+ if(!FLAC__bitbuffer_write_raw_int32(bb, subframe->data.fixed.warmup[i], bits_per_sample))
+ return false;
+
+ if(!subframe_add_entropy_coding_method_(bb, &subframe->data.fixed.entropy_coding_method))
+ return false;
+ switch(subframe->data.fixed.entropy_coding_method.type) {
+ case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
+ if(!subframe_add_residual_partitioned_rice_(bb, residual, residual_samples, subframe->data.fixed.order, subframe->data.fixed.entropy_coding_method.data.partitioned_rice.parameters, subframe->data.fixed.entropy_coding_method.data.partitioned_rice.order))
+ return false;
+ break;
+ default:
+ assert(0);
+ }
+
+ return true;
+}
+
+bool FLAC__subframe_add_lpc(const int32 residual[], unsigned residual_samples, unsigned bits_per_sample, const FLAC__SubframeHeader *subframe, FLAC__BitBuffer *bb)
+{
+ unsigned i;
+
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__SUBFRAME_HEADER_TYPE_LPC | ((subframe->data.lpc.order-1)<<1), FLAC__SUBFRAME_HEADER_TYPE_LEN))
+ return false;
+
+ for(i = 0; i < subframe->data.lpc.order; i++)
+ if(!FLAC__bitbuffer_write_raw_int32(bb, subframe->data.lpc.warmup[i], bits_per_sample))
+ return false;
+
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, subframe->data.lpc.qlp_coeff_precision-1, FLAC__SUBFRAME_HEADER_LPC_QLP_COEFF_PRECISION_LEN))
+ return false;
+ if(!FLAC__bitbuffer_write_raw_int32(bb, subframe->data.lpc.quantization_level, FLAC__SUBFRAME_HEADER_LPC_QLP_SHIFT_LEN))
+ return false;
+ for(i = 0; i < subframe->data.lpc.order; i++)
+ if(!FLAC__bitbuffer_write_raw_int32(bb, subframe->data.lpc.qlp_coeff[i], subframe->data.lpc.qlp_coeff_precision))
+ return false;
+
+ if(!subframe_add_entropy_coding_method_(bb, &subframe->data.lpc.entropy_coding_method))
+ return false;
+ switch(subframe->data.lpc.entropy_coding_method.type) {
+ case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
+ if(!subframe_add_residual_partitioned_rice_(bb, residual, residual_samples, subframe->data.lpc.order, subframe->data.fixed.entropy_coding_method.data.partitioned_rice.parameters, subframe->data.lpc.entropy_coding_method.data.partitioned_rice.order))
+ return false;
+ break;
+ default:
+ assert(0);
+ }
+
+ return true;
+}
+
+bool FLAC__subframe_add_verbatim(const int32 signal[], unsigned samples, unsigned bits_per_sample, FLAC__BitBuffer *bb)
+{
+ unsigned i;
+
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__SUBFRAME_HEADER_TYPE_VERBATIM, FLAC__SUBFRAME_HEADER_TYPE_LEN))
+ return false;
+
+ for(i = 0; i < samples; i++)
+ if(!FLAC__bitbuffer_write_raw_int32(bb, signal[i], bits_per_sample))
+ return false;
+
+ return true;
+}
+
+bool subframe_add_entropy_coding_method_(FLAC__BitBuffer *bb, const FLAC__EntropyCodingMethod *method)
+{
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, method->type, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN))
+ return false;
+ switch(method->type) {
+ case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, method->data.partitioned_rice.order, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
+ return false;
+ break;
+ default:
+ assert(0);
+ }
+ return true;
+}
+
+bool subframe_add_residual_partitioned_rice_(FLAC__BitBuffer *bb, const int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned partition_order)
+{
+ if(partition_order == 0) {
+ unsigned i;
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, rice_parameters[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN))
+ return false;
+ for(i = 0; i < residual_samples; i++) {
+ if(!FLAC__bitbuffer_write_rice_signed(bb, residual[i], rice_parameters[0]))
+ return false;
+ }
+ return true;
+ }
+ else {
+ unsigned i, j, k = 0, k_last = 0;
+ unsigned partition_samples;
+ for(i = 0; i < (1u<<partition_order); i++) {
+ if(!FLAC__bitbuffer_write_raw_uint32(bb, rice_parameters[i], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN))
+ return false;
+ partition_samples = (residual_samples+predictor_order) >> partition_order;
+ if(i == 0)
+ partition_samples -= predictor_order;
+ k += partition_samples;
+ for(j = k_last; j < k; j++)
+ if(!FLAC__bitbuffer_write_rice_signed(bb, residual[j], rice_parameters[i]))
+ return false;
+ k_last = k;
+ }
+ return true;
+ }
+}
diff --git a/src/libFLAC/file_decoder.c b/src/libFLAC/file_decoder.c
new file mode 100644
index 0000000..aed796c
--- /dev/null
+++ b/src/libFLAC/file_decoder.c
@@ -0,0 +1,403 @@
+/* libFLAC - Free Lossless Audio Coder library
+ * Copyright (C) 2000 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h> /* for malloc() */
+#include <string.h> /* for strcmp() */
+#include "FLAC/file_decoder.h"
+#include "protected/stream_decoder.h"
+
+typedef struct FLAC__FileDecoderPrivate {
+ FLAC__StreamDecoderWriteStatus (*write_callback)(const FLAC__FileDecoder *decoder, const FLAC__FrameHeader *header, const int32 *buffer[], void *client_data);
+ void (*metadata_callback)(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);
+ void (*error_callback)(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
+ void *client_data;
+ FILE *file;
+ FLAC__StreamDecoder *stream;
+ /* the rest of these are only used for seeking: */
+ FLAC__StreamMetaData_Encoding metadata; /* we keep this around so we can figure out how to seek quickly */
+ FLAC__FrameHeader last_frame_header; /* holds the info of the last frame we seeked to */
+ uint64 target_sample;
+} FLAC__FileDecoderPrivate;
+
+static FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, byte buffer[], unsigned *bytes, void *client_data);
+static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__FrameHeader *header, const int32 *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 bool seek_to_absolute_sample_(FLAC__FileDecoder *decoder, long filesize, uint64 target_sample);
+
+FLAC__FileDecoder *FLAC__file_decoder_get_new_instance()
+{
+ FLAC__FileDecoder *decoder = (FLAC__FileDecoder*)malloc(sizeof(FLAC__FileDecoder));
+ if(decoder != 0) {
+ decoder->state = FLAC__FILE_DECODER_UNINITIALIZED;
+ decoder->guts = 0;
+ }
+ return decoder;
+}
+
+void FLAC__file_decoder_free_instance(FLAC__FileDecoder *decoder)
+{
+ free(decoder);
+}
+
+FLAC__FileDecoderState FLAC__file_decoder_init(
+ FLAC__FileDecoder *decoder,
+ const char *filename,
+ FLAC__StreamDecoderWriteStatus (*write_callback)(const FLAC__FileDecoder *decoder, const FLAC__FrameHeader *header, const int32 *buffer[], void *client_data),
+ void (*metadata_callback)(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data),
+ void (*error_callback)(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data),
+ void *client_data
+)
+{
+ assert(sizeof(int) >= 4); /* we want to die right away if this is not true */
+ assert(decoder != 0);
+ assert(write_callback != 0);
+ assert(metadata_callback != 0);
+ assert(error_callback != 0);
+ assert(decoder->state == FLAC__FILE_DECODER_UNINITIALIZED);
+ assert(decoder->guts == 0);
+
+ decoder->state = FLAC__FILE_DECODER_OK;
+
+ decoder->guts = (FLAC__FileDecoderPrivate*)malloc(sizeof(FLAC__FileDecoderPrivate));
+ if(decoder->guts == 0)
+ return decoder->state = FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR;
+
+ decoder->guts->write_callback = write_callback;
+ decoder->guts->metadata_callback = metadata_callback;
+ decoder->guts->error_callback = error_callback;
+ decoder->guts->client_data = client_data;
+ decoder->guts->stream = 0;
+
+ if(0 == strcmp(filename, "-"))
+ decoder->guts->file = stdin;
+ else
+ decoder->guts->file = fopen(filename, "rb");
+ if(decoder->guts->file == 0)
+ return decoder->state = FLAC__FILE_DECODER_ERROR_OPENING_FILE;
+
+ decoder->guts->stream = FLAC__stream_decoder_get_new_instance();
+ if(FLAC__stream_decoder_init(decoder->guts->stream, read_callback_, write_callback_, metadata_callback_, error_callback_, decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
+ return decoder->state = FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR; /* this is based on internal knowledge of FLAC__stream_decoder_init() */
+
+ return decoder->state;
+}
+
+void FLAC__file_decoder_finish(FLAC__FileDecoder *decoder)
+{
+ assert(decoder != 0);
+ if(decoder->state == FLAC__FILE_DECODER_UNINITIALIZED)
+ return;
+ if(decoder->guts != 0) {
+ if(decoder->guts->file != 0 && decoder->guts->file != stdin)
+ fclose(decoder->guts->file);
+ if(decoder->guts->stream != 0) {
+ FLAC__stream_decoder_finish(decoder->guts->stream);
+ FLAC__stream_decoder_free_instance(decoder->guts->stream);
+ }
+ free(decoder->guts);
+ decoder->guts = 0;
+ }
+ decoder->state = FLAC__FILE_DECODER_UNINITIALIZED;
+}
+
+bool FLAC__file_decoder_process_whole_file(FLAC__FileDecoder *decoder)
+{
+ bool ret;
+ assert(decoder != 0);
+
+ if(decoder->state == FLAC__FILE_DECODER_END_OF_FILE)
+ return true;
+
+ assert(decoder->state == FLAC__FILE_DECODER_OK);
+
+ ret = FLAC__stream_decoder_process_whole_stream(decoder->guts->stream);
+ if(!ret)
+ decoder->state = FLAC__FILE_DECODER_STREAM_ERROR;
+
+ return ret;
+}
+
+bool FLAC__file_decoder_process_metadata(FLAC__FileDecoder *decoder)
+{
+ bool ret;
+ assert(decoder != 0);
+
+ if(decoder->state == FLAC__FILE_DECODER_END_OF_FILE)
+ return true;
+
+ assert(decoder->state == FLAC__FILE_DECODER_OK);
+
+ ret = FLAC__stream_decoder_process_metadata(decoder->guts->stream);
+ if(!ret)
+ decoder->state = FLAC__FILE_DECODER_STREAM_ERROR;
+
+ return ret;
+}
+
+bool FLAC__file_decoder_process_one_frame(FLAC__FileDecoder *decoder)
+{
+ bool ret;
+ assert(decoder != 0);
+
+ if(decoder->state == FLAC__FILE_DECODER_END_OF_FILE)
+ return true;
+
+ assert(decoder->state == FLAC__FILE_DECODER_OK);
+
+ ret = FLAC__stream_decoder_process_one_frame(decoder->guts->stream);
+ if(!ret)
+ decoder->state = FLAC__FILE_DECODER_STREAM_ERROR;
+
+ return ret;
+}
+
+bool FLAC__file_decoder_process_remaining_frames(FLAC__FileDecoder *decoder)
+{
+ bool ret;
+ assert(decoder != 0);
+
+ if(decoder->state == FLAC__FILE_DECODER_END_OF_FILE)
+ return true;
+
+ assert(decoder->state == FLAC__FILE_DECODER_OK);
+
+ ret = FLAC__stream_decoder_process_remaining_frames(decoder->guts->stream);
+ if(!ret)
+ decoder->state = FLAC__FILE_DECODER_STREAM_ERROR;
+
+ return ret;
+}
+
+bool FLAC__file_decoder_seek_absolute(FLAC__FileDecoder *decoder, uint64 sample)
+{
+ long filesize;
+
+ assert(decoder != 0);
+ assert(decoder->state == FLAC__FILE_DECODER_OK);
+
+ decoder->state = FLAC__FILE_DECODER_SEEKING;
+
+ if(!FLAC__stream_decoder_reset(decoder->guts->stream)) {
+ decoder->state = FLAC__FILE_DECODER_STREAM_ERROR;
+ return false;
+ }
+ /* get the file length */
+ if(0 != fseek(decoder->guts->file, 0, SEEK_END)) {
+ decoder->state = FLAC__FILE_DECODER_SEEK_ERROR;
+ return false;
+ }
+ fflush(decoder->guts->file);
+ if(-1 == (filesize = ftell(decoder->guts->file))) {
+ decoder->state = FLAC__FILE_DECODER_SEEK_ERROR;
+ return false;
+ }
+ /* rewind */
+ if(0 != fseek(decoder->guts->file, 0, SEEK_SET)) {
+ decoder->state = FLAC__FILE_DECODER_SEEK_ERROR;
+ return false;
+ }
+ if(!FLAC__stream_decoder_process_metadata(decoder->guts->stream)) {
+ decoder->state = FLAC__FILE_DECODER_STREAM_ERROR;
+ return false;
+ }
+ if(sample > decoder->guts->metadata.total_samples) {
+ decoder->state = FLAC__FILE_DECODER_SEEK_ERROR;
+ return false;
+ }
+
+ return seek_to_absolute_sample_(decoder, filesize, sample);
+}
+
+FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, byte buffer[], unsigned *bytes, void *client_data)
+{
+ FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
+ (void)decoder;
+ if(feof(file_decoder->guts->file)) {
+ file_decoder->state = FLAC__FILE_DECODER_END_OF_FILE;
+ return FLAC__STREAM_DECODER_READ_END_OF_STREAM;
+ }
+ else if(*bytes > 0) {
+ size_t bytes_read = fread(buffer, sizeof(byte), *bytes, file_decoder->guts->file);
+ if(bytes_read == 0) {
+ if(feof(file_decoder->guts->file)) {
+ file_decoder->state = FLAC__FILE_DECODER_END_OF_FILE;
+ return FLAC__STREAM_DECODER_READ_END_OF_STREAM;
+ }
+ else
+ return FLAC__STREAM_DECODER_READ_ABORT;
+ }
+ else {
+ *bytes = (unsigned)bytes_read;
+ return FLAC__STREAM_DECODER_READ_CONTINUE;
+ }
+ }
+ else
+ return FLAC__STREAM_DECODER_READ_ABORT; /* abort to avoid a deadlock */
+}
+
+FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__FrameHeader *header, const int32 *buffer[], void *client_data)
+{
+ FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
+ (void)decoder;
+
+ if(file_decoder->state == FLAC__FILE_DECODER_SEEKING) {
+ uint64 this_frame_sample = header->number.sample_number;
+ uint64 next_frame_sample = this_frame_sample + (uint64)header->blocksize;
+ uint64 target_sample = file_decoder->guts->target_sample;
+
+ file_decoder->guts->last_frame_header = *header; /* save the header in the guts */
+ 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 */
+ file_decoder->state = FLAC__FILE_DECODER_OK;
+ /* shift out the samples before target_sample */
+ if(delta > 0) {
+ unsigned channel;
+ const int32 *newbuffer[FLAC__MAX_CHANNELS];
+ for(channel = 0; channel < header->channels; channel++)
+ newbuffer[channel] = buffer[channel] + delta;
+ file_decoder->guts->last_frame_header.blocksize -= delta;
+ file_decoder->guts->last_frame_header.number.sample_number += (uint64)delta;
+ /* write the relevant samples */
+ return file_decoder->guts->write_callback(file_decoder, &file_decoder->guts->last_frame_header, newbuffer, file_decoder->guts->client_data);
+ }
+ else {
+ /* write the relevant samples */
+ return file_decoder->guts->write_callback(file_decoder, header, buffer, file_decoder->guts->client_data);
+ }
+ }
+ else {
+ return FLAC__STREAM_DECODER_WRITE_CONTINUE;
+ }
+ }
+ else {
+ return file_decoder->guts->write_callback(file_decoder, header, buffer, file_decoder->guts->client_data);
+ }
+}
+
+void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data)
+{
+ FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
+ (void)decoder;
+
+ if(metadata->type == FLAC__METADATA_TYPE_ENCODING)
+ file_decoder->guts->metadata = metadata->data.encoding;
+ if(file_decoder->state != FLAC__FILE_DECODER_SEEKING)
+ file_decoder->guts->metadata_callback(file_decoder, metadata, file_decoder->guts->client_data);
+}
+
+void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
+{
+ FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data;
+ (void)decoder;
+
+ if(file_decoder->state != FLAC__FILE_DECODER_SEEKING)
+ file_decoder->guts->error_callback(file_decoder, status, file_decoder->guts->client_data);
+}
+
+bool seek_to_absolute_sample_(FLAC__FileDecoder *decoder, long filesize, uint64 target_sample)
+{
+ long l, r, pos, last_pos = -1;
+ unsigned approx_bytes_per_frame;
+ uint64 last_frame_sample = 0xffffffffffffffff;
+ bool needs_seek;
+ const bool is_variable_blocksize_stream = (decoder->guts->metadata.min_blocksize != decoder->guts->metadata.max_blocksize);
+
+ if(!is_variable_blocksize_stream) {
+ /* we are just guessing here, but we want to guess high, not low */
+ /* note there are no () around 'decoder->guts->metadata.bits_per_sample/8' to keep precision up since it's an integer calulation */
+ approx_bytes_per_frame = decoder->guts->metadata.min_blocksize * decoder->guts->metadata.channels * decoder->guts->metadata.bits_per_sample/8 + 64;
+ }
+ else
+ approx_bytes_per_frame = 1152 * decoder->guts->metadata.channels * decoder->guts->metadata.bits_per_sample/8 + 64;
+
+ /* Now we need to use the metadata and the filelength to search to the frame with the correct sample */
+ if(-1 == (l = ftell(decoder->guts->file))) {
+ decoder->state = FLAC__FILE_DECODER_SEEK_ERROR;
+ return false;
+ }
+ l -= FLAC__stream_decoder_input_bytes_unconsumed(decoder->guts->stream);
+#ifdef _MSC_VER
+ /* with VC++ you have to spoon feed it the casting */
+ pos = l + (long)((double)(int64)target_sample / (double)(int64)decoder->guts->metadata.total_samples * (double)(filesize-l+1)) - approx_bytes_per_frame;
+#else
+ pos = l + (long)((double)target_sample / (double)decoder->guts->metadata.total_samples * (double)(filesize-l+1)) - approx_bytes_per_frame;
+#endif
+ r = filesize - ((decoder->guts->metadata.channels * decoder->guts->metadata.bits_per_sample * FLAC__MAX_BLOCK_SIZE) / 8 + 64);
+ if(pos >= r)
+ pos = r-1;
+ if(pos < l)
+ pos = l;
+ needs_seek = true;
+
+ decoder->guts->target_sample = target_sample;
+ while(1) {
+ if(needs_seek) {
+ if(-1 == fseek(decoder->guts->file, pos, SEEK_SET)) {
+ decoder->state = FLAC__FILE_DECODER_SEEK_ERROR;
+ return false;
+ }
+ if(!FLAC__stream_decoder_flush(decoder->guts->stream)) {
+ decoder->state = FLAC__FILE_DECODER_STREAM_ERROR;
+ return false;
+ }
+ }
+ if(!FLAC__stream_decoder_process_one_frame(decoder->guts->stream)) {
+ decoder->state = FLAC__FILE_DECODER_SEEK_ERROR;
+ return false;
+ }
+ /* our write callback will change the state when it gets to the target frame */
+ if(decoder->state != FLAC__FILE_DECODER_SEEKING) {
+ break;
+ }
+ else { /* we need to narrow the search */
+ uint64 this_frame_sample = decoder->guts->last_frame_header.number.sample_number;
+ if(this_frame_sample == last_frame_sample) {
+ /* our last move backwards wasn't big enough */
+ pos -= (last_pos - pos);
+ needs_seek = true;
+ }
+ else {
+ if(target_sample < this_frame_sample) {
+ last_pos = pos;
+ approx_bytes_per_frame = decoder->guts->last_frame_header.blocksize * decoder->guts->last_frame_header.channels * decoder->guts->last_frame_header.bits_per_sample/8 + 64;
+ pos -= approx_bytes_per_frame;
+ needs_seek = true;
+ }
+ else {
+ last_pos = pos;
+ if(-1 == (pos = ftell(decoder->guts->file))) {
+ decoder->state = FLAC__FILE_DECODER_SEEK_ERROR;
+ return false;
+ }
+ pos -= FLAC__stream_decoder_input_bytes_unconsumed(decoder->guts->stream);
+ needs_seek = false;
+ }
+ }
+ if(pos < l)
+ pos = l;
+ last_frame_sample = this_frame_sample;
+ }
+ }
+
+ return true;
+}
diff --git a/src/libFLAC/fixed.c b/src/libFLAC/fixed.c
new file mode 100644
index 0000000..1b762bc
--- /dev/null
+++ b/src/libFLAC/fixed.c
@@ -0,0 +1,159 @@
+/* libFLAC - Free Lossless Audio Coder library
+ * Copyright (C) 2000 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <assert.h>
+#include <math.h>
+#include "private/fixed.h"
+
+#ifndef M_LN2
+/* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */
+#define M_LN2 0.69314718055994530942
+#endif
+
+#ifdef min
+#undef min
+#endif
+#define min(x,y) ((x) < (y)? (x) : (y))
+
+#ifdef local_abs
+#undef local_abs
+#endif
+#define local_abs(x) ((x)<0? -(x) : (x))
+
+unsigned FLAC__fixed_compute_best_predictor(const int32 data[], unsigned data_len, real residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
+{
+ int32 last_error_0 = data[-1];
+ int32 last_error_1 = data[-1] - data[-2];
+ int32 last_error_2 = last_error_1 - (data[-2] - data[-3]);
+ int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]);
+ int32 error_0, error_1, error_2, error_3, error_4;
+ int32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0;
+ unsigned i, order;
+
+ for(i = 0; i < data_len; i++) {
+ error_0 = data[i] ; total_error_0 += local_abs(error_0);
+ error_1 = error_0 - last_error_0; total_error_1 += local_abs(error_1);
+ error_2 = error_1 - last_error_1; total_error_2 += local_abs(error_2);
+ error_3 = error_2 - last_error_2; total_error_3 += local_abs(error_3);
+ error_4 = error_3 - last_error_3; total_error_4 += local_abs(error_4);
+
+ last_error_0 = error_0;
+ last_error_1 = error_1;
+ last_error_2 = error_2;
+ last_error_3 = error_3;
+ }
+
+ if(total_error_0 < min(min(min(total_error_1, total_error_2), total_error_3), total_error_4))
+ order = 0;
+ else if(total_error_1 < min(min(total_error_2, total_error_3), total_error_4))
+ order = 1;
+ else if(total_error_2 < min(total_error_3, total_error_4))
+ order = 2;
+ else if(total_error_3 < total_error_4)
+ order = 3;
+ else
+ order = 4;
+
+ /* Estimate the expected number of bits per residual signal sample. */
+ /* 'total_error*' is linearly related to the variance of the residual */
+ /* signal, so we use it directly to compute E(|x|) */
+ residual_bits_per_sample[0] = (real)((total_error_0 > 0 && data_len > 0) ? log(M_LN2 * total_error_0 / (real) data_len) / M_LN2 : 0.0);
+ residual_bits_per_sample[1] = (real)((total_error_1 > 0 && data_len > 0) ? log(M_LN2 * total_error_1 / (real) data_len) / M_LN2 : 0.0);
+ residual_bits_per_sample[2] = (real)((total_error_2 > 0 && data_len > 0) ? log(M_LN2 * total_error_2 / (real) data_len) / M_LN2 : 0.0);
+ residual_bits_per_sample[3] = (real)((total_error_3 > 0 && data_len > 0) ? log(M_LN2 * total_error_3 / (real) data_len) / M_LN2 : 0.0);
+ residual_bits_per_sample[4] = (real)((total_error_4 > 0 && data_len > 0) ? log(M_LN2 * total_error_4 / (real) data_len) / M_LN2 : 0.0);
+
+ return order;
+}
+
+void FLAC__fixed_compute_residual(const int32 data[], unsigned data_len, unsigned order, int32 residual[])
+{
+ unsigned i;
+
+ switch(order) {
+ case 0:
+ for(i = 0; i < data_len; i++) {
+ residual[i] = data[i];
+ }
+ break;
+ case 1:
+ for(i = 0; i < data_len; i++) {
+ residual[i] = data[i] - data[i-1];
+ }
+ break;
+ case 2:
+ for(i = 0; i < data_len; i++) {
+ /* == data[i] - 2*data[i-1] + data[i-2] */
+ residual[i] = data[i] - (data[i-1] << 1) + data[i-2];
+ }
+ break;
+ case 3:
+ for(i = 0; i < data_len; i++) {
+ /* == data[i] - 3*data[i-1] + 3*data[i-2] - data[i-3] */
+ residual[i] = data[i] - (((data[i-1]-data[i-2])<<1) + (data[i-1]-data[i-2])) - data[i-3];
+ }
+ break;
+ case 4:
+ for(i = 0; i < data_len; i++) {
+ /* == data[i] - 4*data[i-1] + 6*data[i-2] - 4*data[i-3] + data[i-4] */
+ residual[i] = data[i] - ((data[i-1]+data[i-3])<<2) + ((data[i-2]<<2) + (data[i-2]<<1)) + data[i-4];
+ }
+ break;
+ default:
+ assert(0);
+ }
+}
+
+void FLAC__fixed_restore_signal(const int32 residual[], unsigned data_len, unsigned order, int32 data[])
+{
+ unsigned i;
+
+ switch(order) {
+ case 0:
+ for(i = 0; i < data_len; i++) {
+ data[i] = residual[i];
+ }
+ break;
+ case 1:
+ for(i = 0; i < data_len; i++) {
+ data[i] = residual[i] + data[i-1];
+ }
+ break;
+ case 2:
+ for(i = 0; i < data_len; i++) {
+ /* == residual[i] + 2*data[i-1] - data[i-2] */
+ data[i] = residual[i] + (data[i-1]<<1) - data[i-2];
+ }
+ break;
+ case 3:
+ for(i = 0; i < data_len; i++) {
+ /* residual[i] + 3*data[i-1] - 3*data[i-2]) + data[i-3] */
+ data[i] = residual[i] + (((data[i-1]-data[i-2])<<1) + (data[i-1]-data[i-2])) + data[i-3];
+ }
+ break;
+ case 4:
+ for(i = 0; i < data_len; i++) {
+ /* == residual[i] + 4*data[i-1] - 6*data[i-2] + 4*data[i-3] - data[i-4] */
+ data[i] = residual[i] + ((data[i-1]+data[i-3])<<2) - ((data[i-2]<<2) + (data[i-2]<<1)) - data[i-4];
+ }
+ break;
+ default:
+ assert(0);
+ }
+}
diff --git a/src/libFLAC/format.c b/src/libFLAC/format.c
new file mode 100644
index 0000000..ed20941
--- /dev/null
+++ b/src/libFLAC/format.c
@@ -0,0 +1,66 @@
+/* libFLAC - Free Lossless Audio Coder library
+ * Copyright (C) 2000 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include "FLAC/format.h"
+
+const unsigned FLAC__MAJOR_VERSION = 0;
+const unsigned FLAC__MINOR_VERSION = 2;
+
+const byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };
+const unsigned FLAC__STREAM_SYNC = 0x664C6143;
+const unsigned FLAC__STREAM_SYNC_LEN = 32; /* bits */;
+
+const unsigned FLAC__STREAM_METADATA_ENCODING_MIN_BLOCK_SIZE_LEN = 16; /* bits */
+const unsigned FLAC__STREAM_METADATA_ENCODING_MAX_BLOCK_SIZE_LEN = 16; /* bits */
+const unsigned FLAC__STREAM_METADATA_ENCODING_MIN_FRAME_SIZE_LEN = 24; /* bits */
+const unsigned FLAC__STREAM_METADATA_ENCODING_MAX_FRAME_SIZE_LEN = 24; /* bits */
+const unsigned FLAC__STREAM_METADATA_ENCODING_SAMPLE_RATE_LEN = 20; /* bits */
+const unsigned FLAC__STREAM_METADATA_ENCODING_CHANNELS_LEN = 3; /* bits */
+const unsigned FLAC__STREAM_METADATA_ENCODING_BITS_PER_SAMPLE_LEN = 5; /* bits */
+const unsigned FLAC__STREAM_METADATA_ENCODING_TOTAL_SAMPLES_LEN = 36; /* bits */
+const unsigned FLAC__STREAM_METADATA_ENCODING_LENGTH = 18; /* bytes */
+
+const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN = 1; /* bits */
+const unsigned FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */
+const unsigned FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */
+
+const unsigned FLAC__FRAME_HEADER_SYNC = 0x1fe;
+const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 9; /* bits */
+const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 3; /* bits */
+const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */
+const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */
+const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */
+const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */
+const unsigned FLAC__FRAME_HEADER_CRC8_LEN = 8; /* bits */
+
+const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */
+const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */
+const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */
+
+const unsigned FLAC__SUBFRAME_HEADER_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */
+const unsigned FLAC__SUBFRAME_HEADER_LPC_QLP_SHIFT_LEN = 5; /* bits */
+const unsigned FLAC__SUBFRAME_HEADER_LPC_RICE_PARAMETER_LEN = 4; /* bits */
+
+const unsigned FLAC__SUBFRAME_HEADER_TYPE_CONSTANT = 0x00;
+const unsigned FLAC__SUBFRAME_HEADER_TYPE_VERBATIM = 0x02;
+const unsigned FLAC__SUBFRAME_HEADER_TYPE_FIXED = 0x10;
+const unsigned FLAC__SUBFRAME_HEADER_TYPE_LPC = 0x40;
+const unsigned FLAC__SUBFRAME_HEADER_TYPE_LEN = 8; /* bits */
diff --git a/src/libFLAC/include/private/all.h b/src/libFLAC/include/private/all.h
new file mode 100644
index 0000000..b05a4b1
--- /dev/null
+++ b/src/libFLAC/include/private/all.h
@@ -0,0 +1,29 @@
+/* libFLAC - Free Lossless Audio Coder library
+ * Copyright (C) 2000 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef FLAC__PRIVATE__ALL_H
+#define FLAC__PRIVATE__ALL_H
+
+#include "bitbuffer.h"
+#include "crc.h"
+#include "encoder_framing.h"
+#include "fixed.h"
+#include "lpc.h"
+
+#endif
diff --git a/src/libFLAC/include/private/bitbuffer.h b/src/libFLAC/include/private/bitbuffer.h
new file mode 100644
index 0000000..192b6c9
--- /dev/null
+++ b/src/libFLAC/include/private/bitbuffer.h
@@ -0,0 +1,64 @@
+/* libFLAC - Free Lossless Audio Coder library
+ * Copyright (C) 2000 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef FLAC__PRIVATE__BITBUFFER_H
+#define FLAC__PRIVATE__BITBUFFER_H
+
+#include <stdio.h> /* for FILE */
+#include "FLAC/ordinals.h"
+
+typedef struct {
+ byte *buffer;
+ unsigned capacity; /* in bytes */
+ unsigned bytes, bits;
+ unsigned total_bits; /* must always == 8*bytes+bits */
+ unsigned consumed_bytes, consumed_bits;
+ unsigned total_consumed_bits; /* must always == 8*consumed_bytes+consumed_bits */
+} FLAC__BitBuffer;
+
+void FLAC__bitbuffer_init(FLAC__BitBuffer *bb);
+bool FLAC__bitbuffer_init_from(FLAC__BitBuffer *bb, const byte buffer[], unsigned bytes);
+bool FLAC__bitbuffer_concatenate_aligned(FLAC__BitBuffer *dest, const FLAC__BitBuffer *src);
+void FLAC__bitbuffer_free(FLAC__BitBuffer *bb); /* does not 'free(buffer)' */
+bool FLAC__bitbuffer_clear(FLAC__BitBuffer *bb);
+bool FLAC__bitbuffer_clone(FLAC__BitBuffer *dest, const FLAC__BitBuffer *src);
+bool FLAC__bitbuffer_write_zeroes(FLAC__BitBuffer *bb, unsigned bits);
+bool FLAC__bitbuffer_write_raw_uint32(FLAC__BitBuffer *bb, uint32 val, unsigned bits);
+bool FLAC__bitbuffer_write_raw_int32(FLAC__BitBuffer *bb, int32 val, unsigned bits);
+bool FLAC__bitbuffer_write_raw_uint64(FLAC__BitBuffer *bb, uint64 val, unsigned bits);
+bool FLAC__bitbuffer_write_raw_int64(FLAC__BitBuffer *bb, int64 val, unsigned bits);
+bool FLAC__bitbuffer_write_rice_signed(FLAC__BitBuffer *bb, int val, unsigned parameter);
+bool FLAC__bitbuffer_write_rice_signed_guarded(FLAC__BitBuffer *bb, int val, unsigned parameter, unsigned max_bits, bool *overflow);
+bool FLAC__bitbuffer_write_utf8_uint32(FLAC__BitBuffer *bb, uint32 val);
+bool FLAC__bitbuffer_write_utf8_uint64(FLAC__BitBuffer *bb, uint64 val);
+bool FLAC__bitbuffer_zero_pad_to_byte_boundary(FLAC__BitBuffer *bb);
+bool FLAC__bitbuffer_peek_bit(FLAC__BitBuffer *bb, unsigned *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data);
+bool FLAC__bitbuffer_read_bit(FLAC__BitBuffer *bb, unsigned *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data);
+bool FLAC__bitbuffer_read_bit_to_uint32(FLAC__BitBuffer *bb, uint32 *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data);
+bool FLAC__bitbuffer_read_bit_to_uint64(FLAC__BitBuffer *bb, uint64 *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data);
+bool FLAC__bitbuffer_read_raw_uint32(FLAC__BitBuffer *bb, uint32 *val, unsigned bits, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data);
+bool FLAC__bitbuffer_read_raw_int32(FLAC__BitBuffer *bb, int32 *val, unsigned bits, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data);
+bool FLAC__bitbuffer_read_raw_uint64(FLAC__BitBuffer *bb, uint64 *val, unsigned bits, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data);
+bool FLAC__bitbuffer_read_raw_int64(FLAC__BitBuffer *bb, int64 *val, unsigned bits, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data);
+bool FLAC__bitbuffer_read_rice_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data);
+bool FLAC__bitbuffer_read_utf8_uint32(FLAC__BitBuffer *bb, uint32 *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data, byte *raw, unsigned *rawlen);
+bool FLAC__bitbuffer_read_utf8_uint64(FLAC__BitBuffer *bb, uint64 *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data, byte *raw, unsigned *rawlen);
+void FLAC__bitbuffer_dump(const FLAC__BitBuffer *bb, FILE *out);
+
+#endif
diff --git a/src/libFLAC/include/private/crc.h b/src/libFLAC/include/private/crc.h
new file mode 100644
index 0000000..742d9bc
--- /dev/null
+++ b/src/libFLAC/include/private/crc.h
@@ -0,0 +1,30 @@
+/* libFLAC - Free Lossless Audio Coder library
+ * Copyright (C) 2000 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef FLAC__PRIVATE__CRC_H
+#define FLAC__PRIVATE__CRC_H
+
+#include "FLAC/ordinals.h"
+
+/* 8 bit CRC generator, MSB shifted first
+** polynomial = x^8 + x^2 + x^1 + 1
+*/
+byte FLAC__crc8(const byte *data, const unsigned len);
+
+#endif
diff --git a/src/libFLAC/include/private/encoder_framing.h b/src/libFLAC/include/private/encoder_framing.h
new file mode 100644
index 0000000..bf26649
--- /dev/null
+++ b/src/libFLAC/include/private/encoder_framing.h
@@ -0,0 +1,33 @@
+/* libFLAC - Free Lossless Audio Coder library
+ * Copyright (C) 2000 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef FLAC__PRIVATE__ENCODER_FRAMING_H
+#define FLAC__PRIVATE__ENCODER_FRAMING_H
+
+#include "FLAC/format.h"
+#include "bitbuffer.h"
+
+bool FLAC__add_metadata_block(const FLAC__StreamMetaData *metadata, FLAC__BitBuffer *bb);
+bool FLAC__frame_add_header(const FLAC__FrameHeader *header, bool streamable_subset, bool is_last_block, FLAC__BitBuffer *bb);
+bool FLAC__subframe_add_constant(unsigned bits_per_sample, const FLAC__SubframeHeader *subframe, FLAC__BitBuffer *bb);
+bool FLAC__subframe_add_fixed(const int32 residual[], unsigned residual_samples, unsigned bits_per_sample, const FLAC__SubframeHeader *subframe, FLAC__BitBuffer *bb);
+bool FLAC__subframe_add_lpc(const int32 residual[], unsigned residual_samples, unsigned bits_per_sample, const FLAC__SubframeHeader *subframe, FLAC__BitBuffer *bb);
+bool FLAC__subframe_add_verbatim(const int32 signal[], unsigned samples, unsigned bits_per_sample, FLAC__BitBuffer *bb);
+
+#endif
diff --git a/src/libFLAC/include/private/fixed.h b/src/libFLAC/include/private/fixed.h
new file mode 100644
index 0000000..e018da6
--- /dev/null
+++ b/src/libFLAC/include/private/fixed.h
@@ -0,0 +1,65 @@
+/* libFLAC - Free Lossless Audio Coder library
+ * Copyright (C) 2000 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef FLAC__PRIVATE__FIXED_H
+#define FLAC__PRIVATE__FIXED_H
+
+#include "FLAC/format.h"
+
+/*
+ * FLAC__fixed_compute_best_predictor()
+ * --------------------------------------------------------------------
+ * Compute the best fixed predictor and the expected bits-per-sample
+ * of the residual signal for each order.
+ *
+ * IN data[0,data_len-1]
+ * IN data_len
+ * OUT residual_bits_per_sample[0,FLAC__MAX_FIXED_ORDER]
+ */
+unsigned FLAC__fixed_compute_best_predictor(const int32 data[], unsigned data_len, real residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
+
+/*
+ * FLAC__fixed_compute_residual()
+ * --------------------------------------------------------------------
+ * Compute the residual signal obtained from sutracting the predicted
+ * signal from the original.
+ *
+ * IN data[-order,data_len-1] original signal (NOTE THE INDICES!)
+ * IN data_len length of original signal
+ * IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order
+ * OUT residual[0,data_len-1] residual signal
+ */
+void FLAC__fixed_compute_residual(const int32 data[], unsigned data_len, unsigned order, int32 residual[]);
+
+/*
+ * FLAC__fixed_restore_signal()
+ * --------------------------------------------------------------------
+ * Restore the original signal by summing the residual and the
+ * predictor.
+ *
+ * IN residual[0,data_len-1] residual signal
+ * IN data_len length of original signal
+ * IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order
+ * *** IMPORTANT: the caller must pass in the historical samples:
+ * IN data[-order,-1] previously-reconstructed historical samples
+ * OUT data[0,data_len-1] original signal
+ */
+void FLAC__fixed_restore_signal(const int32 residual[], unsigned data_len, unsigned order, int32 data[]);
+
+#endif
diff --git a/src/libFLAC/include/private/lpc.h b/src/libFLAC/include/private/lpc.h
new file mode 100644
index 0000000..c30871b
--- /dev/null
+++ b/src/libFLAC/include/private/lpc.h
@@ -0,0 +1,142 @@
+/* libFLAC - Free Lossless Audio Coder library
+ * Copyright (C) 2000 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef FLAC__PRIVATE__LPC_H
+#define FLAC__PRIVATE__LPC_H
+
+#include "FLAC/ordinals.h"
+
+#define FLAC__MAX_LPC_ORDER (32u)
+
+/*
+ * FLAC__lpc_compute_autocorrelation()
+ * --------------------------------------------------------------------
+ * Compute the autocorrelation for lags between 0 and lag-1.
+ * Assumes data[] outside of [0,data_len-1] == 0.
+ * Asserts that lag > 0.
+ *
+ * IN data[0,data_len-1]
+ * IN data_len
+ * IN 0 < lag <= data_len
+ * OUT autoc[0,lag-1]
+ */
+void FLAC__lpc_compute_autocorrelation(const real data[], unsigned data_len, unsigned lag, real autoc[]);
+
+/*
+ * FLAC__lpc_compute_lp_coefficients()
+ * --------------------------------------------------------------------
+ * Computes LP coefficients for orders 1..max_order.
+ * Do not call if autoc[0] == 0.0. This means the signal is zero
+ * and there is no point in calculating a predictor.
+ *
+ * IN autoc[0,max_order] autocorrelation values
+ * IN 0 < max_order <= FLAC__MAX_LPC_ORDER max LP order to compute
+ * OUT lp_coeff[0,max_order-1][0,max_order-1] LP coefficients for each order
+ * *** IMPORTANT:
+ * *** lp_coeff[0,max_order-1][max_order,FLAC__MAX_LPC_ORDER-1] are untouched
+ * OUT error[0,max_order-1] error for each order
+ *
+ * Example: if max_order is 9, the LP coefficients for order 9 will be
+ * in lp_coeff[8][0,8], the LP coefficients for order 8 will be
+ * in lp_coeff[7][0,7], etc.
+ */
+void FLAC__lpc_compute_lp_coefficients(const real autoc[], unsigned max_order, real lp_coeff[][FLAC__MAX_LPC_ORDER], real error[]);
+
+/*
+ * FLAC__lpc_quantize_coefficients()
+ * --------------------------------------------------------------------
+ * Quantizes the LP coefficients. NOTE: precision + bits_per_sample
+ * must be less than 32 (sizeof(int32)*8).
+ *
+ * IN lp_coeff[0,order-1] LP coefficients
+ * IN order LP order
+ * IN FLAC__MIN_QLP_COEFF_PRECISION < precision
+ * desired precision (in bits, including sign
+ * bit) of largest coefficient
+ * IN bits_per_sample > 0 bits per sample of the originial signal
+ * OUT qlp_coeff[0,order-1] quantized coefficients
+ * OUT bits # of bits to shift right to get approximated
+ * LP coefficients. NOTE: could be negative,
+ * but |*bits| will always be <= precision
+ * RETURN 0 => quantization OK
+ * 1 => coefficients vary too much to quantize to the desired
+ * precision. 'bits' is unset
+ * 2 => coefficients are all zero, which is bad. 'bits' is unset
+ */
+int FLAC__lpc_quantize_coefficients(const real lp_coeff[], unsigned order, unsigned precision, unsigned bits_per_sample, int32 qlp_coeff[], int *bits);
+
+/*
+ * FLAC__lpc_compute_residual_from_qlp_coefficients()
+ * --------------------------------------------------------------------
+ * Compute the residual signal obtained from sutracting the predicted
+ * signal from the original.
+ *
+ * IN data[-order,data_len-1] original signal (NOTE THE INDICES!)
+ * IN data_len length of original signal
+ * IN qlp_coeff[0,order-1] quantized LP coefficients
+ * IN order > 0 LP order
+ * IN lp_quantization quantization of LP coefficients in bits
+ * OUT residual[0,data_len-1] residual signal
+ */
+void FLAC__lpc_compute_residual_from_qlp_coefficients(const int32 data[], unsigned data_len, const int32 qlp_coeff[], unsigned order, int lp_quantization, int32 residual[]);
+
+/*
+ * FLAC__lpc_restore_signal()
+ * --------------------------------------------------------------------
+ * Restore the original signal by summing the residual and the
+ * predictor.
+ *
+ * IN residual[0,data_len-1] residual signal
+ * IN data_len length of original signal
+ * IN qlp_coeff[0,order-1] quantized LP coefficients
+ * IN order > 0 LP order
+ * IN lp_quantization quantization of LP coefficients in bits
+ * *** IMPORTANT: the caller must pass in the historical samples:
+ * IN data[-order,-1] previously-reconstructed historical samples
+ * OUT data[0,data_len-1] original signal
+ */
+void FLAC__lpc_restore_signal(const int32 residual[], unsigned data_len, const int32 qlp_coeff[], unsigned order, int lp_quantization, int32 data[]);
+
+/*
+ * FLAC__lpc_compute_expected_bits_per_residual_sample()
+ * --------------------------------------------------------------------
+ * Compute the expected number of bits per residual signal sample
+ * based on the LP error (which is related to the residual variance).
+ *
+ * IN lpc_error >= 0.0 error returned from calculating LP coefficients
+ * IN total_samples > 0 # of samples in residual signal
+ * RETURN expected bits per sample
+ */
+real FLAC__lpc_compute_expected_bits_per_residual_sample(real lpc_error, unsigned total_samples);
+
+/*
+ * FLAC__lpc_compute_best_order()
+ * --------------------------------------------------------------------
+ * Compute the best order from the array of signal errors returned
+ * during coefficient computation.
+ *
+ * IN lpc_error[0,max_order-1] >= 0.0 error returned from calculating LP coefficients
+ * IN max_order > 0 max LP order
+ * IN total_samples > 0 # of samples in residual signal
+ * IN bits_per_signal_sample # of bits per sample in the original signal
+ * RETURN [1,max_order] best order
+ */
+unsigned FLAC__lpc_compute_best_order(const real lpc_error[], unsigned max_order, unsigned total_samples, unsigned bits_per_signal_sample);
+
+#endif
diff --git a/src/libFLAC/include/protected/stream_decoder.h b/src/libFLAC/include/protected/stream_decoder.h
new file mode 100644
index 0000000..be6e541
--- /dev/null
+++ b/src/libFLAC/include/protected/stream_decoder.h
@@ -0,0 +1,28 @@
+/* libFLAC - Free Lossless Audio Coder library
+ * Copyright (C) 2000 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef FLAC__PROTECTED__STREAM_DECODER_H
+#define FLAC__PROTECTED__STREAM_DECODER_H
+
+#include "FLAC/stream_decoder.h"
+
+/* only useful to the file_decoder */
+unsigned FLAC__stream_decoder_input_bytes_unconsumed(FLAC__StreamDecoder *decoder);
+
+#endif
diff --git a/src/libFLAC/lpc.c b/src/libFLAC/lpc.c
new file mode 100644
index 0000000..615a734
--- /dev/null
+++ b/src/libFLAC/lpc.c
@@ -0,0 +1,238 @@
+/* libFLAC - Free Lossless Audio Coder library
+ * Copyright (C) 2000 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <assert.h>
+#include <math.h>
+#include <stdio.h>
+#include "FLAC/format.h"
+#include "private/lpc.h"
+
+#ifndef M_LN2
+/* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */
+#define M_LN2 0.69314718055994530942
+#endif
+
+void FLAC__lpc_compute_autocorrelation(const real data[], unsigned data_len, unsigned lag, real autoc[])
+{
+ real d;
+ unsigned i;
+
+ assert(lag > 0);
+ assert(lag <= data_len);
+
+ while(lag--) {
+ for(i = lag, d = 0.0; i < data_len; i++)
+ d += data[i] * data[i - lag];
+ autoc[lag] = d;
+ }
+}
+
+void FLAC__lpc_compute_lp_coefficients(const real autoc[], unsigned max_order, real lp_coeff[][FLAC__MAX_LPC_ORDER], real error[])
+{
+ unsigned i, j;
+ real r, err, ref[FLAC__MAX_LPC_ORDER], lpc[FLAC__MAX_LPC_ORDER];
+
+ assert(0 < max_order);
+ assert(max_order <= FLAC__MAX_LPC_ORDER);
+ assert(autoc[0] != 0.0);
+
+ err = autoc[0];
+
+ for(i = 0; i < max_order; i++) {
+ /* Sum up this iteration's reflection coefficient. */
+ r =- autoc[i+1];
+ for(j = 0; j < i; j++)
+ r -= lpc[j] * autoc[i-j];
+ ref[i] = (r/=err);
+
+ /* Update LPC coefficients and total error. */
+ lpc[i]=r;
+ for(j = 0; j < (i>>1); j++) {
+ real tmp = lpc[j];
+ lpc[j] += r * lpc[i-1-j];
+ lpc[i-1-j] += r * tmp;
+ }
+ if(i & 1)
+ lpc[j] += lpc[j] * r;
+
+ err *= (1.0 - r * r);
+
+ /* save this order */
+ for(j = 0; j <= i; j++)
+ lp_coeff[i][j] = -lpc[j]; /* N.B. why do we have to negate here? */
+ error[i] = err;
+ }
+}
+
+int FLAC__lpc_quantize_coefficients(const real lp_coeff[], unsigned order, unsigned precision, unsigned bits_per_sample, int32 qlp_coeff[], int *bits)
+{
+ unsigned i;
+ real d, rprecision = (real)precision, maxlog = -1e99, minlog = 1e99;
+
+ assert(bits_per_sample > 0);
+ assert(bits_per_sample <= sizeof(int32)*8);
+ assert(precision >= FLAC__MIN_QLP_COEFF_PRECISION);
+ assert(precision + bits_per_sample < sizeof(int32)*8);
+#ifdef NDEBUG
+ (void)bits_per_sample; /* silence compiler warning about unused parameter */
+#endif
+
+ for(i = 0; i < order; i++) {
+ if(lp_coeff[i] == 0.0)
+ continue;
+ d = log(fabs(lp_coeff[i])) / M_LN2;
+ if(d > maxlog)
+ maxlog = d;
+ if(d < minlog)
+ minlog = d;
+ }
+ if(maxlog < minlog)
+ return 2;
+ else if(maxlog - minlog >= (real)(precision+1))
+ return 1;
+ else if((rprecision-1.0) - maxlog >= (real)(precision+1))
+ rprecision = (real)precision + maxlog + 1.0;
+
+ *bits = (int)floor((rprecision-1.0) - maxlog); /* '-1' because bits can be negative and the sign bit costs 1 bit */
+ if(*bits > (int)precision || *bits <= -(int)precision) {
+ fprintf(stderr, "@@@ FLAC__lpc_quantize_coefficients(): ERROR: *bits=%d, maxlog=%f, minlog=%f, precision=%u, rprecision=%f\n", *bits, maxlog, minlog, precision, rprecision);
+ return 1;
+ }
+
+ if(*bits != 0) { /* just to avoid wasting time... */
+ for(i = 0; i < order; i++)
+ qlp_coeff[i] = (int32)floor(lp_coeff[i] * (real)(1 << *bits));
+ }
+ return 0;
+}
+
+void FLAC__lpc_compute_residual_from_qlp_coefficients(const int32 data[], unsigned data_len, const int32 qlp_coeff[], unsigned order, int lp_quantization, int32 residual[])
+{
+#ifdef FLAC_OVERFLOW_DETECT
+ int64 sumo;
+#endif
+ unsigned i, j;
+ int32 sum;
+ const int32 *history;
+
+#ifdef FLAC_OVERFLOW_DETECT_VERBOSE
+ fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization);
+ for(i=0;i<order;i++)
+ fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]);
+ fprintf(stderr,"\n");
+#endif
+ assert(order > 0);
+
+ for(i = 0; i < data_len; i++) {
+#ifdef FLAC_OVERFLOW_DETECT
+ sumo = 0;
+#endif
+ sum = 0;
+ history = data;
+ for(j = 0; j < order; j++) {
+ sum += qlp_coeff[j] * (*(--history));
+#ifdef FLAC_OVERFLOW_DETECT
+ sumo += (int64)qlp_coeff[j] * (int64)(*history);
+ if(sumo > 2147483647ll || sumo < -2147483648ll)
+ fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, sumo=%lld\n",sumo);
+#endif
+ }
+ *(residual++) = *(data++) - (sum >> lp_quantization);
+ }
+
+ /* Here's a slightly slower but clearer version:
+ for(i = 0; i < data_len; i++) {
+ sum = 0;
+ history = &(data[i]);
+ for(j = 0; j < order; j++)
+ sum += qlp_coeff[j] * (*(--history));
+ residual[i] = data[i] - (sum >> lp_quantization);
+ }
+ */
+}
+
+void FLAC__lpc_restore_signal(const int32 residual[], unsigned data_len, const int32 qlp_coeff[], unsigned order, int lp_quantization, int32 data[])
+{
+#ifdef FLAC_OVERFLOW_DETECT
+ int64 sumo;
+#endif
+ unsigned i, j;
+ int32 sum, *history;
+
+#ifdef FLAC_OVERFLOW_DETECT_VERBOSE
+ fprintf(stderr,"FLAC__lpc_restore_signal: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization);
+ for(i=0;i<order;i++)
+ fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]);
+ fprintf(stderr,"\n");
+#endif
+ assert(order > 0);
+
+ for(i = 0; i < data_len; i++) {
+#ifdef FLAC_OVERFLOW_DETECT
+ sumo = 0;
+#endif
+ sum = 0;
+ history = data+i;
+ for(j = 0; j < order; j++) {
+ sum += qlp_coeff[j] * (*(--history));
+#ifdef FLAC_OVERFLOW_DETECT
+ sumo += (int64)qlp_coeff[j] * (int64)(*history);
+ if(sumo > 2147483647ll || sumo < -2147483648ll)
+ fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, sumo=%lld\n",sumo);
+#endif
+ }
+ data[i] = residual[i] + (sum >> lp_quantization);
+ }
+}
+
+real FLAC__lpc_compute_expected_bits_per_residual_sample(real lpc_error, unsigned total_samples)
+{
+ real escale;
+
+ assert(lpc_error >= 0.0); /* the error can never be negative */
+ assert(total_samples > 0);
+
+ escale = 0.5 * M_LN2 * M_LN2 / (real)total_samples;
+
+ if(lpc_error > 0.0)
+ return 0.5 * log(escale * lpc_error) / M_LN2;
+ else
+ return 0.0;
+}
+
+unsigned FLAC__lpc_compute_best_order(const real lpc_error[], unsigned max_order, unsigned total_samples, unsigned bits_per_signal_sample)
+{
+ unsigned order, best_order;
+ real best_bits, tmp_bits;
+
+ assert(max_order > 0);
+
+ best_order = 0;
+ best_bits = FLAC__lpc_compute_expected_bits_per_residual_sample(lpc_error[0], total_samples) * (real)total_samples;
+
+ for(order = 1; order < max_order; order++) {
+ tmp_bits = FLAC__lpc_compute_expected_bits_per_residual_sample(lpc_error[order], total_samples) * (real)(total_samples - order) + (real)(order * bits_per_signal_sample);
+ if(tmp_bits < best_bits) {
+ best_order = order;
+ best_bits = tmp_bits;
+ }
+ }
+
+ return best_order+1; /* +1 since index of lpc_error[] is order-1 */
+}
diff --git a/src/libFLAC/stream_decoder.c b/src/libFLAC/stream_decoder.c
new file mode 100644
index 0000000..eaf35bf
--- /dev/null
+++ b/src/libFLAC/stream_decoder.c
@@ -0,0 +1,1114 @@
+/* libFLAC - Free Lossless Audio Coder library
+ * Copyright (C) 2000 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h> /* for malloc() */
+#include "FLAC/stream_decoder.h"
+#include "private/bitbuffer.h"
+#include "private/crc.h"
+#include "private/fixed.h"
+#include "private/lpc.h"
+
+typedef struct FLAC__StreamDecoderPrivate {
+ FLAC__StreamDecoderReadStatus (*read_callback)(const FLAC__StreamDecoder *decoder, byte buffer[], unsigned *bytes, void *client_data);
+ FLAC__StreamDecoderWriteStatus (*write_callback)(const FLAC__StreamDecoder *decoder, const FLAC__FrameHeader *header, const int32 *buffer[], void *client_data);
+ void (*metadata_callback)(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);
+ void (*error_callback)(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
+ void *client_data;
+ FLAC__BitBuffer input;
+ int32 *output[FLAC__MAX_CHANNELS];
+ int32 *residual;
+ unsigned output_capacity;
+ uint32 last_frame_number;
+ uint64 samples_decoded;
+ bool has_stream_header;
+ FLAC__StreamMetaData stream_header;
+ FLAC__FrameHeader frame_header;
+} FLAC__StreamDecoderPrivate;
+
+static byte ID3V2_TAG_[3] = { 'I', 'D', '3' };
+
+static bool stream_decoder_allocate_output(FLAC__StreamDecoder *decoder, unsigned size);
+static bool stream_decoder_find_metadata_(FLAC__StreamDecoder *decoder);
+static bool stream_decoder_read_metadata_(FLAC__StreamDecoder *decoder);
+static bool stream_decoder_skip_id3v2_tag_(FLAC__StreamDecoder *decoder);
+static bool stream_decoder_frame_sync_(FLAC__StreamDecoder *decoder);
+static bool stream_decoder_read_frame_(FLAC__StreamDecoder *decoder, bool *got_a_frame);
+static bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder);
+static bool stream_decoder_read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel);
+static bool stream_decoder_read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel);
+static bool stream_decoder_read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, const unsigned order);
+static bool stream_decoder_read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, const unsigned order);
+static bool stream_decoder_read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel);
+static bool stream_decoder_read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order);
+static bool stream_decoder_read_zero_padding_(FLAC__StreamDecoder *decoder);
+static bool read_callback_(byte buffer[], unsigned *bytes, void *client_data);
+
+FLAC__StreamDecoder *FLAC__stream_decoder_get_new_instance()
+{
+ FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder*)malloc(sizeof(FLAC__StreamDecoder));
+ if(decoder != 0) {
+ decoder->state = FLAC__STREAM_DECODER_UNINITIALIZED;
+ decoder->guts = 0;
+ }
+ return decoder;
+}
+
+void FLAC__stream_decoder_free_instance(FLAC__StreamDecoder *decoder)
+{
+ free(decoder);
+}
+
+FLAC__StreamDecoderState FLAC__stream_decoder_init(
+ FLAC__StreamDecoder *decoder,
+ FLAC__StreamDecoderReadStatus (*read_callback)(const FLAC__StreamDecoder *decoder, byte buffer[], unsigned *bytes, void *client_data),
+ FLAC__StreamDecoderWriteStatus (*write_callback)(const FLAC__StreamDecoder *decoder, const FLAC__FrameHeader *header, const int32 *buffer[], void *client_data),
+ void (*metadata_callback)(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data),
+ void (*error_callback)(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data),
+ void *client_data
+)
+{
+ unsigned i;
+
+ assert(sizeof(int) >= 4); /* we want to die right away if this is not true */
+ assert(decoder != 0);
+ assert(read_callback != 0);
+ assert(write_callback != 0);
+ assert(metadata_callback != 0);
+ assert(error_callback != 0);
+ assert(decoder->state == FLAC__STREAM_DECODER_UNINITIALIZED);
+ assert(decoder->guts == 0);
+
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA;
+
+ decoder->guts = (FLAC__StreamDecoderPrivate*)malloc(sizeof(FLAC__StreamDecoderPrivate));
+ if(decoder->guts == 0)
+ return decoder->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
+
+ decoder->guts->read_callback = read_callback;
+ decoder->guts->write_callback = write_callback;
+ decoder->guts->metadata_callback = metadata_callback;
+ decoder->guts->error_callback = error_callback;
+ decoder->guts->client_data = client_data;
+
+ FLAC__bitbuffer_init(&decoder->guts->input);
+
+ for(i = 0; i < FLAC__MAX_CHANNELS; i++)
+ decoder->guts->output[i] = 0;
+ decoder->guts->residual = 0;
+
+ decoder->guts->output_capacity = 0;
+ decoder->guts->last_frame_number = 0;
+ decoder->guts->samples_decoded = 0;
+ decoder->guts->has_stream_header = false;
+
+ return decoder->state;
+}
+
+void FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder)
+{
+ unsigned i;
+ assert(decoder != 0);
+ if(decoder->state == FLAC__STREAM_DECODER_UNINITIALIZED)
+ return;
+ if(decoder->guts != 0) {
+ FLAC__bitbuffer_free(&decoder->guts->input);
+ for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
+ if(decoder->guts->output[i] != 0) {
+ free(decoder->guts->output[i]);
+ decoder->guts->output[i] = 0;
+ }
+ }
+ if(decoder->guts->residual != 0) {
+ free(decoder->guts->residual);
+ decoder->guts->residual = 0;
+ }
+ free(decoder->guts);
+ decoder->guts = 0;
+ }
+ decoder->state = FLAC__STREAM_DECODER_UNINITIALIZED;
+}
+
+bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder)
+{
+ assert(decoder != 0);
+
+ if(!FLAC__bitbuffer_clear(&decoder->guts->input)) {
+ decoder->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
+ return false;
+ }
+
+ return true;
+}
+
+bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder)
+{
+ assert(decoder != 0);
+
+ if(!FLAC__stream_decoder_flush(decoder)) {
+ decoder->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
+ return false;
+ }
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA;
+
+ return true;
+}
+
+bool FLAC__stream_decoder_process_whole_stream(FLAC__StreamDecoder *decoder)
+{
+ bool dummy;
+ assert(decoder != 0);
+
+ if(decoder->state == FLAC__STREAM_DECODER_END_OF_STREAM)
+ return true;
+
+ assert(decoder->state == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA);
+
+ if(!FLAC__stream_decoder_reset(decoder)) {
+ decoder->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
+ return false;
+ }
+
+ while(1) {
+ switch(decoder->state) {
+ case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
+ if(!stream_decoder_find_metadata_(decoder))
+ return false; /* above function sets the status for us */
+ break;
+ case FLAC__STREAM_DECODER_READ_METADATA:
+ if(!stream_decoder_read_metadata_(decoder))
+ return false; /* above function sets the status for us */
+ break;
+ case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
+ if(!stream_decoder_frame_sync_(decoder))
+ return true; /* above function sets the status for us */
+ break;
+ case FLAC__STREAM_DECODER_READ_FRAME:
+ if(!stream_decoder_read_frame_(decoder, &dummy))
+ return false; /* above function sets the status for us */
+ break;
+ case FLAC__STREAM_DECODER_END_OF_STREAM:
+ return true;
+ default:
+ assert(0);
+ }
+ }
+}
+
+bool FLAC__stream_decoder_process_metadata(FLAC__StreamDecoder *decoder)
+{
+ assert(decoder != 0);
+
+ if(decoder->state == FLAC__STREAM_DECODER_END_OF_STREAM)
+ return true;
+
+ assert(decoder->state == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA);
+
+ if(!FLAC__stream_decoder_reset(decoder)) {
+ decoder->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
+ return false;
+ }
+
+ while(1) {
+ switch(decoder->state) {
+ case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
+ if(!stream_decoder_find_metadata_(decoder))
+ return false; /* above function sets the status for us */
+ break;
+ case FLAC__STREAM_DECODER_READ_METADATA:
+ if(!stream_decoder_read_metadata_(decoder))
+ return false; /* above function sets the status for us */
+ break;
+ case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
+ return true;
+ break;
+ case FLAC__STREAM_DECODER_END_OF_STREAM:
+ return true;
+ default:
+ assert(0);
+ }
+ }
+}
+
+bool FLAC__stream_decoder_process_one_frame(FLAC__StreamDecoder *decoder)
+{
+ bool got_a_frame;
+ assert(decoder != 0);
+
+ if(decoder->state == FLAC__STREAM_DECODER_END_OF_STREAM)
+ return true;
+
+ assert(decoder->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC);
+
+ while(1) {
+ switch(decoder->state) {
+ case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
+ if(!stream_decoder_frame_sync_(decoder))
+ return true; /* above function sets the status for us */
+ break;
+ case FLAC__STREAM_DECODER_READ_FRAME:
+ if(!stream_decoder_read_frame_(decoder, &got_a_frame))
+ return false; /* above function sets the status for us */
+ if(got_a_frame)
+ return true; /* above function sets the status for us */
+ break;
+ case FLAC__STREAM_DECODER_END_OF_STREAM:
+ return true;
+ default:
+ assert(0);
+ }
+ }
+}
+
+bool FLAC__stream_decoder_process_remaining_frames(FLAC__StreamDecoder *decoder)
+{
+ bool dummy;
+ assert(decoder != 0);
+
+ if(decoder->state == FLAC__STREAM_DECODER_END_OF_STREAM)
+ return true;
+
+ assert(decoder->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC);
+
+ while(1) {
+ switch(decoder->state) {
+ case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
+ if(!stream_decoder_frame_sync_(decoder))
+ return true; /* above function sets the status for us */
+ break;
+ case FLAC__STREAM_DECODER_READ_FRAME:
+ if(!stream_decoder_read_frame_(decoder, &dummy))
+ return false; /* above function sets the status for us */
+ break;
+ case FLAC__STREAM_DECODER_END_OF_STREAM:
+ return true;
+ default:
+ assert(0);
+ }
+ }
+}
+
+unsigned FLAC__stream_decoder_input_bytes_unconsumed(FLAC__StreamDecoder *decoder)
+{
+ assert(decoder != 0);
+ return decoder->guts->input.bytes - decoder->guts->input.consumed_bytes;
+}
+
+bool stream_decoder_allocate_output(FLAC__StreamDecoder *decoder, unsigned size)
+{
+ unsigned i;
+ int32 *tmp;
+
+ if(size <= decoder->guts->output_capacity)
+ return true;
+
+ for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
+ if(decoder->guts->output[i] != 0) {
+ free(decoder->guts->output[i]);
+ decoder->guts->output[i] = 0;
+ }
+ }
+ if(decoder->guts->residual != 0) {
+ free(decoder->guts->residual);
+ decoder->guts->residual = 0;
+ }
+
+ for(i = 0; i < decoder->guts->frame_header.channels; i++) {
+ tmp = (int32*)malloc(sizeof(int32)*size);
+ if(tmp == 0) {
+ decoder->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
+ return false;
+ }
+ decoder->guts->output[i] = tmp;
+ }
+ tmp = (int32*)malloc(sizeof(int32)*size);
+ if(tmp == 0) {
+ decoder->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
+ return false;
+ }
+ decoder->guts->residual = tmp;
+
+ decoder->guts->output_capacity = size;
+
+ return true;
+}
+
+bool stream_decoder_find_metadata_(FLAC__StreamDecoder *decoder)
+{
+ uint32 x;
+ unsigned i, id;
+ bool first = 1;
+
+ assert(decoder->guts->input.consumed_bits == 0); /* make sure we're byte aligned */
+
+ for(i = id = 0; i < 4; ) {
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ if(x == FLAC__STREAM_SYNC_STRING[i]) {
+ first = 1;
+ i++;
+ id = 0;
+ continue;
+ }
+ if(x == ID3V2_TAG_[id]) {
+ id++;
+ i = 0;
+ if(id == 3) {
+ if(!stream_decoder_skip_id3v2_tag_(decoder))
+ return false; /* the read_callback_ sets the state for us */
+ }
+ continue;
+ }
+ if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
+ unsigned y;
+ if(!FLAC__bitbuffer_peek_bit(&decoder->guts->input, &y, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ if(!y) { /* MAGIC NUMBER for the last sync bit */
+ decoder->state = FLAC__STREAM_DECODER_READ_FRAME;
+ return true;
+ }
+ }
+ i = 0;
+ if(first) {
+ decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
+ first = 0;
+ }
+ }
+
+ decoder->state = FLAC__STREAM_DECODER_READ_METADATA;
+ return true;
+}
+
+bool stream_decoder_read_metadata_(FLAC__StreamDecoder *decoder)
+{
+ uint32 i, x, last_block, type, length;
+
+ assert(decoder->guts->input.consumed_bits == 0); /* make sure we're byte aligned */
+
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &last_block, FLAC__STREAM_METADATA_IS_LAST_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &type, FLAC__STREAM_METADATA_TYPE_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &length, FLAC__STREAM_METADATA_LENGTH_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ if(type == FLAC__METADATA_TYPE_ENCODING) {
+ decoder->guts->stream_header.type = type;
+ decoder->guts->stream_header.is_last = last_block;
+ decoder->guts->stream_header.length = length;
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__STREAM_METADATA_ENCODING_MIN_BLOCK_SIZE_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ decoder->guts->stream_header.data.encoding.min_blocksize = x;
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__STREAM_METADATA_ENCODING_MAX_BLOCK_SIZE_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ decoder->guts->stream_header.data.encoding.max_blocksize = x;
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__STREAM_METADATA_ENCODING_MIN_FRAME_SIZE_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ decoder->guts->stream_header.data.encoding.min_framesize = x;
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__STREAM_METADATA_ENCODING_MAX_FRAME_SIZE_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ decoder->guts->stream_header.data.encoding.max_framesize = x;
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__STREAM_METADATA_ENCODING_SAMPLE_RATE_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ decoder->guts->stream_header.data.encoding.sample_rate = x;
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__STREAM_METADATA_ENCODING_CHANNELS_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ decoder->guts->stream_header.data.encoding.channels = x+1;
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__STREAM_METADATA_ENCODING_BITS_PER_SAMPLE_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ decoder->guts->stream_header.data.encoding.bits_per_sample = x+1;
+ if(!FLAC__bitbuffer_read_raw_uint64(&decoder->guts->input, &decoder->guts->stream_header.data.encoding.total_samples, FLAC__STREAM_METADATA_ENCODING_TOTAL_SAMPLES_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ decoder->guts->has_stream_header = true;
+ decoder->guts->metadata_callback(decoder, &decoder->guts->stream_header, decoder->guts->client_data);
+ }
+ else {
+ /* skip other metadata blocks */
+ for(i = 0; i < length; i++) {
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ }
+ }
+
+ if(last_block)
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+
+ return true;
+}
+
+bool stream_decoder_skip_id3v2_tag_(FLAC__StreamDecoder *decoder)
+{
+ uint32 x;
+ unsigned i, skip;
+
+ /* skip the version and flags bytes */
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 24, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ /* get the size (in bytes) to skip */
+ skip = 0;
+ for(i = 0; i < 4; i++) {
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ skip <<= 7;
+ skip |= (x & 0x7f);
+ }
+ /* skip the rest of the tag */
+ for(i = 0; i < skip; i++) {
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ }
+ return true;
+}
+
+bool stream_decoder_frame_sync_(FLAC__StreamDecoder *decoder)
+{
+ uint32 x;
+ bool first = 1;
+
+ /* If we know the total number of samples in the stream, stop if we've read that many. */
+ /* This will stop us, for example, from wasting time trying to sync on an ID3V1 tag. */
+ if(decoder->guts->has_stream_header && decoder->guts->stream_header.data.encoding.total_samples) {
+ if(decoder->guts->samples_decoded >= decoder->guts->stream_header.data.encoding.total_samples) {
+ decoder->state = FLAC__STREAM_DECODER_END_OF_STREAM;
+ return true;
+ }
+ }
+
+ /* make sure we're byte aligned */
+ if(decoder->guts->input.consumed_bits != 0) {
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8-decoder->guts->input.consumed_bits, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ }
+
+ while(1) {
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
+ unsigned y;
+ if(!FLAC__bitbuffer_peek_bit(&decoder->guts->input, &y, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ if(!y) { /* MAGIC NUMBER for the last sync bit */
+ decoder->state = FLAC__STREAM_DECODER_READ_FRAME;
+ return true;
+ }
+ }
+ if(first) {
+ decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
+ first = 0;
+ }
+ }
+
+ return true;
+}
+
+bool stream_decoder_read_frame_(FLAC__StreamDecoder *decoder, bool *got_a_frame)
+{
+ unsigned channel;
+ unsigned i;
+ int32 mid, side, left, right;
+
+ *got_a_frame = false;
+
+ if(!stream_decoder_read_frame_header_(decoder))
+ return false;
+ if(decoder->state != FLAC__STREAM_DECODER_READ_FRAME) {
+ if(decoder->state == FLAC__STREAM_DECODER_RESYNC_IN_HEADER)
+ decoder->state = FLAC__STREAM_DECODER_READ_FRAME;
+ else
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+ return true;
+ }
+ if(!stream_decoder_allocate_output(decoder, decoder->guts->frame_header.blocksize))
+ return false;
+ for(channel = 0; channel < decoder->guts->frame_header.channels; channel++) {
+ if(!stream_decoder_read_subframe_(decoder, channel))
+ return false;
+ if(decoder->state != FLAC__STREAM_DECODER_READ_FRAME) {
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+ return true;
+ }
+ }
+ if(!stream_decoder_read_zero_padding_(decoder))
+ return false;
+
+ /* Undo any special channel coding */
+ switch(decoder->guts->frame_header.channel_assignment) {
+ case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
+ /* do nothing */
+ break;
+ case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
+ assert(decoder->guts->frame_header.channels == 2);
+ for(i = 0; i < decoder->guts->frame_header.blocksize; i++)
+ decoder->guts->output[1][i] = decoder->guts->output[0][i] - decoder->guts->output[1][i];
+ break;
+ case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
+ assert(decoder->guts->frame_header.channels == 2);
+ for(i = 0; i < decoder->guts->frame_header.blocksize; i++)
+ decoder->guts->output[0][i] += decoder->guts->output[1][i];
+ break;
+ case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
+ assert(decoder->guts->frame_header.channels == 2);
+ for(i = 0; i < decoder->guts->frame_header.blocksize; i++) {
+ mid = decoder->guts->output[0][i];
+ side = decoder->guts->output[1][i];
+ mid <<= 1;
+ if(side & 1) /* i.e. if 'side' is odd... */
+ mid++;
+ left = mid + side;
+ right = mid - side;
+ decoder->guts->output[0][i] = left >> 1;
+ decoder->guts->output[1][i] = right >> 1;
+ }
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ *got_a_frame = true;
+
+ /* put the latest values into the public section of the decoder instance */
+ decoder->channels = decoder->guts->frame_header.channels;
+ decoder->channel_assignment = decoder->guts->frame_header.channel_assignment;
+ decoder->bits_per_sample = decoder->guts->frame_header.bits_per_sample;
+ decoder->sample_rate = decoder->guts->frame_header.sample_rate;
+ decoder->blocksize = decoder->guts->frame_header.blocksize;
+
+ decoder->guts->samples_decoded += decoder->guts->frame_header.blocksize;
+
+ /* write it */
+ if(decoder->guts->write_callback(decoder, &decoder->guts->frame_header, decoder->guts->output, decoder->guts->client_data) != FLAC__STREAM_DECODER_WRITE_CONTINUE)
+ return false;
+
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+ return true;
+}
+
+bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder)
+{
+ uint32 x;
+ uint64 xx;
+ unsigned i, blocksize_hint = 0, sample_rate_hint = 0;
+ byte crc, raw_header[15]; /* MAGIC NUMBER based on the maximum frame header size, including CRC */
+ unsigned raw_header_len;
+ bool is_unparseable = false;
+
+ assert(decoder->guts->input.consumed_bits == 0); /* make sure we're byte aligned */
+
+ /* init the raw header with the first 8 bits of the sync code */
+ raw_header[0] = 0xff; /* MAGIC NUMBER for the first 8 frame sync bits */
+ raw_header_len = 1;
+
+ /*
+ * read in the raw header as bytes so we can CRC it, and parse it on the way
+ */
+ for(i = 0; i < 2; i++) {
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ else if(x == 0xff) { /* MAGIC NUMBER for the first part of the sync code */
+ /* if we get here it means our original sync was erroneous since the sync code cannot appear in the header */
+ uint32 y;
+ if(!FLAC__bitbuffer_peek_bit(&decoder->guts->input, &y, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ if(!y) { /* MAGIC NUMBER for the last sync bit */
+ decoder->state = FLAC__STREAM_DECODER_RESYNC_IN_HEADER;
+ return true;
+ }
+ else {
+ decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+ return true;
+ }
+ }
+ raw_header[raw_header_len++] = (byte)x;
+ }
+ assert(!(raw_header[1] & 0x80)); /* last sync bit should be confirmed zero before we get here */
+
+ switch(x = raw_header[1] >> 4) {
+ case 0:
+ if(decoder->guts->has_stream_header && decoder->guts->stream_header.data.encoding.min_blocksize == decoder->guts->stream_header.data.encoding.max_blocksize) /* i.e. it's a fixed-blocksize stream */
+ decoder->guts->frame_header.blocksize = decoder->guts->stream_header.data.encoding.min_blocksize;
+ else
+ is_unparseable = true;
+ break;
+ case 1:
+ decoder->guts->frame_header.blocksize = 192;
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ decoder->guts->frame_header.blocksize = 576 << (x-2);
+ break;
+ case 6:
+ case 7:
+ blocksize_hint = x;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ switch(x = raw_header[1] & 0x0f) {
+ case 0:
+ if(decoder->guts->has_stream_header)
+ decoder->guts->frame_header.sample_rate = decoder->guts->stream_header.data.encoding.sample_rate;
+ else
+ is_unparseable = true;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ is_unparseable = true;
+ break;
+ case 4:
+ decoder->guts->frame_header.sample_rate = 8000;
+ break;
+ case 5:
+ decoder->guts->frame_header.sample_rate = 16000;
+ break;
+ case 6:
+ decoder->guts->frame_header.sample_rate = 22050;
+ break;
+ case 7:
+ decoder->guts->frame_header.sample_rate = 24000;
+ break;
+ case 8:
+ decoder->guts->frame_header.sample_rate = 32000;
+ break;
+ case 9:
+ decoder->guts->frame_header.sample_rate = 44100;
+ break;
+ case 10:
+ decoder->guts->frame_header.sample_rate = 48000;
+ break;
+ case 11:
+ decoder->guts->frame_header.sample_rate = 96000;
+ break;
+ case 12:
+ case 13:
+ case 14:
+ sample_rate_hint = x;
+ break;
+ case 15:
+ decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+ return true;
+ default:
+ assert(0);
+ }
+
+ x = (unsigned)(raw_header[2] >> 4);
+ if(x & 8) {
+ decoder->guts->frame_header.channels = 2;
+ switch(x & 7) {
+ case 0:
+ decoder->guts->frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE;
+ break;
+ case 1:
+ decoder->guts->frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE;
+ break;
+ case 2:
+ decoder->guts->frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_MID_SIDE;
+ break;
+ default:
+ is_unparseable = true;
+ break;
+ }
+ }
+ else {
+ decoder->guts->frame_header.channels = (unsigned)x + 1;
+ decoder->guts->frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT;
+ }
+
+ switch(x = (unsigned)(raw_header[2] & 0x0e) >> 1) {
+ case 0:
+ if(decoder->guts->has_stream_header)
+ decoder->guts->frame_header.bits_per_sample = decoder->guts->stream_header.data.encoding.bits_per_sample;
+ else
+ is_unparseable = true;
+ break;
+ case 1:
+ decoder->guts->frame_header.bits_per_sample = 8;
+ break;
+ case 2:
+ decoder->guts->frame_header.bits_per_sample = 12;
+ break;
+ case 4:
+ decoder->guts->frame_header.bits_per_sample = 16;
+ break;
+ case 5:
+ decoder->guts->frame_header.bits_per_sample = 20;
+ break;
+ case 6:
+ decoder->guts->frame_header.bits_per_sample = 24;
+ break;
+ case 3:
+ case 7:
+ is_unparseable = true;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ if(raw_header[2] & 0x01) { /* this should be a zero padding bit */
+ decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+ return true;
+ }
+
+ if(blocksize_hint) {
+ if(!FLAC__bitbuffer_read_utf8_uint64(&decoder->guts->input, &xx, read_callback_, decoder, raw_header, &raw_header_len))
+ return false; /* the read_callback_ sets the state for us */
+ if(xx == 0xffffffffffffffff) {
+ if(raw_header[raw_header_len-1] == 0xff) { /* MAGIC NUMBER for sync code */
+ uint32 y;
+ if(!FLAC__bitbuffer_peek_bit(&decoder->guts->input, &y, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ if(!y) { /* MAGIC NUMBER for the last sync bit */
+ decoder->state = FLAC__STREAM_DECODER_RESYNC_IN_HEADER;
+ return true;
+ }
+ else {
+ decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+ return true;
+ }
+ }
+ else {
+ decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+ return true;
+ }
+ }
+ if(decoder->guts->has_stream_header && decoder->guts->stream_header.data.encoding.min_blocksize == decoder->guts->stream_header.data.encoding.max_blocksize) /* i.e. it's a fixed-blocksize stream */
+ decoder->guts->frame_header.number.sample_number = (uint64)decoder->guts->last_frame_number * (int64)decoder->guts->stream_header.data.encoding.min_blocksize + xx;
+ else
+ decoder->guts->frame_header.number.sample_number = xx;
+ }
+ else {
+ if(!FLAC__bitbuffer_read_utf8_uint32(&decoder->guts->input, &x, read_callback_, decoder, raw_header, &raw_header_len))
+ return false; /* the read_callback_ sets the state for us */
+ if(x == 0xffffffff) {
+ if(raw_header[raw_header_len-1] == 0xff) { /* MAGIC NUMBER for sync code */
+ uint32 y;
+ if(!FLAC__bitbuffer_peek_bit(&decoder->guts->input, &y, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ if(!y) { /* MAGIC NUMBER for the last sync bit */
+ decoder->state = FLAC__STREAM_DECODER_RESYNC_IN_HEADER;
+ return true;
+ }
+ else {
+ decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+ return true;
+ }
+ }
+ else {
+ decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+ return true;
+ }
+ }
+ decoder->guts->last_frame_number = x;
+ if(decoder->guts->has_stream_header) {
+ decoder->guts->frame_header.number.sample_number = (int64)decoder->guts->stream_header.data.encoding.min_blocksize * (int64)x;
+ }
+ else {
+ is_unparseable = true;
+ }
+ }
+
+ if(blocksize_hint) {
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ raw_header[raw_header_len++] = (byte)x;
+ if(blocksize_hint == 7) {
+ uint32 _x;
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &_x, 8, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ raw_header[raw_header_len++] = (byte)_x;
+ x = (x << 8) | _x;
+ }
+ decoder->guts->frame_header.blocksize = x+1;
+ }
+
+ if(sample_rate_hint) {
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ raw_header[raw_header_len++] = (byte)x;
+ if(sample_rate_hint != 12) {
+ uint32 _x;
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &_x, 8, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ raw_header[raw_header_len++] = (byte)_x;
+ x = (x << 8) | _x;
+ }
+ if(sample_rate_hint == 12)
+ decoder->guts->frame_header.sample_rate = x*1000;
+ else if(sample_rate_hint == 13)
+ decoder->guts->frame_header.sample_rate = x;
+ else
+ decoder->guts->frame_header.sample_rate = x*10;
+ }
+
+ /* read the crc byte */
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ crc = (byte)x;
+
+ if(FLAC__crc8(raw_header, raw_header_len) != crc) {
+ decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+ return true;
+ }
+
+ if(is_unparseable) {
+ decoder->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
+ return false;
+ }
+
+ return true;
+}
+
+bool stream_decoder_read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel)
+{
+ uint32 x;
+
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__SUBFRAME_HEADER_TYPE_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ if(x & 0x01 || x & 0x80) {
+ decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+ return true;
+ }
+ else if(x == 0) {
+ return stream_decoder_read_subframe_constant_(decoder, channel);
+ }
+ else if(x == 2) {
+ return stream_decoder_read_subframe_verbatim_(decoder, channel);
+ }
+ else if(x < 16) {
+ decoder->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
+ return false;
+ }
+ else if(x <= 24) {
+ return stream_decoder_read_subframe_fixed_(decoder, channel, (x>>1)&7);
+ }
+ else if(x < 64) {
+ decoder->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
+ return false;
+ }
+ else {
+ return stream_decoder_read_subframe_lpc_(decoder, channel, ((x>>1)&31)+1);
+ }
+}
+
+bool stream_decoder_read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel)
+{
+ int32 x;
+ unsigned i;
+
+ if(!FLAC__bitbuffer_read_raw_int32(&decoder->guts->input, &x, decoder->guts->frame_header.bits_per_sample, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+
+ for(i = 0; i < decoder->guts->frame_header.blocksize; i++)
+ decoder->guts->output[channel][i] = x;
+
+ return true;
+}
+
+bool stream_decoder_read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, const unsigned order)
+{
+ FLAC__SubframeHeader_Fixed subframe_header;
+ int32 i32;
+ uint32 u32;
+ unsigned u;
+
+ subframe_header.order = order;
+
+ /* read warm-up samples */
+ for(u = 0; u < order; u++) {
+ if(!FLAC__bitbuffer_read_raw_int32(&decoder->guts->input, &i32, decoder->guts->frame_header.bits_per_sample, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ decoder->guts->output[channel][u] = i32;
+ }
+
+ /* read entropy coding method info */
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ subframe_header.entropy_coding_method.type = u32;
+ switch(subframe_header.entropy_coding_method.type) {
+ case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ subframe_header.entropy_coding_method.data.partitioned_rice.order = u32;
+ break;
+ default:
+ decoder->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
+ return false;
+ }
+
+ /* read residual */
+ switch(subframe_header.entropy_coding_method.type) {
+ case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
+ if(!stream_decoder_read_residual_partitioned_rice_(decoder, order, subframe_header.entropy_coding_method.data.partitioned_rice.order))
+ return false;
+ break;
+ default:
+ assert(0);
+ }
+
+ /* decode the subframe */
+ FLAC__fixed_restore_signal(decoder->guts->residual, decoder->guts->frame_header.blocksize-order, order, decoder->guts->output[channel]+order);
+
+ return true;
+}
+
+bool stream_decoder_read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, const unsigned order)
+{
+ FLAC__SubframeHeader_LPC subframe_header;
+ int32 i32;
+ uint32 u32;
+ unsigned u;
+
+ subframe_header.order = order;
+
+ /* read warm-up samples */
+ for(u = 0; u < order; u++) {
+ if(!FLAC__bitbuffer_read_raw_int32(&decoder->guts->input, &i32, decoder->guts->frame_header.bits_per_sample, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ decoder->guts->output[channel][u] = i32;
+ }
+
+ /* read qlp coeff precision */
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &u32, FLAC__SUBFRAME_HEADER_LPC_QLP_COEFF_PRECISION_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ if(u32 == 15) {
+ decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+ return true;
+ }
+ subframe_header.qlp_coeff_precision = u32+1;
+
+ /* read qlp shift */
+ if(!FLAC__bitbuffer_read_raw_int32(&decoder->guts->input, &i32, FLAC__SUBFRAME_HEADER_LPC_QLP_SHIFT_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ subframe_header.quantization_level = i32;
+
+ /* read quantized lp coefficiencts */
+ for(u = 0; u < order; u++) {
+ if(!FLAC__bitbuffer_read_raw_int32(&decoder->guts->input, &i32, subframe_header.qlp_coeff_precision, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ subframe_header.qlp_coeff[u] = i32;
+ }
+
+ /* read entropy coding method info */
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ subframe_header.entropy_coding_method.type = u32;
+ switch(subframe_header.entropy_coding_method.type) {
+ case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ subframe_header.entropy_coding_method.data.partitioned_rice.order = u32;
+ break;
+ default:
+ decoder->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
+ return false;
+ }
+
+ /* read residual */
+ switch(subframe_header.entropy_coding_method.type) {
+ case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE:
+ if(!stream_decoder_read_residual_partitioned_rice_(decoder, order, subframe_header.entropy_coding_method.data.partitioned_rice.order))
+ return false;
+ break;
+ default:
+ assert(0);
+ }
+
+ /* decode the subframe */
+ FLAC__lpc_restore_signal(decoder->guts->residual, decoder->guts->frame_header.blocksize-order, subframe_header.qlp_coeff, order, subframe_header.quantization_level, decoder->guts->output[channel]+order);
+
+ return true;
+}
+
+bool stream_decoder_read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel)
+{
+ int32 x;
+ unsigned i;
+
+ for(i = 0; i < decoder->guts->frame_header.blocksize; i++) {
+ if(!FLAC__bitbuffer_read_raw_int32(&decoder->guts->input, &x, decoder->guts->frame_header.bits_per_sample, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ decoder->guts->output[channel][i] = x;
+ }
+
+ return true;
+}
+
+bool stream_decoder_read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order)
+{
+ uint32 rice_parameter;
+ int i;
+ unsigned partition, sample, u;
+ const unsigned partitions = 1u << partition_order;
+ const unsigned partition_samples = partition_order > 0? decoder->guts->frame_header.blocksize >> partition_order : decoder->guts->frame_header.blocksize - predictor_order;
+
+ sample = 0;
+ for(partition = 0; partition < partitions; partition++) {
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) {
+ if(!FLAC__bitbuffer_read_rice_signed(&decoder->guts->input, &i, rice_parameter, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ decoder->guts->residual[sample] = i;
+ }
+ }
+
+ return true;
+}
+
+bool stream_decoder_read_zero_padding_(FLAC__StreamDecoder *decoder)
+{
+ if(decoder->guts->input.consumed_bits != 0) {
+ uint32 zero;
+ if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &zero, 8-decoder->guts->input.consumed_bits, read_callback_, decoder))
+ return false; /* the read_callback_ sets the state for us */
+ if(zero != 0) {
+ decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
+ decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+ }
+ }
+ return true;
+}
+
+bool read_callback_(byte buffer[], unsigned *bytes, void *client_data)
+{
+ FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder *)client_data;
+ FLAC__StreamDecoderReadStatus status;
+ status = decoder->guts->read_callback(decoder, buffer, bytes, decoder->guts->client_data);
+ if(status == FLAC__STREAM_DECODER_READ_END_OF_STREAM)
+ decoder->state = FLAC__STREAM_DECODER_END_OF_STREAM;
+ else if(status == FLAC__STREAM_DECODER_READ_ABORT)
+ decoder->state = FLAC__STREAM_DECODER_ABORTED;
+ return status == FLAC__STREAM_DECODER_READ_CONTINUE;
+}