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