1c74663799493f2b1e6123c18def94295d0afab7Kenny Root/* libFLAC - Free Lossless Audio Codec library
2c74663799493f2b1e6123c18def94295d0afab7Kenny Root * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007  Josh Coalson
3c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
4c74663799493f2b1e6123c18def94295d0afab7Kenny Root * Redistribution and use in source and binary forms, with or without
5c74663799493f2b1e6123c18def94295d0afab7Kenny Root * modification, are permitted provided that the following conditions
6c74663799493f2b1e6123c18def94295d0afab7Kenny Root * are met:
7c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
8c74663799493f2b1e6123c18def94295d0afab7Kenny Root * - Redistributions of source code must retain the above copyright
9c74663799493f2b1e6123c18def94295d0afab7Kenny Root * notice, this list of conditions and the following disclaimer.
10c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
11c74663799493f2b1e6123c18def94295d0afab7Kenny Root * - Redistributions in binary form must reproduce the above copyright
12c74663799493f2b1e6123c18def94295d0afab7Kenny Root * notice, this list of conditions and the following disclaimer in the
13c74663799493f2b1e6123c18def94295d0afab7Kenny Root * documentation and/or other materials provided with the distribution.
14c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
15c74663799493f2b1e6123c18def94295d0afab7Kenny Root * - Neither the name of the Xiph.org Foundation nor the names of its
16c74663799493f2b1e6123c18def94295d0afab7Kenny Root * contributors may be used to endorse or promote products derived from
17c74663799493f2b1e6123c18def94295d0afab7Kenny Root * this software without specific prior written permission.
18c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
19c74663799493f2b1e6123c18def94295d0afab7Kenny Root * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20c74663799493f2b1e6123c18def94295d0afab7Kenny Root * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21c74663799493f2b1e6123c18def94295d0afab7Kenny Root * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22c74663799493f2b1e6123c18def94295d0afab7Kenny Root * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23c74663799493f2b1e6123c18def94295d0afab7Kenny Root * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24c74663799493f2b1e6123c18def94295d0afab7Kenny Root * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25c74663799493f2b1e6123c18def94295d0afab7Kenny Root * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26c74663799493f2b1e6123c18def94295d0afab7Kenny Root * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27c74663799493f2b1e6123c18def94295d0afab7Kenny Root * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28c74663799493f2b1e6123c18def94295d0afab7Kenny Root * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29c74663799493f2b1e6123c18def94295d0afab7Kenny Root * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30c74663799493f2b1e6123c18def94295d0afab7Kenny Root */
31c74663799493f2b1e6123c18def94295d0afab7Kenny Root
32c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if HAVE_CONFIG_H
33c74663799493f2b1e6123c18def94295d0afab7Kenny Root#  include <config.h>
34c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
35c74663799493f2b1e6123c18def94295d0afab7Kenny Root
36c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if defined _MSC_VER || defined __MINGW32__
37c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include <io.h> /* for _setmode() */
38c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include <fcntl.h> /* for _O_BINARY */
39c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
40c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if defined __CYGWIN__ || defined __EMX__
41c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include <io.h> /* for setmode(), O_BINARY */
42c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include <fcntl.h> /* for _O_BINARY */
43c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
44c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include <limits.h>
45c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include <stdio.h>
46c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include <stdlib.h> /* for malloc() */
47c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include <string.h> /* for memcpy() */
48c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include <sys/types.h> /* for off_t */
49c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
50c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if _MSC_VER <= 1600 || defined __BORLANDC__ /* @@@ [2G limit] */
51c74663799493f2b1e6123c18def94295d0afab7Kenny Root#define fseeko fseek
52c74663799493f2b1e6123c18def94295d0afab7Kenny Root#define ftello ftell
53c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
54c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
55c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "FLAC/assert.h"
56c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "FLAC/stream_decoder.h"
57c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "share/alloc.h"
58c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "protected/stream_encoder.h"
59c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "private/bitwriter.h"
60c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "private/bitmath.h"
61c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "private/crc.h"
62c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "private/cpu.h"
63c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "private/fixed.h"
64c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "private/format.h"
65c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "private/lpc.h"
66c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "private/md5.h"
67c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "private/memory.h"
68c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if FLAC__HAS_OGG
69c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "private/ogg_helper.h"
70c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "private/ogg_mapping.h"
71c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
72c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "private/stream_encoder_framing.h"
73c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "private/window.h"
74c74663799493f2b1e6123c18def94295d0afab7Kenny Root
75c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLaC__INLINE
76c74663799493f2b1e6123c18def94295d0afab7Kenny Root#define FLaC__INLINE
77c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
78c74663799493f2b1e6123c18def94295d0afab7Kenny Root
79c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef min
80c74663799493f2b1e6123c18def94295d0afab7Kenny Root#undef min
81c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
82c74663799493f2b1e6123c18def94295d0afab7Kenny Root#define min(x,y) ((x)<(y)?(x):(y))
83c74663799493f2b1e6123c18def94295d0afab7Kenny Root
84c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef max
85c74663799493f2b1e6123c18def94295d0afab7Kenny Root#undef max
86c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
87c74663799493f2b1e6123c18def94295d0afab7Kenny Root#define max(x,y) ((x)>(y)?(x):(y))
88c74663799493f2b1e6123c18def94295d0afab7Kenny Root
89c74663799493f2b1e6123c18def94295d0afab7Kenny Root/* Exact Rice codeword length calculation is off by default.  The simple
90c74663799493f2b1e6123c18def94295d0afab7Kenny Root * (and fast) estimation (of how many bits a residual value will be
91c74663799493f2b1e6123c18def94295d0afab7Kenny Root * encoded with) in this encoder is very good, almost always yielding
92c74663799493f2b1e6123c18def94295d0afab7Kenny Root * compression within 0.1% of exact calculation.
93c74663799493f2b1e6123c18def94295d0afab7Kenny Root */
94c74663799493f2b1e6123c18def94295d0afab7Kenny Root#undef EXACT_RICE_BITS_CALCULATION
95c74663799493f2b1e6123c18def94295d0afab7Kenny Root/* Rice parameter searching is off by default.  The simple (and fast)
96c74663799493f2b1e6123c18def94295d0afab7Kenny Root * parameter estimation in this encoder is very good, almost always
97c74663799493f2b1e6123c18def94295d0afab7Kenny Root * yielding compression within 0.1% of the optimal parameters.
98c74663799493f2b1e6123c18def94295d0afab7Kenny Root */
99c74663799493f2b1e6123c18def94295d0afab7Kenny Root#undef ENABLE_RICE_PARAMETER_SEARCH
100c74663799493f2b1e6123c18def94295d0afab7Kenny Root
101c74663799493f2b1e6123c18def94295d0afab7Kenny Root
102c74663799493f2b1e6123c18def94295d0afab7Kenny Roottypedef struct {
103c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 *data[FLAC__MAX_CHANNELS];
104c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned size; /* of each data[] in samples */
105c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned tail;
106c74663799493f2b1e6123c18def94295d0afab7Kenny Root} verify_input_fifo;
107c74663799493f2b1e6123c18def94295d0afab7Kenny Root
108c74663799493f2b1e6123c18def94295d0afab7Kenny Roottypedef struct {
109c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__byte *data;
110c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned capacity;
111c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned bytes;
112c74663799493f2b1e6123c18def94295d0afab7Kenny Root} verify_output;
113c74663799493f2b1e6123c18def94295d0afab7Kenny Root
114c74663799493f2b1e6123c18def94295d0afab7Kenny Roottypedef enum {
115c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ENCODER_IN_MAGIC = 0,
116c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ENCODER_IN_METADATA = 1,
117c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ENCODER_IN_AUDIO = 2
118c74663799493f2b1e6123c18def94295d0afab7Kenny Root} EncoderStateHint;
119c74663799493f2b1e6123c18def94295d0afab7Kenny Root
120c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic struct CompressionLevels {
121c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool do_mid_side_stereo;
122c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool loose_mid_side_stereo;
123c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned max_lpc_order;
124c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned qlp_coeff_precision;
125c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool do_qlp_coeff_prec_search;
126c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool do_escape_coding;
127c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool do_exhaustive_model_search;
128c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_residual_partition_order;
129c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned max_residual_partition_order;
130c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter_search_dist;
131c74663799493f2b1e6123c18def94295d0afab7Kenny Root} compression_levels_[] = {
132c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{ false, false,  0, 0, false, false, false, 0, 3, 0 },
133c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{ true , true ,  0, 0, false, false, false, 0, 3, 0 },
134c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{ true , false,  0, 0, false, false, false, 0, 3, 0 },
135c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{ false, false,  6, 0, false, false, false, 0, 4, 0 },
136c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{ true , true ,  8, 0, false, false, false, 0, 4, 0 },
137c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{ true , false,  8, 0, false, false, false, 0, 5, 0 },
138c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{ true , false,  8, 0, false, false, false, 0, 6, 0 },
139c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{ true , false,  8, 0, false, false, true , 0, 6, 0 },
140c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{ true , false, 12, 0, false, false, true , 0, 6, 0 }
141c74663799493f2b1e6123c18def94295d0afab7Kenny Root};
142c74663799493f2b1e6123c18def94295d0afab7Kenny Root
143c74663799493f2b1e6123c18def94295d0afab7Kenny Root
144c74663799493f2b1e6123c18def94295d0afab7Kenny Root/***********************************************************************
145c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
146c74663799493f2b1e6123c18def94295d0afab7Kenny Root * Private class method prototypes
147c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
148c74663799493f2b1e6123c18def94295d0afab7Kenny Root ***********************************************************************/
149c74663799493f2b1e6123c18def94295d0afab7Kenny Root
150c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic void set_defaults_(FLAC__StreamEncoder *encoder);
151c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic void free_(FLAC__StreamEncoder *encoder);
152c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_blocksize);
153c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, unsigned samples, FLAC__bool is_last_block);
154c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__StreamEncoderWriteStatus write_frame_(FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, FLAC__bool is_last_block);
155c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic void update_metadata_(const FLAC__StreamEncoder *encoder);
156c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if FLAC__HAS_OGG
157c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic void update_ogg_metadata_(FLAC__StreamEncoder *encoder);
158c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
159c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block, FLAC__bool is_last_block);
160c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block);
161c74663799493f2b1e6123c18def94295d0afab7Kenny Root
162c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__bool process_subframe_(
163c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
164c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_partition_order,
165c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned max_partition_order,
166c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__FrameHeader *frame_header,
167c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned subframe_bps,
168c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 integer_signal[],
169c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__Subframe *subframe[2],
170c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2],
171c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 *residual[2],
172c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned *best_subframe,
173c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned *best_bits
174c74663799493f2b1e6123c18def94295d0afab7Kenny Root);
175c74663799493f2b1e6123c18def94295d0afab7Kenny Root
176c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__bool add_subframe_(
177c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
178c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned blocksize,
179c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned subframe_bps,
180c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__Subframe *subframe,
181c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__BitWriter *frame
182c74663799493f2b1e6123c18def94295d0afab7Kenny Root);
183c74663799493f2b1e6123c18def94295d0afab7Kenny Root
184c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic unsigned evaluate_constant_subframe_(
185c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
186c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 signal,
187c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned blocksize,
188c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned subframe_bps,
189c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__Subframe *subframe
190c74663799493f2b1e6123c18def94295d0afab7Kenny Root);
191c74663799493f2b1e6123c18def94295d0afab7Kenny Root
192c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic unsigned evaluate_fixed_subframe_(
193c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
194c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 signal[],
195c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 residual[],
196c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__uint64 abs_residual_partition_sums[],
197c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned raw_bits_per_partition[],
198c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned blocksize,
199c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned subframe_bps,
200c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned order,
201c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter,
202c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter_limit,
203c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_partition_order,
204c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned max_partition_order,
205c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool do_escape_coding,
206c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter_search_dist,
207c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__Subframe *subframe,
208c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
209c74663799493f2b1e6123c18def94295d0afab7Kenny Root);
210c74663799493f2b1e6123c18def94295d0afab7Kenny Root
211c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
212c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic unsigned evaluate_lpc_subframe_(
213c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
214c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 signal[],
215c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 residual[],
216c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__uint64 abs_residual_partition_sums[],
217c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned raw_bits_per_partition[],
218c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__real lp_coeff[],
219c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned blocksize,
220c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned subframe_bps,
221c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned order,
222c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned qlp_coeff_precision,
223c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter,
224c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter_limit,
225c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_partition_order,
226c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned max_partition_order,
227c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool do_escape_coding,
228c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter_search_dist,
229c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__Subframe *subframe,
230c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
231c74663799493f2b1e6123c18def94295d0afab7Kenny Root);
232c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
233c74663799493f2b1e6123c18def94295d0afab7Kenny Root
234c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic unsigned evaluate_verbatim_subframe_(
235c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
236c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 signal[],
237c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned blocksize,
238c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned subframe_bps,
239c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__Subframe *subframe
240c74663799493f2b1e6123c18def94295d0afab7Kenny Root);
241c74663799493f2b1e6123c18def94295d0afab7Kenny Root
242c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic unsigned find_best_partition_order_(
243c74663799493f2b1e6123c18def94295d0afab7Kenny Root	struct FLAC__StreamEncoderPrivate *private_,
244c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 residual[],
245c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__uint64 abs_residual_partition_sums[],
246c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned raw_bits_per_partition[],
247c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned residual_samples,
248c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned predictor_order,
249c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter,
250c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter_limit,
251c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_partition_order,
252c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned max_partition_order,
253c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned bps,
254c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool do_escape_coding,
255c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter_search_dist,
256c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__EntropyCodingMethod *best_ecm
257c74663799493f2b1e6123c18def94295d0afab7Kenny Root);
258c74663799493f2b1e6123c18def94295d0afab7Kenny Root
259c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic void precompute_partition_info_sums_(
260c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 residual[],
261c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__uint64 abs_residual_partition_sums[],
262c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned residual_samples,
263c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned predictor_order,
264c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_partition_order,
265c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned max_partition_order,
266c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned bps
267c74663799493f2b1e6123c18def94295d0afab7Kenny Root);
268c74663799493f2b1e6123c18def94295d0afab7Kenny Root
269c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic void precompute_partition_info_escapes_(
270c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 residual[],
271c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned raw_bits_per_partition[],
272c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned residual_samples,
273c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned predictor_order,
274c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_partition_order,
275c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned max_partition_order
276c74663799493f2b1e6123c18def94295d0afab7Kenny Root);
277c74663799493f2b1e6123c18def94295d0afab7Kenny Root
278c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__bool set_partitioned_rice_(
279c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef EXACT_RICE_BITS_CALCULATION
280c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 residual[],
281c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
282c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__uint64 abs_residual_partition_sums[],
283c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned raw_bits_per_partition[],
284c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned residual_samples,
285c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned predictor_order,
286c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned suggested_rice_parameter,
287c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned rice_parameter_limit,
288c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned rice_parameter_search_dist,
289c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned partition_order,
290c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__bool search_for_escapes,
291c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents,
292c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned *bits
293c74663799493f2b1e6123c18def94295d0afab7Kenny Root);
294c74663799493f2b1e6123c18def94295d0afab7Kenny Root
295c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic unsigned get_wasted_bits_(FLAC__int32 signal[], unsigned samples);
296c74663799493f2b1e6123c18def94295d0afab7Kenny Root
297c74663799493f2b1e6123c18def94295d0afab7Kenny Root/* verify-related routines: */
298c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic void append_to_verify_fifo_(
299c74663799493f2b1e6123c18def94295d0afab7Kenny Root	verify_input_fifo *fifo,
300c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 * const input[],
301c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned input_offset,
302c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned channels,
303c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned wide_samples
304c74663799493f2b1e6123c18def94295d0afab7Kenny Root);
305c74663799493f2b1e6123c18def94295d0afab7Kenny Root
306c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic void append_to_verify_fifo_interleaved_(
307c74663799493f2b1e6123c18def94295d0afab7Kenny Root	verify_input_fifo *fifo,
308c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 input[],
309c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned input_offset,
310c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned channels,
311c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned wide_samples
312c74663799493f2b1e6123c18def94295d0afab7Kenny Root);
313c74663799493f2b1e6123c18def94295d0afab7Kenny Root
314c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__StreamDecoderReadStatus verify_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
315c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__StreamDecoderWriteStatus verify_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
316c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic void verify_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
317c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic void verify_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
318c74663799493f2b1e6123c18def94295d0afab7Kenny Root
319c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__StreamEncoderReadStatus file_read_callback_(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
320c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__StreamEncoderSeekStatus file_seek_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data);
321c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__StreamEncoderTellStatus file_tell_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
322c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__StreamEncoderWriteStatus file_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data);
323c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FILE *get_binary_stdout_(void);
324c74663799493f2b1e6123c18def94295d0afab7Kenny Root
325c74663799493f2b1e6123c18def94295d0afab7Kenny Root
326c74663799493f2b1e6123c18def94295d0afab7Kenny Root/***********************************************************************
327c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
328c74663799493f2b1e6123c18def94295d0afab7Kenny Root * Private class data
329c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
330c74663799493f2b1e6123c18def94295d0afab7Kenny Root ***********************************************************************/
331c74663799493f2b1e6123c18def94295d0afab7Kenny Root
332c74663799493f2b1e6123c18def94295d0afab7Kenny Roottypedef struct FLAC__StreamEncoderPrivate {
333c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned input_capacity;                          /* current size (in samples) of the signal and residual buffers */
334c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 *integer_signal[FLAC__MAX_CHANNELS];  /* the integer version of the input signal */
335c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 *integer_signal_mid_side[2];          /* the integer version of the mid-side input signal (stereo only) */
336c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
337c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__real *real_signal[FLAC__MAX_CHANNELS];      /* (@@@ currently unused) the floating-point version of the input signal */
338c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__real *real_signal_mid_side[2];              /* (@@@ currently unused) the floating-point version of the mid-side input signal (stereo only) */
339c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__real *window[FLAC__MAX_APODIZATION_FUNCTIONS]; /* the pre-computed floating-point window for each apodization function */
340c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__real *windowed_signal;                      /* the integer_signal[] * current window[] */
341c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
342c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned subframe_bps[FLAC__MAX_CHANNELS];        /* the effective bits per sample of the input signal (stream bps - wasted bits) */
343c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned subframe_bps_mid_side[2];                /* the effective bits per sample of the mid-side input signal (stream bps - wasted bits + 0/1) */
344c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 *residual_workspace[FLAC__MAX_CHANNELS][2]; /* each channel has a candidate and best workspace where the subframe residual signals will be stored */
345c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 *residual_workspace_mid_side[2][2];
346c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__Subframe subframe_workspace[FLAC__MAX_CHANNELS][2];
347c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__Subframe subframe_workspace_mid_side[2][2];
348c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__Subframe *subframe_workspace_ptr[FLAC__MAX_CHANNELS][2];
349c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__Subframe *subframe_workspace_ptr_mid_side[2][2];
350c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_workspace[FLAC__MAX_CHANNELS][2];
351c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_workspace_mid_side[FLAC__MAX_CHANNELS][2];
352c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents_workspace_ptr[FLAC__MAX_CHANNELS][2];
353c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents_workspace_ptr_mid_side[FLAC__MAX_CHANNELS][2];
354c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned best_subframe[FLAC__MAX_CHANNELS];       /* index (0 or 1) into 2nd dimension of the above workspaces */
355c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned best_subframe_mid_side[2];
356c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned best_subframe_bits[FLAC__MAX_CHANNELS];  /* size in bits of the best subframe for each channel */
357c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned best_subframe_bits_mid_side[2];
358c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__uint64 *abs_residual_partition_sums;        /* workspace where the sum of abs(candidate residual) for each partition is stored */
359c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned *raw_bits_per_partition;                 /* workspace where the sum of silog2(candidate residual) for each partition is stored */
360c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__BitWriter *frame;                           /* the current frame being worked on */
361c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned loose_mid_side_stereo_frames;            /* rounded number of frames the encoder will use before trying both independent and mid/side frames again */
362c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned loose_mid_side_stereo_frame_count;       /* number of frames using the current channel assignment */
363c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ChannelAssignment last_channel_assignment;
364c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamMetadata streaminfo;                  /* scratchpad for STREAMINFO as it is built */
365c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamMetadata_SeekTable *seek_table;       /* pointer into encoder->protected_->metadata_ where the seek table is */
366c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned current_sample_number;
367c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned current_frame_number;
368c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__MD5Context md5context;
369c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__CPUInfo cpuinfo;
370c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
371c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
372c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
373c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
374c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
375c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
376c74663799493f2b1e6123c18def94295d0afab7Kenny Root	void (*local_lpc_compute_autocorrelation)(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
377c74663799493f2b1e6123c18def94295d0afab7Kenny Root	void (*local_lpc_compute_residual_from_qlp_coefficients)(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
378c74663799493f2b1e6123c18def94295d0afab7Kenny Root	void (*local_lpc_compute_residual_from_qlp_coefficients_64bit)(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
379c74663799493f2b1e6123c18def94295d0afab7Kenny Root	void (*local_lpc_compute_residual_from_qlp_coefficients_16bit)(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
380c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
381c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool use_wide_by_block;          /* use slow 64-bit versions of some functions because of the block size */
382c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool use_wide_by_partition;      /* use slow 64-bit versions of some functions because of the min partition order and blocksize */
383c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool use_wide_by_order;          /* use slow 64-bit versions of some functions because of the lpc order */
384c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool disable_constant_subframes;
385c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool disable_fixed_subframes;
386c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool disable_verbatim_subframes;
387c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if FLAC__HAS_OGG
388c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool is_ogg;
389c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
390c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderReadCallback read_callback; /* currently only needed for Ogg FLAC */
391c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderSeekCallback seek_callback;
392c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderTellCallback tell_callback;
393c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderWriteCallback write_callback;
394c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderMetadataCallback metadata_callback;
395c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderProgressCallback progress_callback;
396c74663799493f2b1e6123c18def94295d0afab7Kenny Root	void *client_data;
397c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned first_seekpoint_to_check;
398c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FILE *file;                            /* only used when encoding to a file */
399c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__uint64 bytes_written;
400c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__uint64 samples_written;
401c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned frames_written;
402c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned total_frames_estimate;
403c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* unaligned (original) pointers to allocated data */
404c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 *integer_signal_unaligned[FLAC__MAX_CHANNELS];
405c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 *integer_signal_mid_side_unaligned[2];
406c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
407c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__real *real_signal_unaligned[FLAC__MAX_CHANNELS]; /* (@@@ currently unused) */
408c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__real *real_signal_mid_side_unaligned[2]; /* (@@@ currently unused) */
409c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__real *window_unaligned[FLAC__MAX_APODIZATION_FUNCTIONS];
410c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__real *windowed_signal_unaligned;
411c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
412c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 *residual_workspace_unaligned[FLAC__MAX_CHANNELS][2];
413c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 *residual_workspace_mid_side_unaligned[2][2];
414c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__uint64 *abs_residual_partition_sums_unaligned;
415c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned *raw_bits_per_partition_unaligned;
416c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
417c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * These fields have been moved here from private function local
418c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * declarations merely to save stack space during encoding.
419c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
420c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
421c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__real lp_coeff[FLAC__MAX_LPC_ORDER][FLAC__MAX_LPC_ORDER]; /* from process_subframe_() */
422c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
423c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_extra[2]; /* from find_best_partition_order_() */
424c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
425c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * The data for the verify section
426c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
427c74663799493f2b1e6123c18def94295d0afab7Kenny Root	struct {
428c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__StreamDecoder *decoder;
429c74663799493f2b1e6123c18def94295d0afab7Kenny Root		EncoderStateHint state_hint;
430c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__bool needs_magic_hack;
431c74663799493f2b1e6123c18def94295d0afab7Kenny Root		verify_input_fifo input_fifo;
432c74663799493f2b1e6123c18def94295d0afab7Kenny Root		verify_output output;
433c74663799493f2b1e6123c18def94295d0afab7Kenny Root		struct {
434c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__uint64 absolute_sample;
435c74663799493f2b1e6123c18def94295d0afab7Kenny Root			unsigned frame_number;
436c74663799493f2b1e6123c18def94295d0afab7Kenny Root			unsigned channel;
437c74663799493f2b1e6123c18def94295d0afab7Kenny Root			unsigned sample;
438c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__int32 expected;
439c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__int32 got;
440c74663799493f2b1e6123c18def94295d0afab7Kenny Root		} error_stats;
441c74663799493f2b1e6123c18def94295d0afab7Kenny Root	} verify;
442c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool is_being_deleted; /* if true, call to ..._finish() from ..._delete() will not call the callbacks */
443c74663799493f2b1e6123c18def94295d0afab7Kenny Root} FLAC__StreamEncoderPrivate;
444c74663799493f2b1e6123c18def94295d0afab7Kenny Root
445c74663799493f2b1e6123c18def94295d0afab7Kenny Root/***********************************************************************
446c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
447c74663799493f2b1e6123c18def94295d0afab7Kenny Root * Public static class data
448c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
449c74663799493f2b1e6123c18def94295d0afab7Kenny Root ***********************************************************************/
450c74663799493f2b1e6123c18def94295d0afab7Kenny Root
451c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API const char * const FLAC__StreamEncoderStateString[] = {
452c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_OK",
453c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_UNINITIALIZED",
454c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_OGG_ERROR",
455c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR",
456c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA",
457c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_CLIENT_ERROR",
458c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_IO_ERROR",
459c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_FRAMING_ERROR",
460c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR"
461c74663799493f2b1e6123c18def94295d0afab7Kenny Root};
462c74663799493f2b1e6123c18def94295d0afab7Kenny Root
463c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API const char * const FLAC__StreamEncoderInitStatusString[] = {
464c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_INIT_STATUS_OK",
465c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR",
466c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER",
467c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS",
468c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS",
469c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE",
470c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE",
471c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE",
472c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER",
473c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION",
474c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER",
475c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE",
476c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA",
477c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED"
478c74663799493f2b1e6123c18def94295d0afab7Kenny Root};
479c74663799493f2b1e6123c18def94295d0afab7Kenny Root
480c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API const char * const FLAC__treamEncoderReadStatusString[] = {
481c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE",
482c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM",
483c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_READ_STATUS_ABORT",
484c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED"
485c74663799493f2b1e6123c18def94295d0afab7Kenny Root};
486c74663799493f2b1e6123c18def94295d0afab7Kenny Root
487c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API const char * const FLAC__StreamEncoderWriteStatusString[] = {
488c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_WRITE_STATUS_OK",
489c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR"
490c74663799493f2b1e6123c18def94295d0afab7Kenny Root};
491c74663799493f2b1e6123c18def94295d0afab7Kenny Root
492c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API const char * const FLAC__StreamEncoderSeekStatusString[] = {
493c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_SEEK_STATUS_OK",
494c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR",
495c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED"
496c74663799493f2b1e6123c18def94295d0afab7Kenny Root};
497c74663799493f2b1e6123c18def94295d0afab7Kenny Root
498c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API const char * const FLAC__StreamEncoderTellStatusString[] = {
499c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_TELL_STATUS_OK",
500c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_TELL_STATUS_ERROR",
501c74663799493f2b1e6123c18def94295d0afab7Kenny Root	"FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED"
502c74663799493f2b1e6123c18def94295d0afab7Kenny Root};
503c74663799493f2b1e6123c18def94295d0afab7Kenny Root
504c74663799493f2b1e6123c18def94295d0afab7Kenny Root/* Number of samples that will be overread to watch for end of stream.  By
505c74663799493f2b1e6123c18def94295d0afab7Kenny Root * 'overread', we mean that the FLAC__stream_encoder_process*() calls will
506c74663799493f2b1e6123c18def94295d0afab7Kenny Root * always try to read blocksize+1 samples before encoding a block, so that
507c74663799493f2b1e6123c18def94295d0afab7Kenny Root * even if the stream has a total sample count that is an integral multiple
508c74663799493f2b1e6123c18def94295d0afab7Kenny Root * of the blocksize, we will still notice when we are encoding the last
509c74663799493f2b1e6123c18def94295d0afab7Kenny Root * block.  This is needed, for example, to correctly set the end-of-stream
510c74663799493f2b1e6123c18def94295d0afab7Kenny Root * marker in Ogg FLAC.
511c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
512c74663799493f2b1e6123c18def94295d0afab7Kenny Root * WATCHOUT: some parts of the code assert that OVERREAD_ == 1 and there's
513c74663799493f2b1e6123c18def94295d0afab7Kenny Root * not really any reason to change it.
514c74663799493f2b1e6123c18def94295d0afab7Kenny Root */
515c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic const unsigned OVERREAD_ = 1;
516c74663799493f2b1e6123c18def94295d0afab7Kenny Root
517c74663799493f2b1e6123c18def94295d0afab7Kenny Root/***********************************************************************
518c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
519c74663799493f2b1e6123c18def94295d0afab7Kenny Root * Class constructor/destructor
520c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
521c74663799493f2b1e6123c18def94295d0afab7Kenny Root */
522c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(void)
523c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
524c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder;
525c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned i;
526c74663799493f2b1e6123c18def94295d0afab7Kenny Root
527c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
528c74663799493f2b1e6123c18def94295d0afab7Kenny Root
529c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder = (FLAC__StreamEncoder*)calloc(1, sizeof(FLAC__StreamEncoder));
530c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder == 0) {
531c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return 0;
532c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
533c74663799493f2b1e6123c18def94295d0afab7Kenny Root
534c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_ = (FLAC__StreamEncoderProtected*)calloc(1, sizeof(FLAC__StreamEncoderProtected));
535c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_ == 0) {
536c74663799493f2b1e6123c18def94295d0afab7Kenny Root		free(encoder);
537c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return 0;
538c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
539c74663799493f2b1e6123c18def94295d0afab7Kenny Root
540c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_ = (FLAC__StreamEncoderPrivate*)calloc(1, sizeof(FLAC__StreamEncoderPrivate));
541c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->private_ == 0) {
542c74663799493f2b1e6123c18def94295d0afab7Kenny Root		free(encoder->protected_);
543c74663799493f2b1e6123c18def94295d0afab7Kenny Root		free(encoder);
544c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return 0;
545c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
546c74663799493f2b1e6123c18def94295d0afab7Kenny Root
547c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->frame = FLAC__bitwriter_new();
548c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->private_->frame == 0) {
549c74663799493f2b1e6123c18def94295d0afab7Kenny Root		free(encoder->private_);
550c74663799493f2b1e6123c18def94295d0afab7Kenny Root		free(encoder->protected_);
551c74663799493f2b1e6123c18def94295d0afab7Kenny Root		free(encoder);
552c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return 0;
553c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
554c74663799493f2b1e6123c18def94295d0afab7Kenny Root
555c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->file = 0;
556c74663799493f2b1e6123c18def94295d0afab7Kenny Root
557c74663799493f2b1e6123c18def94295d0afab7Kenny Root	set_defaults_(encoder);
558c74663799493f2b1e6123c18def94295d0afab7Kenny Root
559c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->is_being_deleted = false;
560c74663799493f2b1e6123c18def94295d0afab7Kenny Root
561c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
562c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->subframe_workspace_ptr[i][0] = &encoder->private_->subframe_workspace[i][0];
563c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->subframe_workspace_ptr[i][1] = &encoder->private_->subframe_workspace[i][1];
564c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
565c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < 2; i++) {
566c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->subframe_workspace_ptr_mid_side[i][0] = &encoder->private_->subframe_workspace_mid_side[i][0];
567c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->subframe_workspace_ptr_mid_side[i][1] = &encoder->private_->subframe_workspace_mid_side[i][1];
568c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
569c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
570c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->partitioned_rice_contents_workspace_ptr[i][0] = &encoder->private_->partitioned_rice_contents_workspace[i][0];
571c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->partitioned_rice_contents_workspace_ptr[i][1] = &encoder->private_->partitioned_rice_contents_workspace[i][1];
572c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
573c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < 2; i++) {
574c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[i][0] = &encoder->private_->partitioned_rice_contents_workspace_mid_side[i][0];
575c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[i][1] = &encoder->private_->partitioned_rice_contents_workspace_mid_side[i][1];
576c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
577c74663799493f2b1e6123c18def94295d0afab7Kenny Root
578c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
579c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace[i][0]);
580c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace[i][1]);
581c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
582c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < 2; i++) {
583c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][0]);
584c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][1]);
585c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
586c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < 2; i++)
587c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_extra[i]);
588c74663799493f2b1e6123c18def94295d0afab7Kenny Root
589c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED;
590c74663799493f2b1e6123c18def94295d0afab7Kenny Root
591c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder;
592c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
593c74663799493f2b1e6123c18def94295d0afab7Kenny Root
594c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder)
595c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
596c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned i;
597c74663799493f2b1e6123c18def94295d0afab7Kenny Root
598c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
599c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
600c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
601c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_->frame);
602c74663799493f2b1e6123c18def94295d0afab7Kenny Root
603c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->is_being_deleted = true;
604c74663799493f2b1e6123c18def94295d0afab7Kenny Root
605c74663799493f2b1e6123c18def94295d0afab7Kenny Root	(void)FLAC__stream_encoder_finish(encoder);
606c74663799493f2b1e6123c18def94295d0afab7Kenny Root
607c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 != encoder->private_->verify.decoder)
608c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__stream_decoder_delete(encoder->private_->verify.decoder);
609c74663799493f2b1e6123c18def94295d0afab7Kenny Root
610c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < FLAC__MAX_CHANNELS; i++) {
611c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace[i][0]);
612c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace[i][1]);
613c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
614c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < 2; i++) {
615c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][0]);
616c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][1]);
617c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
618c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < 2; i++)
619c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_extra[i]);
620c74663799493f2b1e6123c18def94295d0afab7Kenny Root
621c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bitwriter_delete(encoder->private_->frame);
622c74663799493f2b1e6123c18def94295d0afab7Kenny Root	free(encoder->private_);
623c74663799493f2b1e6123c18def94295d0afab7Kenny Root	free(encoder->protected_);
624c74663799493f2b1e6123c18def94295d0afab7Kenny Root	free(encoder);
625c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
626c74663799493f2b1e6123c18def94295d0afab7Kenny Root
627c74663799493f2b1e6123c18def94295d0afab7Kenny Root/***********************************************************************
628c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
629c74663799493f2b1e6123c18def94295d0afab7Kenny Root * Public class methods
630c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
631c74663799493f2b1e6123c18def94295d0afab7Kenny Root ***********************************************************************/
632c74663799493f2b1e6123c18def94295d0afab7Kenny Root
633c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__StreamEncoderInitStatus init_stream_internal_(
634c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
635c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderReadCallback read_callback,
636c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderWriteCallback write_callback,
637c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderSeekCallback seek_callback,
638c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderTellCallback tell_callback,
639c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderMetadataCallback metadata_callback,
640c74663799493f2b1e6123c18def94295d0afab7Kenny Root	void *client_data,
641c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool is_ogg
642c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
643c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
644c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned i;
645c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool metadata_has_seektable, metadata_has_vorbis_comment, metadata_picture_has_type1, metadata_picture_has_type2;
646c74663799493f2b1e6123c18def94295d0afab7Kenny Root
647c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
648c74663799493f2b1e6123c18def94295d0afab7Kenny Root
649c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
650c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED;
651c74663799493f2b1e6123c18def94295d0afab7Kenny Root
652c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if !FLAC__HAS_OGG
653c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(is_ogg)
654c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER;
655c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
656c74663799493f2b1e6123c18def94295d0afab7Kenny Root
657c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 == write_callback || (seek_callback && 0 == tell_callback))
658c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS;
659c74663799493f2b1e6123c18def94295d0afab7Kenny Root
660c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->channels == 0 || encoder->protected_->channels > FLAC__MAX_CHANNELS)
661c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS;
662c74663799493f2b1e6123c18def94295d0afab7Kenny Root
663c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->channels != 2) {
664c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->do_mid_side_stereo = false;
665c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->loose_mid_side_stereo = false;
666c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
667c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else if(!encoder->protected_->do_mid_side_stereo)
668c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->loose_mid_side_stereo = false;
669c74663799493f2b1e6123c18def94295d0afab7Kenny Root
670c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->bits_per_sample >= 32)
671c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->do_mid_side_stereo = false; /* since we currenty do 32-bit math, the side channel would have 33 bps and overflow */
672c74663799493f2b1e6123c18def94295d0afab7Kenny Root
673c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->bits_per_sample < FLAC__MIN_BITS_PER_SAMPLE || encoder->protected_->bits_per_sample > FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE)
674c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE;
675c74663799493f2b1e6123c18def94295d0afab7Kenny Root
676c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!FLAC__format_sample_rate_is_valid(encoder->protected_->sample_rate))
677c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE;
678c74663799493f2b1e6123c18def94295d0afab7Kenny Root
679c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->blocksize == 0) {
680c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->protected_->max_lpc_order == 0)
681c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->blocksize = 1152;
682c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else
683c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->blocksize = 4096;
684c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
685c74663799493f2b1e6123c18def94295d0afab7Kenny Root
686c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->blocksize < FLAC__MIN_BLOCK_SIZE || encoder->protected_->blocksize > FLAC__MAX_BLOCK_SIZE)
687c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE;
688c74663799493f2b1e6123c18def94295d0afab7Kenny Root
689c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->max_lpc_order > FLAC__MAX_LPC_ORDER)
690c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER;
691c74663799493f2b1e6123c18def94295d0afab7Kenny Root
692c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->blocksize < encoder->protected_->max_lpc_order)
693c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER;
694c74663799493f2b1e6123c18def94295d0afab7Kenny Root
695c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->qlp_coeff_precision == 0) {
696c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->protected_->bits_per_sample < 16) {
697c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* @@@ need some data about how to set this here w.r.t. blocksize and sample rate */
698c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* @@@ until then we'll make a guess */
699c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->qlp_coeff_precision = max(FLAC__MIN_QLP_COEFF_PRECISION, 2 + encoder->protected_->bits_per_sample / 2);
700c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
701c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(encoder->protected_->bits_per_sample == 16) {
702c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(encoder->protected_->blocksize <= 192)
703c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->qlp_coeff_precision = 7;
704c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else if(encoder->protected_->blocksize <= 384)
705c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->qlp_coeff_precision = 8;
706c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else if(encoder->protected_->blocksize <= 576)
707c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->qlp_coeff_precision = 9;
708c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else if(encoder->protected_->blocksize <= 1152)
709c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->qlp_coeff_precision = 10;
710c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else if(encoder->protected_->blocksize <= 2304)
711c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->qlp_coeff_precision = 11;
712c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else if(encoder->protected_->blocksize <= 4608)
713c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->qlp_coeff_precision = 12;
714c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else
715c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->qlp_coeff_precision = 13;
716c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
717c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else {
718c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(encoder->protected_->blocksize <= 384)
719c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION-2;
720c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else if(encoder->protected_->blocksize <= 1152)
721c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION-1;
722c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else
723c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION;
724c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
725c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ASSERT(encoder->protected_->qlp_coeff_precision <= FLAC__MAX_QLP_COEFF_PRECISION);
726c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
727c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else if(encoder->protected_->qlp_coeff_precision < FLAC__MIN_QLP_COEFF_PRECISION || encoder->protected_->qlp_coeff_precision > FLAC__MAX_QLP_COEFF_PRECISION)
728c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION;
729c74663799493f2b1e6123c18def94295d0afab7Kenny Root
730c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->streamable_subset) {
731c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(
732c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->blocksize != 192 &&
733c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->blocksize != 576 &&
734c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->blocksize != 1152 &&
735c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->blocksize != 2304 &&
736c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->blocksize != 4608 &&
737c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->blocksize != 256 &&
738c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->blocksize != 512 &&
739c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->blocksize != 1024 &&
740c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->blocksize != 2048 &&
741c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->blocksize != 4096 &&
742c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->blocksize != 8192 &&
743c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->blocksize != 16384
744c74663799493f2b1e6123c18def94295d0afab7Kenny Root		)
745c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
746c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(!FLAC__format_sample_rate_is_subset(encoder->protected_->sample_rate))
747c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
748c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(
749c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->bits_per_sample != 8 &&
750c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->bits_per_sample != 12 &&
751c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->bits_per_sample != 16 &&
752c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->bits_per_sample != 20 &&
753c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->bits_per_sample != 24
754c74663799493f2b1e6123c18def94295d0afab7Kenny Root		)
755c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
756c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->protected_->max_residual_partition_order > FLAC__SUBSET_MAX_RICE_PARTITION_ORDER)
757c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
758c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(
759c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->sample_rate <= 48000 &&
760c74663799493f2b1e6123c18def94295d0afab7Kenny Root			(
761c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->blocksize > FLAC__SUBSET_MAX_BLOCK_SIZE_48000HZ ||
762c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->max_lpc_order > FLAC__SUBSET_MAX_LPC_ORDER_48000HZ
763c74663799493f2b1e6123c18def94295d0afab7Kenny Root			)
764c74663799493f2b1e6123c18def94295d0afab7Kenny Root		) {
765c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
766c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
767c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
768c74663799493f2b1e6123c18def94295d0afab7Kenny Root
769c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->max_residual_partition_order >= (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
770c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->max_residual_partition_order = (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN) - 1;
771c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->min_residual_partition_order >= encoder->protected_->max_residual_partition_order)
772c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->min_residual_partition_order = encoder->protected_->max_residual_partition_order;
773c74663799493f2b1e6123c18def94295d0afab7Kenny Root
774c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if FLAC__HAS_OGG
775c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* reorder metadata if necessary to ensure that any VORBIS_COMMENT is the first, according to the mapping spec */
776c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(is_ogg && 0 != encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 1) {
777c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned i;
778c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(i = 1; i < encoder->protected_->num_metadata_blocks; i++) {
779c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(0 != encoder->protected_->metadata[i] && encoder->protected_->metadata[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
780c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__StreamMetadata *vc = encoder->protected_->metadata[i];
781c74663799493f2b1e6123c18def94295d0afab7Kenny Root				for( ; i > 0; i--)
782c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->protected_->metadata[i] = encoder->protected_->metadata[i-1];
783c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->metadata[0] = vc;
784c74663799493f2b1e6123c18def94295d0afab7Kenny Root				break;
785c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
786c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
787c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
788c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
789c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* keep track of any SEEKTABLE block */
790c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 != encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 0) {
791c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned i;
792c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(i = 0; i < encoder->protected_->num_metadata_blocks; i++) {
793c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(0 != encoder->protected_->metadata[i] && encoder->protected_->metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) {
794c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->seek_table = &encoder->protected_->metadata[i]->data.seek_table;
795c74663799493f2b1e6123c18def94295d0afab7Kenny Root				break; /* take only the first one */
796c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
797c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
798c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
799c74663799493f2b1e6123c18def94295d0afab7Kenny Root
800c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* validate metadata */
801c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 == encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 0)
802c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
803c74663799493f2b1e6123c18def94295d0afab7Kenny Root	metadata_has_seektable = false;
804c74663799493f2b1e6123c18def94295d0afab7Kenny Root	metadata_has_vorbis_comment = false;
805c74663799493f2b1e6123c18def94295d0afab7Kenny Root	metadata_picture_has_type1 = false;
806c74663799493f2b1e6123c18def94295d0afab7Kenny Root	metadata_picture_has_type2 = false;
807c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < encoder->protected_->num_metadata_blocks; i++) {
808c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const FLAC__StreamMetadata *m = encoder->protected_->metadata[i];
809c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(m->type == FLAC__METADATA_TYPE_STREAMINFO)
810c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
811c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(m->type == FLAC__METADATA_TYPE_SEEKTABLE) {
812c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(metadata_has_seektable) /* only one is allowed */
813c74663799493f2b1e6123c18def94295d0afab7Kenny Root				return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
814c74663799493f2b1e6123c18def94295d0afab7Kenny Root			metadata_has_seektable = true;
815c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(!FLAC__format_seektable_is_legal(&m->data.seek_table))
816c74663799493f2b1e6123c18def94295d0afab7Kenny Root				return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
817c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
818c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(m->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
819c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(metadata_has_vorbis_comment) /* only one is allowed */
820c74663799493f2b1e6123c18def94295d0afab7Kenny Root				return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
821c74663799493f2b1e6123c18def94295d0afab7Kenny Root			metadata_has_vorbis_comment = true;
822c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
823c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(m->type == FLAC__METADATA_TYPE_CUESHEET) {
824c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(!FLAC__format_cuesheet_is_legal(&m->data.cue_sheet, m->data.cue_sheet.is_cd, /*violation=*/0))
825c74663799493f2b1e6123c18def94295d0afab7Kenny Root				return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
826c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
827c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(m->type == FLAC__METADATA_TYPE_PICTURE) {
828c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(!FLAC__format_picture_is_legal(&m->data.picture, /*violation=*/0))
829c74663799493f2b1e6123c18def94295d0afab7Kenny Root				return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
830c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(m->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD) {
831c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(metadata_picture_has_type1) /* there should only be 1 per stream */
832c74663799493f2b1e6123c18def94295d0afab7Kenny Root					return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
833c74663799493f2b1e6123c18def94295d0afab7Kenny Root				metadata_picture_has_type1 = true;
834c74663799493f2b1e6123c18def94295d0afab7Kenny Root				/* standard icon must be 32x32 pixel PNG */
835c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(
836c74663799493f2b1e6123c18def94295d0afab7Kenny Root					m->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD &&
837c74663799493f2b1e6123c18def94295d0afab7Kenny Root					(
838c74663799493f2b1e6123c18def94295d0afab7Kenny Root						(strcmp(m->data.picture.mime_type, "image/png") && strcmp(m->data.picture.mime_type, "-->")) ||
839c74663799493f2b1e6123c18def94295d0afab7Kenny Root						m->data.picture.width != 32 ||
840c74663799493f2b1e6123c18def94295d0afab7Kenny Root						m->data.picture.height != 32
841c74663799493f2b1e6123c18def94295d0afab7Kenny Root					)
842c74663799493f2b1e6123c18def94295d0afab7Kenny Root				)
843c74663799493f2b1e6123c18def94295d0afab7Kenny Root					return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
844c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
845c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else if(m->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON) {
846c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(metadata_picture_has_type2) /* there should only be 1 per stream */
847c74663799493f2b1e6123c18def94295d0afab7Kenny Root					return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA;
848c74663799493f2b1e6123c18def94295d0afab7Kenny Root				metadata_picture_has_type2 = true;
849c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
850c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
851c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
852c74663799493f2b1e6123c18def94295d0afab7Kenny Root
853c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->input_capacity = 0;
854c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < encoder->protected_->channels; i++) {
855c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->integer_signal_unaligned[i] = encoder->private_->integer_signal[i] = 0;
856c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
857c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->real_signal_unaligned[i] = encoder->private_->real_signal[i] = 0;
858c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
859c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
860c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < 2; i++) {
861c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->integer_signal_mid_side_unaligned[i] = encoder->private_->integer_signal_mid_side[i] = 0;
862c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
863c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->real_signal_mid_side_unaligned[i] = encoder->private_->real_signal_mid_side[i] = 0;
864c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
865c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
866c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
867c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < encoder->protected_->num_apodizations; i++)
868c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->window_unaligned[i] = encoder->private_->window[i] = 0;
869c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->windowed_signal_unaligned = encoder->private_->windowed_signal = 0;
870c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
871c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < encoder->protected_->channels; i++) {
872c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->residual_workspace_unaligned[i][0] = encoder->private_->residual_workspace[i][0] = 0;
873c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->residual_workspace_unaligned[i][1] = encoder->private_->residual_workspace[i][1] = 0;
874c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->best_subframe[i] = 0;
875c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
876c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < 2; i++) {
877c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->residual_workspace_mid_side_unaligned[i][0] = encoder->private_->residual_workspace_mid_side[i][0] = 0;
878c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->residual_workspace_mid_side_unaligned[i][1] = encoder->private_->residual_workspace_mid_side[i][1] = 0;
879c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->best_subframe_mid_side[i] = 0;
880c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
881c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->abs_residual_partition_sums_unaligned = encoder->private_->abs_residual_partition_sums = 0;
882c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->raw_bits_per_partition_unaligned = encoder->private_->raw_bits_per_partition = 0;
883c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
884c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->loose_mid_side_stereo_frames = (unsigned)((FLAC__double)encoder->protected_->sample_rate * 0.4 / (FLAC__double)encoder->protected_->blocksize + 0.5);
885c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
886c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* 26214 is the approximate fixed-point equivalent to 0.4 (0.4 * 2^16) */
887c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* sample rate can be up to 655350 Hz, and thus use 20 bits, so we do the multiply&divide by hand */
888c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(FLAC__MAX_SAMPLE_RATE <= 655350);
889c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(FLAC__MAX_BLOCK_SIZE <= 65535);
890c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(encoder->protected_->sample_rate <= 655350);
891c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(encoder->protected_->blocksize <= 65535);
892c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->loose_mid_side_stereo_frames = (unsigned)FLAC__fixedpoint_trunc((((FLAC__uint64)(encoder->protected_->sample_rate) * (FLAC__uint64)(26214)) << 16) / (encoder->protected_->blocksize<<16) + FLAC__FP_ONE_HALF);
893c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
894c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->private_->loose_mid_side_stereo_frames == 0)
895c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->loose_mid_side_stereo_frames = 1;
896c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->loose_mid_side_stereo_frame_count = 0;
897c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->current_sample_number = 0;
898c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->current_frame_number = 0;
899c74663799493f2b1e6123c18def94295d0afab7Kenny Root
900c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->use_wide_by_block = (encoder->protected_->bits_per_sample + FLAC__bitmath_ilog2(encoder->protected_->blocksize)+1 > 30);
901c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->use_wide_by_order = (encoder->protected_->bits_per_sample + FLAC__bitmath_ilog2(max(encoder->protected_->max_lpc_order, FLAC__MAX_FIXED_ORDER))+1 > 30); /*@@@ need to use this? */
902c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->use_wide_by_partition = (false); /*@@@ need to set this */
903c74663799493f2b1e6123c18def94295d0afab7Kenny Root
904c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
905c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * get the CPU info and set the function pointers
906c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
907c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__cpu_info(&encoder->private_->cpuinfo);
908c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* first default to the non-asm routines */
909c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
910c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation;
911c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
912c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor;
913c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
914c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients;
915c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide;
916c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients;
917c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
918c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* now override with asm where appropriate */
919c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
920c74663799493f2b1e6123c18def94295d0afab7Kenny Root# ifndef FLAC__NO_ASM
921c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->private_->cpuinfo.use_asm) {
922c74663799493f2b1e6123c18def94295d0afab7Kenny Root#  ifdef FLAC__CPU_IA32
923c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
924c74663799493f2b1e6123c18def94295d0afab7Kenny Root#   ifdef FLAC__HAS_NASM
925c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->private_->cpuinfo.data.ia32.sse) {
926c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(encoder->protected_->max_lpc_order < 4)
927c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4;
928c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else if(encoder->protected_->max_lpc_order < 8)
929c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8;
930c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else if(encoder->protected_->max_lpc_order < 12)
931c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12;
932c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else
933c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32;
934c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
935c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(encoder->private_->cpuinfo.data.ia32._3dnow)
936c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_3dnow;
937c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else
938c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32;
939c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->private_->cpuinfo.data.ia32.mmx) {
940c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32;
941c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx;
942c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
943c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else {
944c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32;
945c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32;
946c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
947c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->private_->cpuinfo.data.ia32.mmx && encoder->private_->cpuinfo.data.ia32.cmov)
948c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov;
949c74663799493f2b1e6123c18def94295d0afab7Kenny Root#   endif /* FLAC__HAS_NASM */
950c74663799493f2b1e6123c18def94295d0afab7Kenny Root#  endif /* FLAC__CPU_IA32 */
951c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
952c74663799493f2b1e6123c18def94295d0afab7Kenny Root# endif /* !FLAC__NO_ASM */
953c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif /* !FLAC__INTEGER_ONLY_LIBRARY */
954c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* finally override based on wide-ness if necessary */
955c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->private_->use_wide_by_block) {
956c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_wide;
957c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
958c74663799493f2b1e6123c18def94295d0afab7Kenny Root
959c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* set state to OK; from here on, errors are fatal and we'll override the state then */
960c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->state = FLAC__STREAM_ENCODER_OK;
961c74663799493f2b1e6123c18def94295d0afab7Kenny Root
962c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if FLAC__HAS_OGG
963c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->is_ogg = is_ogg;
964c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(is_ogg && !FLAC__ogg_encoder_aspect_init(&encoder->protected_->ogg_encoder_aspect)) {
965c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
966c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
967c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
968c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
969c74663799493f2b1e6123c18def94295d0afab7Kenny Root
970c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->read_callback = read_callback;
971c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->write_callback = write_callback;
972c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->seek_callback = seek_callback;
973c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->tell_callback = tell_callback;
974c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->metadata_callback = metadata_callback;
975c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->client_data = client_data;
976c74663799493f2b1e6123c18def94295d0afab7Kenny Root
977c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!resize_buffers_(encoder, encoder->protected_->blocksize)) {
978c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/* the above function sets the state for us in case of an error */
979c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
980c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
981c74663799493f2b1e6123c18def94295d0afab7Kenny Root
982c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!FLAC__bitwriter_init(encoder->private_->frame)) {
983c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
984c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
985c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
986c74663799493f2b1e6123c18def94295d0afab7Kenny Root
987c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
988c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Set up the verify stuff if necessary
989c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
990c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->verify) {
991c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/*
992c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 * First, set up the fifo which will hold the
993c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 * original signal to compare against
994c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 */
995c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->verify.input_fifo.size = encoder->protected_->blocksize+OVERREAD_;
996c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(i = 0; i < encoder->protected_->channels; i++) {
997c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(0 == (encoder->private_->verify.input_fifo.data[i] = (FLAC__int32*)safe_malloc_mul_2op_(sizeof(FLAC__int32), /*times*/encoder->private_->verify.input_fifo.size))) {
998c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
999c74663799493f2b1e6123c18def94295d0afab7Kenny Root				return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
1000c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
1001c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
1002c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->verify.input_fifo.tail = 0;
1003c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1004c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/*
1005c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 * Now set up a stream decoder for verification
1006c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 */
1007c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->verify.decoder = FLAC__stream_decoder_new();
1008c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(0 == encoder->private_->verify.decoder) {
1009c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR;
1010c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
1011c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
1012c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1013c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(FLAC__stream_decoder_init_stream(encoder->private_->verify.decoder, verify_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, verify_write_callback_, verify_metadata_callback_, verify_error_callback_, /*client_data=*/encoder) != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
1014c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR;
1015c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
1016c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
1017c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1018c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->verify.error_stats.absolute_sample = 0;
1019c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->verify.error_stats.frame_number = 0;
1020c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->verify.error_stats.channel = 0;
1021c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->verify.error_stats.sample = 0;
1022c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->verify.error_stats.expected = 0;
1023c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->verify.error_stats.got = 0;
1024c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1025c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
1026c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * These must be done before we write any metadata, because that
1027c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * calls the write_callback, which uses these values.
1028c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
1029c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->first_seekpoint_to_check = 0;
1030c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->samples_written = 0;
1031c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->streaminfo_offset = 0;
1032c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->seektable_offset = 0;
1033c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->audio_offset = 0;
1034c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1035c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
1036c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * write the stream header
1037c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
1038c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->verify)
1039c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->verify.state_hint = ENCODER_IN_MAGIC;
1040c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!FLAC__bitwriter_write_raw_uint32(encoder->private_->frame, FLAC__STREAM_SYNC, FLAC__STREAM_SYNC_LEN)) {
1041c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
1042c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
1043c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1044c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!write_bitbuffer_(encoder, 0, /*is_last_block=*/false)) {
1045c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/* the above function sets the state for us in case of an error */
1046c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
1047c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1048c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1049c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
1050c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * write the STREAMINFO metadata block
1051c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
1052c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->verify)
1053c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->verify.state_hint = ENCODER_IN_METADATA;
1054c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->streaminfo.type = FLAC__METADATA_TYPE_STREAMINFO;
1055c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->streaminfo.is_last = false; /* we will have at a minimum a VORBIS_COMMENT afterwards */
1056c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->streaminfo.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
1057c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->streaminfo.data.stream_info.min_blocksize = encoder->protected_->blocksize; /* this encoder uses the same blocksize for the whole stream */
1058c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->streaminfo.data.stream_info.max_blocksize = encoder->protected_->blocksize;
1059c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->streaminfo.data.stream_info.min_framesize = 0; /* we don't know this yet; have to fill it in later */
1060c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->streaminfo.data.stream_info.max_framesize = 0; /* we don't know this yet; have to fill it in later */
1061c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->streaminfo.data.stream_info.sample_rate = encoder->protected_->sample_rate;
1062c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->streaminfo.data.stream_info.channels = encoder->protected_->channels;
1063c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->streaminfo.data.stream_info.bits_per_sample = encoder->protected_->bits_per_sample;
1064c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->streaminfo.data.stream_info.total_samples = encoder->protected_->total_samples_estimate; /* we will replace this later with the real total */
1065c74663799493f2b1e6123c18def94295d0afab7Kenny Root	memset(encoder->private_->streaminfo.data.stream_info.md5sum, 0, 16); /* we don't know this yet; have to fill it in later */
1066c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->do_md5)
1067c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__MD5Init(&encoder->private_->md5context);
1068c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!FLAC__add_metadata_block(&encoder->private_->streaminfo, encoder->private_->frame)) {
1069c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
1070c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
1071c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1072c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!write_bitbuffer_(encoder, 0, /*is_last_block=*/false)) {
1073c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/* the above function sets the state for us in case of an error */
1074c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
1075c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1076c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1077c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
1078c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Now that the STREAMINFO block is written, we can init this to an
1079c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * absurdly-high value...
1080c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
1081c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->streaminfo.data.stream_info.min_framesize = (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN) - 1;
1082c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* ... and clear this to 0 */
1083c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->streaminfo.data.stream_info.total_samples = 0;
1084c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1085c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
1086c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Check to see if the supplied metadata contains a VORBIS_COMMENT;
1087c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * if not, we will write an empty one (FLAC__add_metadata_block()
1088c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * automatically supplies the vendor string).
1089c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 *
1090c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * WATCHOUT: the Ogg FLAC mapping requires us to write this block after
1091c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * the STREAMINFO.  (In the case that metadata_has_vorbis_comment is
1092c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * true it will have already insured that the metadata list is properly
1093c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * ordered.)
1094c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
1095c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!metadata_has_vorbis_comment) {
1096c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__StreamMetadata vorbis_comment;
1097c74663799493f2b1e6123c18def94295d0afab7Kenny Root		vorbis_comment.type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
1098c74663799493f2b1e6123c18def94295d0afab7Kenny Root		vorbis_comment.is_last = (encoder->protected_->num_metadata_blocks == 0);
1099c74663799493f2b1e6123c18def94295d0afab7Kenny Root		vorbis_comment.length = 4 + 4; /* MAGIC NUMBER */
1100c74663799493f2b1e6123c18def94295d0afab7Kenny Root		vorbis_comment.data.vorbis_comment.vendor_string.length = 0;
1101c74663799493f2b1e6123c18def94295d0afab7Kenny Root		vorbis_comment.data.vorbis_comment.vendor_string.entry = 0;
1102c74663799493f2b1e6123c18def94295d0afab7Kenny Root		vorbis_comment.data.vorbis_comment.num_comments = 0;
1103c74663799493f2b1e6123c18def94295d0afab7Kenny Root		vorbis_comment.data.vorbis_comment.comments = 0;
1104c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(!FLAC__add_metadata_block(&vorbis_comment, encoder->private_->frame)) {
1105c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
1106c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
1107c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
1108c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(!write_bitbuffer_(encoder, 0, /*is_last_block=*/false)) {
1109c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* the above function sets the state for us in case of an error */
1110c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
1111c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
1112c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1113c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1114c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
1115c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * write the user's metadata blocks
1116c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
1117c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < encoder->protected_->num_metadata_blocks; i++) {
1118c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->metadata[i]->is_last = (i == encoder->protected_->num_metadata_blocks - 1);
1119c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(!FLAC__add_metadata_block(encoder->protected_->metadata[i], encoder->private_->frame)) {
1120c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
1121c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
1122c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
1123c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(!write_bitbuffer_(encoder, 0, /*is_last_block=*/false)) {
1124c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* the above function sets the state for us in case of an error */
1125c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
1126c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
1127c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1128c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1129c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* now that all the metadata is written, we save the stream offset */
1130c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->private_->tell_callback && encoder->private_->tell_callback(encoder, &encoder->protected_->audio_offset, encoder->private_->client_data) == FLAC__STREAM_ENCODER_TELL_STATUS_ERROR) { /* FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED just means we didn't get the offset; no error */
1131c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
1132c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
1133c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1134c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1135c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->verify)
1136c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->verify.state_hint = ENCODER_IN_AUDIO;
1137c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1138c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return FLAC__STREAM_ENCODER_INIT_STATUS_OK;
1139c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1140c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1141c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_stream(
1142c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
1143c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderWriteCallback write_callback,
1144c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderSeekCallback seek_callback,
1145c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderTellCallback tell_callback,
1146c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderMetadataCallback metadata_callback,
1147c74663799493f2b1e6123c18def94295d0afab7Kenny Root	void *client_data
1148c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
1149c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1150c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return init_stream_internal_(
1151c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder,
1152c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/*read_callback=*/0,
1153c74663799493f2b1e6123c18def94295d0afab7Kenny Root		write_callback,
1154c74663799493f2b1e6123c18def94295d0afab7Kenny Root		seek_callback,
1155c74663799493f2b1e6123c18def94295d0afab7Kenny Root		tell_callback,
1156c74663799493f2b1e6123c18def94295d0afab7Kenny Root		metadata_callback,
1157c74663799493f2b1e6123c18def94295d0afab7Kenny Root		client_data,
1158c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/*is_ogg=*/false
1159c74663799493f2b1e6123c18def94295d0afab7Kenny Root	);
1160c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1161c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1162c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_stream(
1163c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
1164c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderReadCallback read_callback,
1165c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderWriteCallback write_callback,
1166c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderSeekCallback seek_callback,
1167c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderTellCallback tell_callback,
1168c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderMetadataCallback metadata_callback,
1169c74663799493f2b1e6123c18def94295d0afab7Kenny Root	void *client_data
1170c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
1171c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1172c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return init_stream_internal_(
1173c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder,
1174c74663799493f2b1e6123c18def94295d0afab7Kenny Root		read_callback,
1175c74663799493f2b1e6123c18def94295d0afab7Kenny Root		write_callback,
1176c74663799493f2b1e6123c18def94295d0afab7Kenny Root		seek_callback,
1177c74663799493f2b1e6123c18def94295d0afab7Kenny Root		tell_callback,
1178c74663799493f2b1e6123c18def94295d0afab7Kenny Root		metadata_callback,
1179c74663799493f2b1e6123c18def94295d0afab7Kenny Root		client_data,
1180c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/*is_ogg=*/true
1181c74663799493f2b1e6123c18def94295d0afab7Kenny Root	);
1182c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1183c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1184c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__StreamEncoderInitStatus init_FILE_internal_(
1185c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
1186c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FILE *file,
1187c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderProgressCallback progress_callback,
1188c74663799493f2b1e6123c18def94295d0afab7Kenny Root	void *client_data,
1189c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool is_ogg
1190c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
1191c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1192c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderInitStatus init_status;
1193c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1194c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1195c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != file);
1196c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1197c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1198c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED;
1199c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1200c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* double protection */
1201c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(file == 0) {
1202c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->state = FLAC__STREAM_ENCODER_IO_ERROR;
1203c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
1204c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1205c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1206c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
1207c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * To make sure that our file does not go unclosed after an error, we
1208c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * must assign the FILE pointer before any further error can occur in
1209c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * this routine.
1210c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
1211c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(file == stdout)
1212c74663799493f2b1e6123c18def94295d0afab7Kenny Root		file = get_binary_stdout_(); /* just to be safe */
1213c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1214c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->file = file;
1215c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1216c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->progress_callback = progress_callback;
1217c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->bytes_written = 0;
1218c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->samples_written = 0;
1219c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->frames_written = 0;
1220c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1221c74663799493f2b1e6123c18def94295d0afab7Kenny Root	init_status = init_stream_internal_(
1222c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder,
1223c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->file == stdout? 0 : is_ogg? file_read_callback_ : 0,
1224c74663799493f2b1e6123c18def94295d0afab7Kenny Root		file_write_callback_,
1225c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->file == stdout? 0 : file_seek_callback_,
1226c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->file == stdout? 0 : file_tell_callback_,
1227c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/*metadata_callback=*/0,
1228c74663799493f2b1e6123c18def94295d0afab7Kenny Root		client_data,
1229c74663799493f2b1e6123c18def94295d0afab7Kenny Root		is_ogg
1230c74663799493f2b1e6123c18def94295d0afab7Kenny Root	);
1231c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
1232c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/* the above function sets the state for us in case of an error */
1233c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return init_status;
1234c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1235c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1236c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{
1237c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder);
1238c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1239c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ASSERT(blocksize != 0);
1240c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->total_frames_estimate = (unsigned)((FLAC__stream_encoder_get_total_samples_estimate(encoder) + blocksize - 1) / blocksize);
1241c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1242c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1243c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return init_status;
1244c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1245c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1246c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_FILE(
1247c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
1248c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FILE *file,
1249c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderProgressCallback progress_callback,
1250c74663799493f2b1e6123c18def94295d0afab7Kenny Root	void *client_data
1251c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
1252c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1253c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return init_FILE_internal_(encoder, file, progress_callback, client_data, /*is_ogg=*/false);
1254c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1255c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1256c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_FILE(
1257c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
1258c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FILE *file,
1259c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderProgressCallback progress_callback,
1260c74663799493f2b1e6123c18def94295d0afab7Kenny Root	void *client_data
1261c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
1262c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1263c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return init_FILE_internal_(encoder, file, progress_callback, client_data, /*is_ogg=*/true);
1264c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1265c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1266c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLAC__StreamEncoderInitStatus init_file_internal_(
1267c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
1268c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const char *filename,
1269c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderProgressCallback progress_callback,
1270c74663799493f2b1e6123c18def94295d0afab7Kenny Root	void *client_data,
1271c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool is_ogg
1272c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
1273c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1274c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FILE *file;
1275c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1276c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1277c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1278c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
1279c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * To make sure that our file does not go unclosed after an error, we
1280c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * have to do the same entrance checks here that are later performed
1281c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * in FLAC__stream_encoder_init_FILE() before the FILE* is assigned.
1282c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
1283c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1284c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED;
1285c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1286c74663799493f2b1e6123c18def94295d0afab7Kenny Root	file = filename? fopen(filename, "w+b") : stdout;
1287c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1288c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(file == 0) {
1289c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->state = FLAC__STREAM_ENCODER_IO_ERROR;
1290c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
1291c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1292c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1293c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return init_FILE_internal_(encoder, file, progress_callback, client_data, is_ogg);
1294c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1295c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1296c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_file(
1297c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
1298c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const char *filename,
1299c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderProgressCallback progress_callback,
1300c74663799493f2b1e6123c18def94295d0afab7Kenny Root	void *client_data
1301c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
1302c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1303c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return init_file_internal_(encoder, filename, progress_callback, client_data, /*is_ogg=*/false);
1304c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1305c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1306c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_file(
1307c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
1308c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const char *filename,
1309c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderProgressCallback progress_callback,
1310c74663799493f2b1e6123c18def94295d0afab7Kenny Root	void *client_data
1311c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
1312c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1313c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return init_file_internal_(encoder, filename, progress_callback, client_data, /*is_ogg=*/true);
1314c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1315c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1316c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder)
1317c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1318c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool error = false;
1319c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1320c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1321c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1322c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1323c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1324c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state == FLAC__STREAM_ENCODER_UNINITIALIZED)
1325c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return true;
1326c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1327c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state == FLAC__STREAM_ENCODER_OK && !encoder->private_->is_being_deleted) {
1328c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->private_->current_sample_number != 0) {
1329c74663799493f2b1e6123c18def94295d0afab7Kenny Root			const FLAC__bool is_fractional_block = encoder->protected_->blocksize != encoder->private_->current_sample_number;
1330c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->blocksize = encoder->private_->current_sample_number;
1331c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(!process_frame_(encoder, is_fractional_block, /*is_last_block=*/true))
1332c74663799493f2b1e6123c18def94295d0afab7Kenny Root				error = true;
1333c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
1334c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1335c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1336c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->do_md5)
1337c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__MD5Final(encoder->private_->streaminfo.data.stream_info.md5sum, &encoder->private_->md5context);
1338c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1339c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!encoder->private_->is_being_deleted) {
1340c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->protected_->state == FLAC__STREAM_ENCODER_OK) {
1341c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(encoder->private_->seek_callback) {
1342c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if FLAC__HAS_OGG
1343c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(encoder->private_->is_ogg)
1344c74663799493f2b1e6123c18def94295d0afab7Kenny Root					update_ogg_metadata_(encoder);
1345c74663799493f2b1e6123c18def94295d0afab7Kenny Root				else
1346c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
1347c74663799493f2b1e6123c18def94295d0afab7Kenny Root				update_metadata_(encoder);
1348c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1349c74663799493f2b1e6123c18def94295d0afab7Kenny Root				/* check if an error occurred while updating metadata */
1350c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(encoder->protected_->state != FLAC__STREAM_ENCODER_OK)
1351c74663799493f2b1e6123c18def94295d0afab7Kenny Root					error = true;
1352c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
1353c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(encoder->private_->metadata_callback)
1354c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->metadata_callback(encoder, &encoder->private_->streaminfo, encoder->private_->client_data);
1355c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
1356c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1357c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->protected_->verify && 0 != encoder->private_->verify.decoder && !FLAC__stream_decoder_finish(encoder->private_->verify.decoder)) {
1358c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(!error)
1359c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA;
1360c74663799493f2b1e6123c18def94295d0afab7Kenny Root			error = true;
1361c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
1362c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1363c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1364c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 != encoder->private_->file) {
1365c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->private_->file != stdout)
1366c74663799493f2b1e6123c18def94295d0afab7Kenny Root			fclose(encoder->private_->file);
1367c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->file = 0;
1368c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1369c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1370c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if FLAC__HAS_OGG
1371c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->private_->is_ogg)
1372c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ogg_encoder_aspect_finish(&encoder->protected_->ogg_encoder_aspect);
1373c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
1374c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1375c74663799493f2b1e6123c18def94295d0afab7Kenny Root	free_(encoder);
1376c74663799493f2b1e6123c18def94295d0afab7Kenny Root	set_defaults_(encoder);
1377c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1378c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!error)
1379c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED;
1380c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1381c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return !error;
1382c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1383c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1384c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_ogg_serial_number(FLAC__StreamEncoder *encoder, long value)
1385c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1386c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1387c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1388c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1389c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1390c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1391c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if FLAC__HAS_OGG
1392c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* can't check encoder->private_->is_ogg since that's not set until init time */
1393c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ogg_encoder_aspect_set_serial_number(&encoder->protected_->ogg_encoder_aspect, value);
1394c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1395c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
1396c74663799493f2b1e6123c18def94295d0afab7Kenny Root	(void)value;
1397c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return false;
1398c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
1399c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1400c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1401c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value)
1402c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1403c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1404c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1405c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1406c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1407c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1408c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__MANDATORY_VERIFY_WHILE_ENCODING
1409c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->verify = value;
1410c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
1411c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1412c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1413c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1414c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_streamable_subset(FLAC__StreamEncoder *encoder, FLAC__bool value)
1415c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1416c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1417c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1418c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1419c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1420c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1421c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->streamable_subset = value;
1422c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1423c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1424c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1425c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value)
1426c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1427c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1428c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1429c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1430c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1431c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1432c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->do_md5 = value;
1433c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1434c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1435c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1436c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_channels(FLAC__StreamEncoder *encoder, unsigned value)
1437c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1438c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1439c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1440c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1441c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1442c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1443c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->channels = value;
1444c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1445c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1446c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1447c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_bits_per_sample(FLAC__StreamEncoder *encoder, unsigned value)
1448c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1449c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1450c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1451c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1452c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1453c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1454c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->bits_per_sample = value;
1455c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1456c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1457c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1458c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *encoder, unsigned value)
1459c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1460c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1461c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1462c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1463c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1464c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1465c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->sample_rate = value;
1466c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1467c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1468c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1469c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_compression_level(FLAC__StreamEncoder *encoder, unsigned value)
1470c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1471c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool ok = true;
1472c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1473c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1474c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1475c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1476c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1477c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(value >= sizeof(compression_levels_)/sizeof(compression_levels_[0]))
1478c74663799493f2b1e6123c18def94295d0afab7Kenny Root		value = sizeof(compression_levels_)/sizeof(compression_levels_[0]) - 1;
1479c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ok &= FLAC__stream_encoder_set_do_mid_side_stereo          (encoder, compression_levels_[value].do_mid_side_stereo);
1480c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ok &= FLAC__stream_encoder_set_loose_mid_side_stereo       (encoder, compression_levels_[value].loose_mid_side_stereo);
1481c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
1482c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if 0
1483c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* was: */
1484c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ok &= FLAC__stream_encoder_set_apodization                 (encoder, compression_levels_[value].apodization);
1485c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* but it's too hard to specify the string in a locale-specific way */
1486c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
1487c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->num_apodizations = 1;
1488c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY;
1489c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->apodizations[0].parameters.tukey.p = 0.5;
1490c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
1491c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
1492c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ok &= FLAC__stream_encoder_set_max_lpc_order               (encoder, compression_levels_[value].max_lpc_order);
1493c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ok &= FLAC__stream_encoder_set_qlp_coeff_precision         (encoder, compression_levels_[value].qlp_coeff_precision);
1494c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ok &= FLAC__stream_encoder_set_do_qlp_coeff_prec_search    (encoder, compression_levels_[value].do_qlp_coeff_prec_search);
1495c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ok &= FLAC__stream_encoder_set_do_escape_coding            (encoder, compression_levels_[value].do_escape_coding);
1496c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ok &= FLAC__stream_encoder_set_do_exhaustive_model_search  (encoder, compression_levels_[value].do_exhaustive_model_search);
1497c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ok &= FLAC__stream_encoder_set_min_residual_partition_order(encoder, compression_levels_[value].min_residual_partition_order);
1498c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ok &= FLAC__stream_encoder_set_max_residual_partition_order(encoder, compression_levels_[value].max_residual_partition_order);
1499c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ok &= FLAC__stream_encoder_set_rice_parameter_search_dist  (encoder, compression_levels_[value].rice_parameter_search_dist);
1500c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return ok;
1501c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1502c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1503c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_blocksize(FLAC__StreamEncoder *encoder, unsigned value)
1504c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1505c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1506c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1507c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1508c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1509c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1510c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->blocksize = value;
1511c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1512c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1513c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1514c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_do_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value)
1515c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1516c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1517c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1518c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1519c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1520c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1521c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->do_mid_side_stereo = value;
1522c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1523c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1524c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1525c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value)
1526c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1527c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1528c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1529c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1530c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1531c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1532c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->loose_mid_side_stereo = value;
1533c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1534c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1535c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1536c74663799493f2b1e6123c18def94295d0afab7Kenny Root/*@@@@add to tests*/
1537c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *encoder, const char *specification)
1538c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1539c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1540c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1541c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1542c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != specification);
1543c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1544c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1545c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef FLAC__INTEGER_ONLY_LIBRARY
1546c74663799493f2b1e6123c18def94295d0afab7Kenny Root	(void)specification; /* silently ignore since we haven't integerized; will always use a rectangular window */
1547c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
1548c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->num_apodizations = 0;
1549c74663799493f2b1e6123c18def94295d0afab7Kenny Root	while(1) {
1550c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const char *s = strchr(specification, ';');
1551c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const size_t n = s? (size_t)(s - specification) : strlen(specification);
1552c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if     (n==8  && 0 == strncmp("bartlett"     , specification, n))
1553c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BARTLETT;
1554c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(n==13 && 0 == strncmp("bartlett_hann", specification, n))
1555c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BARTLETT_HANN;
1556c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(n==8  && 0 == strncmp("blackman"     , specification, n))
1557c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BLACKMAN;
1558c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(n==26 && 0 == strncmp("blackman_harris_4term_92db", specification, n))
1559c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE;
1560c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(n==6  && 0 == strncmp("connes"       , specification, n))
1561c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_CONNES;
1562c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(n==7  && 0 == strncmp("flattop"      , specification, n))
1563c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_FLATTOP;
1564c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(n>7   && 0 == strncmp("gauss("       , specification, 6)) {
1565c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__real stddev = (FLAC__real)strtod(specification+6, 0);
1566c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if (stddev > 0.0 && stddev <= 0.5) {
1567c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.gauss.stddev = stddev;
1568c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_GAUSS;
1569c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
1570c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
1571c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(n==7  && 0 == strncmp("hamming"      , specification, n))
1572c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_HAMMING;
1573c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(n==4  && 0 == strncmp("hann"         , specification, n))
1574c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_HANN;
1575c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(n==13 && 0 == strncmp("kaiser_bessel", specification, n))
1576c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_KAISER_BESSEL;
1577c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(n==7  && 0 == strncmp("nuttall"      , specification, n))
1578c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_NUTTALL;
1579c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(n==9  && 0 == strncmp("rectangle"    , specification, n))
1580c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_RECTANGLE;
1581c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(n==8  && 0 == strncmp("triangle"     , specification, n))
1582c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TRIANGLE;
1583c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(n>7   && 0 == strncmp("tukey("       , specification, 6)) {
1584c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__real p = (FLAC__real)strtod(specification+6, 0);
1585c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if (p >= 0.0 && p <= 1.0) {
1586c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.tukey.p = p;
1587c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY;
1588c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
1589c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
1590c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(n==5  && 0 == strncmp("welch"        , specification, n))
1591c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_WELCH;
1592c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if (encoder->protected_->num_apodizations == 32)
1593c74663799493f2b1e6123c18def94295d0afab7Kenny Root			break;
1594c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if (s)
1595c74663799493f2b1e6123c18def94295d0afab7Kenny Root			specification = s+1;
1596c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else
1597c74663799493f2b1e6123c18def94295d0afab7Kenny Root			break;
1598c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1599c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->num_apodizations == 0) {
1600c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->num_apodizations = 1;
1601c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY;
1602c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->apodizations[0].parameters.tukey.p = 0.5;
1603c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1604c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
1605c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1606c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1607c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1608c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_max_lpc_order(FLAC__StreamEncoder *encoder, unsigned value)
1609c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1610c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1611c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1612c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1613c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1614c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1615c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->max_lpc_order = value;
1616c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1617c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1618c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1619c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_qlp_coeff_precision(FLAC__StreamEncoder *encoder, unsigned value)
1620c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1621c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1622c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1623c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1624c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1625c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1626c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->qlp_coeff_precision = value;
1627c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1628c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1629c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1630c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_do_qlp_coeff_prec_search(FLAC__StreamEncoder *encoder, FLAC__bool value)
1631c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1632c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1633c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1634c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1635c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1636c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1637c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->do_qlp_coeff_prec_search = value;
1638c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1639c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1640c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1641c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_do_escape_coding(FLAC__StreamEncoder *encoder, FLAC__bool value)
1642c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1643c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1644c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1645c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1646c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1647c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1648c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if 0
1649c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*@@@ deprecated: */
1650c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->do_escape_coding = value;
1651c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
1652c74663799493f2b1e6123c18def94295d0afab7Kenny Root	(void)value;
1653c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
1654c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1655c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1656c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1657c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_do_exhaustive_model_search(FLAC__StreamEncoder *encoder, FLAC__bool value)
1658c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1659c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1660c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1661c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1662c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1663c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1664c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->do_exhaustive_model_search = value;
1665c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1666c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1667c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1668c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_min_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value)
1669c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1670c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1671c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1672c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1673c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1674c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1675c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->min_residual_partition_order = value;
1676c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1677c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1678c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1679c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_max_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value)
1680c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1681c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1682c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1683c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1684c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1685c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1686c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->max_residual_partition_order = value;
1687c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1688c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1689c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1690c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_rice_parameter_search_dist(FLAC__StreamEncoder *encoder, unsigned value)
1691c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1692c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1693c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1694c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1695c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1696c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1697c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if 0
1698c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*@@@ deprecated: */
1699c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->rice_parameter_search_dist = value;
1700c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
1701c74663799493f2b1e6123c18def94295d0afab7Kenny Root	(void)value;
1702c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
1703c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1704c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1705c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1706c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_total_samples_estimate(FLAC__StreamEncoder *encoder, FLAC__uint64 value)
1707c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1708c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1709c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1710c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1711c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1712c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1713c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->total_samples_estimate = value;
1714c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1715c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1716c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1717c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
1718c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1719c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1720c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1721c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1722c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1723c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1724c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 == metadata)
1725c74663799493f2b1e6123c18def94295d0afab7Kenny Root		num_blocks = 0;
1726c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 == num_blocks)
1727c74663799493f2b1e6123c18def94295d0afab7Kenny Root		metadata = 0;
1728c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* realloc() does not do exactly what we want so... */
1729c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->metadata) {
1730c74663799493f2b1e6123c18def94295d0afab7Kenny Root		free(encoder->protected_->metadata);
1731c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->metadata = 0;
1732c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->num_metadata_blocks = 0;
1733c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1734c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(num_blocks) {
1735c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__StreamMetadata **m;
1736c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(0 == (m = (FLAC__StreamMetadata**)safe_malloc_mul_2op_(sizeof(m[0]), /*times*/num_blocks)))
1737c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return false;
1738c74663799493f2b1e6123c18def94295d0afab7Kenny Root		memcpy(m, metadata, sizeof(m[0]) * num_blocks);
1739c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->metadata = m;
1740c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->num_metadata_blocks = num_blocks;
1741c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
1742c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if FLAC__HAS_OGG
1743c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!FLAC__ogg_encoder_aspect_set_num_metadata(&encoder->protected_->ogg_encoder_aspect, num_blocks))
1744c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1745c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
1746c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1747c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1748c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1749c74663799493f2b1e6123c18def94295d0afab7Kenny Root/*
1750c74663799493f2b1e6123c18def94295d0afab7Kenny Root * These three functions are not static, but not publically exposed in
1751c74663799493f2b1e6123c18def94295d0afab7Kenny Root * include/FLAC/ either.  They are used by the test suite.
1752c74663799493f2b1e6123c18def94295d0afab7Kenny Root */
1753c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value)
1754c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1755c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1756c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1757c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1758c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1759c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1760c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->disable_constant_subframes = value;
1761c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1762c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1763c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1764c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value)
1765c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1766c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1767c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1768c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1769c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1770c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1771c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->disable_fixed_subframes = value;
1772c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1773c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1774c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1775c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value)
1776c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1777c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1778c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1779c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1780c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
1781c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
1782c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->disable_verbatim_subframes = value;
1783c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
1784c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1785c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1786c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_get_state(const FLAC__StreamEncoder *encoder)
1787c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1788c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1789c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1790c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1791c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->state;
1792c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1793c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1794c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__StreamDecoderState FLAC__stream_encoder_get_verify_decoder_state(const FLAC__StreamEncoder *encoder)
1795c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1796c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1797c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1798c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1799c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->verify)
1800c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__stream_decoder_get_state(encoder->private_->verify.decoder);
1801c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else
1802c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_DECODER_UNINITIALIZED;
1803c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1804c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1805c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API const char *FLAC__stream_encoder_get_resolved_state_string(const FLAC__StreamEncoder *encoder)
1806c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1807c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1808c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1809c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1810c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->state != FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR)
1811c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__StreamEncoderStateString[encoder->protected_->state];
1812c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else
1813c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__stream_decoder_get_resolved_state_string(encoder->private_->verify.decoder);
1814c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1815c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1816c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API void FLAC__stream_encoder_get_verify_decoder_error_stats(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
1817c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1818c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1819c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1820c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1821c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 != absolute_sample)
1822c74663799493f2b1e6123c18def94295d0afab7Kenny Root		*absolute_sample = encoder->private_->verify.error_stats.absolute_sample;
1823c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 != frame_number)
1824c74663799493f2b1e6123c18def94295d0afab7Kenny Root		*frame_number = encoder->private_->verify.error_stats.frame_number;
1825c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 != channel)
1826c74663799493f2b1e6123c18def94295d0afab7Kenny Root		*channel = encoder->private_->verify.error_stats.channel;
1827c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 != sample)
1828c74663799493f2b1e6123c18def94295d0afab7Kenny Root		*sample = encoder->private_->verify.error_stats.sample;
1829c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 != expected)
1830c74663799493f2b1e6123c18def94295d0afab7Kenny Root		*expected = encoder->private_->verify.error_stats.expected;
1831c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 != got)
1832c74663799493f2b1e6123c18def94295d0afab7Kenny Root		*got = encoder->private_->verify.error_stats.got;
1833c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1834c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1835c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_get_verify(const FLAC__StreamEncoder *encoder)
1836c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1837c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1838c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1839c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1840c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->verify;
1841c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1842c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1843c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_get_streamable_subset(const FLAC__StreamEncoder *encoder)
1844c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1845c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1846c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1847c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1848c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->streamable_subset;
1849c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1850c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1851c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_get_do_md5(const FLAC__StreamEncoder *encoder)
1852c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1853c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1854c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1855c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1856c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->do_md5;
1857c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1858c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1859c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API unsigned FLAC__stream_encoder_get_channels(const FLAC__StreamEncoder *encoder)
1860c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1861c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1862c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1863c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1864c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->channels;
1865c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1866c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1867c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API unsigned FLAC__stream_encoder_get_bits_per_sample(const FLAC__StreamEncoder *encoder)
1868c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1869c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1870c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1871c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1872c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->bits_per_sample;
1873c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1874c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1875c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API unsigned FLAC__stream_encoder_get_sample_rate(const FLAC__StreamEncoder *encoder)
1876c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1877c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1878c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1879c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1880c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->sample_rate;
1881c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1882c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1883c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API unsigned FLAC__stream_encoder_get_blocksize(const FLAC__StreamEncoder *encoder)
1884c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1885c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1886c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1887c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1888c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->blocksize;
1889c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1890c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1891c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_get_do_mid_side_stereo(const FLAC__StreamEncoder *encoder)
1892c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1893c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1894c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1895c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1896c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->do_mid_side_stereo;
1897c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1898c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1899c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_get_loose_mid_side_stereo(const FLAC__StreamEncoder *encoder)
1900c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1901c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1902c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1903c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1904c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->loose_mid_side_stereo;
1905c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1906c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1907c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API unsigned FLAC__stream_encoder_get_max_lpc_order(const FLAC__StreamEncoder *encoder)
1908c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1909c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1910c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1911c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1912c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->max_lpc_order;
1913c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1914c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1915c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API unsigned FLAC__stream_encoder_get_qlp_coeff_precision(const FLAC__StreamEncoder *encoder)
1916c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1917c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1918c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1919c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1920c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->qlp_coeff_precision;
1921c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1922c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1923c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__StreamEncoder *encoder)
1924c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1925c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1926c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1927c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1928c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->do_qlp_coeff_prec_search;
1929c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1930c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1931c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_get_do_escape_coding(const FLAC__StreamEncoder *encoder)
1932c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1933c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1934c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1935c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1936c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->do_escape_coding;
1937c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1938c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1939c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_get_do_exhaustive_model_search(const FLAC__StreamEncoder *encoder)
1940c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1941c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1942c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1943c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1944c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->do_exhaustive_model_search;
1945c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1946c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1947c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API unsigned FLAC__stream_encoder_get_min_residual_partition_order(const FLAC__StreamEncoder *encoder)
1948c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1949c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1950c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1951c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1952c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->min_residual_partition_order;
1953c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1954c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1955c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API unsigned FLAC__stream_encoder_get_max_residual_partition_order(const FLAC__StreamEncoder *encoder)
1956c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1957c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1958c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1959c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1960c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->max_residual_partition_order;
1961c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1962c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1963c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API unsigned FLAC__stream_encoder_get_rice_parameter_search_dist(const FLAC__StreamEncoder *encoder)
1964c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1965c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1966c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1967c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1968c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->rice_parameter_search_dist;
1969c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1970c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1971c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__uint64 FLAC__stream_encoder_get_total_samples_estimate(const FLAC__StreamEncoder *encoder)
1972c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1973c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1974c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1975c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1976c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return encoder->protected_->total_samples_estimate;
1977c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
1978c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1979c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
1980c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
1981c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned i, j = 0, channel;
1982c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize;
1983c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1984c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
1985c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
1986c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
1987c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK);
1988c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1989c74663799493f2b1e6123c18def94295d0afab7Kenny Root	do {
1990c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const unsigned n = min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j);
1991c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1992c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->protected_->verify)
1993c74663799493f2b1e6123c18def94295d0afab7Kenny Root			append_to_verify_fifo_(&encoder->private_->verify.input_fifo, buffer, j, channels, n);
1994c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1995c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(channel = 0; channel < channels; channel++)
1996c74663799493f2b1e6123c18def94295d0afab7Kenny Root			memcpy(&encoder->private_->integer_signal[channel][encoder->private_->current_sample_number], &buffer[channel][j], sizeof(buffer[channel][0]) * n);
1997c74663799493f2b1e6123c18def94295d0afab7Kenny Root
1998c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->protected_->do_mid_side_stereo) {
1999c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__ASSERT(channels == 2);
2000c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */
2001c74663799493f2b1e6123c18def94295d0afab7Kenny Root			for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) {
2002c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->integer_signal_mid_side[1][i] = buffer[0][j] - buffer[1][j];
2003c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->integer_signal_mid_side[0][i] = (buffer[0][j] + buffer[1][j]) >> 1; /* NOTE: not the same as 'mid = (buffer[0][j] + buffer[1][j]) / 2' ! */
2004c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2005c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2006c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else
2007c74663799493f2b1e6123c18def94295d0afab7Kenny Root			j += n;
2008c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2009c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->current_sample_number += n;
2010c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2011c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */
2012c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->private_->current_sample_number > blocksize) {
2013c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__ASSERT(encoder->private_->current_sample_number == blocksize+OVERREAD_);
2014c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__ASSERT(OVERREAD_ == 1); /* assert we only overread 1 sample which simplifies the rest of the code below */
2015c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(!process_frame_(encoder, /*is_fractional_block=*/false, /*is_last_block=*/false))
2016c74663799493f2b1e6123c18def94295d0afab7Kenny Root				return false;
2017c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* move unprocessed overread samples to beginnings of arrays */
2018c74663799493f2b1e6123c18def94295d0afab7Kenny Root			for(channel = 0; channel < channels; channel++)
2019c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->integer_signal[channel][0] = encoder->private_->integer_signal[channel][blocksize];
2020c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(encoder->protected_->do_mid_side_stereo) {
2021c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->integer_signal_mid_side[0][0] = encoder->private_->integer_signal_mid_side[0][blocksize];
2022c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->integer_signal_mid_side[1][0] = encoder->private_->integer_signal_mid_side[1][blocksize];
2023c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2024c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->current_sample_number = 1;
2025c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2026c74663799493f2b1e6123c18def94295d0afab7Kenny Root	} while(j < samples);
2027c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2028c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
2029c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
2030c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2031c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
2032c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
2033c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned i, j, k, channel;
2034c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 x, mid, side;
2035c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize;
2036c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2037c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
2038c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_);
2039c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->protected_);
2040c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK);
2041c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2042c74663799493f2b1e6123c18def94295d0afab7Kenny Root	j = k = 0;
2043c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2044c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * we have several flavors of the same basic loop, optimized for
2045c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * different conditions:
2046c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2047c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->do_mid_side_stereo && channels == 2) {
2048c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/*
2049c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 * stereo coding: unroll channel loop
2050c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 */
2051c74663799493f2b1e6123c18def94295d0afab7Kenny Root		do {
2052c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(encoder->protected_->verify)
2053c74663799493f2b1e6123c18def94295d0afab7Kenny Root				append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j));
2054c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2055c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */
2056c74663799493f2b1e6123c18def94295d0afab7Kenny Root			for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) {
2057c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->integer_signal[0][i] = mid = side = buffer[k++];
2058c74663799493f2b1e6123c18def94295d0afab7Kenny Root				x = buffer[k++];
2059c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->integer_signal[1][i] = x;
2060c74663799493f2b1e6123c18def94295d0afab7Kenny Root				mid += x;
2061c74663799493f2b1e6123c18def94295d0afab7Kenny Root				side -= x;
2062c74663799493f2b1e6123c18def94295d0afab7Kenny Root				mid >>= 1; /* NOTE: not the same as 'mid = (left + right) / 2' ! */
2063c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->integer_signal_mid_side[1][i] = side;
2064c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->integer_signal_mid_side[0][i] = mid;
2065c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2066c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->current_sample_number = i;
2067c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */
2068c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(i > blocksize) {
2069c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(!process_frame_(encoder, /*is_fractional_block=*/false, /*is_last_block=*/false))
2070c74663799493f2b1e6123c18def94295d0afab7Kenny Root					return false;
2071c74663799493f2b1e6123c18def94295d0afab7Kenny Root				/* move unprocessed overread samples to beginnings of arrays */
2072c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__ASSERT(i == blocksize+OVERREAD_);
2073c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__ASSERT(OVERREAD_ == 1); /* assert we only overread 1 sample which simplifies the rest of the code below */
2074c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->integer_signal[0][0] = encoder->private_->integer_signal[0][blocksize];
2075c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->integer_signal[1][0] = encoder->private_->integer_signal[1][blocksize];
2076c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->integer_signal_mid_side[0][0] = encoder->private_->integer_signal_mid_side[0][blocksize];
2077c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->integer_signal_mid_side[1][0] = encoder->private_->integer_signal_mid_side[1][blocksize];
2078c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->current_sample_number = 1;
2079c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2080c74663799493f2b1e6123c18def94295d0afab7Kenny Root		} while(j < samples);
2081c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2082c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else {
2083c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/*
2084c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 * independent channel coding: buffer each channel in inner loop
2085c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 */
2086c74663799493f2b1e6123c18def94295d0afab7Kenny Root		do {
2087c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(encoder->protected_->verify)
2088c74663799493f2b1e6123c18def94295d0afab7Kenny Root				append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j));
2089c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2090c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */
2091c74663799493f2b1e6123c18def94295d0afab7Kenny Root			for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) {
2092c74663799493f2b1e6123c18def94295d0afab7Kenny Root				for(channel = 0; channel < channels; channel++)
2093c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->private_->integer_signal[channel][i] = buffer[k++];
2094c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2095c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->current_sample_number = i;
2096c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */
2097c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(i > blocksize) {
2098c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(!process_frame_(encoder, /*is_fractional_block=*/false, /*is_last_block=*/false))
2099c74663799493f2b1e6123c18def94295d0afab7Kenny Root					return false;
2100c74663799493f2b1e6123c18def94295d0afab7Kenny Root				/* move unprocessed overread samples to beginnings of arrays */
2101c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__ASSERT(i == blocksize+OVERREAD_);
2102c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__ASSERT(OVERREAD_ == 1); /* assert we only overread 1 sample which simplifies the rest of the code below */
2103c74663799493f2b1e6123c18def94295d0afab7Kenny Root				for(channel = 0; channel < channels; channel++)
2104c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->private_->integer_signal[channel][0] = encoder->private_->integer_signal[channel][blocksize];
2105c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->current_sample_number = 1;
2106c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2107c74663799493f2b1e6123c18def94295d0afab7Kenny Root		} while(j < samples);
2108c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2109c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2110c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
2111c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
2112c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2113c74663799493f2b1e6123c18def94295d0afab7Kenny Root/***********************************************************************
2114c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
2115c74663799493f2b1e6123c18def94295d0afab7Kenny Root * Private class methods
2116c74663799493f2b1e6123c18def94295d0afab7Kenny Root *
2117c74663799493f2b1e6123c18def94295d0afab7Kenny Root ***********************************************************************/
2118c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2119c74663799493f2b1e6123c18def94295d0afab7Kenny Rootvoid set_defaults_(FLAC__StreamEncoder *encoder)
2120c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
2121c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
2122c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2123c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef FLAC__MANDATORY_VERIFY_WHILE_ENCODING
2124c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->verify = true;
2125c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
2126c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->verify = false;
2127c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
2128c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->streamable_subset = true;
2129c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->do_md5 = true;
2130c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->do_mid_side_stereo = false;
2131c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->loose_mid_side_stereo = false;
2132c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->channels = 2;
2133c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->bits_per_sample = 16;
2134c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->sample_rate = 44100;
2135c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->blocksize = 0;
2136c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
2137c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->num_apodizations = 1;
2138c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY;
2139c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->apodizations[0].parameters.tukey.p = 0.5;
2140c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
2141c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->max_lpc_order = 0;
2142c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->qlp_coeff_precision = 0;
2143c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->do_qlp_coeff_prec_search = false;
2144c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->do_exhaustive_model_search = false;
2145c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->do_escape_coding = false;
2146c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->min_residual_partition_order = 0;
2147c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->max_residual_partition_order = 0;
2148c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->rice_parameter_search_dist = 0;
2149c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->total_samples_estimate = 0;
2150c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->metadata = 0;
2151c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->num_metadata_blocks = 0;
2152c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2153c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->seek_table = 0;
2154c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->disable_constant_subframes = false;
2155c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->disable_fixed_subframes = false;
2156c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->disable_verbatim_subframes = false;
2157c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if FLAC__HAS_OGG
2158c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->is_ogg = false;
2159c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
2160c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->read_callback = 0;
2161c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->write_callback = 0;
2162c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->seek_callback = 0;
2163c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->tell_callback = 0;
2164c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->metadata_callback = 0;
2165c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->progress_callback = 0;
2166c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->client_data = 0;
2167c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2168c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if FLAC__HAS_OGG
2169c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ogg_encoder_aspect_set_defaults(&encoder->protected_->ogg_encoder_aspect);
2170c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
2171c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
2172c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2173c74663799493f2b1e6123c18def94295d0afab7Kenny Rootvoid free_(FLAC__StreamEncoder *encoder)
2174c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
2175c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned i, channel;
2176c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2177c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder);
2178c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->metadata) {
2179c74663799493f2b1e6123c18def94295d0afab7Kenny Root		free(encoder->protected_->metadata);
2180c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->metadata = 0;
2181c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->num_metadata_blocks = 0;
2182c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2183c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < encoder->protected_->channels; i++) {
2184c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(0 != encoder->private_->integer_signal_unaligned[i]) {
2185c74663799493f2b1e6123c18def94295d0afab7Kenny Root			free(encoder->private_->integer_signal_unaligned[i]);
2186c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->integer_signal_unaligned[i] = 0;
2187c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2188c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
2189c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(0 != encoder->private_->real_signal_unaligned[i]) {
2190c74663799493f2b1e6123c18def94295d0afab7Kenny Root			free(encoder->private_->real_signal_unaligned[i]);
2191c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->real_signal_unaligned[i] = 0;
2192c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2193c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
2194c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2195c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < 2; i++) {
2196c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(0 != encoder->private_->integer_signal_mid_side_unaligned[i]) {
2197c74663799493f2b1e6123c18def94295d0afab7Kenny Root			free(encoder->private_->integer_signal_mid_side_unaligned[i]);
2198c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->integer_signal_mid_side_unaligned[i] = 0;
2199c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2200c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
2201c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(0 != encoder->private_->real_signal_mid_side_unaligned[i]) {
2202c74663799493f2b1e6123c18def94295d0afab7Kenny Root			free(encoder->private_->real_signal_mid_side_unaligned[i]);
2203c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->real_signal_mid_side_unaligned[i] = 0;
2204c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2205c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
2206c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2207c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
2208c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < encoder->protected_->num_apodizations; i++) {
2209c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(0 != encoder->private_->window_unaligned[i]) {
2210c74663799493f2b1e6123c18def94295d0afab7Kenny Root			free(encoder->private_->window_unaligned[i]);
2211c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->window_unaligned[i] = 0;
2212c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2213c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2214c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 != encoder->private_->windowed_signal_unaligned) {
2215c74663799493f2b1e6123c18def94295d0afab7Kenny Root		free(encoder->private_->windowed_signal_unaligned);
2216c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->windowed_signal_unaligned = 0;
2217c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2218c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
2219c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(channel = 0; channel < encoder->protected_->channels; channel++) {
2220c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(i = 0; i < 2; i++) {
2221c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(0 != encoder->private_->residual_workspace_unaligned[channel][i]) {
2222c74663799493f2b1e6123c18def94295d0afab7Kenny Root				free(encoder->private_->residual_workspace_unaligned[channel][i]);
2223c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->residual_workspace_unaligned[channel][i] = 0;
2224c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2225c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2226c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2227c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(channel = 0; channel < 2; channel++) {
2228c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(i = 0; i < 2; i++) {
2229c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(0 != encoder->private_->residual_workspace_mid_side_unaligned[channel][i]) {
2230c74663799493f2b1e6123c18def94295d0afab7Kenny Root				free(encoder->private_->residual_workspace_mid_side_unaligned[channel][i]);
2231c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->residual_workspace_mid_side_unaligned[channel][i] = 0;
2232c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2233c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2234c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2235c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 != encoder->private_->abs_residual_partition_sums_unaligned) {
2236c74663799493f2b1e6123c18def94295d0afab7Kenny Root		free(encoder->private_->abs_residual_partition_sums_unaligned);
2237c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->abs_residual_partition_sums_unaligned = 0;
2238c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2239c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 != encoder->private_->raw_bits_per_partition_unaligned) {
2240c74663799493f2b1e6123c18def94295d0afab7Kenny Root		free(encoder->private_->raw_bits_per_partition_unaligned);
2241c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->raw_bits_per_partition_unaligned = 0;
2242c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2243c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->verify) {
2244c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(i = 0; i < encoder->protected_->channels; i++) {
2245c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(0 != encoder->private_->verify.input_fifo.data[i]) {
2246c74663799493f2b1e6123c18def94295d0afab7Kenny Root				free(encoder->private_->verify.input_fifo.data[i]);
2247c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->verify.input_fifo.data[i] = 0;
2248c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2249c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2250c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2251c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bitwriter_free(encoder->private_->frame);
2252c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
2253c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2254c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_blocksize)
2255c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
2256c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool ok;
2257c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned i, channel;
2258c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2259c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(new_blocksize > 0);
2260c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK);
2261c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(encoder->private_->current_sample_number == 0);
2262c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2263c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* To avoid excessive malloc'ing, we only grow the buffer; no shrinking. */
2264c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(new_blocksize <= encoder->private_->input_capacity)
2265c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return true;
2266c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2267c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ok = true;
2268c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2269c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* WATCHOUT: FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx()
2270c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * requires that the input arrays (in our case the integer signals)
2271c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * have a buffer of up to 3 zeroes in front (at negative indices) for
2272c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * alignment purposes; we use 4 in front to keep the data well-aligned.
2273c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2274c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2275c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; ok && i < encoder->protected_->channels; i++) {
2276c74663799493f2b1e6123c18def94295d0afab7Kenny Root		ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize+4+OVERREAD_, &encoder->private_->integer_signal_unaligned[i], &encoder->private_->integer_signal[i]);
2277c74663799493f2b1e6123c18def94295d0afab7Kenny Root		memset(encoder->private_->integer_signal[i], 0, sizeof(FLAC__int32)*4);
2278c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->integer_signal[i] += 4;
2279c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
2280c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if 0 /* @@@ currently unused */
2281c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->protected_->max_lpc_order > 0)
2282c74663799493f2b1e6123c18def94295d0afab7Kenny Root			ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize+OVERREAD_, &encoder->private_->real_signal_unaligned[i], &encoder->private_->real_signal[i]);
2283c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
2284c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
2285c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2286c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; ok && i < 2; i++) {
2287c74663799493f2b1e6123c18def94295d0afab7Kenny Root		ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize+4+OVERREAD_, &encoder->private_->integer_signal_mid_side_unaligned[i], &encoder->private_->integer_signal_mid_side[i]);
2288c74663799493f2b1e6123c18def94295d0afab7Kenny Root		memset(encoder->private_->integer_signal_mid_side[i], 0, sizeof(FLAC__int32)*4);
2289c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->integer_signal_mid_side[i] += 4;
2290c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
2291c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if 0 /* @@@ currently unused */
2292c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->protected_->max_lpc_order > 0)
2293c74663799493f2b1e6123c18def94295d0afab7Kenny Root			ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize+OVERREAD_, &encoder->private_->real_signal_mid_side_unaligned[i], &encoder->private_->real_signal_mid_side[i]);
2294c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
2295c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
2296c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2297c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
2298c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(ok && encoder->protected_->max_lpc_order > 0) {
2299c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(i = 0; ok && i < encoder->protected_->num_apodizations; i++)
2300c74663799493f2b1e6123c18def94295d0afab7Kenny Root			ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize, &encoder->private_->window_unaligned[i], &encoder->private_->window[i]);
2301c74663799493f2b1e6123c18def94295d0afab7Kenny Root		ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize, &encoder->private_->windowed_signal_unaligned, &encoder->private_->windowed_signal);
2302c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2303c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
2304c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(channel = 0; ok && channel < encoder->protected_->channels; channel++) {
2305c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(i = 0; ok && i < 2; i++) {
2306c74663799493f2b1e6123c18def94295d0afab7Kenny Root			ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize, &encoder->private_->residual_workspace_unaligned[channel][i], &encoder->private_->residual_workspace[channel][i]);
2307c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2308c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2309c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(channel = 0; ok && channel < 2; channel++) {
2310c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(i = 0; ok && i < 2; i++) {
2311c74663799493f2b1e6123c18def94295d0afab7Kenny Root			ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize, &encoder->private_->residual_workspace_mid_side_unaligned[channel][i], &encoder->private_->residual_workspace_mid_side[channel][i]);
2312c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2313c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2314c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* the *2 is an approximation to the series 1 + 1/2 + 1/4 + ... that sums tree occupies in a flat array */
2315c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*@@@ new_blocksize*2 is too pessimistic, but to fix, we need smarter logic because a smaller new_blocksize can actually increase the # of partitions; would require moving this out into a separate function, then checking its capacity against the need of the current blocksize&min/max_partition_order (and maybe predictor order) */
2316c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ok = ok && FLAC__memory_alloc_aligned_uint64_array(new_blocksize * 2, &encoder->private_->abs_residual_partition_sums_unaligned, &encoder->private_->abs_residual_partition_sums);
2317c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->do_escape_coding)
2318c74663799493f2b1e6123c18def94295d0afab7Kenny Root		ok = ok && FLAC__memory_alloc_aligned_unsigned_array(new_blocksize * 2, &encoder->private_->raw_bits_per_partition_unaligned, &encoder->private_->raw_bits_per_partition);
2319c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2320c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* now adjust the windows if the blocksize has changed */
2321c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
2322c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(ok && new_blocksize != encoder->private_->input_capacity && encoder->protected_->max_lpc_order > 0) {
2323c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(i = 0; ok && i < encoder->protected_->num_apodizations; i++) {
2324c74663799493f2b1e6123c18def94295d0afab7Kenny Root			switch(encoder->protected_->apodizations[i].type) {
2325c74663799493f2b1e6123c18def94295d0afab7Kenny Root				case FLAC__APODIZATION_BARTLETT:
2326c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__window_bartlett(encoder->private_->window[i], new_blocksize);
2327c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
2328c74663799493f2b1e6123c18def94295d0afab7Kenny Root				case FLAC__APODIZATION_BARTLETT_HANN:
2329c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__window_bartlett_hann(encoder->private_->window[i], new_blocksize);
2330c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
2331c74663799493f2b1e6123c18def94295d0afab7Kenny Root				case FLAC__APODIZATION_BLACKMAN:
2332c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__window_blackman(encoder->private_->window[i], new_blocksize);
2333c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
2334c74663799493f2b1e6123c18def94295d0afab7Kenny Root				case FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE:
2335c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__window_blackman_harris_4term_92db_sidelobe(encoder->private_->window[i], new_blocksize);
2336c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
2337c74663799493f2b1e6123c18def94295d0afab7Kenny Root				case FLAC__APODIZATION_CONNES:
2338c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__window_connes(encoder->private_->window[i], new_blocksize);
2339c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
2340c74663799493f2b1e6123c18def94295d0afab7Kenny Root				case FLAC__APODIZATION_FLATTOP:
2341c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__window_flattop(encoder->private_->window[i], new_blocksize);
2342c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
2343c74663799493f2b1e6123c18def94295d0afab7Kenny Root				case FLAC__APODIZATION_GAUSS:
2344c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__window_gauss(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.gauss.stddev);
2345c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
2346c74663799493f2b1e6123c18def94295d0afab7Kenny Root				case FLAC__APODIZATION_HAMMING:
2347c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__window_hamming(encoder->private_->window[i], new_blocksize);
2348c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
2349c74663799493f2b1e6123c18def94295d0afab7Kenny Root				case FLAC__APODIZATION_HANN:
2350c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__window_hann(encoder->private_->window[i], new_blocksize);
2351c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
2352c74663799493f2b1e6123c18def94295d0afab7Kenny Root				case FLAC__APODIZATION_KAISER_BESSEL:
2353c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__window_kaiser_bessel(encoder->private_->window[i], new_blocksize);
2354c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
2355c74663799493f2b1e6123c18def94295d0afab7Kenny Root				case FLAC__APODIZATION_NUTTALL:
2356c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__window_nuttall(encoder->private_->window[i], new_blocksize);
2357c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
2358c74663799493f2b1e6123c18def94295d0afab7Kenny Root				case FLAC__APODIZATION_RECTANGLE:
2359c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__window_rectangle(encoder->private_->window[i], new_blocksize);
2360c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
2361c74663799493f2b1e6123c18def94295d0afab7Kenny Root				case FLAC__APODIZATION_TRIANGLE:
2362c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__window_triangle(encoder->private_->window[i], new_blocksize);
2363c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
2364c74663799493f2b1e6123c18def94295d0afab7Kenny Root				case FLAC__APODIZATION_TUKEY:
2365c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__window_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.tukey.p);
2366c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
2367c74663799493f2b1e6123c18def94295d0afab7Kenny Root				case FLAC__APODIZATION_WELCH:
2368c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__window_welch(encoder->private_->window[i], new_blocksize);
2369c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
2370c74663799493f2b1e6123c18def94295d0afab7Kenny Root				default:
2371c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__ASSERT(0);
2372c74663799493f2b1e6123c18def94295d0afab7Kenny Root					/* double protection */
2373c74663799493f2b1e6123c18def94295d0afab7Kenny Root					FLAC__window_hann(encoder->private_->window[i], new_blocksize);
2374c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
2375c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2376c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2377c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2378c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
2379c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2380c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(ok)
2381c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->input_capacity = new_blocksize;
2382c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else
2383c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
2384c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2385c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return ok;
2386c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
2387c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2388c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, unsigned samples, FLAC__bool is_last_block)
2389c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
2390c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__byte *buffer;
2391c74663799493f2b1e6123c18def94295d0afab7Kenny Root	size_t bytes;
2392c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2393c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(encoder->private_->frame));
2394c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2395c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!FLAC__bitwriter_get_buffer(encoder->private_->frame, &buffer, &bytes)) {
2396c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
2397c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
2398c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2399c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2400c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->verify) {
2401c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->verify.output.data = buffer;
2402c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->verify.output.bytes = bytes;
2403c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->private_->verify.state_hint == ENCODER_IN_MAGIC) {
2404c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->verify.needs_magic_hack = true;
2405c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2406c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else {
2407c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(!FLAC__stream_decoder_process_single(encoder->private_->verify.decoder)) {
2408c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__bitwriter_release_buffer(encoder->private_->frame);
2409c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__bitwriter_clear(encoder->private_->frame);
2410c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(encoder->protected_->state != FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA)
2411c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR;
2412c74663799493f2b1e6123c18def94295d0afab7Kenny Root				return false;
2413c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2414c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2415c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2416c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2417c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(write_frame_(encoder, buffer, bytes, samples, is_last_block) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
2418c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__bitwriter_release_buffer(encoder->private_->frame);
2419c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__bitwriter_clear(encoder->private_->frame);
2420c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
2421c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
2422c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2423c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2424c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bitwriter_release_buffer(encoder->private_->frame);
2425c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bitwriter_clear(encoder->private_->frame);
2426c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2427c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(samples > 0) {
2428c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->streaminfo.data.stream_info.min_framesize = min(bytes, encoder->private_->streaminfo.data.stream_info.min_framesize);
2429c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->streaminfo.data.stream_info.max_framesize = max(bytes, encoder->private_->streaminfo.data.stream_info.max_framesize);
2430c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2431c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2432c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
2433c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
2434c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2435c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__StreamEncoderWriteStatus write_frame_(FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, FLAC__bool is_last_block)
2436c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
2437c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderWriteStatus status;
2438c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__uint64 output_position = 0;
2439c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2440c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED just means we didn't get the offset; no error */
2441c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->private_->tell_callback && encoder->private_->tell_callback(encoder, &output_position, encoder->private_->client_data) == FLAC__STREAM_ENCODER_TELL_STATUS_ERROR) {
2442c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
2443c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
2444c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2445c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2446c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2447c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Watch for the STREAMINFO block and first SEEKTABLE block to go by and store their offsets.
2448c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2449c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(samples == 0) {
2450c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__MetadataType type = (buffer[0] & 0x7f);
2451c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(type == FLAC__METADATA_TYPE_STREAMINFO)
2452c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->streaminfo_offset = output_position;
2453c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(type == FLAC__METADATA_TYPE_SEEKTABLE && encoder->protected_->seektable_offset == 0)
2454c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->seektable_offset = output_position;
2455c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2456c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2457c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2458c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Mark the current seek point if hit (if audio_offset == 0 that
2459c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * means we're still writing metadata and haven't hit the first
2460c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * frame yet)
2461c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2462c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 != encoder->private_->seek_table && encoder->protected_->audio_offset > 0 && encoder->private_->seek_table->num_points > 0) {
2463c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder);
2464c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const FLAC__uint64 frame_first_sample = encoder->private_->samples_written;
2465c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1;
2466c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__uint64 test_sample;
2467c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned i;
2468c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(i = encoder->private_->first_seekpoint_to_check; i < encoder->private_->seek_table->num_points; i++) {
2469c74663799493f2b1e6123c18def94295d0afab7Kenny Root			test_sample = encoder->private_->seek_table->points[i].sample_number;
2470c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(test_sample > frame_last_sample) {
2471c74663799493f2b1e6123c18def94295d0afab7Kenny Root				break;
2472c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2473c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else if(test_sample >= frame_first_sample) {
2474c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->seek_table->points[i].sample_number = frame_first_sample;
2475c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->seek_table->points[i].stream_offset = output_position - encoder->protected_->audio_offset;
2476c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->seek_table->points[i].frame_samples = blocksize;
2477c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->first_seekpoint_to_check++;
2478c74663799493f2b1e6123c18def94295d0afab7Kenny Root				/* DO NOT: "break;" and here's why:
2479c74663799493f2b1e6123c18def94295d0afab7Kenny Root				 * The seektable template may contain more than one target
2480c74663799493f2b1e6123c18def94295d0afab7Kenny Root				 * sample for any given frame; we will keep looping, generating
2481c74663799493f2b1e6123c18def94295d0afab7Kenny Root				 * duplicate seekpoints for them, and we'll clean it up later,
2482c74663799493f2b1e6123c18def94295d0afab7Kenny Root				 * just before writing the seektable back to the metadata.
2483c74663799493f2b1e6123c18def94295d0afab7Kenny Root				 */
2484c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2485c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else {
2486c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->private_->first_seekpoint_to_check++;
2487c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2488c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2489c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2490c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2491c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if FLAC__HAS_OGG
2492c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->private_->is_ogg) {
2493c74663799493f2b1e6123c18def94295d0afab7Kenny Root		status = FLAC__ogg_encoder_aspect_write_callback_wrapper(
2494c74663799493f2b1e6123c18def94295d0afab7Kenny Root			&encoder->protected_->ogg_encoder_aspect,
2495c74663799493f2b1e6123c18def94295d0afab7Kenny Root			buffer,
2496c74663799493f2b1e6123c18def94295d0afab7Kenny Root			bytes,
2497c74663799493f2b1e6123c18def94295d0afab7Kenny Root			samples,
2498c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->current_frame_number,
2499c74663799493f2b1e6123c18def94295d0afab7Kenny Root			is_last_block,
2500c74663799493f2b1e6123c18def94295d0afab7Kenny Root			(FLAC__OggEncoderAspectWriteCallbackProxy)encoder->private_->write_callback,
2501c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder,
2502c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->client_data
2503c74663799493f2b1e6123c18def94295d0afab7Kenny Root		);
2504c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2505c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else
2506c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
2507c74663799493f2b1e6123c18def94295d0afab7Kenny Root	status = encoder->private_->write_callback(encoder, buffer, bytes, samples, encoder->private_->current_frame_number, encoder->private_->client_data);
2508c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2509c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
2510c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->bytes_written += bytes;
2511c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->samples_written += samples;
2512c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/* we keep a high watermark on the number of frames written because
2513c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 * when the encoder goes back to write metadata, 'current_frame'
2514c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 * will drop back to 0.
2515c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 */
2516c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->frames_written = max(encoder->private_->frames_written, encoder->private_->current_frame_number+1);
2517c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2518c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else
2519c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
2520c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2521c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return status;
2522c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
2523c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2524c74663799493f2b1e6123c18def94295d0afab7Kenny Root/* Gets called when the encoding process has finished so that we can update the STREAMINFO and SEEKTABLE blocks.  */
2525c74663799493f2b1e6123c18def94295d0afab7Kenny Rootvoid update_metadata_(const FLAC__StreamEncoder *encoder)
2526c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
2527c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
2528c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__StreamMetadata *metadata = &encoder->private_->streaminfo;
2529c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
2530c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned min_framesize = metadata->data.stream_info.min_framesize;
2531c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned max_framesize = metadata->data.stream_info.max_framesize;
2532c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned bps = metadata->data.stream_info.bits_per_sample;
2533c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderSeekStatus seek_status;
2534c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2535c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
2536c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2537c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* All this is based on intimate knowledge of the stream header
2538c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * layout, but a change to the header format that would break this
2539c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * would also break all streams encoded in the previous format.
2540c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2541c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2542c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2543c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Write MD5 signature
2544c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2545c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{
2546c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const unsigned md5_offset =
2547c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__STREAM_METADATA_HEADER_LENGTH +
2548c74663799493f2b1e6123c18def94295d0afab7Kenny Root			(
2549c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
2550c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
2551c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
2552c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
2553c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
2554c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
2555c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN +
2556c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN
2557c74663799493f2b1e6123c18def94295d0afab7Kenny Root			) / 8;
2558c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2559c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if((seek_status = encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + md5_offset, encoder->private_->client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) {
2560c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR)
2561c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
2562c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return;
2563c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2564c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->private_->write_callback(encoder, metadata->data.stream_info.md5sum, 16, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
2565c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
2566c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return;
2567c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2568c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2569c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2570c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2571c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Write total samples
2572c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2573c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{
2574c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const unsigned total_samples_byte_offset =
2575c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__STREAM_METADATA_HEADER_LENGTH +
2576c74663799493f2b1e6123c18def94295d0afab7Kenny Root			(
2577c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
2578c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
2579c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
2580c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
2581c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
2582c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
2583c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN
2584c74663799493f2b1e6123c18def94295d0afab7Kenny Root				- 4
2585c74663799493f2b1e6123c18def94295d0afab7Kenny Root			) / 8;
2586c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2587c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[0] = ((FLAC__byte)(bps-1) << 4) | (FLAC__byte)((samples >> 32) & 0x0F);
2588c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
2589c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
2590c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
2591c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[4] = (FLAC__byte)(samples & 0xFF);
2592c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if((seek_status = encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + total_samples_byte_offset, encoder->private_->client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) {
2593c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR)
2594c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
2595c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return;
2596c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2597c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->private_->write_callback(encoder, b, 5, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
2598c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
2599c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return;
2600c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2601c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2602c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2603c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2604c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Write min/max framesize
2605c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2606c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{
2607c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const unsigned min_framesize_offset =
2608c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__STREAM_METADATA_HEADER_LENGTH +
2609c74663799493f2b1e6123c18def94295d0afab7Kenny Root			(
2610c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
2611c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN
2612c74663799493f2b1e6123c18def94295d0afab7Kenny Root			) / 8;
2613c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2614c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
2615c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
2616c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[2] = (FLAC__byte)(min_framesize & 0xFF);
2617c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
2618c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
2619c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[5] = (FLAC__byte)(max_framesize & 0xFF);
2620c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if((seek_status = encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + min_framesize_offset, encoder->private_->client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) {
2621c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR)
2622c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
2623c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return;
2624c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2625c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->private_->write_callback(encoder, b, 6, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
2626c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
2627c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return;
2628c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2629c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2630c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2631c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2632c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Write seektable
2633c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2634c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) {
2635c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned i;
2636c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2637c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__format_seektable_sort(encoder->private_->seek_table);
2638c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2639c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table));
2640c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2641c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if((seek_status = encoder->private_->seek_callback(encoder, encoder->protected_->seektable_offset + FLAC__STREAM_METADATA_HEADER_LENGTH, encoder->private_->client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) {
2642c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR)
2643c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
2644c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return;
2645c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2646c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2647c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(i = 0; i < encoder->private_->seek_table->num_points; i++) {
2648c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__uint64 xx;
2649c74663799493f2b1e6123c18def94295d0afab7Kenny Root			unsigned x;
2650c74663799493f2b1e6123c18def94295d0afab7Kenny Root			xx = encoder->private_->seek_table->points[i].sample_number;
2651c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[7] = (FLAC__byte)xx; xx >>= 8;
2652c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[6] = (FLAC__byte)xx; xx >>= 8;
2653c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[5] = (FLAC__byte)xx; xx >>= 8;
2654c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[4] = (FLAC__byte)xx; xx >>= 8;
2655c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[3] = (FLAC__byte)xx; xx >>= 8;
2656c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[2] = (FLAC__byte)xx; xx >>= 8;
2657c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[1] = (FLAC__byte)xx; xx >>= 8;
2658c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[0] = (FLAC__byte)xx; xx >>= 8;
2659c74663799493f2b1e6123c18def94295d0afab7Kenny Root			xx = encoder->private_->seek_table->points[i].stream_offset;
2660c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[15] = (FLAC__byte)xx; xx >>= 8;
2661c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[14] = (FLAC__byte)xx; xx >>= 8;
2662c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[13] = (FLAC__byte)xx; xx >>= 8;
2663c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[12] = (FLAC__byte)xx; xx >>= 8;
2664c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[11] = (FLAC__byte)xx; xx >>= 8;
2665c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[10] = (FLAC__byte)xx; xx >>= 8;
2666c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[9] = (FLAC__byte)xx; xx >>= 8;
2667c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[8] = (FLAC__byte)xx; xx >>= 8;
2668c74663799493f2b1e6123c18def94295d0afab7Kenny Root			x = encoder->private_->seek_table->points[i].frame_samples;
2669c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[17] = (FLAC__byte)x; x >>= 8;
2670c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[16] = (FLAC__byte)x; x >>= 8;
2671c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(encoder->private_->write_callback(encoder, b, 18, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
2672c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
2673c74663799493f2b1e6123c18def94295d0afab7Kenny Root				return;
2674c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2675c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2676c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2677c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
2678c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2679c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if FLAC__HAS_OGG
2680c74663799493f2b1e6123c18def94295d0afab7Kenny Root/* Gets called when the encoding process has finished so that we can update the STREAMINFO and SEEKTABLE blocks.  */
2681c74663799493f2b1e6123c18def94295d0afab7Kenny Rootvoid update_ogg_metadata_(FLAC__StreamEncoder *encoder)
2682c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
2683c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* the # of bytes in the 1st packet that precede the STREAMINFO */
2684c74663799493f2b1e6123c18def94295d0afab7Kenny Root	static const unsigned FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH =
2685c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH +
2686c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__OGG_MAPPING_MAGIC_LENGTH +
2687c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH +
2688c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH +
2689c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH +
2690c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__STREAM_SYNC_LENGTH
2691c74663799493f2b1e6123c18def94295d0afab7Kenny Root	;
2692c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
2693c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__StreamMetadata *metadata = &encoder->private_->streaminfo;
2694c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
2695c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned min_framesize = metadata->data.stream_info.min_framesize;
2696c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned max_framesize = metadata->data.stream_info.max_framesize;
2697c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ogg_page page;
2698c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2699c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
2700c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(0 != encoder->private_->seek_callback);
2701c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2702c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* Pre-check that client supports seeking, since we don't want the
2703c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * ogg_helper code to ever have to deal with this condition.
2704c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2705c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->private_->seek_callback(encoder, 0, encoder->private_->client_data) == FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED)
2706c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return;
2707c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2708c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* All this is based on intimate knowledge of the stream header
2709c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * layout, but a change to the header format that would break this
2710c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * would also break all streams encoded in the previous format.
2711c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2712c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2713c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/**
2714c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 ** Write STREAMINFO stats
2715c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 **/
2716c74663799493f2b1e6123c18def94295d0afab7Kenny Root	simple_ogg_page__init(&page);
2717c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!simple_ogg_page__get_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) {
2718c74663799493f2b1e6123c18def94295d0afab7Kenny Root		simple_ogg_page__clear(&page);
2719c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return; /* state already set */
2720c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2721c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2722c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2723c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Write MD5 signature
2724c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2725c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{
2726c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const unsigned md5_offset =
2727c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH +
2728c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__STREAM_METADATA_HEADER_LENGTH +
2729c74663799493f2b1e6123c18def94295d0afab7Kenny Root			(
2730c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
2731c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
2732c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
2733c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
2734c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
2735c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
2736c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN +
2737c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN
2738c74663799493f2b1e6123c18def94295d0afab7Kenny Root			) / 8;
2739c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2740c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(md5_offset + 16 > (unsigned)page.body_len) {
2741c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
2742c74663799493f2b1e6123c18def94295d0afab7Kenny Root			simple_ogg_page__clear(&page);
2743c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return;
2744c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2745c74663799493f2b1e6123c18def94295d0afab7Kenny Root		memcpy(page.body + md5_offset, metadata->data.stream_info.md5sum, 16);
2746c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2747c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2748c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2749c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Write total samples
2750c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2751c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{
2752c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const unsigned total_samples_byte_offset =
2753c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH +
2754c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__STREAM_METADATA_HEADER_LENGTH +
2755c74663799493f2b1e6123c18def94295d0afab7Kenny Root			(
2756c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
2757c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
2758c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
2759c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
2760c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
2761c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
2762c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN
2763c74663799493f2b1e6123c18def94295d0afab7Kenny Root				- 4
2764c74663799493f2b1e6123c18def94295d0afab7Kenny Root			) / 8;
2765c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2766c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(total_samples_byte_offset + 5 > (unsigned)page.body_len) {
2767c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
2768c74663799493f2b1e6123c18def94295d0afab7Kenny Root			simple_ogg_page__clear(&page);
2769c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return;
2770c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2771c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[0] = (FLAC__byte)page.body[total_samples_byte_offset] & 0xF0;
2772c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[0] |= (FLAC__byte)((samples >> 32) & 0x0F);
2773c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
2774c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
2775c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
2776c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[4] = (FLAC__byte)(samples & 0xFF);
2777c74663799493f2b1e6123c18def94295d0afab7Kenny Root		memcpy(page.body + total_samples_byte_offset, b, 5);
2778c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2779c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2780c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2781c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Write min/max framesize
2782c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2783c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{
2784c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const unsigned min_framesize_offset =
2785c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FIRST_OGG_PACKET_STREAMINFO_PREFIX_LENGTH +
2786c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__STREAM_METADATA_HEADER_LENGTH +
2787c74663799493f2b1e6123c18def94295d0afab7Kenny Root			(
2788c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
2789c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN
2790c74663799493f2b1e6123c18def94295d0afab7Kenny Root			) / 8;
2791c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2792c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(min_framesize_offset + 6 > (unsigned)page.body_len) {
2793c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
2794c74663799493f2b1e6123c18def94295d0afab7Kenny Root			simple_ogg_page__clear(&page);
2795c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return;
2796c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2797c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
2798c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
2799c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[2] = (FLAC__byte)(min_framesize & 0xFF);
2800c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
2801c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
2802c74663799493f2b1e6123c18def94295d0afab7Kenny Root		b[5] = (FLAC__byte)(max_framesize & 0xFF);
2803c74663799493f2b1e6123c18def94295d0afab7Kenny Root		memcpy(page.body + min_framesize_offset, b, 6);
2804c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2805c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!simple_ogg_page__set_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) {
2806c74663799493f2b1e6123c18def94295d0afab7Kenny Root		simple_ogg_page__clear(&page);
2807c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return; /* state already set */
2808c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2809c74663799493f2b1e6123c18def94295d0afab7Kenny Root	simple_ogg_page__clear(&page);
2810c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2811c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2812c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Write seektable
2813c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2814c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) {
2815c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned i;
2816c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__byte *p;
2817c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2818c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__format_seektable_sort(encoder->private_->seek_table);
2819c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2820c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table));
2821c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2822c74663799493f2b1e6123c18def94295d0afab7Kenny Root		simple_ogg_page__init(&page);
2823c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(!simple_ogg_page__get_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) {
2824c74663799493f2b1e6123c18def94295d0afab7Kenny Root			simple_ogg_page__clear(&page);
2825c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return; /* state already set */
2826c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2827c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2828c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if((FLAC__STREAM_METADATA_HEADER_LENGTH + 18*encoder->private_->seek_table->num_points) != (unsigned)page.body_len) {
2829c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
2830c74663799493f2b1e6123c18def94295d0afab7Kenny Root			simple_ogg_page__clear(&page);
2831c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return;
2832c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2833c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2834c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(i = 0, p = page.body + FLAC__STREAM_METADATA_HEADER_LENGTH; i < encoder->private_->seek_table->num_points; i++, p += 18) {
2835c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__uint64 xx;
2836c74663799493f2b1e6123c18def94295d0afab7Kenny Root			unsigned x;
2837c74663799493f2b1e6123c18def94295d0afab7Kenny Root			xx = encoder->private_->seek_table->points[i].sample_number;
2838c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[7] = (FLAC__byte)xx; xx >>= 8;
2839c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[6] = (FLAC__byte)xx; xx >>= 8;
2840c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[5] = (FLAC__byte)xx; xx >>= 8;
2841c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[4] = (FLAC__byte)xx; xx >>= 8;
2842c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[3] = (FLAC__byte)xx; xx >>= 8;
2843c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[2] = (FLAC__byte)xx; xx >>= 8;
2844c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[1] = (FLAC__byte)xx; xx >>= 8;
2845c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[0] = (FLAC__byte)xx; xx >>= 8;
2846c74663799493f2b1e6123c18def94295d0afab7Kenny Root			xx = encoder->private_->seek_table->points[i].stream_offset;
2847c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[15] = (FLAC__byte)xx; xx >>= 8;
2848c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[14] = (FLAC__byte)xx; xx >>= 8;
2849c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[13] = (FLAC__byte)xx; xx >>= 8;
2850c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[12] = (FLAC__byte)xx; xx >>= 8;
2851c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[11] = (FLAC__byte)xx; xx >>= 8;
2852c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[10] = (FLAC__byte)xx; xx >>= 8;
2853c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[9] = (FLAC__byte)xx; xx >>= 8;
2854c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[8] = (FLAC__byte)xx; xx >>= 8;
2855c74663799493f2b1e6123c18def94295d0afab7Kenny Root			x = encoder->private_->seek_table->points[i].frame_samples;
2856c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[17] = (FLAC__byte)x; x >>= 8;
2857c74663799493f2b1e6123c18def94295d0afab7Kenny Root			b[16] = (FLAC__byte)x; x >>= 8;
2858c74663799493f2b1e6123c18def94295d0afab7Kenny Root			memcpy(p, b, 18);
2859c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2860c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2861c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(!simple_ogg_page__set_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) {
2862c74663799493f2b1e6123c18def94295d0afab7Kenny Root			simple_ogg_page__clear(&page);
2863c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return; /* state already set */
2864c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2865c74663799493f2b1e6123c18def94295d0afab7Kenny Root		simple_ogg_page__clear(&page);
2866c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2867c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
2868c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
2869c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2870c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block, FLAC__bool is_last_block)
2871c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
2872c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__uint16 crc;
2873c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK);
2874c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2875c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2876c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Accumulate raw signal to the MD5 signature
2877c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2878c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->do_md5 && !FLAC__MD5Accumulate(&encoder->private_->md5context, (const FLAC__int32 * const *)encoder->private_->integer_signal, encoder->protected_->channels, encoder->protected_->blocksize, (encoder->protected_->bits_per_sample+7) / 8)) {
2879c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
2880c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
2881c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2882c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2883c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2884c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Process the frame header and subframes into the frame bitbuffer
2885c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2886c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!process_subframes_(encoder, is_fractional_block)) {
2887c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/* the above function sets the state for us in case of an error */
2888c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
2889c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2890c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2891c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2892c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Zero-pad the frame to a byte_boundary
2893c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2894c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!FLAC__bitwriter_zero_pad_to_byte_boundary(encoder->private_->frame)) {
2895c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
2896c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
2897c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2898c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2899c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2900c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * CRC-16 the whole thing
2901c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2902c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(encoder->private_->frame));
2903c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(
2904c74663799493f2b1e6123c18def94295d0afab7Kenny Root		!FLAC__bitwriter_get_write_crc16(encoder->private_->frame, &crc) ||
2905c74663799493f2b1e6123c18def94295d0afab7Kenny Root		!FLAC__bitwriter_write_raw_uint32(encoder->private_->frame, crc, FLAC__FRAME_FOOTER_CRC_LEN)
2906c74663799493f2b1e6123c18def94295d0afab7Kenny Root	) {
2907c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
2908c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
2909c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2910c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2911c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2912c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Write it
2913c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2914c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!write_bitbuffer_(encoder, encoder->protected_->blocksize, is_last_block)) {
2915c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/* the above function sets the state for us in case of an error */
2916c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return false;
2917c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2918c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2919c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2920c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Get ready for the next frame
2921c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2922c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->current_sample_number = 0;
2923c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->current_frame_number++;
2924c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->streaminfo.data.stream_info.total_samples += (FLAC__uint64)encoder->protected_->blocksize;
2925c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2926c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
2927c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
2928c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2929c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block)
2930c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
2931c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__FrameHeader frame_header;
2932c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned channel, min_partition_order = encoder->protected_->min_residual_partition_order, max_partition_order;
2933c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool do_independent, do_mid_side;
2934c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2935c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2936c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Calculate the min,max Rice partition orders
2937c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2938c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(is_fractional_block) {
2939c74663799493f2b1e6123c18def94295d0afab7Kenny Root		max_partition_order = 0;
2940c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2941c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else {
2942c74663799493f2b1e6123c18def94295d0afab7Kenny Root		max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize(encoder->protected_->blocksize);
2943c74663799493f2b1e6123c18def94295d0afab7Kenny Root		max_partition_order = min(max_partition_order, encoder->protected_->max_residual_partition_order);
2944c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2945c74663799493f2b1e6123c18def94295d0afab7Kenny Root	min_partition_order = min(min_partition_order, max_partition_order);
2946c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2947c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2948c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Setup the frame
2949c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2950c74663799493f2b1e6123c18def94295d0afab7Kenny Root	frame_header.blocksize = encoder->protected_->blocksize;
2951c74663799493f2b1e6123c18def94295d0afab7Kenny Root	frame_header.sample_rate = encoder->protected_->sample_rate;
2952c74663799493f2b1e6123c18def94295d0afab7Kenny Root	frame_header.channels = encoder->protected_->channels;
2953c74663799493f2b1e6123c18def94295d0afab7Kenny Root	frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT; /* the default unless the encoder determines otherwise */
2954c74663799493f2b1e6123c18def94295d0afab7Kenny Root	frame_header.bits_per_sample = encoder->protected_->bits_per_sample;
2955c74663799493f2b1e6123c18def94295d0afab7Kenny Root	frame_header.number_type = FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER;
2956c74663799493f2b1e6123c18def94295d0afab7Kenny Root	frame_header.number.frame_number = encoder->private_->current_frame_number;
2957c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2958c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2959c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Figure out what channel assignments to try
2960c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2961c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->do_mid_side_stereo) {
2962c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->protected_->loose_mid_side_stereo) {
2963c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(encoder->private_->loose_mid_side_stereo_frame_count == 0) {
2964c74663799493f2b1e6123c18def94295d0afab7Kenny Root				do_independent = true;
2965c74663799493f2b1e6123c18def94295d0afab7Kenny Root				do_mid_side = true;
2966c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2967c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else {
2968c74663799493f2b1e6123c18def94295d0afab7Kenny Root				do_independent = (encoder->private_->last_channel_assignment == FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT);
2969c74663799493f2b1e6123c18def94295d0afab7Kenny Root				do_mid_side = !do_independent;
2970c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
2971c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2972c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else {
2973c74663799493f2b1e6123c18def94295d0afab7Kenny Root			do_independent = true;
2974c74663799493f2b1e6123c18def94295d0afab7Kenny Root			do_mid_side = true;
2975c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2976c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2977c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else {
2978c74663799493f2b1e6123c18def94295d0afab7Kenny Root		do_independent = true;
2979c74663799493f2b1e6123c18def94295d0afab7Kenny Root		do_mid_side = false;
2980c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2981c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2982c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(do_independent || do_mid_side);
2983c74663799493f2b1e6123c18def94295d0afab7Kenny Root
2984c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
2985c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Check for wasted bits; set effective bps for each subframe
2986c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
2987c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(do_independent) {
2988c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(channel = 0; channel < encoder->protected_->channels; channel++) {
2989c74663799493f2b1e6123c18def94295d0afab7Kenny Root			const unsigned w = get_wasted_bits_(encoder->private_->integer_signal[channel], encoder->protected_->blocksize);
2990c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->subframe_workspace[channel][0].wasted_bits = encoder->private_->subframe_workspace[channel][1].wasted_bits = w;
2991c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->subframe_bps[channel] = encoder->protected_->bits_per_sample - w;
2992c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
2993c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
2994c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(do_mid_side) {
2995c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ASSERT(encoder->protected_->channels == 2);
2996c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(channel = 0; channel < 2; channel++) {
2997c74663799493f2b1e6123c18def94295d0afab7Kenny Root			const unsigned w = get_wasted_bits_(encoder->private_->integer_signal_mid_side[channel], encoder->protected_->blocksize);
2998c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->subframe_workspace_mid_side[channel][0].wasted_bits = encoder->private_->subframe_workspace_mid_side[channel][1].wasted_bits = w;
2999c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->subframe_bps_mid_side[channel] = encoder->protected_->bits_per_sample - w + (channel==0? 0:1);
3000c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3001c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3002c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3003c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
3004c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * First do a normal encoding pass of each independent channel
3005c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
3006c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(do_independent) {
3007c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(channel = 0; channel < encoder->protected_->channels; channel++) {
3008c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(!
3009c74663799493f2b1e6123c18def94295d0afab7Kenny Root				process_subframe_(
3010c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder,
3011c74663799493f2b1e6123c18def94295d0afab7Kenny Root					min_partition_order,
3012c74663799493f2b1e6123c18def94295d0afab7Kenny Root					max_partition_order,
3013c74663799493f2b1e6123c18def94295d0afab7Kenny Root					&frame_header,
3014c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->private_->subframe_bps[channel],
3015c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->private_->integer_signal[channel],
3016c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->private_->subframe_workspace_ptr[channel],
3017c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->private_->partitioned_rice_contents_workspace_ptr[channel],
3018c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->private_->residual_workspace[channel],
3019c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->private_->best_subframe+channel,
3020c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->private_->best_subframe_bits+channel
3021c74663799493f2b1e6123c18def94295d0afab7Kenny Root				)
3022c74663799493f2b1e6123c18def94295d0afab7Kenny Root			)
3023c74663799493f2b1e6123c18def94295d0afab7Kenny Root				return false;
3024c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3025c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3026c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3027c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
3028c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Now do mid and side channels if requested
3029c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
3030c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(do_mid_side) {
3031c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ASSERT(encoder->protected_->channels == 2);
3032c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3033c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(channel = 0; channel < 2; channel++) {
3034c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(!
3035c74663799493f2b1e6123c18def94295d0afab7Kenny Root				process_subframe_(
3036c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder,
3037c74663799493f2b1e6123c18def94295d0afab7Kenny Root					min_partition_order,
3038c74663799493f2b1e6123c18def94295d0afab7Kenny Root					max_partition_order,
3039c74663799493f2b1e6123c18def94295d0afab7Kenny Root					&frame_header,
3040c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->private_->subframe_bps_mid_side[channel],
3041c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->private_->integer_signal_mid_side[channel],
3042c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->private_->subframe_workspace_ptr_mid_side[channel],
3043c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[channel],
3044c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->private_->residual_workspace_mid_side[channel],
3045c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->private_->best_subframe_mid_side+channel,
3046c74663799493f2b1e6123c18def94295d0afab7Kenny Root					encoder->private_->best_subframe_bits_mid_side+channel
3047c74663799493f2b1e6123c18def94295d0afab7Kenny Root				)
3048c74663799493f2b1e6123c18def94295d0afab7Kenny Root			)
3049c74663799493f2b1e6123c18def94295d0afab7Kenny Root				return false;
3050c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3051c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3052c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3053c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/*
3054c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * Compose the frame bitbuffer
3055c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
3056c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(do_mid_side) {
3057c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned left_bps = 0, right_bps = 0; /* initialized only to prevent superfluous compiler warning */
3058c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__Subframe *left_subframe = 0, *right_subframe = 0; /* initialized only to prevent superfluous compiler warning */
3059c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ChannelAssignment channel_assignment;
3060c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3061c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ASSERT(encoder->protected_->channels == 2);
3062c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3063c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->protected_->loose_mid_side_stereo && encoder->private_->loose_mid_side_stereo_frame_count > 0) {
3064c74663799493f2b1e6123c18def94295d0afab7Kenny Root			channel_assignment = (encoder->private_->last_channel_assignment == FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT? FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT : FLAC__CHANNEL_ASSIGNMENT_MID_SIDE);
3065c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3066c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else {
3067c74663799493f2b1e6123c18def94295d0afab7Kenny Root			unsigned bits[4]; /* WATCHOUT - indexed by FLAC__ChannelAssignment */
3068c74663799493f2b1e6123c18def94295d0afab7Kenny Root			unsigned min_bits;
3069c74663799493f2b1e6123c18def94295d0afab7Kenny Root			int ca;
3070c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3071c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT == 0);
3072c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE   == 1);
3073c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE  == 2);
3074c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__ASSERT(FLAC__CHANNEL_ASSIGNMENT_MID_SIDE    == 3);
3075c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__ASSERT(do_independent && do_mid_side);
3076c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3077c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* We have to figure out which channel assignent results in the smallest frame */
3078c74663799493f2b1e6123c18def94295d0afab7Kenny Root			bits[FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT] = encoder->private_->best_subframe_bits         [0] + encoder->private_->best_subframe_bits         [1];
3079c74663799493f2b1e6123c18def94295d0afab7Kenny Root			bits[FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE  ] = encoder->private_->best_subframe_bits         [0] + encoder->private_->best_subframe_bits_mid_side[1];
3080c74663799493f2b1e6123c18def94295d0afab7Kenny Root			bits[FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE ] = encoder->private_->best_subframe_bits         [1] + encoder->private_->best_subframe_bits_mid_side[1];
3081c74663799493f2b1e6123c18def94295d0afab7Kenny Root			bits[FLAC__CHANNEL_ASSIGNMENT_MID_SIDE   ] = encoder->private_->best_subframe_bits_mid_side[0] + encoder->private_->best_subframe_bits_mid_side[1];
3082c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3083c74663799493f2b1e6123c18def94295d0afab7Kenny Root			channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT;
3084c74663799493f2b1e6123c18def94295d0afab7Kenny Root			min_bits = bits[channel_assignment];
3085c74663799493f2b1e6123c18def94295d0afab7Kenny Root			for(ca = 1; ca <= 3; ca++) {
3086c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(bits[ca] < min_bits) {
3087c74663799493f2b1e6123c18def94295d0afab7Kenny Root					min_bits = bits[ca];
3088c74663799493f2b1e6123c18def94295d0afab7Kenny Root					channel_assignment = (FLAC__ChannelAssignment)ca;
3089c74663799493f2b1e6123c18def94295d0afab7Kenny Root				}
3090c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3091c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3092c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3093c74663799493f2b1e6123c18def94295d0afab7Kenny Root		frame_header.channel_assignment = channel_assignment;
3094c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3095c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(!FLAC__frame_add_header(&frame_header, encoder->private_->frame)) {
3096c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
3097c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return false;
3098c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3099c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3100c74663799493f2b1e6123c18def94295d0afab7Kenny Root		switch(channel_assignment) {
3101c74663799493f2b1e6123c18def94295d0afab7Kenny Root			case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
3102c74663799493f2b1e6123c18def94295d0afab7Kenny Root				left_subframe  = &encoder->private_->subframe_workspace         [0][encoder->private_->best_subframe         [0]];
3103c74663799493f2b1e6123c18def94295d0afab7Kenny Root				right_subframe = &encoder->private_->subframe_workspace         [1][encoder->private_->best_subframe         [1]];
3104c74663799493f2b1e6123c18def94295d0afab7Kenny Root				break;
3105c74663799493f2b1e6123c18def94295d0afab7Kenny Root			case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
3106c74663799493f2b1e6123c18def94295d0afab7Kenny Root				left_subframe  = &encoder->private_->subframe_workspace         [0][encoder->private_->best_subframe         [0]];
3107c74663799493f2b1e6123c18def94295d0afab7Kenny Root				right_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]];
3108c74663799493f2b1e6123c18def94295d0afab7Kenny Root				break;
3109c74663799493f2b1e6123c18def94295d0afab7Kenny Root			case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
3110c74663799493f2b1e6123c18def94295d0afab7Kenny Root				left_subframe  = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]];
3111c74663799493f2b1e6123c18def94295d0afab7Kenny Root				right_subframe = &encoder->private_->subframe_workspace         [1][encoder->private_->best_subframe         [1]];
3112c74663799493f2b1e6123c18def94295d0afab7Kenny Root				break;
3113c74663799493f2b1e6123c18def94295d0afab7Kenny Root			case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
3114c74663799493f2b1e6123c18def94295d0afab7Kenny Root				left_subframe  = &encoder->private_->subframe_workspace_mid_side[0][encoder->private_->best_subframe_mid_side[0]];
3115c74663799493f2b1e6123c18def94295d0afab7Kenny Root				right_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]];
3116c74663799493f2b1e6123c18def94295d0afab7Kenny Root				break;
3117c74663799493f2b1e6123c18def94295d0afab7Kenny Root			default:
3118c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__ASSERT(0);
3119c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3120c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3121c74663799493f2b1e6123c18def94295d0afab7Kenny Root		switch(channel_assignment) {
3122c74663799493f2b1e6123c18def94295d0afab7Kenny Root			case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
3123c74663799493f2b1e6123c18def94295d0afab7Kenny Root				left_bps  = encoder->private_->subframe_bps         [0];
3124c74663799493f2b1e6123c18def94295d0afab7Kenny Root				right_bps = encoder->private_->subframe_bps         [1];
3125c74663799493f2b1e6123c18def94295d0afab7Kenny Root				break;
3126c74663799493f2b1e6123c18def94295d0afab7Kenny Root			case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
3127c74663799493f2b1e6123c18def94295d0afab7Kenny Root				left_bps  = encoder->private_->subframe_bps         [0];
3128c74663799493f2b1e6123c18def94295d0afab7Kenny Root				right_bps = encoder->private_->subframe_bps_mid_side[1];
3129c74663799493f2b1e6123c18def94295d0afab7Kenny Root				break;
3130c74663799493f2b1e6123c18def94295d0afab7Kenny Root			case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
3131c74663799493f2b1e6123c18def94295d0afab7Kenny Root				left_bps  = encoder->private_->subframe_bps_mid_side[1];
3132c74663799493f2b1e6123c18def94295d0afab7Kenny Root				right_bps = encoder->private_->subframe_bps         [1];
3133c74663799493f2b1e6123c18def94295d0afab7Kenny Root				break;
3134c74663799493f2b1e6123c18def94295d0afab7Kenny Root			case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
3135c74663799493f2b1e6123c18def94295d0afab7Kenny Root				left_bps  = encoder->private_->subframe_bps_mid_side[0];
3136c74663799493f2b1e6123c18def94295d0afab7Kenny Root				right_bps = encoder->private_->subframe_bps_mid_side[1];
3137c74663799493f2b1e6123c18def94295d0afab7Kenny Root				break;
3138c74663799493f2b1e6123c18def94295d0afab7Kenny Root			default:
3139c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__ASSERT(0);
3140c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3141c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3142c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/* note that encoder_add_subframe_ sets the state for us in case of an error */
3143c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(!add_subframe_(encoder, frame_header.blocksize, left_bps , left_subframe , encoder->private_->frame))
3144c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return false;
3145c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(!add_subframe_(encoder, frame_header.blocksize, right_bps, right_subframe, encoder->private_->frame))
3146c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return false;
3147c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3148c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else {
3149c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(!FLAC__frame_add_header(&frame_header, encoder->private_->frame)) {
3150c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
3151c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return false;
3152c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3153c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3154c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(channel = 0; channel < encoder->protected_->channels; channel++) {
3155c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(!add_subframe_(encoder, frame_header.blocksize, encoder->private_->subframe_bps[channel], &encoder->private_->subframe_workspace[channel][encoder->private_->best_subframe[channel]], encoder->private_->frame)) {
3156c74663799493f2b1e6123c18def94295d0afab7Kenny Root				/* the above function sets the state for us in case of an error */
3157c74663799493f2b1e6123c18def94295d0afab7Kenny Root				return false;
3158c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3159c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3160c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3161c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3162c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->protected_->loose_mid_side_stereo) {
3163c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->loose_mid_side_stereo_frame_count++;
3164c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoder->private_->loose_mid_side_stereo_frame_count >= encoder->private_->loose_mid_side_stereo_frames)
3165c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->loose_mid_side_stereo_frame_count = 0;
3166c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3167c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3168c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->last_channel_assignment = frame_header.channel_assignment;
3169c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3170c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
3171c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
3172c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3173c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__bool process_subframe_(
3174c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
3175c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_partition_order,
3176c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned max_partition_order,
3177c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__FrameHeader *frame_header,
3178c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned subframe_bps,
3179c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 integer_signal[],
3180c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__Subframe *subframe[2],
3181c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2],
3182c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 *residual[2],
3183c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned *best_subframe,
3184c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned *best_bits
3185c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
3186c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
3187c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
3188c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__float fixed_residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1];
3189c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
3190c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__fixedpoint fixed_residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1];
3191c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3192c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
3193c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__double lpc_residual_bits_per_sample;
3194c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__real autoc[FLAC__MAX_LPC_ORDER+1]; /* WATCHOUT: the size is important even though encoder->protected_->max_lpc_order might be less; some asm routines need all the space */
3195c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__double lpc_error[FLAC__MAX_LPC_ORDER];
3196c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_lpc_order, max_lpc_order, lpc_order;
3197c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_qlp_coeff_precision, max_qlp_coeff_precision, qlp_coeff_precision;
3198c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3199c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_fixed_order, max_fixed_order, guess_fixed_order, fixed_order;
3200c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter;
3201c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned _candidate_bits, _best_bits;
3202c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned _best_subframe;
3203c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* only use RICE2 partitions if stream bps > 16 */
3204c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned rice_parameter_limit = FLAC__stream_encoder_get_bits_per_sample(encoder) > 16? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
3205c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3206c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(frame_header->blocksize > 0);
3207c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3208c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* verbatim subframe is the baseline against which we measure other compressed subframes */
3209c74663799493f2b1e6123c18def94295d0afab7Kenny Root	_best_subframe = 0;
3210c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->private_->disable_verbatim_subframes && frame_header->blocksize >= FLAC__MAX_FIXED_ORDER)
3211c74663799493f2b1e6123c18def94295d0afab7Kenny Root		_best_bits = UINT_MAX;
3212c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else
3213c74663799493f2b1e6123c18def94295d0afab7Kenny Root		_best_bits = evaluate_verbatim_subframe_(encoder, integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]);
3214c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3215c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(frame_header->blocksize >= FLAC__MAX_FIXED_ORDER) {
3216c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned signal_is_constant = false;
3217c74663799493f2b1e6123c18def94295d0afab7Kenny Root		guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor(integer_signal+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample);
3218c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/* check for constant subframe */
3219c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(
3220c74663799493f2b1e6123c18def94295d0afab7Kenny Root			!encoder->private_->disable_constant_subframes &&
3221c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
3222c74663799493f2b1e6123c18def94295d0afab7Kenny Root			fixed_residual_bits_per_sample[1] == 0.0
3223c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
3224c74663799493f2b1e6123c18def94295d0afab7Kenny Root			fixed_residual_bits_per_sample[1] == FLAC__FP_ZERO
3225c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3226c74663799493f2b1e6123c18def94295d0afab7Kenny Root		) {
3227c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* the above means it's possible all samples are the same value; now double-check it: */
3228c74663799493f2b1e6123c18def94295d0afab7Kenny Root			unsigned i;
3229c74663799493f2b1e6123c18def94295d0afab7Kenny Root			signal_is_constant = true;
3230c74663799493f2b1e6123c18def94295d0afab7Kenny Root			for(i = 1; i < frame_header->blocksize; i++) {
3231c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(integer_signal[0] != integer_signal[i]) {
3232c74663799493f2b1e6123c18def94295d0afab7Kenny Root					signal_is_constant = false;
3233c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
3234c74663799493f2b1e6123c18def94295d0afab7Kenny Root				}
3235c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3236c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3237c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(signal_is_constant) {
3238c74663799493f2b1e6123c18def94295d0afab7Kenny Root			_candidate_bits = evaluate_constant_subframe_(encoder, integer_signal[0], frame_header->blocksize, subframe_bps, subframe[!_best_subframe]);
3239c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(_candidate_bits < _best_bits) {
3240c74663799493f2b1e6123c18def94295d0afab7Kenny Root				_best_subframe = !_best_subframe;
3241c74663799493f2b1e6123c18def94295d0afab7Kenny Root				_best_bits = _candidate_bits;
3242c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3243c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3244c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else {
3245c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(!encoder->private_->disable_fixed_subframes || (encoder->protected_->max_lpc_order == 0 && _best_bits == UINT_MAX)) {
3246c74663799493f2b1e6123c18def94295d0afab7Kenny Root				/* encode fixed */
3247c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(encoder->protected_->do_exhaustive_model_search) {
3248c74663799493f2b1e6123c18def94295d0afab7Kenny Root					min_fixed_order = 0;
3249c74663799493f2b1e6123c18def94295d0afab7Kenny Root					max_fixed_order = FLAC__MAX_FIXED_ORDER;
3250c74663799493f2b1e6123c18def94295d0afab7Kenny Root				}
3251c74663799493f2b1e6123c18def94295d0afab7Kenny Root				else {
3252c74663799493f2b1e6123c18def94295d0afab7Kenny Root					min_fixed_order = max_fixed_order = guess_fixed_order;
3253c74663799493f2b1e6123c18def94295d0afab7Kenny Root				}
3254c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(max_fixed_order >= frame_header->blocksize)
3255c74663799493f2b1e6123c18def94295d0afab7Kenny Root					max_fixed_order = frame_header->blocksize - 1;
3256c74663799493f2b1e6123c18def94295d0afab7Kenny Root				for(fixed_order = min_fixed_order; fixed_order <= max_fixed_order; fixed_order++) {
3257c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
3258c74663799493f2b1e6123c18def94295d0afab7Kenny Root					if(fixed_residual_bits_per_sample[fixed_order] >= (FLAC__float)subframe_bps)
3259c74663799493f2b1e6123c18def94295d0afab7Kenny Root						continue; /* don't even try */
3260c74663799493f2b1e6123c18def94295d0afab7Kenny Root					rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > 0.0)? (unsigned)(fixed_residual_bits_per_sample[fixed_order]+0.5) : 0; /* 0.5 is for rounding */
3261c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
3262c74663799493f2b1e6123c18def94295d0afab7Kenny Root					if(FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]) >= (int)subframe_bps)
3263c74663799493f2b1e6123c18def94295d0afab7Kenny Root						continue; /* don't even try */
3264c74663799493f2b1e6123c18def94295d0afab7Kenny Root					rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > FLAC__FP_ZERO)? (unsigned)FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]+FLAC__FP_ONE_HALF) : 0; /* 0.5 is for rounding */
3265c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3266c74663799493f2b1e6123c18def94295d0afab7Kenny Root					rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */
3267c74663799493f2b1e6123c18def94295d0afab7Kenny Root					if(rice_parameter >= rice_parameter_limit) {
3268c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef DEBUG_VERBOSE
3269c74663799493f2b1e6123c18def94295d0afab7Kenny Root						fprintf(stderr, "clipping rice_parameter (%u -> %u) @0\n", rice_parameter, rice_parameter_limit - 1);
3270c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3271c74663799493f2b1e6123c18def94295d0afab7Kenny Root						rice_parameter = rice_parameter_limit - 1;
3272c74663799493f2b1e6123c18def94295d0afab7Kenny Root					}
3273c74663799493f2b1e6123c18def94295d0afab7Kenny Root					_candidate_bits =
3274c74663799493f2b1e6123c18def94295d0afab7Kenny Root						evaluate_fixed_subframe_(
3275c74663799493f2b1e6123c18def94295d0afab7Kenny Root							encoder,
3276c74663799493f2b1e6123c18def94295d0afab7Kenny Root							integer_signal,
3277c74663799493f2b1e6123c18def94295d0afab7Kenny Root							residual[!_best_subframe],
3278c74663799493f2b1e6123c18def94295d0afab7Kenny Root							encoder->private_->abs_residual_partition_sums,
3279c74663799493f2b1e6123c18def94295d0afab7Kenny Root							encoder->private_->raw_bits_per_partition,
3280c74663799493f2b1e6123c18def94295d0afab7Kenny Root							frame_header->blocksize,
3281c74663799493f2b1e6123c18def94295d0afab7Kenny Root							subframe_bps,
3282c74663799493f2b1e6123c18def94295d0afab7Kenny Root							fixed_order,
3283c74663799493f2b1e6123c18def94295d0afab7Kenny Root							rice_parameter,
3284c74663799493f2b1e6123c18def94295d0afab7Kenny Root							rice_parameter_limit,
3285c74663799493f2b1e6123c18def94295d0afab7Kenny Root							min_partition_order,
3286c74663799493f2b1e6123c18def94295d0afab7Kenny Root							max_partition_order,
3287c74663799493f2b1e6123c18def94295d0afab7Kenny Root							encoder->protected_->do_escape_coding,
3288c74663799493f2b1e6123c18def94295d0afab7Kenny Root							encoder->protected_->rice_parameter_search_dist,
3289c74663799493f2b1e6123c18def94295d0afab7Kenny Root							subframe[!_best_subframe],
3290c74663799493f2b1e6123c18def94295d0afab7Kenny Root							partitioned_rice_contents[!_best_subframe]
3291c74663799493f2b1e6123c18def94295d0afab7Kenny Root						);
3292c74663799493f2b1e6123c18def94295d0afab7Kenny Root					if(_candidate_bits < _best_bits) {
3293c74663799493f2b1e6123c18def94295d0afab7Kenny Root						_best_subframe = !_best_subframe;
3294c74663799493f2b1e6123c18def94295d0afab7Kenny Root						_best_bits = _candidate_bits;
3295c74663799493f2b1e6123c18def94295d0afab7Kenny Root					}
3296c74663799493f2b1e6123c18def94295d0afab7Kenny Root				}
3297c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3298c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3299c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
3300c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* encode lpc */
3301c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(encoder->protected_->max_lpc_order > 0) {
3302c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(encoder->protected_->max_lpc_order >= frame_header->blocksize)
3303c74663799493f2b1e6123c18def94295d0afab7Kenny Root					max_lpc_order = frame_header->blocksize-1;
3304c74663799493f2b1e6123c18def94295d0afab7Kenny Root				else
3305c74663799493f2b1e6123c18def94295d0afab7Kenny Root					max_lpc_order = encoder->protected_->max_lpc_order;
3306c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(max_lpc_order > 0) {
3307c74663799493f2b1e6123c18def94295d0afab7Kenny Root					unsigned a;
3308c74663799493f2b1e6123c18def94295d0afab7Kenny Root					for (a = 0; a < encoder->protected_->num_apodizations; a++) {
3309c74663799493f2b1e6123c18def94295d0afab7Kenny Root						FLAC__lpc_window_data(integer_signal, encoder->private_->window[a], encoder->private_->windowed_signal, frame_header->blocksize);
3310c74663799493f2b1e6123c18def94295d0afab7Kenny Root						encoder->private_->local_lpc_compute_autocorrelation(encoder->private_->windowed_signal, frame_header->blocksize, max_lpc_order+1, autoc);
3311c74663799493f2b1e6123c18def94295d0afab7Kenny Root						/* if autoc[0] == 0.0, the signal is constant and we usually won't get here, but it can happen */
3312c74663799493f2b1e6123c18def94295d0afab7Kenny Root						if(autoc[0] != 0.0) {
3313c74663799493f2b1e6123c18def94295d0afab7Kenny Root							FLAC__lpc_compute_lp_coefficients(autoc, &max_lpc_order, encoder->private_->lp_coeff, lpc_error);
3314c74663799493f2b1e6123c18def94295d0afab7Kenny Root							if(encoder->protected_->do_exhaustive_model_search) {
3315c74663799493f2b1e6123c18def94295d0afab7Kenny Root								min_lpc_order = 1;
3316c74663799493f2b1e6123c18def94295d0afab7Kenny Root							}
3317c74663799493f2b1e6123c18def94295d0afab7Kenny Root							else {
3318c74663799493f2b1e6123c18def94295d0afab7Kenny Root								const unsigned guess_lpc_order =
3319c74663799493f2b1e6123c18def94295d0afab7Kenny Root									FLAC__lpc_compute_best_order(
3320c74663799493f2b1e6123c18def94295d0afab7Kenny Root										lpc_error,
3321c74663799493f2b1e6123c18def94295d0afab7Kenny Root										max_lpc_order,
3322c74663799493f2b1e6123c18def94295d0afab7Kenny Root										frame_header->blocksize,
3323c74663799493f2b1e6123c18def94295d0afab7Kenny Root										subframe_bps + (
3324c74663799493f2b1e6123c18def94295d0afab7Kenny Root											encoder->protected_->do_qlp_coeff_prec_search?
3325c74663799493f2b1e6123c18def94295d0afab7Kenny Root												FLAC__MIN_QLP_COEFF_PRECISION : /* have to guess; use the min possible size to avoid accidentally favoring lower orders */
3326c74663799493f2b1e6123c18def94295d0afab7Kenny Root												encoder->protected_->qlp_coeff_precision
3327c74663799493f2b1e6123c18def94295d0afab7Kenny Root										)
3328c74663799493f2b1e6123c18def94295d0afab7Kenny Root									);
3329c74663799493f2b1e6123c18def94295d0afab7Kenny Root								min_lpc_order = max_lpc_order = guess_lpc_order;
3330c74663799493f2b1e6123c18def94295d0afab7Kenny Root							}
3331c74663799493f2b1e6123c18def94295d0afab7Kenny Root							if(max_lpc_order >= frame_header->blocksize)
3332c74663799493f2b1e6123c18def94295d0afab7Kenny Root								max_lpc_order = frame_header->blocksize - 1;
3333c74663799493f2b1e6123c18def94295d0afab7Kenny Root							for(lpc_order = min_lpc_order; lpc_order <= max_lpc_order; lpc_order++) {
3334c74663799493f2b1e6123c18def94295d0afab7Kenny Root								lpc_residual_bits_per_sample = FLAC__lpc_compute_expected_bits_per_residual_sample(lpc_error[lpc_order-1], frame_header->blocksize-lpc_order);
3335c74663799493f2b1e6123c18def94295d0afab7Kenny Root								if(lpc_residual_bits_per_sample >= (FLAC__double)subframe_bps)
3336c74663799493f2b1e6123c18def94295d0afab7Kenny Root									continue; /* don't even try */
3337c74663799493f2b1e6123c18def94295d0afab7Kenny Root								rice_parameter = (lpc_residual_bits_per_sample > 0.0)? (unsigned)(lpc_residual_bits_per_sample+0.5) : 0; /* 0.5 is for rounding */
3338c74663799493f2b1e6123c18def94295d0afab7Kenny Root								rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */
3339c74663799493f2b1e6123c18def94295d0afab7Kenny Root								if(rice_parameter >= rice_parameter_limit) {
3340c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef DEBUG_VERBOSE
3341c74663799493f2b1e6123c18def94295d0afab7Kenny Root									fprintf(stderr, "clipping rice_parameter (%u -> %u) @1\n", rice_parameter, rice_parameter_limit - 1);
3342c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3343c74663799493f2b1e6123c18def94295d0afab7Kenny Root									rice_parameter = rice_parameter_limit - 1;
3344c74663799493f2b1e6123c18def94295d0afab7Kenny Root								}
3345c74663799493f2b1e6123c18def94295d0afab7Kenny Root								if(encoder->protected_->do_qlp_coeff_prec_search) {
3346c74663799493f2b1e6123c18def94295d0afab7Kenny Root									min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION;
3347c74663799493f2b1e6123c18def94295d0afab7Kenny Root									/* try to ensure a 32-bit datapath throughout for 16bps(+1bps for side channel) or less */
3348c74663799493f2b1e6123c18def94295d0afab7Kenny Root									if(subframe_bps <= 17) {
3349c74663799493f2b1e6123c18def94295d0afab7Kenny Root										max_qlp_coeff_precision = min(32 - subframe_bps - lpc_order, FLAC__MAX_QLP_COEFF_PRECISION);
3350c74663799493f2b1e6123c18def94295d0afab7Kenny Root										max_qlp_coeff_precision = max(max_qlp_coeff_precision, min_qlp_coeff_precision);
3351c74663799493f2b1e6123c18def94295d0afab7Kenny Root									}
3352c74663799493f2b1e6123c18def94295d0afab7Kenny Root									else
3353c74663799493f2b1e6123c18def94295d0afab7Kenny Root										max_qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION;
3354c74663799493f2b1e6123c18def94295d0afab7Kenny Root								}
3355c74663799493f2b1e6123c18def94295d0afab7Kenny Root								else {
3356c74663799493f2b1e6123c18def94295d0afab7Kenny Root									min_qlp_coeff_precision = max_qlp_coeff_precision = encoder->protected_->qlp_coeff_precision;
3357c74663799493f2b1e6123c18def94295d0afab7Kenny Root								}
3358c74663799493f2b1e6123c18def94295d0afab7Kenny Root								for(qlp_coeff_precision = min_qlp_coeff_precision; qlp_coeff_precision <= max_qlp_coeff_precision; qlp_coeff_precision++) {
3359c74663799493f2b1e6123c18def94295d0afab7Kenny Root									_candidate_bits =
3360c74663799493f2b1e6123c18def94295d0afab7Kenny Root										evaluate_lpc_subframe_(
3361c74663799493f2b1e6123c18def94295d0afab7Kenny Root											encoder,
3362c74663799493f2b1e6123c18def94295d0afab7Kenny Root											integer_signal,
3363c74663799493f2b1e6123c18def94295d0afab7Kenny Root											residual[!_best_subframe],
3364c74663799493f2b1e6123c18def94295d0afab7Kenny Root											encoder->private_->abs_residual_partition_sums,
3365c74663799493f2b1e6123c18def94295d0afab7Kenny Root											encoder->private_->raw_bits_per_partition,
3366c74663799493f2b1e6123c18def94295d0afab7Kenny Root											encoder->private_->lp_coeff[lpc_order-1],
3367c74663799493f2b1e6123c18def94295d0afab7Kenny Root											frame_header->blocksize,
3368c74663799493f2b1e6123c18def94295d0afab7Kenny Root											subframe_bps,
3369c74663799493f2b1e6123c18def94295d0afab7Kenny Root											lpc_order,
3370c74663799493f2b1e6123c18def94295d0afab7Kenny Root											qlp_coeff_precision,
3371c74663799493f2b1e6123c18def94295d0afab7Kenny Root											rice_parameter,
3372c74663799493f2b1e6123c18def94295d0afab7Kenny Root											rice_parameter_limit,
3373c74663799493f2b1e6123c18def94295d0afab7Kenny Root											min_partition_order,
3374c74663799493f2b1e6123c18def94295d0afab7Kenny Root											max_partition_order,
3375c74663799493f2b1e6123c18def94295d0afab7Kenny Root											encoder->protected_->do_escape_coding,
3376c74663799493f2b1e6123c18def94295d0afab7Kenny Root											encoder->protected_->rice_parameter_search_dist,
3377c74663799493f2b1e6123c18def94295d0afab7Kenny Root											subframe[!_best_subframe],
3378c74663799493f2b1e6123c18def94295d0afab7Kenny Root											partitioned_rice_contents[!_best_subframe]
3379c74663799493f2b1e6123c18def94295d0afab7Kenny Root										);
3380c74663799493f2b1e6123c18def94295d0afab7Kenny Root									if(_candidate_bits > 0) { /* if == 0, there was a problem quantizing the lpcoeffs */
3381c74663799493f2b1e6123c18def94295d0afab7Kenny Root										if(_candidate_bits < _best_bits) {
3382c74663799493f2b1e6123c18def94295d0afab7Kenny Root											_best_subframe = !_best_subframe;
3383c74663799493f2b1e6123c18def94295d0afab7Kenny Root											_best_bits = _candidate_bits;
3384c74663799493f2b1e6123c18def94295d0afab7Kenny Root										}
3385c74663799493f2b1e6123c18def94295d0afab7Kenny Root									}
3386c74663799493f2b1e6123c18def94295d0afab7Kenny Root								}
3387c74663799493f2b1e6123c18def94295d0afab7Kenny Root							}
3388c74663799493f2b1e6123c18def94295d0afab7Kenny Root						}
3389c74663799493f2b1e6123c18def94295d0afab7Kenny Root					}
3390c74663799493f2b1e6123c18def94295d0afab7Kenny Root				}
3391c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3392c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
3393c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3394c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3395c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3396c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* under rare circumstances this can happen when all but lpc subframe types are disabled: */
3397c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(_best_bits == UINT_MAX) {
3398c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ASSERT(_best_subframe == 0);
3399c74663799493f2b1e6123c18def94295d0afab7Kenny Root		_best_bits = evaluate_verbatim_subframe_(encoder, integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]);
3400c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3401c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3402c74663799493f2b1e6123c18def94295d0afab7Kenny Root	*best_subframe = _best_subframe;
3403c74663799493f2b1e6123c18def94295d0afab7Kenny Root	*best_bits = _best_bits;
3404c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3405c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
3406c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
3407c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3408c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__bool add_subframe_(
3409c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
3410c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned blocksize,
3411c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned subframe_bps,
3412c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__Subframe *subframe,
3413c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__BitWriter *frame
3414c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
3415c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
3416c74663799493f2b1e6123c18def94295d0afab7Kenny Root	switch(subframe->type) {
3417c74663799493f2b1e6123c18def94295d0afab7Kenny Root		case FLAC__SUBFRAME_TYPE_CONSTANT:
3418c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(!FLAC__subframe_add_constant(&(subframe->data.constant), subframe_bps, subframe->wasted_bits, frame)) {
3419c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
3420c74663799493f2b1e6123c18def94295d0afab7Kenny Root				return false;
3421c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3422c74663799493f2b1e6123c18def94295d0afab7Kenny Root			break;
3423c74663799493f2b1e6123c18def94295d0afab7Kenny Root		case FLAC__SUBFRAME_TYPE_FIXED:
3424c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(!FLAC__subframe_add_fixed(&(subframe->data.fixed), blocksize - subframe->data.fixed.order, subframe_bps, subframe->wasted_bits, frame)) {
3425c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
3426c74663799493f2b1e6123c18def94295d0afab7Kenny Root				return false;
3427c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3428c74663799493f2b1e6123c18def94295d0afab7Kenny Root			break;
3429c74663799493f2b1e6123c18def94295d0afab7Kenny Root		case FLAC__SUBFRAME_TYPE_LPC:
3430c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(!FLAC__subframe_add_lpc(&(subframe->data.lpc), blocksize - subframe->data.lpc.order, subframe_bps, subframe->wasted_bits, frame)) {
3431c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
3432c74663799493f2b1e6123c18def94295d0afab7Kenny Root				return false;
3433c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3434c74663799493f2b1e6123c18def94295d0afab7Kenny Root			break;
3435c74663799493f2b1e6123c18def94295d0afab7Kenny Root		case FLAC__SUBFRAME_TYPE_VERBATIM:
3436c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(!FLAC__subframe_add_verbatim(&(subframe->data.verbatim), blocksize, subframe_bps, subframe->wasted_bits, frame)) {
3437c74663799493f2b1e6123c18def94295d0afab7Kenny Root				encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
3438c74663799493f2b1e6123c18def94295d0afab7Kenny Root				return false;
3439c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3440c74663799493f2b1e6123c18def94295d0afab7Kenny Root			break;
3441c74663799493f2b1e6123c18def94295d0afab7Kenny Root		default:
3442c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__ASSERT(0);
3443c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3444c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3445c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
3446c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
3447c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3448c74663799493f2b1e6123c18def94295d0afab7Kenny Root#define SPOTCHECK_ESTIMATE 0
3449c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if SPOTCHECK_ESTIMATE
3450c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic void spotcheck_subframe_estimate_(
3451c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
3452c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned blocksize,
3453c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned subframe_bps,
3454c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__Subframe *subframe,
3455c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned estimate
3456c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
3457c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
3458c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool ret;
3459c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__BitWriter *frame = FLAC__bitwriter_new();
3460c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(frame == 0) {
3461c74663799493f2b1e6123c18def94295d0afab7Kenny Root		fprintf(stderr, "EST: can't allocate frame\n");
3462c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return;
3463c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3464c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!FLAC__bitwriter_init(frame)) {
3465c74663799493f2b1e6123c18def94295d0afab7Kenny Root		fprintf(stderr, "EST: can't init frame\n");
3466c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return;
3467c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3468c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ret = add_subframe_(encoder, blocksize, subframe_bps, subframe, frame);
3469c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(ret);
3470c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{
3471c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const unsigned actual = FLAC__bitwriter_get_input_bits_unconsumed(frame);
3472c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(estimate != actual)
3473c74663799493f2b1e6123c18def94295d0afab7Kenny Root			fprintf(stderr, "EST: bad, frame#%u sub#%%d type=%8s est=%u, actual=%u, delta=%d\n", encoder->private_->current_frame_number, FLAC__SubframeTypeString[subframe->type], estimate, actual, (int)actual-(int)estimate);
3474c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3475c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bitwriter_delete(frame);
3476c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
3477c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3478c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3479c74663799493f2b1e6123c18def94295d0afab7Kenny Rootunsigned evaluate_constant_subframe_(
3480c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
3481c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 signal,
3482c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned blocksize,
3483c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned subframe_bps,
3484c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__Subframe *subframe
3485c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
3486c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
3487c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned estimate;
3488c74663799493f2b1e6123c18def94295d0afab7Kenny Root	subframe->type = FLAC__SUBFRAME_TYPE_CONSTANT;
3489c74663799493f2b1e6123c18def94295d0afab7Kenny Root	subframe->data.constant.value = signal;
3490c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3491c74663799493f2b1e6123c18def94295d0afab7Kenny Root	estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + subframe_bps;
3492c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3493c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if SPOTCHECK_ESTIMATE
3494c74663799493f2b1e6123c18def94295d0afab7Kenny Root	spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate);
3495c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
3496c74663799493f2b1e6123c18def94295d0afab7Kenny Root	(void)encoder, (void)blocksize;
3497c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3498c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3499c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return estimate;
3500c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
3501c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3502c74663799493f2b1e6123c18def94295d0afab7Kenny Rootunsigned evaluate_fixed_subframe_(
3503c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
3504c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 signal[],
3505c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 residual[],
3506c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__uint64 abs_residual_partition_sums[],
3507c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned raw_bits_per_partition[],
3508c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned blocksize,
3509c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned subframe_bps,
3510c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned order,
3511c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter,
3512c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter_limit,
3513c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_partition_order,
3514c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned max_partition_order,
3515c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool do_escape_coding,
3516c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter_search_dist,
3517c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__Subframe *subframe,
3518c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
3519c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
3520c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
3521c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned i, residual_bits, estimate;
3522c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned residual_samples = blocksize - order;
3523c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3524c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__fixed_compute_residual(signal+order, residual_samples, order, residual);
3525c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3526c74663799493f2b1e6123c18def94295d0afab7Kenny Root	subframe->type = FLAC__SUBFRAME_TYPE_FIXED;
3527c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3528c74663799493f2b1e6123c18def94295d0afab7Kenny Root	subframe->data.fixed.entropy_coding_method.type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE;
3529c74663799493f2b1e6123c18def94295d0afab7Kenny Root	subframe->data.fixed.entropy_coding_method.data.partitioned_rice.contents = partitioned_rice_contents;
3530c74663799493f2b1e6123c18def94295d0afab7Kenny Root	subframe->data.fixed.residual = residual;
3531c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3532c74663799493f2b1e6123c18def94295d0afab7Kenny Root	residual_bits =
3533c74663799493f2b1e6123c18def94295d0afab7Kenny Root		find_best_partition_order_(
3534c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_,
3535c74663799493f2b1e6123c18def94295d0afab7Kenny Root			residual,
3536c74663799493f2b1e6123c18def94295d0afab7Kenny Root			abs_residual_partition_sums,
3537c74663799493f2b1e6123c18def94295d0afab7Kenny Root			raw_bits_per_partition,
3538c74663799493f2b1e6123c18def94295d0afab7Kenny Root			residual_samples,
3539c74663799493f2b1e6123c18def94295d0afab7Kenny Root			order,
3540c74663799493f2b1e6123c18def94295d0afab7Kenny Root			rice_parameter,
3541c74663799493f2b1e6123c18def94295d0afab7Kenny Root			rice_parameter_limit,
3542c74663799493f2b1e6123c18def94295d0afab7Kenny Root			min_partition_order,
3543c74663799493f2b1e6123c18def94295d0afab7Kenny Root			max_partition_order,
3544c74663799493f2b1e6123c18def94295d0afab7Kenny Root			subframe_bps,
3545c74663799493f2b1e6123c18def94295d0afab7Kenny Root			do_escape_coding,
3546c74663799493f2b1e6123c18def94295d0afab7Kenny Root			rice_parameter_search_dist,
3547c74663799493f2b1e6123c18def94295d0afab7Kenny Root			&subframe->data.fixed.entropy_coding_method
3548c74663799493f2b1e6123c18def94295d0afab7Kenny Root		);
3549c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3550c74663799493f2b1e6123c18def94295d0afab7Kenny Root	subframe->data.fixed.order = order;
3551c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < order; i++)
3552c74663799493f2b1e6123c18def94295d0afab7Kenny Root		subframe->data.fixed.warmup[i] = signal[i];
3553c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3554c74663799493f2b1e6123c18def94295d0afab7Kenny Root	estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (order * subframe_bps) + residual_bits;
3555c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3556c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if SPOTCHECK_ESTIMATE
3557c74663799493f2b1e6123c18def94295d0afab7Kenny Root	spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate);
3558c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3559c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3560c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return estimate;
3561c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
3562c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3563c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifndef FLAC__INTEGER_ONLY_LIBRARY
3564c74663799493f2b1e6123c18def94295d0afab7Kenny Rootunsigned evaluate_lpc_subframe_(
3565c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
3566c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 signal[],
3567c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 residual[],
3568c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__uint64 abs_residual_partition_sums[],
3569c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned raw_bits_per_partition[],
3570c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__real lp_coeff[],
3571c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned blocksize,
3572c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned subframe_bps,
3573c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned order,
3574c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned qlp_coeff_precision,
3575c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter,
3576c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter_limit,
3577c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_partition_order,
3578c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned max_partition_order,
3579c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool do_escape_coding,
3580c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter_search_dist,
3581c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__Subframe *subframe,
3582c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
3583c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
3584c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
3585c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER];
3586c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned i, residual_bits, estimate;
3587c74663799493f2b1e6123c18def94295d0afab7Kenny Root	int quantization, ret;
3588c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned residual_samples = blocksize - order;
3589c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3590c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* try to keep qlp coeff precision such that only 32-bit math is required for decode of <=16bps streams */
3591c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(subframe_bps <= 16) {
3592c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ASSERT(order > 0);
3593c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ASSERT(order <= FLAC__MAX_LPC_ORDER);
3594c74663799493f2b1e6123c18def94295d0afab7Kenny Root		qlp_coeff_precision = min(qlp_coeff_precision, 32 - subframe_bps - FLAC__bitmath_ilog2(order));
3595c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3596c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3597c74663799493f2b1e6123c18def94295d0afab7Kenny Root	ret = FLAC__lpc_quantize_coefficients(lp_coeff, order, qlp_coeff_precision, qlp_coeff, &quantization);
3598c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(ret != 0)
3599c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return 0; /* this is a hack to indicate to the caller that we can't do lp at this order on this subframe */
3600c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3601c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(subframe_bps + qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32)
3602c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(subframe_bps <= 16 && qlp_coeff_precision <= 16)
3603c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit(signal+order, residual_samples, qlp_coeff, order, quantization, residual);
3604c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else
3605c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->local_lpc_compute_residual_from_qlp_coefficients(signal+order, residual_samples, qlp_coeff, order, quantization, residual);
3606c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else
3607c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit(signal+order, residual_samples, qlp_coeff, order, quantization, residual);
3608c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3609c74663799493f2b1e6123c18def94295d0afab7Kenny Root	subframe->type = FLAC__SUBFRAME_TYPE_LPC;
3610c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3611c74663799493f2b1e6123c18def94295d0afab7Kenny Root	subframe->data.lpc.entropy_coding_method.type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE;
3612c74663799493f2b1e6123c18def94295d0afab7Kenny Root	subframe->data.lpc.entropy_coding_method.data.partitioned_rice.contents = partitioned_rice_contents;
3613c74663799493f2b1e6123c18def94295d0afab7Kenny Root	subframe->data.lpc.residual = residual;
3614c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3615c74663799493f2b1e6123c18def94295d0afab7Kenny Root	residual_bits =
3616c74663799493f2b1e6123c18def94295d0afab7Kenny Root		find_best_partition_order_(
3617c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_,
3618c74663799493f2b1e6123c18def94295d0afab7Kenny Root			residual,
3619c74663799493f2b1e6123c18def94295d0afab7Kenny Root			abs_residual_partition_sums,
3620c74663799493f2b1e6123c18def94295d0afab7Kenny Root			raw_bits_per_partition,
3621c74663799493f2b1e6123c18def94295d0afab7Kenny Root			residual_samples,
3622c74663799493f2b1e6123c18def94295d0afab7Kenny Root			order,
3623c74663799493f2b1e6123c18def94295d0afab7Kenny Root			rice_parameter,
3624c74663799493f2b1e6123c18def94295d0afab7Kenny Root			rice_parameter_limit,
3625c74663799493f2b1e6123c18def94295d0afab7Kenny Root			min_partition_order,
3626c74663799493f2b1e6123c18def94295d0afab7Kenny Root			max_partition_order,
3627c74663799493f2b1e6123c18def94295d0afab7Kenny Root			subframe_bps,
3628c74663799493f2b1e6123c18def94295d0afab7Kenny Root			do_escape_coding,
3629c74663799493f2b1e6123c18def94295d0afab7Kenny Root			rice_parameter_search_dist,
3630c74663799493f2b1e6123c18def94295d0afab7Kenny Root			&subframe->data.lpc.entropy_coding_method
3631c74663799493f2b1e6123c18def94295d0afab7Kenny Root		);
3632c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3633c74663799493f2b1e6123c18def94295d0afab7Kenny Root	subframe->data.lpc.order = order;
3634c74663799493f2b1e6123c18def94295d0afab7Kenny Root	subframe->data.lpc.qlp_coeff_precision = qlp_coeff_precision;
3635c74663799493f2b1e6123c18def94295d0afab7Kenny Root	subframe->data.lpc.quantization_level = quantization;
3636c74663799493f2b1e6123c18def94295d0afab7Kenny Root	memcpy(subframe->data.lpc.qlp_coeff, qlp_coeff, sizeof(FLAC__int32)*FLAC__MAX_LPC_ORDER);
3637c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < order; i++)
3638c74663799493f2b1e6123c18def94295d0afab7Kenny Root		subframe->data.lpc.warmup[i] = signal[i];
3639c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3640c74663799493f2b1e6123c18def94295d0afab7Kenny Root	estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN + FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN + (order * (qlp_coeff_precision + subframe_bps)) + residual_bits;
3641c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3642c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if SPOTCHECK_ESTIMATE
3643c74663799493f2b1e6123c18def94295d0afab7Kenny Root	spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate);
3644c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3645c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3646c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return estimate;
3647c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
3648c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3649c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3650c74663799493f2b1e6123c18def94295d0afab7Kenny Rootunsigned evaluate_verbatim_subframe_(
3651c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder,
3652c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 signal[],
3653c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned blocksize,
3654c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned subframe_bps,
3655c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__Subframe *subframe
3656c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
3657c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
3658c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned estimate;
3659c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3660c74663799493f2b1e6123c18def94295d0afab7Kenny Root	subframe->type = FLAC__SUBFRAME_TYPE_VERBATIM;
3661c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3662c74663799493f2b1e6123c18def94295d0afab7Kenny Root	subframe->data.verbatim.data = signal;
3663c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3664c74663799493f2b1e6123c18def94295d0afab7Kenny Root	estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (blocksize * subframe_bps);
3665c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3666c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if SPOTCHECK_ESTIMATE
3667c74663799493f2b1e6123c18def94295d0afab7Kenny Root	spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate);
3668c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
3669c74663799493f2b1e6123c18def94295d0afab7Kenny Root	(void)encoder;
3670c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3671c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3672c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return estimate;
3673c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
3674c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3675c74663799493f2b1e6123c18def94295d0afab7Kenny Rootunsigned find_best_partition_order_(
3676c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoderPrivate *private_,
3677c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 residual[],
3678c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__uint64 abs_residual_partition_sums[],
3679c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned raw_bits_per_partition[],
3680c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned residual_samples,
3681c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned predictor_order,
3682c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter,
3683c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter_limit,
3684c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_partition_order,
3685c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned max_partition_order,
3686c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned bps,
3687c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__bool do_escape_coding,
3688c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter_search_dist,
3689c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__EntropyCodingMethod *best_ecm
3690c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
3691c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
3692c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned residual_bits, best_residual_bits = 0;
3693c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned best_parameters_index = 0;
3694c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned best_partition_order = 0;
3695c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned blocksize = residual_samples + predictor_order;
3696c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3697c74663799493f2b1e6123c18def94295d0afab7Kenny Root	max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(max_partition_order, blocksize, predictor_order);
3698c74663799493f2b1e6123c18def94295d0afab7Kenny Root	min_partition_order = min(min_partition_order, max_partition_order);
3699c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3700c74663799493f2b1e6123c18def94295d0afab7Kenny Root	precompute_partition_info_sums_(residual, abs_residual_partition_sums, residual_samples, predictor_order, min_partition_order, max_partition_order, bps);
3701c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3702c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(do_escape_coding)
3703c74663799493f2b1e6123c18def94295d0afab7Kenny Root		precompute_partition_info_escapes_(residual, raw_bits_per_partition, residual_samples, predictor_order, min_partition_order, max_partition_order);
3704c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3705c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{
3706c74663799493f2b1e6123c18def94295d0afab7Kenny Root		int partition_order;
3707c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned sum;
3708c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3709c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(partition_order = (int)max_partition_order, sum = 0; partition_order >= (int)min_partition_order; partition_order--) {
3710c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(!
3711c74663799493f2b1e6123c18def94295d0afab7Kenny Root				set_partitioned_rice_(
3712c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef EXACT_RICE_BITS_CALCULATION
3713c74663799493f2b1e6123c18def94295d0afab7Kenny Root					residual,
3714c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3715c74663799493f2b1e6123c18def94295d0afab7Kenny Root					abs_residual_partition_sums+sum,
3716c74663799493f2b1e6123c18def94295d0afab7Kenny Root					raw_bits_per_partition+sum,
3717c74663799493f2b1e6123c18def94295d0afab7Kenny Root					residual_samples,
3718c74663799493f2b1e6123c18def94295d0afab7Kenny Root					predictor_order,
3719c74663799493f2b1e6123c18def94295d0afab7Kenny Root					rice_parameter,
3720c74663799493f2b1e6123c18def94295d0afab7Kenny Root					rice_parameter_limit,
3721c74663799493f2b1e6123c18def94295d0afab7Kenny Root					rice_parameter_search_dist,
3722c74663799493f2b1e6123c18def94295d0afab7Kenny Root					(unsigned)partition_order,
3723c74663799493f2b1e6123c18def94295d0afab7Kenny Root					do_escape_coding,
3724c74663799493f2b1e6123c18def94295d0afab7Kenny Root					&private_->partitioned_rice_contents_extra[!best_parameters_index],
3725c74663799493f2b1e6123c18def94295d0afab7Kenny Root					&residual_bits
3726c74663799493f2b1e6123c18def94295d0afab7Kenny Root				)
3727c74663799493f2b1e6123c18def94295d0afab7Kenny Root			)
3728c74663799493f2b1e6123c18def94295d0afab7Kenny Root			{
3729c74663799493f2b1e6123c18def94295d0afab7Kenny Root				FLAC__ASSERT(best_residual_bits != 0);
3730c74663799493f2b1e6123c18def94295d0afab7Kenny Root				break;
3731c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3732c74663799493f2b1e6123c18def94295d0afab7Kenny Root			sum += 1u << partition_order;
3733c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(best_residual_bits == 0 || residual_bits < best_residual_bits) {
3734c74663799493f2b1e6123c18def94295d0afab7Kenny Root				best_residual_bits = residual_bits;
3735c74663799493f2b1e6123c18def94295d0afab7Kenny Root				best_parameters_index = !best_parameters_index;
3736c74663799493f2b1e6123c18def94295d0afab7Kenny Root				best_partition_order = partition_order;
3737c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3738c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3739c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3740c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3741c74663799493f2b1e6123c18def94295d0afab7Kenny Root	best_ecm->data.partitioned_rice.order = best_partition_order;
3742c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3743c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{
3744c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/*
3745c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 * We are allowed to de-const the pointer based on our special
3746c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 * knowledge; it is const to the outside world.
3747c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 */
3748c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__EntropyCodingMethod_PartitionedRiceContents* prc = (FLAC__EntropyCodingMethod_PartitionedRiceContents*)best_ecm->data.partitioned_rice.contents;
3749c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned partition;
3750c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3751c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/* save best parameters and raw_bits */
3752c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(prc, max(6, best_partition_order));
3753c74663799493f2b1e6123c18def94295d0afab7Kenny Root		memcpy(prc->parameters, private_->partitioned_rice_contents_extra[best_parameters_index].parameters, sizeof(unsigned)*(1<<(best_partition_order)));
3754c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(do_escape_coding)
3755c74663799493f2b1e6123c18def94295d0afab7Kenny Root			memcpy(prc->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, sizeof(unsigned)*(1<<(best_partition_order)));
3756c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/*
3757c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 * Now need to check if the type should be changed to
3758c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 * FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 based on the
3759c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 * size of the rice parameters.
3760c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 */
3761c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(partition = 0; partition < (1u<<best_partition_order); partition++) {
3762c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(prc->parameters[partition] >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
3763c74663799493f2b1e6123c18def94295d0afab7Kenny Root				best_ecm->type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2;
3764c74663799493f2b1e6123c18def94295d0afab7Kenny Root				break;
3765c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3766c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3767c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3768c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3769c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return best_residual_bits;
3770c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
3771c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3772c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && defined FLAC__HAS_NASM
3773c74663799493f2b1e6123c18def94295d0afab7Kenny Rootextern void precompute_partition_info_sums_32bit_asm_ia32_(
3774c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 residual[],
3775c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__uint64 abs_residual_partition_sums[],
3776c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned blocksize,
3777c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned predictor_order,
3778c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_partition_order,
3779c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned max_partition_order
3780c74663799493f2b1e6123c18def94295d0afab7Kenny Root);
3781c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3782c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3783c74663799493f2b1e6123c18def94295d0afab7Kenny Rootvoid precompute_partition_info_sums_(
3784c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 residual[],
3785c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__uint64 abs_residual_partition_sums[],
3786c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned residual_samples,
3787c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned predictor_order,
3788c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_partition_order,
3789c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned max_partition_order,
3790c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned bps
3791c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
3792c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
3793c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned default_partition_samples = (residual_samples + predictor_order) >> max_partition_order;
3794c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned partitions = 1u << max_partition_order;
3795c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3796c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(default_partition_samples > predictor_order);
3797c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3798c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && defined FLAC__HAS_NASM
3799c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* slightly pessimistic but still catches all common cases */
3800c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* WATCHOUT: "+ bps" is an assumption that the average residual magnitude will not be more than "bps" bits */
3801c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(FLAC__bitmath_ilog2(default_partition_samples) + bps < 32) {
3802c74663799493f2b1e6123c18def94295d0afab7Kenny Root		precompute_partition_info_sums_32bit_asm_ia32_(residual, abs_residual_partition_sums, residual_samples + predictor_order, predictor_order, min_partition_order, max_partition_order);
3803c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return;
3804c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3805c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3806c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3807c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* first do max_partition_order */
3808c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{
3809c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order);
3810c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/* slightly pessimistic but still catches all common cases */
3811c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/* WATCHOUT: "+ bps" is an assumption that the average residual magnitude will not be more than "bps" bits */
3812c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(FLAC__bitmath_ilog2(default_partition_samples) + bps < 32) {
3813c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__uint32 abs_residual_partition_sum;
3814c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3815c74663799493f2b1e6123c18def94295d0afab7Kenny Root			for(partition = residual_sample = 0; partition < partitions; partition++) {
3816c74663799493f2b1e6123c18def94295d0afab7Kenny Root				end += default_partition_samples;
3817c74663799493f2b1e6123c18def94295d0afab7Kenny Root				abs_residual_partition_sum = 0;
3818c74663799493f2b1e6123c18def94295d0afab7Kenny Root				for( ; residual_sample < end; residual_sample++)
3819c74663799493f2b1e6123c18def94295d0afab7Kenny Root					abs_residual_partition_sum += abs(residual[residual_sample]); /* abs(INT_MIN) is undefined, but if the residual is INT_MIN we have bigger problems */
3820c74663799493f2b1e6123c18def94295d0afab7Kenny Root				abs_residual_partition_sums[partition] = abs_residual_partition_sum;
3821c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3822c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3823c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else { /* have to pessimistically use 64 bits for accumulator */
3824c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__uint64 abs_residual_partition_sum;
3825c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3826c74663799493f2b1e6123c18def94295d0afab7Kenny Root			for(partition = residual_sample = 0; partition < partitions; partition++) {
3827c74663799493f2b1e6123c18def94295d0afab7Kenny Root				end += default_partition_samples;
3828c74663799493f2b1e6123c18def94295d0afab7Kenny Root				abs_residual_partition_sum = 0;
3829c74663799493f2b1e6123c18def94295d0afab7Kenny Root				for( ; residual_sample < end; residual_sample++)
3830c74663799493f2b1e6123c18def94295d0afab7Kenny Root					abs_residual_partition_sum += abs(residual[residual_sample]); /* abs(INT_MIN) is undefined, but if the residual is INT_MIN we have bigger problems */
3831c74663799493f2b1e6123c18def94295d0afab7Kenny Root				abs_residual_partition_sums[partition] = abs_residual_partition_sum;
3832c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3833c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3834c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3835c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3836c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* now merge partitions for lower orders */
3837c74663799493f2b1e6123c18def94295d0afab7Kenny Root	{
3838c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned from_partition = 0, to_partition = partitions;
3839c74663799493f2b1e6123c18def94295d0afab7Kenny Root		int partition_order;
3840c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(partition_order = (int)max_partition_order - 1; partition_order >= (int)min_partition_order; partition_order--) {
3841c74663799493f2b1e6123c18def94295d0afab7Kenny Root			unsigned i;
3842c74663799493f2b1e6123c18def94295d0afab7Kenny Root			partitions >>= 1;
3843c74663799493f2b1e6123c18def94295d0afab7Kenny Root			for(i = 0; i < partitions; i++) {
3844c74663799493f2b1e6123c18def94295d0afab7Kenny Root				abs_residual_partition_sums[to_partition++] =
3845c74663799493f2b1e6123c18def94295d0afab7Kenny Root					abs_residual_partition_sums[from_partition  ] +
3846c74663799493f2b1e6123c18def94295d0afab7Kenny Root					abs_residual_partition_sums[from_partition+1];
3847c74663799493f2b1e6123c18def94295d0afab7Kenny Root				from_partition += 2;
3848c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3849c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3850c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3851c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
3852c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3853c74663799493f2b1e6123c18def94295d0afab7Kenny Rootvoid precompute_partition_info_escapes_(
3854c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 residual[],
3855c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned raw_bits_per_partition[],
3856c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned residual_samples,
3857c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned predictor_order,
3858c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_partition_order,
3859c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned max_partition_order
3860c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
3861c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
3862c74663799493f2b1e6123c18def94295d0afab7Kenny Root	int partition_order;
3863c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned from_partition, to_partition = 0;
3864c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned blocksize = residual_samples + predictor_order;
3865c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3866c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* first do max_partition_order */
3867c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(partition_order = (int)max_partition_order; partition_order >= 0; partition_order--) {
3868c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__int32 r;
3869c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__uint32 rmax;
3870c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned partition, partition_sample, partition_samples, residual_sample;
3871c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const unsigned partitions = 1u << partition_order;
3872c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const unsigned default_partition_samples = blocksize >> partition_order;
3873c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3874c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ASSERT(default_partition_samples > predictor_order);
3875c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3876c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(partition = residual_sample = 0; partition < partitions; partition++) {
3877c74663799493f2b1e6123c18def94295d0afab7Kenny Root			partition_samples = default_partition_samples;
3878c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(partition == 0)
3879c74663799493f2b1e6123c18def94295d0afab7Kenny Root				partition_samples -= predictor_order;
3880c74663799493f2b1e6123c18def94295d0afab7Kenny Root			rmax = 0;
3881c74663799493f2b1e6123c18def94295d0afab7Kenny Root			for(partition_sample = 0; partition_sample < partition_samples; partition_sample++) {
3882c74663799493f2b1e6123c18def94295d0afab7Kenny Root				r = residual[residual_sample++];
3883c74663799493f2b1e6123c18def94295d0afab7Kenny Root				/* OPT: maybe faster: rmax |= r ^ (r>>31) */
3884c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(r < 0)
3885c74663799493f2b1e6123c18def94295d0afab7Kenny Root					rmax |= ~r;
3886c74663799493f2b1e6123c18def94295d0afab7Kenny Root				else
3887c74663799493f2b1e6123c18def94295d0afab7Kenny Root					rmax |= r;
3888c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
3889c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* now we know all residual values are in the range [-rmax-1,rmax] */
3890c74663799493f2b1e6123c18def94295d0afab7Kenny Root			raw_bits_per_partition[partition] = rmax? FLAC__bitmath_ilog2(rmax) + 2 : 1;
3891c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3892c74663799493f2b1e6123c18def94295d0afab7Kenny Root		to_partition = partitions;
3893c74663799493f2b1e6123c18def94295d0afab7Kenny Root		break; /*@@@ yuck, should remove the 'for' loop instead */
3894c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3895c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3896c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* now merge partitions for lower orders */
3897c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(from_partition = 0, --partition_order; partition_order >= (int)min_partition_order; partition_order--) {
3898c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned m;
3899c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned i;
3900c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const unsigned partitions = 1u << partition_order;
3901c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(i = 0; i < partitions; i++) {
3902c74663799493f2b1e6123c18def94295d0afab7Kenny Root			m = raw_bits_per_partition[from_partition];
3903c74663799493f2b1e6123c18def94295d0afab7Kenny Root			from_partition++;
3904c74663799493f2b1e6123c18def94295d0afab7Kenny Root			raw_bits_per_partition[to_partition] = max(m, raw_bits_per_partition[from_partition]);
3905c74663799493f2b1e6123c18def94295d0afab7Kenny Root			from_partition++;
3906c74663799493f2b1e6123c18def94295d0afab7Kenny Root			to_partition++;
3907c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
3908c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
3909c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
3910c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3911c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef EXACT_RICE_BITS_CALCULATION
3912c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLaC__INLINE unsigned count_rice_bits_in_partition_(
3913c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned rice_parameter,
3914c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned partition_samples,
3915c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 *residual
3916c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
3917c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
3918c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned i, partition_bits =
3919c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + /* actually could end up being FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN but err on side of 16bps */
3920c74663799493f2b1e6123c18def94295d0afab7Kenny Root		(1+rice_parameter) * partition_samples /* 1 for unary stop bit + rice_parameter for the binary portion */
3921c74663799493f2b1e6123c18def94295d0afab7Kenny Root	;
3922c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < partition_samples; i++)
3923c74663799493f2b1e6123c18def94295d0afab7Kenny Root		partition_bits += ( (FLAC__uint32)((residual[i]<<1)^(residual[i]>>31)) >> rice_parameter );
3924c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return partition_bits;
3925c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
3926c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
3927c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic FLaC__INLINE unsigned count_rice_bits_in_partition_(
3928c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned rice_parameter,
3929c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned partition_samples,
3930c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__uint64 abs_residual_partition_sum
3931c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
3932c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
3933c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return
3934c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + /* actually could end up being FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN but err on side of 16bps */
3935c74663799493f2b1e6123c18def94295d0afab7Kenny Root		(1+rice_parameter) * partition_samples + /* 1 for unary stop bit + rice_parameter for the binary portion */
3936c74663799493f2b1e6123c18def94295d0afab7Kenny Root		(
3937c74663799493f2b1e6123c18def94295d0afab7Kenny Root			rice_parameter?
3938c74663799493f2b1e6123c18def94295d0afab7Kenny Root				(unsigned)(abs_residual_partition_sum >> (rice_parameter-1)) /* rice_parameter-1 because the real coder sign-folds instead of using a sign bit */
3939c74663799493f2b1e6123c18def94295d0afab7Kenny Root				: (unsigned)(abs_residual_partition_sum << 1) /* can't shift by negative number, so reverse */
3940c74663799493f2b1e6123c18def94295d0afab7Kenny Root		)
3941c74663799493f2b1e6123c18def94295d0afab7Kenny Root		- (partition_samples >> 1)
3942c74663799493f2b1e6123c18def94295d0afab7Kenny Root		/* -(partition_samples>>1) to subtract out extra contributions to the abs_residual_partition_sum.
3943c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 * The actual number of bits used is closer to the sum(for all i in the partition) of  abs(residual[i])>>(rice_parameter-1)
3944c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 * By using the abs_residual_partition sum, we also add in bits in the LSBs that would normally be shifted out.
3945c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 * So the subtraction term tries to guess how many extra bits were contributed.
3946c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 * If the LSBs are randomly distributed, this should average to 0.5 extra bits per sample.
3947c74663799493f2b1e6123c18def94295d0afab7Kenny Root		 */
3948c74663799493f2b1e6123c18def94295d0afab7Kenny Root	;
3949c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
3950c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3951c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3952c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__bool set_partitioned_rice_(
3953c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef EXACT_RICE_BITS_CALCULATION
3954c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__int32 residual[],
3955c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3956c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__uint64 abs_residual_partition_sums[],
3957c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned raw_bits_per_partition[],
3958c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned residual_samples,
3959c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned predictor_order,
3960c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned suggested_rice_parameter,
3961c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned rice_parameter_limit,
3962c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned rice_parameter_search_dist,
3963c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned partition_order,
3964c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const FLAC__bool search_for_escapes,
3965c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents,
3966c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned *bits
3967c74663799493f2b1e6123c18def94295d0afab7Kenny Root)
3968c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
3969c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned rice_parameter, partition_bits;
3970c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned best_partition_bits, best_rice_parameter = 0;
3971c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned bits_ = FLAC__ENTROPY_CODING_METHOD_TYPE_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN;
3972c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned *parameters, *raw_bits;
3973c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef ENABLE_RICE_PARAMETER_SEARCH
3974c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned min_rice_parameter, max_rice_parameter;
3975c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
3976c74663799493f2b1e6123c18def94295d0afab7Kenny Root	(void)rice_parameter_search_dist;
3977c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3978c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3979c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(suggested_rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER);
3980c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(rice_parameter_limit <= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER);
3981c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3982c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, max(6, partition_order));
3983c74663799493f2b1e6123c18def94295d0afab7Kenny Root	parameters = partitioned_rice_contents->parameters;
3984c74663799493f2b1e6123c18def94295d0afab7Kenny Root	raw_bits = partitioned_rice_contents->raw_bits;
3985c74663799493f2b1e6123c18def94295d0afab7Kenny Root
3986c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(partition_order == 0) {
3987c74663799493f2b1e6123c18def94295d0afab7Kenny Root		best_partition_bits = (unsigned)(-1);
3988c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef ENABLE_RICE_PARAMETER_SEARCH
3989c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(rice_parameter_search_dist) {
3990c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(suggested_rice_parameter < rice_parameter_search_dist)
3991c74663799493f2b1e6123c18def94295d0afab7Kenny Root				min_rice_parameter = 0;
3992c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else
3993c74663799493f2b1e6123c18def94295d0afab7Kenny Root				min_rice_parameter = suggested_rice_parameter - rice_parameter_search_dist;
3994c74663799493f2b1e6123c18def94295d0afab7Kenny Root			max_rice_parameter = suggested_rice_parameter + rice_parameter_search_dist;
3995c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(max_rice_parameter >= rice_parameter_limit) {
3996c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef DEBUG_VERBOSE
3997c74663799493f2b1e6123c18def94295d0afab7Kenny Root				fprintf(stderr, "clipping rice_parameter (%u -> %u) @5\n", max_rice_parameter, rice_parameter_limit - 1);
3998c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
3999c74663799493f2b1e6123c18def94295d0afab7Kenny Root				max_rice_parameter = rice_parameter_limit - 1;
4000c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
4001c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
4002c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else
4003c74663799493f2b1e6123c18def94295d0afab7Kenny Root			min_rice_parameter = max_rice_parameter = suggested_rice_parameter;
4004c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4005c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) {
4006c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
4007c74663799493f2b1e6123c18def94295d0afab7Kenny Root			rice_parameter = suggested_rice_parameter;
4008c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
4009c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef EXACT_RICE_BITS_CALCULATION
4010c74663799493f2b1e6123c18def94295d0afab7Kenny Root			partition_bits = count_rice_bits_in_partition_(rice_parameter, residual_samples, residual);
4011c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
4012c74663799493f2b1e6123c18def94295d0afab7Kenny Root			partition_bits = count_rice_bits_in_partition_(rice_parameter, residual_samples, abs_residual_partition_sums[0]);
4013c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
4014c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(partition_bits < best_partition_bits) {
4015c74663799493f2b1e6123c18def94295d0afab7Kenny Root				best_rice_parameter = rice_parameter;
4016c74663799493f2b1e6123c18def94295d0afab7Kenny Root				best_partition_bits = partition_bits;
4017c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
4018c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef ENABLE_RICE_PARAMETER_SEARCH
4019c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
4020c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
4021c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(search_for_escapes) {
4022c74663799493f2b1e6123c18def94295d0afab7Kenny Root			partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[0] * residual_samples;
4023c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(partition_bits <= best_partition_bits) {
4024c74663799493f2b1e6123c18def94295d0afab7Kenny Root				raw_bits[0] = raw_bits_per_partition[0];
4025c74663799493f2b1e6123c18def94295d0afab7Kenny Root				best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */
4026c74663799493f2b1e6123c18def94295d0afab7Kenny Root				best_partition_bits = partition_bits;
4027c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
4028c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else
4029c74663799493f2b1e6123c18def94295d0afab7Kenny Root				raw_bits[0] = 0;
4030c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
4031c74663799493f2b1e6123c18def94295d0afab7Kenny Root		parameters[0] = best_rice_parameter;
4032c74663799493f2b1e6123c18def94295d0afab7Kenny Root		bits_ += best_partition_bits;
4033c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
4034c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else {
4035c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned partition, residual_sample;
4036c74663799493f2b1e6123c18def94295d0afab7Kenny Root		unsigned partition_samples;
4037c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__uint64 mean, k;
4038c74663799493f2b1e6123c18def94295d0afab7Kenny Root		const unsigned partitions = 1u << partition_order;
4039c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(partition = residual_sample = 0; partition < partitions; partition++) {
4040c74663799493f2b1e6123c18def94295d0afab7Kenny Root			partition_samples = (residual_samples+predictor_order) >> partition_order;
4041c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(partition == 0) {
4042c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(partition_samples <= predictor_order)
4043c74663799493f2b1e6123c18def94295d0afab7Kenny Root					return false;
4044c74663799493f2b1e6123c18def94295d0afab7Kenny Root				else
4045c74663799493f2b1e6123c18def94295d0afab7Kenny Root					partition_samples -= predictor_order;
4046c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
4047c74663799493f2b1e6123c18def94295d0afab7Kenny Root			mean = abs_residual_partition_sums[partition];
4048c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* we are basically calculating the size in bits of the
4049c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 * average residual magnitude in the partition:
4050c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 *   rice_parameter = floor(log2(mean/partition_samples))
4051c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 * 'mean' is not a good name for the variable, it is
4052c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 * actually the sum of magnitudes of all residual values
4053c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 * in the partition, so the actual mean is
4054c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 * mean/partition_samples
4055c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 */
4056c74663799493f2b1e6123c18def94295d0afab7Kenny Root			for(rice_parameter = 0, k = partition_samples; k < mean; rice_parameter++, k <<= 1)
4057c74663799493f2b1e6123c18def94295d0afab7Kenny Root				;
4058c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(rice_parameter >= rice_parameter_limit) {
4059c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef DEBUG_VERBOSE
4060c74663799493f2b1e6123c18def94295d0afab7Kenny Root				fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, rice_parameter_limit - 1);
4061c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
4062c74663799493f2b1e6123c18def94295d0afab7Kenny Root				rice_parameter = rice_parameter_limit - 1;
4063c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
4064c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4065c74663799493f2b1e6123c18def94295d0afab7Kenny Root			best_partition_bits = (unsigned)(-1);
4066c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef ENABLE_RICE_PARAMETER_SEARCH
4067c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(rice_parameter_search_dist) {
4068c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(rice_parameter < rice_parameter_search_dist)
4069c74663799493f2b1e6123c18def94295d0afab7Kenny Root					min_rice_parameter = 0;
4070c74663799493f2b1e6123c18def94295d0afab7Kenny Root				else
4071c74663799493f2b1e6123c18def94295d0afab7Kenny Root					min_rice_parameter = rice_parameter - rice_parameter_search_dist;
4072c74663799493f2b1e6123c18def94295d0afab7Kenny Root				max_rice_parameter = rice_parameter + rice_parameter_search_dist;
4073c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(max_rice_parameter >= rice_parameter_limit) {
4074c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef DEBUG_VERBOSE
4075c74663799493f2b1e6123c18def94295d0afab7Kenny Root					fprintf(stderr, "clipping rice_parameter (%u -> %u) @7\n", max_rice_parameter, rice_parameter_limit - 1);
4076c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
4077c74663799493f2b1e6123c18def94295d0afab7Kenny Root					max_rice_parameter = rice_parameter_limit - 1;
4078c74663799493f2b1e6123c18def94295d0afab7Kenny Root				}
4079c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
4080c74663799493f2b1e6123c18def94295d0afab7Kenny Root			else
4081c74663799493f2b1e6123c18def94295d0afab7Kenny Root				min_rice_parameter = max_rice_parameter = rice_parameter;
4082c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4083c74663799493f2b1e6123c18def94295d0afab7Kenny Root			for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) {
4084c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
4085c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef EXACT_RICE_BITS_CALCULATION
4086c74663799493f2b1e6123c18def94295d0afab7Kenny Root				partition_bits = count_rice_bits_in_partition_(rice_parameter, partition_samples, residual+residual_sample);
4087c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
4088c74663799493f2b1e6123c18def94295d0afab7Kenny Root				partition_bits = count_rice_bits_in_partition_(rice_parameter, partition_samples, abs_residual_partition_sums[partition]);
4089c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
4090c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(partition_bits < best_partition_bits) {
4091c74663799493f2b1e6123c18def94295d0afab7Kenny Root					best_rice_parameter = rice_parameter;
4092c74663799493f2b1e6123c18def94295d0afab7Kenny Root					best_partition_bits = partition_bits;
4093c74663799493f2b1e6123c18def94295d0afab7Kenny Root				}
4094c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef ENABLE_RICE_PARAMETER_SEARCH
4095c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
4096c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
4097c74663799493f2b1e6123c18def94295d0afab7Kenny Root			if(search_for_escapes) {
4098c74663799493f2b1e6123c18def94295d0afab7Kenny Root				partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[partition] * partition_samples;
4099c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(partition_bits <= best_partition_bits) {
4100c74663799493f2b1e6123c18def94295d0afab7Kenny Root					raw_bits[partition] = raw_bits_per_partition[partition];
4101c74663799493f2b1e6123c18def94295d0afab7Kenny Root					best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */
4102c74663799493f2b1e6123c18def94295d0afab7Kenny Root					best_partition_bits = partition_bits;
4103c74663799493f2b1e6123c18def94295d0afab7Kenny Root				}
4104c74663799493f2b1e6123c18def94295d0afab7Kenny Root				else
4105c74663799493f2b1e6123c18def94295d0afab7Kenny Root					raw_bits[partition] = 0;
4106c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
4107c74663799493f2b1e6123c18def94295d0afab7Kenny Root			parameters[partition] = best_rice_parameter;
4108c74663799493f2b1e6123c18def94295d0afab7Kenny Root			bits_ += best_partition_bits;
4109c74663799493f2b1e6123c18def94295d0afab7Kenny Root			residual_sample += partition_samples;
4110c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
4111c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
4112c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4113c74663799493f2b1e6123c18def94295d0afab7Kenny Root	*bits = bits_;
4114c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return true;
4115c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
4116c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4117c74663799493f2b1e6123c18def94295d0afab7Kenny Rootunsigned get_wasted_bits_(FLAC__int32 signal[], unsigned samples)
4118c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
4119c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned i, shift;
4120c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__int32 x = 0;
4121c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4122c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(i = 0; i < samples && !(x&1); i++)
4123c74663799493f2b1e6123c18def94295d0afab7Kenny Root		x |= signal[i];
4124c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4125c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(x == 0) {
4126c74663799493f2b1e6123c18def94295d0afab7Kenny Root		shift = 0;
4127c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
4128c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else {
4129c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(shift = 0; !(x&1); shift++)
4130c74663799493f2b1e6123c18def94295d0afab7Kenny Root			x >>= 1;
4131c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
4132c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4133c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(shift > 0) {
4134c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(i = 0; i < samples; i++)
4135c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 signal[i] >>= shift;
4136c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
4137c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4138c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return shift;
4139c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
4140c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4141c74663799493f2b1e6123c18def94295d0afab7Kenny Rootvoid append_to_verify_fifo_(verify_input_fifo *fifo, const FLAC__int32 * const input[], unsigned input_offset, unsigned channels, unsigned wide_samples)
4142c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
4143c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned channel;
4144c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4145c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(channel = 0; channel < channels; channel++)
4146c74663799493f2b1e6123c18def94295d0afab7Kenny Root		memcpy(&fifo->data[channel][fifo->tail], &input[channel][input_offset], sizeof(FLAC__int32) * wide_samples);
4147c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4148c74663799493f2b1e6123c18def94295d0afab7Kenny Root	fifo->tail += wide_samples;
4149c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4150c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(fifo->tail <= fifo->size);
4151c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
4152c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4153c74663799493f2b1e6123c18def94295d0afab7Kenny Rootvoid append_to_verify_fifo_interleaved_(verify_input_fifo *fifo, const FLAC__int32 input[], unsigned input_offset, unsigned channels, unsigned wide_samples)
4154c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
4155c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned channel;
4156c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned sample, wide_sample;
4157c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned tail = fifo->tail;
4158c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4159c74663799493f2b1e6123c18def94295d0afab7Kenny Root	sample = input_offset * channels;
4160c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(wide_sample = 0; wide_sample < wide_samples; wide_sample++) {
4161c74663799493f2b1e6123c18def94295d0afab7Kenny Root		for(channel = 0; channel < channels; channel++)
4162c74663799493f2b1e6123c18def94295d0afab7Kenny Root			fifo->data[channel][tail] = input[sample++];
4163c74663799493f2b1e6123c18def94295d0afab7Kenny Root		tail++;
4164c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
4165c74663799493f2b1e6123c18def94295d0afab7Kenny Root	fifo->tail = tail;
4166c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4167c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(fifo->tail <= fifo->size);
4168c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
4169c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4170c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__StreamDecoderReadStatus verify_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
4171c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
4172c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder = (FLAC__StreamEncoder*)client_data;
4173c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const size_t encoded_bytes = encoder->private_->verify.output.bytes;
4174c74663799493f2b1e6123c18def94295d0afab7Kenny Root	(void)decoder;
4175c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4176c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(encoder->private_->verify.needs_magic_hack) {
4177c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__ASSERT(*bytes >= FLAC__STREAM_SYNC_LENGTH);
4178c74663799493f2b1e6123c18def94295d0afab7Kenny Root		*bytes = FLAC__STREAM_SYNC_LENGTH;
4179c74663799493f2b1e6123c18def94295d0afab7Kenny Root		memcpy(buffer, FLAC__STREAM_SYNC_STRING, *bytes);
4180c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->verify.needs_magic_hack = false;
4181c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
4182c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else {
4183c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(encoded_bytes == 0) {
4184c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/*
4185c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 * If we get here, a FIFO underflow has occurred,
4186c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 * which means there is a bug somewhere.
4187c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 */
4188c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__ASSERT(0);
4189c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
4190c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
4191c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if(encoded_bytes < *bytes)
4192c74663799493f2b1e6123c18def94295d0afab7Kenny Root			*bytes = encoded_bytes;
4193c74663799493f2b1e6123c18def94295d0afab7Kenny Root		memcpy(buffer, encoder->private_->verify.output.data, *bytes);
4194c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->verify.output.data += *bytes;
4195c74663799493f2b1e6123c18def94295d0afab7Kenny Root		encoder->private_->verify.output.bytes -= *bytes;
4196c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
4197c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4198c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
4199c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
4200c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4201c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__StreamDecoderWriteStatus verify_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
4202c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
4203c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder = (FLAC__StreamEncoder *)client_data;
4204c74663799493f2b1e6123c18def94295d0afab7Kenny Root	unsigned channel;
4205c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned channels = frame->header.channels;
4206c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned blocksize = frame->header.blocksize;
4207c74663799493f2b1e6123c18def94295d0afab7Kenny Root	const unsigned bytes_per_block = sizeof(FLAC__int32) * blocksize;
4208c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4209c74663799493f2b1e6123c18def94295d0afab7Kenny Root	(void)decoder;
4210c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4211c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(channel = 0; channel < channels; channel++) {
4212c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(0 != memcmp(buffer[channel], encoder->private_->verify.input_fifo.data[channel], bytes_per_block)) {
4213c74663799493f2b1e6123c18def94295d0afab7Kenny Root			unsigned i, sample = 0;
4214c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__int32 expect = 0, got = 0;
4215c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4216c74663799493f2b1e6123c18def94295d0afab7Kenny Root			for(i = 0; i < blocksize; i++) {
4217c74663799493f2b1e6123c18def94295d0afab7Kenny Root				if(buffer[channel][i] != encoder->private_->verify.input_fifo.data[channel][i]) {
4218c74663799493f2b1e6123c18def94295d0afab7Kenny Root					sample = i;
4219c74663799493f2b1e6123c18def94295d0afab7Kenny Root					expect = (FLAC__int32)encoder->private_->verify.input_fifo.data[channel][i];
4220c74663799493f2b1e6123c18def94295d0afab7Kenny Root					got = (FLAC__int32)buffer[channel][i];
4221c74663799493f2b1e6123c18def94295d0afab7Kenny Root					break;
4222c74663799493f2b1e6123c18def94295d0afab7Kenny Root				}
4223c74663799493f2b1e6123c18def94295d0afab7Kenny Root			}
4224c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__ASSERT(i < blocksize);
4225c74663799493f2b1e6123c18def94295d0afab7Kenny Root			FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
4226c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->verify.error_stats.absolute_sample = frame->header.number.sample_number + sample;
4227c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->verify.error_stats.frame_number = (unsigned)(frame->header.number.sample_number / blocksize);
4228c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->verify.error_stats.channel = channel;
4229c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->verify.error_stats.sample = sample;
4230c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->verify.error_stats.expected = expect;
4231c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->verify.error_stats.got = got;
4232c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA;
4233c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
4234c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
4235c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
4236c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* dequeue the frame from the fifo */
4237c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->private_->verify.input_fifo.tail -= blocksize;
4238c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__ASSERT(encoder->private_->verify.input_fifo.tail <= OVERREAD_);
4239c74663799493f2b1e6123c18def94295d0afab7Kenny Root	for(channel = 0; channel < channels; channel++)
4240c74663799493f2b1e6123c18def94295d0afab7Kenny Root		memmove(&encoder->private_->verify.input_fifo.data[channel][0], &encoder->private_->verify.input_fifo.data[channel][blocksize], encoder->private_->verify.input_fifo.tail * sizeof(encoder->private_->verify.input_fifo.data[0][0]));
4241c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
4242c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
4243c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4244c74663799493f2b1e6123c18def94295d0afab7Kenny Rootvoid verify_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
4245c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
4246c74663799493f2b1e6123c18def94295d0afab7Kenny Root	(void)decoder, (void)metadata, (void)client_data;
4247c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
4248c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4249c74663799493f2b1e6123c18def94295d0afab7Kenny Rootvoid verify_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
4250c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
4251c74663799493f2b1e6123c18def94295d0afab7Kenny Root	FLAC__StreamEncoder *encoder = (FLAC__StreamEncoder*)client_data;
4252c74663799493f2b1e6123c18def94295d0afab7Kenny Root	(void)decoder, (void)status;
4253c74663799493f2b1e6123c18def94295d0afab7Kenny Root	encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR;
4254c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
4255c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4256c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__StreamEncoderReadStatus file_read_callback_(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
4257c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
4258c74663799493f2b1e6123c18def94295d0afab7Kenny Root	(void)client_data;
4259c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4260c74663799493f2b1e6123c18def94295d0afab7Kenny Root	*bytes = fread(buffer, 1, *bytes, encoder->private_->file);
4261c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if (*bytes == 0) {
4262c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if (feof(encoder->private_->file))
4263c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM;
4264c74663799493f2b1e6123c18def94295d0afab7Kenny Root		else if (ferror(encoder->private_->file))
4265c74663799493f2b1e6123c18def94295d0afab7Kenny Root			return FLAC__STREAM_ENCODER_READ_STATUS_ABORT;
4266c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
4267c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE;
4268c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
4269c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4270c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__StreamEncoderSeekStatus file_seek_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
4271c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
4272c74663799493f2b1e6123c18def94295d0afab7Kenny Root	(void)client_data;
4273c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4274c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(fseeko(encoder->private_->file, (off_t)absolute_byte_offset, SEEK_SET) < 0)
4275c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR;
4276c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else
4277c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_SEEK_STATUS_OK;
4278c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
4279c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4280c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__StreamEncoderTellStatus file_tell_callback_(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
4281c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
4282c74663799493f2b1e6123c18def94295d0afab7Kenny Root	off_t offset;
4283c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4284c74663799493f2b1e6123c18def94295d0afab7Kenny Root	(void)client_data;
4285c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4286c74663799493f2b1e6123c18def94295d0afab7Kenny Root	offset = ftello(encoder->private_->file);
4287c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4288c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(offset < 0) {
4289c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR;
4290c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
4291c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else {
4292c74663799493f2b1e6123c18def94295d0afab7Kenny Root		*absolute_byte_offset = (FLAC__uint64)offset;
4293c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_TELL_STATUS_OK;
4294c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
4295c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
4296c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4297c74663799493f2b1e6123c18def94295d0afab7Kenny Root#ifdef FLAC__VALGRIND_TESTING
4298c74663799493f2b1e6123c18def94295d0afab7Kenny Rootstatic size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
4299c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
4300c74663799493f2b1e6123c18def94295d0afab7Kenny Root	size_t ret = fwrite(ptr, size, nmemb, stream);
4301c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(!ferror(stream))
4302c74663799493f2b1e6123c18def94295d0afab7Kenny Root		fflush(stream);
4303c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return ret;
4304c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
4305c74663799493f2b1e6123c18def94295d0afab7Kenny Root#else
4306c74663799493f2b1e6123c18def94295d0afab7Kenny Root#define local__fwrite fwrite
4307c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
4308c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4309c74663799493f2b1e6123c18def94295d0afab7Kenny RootFLAC__StreamEncoderWriteStatus file_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data)
4310c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
4311c74663799493f2b1e6123c18def94295d0afab7Kenny Root	(void)client_data, (void)current_frame;
4312c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4313c74663799493f2b1e6123c18def94295d0afab7Kenny Root	if(local__fwrite(buffer, sizeof(FLAC__byte), bytes, encoder->private_->file) == bytes) {
4314c74663799493f2b1e6123c18def94295d0afab7Kenny Root		FLAC__bool call_it = 0 != encoder->private_->progress_callback && (
4315c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if FLAC__HAS_OGG
4316c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* We would like to be able to use 'samples > 0' in the
4317c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 * clause here but currently because of the nature of our
4318c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 * Ogg writing implementation, 'samples' is always 0 (see
4319c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 * ogg_encoder_aspect.c).  The downside is extra progress
4320c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 * callbacks.
4321c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 */
4322c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->is_ogg? true :
4323c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
4324c74663799493f2b1e6123c18def94295d0afab7Kenny Root			samples > 0
4325c74663799493f2b1e6123c18def94295d0afab7Kenny Root		);
4326c74663799493f2b1e6123c18def94295d0afab7Kenny Root		if(call_it) {
4327c74663799493f2b1e6123c18def94295d0afab7Kenny Root			/* NOTE: We have to add +bytes, +samples, and +1 to the stats
4328c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 * because at this point in the callback chain, the stats
4329c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 * have not been updated.  Only after we return and control
4330c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 * gets back to write_frame_() are the stats updated
4331c74663799493f2b1e6123c18def94295d0afab7Kenny Root			 */
4332c74663799493f2b1e6123c18def94295d0afab7Kenny Root			encoder->private_->progress_callback(encoder, encoder->private_->bytes_written+bytes, encoder->private_->samples_written+samples, encoder->private_->frames_written+(samples?1:0), encoder->private_->total_frames_estimate, encoder->private_->client_data);
4333c74663799493f2b1e6123c18def94295d0afab7Kenny Root		}
4334c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
4335c74663799493f2b1e6123c18def94295d0afab7Kenny Root	}
4336c74663799493f2b1e6123c18def94295d0afab7Kenny Root	else
4337c74663799493f2b1e6123c18def94295d0afab7Kenny Root		return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
4338c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
4339c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4340c74663799493f2b1e6123c18def94295d0afab7Kenny Root/*
4341c74663799493f2b1e6123c18def94295d0afab7Kenny Root * This will forcibly set stdout to binary mode (for OSes that require it)
4342c74663799493f2b1e6123c18def94295d0afab7Kenny Root */
4343c74663799493f2b1e6123c18def94295d0afab7Kenny RootFILE *get_binary_stdout_(void)
4344c74663799493f2b1e6123c18def94295d0afab7Kenny Root{
4345c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* if something breaks here it is probably due to the presence or
4346c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * absence of an underscore before the identifiers 'setmode',
4347c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 * 'fileno', and/or 'O_BINARY'; check your system header files.
4348c74663799493f2b1e6123c18def94295d0afab7Kenny Root	 */
4349c74663799493f2b1e6123c18def94295d0afab7Kenny Root#if defined _MSC_VER || defined __MINGW32__
4350c74663799493f2b1e6123c18def94295d0afab7Kenny Root	_setmode(_fileno(stdout), _O_BINARY);
4351c74663799493f2b1e6123c18def94295d0afab7Kenny Root#elif defined __CYGWIN__
4352c74663799493f2b1e6123c18def94295d0afab7Kenny Root	/* almost certainly not needed for any modern Cygwin, but let's be safe... */
4353c74663799493f2b1e6123c18def94295d0afab7Kenny Root	setmode(_fileno(stdout), _O_BINARY);
4354c74663799493f2b1e6123c18def94295d0afab7Kenny Root#elif defined __EMX__
4355c74663799493f2b1e6123c18def94295d0afab7Kenny Root	setmode(fileno(stdout), O_BINARY);
4356c74663799493f2b1e6123c18def94295d0afab7Kenny Root#endif
4357c74663799493f2b1e6123c18def94295d0afab7Kenny Root
4358c74663799493f2b1e6123c18def94295d0afab7Kenny Root	return stdout;
4359c74663799493f2b1e6123c18def94295d0afab7Kenny Root}
4360