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