minor syntax
[flac.git] / src / libFLAC / file_encoder.c
1 /* libFLAC - Free Lossless Audio Codec library
2  * Copyright (C) 2002,2003  Josh Coalson
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * - Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * - Neither the name of the Xiph.org Foundation nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include <stdio.h>
33 #include <stdlib.h> /* for malloc() */
34 #include <string.h> /* for strlen(), strcpy() */
35 #include "FLAC/assert.h"
36 #include "protected/file_encoder.h"
37
38 /***********************************************************************
39  *
40  * Private class method prototypes
41  *
42  ***********************************************************************/
43
44 /* unpublished debug routines */
45 extern FLAC__bool FLAC__seekable_stream_encoder_disable_constant_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
46 extern FLAC__bool FLAC__seekable_stream_encoder_disable_fixed_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
47 extern FLAC__bool FLAC__seekable_stream_encoder_disable_verbatim_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
48
49 static void set_defaults_(FLAC__FileEncoder *encoder);
50 static FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data);
51 static FLAC__SeekableStreamEncoderTellStatus tell_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
52 static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
53
54 /***********************************************************************
55  *
56  * Private class data
57  *
58  ***********************************************************************/
59
60 typedef struct FLAC__FileEncoderPrivate {
61         FLAC__FileEncoderProgressCallback progress_callback;
62         void *client_data;
63         char *filename;
64         FLAC__uint64 bytes_written;
65         FLAC__uint64 samples_written;
66         unsigned total_frames_estimate;
67         FLAC__SeekableStreamEncoder *seekable_stream_encoder;
68         FILE *file;
69 } FLAC__FileEncoderPrivate;
70
71 /***********************************************************************
72  *
73  * Public static class data
74  *
75  ***********************************************************************/
76
77 FLAC_API const char * const FLAC__FileEncoderStateString[] = {
78         "FLAC__FILE_ENCODER_OK",
79         "FLAC__FILE_ENCODER_NO_FILENAME",
80         "FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR",
81         "FLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING",
82         "FLAC__FILE_ENCODER_ERROR_OPENING_FILE",
83         "FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR",
84         "FLAC__FILE_ENCODER_ALREADY_INITIALIZED",
85         "FLAC__FILE_ENCODER_UNINITIALIZED"
86 };
87
88
89 /***********************************************************************
90  *
91  * Class constructor/destructor
92  *
93  ***********************************************************************/
94
95 FLAC_API FLAC__FileEncoder *FLAC__file_encoder_new()
96 {
97         FLAC__FileEncoder *encoder;
98
99         FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
100
101         encoder = (FLAC__FileEncoder*)calloc(1, sizeof(FLAC__FileEncoder));
102         if(encoder == 0) {
103                 return 0;
104         }
105
106         encoder->protected_ = (FLAC__FileEncoderProtected*)calloc(1, sizeof(FLAC__FileEncoderProtected));
107         if(encoder->protected_ == 0) {
108                 free(encoder);
109                 return 0;
110         }
111
112         encoder->private_ = (FLAC__FileEncoderPrivate*)calloc(1, sizeof(FLAC__FileEncoderPrivate));
113         if(encoder->private_ == 0) {
114                 free(encoder->protected_);
115                 free(encoder);
116                 return 0;
117         }
118
119         encoder->private_->seekable_stream_encoder = FLAC__seekable_stream_encoder_new();
120         if(0 == encoder->private_->seekable_stream_encoder) {
121                 free(encoder->private_);
122                 free(encoder->protected_);
123                 free(encoder);
124                 return 0;
125         }
126
127         encoder->private_->file = 0;
128
129         set_defaults_(encoder);
130
131         encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED;
132
133         return encoder;
134 }
135
136 FLAC_API void FLAC__file_encoder_delete(FLAC__FileEncoder *encoder)
137 {
138         FLAC__ASSERT(0 != encoder);
139         FLAC__ASSERT(0 != encoder->protected_);
140         FLAC__ASSERT(0 != encoder->private_);
141         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
142
143         (void)FLAC__file_encoder_finish(encoder);
144
145         FLAC__seekable_stream_encoder_delete(encoder->private_->seekable_stream_encoder);
146
147         free(encoder->private_);
148         free(encoder->protected_);
149         free(encoder);
150 }
151
152 /***********************************************************************
153  *
154  * Public class methods
155  *
156  ***********************************************************************/
157
158 FLAC_API FLAC__FileEncoderState FLAC__file_encoder_init(FLAC__FileEncoder *encoder)
159 {
160         FLAC__ASSERT(0 != encoder);
161
162         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
163                 return encoder->protected_->state = FLAC__FILE_ENCODER_ALREADY_INITIALIZED;
164
165         if(0 == encoder->private_->filename)
166                 return encoder->protected_->state = FLAC__FILE_ENCODER_NO_FILENAME;
167
168         encoder->private_->file = fopen(encoder->private_->filename, "w+b");
169
170         if(encoder->private_->file == 0)
171                 return encoder->protected_->state = FLAC__FILE_ENCODER_ERROR_OPENING_FILE;
172
173         encoder->private_->bytes_written = 0;
174         encoder->private_->samples_written = 0;
175
176         FLAC__seekable_stream_encoder_set_seek_callback(encoder->private_->seekable_stream_encoder, seek_callback_);
177         FLAC__seekable_stream_encoder_set_tell_callback(encoder->private_->seekable_stream_encoder, tell_callback_);
178         FLAC__seekable_stream_encoder_set_write_callback(encoder->private_->seekable_stream_encoder, write_callback_);
179         FLAC__seekable_stream_encoder_set_client_data(encoder->private_->seekable_stream_encoder, encoder);
180
181         if(FLAC__seekable_stream_encoder_init(encoder->private_->seekable_stream_encoder) != FLAC__SEEKABLE_STREAM_ENCODER_OK)
182                 return encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
183
184         {
185                 unsigned blocksize = FLAC__file_encoder_get_blocksize(encoder);
186
187                 FLAC__ASSERT(blocksize != 0);
188                 encoder->private_->total_frames_estimate = (unsigned)((FLAC__file_encoder_get_total_samples_estimate(encoder) + blocksize - 1) / blocksize);
189         }
190
191         return encoder->protected_->state = FLAC__FILE_ENCODER_OK;
192 }
193
194 FLAC_API void FLAC__file_encoder_finish(FLAC__FileEncoder *encoder)
195 {
196         FLAC__ASSERT(0 != encoder);
197
198         if(encoder->protected_->state == FLAC__FILE_ENCODER_UNINITIALIZED)
199                 return;
200
201         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
202
203         /* FLAC__seekable_stream_encoder_finish() might write data so we must close the file after it. */
204
205         FLAC__seekable_stream_encoder_finish(encoder->private_->seekable_stream_encoder);
206
207         if(0 != encoder->private_->file) {
208                 fclose(encoder->private_->file);
209                 encoder->private_->file = 0;
210         }
211
212         if(0 != encoder->private_->filename) {
213                 free(encoder->private_->filename);
214                 encoder->private_->filename = 0;
215         }
216
217         set_defaults_(encoder);
218
219         encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED;
220 }
221
222 FLAC_API FLAC__bool FLAC__file_encoder_set_verify(FLAC__FileEncoder *encoder, FLAC__bool value)
223 {
224         FLAC__ASSERT(0 != encoder);
225         FLAC__ASSERT(0 != encoder->private_);
226         FLAC__ASSERT(0 != encoder->protected_);
227         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
228         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
229                 return false;
230         return FLAC__seekable_stream_encoder_set_verify(encoder->private_->seekable_stream_encoder, value);
231 }
232
233 FLAC_API FLAC__bool FLAC__file_encoder_set_streamable_subset(FLAC__FileEncoder *encoder, FLAC__bool value)
234 {
235         FLAC__ASSERT(0 != encoder);
236         FLAC__ASSERT(0 != encoder->private_);
237         FLAC__ASSERT(0 != encoder->protected_);
238         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
239         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
240                 return false;
241         return FLAC__seekable_stream_encoder_set_streamable_subset(encoder->private_->seekable_stream_encoder, value);
242 }
243
244 FLAC_API FLAC__bool FLAC__file_encoder_set_do_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value)
245 {
246         FLAC__ASSERT(0 != encoder);
247         FLAC__ASSERT(0 != encoder->private_);
248         FLAC__ASSERT(0 != encoder->protected_);
249         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
250         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
251                 return false;
252         return FLAC__seekable_stream_encoder_set_do_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
253 }
254
255 FLAC_API FLAC__bool FLAC__file_encoder_set_loose_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value)
256 {
257         FLAC__ASSERT(0 != encoder);
258         FLAC__ASSERT(0 != encoder->private_);
259         FLAC__ASSERT(0 != encoder->protected_);
260         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
261         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
262                 return false;
263         return FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
264 }
265
266 FLAC_API FLAC__bool FLAC__file_encoder_set_channels(FLAC__FileEncoder *encoder, unsigned value)
267 {
268         FLAC__ASSERT(0 != encoder);
269         FLAC__ASSERT(0 != encoder->private_);
270         FLAC__ASSERT(0 != encoder->protected_);
271         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
272         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
273                 return false;
274         return FLAC__seekable_stream_encoder_set_channels(encoder->private_->seekable_stream_encoder, value);
275 }
276
277 FLAC_API FLAC__bool FLAC__file_encoder_set_bits_per_sample(FLAC__FileEncoder *encoder, unsigned value)
278 {
279         FLAC__ASSERT(0 != encoder);
280         FLAC__ASSERT(0 != encoder->private_);
281         FLAC__ASSERT(0 != encoder->protected_);
282         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
283         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
284                 return false;
285         return FLAC__seekable_stream_encoder_set_bits_per_sample(encoder->private_->seekable_stream_encoder, value);
286 }
287
288 FLAC_API FLAC__bool FLAC__file_encoder_set_sample_rate(FLAC__FileEncoder *encoder, unsigned value)
289 {
290         FLAC__ASSERT(0 != encoder);
291         FLAC__ASSERT(0 != encoder->private_);
292         FLAC__ASSERT(0 != encoder->protected_);
293         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
294         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
295                 return false;
296         return FLAC__seekable_stream_encoder_set_sample_rate(encoder->private_->seekable_stream_encoder, value);
297 }
298
299 FLAC_API FLAC__bool FLAC__file_encoder_set_blocksize(FLAC__FileEncoder *encoder, unsigned value)
300 {
301         FLAC__ASSERT(0 != encoder);
302         FLAC__ASSERT(0 != encoder->private_);
303         FLAC__ASSERT(0 != encoder->protected_);
304         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
305         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
306                 return false;
307         return FLAC__seekable_stream_encoder_set_blocksize(encoder->private_->seekable_stream_encoder, value);
308 }
309
310 FLAC_API FLAC__bool FLAC__file_encoder_set_max_lpc_order(FLAC__FileEncoder *encoder, unsigned value)
311 {
312         FLAC__ASSERT(0 != encoder);
313         FLAC__ASSERT(0 != encoder->private_);
314         FLAC__ASSERT(0 != encoder->protected_);
315         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
316         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
317                 return false;
318         return FLAC__seekable_stream_encoder_set_max_lpc_order(encoder->private_->seekable_stream_encoder, value);
319 }
320
321 FLAC_API FLAC__bool FLAC__file_encoder_set_qlp_coeff_precision(FLAC__FileEncoder *encoder, unsigned value)
322 {
323         FLAC__ASSERT(0 != encoder);
324         FLAC__ASSERT(0 != encoder->private_);
325         FLAC__ASSERT(0 != encoder->protected_);
326         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
327         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
328                 return false;
329         return FLAC__seekable_stream_encoder_set_qlp_coeff_precision(encoder->private_->seekable_stream_encoder, value);
330 }
331
332 FLAC_API FLAC__bool FLAC__file_encoder_set_do_qlp_coeff_prec_search(FLAC__FileEncoder *encoder, FLAC__bool value)
333 {
334         FLAC__ASSERT(0 != encoder);
335         FLAC__ASSERT(0 != encoder->private_);
336         FLAC__ASSERT(0 != encoder->protected_);
337         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
338         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
339                 return false;
340         return FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder, value);
341 }
342
343 FLAC_API FLAC__bool FLAC__file_encoder_set_do_escape_coding(FLAC__FileEncoder *encoder, FLAC__bool value)
344 {
345         FLAC__ASSERT(0 != encoder);
346         FLAC__ASSERT(0 != encoder->private_);
347         FLAC__ASSERT(0 != encoder->protected_);
348         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
349         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
350                 return false;
351         return FLAC__seekable_stream_encoder_set_do_escape_coding(encoder->private_->seekable_stream_encoder, value);
352 }
353
354 FLAC_API FLAC__bool FLAC__file_encoder_set_do_exhaustive_model_search(FLAC__FileEncoder *encoder, FLAC__bool value)
355 {
356         FLAC__ASSERT(0 != encoder);
357         FLAC__ASSERT(0 != encoder->private_);
358         FLAC__ASSERT(0 != encoder->protected_);
359         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
360         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
361                 return false;
362         return FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder, value);
363 }
364
365 FLAC_API FLAC__bool FLAC__file_encoder_set_min_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value)
366 {
367         FLAC__ASSERT(0 != encoder);
368         FLAC__ASSERT(0 != encoder->private_);
369         FLAC__ASSERT(0 != encoder->protected_);
370         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
371         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
372                 return false;
373         return FLAC__seekable_stream_encoder_set_min_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
374 }
375
376 FLAC_API FLAC__bool FLAC__file_encoder_set_max_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value)
377 {
378         FLAC__ASSERT(0 != encoder);
379         FLAC__ASSERT(0 != encoder->private_);
380         FLAC__ASSERT(0 != encoder->protected_);
381         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
382         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
383                 return false;
384         return FLAC__seekable_stream_encoder_set_max_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
385 }
386
387 FLAC_API FLAC__bool FLAC__file_encoder_set_rice_parameter_search_dist(FLAC__FileEncoder *encoder, unsigned value)
388 {
389         FLAC__ASSERT(0 != encoder);
390         FLAC__ASSERT(0 != encoder->private_);
391         FLAC__ASSERT(0 != encoder->protected_);
392         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
393         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
394                 return false;
395         return FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder, value);
396 }
397
398 FLAC_API FLAC__bool FLAC__file_encoder_set_total_samples_estimate(FLAC__FileEncoder *encoder, FLAC__uint64 value)
399 {
400         FLAC__ASSERT(0 != encoder);
401         FLAC__ASSERT(0 != encoder->private_);
402         FLAC__ASSERT(0 != encoder->protected_);
403         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
404         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
405                 return false;
406         return FLAC__seekable_stream_encoder_set_total_samples_estimate(encoder->private_->seekable_stream_encoder, value);
407 }
408
409 FLAC_API FLAC__bool FLAC__file_encoder_set_metadata(FLAC__FileEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
410 {
411         FLAC__ASSERT(0 != encoder);
412         FLAC__ASSERT(0 != encoder->private_);
413         FLAC__ASSERT(0 != encoder->protected_);
414         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
415         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
416                 return false;
417         return FLAC__seekable_stream_encoder_set_metadata(encoder->private_->seekable_stream_encoder, metadata, num_blocks);
418 }
419
420 FLAC_API FLAC__bool FLAC__file_encoder_set_filename(FLAC__FileEncoder *encoder, const char *value)
421 {
422         FLAC__ASSERT(0 != encoder);
423         FLAC__ASSERT(0 != encoder->private_);
424         FLAC__ASSERT(0 != encoder->protected_);
425         FLAC__ASSERT(0 != value);
426         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
427                 return false;
428         if(0 != encoder->private_->filename) {
429                 free(encoder->private_->filename);
430                 encoder->private_->filename = 0;
431         }
432         if(0 == (encoder->private_->filename = (char*)malloc(strlen(value)+1))) {
433                 encoder->protected_->state = FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR;
434                 return false;
435         }
436         strcpy(encoder->private_->filename, value);
437         return true;
438 }
439
440 FLAC_API FLAC__bool FLAC__file_encoder_set_progress_callback(FLAC__FileEncoder *encoder, FLAC__FileEncoderProgressCallback value)
441 {
442         FLAC__ASSERT(0 != encoder);
443         FLAC__ASSERT(0 != encoder->private_);
444         FLAC__ASSERT(0 != encoder->protected_);
445         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
446                 return false;
447         encoder->private_->progress_callback = value;
448         return true;
449 }
450
451 FLAC_API FLAC__bool FLAC__file_encoder_set_client_data(FLAC__FileEncoder *encoder, void *value)
452 {
453         FLAC__ASSERT(0 != encoder);
454         FLAC__ASSERT(0 != encoder->private_);
455         FLAC__ASSERT(0 != encoder->protected_);
456         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
457                 return false;
458         encoder->private_->client_data = value;
459         return true;
460 }
461
462 /*
463  * These three functions are not static, but not publically exposed in
464  * include/FLAC/ either.  They are used by the test suite.
465  */
466 FLAC_API FLAC__bool FLAC__file_encoder_disable_constant_subframes(FLAC__FileEncoder *encoder, FLAC__bool value)
467 {
468         FLAC__ASSERT(0 != encoder);
469         FLAC__ASSERT(0 != encoder->private_);
470         FLAC__ASSERT(0 != encoder->protected_);
471         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
472                 return false;
473         return FLAC__seekable_stream_encoder_disable_constant_subframes(encoder->private_->seekable_stream_encoder, value);
474 }
475
476 FLAC_API FLAC__bool FLAC__file_encoder_disable_fixed_subframes(FLAC__FileEncoder *encoder, FLAC__bool value)
477 {
478         FLAC__ASSERT(0 != encoder);
479         FLAC__ASSERT(0 != encoder->private_);
480         FLAC__ASSERT(0 != encoder->protected_);
481         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
482                 return false;
483         return FLAC__seekable_stream_encoder_disable_fixed_subframes(encoder->private_->seekable_stream_encoder, value);
484 }
485
486 FLAC_API FLAC__bool FLAC__file_encoder_disable_verbatim_subframes(FLAC__FileEncoder *encoder, FLAC__bool value)
487 {
488         FLAC__ASSERT(0 != encoder);
489         FLAC__ASSERT(0 != encoder->private_);
490         FLAC__ASSERT(0 != encoder->protected_);
491         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
492                 return false;
493         return FLAC__seekable_stream_encoder_disable_verbatim_subframes(encoder->private_->seekable_stream_encoder, value);
494 }
495
496 FLAC_API FLAC__FileEncoderState FLAC__file_encoder_get_state(const FLAC__FileEncoder *encoder)
497 {
498         FLAC__ASSERT(0 != encoder);
499         FLAC__ASSERT(0 != encoder->protected_);
500         return encoder->protected_->state;
501 }
502
503 FLAC_API FLAC__SeekableStreamEncoderState FLAC__file_encoder_get_seekable_stream_encoder_state(const FLAC__FileEncoder *encoder)
504 {
505         FLAC__ASSERT(0 != encoder);
506         FLAC__ASSERT(0 != encoder->private_);
507         return FLAC__seekable_stream_encoder_get_state(encoder->private_->seekable_stream_encoder);
508 }
509
510 FLAC_API FLAC__StreamEncoderState FLAC__file_encoder_get_stream_encoder_state(const FLAC__FileEncoder *encoder)
511 {
512         FLAC__ASSERT(0 != encoder);
513         FLAC__ASSERT(0 != encoder->private_);
514         return FLAC__seekable_stream_encoder_get_stream_encoder_state(encoder->private_->seekable_stream_encoder);
515 }
516
517 FLAC_API FLAC__StreamDecoderState FLAC__file_encoder_get_verify_decoder_state(const FLAC__FileEncoder *encoder)
518 {
519         FLAC__ASSERT(0 != encoder);
520         FLAC__ASSERT(0 != encoder->private_);
521         return FLAC__seekable_stream_encoder_get_verify_decoder_state(encoder->private_->seekable_stream_encoder);
522 }
523
524 FLAC_API const char *FLAC__file_encoder_get_resolved_state_string(const FLAC__FileEncoder *encoder)
525 {
526         if(encoder->protected_->state != FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR)
527                 return FLAC__FileEncoderStateString[encoder->protected_->state];
528         else
529                 return FLAC__seekable_stream_encoder_get_resolved_state_string(encoder->private_->seekable_stream_encoder);
530 }
531
532 FLAC_API void FLAC__file_encoder_get_verify_decoder_error_stats(const FLAC__FileEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
533 {
534         FLAC__ASSERT(0 != encoder);
535         FLAC__ASSERT(0 != encoder->private_);
536         FLAC__seekable_stream_encoder_get_verify_decoder_error_stats(encoder->private_->seekable_stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
537 }
538
539 FLAC_API FLAC__bool FLAC__file_encoder_get_verify(const FLAC__FileEncoder *encoder)
540 {
541         FLAC__ASSERT(0 != encoder);
542         FLAC__ASSERT(0 != encoder->private_);
543         return FLAC__seekable_stream_encoder_get_verify(encoder->private_->seekable_stream_encoder);
544 }
545
546 FLAC_API FLAC__bool FLAC__file_encoder_get_streamable_subset(const FLAC__FileEncoder *encoder)
547 {
548         FLAC__ASSERT(0 != encoder);
549         FLAC__ASSERT(0 != encoder->private_);
550         return FLAC__seekable_stream_encoder_get_streamable_subset(encoder->private_->seekable_stream_encoder);
551 }
552
553 FLAC_API FLAC__bool FLAC__file_encoder_get_do_mid_side_stereo(const FLAC__FileEncoder *encoder)
554 {
555         FLAC__ASSERT(0 != encoder);
556         FLAC__ASSERT(0 != encoder->private_);
557         return FLAC__seekable_stream_encoder_get_do_mid_side_stereo(encoder->private_->seekable_stream_encoder);
558 }
559
560 FLAC_API FLAC__bool FLAC__file_encoder_get_loose_mid_side_stereo(const FLAC__FileEncoder *encoder)
561 {
562         FLAC__ASSERT(0 != encoder);
563         FLAC__ASSERT(0 != encoder->private_);
564         return FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder);
565 }
566
567 FLAC_API unsigned FLAC__file_encoder_get_channels(const FLAC__FileEncoder *encoder)
568 {
569         FLAC__ASSERT(0 != encoder);
570         FLAC__ASSERT(0 != encoder->private_);
571         return FLAC__seekable_stream_encoder_get_channels(encoder->private_->seekable_stream_encoder);
572 }
573
574 FLAC_API unsigned FLAC__file_encoder_get_bits_per_sample(const FLAC__FileEncoder *encoder)
575 {
576         FLAC__ASSERT(0 != encoder);
577         FLAC__ASSERT(0 != encoder->private_);
578         return FLAC__seekable_stream_encoder_get_bits_per_sample(encoder->private_->seekable_stream_encoder);
579 }
580
581 FLAC_API unsigned FLAC__file_encoder_get_sample_rate(const FLAC__FileEncoder *encoder)
582 {
583         FLAC__ASSERT(0 != encoder);
584         FLAC__ASSERT(0 != encoder->private_);
585         return FLAC__seekable_stream_encoder_get_sample_rate(encoder->private_->seekable_stream_encoder);
586 }
587
588 FLAC_API unsigned FLAC__file_encoder_get_blocksize(const FLAC__FileEncoder *encoder)
589 {
590         FLAC__ASSERT(0 != encoder);
591         FLAC__ASSERT(0 != encoder->private_);
592         return FLAC__seekable_stream_encoder_get_blocksize(encoder->private_->seekable_stream_encoder);
593 }
594
595 FLAC_API unsigned FLAC__file_encoder_get_max_lpc_order(const FLAC__FileEncoder *encoder)
596 {
597         FLAC__ASSERT(0 != encoder);
598         FLAC__ASSERT(0 != encoder->private_);
599         return FLAC__seekable_stream_encoder_get_max_lpc_order(encoder->private_->seekable_stream_encoder);
600 }
601
602 FLAC_API unsigned FLAC__file_encoder_get_qlp_coeff_precision(const FLAC__FileEncoder *encoder)
603 {
604         FLAC__ASSERT(0 != encoder);
605         FLAC__ASSERT(0 != encoder->private_);
606         return FLAC__seekable_stream_encoder_get_qlp_coeff_precision(encoder->private_->seekable_stream_encoder);
607 }
608
609 FLAC_API FLAC__bool FLAC__file_encoder_get_do_qlp_coeff_prec_search(const FLAC__FileEncoder *encoder)
610 {
611         FLAC__ASSERT(0 != encoder);
612         FLAC__ASSERT(0 != encoder->private_);
613         return FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder);
614 }
615
616 FLAC_API FLAC__bool FLAC__file_encoder_get_do_escape_coding(const FLAC__FileEncoder *encoder)
617 {
618         FLAC__ASSERT(0 != encoder);
619         FLAC__ASSERT(0 != encoder->private_);
620         return FLAC__seekable_stream_encoder_get_do_escape_coding(encoder->private_->seekable_stream_encoder);
621 }
622
623 FLAC_API FLAC__bool FLAC__file_encoder_get_do_exhaustive_model_search(const FLAC__FileEncoder *encoder)
624 {
625         FLAC__ASSERT(0 != encoder);
626         FLAC__ASSERT(0 != encoder->private_);
627         return FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder);
628 }
629
630 FLAC_API unsigned FLAC__file_encoder_get_min_residual_partition_order(const FLAC__FileEncoder *encoder)
631 {
632         FLAC__ASSERT(0 != encoder);
633         FLAC__ASSERT(0 != encoder->private_);
634         return FLAC__seekable_stream_encoder_get_min_residual_partition_order(encoder->private_->seekable_stream_encoder);
635 }
636
637 FLAC_API unsigned FLAC__file_encoder_get_max_residual_partition_order(const FLAC__FileEncoder *encoder)
638 {
639         FLAC__ASSERT(0 != encoder);
640         FLAC__ASSERT(0 != encoder->private_);
641         return FLAC__seekable_stream_encoder_get_max_residual_partition_order(encoder->private_->seekable_stream_encoder);
642 }
643
644 FLAC_API unsigned FLAC__file_encoder_get_rice_parameter_search_dist(const FLAC__FileEncoder *encoder)
645 {
646         FLAC__ASSERT(0 != encoder);
647         FLAC__ASSERT(0 != encoder->private_);
648         return FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder);
649 }
650
651 FLAC_API FLAC__uint64 FLAC__file_encoder_get_total_samples_estimate(const FLAC__FileEncoder *encoder)
652 {
653         FLAC__ASSERT(0 != encoder);
654         FLAC__ASSERT(0 != encoder->private_);
655         return FLAC__seekable_stream_encoder_get_total_samples_estimate(encoder->private_->seekable_stream_encoder);
656 }
657
658 FLAC_API FLAC__bool FLAC__file_encoder_process(FLAC__FileEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
659 {
660         FLAC__ASSERT(0 != encoder);
661         FLAC__ASSERT(0 != encoder->private_);
662         if(!FLAC__seekable_stream_encoder_process(encoder->private_->seekable_stream_encoder, buffer, samples)) {
663                 encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
664                 return false;
665         }
666         else
667                 return true;
668 }
669
670 /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
671 FLAC_API FLAC__bool FLAC__file_encoder_process_interleaved(FLAC__FileEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
672 {
673         FLAC__ASSERT(0 != encoder);
674         FLAC__ASSERT(0 != encoder->private_);
675         if(!FLAC__seekable_stream_encoder_process_interleaved(encoder->private_->seekable_stream_encoder, buffer, samples)) {
676                 encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
677                 return false;
678         }
679         else
680                 return true;
681 }
682
683
684 /***********************************************************************
685  *
686  * Private class methods
687  *
688  ***********************************************************************/
689
690 void set_defaults_(FLAC__FileEncoder *encoder)
691 {
692         FLAC__ASSERT(0 != encoder);
693         FLAC__ASSERT(0 != encoder->private_);
694
695         encoder->private_->progress_callback = 0;
696         encoder->private_->client_data = 0;
697         encoder->private_->total_frames_estimate = 0;
698         encoder->private_->filename = 0;
699 }
700
701 FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
702 {
703         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
704
705         (void)encoder;
706
707         FLAC__ASSERT(0 != file_encoder);
708
709         if(fseek(file_encoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
710                 return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR;
711         else
712                 return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK;
713 }
714
715 FLAC__SeekableStreamEncoderTellStatus tell_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
716 {
717         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
718         long offset;
719
720         (void)encoder;
721
722         FLAC__ASSERT(0 != file_encoder);
723
724         offset = ftell(file_encoder->private_->file);
725
726         if(offset < 0) {
727                 return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_ERROR;
728         }
729         else {
730                 *absolute_byte_offset = (FLAC__uint64)offset;
731                 return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK;
732         }
733 }
734
735 #ifdef FLAC__VALGRIND_TESTING
736 static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
737 {
738         size_t ret = fwrite(ptr, size, nmemb, stream);
739         if(!ferror(stream))
740                 fflush(stream);
741         return ret;
742 }
743 #else
744 #define local__fwrite fwrite
745 #endif
746
747 FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
748 {
749         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
750
751         (void)encoder, (void)samples, (void)current_frame;
752
753         FLAC__ASSERT(0 != file_encoder);
754
755         if(local__fwrite(buffer, sizeof(FLAC__byte), bytes, file_encoder->private_->file) == bytes) {
756                 file_encoder->private_->bytes_written += bytes;
757                 file_encoder->private_->samples_written += samples;
758                 if(0 != file_encoder->private_->progress_callback && samples > 0)
759                         file_encoder->private_->progress_callback(file_encoder, file_encoder->private_->bytes_written, file_encoder->private_->samples_written, current_frame+1, file_encoder->private_->total_frames_estimate, file_encoder->private_->client_data);
760                 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
761         }
762         else
763                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
764 }