c1741cd96ba7704fc8665ac7000a0bc348bb0416
[flac.git] / src / libFLAC / file_encoder.c
1 /* libFLAC - Free Lossless Audio Codec library
2  * Copyright (C) 2002  Josh Coalson
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA  02111-1307, USA.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h> /* for malloc() */
22 #include <string.h> /* for memcpy() */
23 #include "FLAC/assert.h"
24 #include "protected/file_encoder.h"
25 #include "protected/seekable_stream_encoder.h"
26
27 /***********************************************************************
28  *
29  * Private class method prototypes
30  *
31  ***********************************************************************/
32
33 /* unpublished debug routines */
34 extern FLAC__bool FLAC__seekable_stream_encoder_disable_constant_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
35 extern FLAC__bool FLAC__seekable_stream_encoder_disable_fixed_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
36 extern FLAC__bool FLAC__seekable_stream_encoder_disable_verbatim_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
37
38 static void set_defaults_(FLAC__FileEncoder *encoder);
39 static FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data);
40 static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
41
42 /***********************************************************************
43  *
44  * Private class data
45  *
46  ***********************************************************************/
47
48 typedef struct FLAC__FileEncoderPrivate {
49         FLAC__FileEncoderProgressCallback progress_callback;
50         void *client_data;
51         char *filename;
52         FLAC__uint64 bytes_written;
53         FLAC__uint64 samples_written;
54         unsigned total_frames_estimate;
55         FLAC__SeekableStreamEncoder *seekable_stream_encoder;
56         FILE *file;
57 } FLAC__FileEncoderPrivate;
58
59 /***********************************************************************
60  *
61  * Public static class data
62  *
63  ***********************************************************************/
64
65 FLAC_API const char * const FLAC__FileEncoderStateString[] = {
66         "FLAC__FILE_ENCODER_OK",
67         "FLAC__FILE_ENCODER_NO_FILENAME",
68         "FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR",
69         "FLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING",
70         "FLAC__FILE_ENCODER_ERROR_OPENING_FILE",
71         "FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR",
72         "FLAC__FILE_ENCODER_ALREADY_INITIALIZED",
73         "FLAC__FILE_ENCODER_UNINITIALIZED"
74 };
75
76
77 /***********************************************************************
78  *
79  * Class constructor/destructor
80  *
81  ***********************************************************************/
82
83 FLAC_API FLAC__FileEncoder *FLAC__file_encoder_new()
84 {
85         FLAC__FileEncoder *encoder;
86
87         FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
88
89         encoder = (FLAC__FileEncoder*)malloc(sizeof(FLAC__FileEncoder));
90         if(encoder == 0) {
91                 return 0;
92         }
93         memset(encoder, 0, sizeof(FLAC__FileEncoder));
94
95         encoder->protected_ = (FLAC__FileEncoderProtected*)malloc(sizeof(FLAC__FileEncoderProtected));
96         if(encoder->protected_ == 0) {
97                 free(encoder);
98                 return 0;
99         }
100         memset(encoder->protected_, 0, sizeof(FLAC__FileEncoderProtected));
101
102         encoder->private_ = (FLAC__FileEncoderPrivate*)malloc(sizeof(FLAC__FileEncoderPrivate));
103         if(encoder->private_ == 0) {
104                 free(encoder->protected_);
105                 free(encoder);
106                 return 0;
107         }
108         memset(encoder->private_, 0, sizeof(FLAC__FileEncoderPrivate));
109
110         encoder->private_->seekable_stream_encoder = FLAC__seekable_stream_encoder_new();
111         if(0 == encoder->private_->seekable_stream_encoder) {
112                 free(encoder->private_);
113                 free(encoder->protected_);
114                 free(encoder);
115                 return 0;
116         }
117
118         encoder->private_->file = 0;
119
120         set_defaults_(encoder);
121
122         encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED;
123
124         return encoder;
125 }
126
127 FLAC_API void FLAC__file_encoder_delete(FLAC__FileEncoder *encoder)
128 {
129         FLAC__ASSERT(0 != encoder);
130         FLAC__ASSERT(0 != encoder->protected_);
131         FLAC__ASSERT(0 != encoder->private_);
132         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
133
134         (void)FLAC__file_encoder_finish(encoder);
135
136         FLAC__seekable_stream_encoder_delete(encoder->private_->seekable_stream_encoder);
137
138         free(encoder->private_);
139         free(encoder->protected_);
140         free(encoder);
141 }
142
143 /***********************************************************************
144  *
145  * Public class methods
146  *
147  ***********************************************************************/
148
149 FLAC_API FLAC__FileEncoderState FLAC__file_encoder_init(FLAC__FileEncoder *encoder)
150 {
151         FLAC__ASSERT(0 != encoder);
152
153         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
154                 return encoder->protected_->state = FLAC__FILE_ENCODER_ALREADY_INITIALIZED;
155
156         if(0 == encoder->private_->filename)
157                 return encoder->protected_->state = FLAC__FILE_ENCODER_NO_FILENAME;
158
159         encoder->private_->file = fopen(encoder->private_->filename, "w+b");
160
161         if(encoder->private_->file == 0)
162                 return encoder->protected_->state = FLAC__FILE_ENCODER_ERROR_OPENING_FILE;
163
164         encoder->private_->bytes_written = 0;
165         encoder->private_->samples_written = 0;
166
167         FLAC__seekable_stream_encoder_set_seek_callback(encoder->private_->seekable_stream_encoder, seek_callback_);
168         FLAC__seekable_stream_encoder_set_write_callback(encoder->private_->seekable_stream_encoder, write_callback_);
169         FLAC__seekable_stream_encoder_set_client_data(encoder->private_->seekable_stream_encoder, encoder);
170
171         if(FLAC__seekable_stream_encoder_init(encoder->private_->seekable_stream_encoder) != FLAC__SEEKABLE_STREAM_ENCODER_OK)
172                 return encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
173
174         {
175                 unsigned blocksize = FLAC__file_encoder_get_blocksize(encoder);
176
177                 FLAC__ASSERT(blocksize != 0);
178                 encoder->private_->total_frames_estimate = (unsigned)((FLAC__file_encoder_get_total_samples_estimate(encoder) + blocksize - 1) / blocksize);
179         }
180
181         return encoder->protected_->state = FLAC__FILE_ENCODER_OK;
182 }
183
184 FLAC_API void FLAC__file_encoder_finish(FLAC__FileEncoder *encoder)
185 {
186         FLAC__ASSERT(0 != encoder);
187
188         if(encoder->protected_->state == FLAC__FILE_ENCODER_UNINITIALIZED)
189                 return;
190
191         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
192
193         /* FLAC__seekable_stream_encoder_finish() might write data so we must close the file after it. */
194
195         FLAC__seekable_stream_encoder_finish(encoder->private_->seekable_stream_encoder);
196
197         if(0 != encoder->private_->file) {
198                 fclose(encoder->private_->file);
199                 encoder->private_->file = 0;
200         }
201
202         if(0 != encoder->private_->filename) {
203                 free(encoder->private_->filename);
204                 encoder->private_->filename = 0;
205         }
206
207         set_defaults_(encoder);
208
209         encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED;
210 }
211
212 FLAC_API FLAC__bool FLAC__file_encoder_set_verify(FLAC__FileEncoder *encoder, FLAC__bool value)
213 {
214         FLAC__ASSERT(0 != encoder);
215         FLAC__ASSERT(0 != encoder->private_);
216         FLAC__ASSERT(0 != encoder->protected_);
217         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
218         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
219                 return false;
220         return FLAC__seekable_stream_encoder_set_verify(encoder->private_->seekable_stream_encoder, value);
221 }
222
223 FLAC_API FLAC__bool FLAC__file_encoder_set_streamable_subset(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_streamable_subset(encoder->private_->seekable_stream_encoder, value);
232 }
233
234 FLAC_API FLAC__bool FLAC__file_encoder_set_do_mid_side_stereo(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_do_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
243 }
244
245 FLAC_API FLAC__bool FLAC__file_encoder_set_loose_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_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
254 }
255
256 FLAC_API FLAC__bool FLAC__file_encoder_set_channels(FLAC__FileEncoder *encoder, unsigned 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_channels(encoder->private_->seekable_stream_encoder, value);
265 }
266
267 FLAC_API FLAC__bool FLAC__file_encoder_set_bits_per_sample(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_bits_per_sample(encoder->private_->seekable_stream_encoder, value);
276 }
277
278 FLAC_API FLAC__bool FLAC__file_encoder_set_sample_rate(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_sample_rate(encoder->private_->seekable_stream_encoder, value);
287 }
288
289 FLAC_API FLAC__bool FLAC__file_encoder_set_blocksize(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_blocksize(encoder->private_->seekable_stream_encoder, value);
298 }
299
300 FLAC_API FLAC__bool FLAC__file_encoder_set_max_lpc_order(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_max_lpc_order(encoder->private_->seekable_stream_encoder, value);
309 }
310
311 FLAC_API FLAC__bool FLAC__file_encoder_set_qlp_coeff_precision(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_qlp_coeff_precision(encoder->private_->seekable_stream_encoder, value);
320 }
321
322 FLAC_API FLAC__bool FLAC__file_encoder_set_do_qlp_coeff_prec_search(FLAC__FileEncoder *encoder, FLAC__bool 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_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder, value);
331 }
332
333 FLAC_API FLAC__bool FLAC__file_encoder_set_do_escape_coding(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_escape_coding(encoder->private_->seekable_stream_encoder, value);
342 }
343
344 FLAC_API FLAC__bool FLAC__file_encoder_set_do_exhaustive_model_search(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_exhaustive_model_search(encoder->private_->seekable_stream_encoder, value);
353 }
354
355 FLAC_API FLAC__bool FLAC__file_encoder_set_min_residual_partition_order(FLAC__FileEncoder *encoder, unsigned 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_min_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
364 }
365
366 FLAC_API FLAC__bool FLAC__file_encoder_set_max_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_max_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
375 }
376
377 FLAC_API FLAC__bool FLAC__file_encoder_set_rice_parameter_search_dist(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_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder, value);
386 }
387
388 FLAC_API FLAC__bool FLAC__file_encoder_set_total_samples_estimate(FLAC__FileEncoder *encoder, FLAC__uint64 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_total_samples_estimate(encoder->private_->seekable_stream_encoder, value);
397 }
398
399 FLAC_API FLAC__bool FLAC__file_encoder_set_metadata(FLAC__FileEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
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_metadata(encoder->private_->seekable_stream_encoder, metadata, num_blocks);
408 }
409
410 FLAC_API FLAC__bool FLAC__file_encoder_set_filename(FLAC__FileEncoder *encoder, const char *value)
411 {
412         FLAC__ASSERT(0 != encoder);
413         FLAC__ASSERT(0 != encoder->private_);
414         FLAC__ASSERT(0 != encoder->protected_);
415         FLAC__ASSERT(0 != value);
416         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
417                 return false;
418         if(0 != encoder->private_->filename) {
419                 free(encoder->private_->filename);
420                 encoder->private_->filename = 0;
421         }
422         if(0 == (encoder->private_->filename = (char*)malloc(strlen(value)+1))) {
423                 encoder->protected_->state = FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR;
424                 return false;
425         }
426         strcpy(encoder->private_->filename, value);
427         return true;
428 }
429
430 FLAC_API FLAC__bool FLAC__file_encoder_set_progress_callback(FLAC__FileEncoder *encoder, FLAC__FileEncoderProgressCallback value)
431 {
432         FLAC__ASSERT(0 != encoder);
433         FLAC__ASSERT(0 != encoder->private_);
434         FLAC__ASSERT(0 != encoder->protected_);
435         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
436                 return false;
437         encoder->private_->progress_callback = value;
438         return true;
439 }
440
441 FLAC_API FLAC__bool FLAC__file_encoder_set_client_data(FLAC__FileEncoder *encoder, void *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_->client_data = value;
449         return true;
450 }
451
452 /*
453  * These three functions are not static, but not publically exposed in
454  * include/FLAC/ either.  They are used by the test suite.
455  */
456 FLAC_API FLAC__bool FLAC__file_encoder_disable_constant_subframes(FLAC__FileEncoder *encoder, FLAC__bool value)
457 {
458         FLAC__ASSERT(0 != encoder);
459         FLAC__ASSERT(0 != encoder->private_);
460         FLAC__ASSERT(0 != encoder->protected_);
461         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
462                 return false;
463         return FLAC__seekable_stream_encoder_disable_constant_subframes(encoder->private_->seekable_stream_encoder, value);
464 }
465
466 FLAC_API FLAC__bool FLAC__file_encoder_disable_fixed_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_fixed_subframes(encoder->private_->seekable_stream_encoder, value);
474 }
475
476 FLAC_API FLAC__bool FLAC__file_encoder_disable_verbatim_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_verbatim_subframes(encoder->private_->seekable_stream_encoder, value);
484 }
485
486 FLAC_API FLAC__FileEncoderState FLAC__file_encoder_get_state(const FLAC__FileEncoder *encoder)
487 {
488         FLAC__ASSERT(0 != encoder);
489         FLAC__ASSERT(0 != encoder->protected_);
490         return encoder->protected_->state;
491 }
492
493 FLAC_API FLAC__SeekableStreamEncoderState FLAC__file_encoder_get_seekable_stream_encoder_state(const FLAC__FileEncoder *encoder)
494 {
495         FLAC__ASSERT(0 != encoder);
496         FLAC__ASSERT(0 != encoder->private_);
497         return FLAC__seekable_stream_encoder_get_state(encoder->private_->seekable_stream_encoder);
498 }
499
500 FLAC_API FLAC__StreamEncoderState FLAC__file_encoder_get_stream_encoder_state(const FLAC__FileEncoder *encoder)
501 {
502         FLAC__ASSERT(0 != encoder);
503         FLAC__ASSERT(0 != encoder->private_);
504         return FLAC__seekable_stream_encoder_get_stream_encoder_state(encoder->private_->seekable_stream_encoder);
505 }
506
507 FLAC_API FLAC__StreamDecoderState FLAC__file_encoder_get_verify_decoder_state(const FLAC__FileEncoder *encoder)
508 {
509         FLAC__ASSERT(0 != encoder);
510         FLAC__ASSERT(0 != encoder->private_);
511         return FLAC__seekable_stream_encoder_get_verify_decoder_state(encoder->private_->seekable_stream_encoder);
512 }
513
514 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)
515 {
516         FLAC__ASSERT(0 != encoder);
517         FLAC__ASSERT(0 != encoder->private_);
518         FLAC__seekable_stream_encoder_get_verify_decoder_error_stats(encoder->private_->seekable_stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
519 }
520
521 FLAC_API FLAC__bool FLAC__file_encoder_get_verify(const FLAC__FileEncoder *encoder)
522 {
523         FLAC__ASSERT(0 != encoder);
524         FLAC__ASSERT(0 != encoder->private_);
525         return FLAC__seekable_stream_encoder_get_verify(encoder->private_->seekable_stream_encoder);
526 }
527
528 FLAC_API FLAC__bool FLAC__file_encoder_get_streamable_subset(const FLAC__FileEncoder *encoder)
529 {
530         FLAC__ASSERT(0 != encoder);
531         FLAC__ASSERT(0 != encoder->private_);
532         return FLAC__seekable_stream_encoder_get_streamable_subset(encoder->private_->seekable_stream_encoder);
533 }
534
535 FLAC_API FLAC__bool FLAC__file_encoder_get_do_mid_side_stereo(const FLAC__FileEncoder *encoder)
536 {
537         FLAC__ASSERT(0 != encoder);
538         FLAC__ASSERT(0 != encoder->private_);
539         return FLAC__seekable_stream_encoder_get_do_mid_side_stereo(encoder->private_->seekable_stream_encoder);
540 }
541
542 FLAC_API FLAC__bool FLAC__file_encoder_get_loose_mid_side_stereo(const FLAC__FileEncoder *encoder)
543 {
544         FLAC__ASSERT(0 != encoder);
545         FLAC__ASSERT(0 != encoder->private_);
546         return FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder);
547 }
548
549 FLAC_API unsigned FLAC__file_encoder_get_channels(const FLAC__FileEncoder *encoder)
550 {
551         FLAC__ASSERT(0 != encoder);
552         FLAC__ASSERT(0 != encoder->private_);
553         return FLAC__seekable_stream_encoder_get_channels(encoder->private_->seekable_stream_encoder);
554 }
555
556 FLAC_API unsigned FLAC__file_encoder_get_bits_per_sample(const FLAC__FileEncoder *encoder)
557 {
558         FLAC__ASSERT(0 != encoder);
559         FLAC__ASSERT(0 != encoder->private_);
560         return FLAC__seekable_stream_encoder_get_bits_per_sample(encoder->private_->seekable_stream_encoder);
561 }
562
563 FLAC_API unsigned FLAC__file_encoder_get_sample_rate(const FLAC__FileEncoder *encoder)
564 {
565         FLAC__ASSERT(0 != encoder);
566         FLAC__ASSERT(0 != encoder->private_);
567         return FLAC__seekable_stream_encoder_get_sample_rate(encoder->private_->seekable_stream_encoder);
568 }
569
570 FLAC_API unsigned FLAC__file_encoder_get_blocksize(const FLAC__FileEncoder *encoder)
571 {
572         FLAC__ASSERT(0 != encoder);
573         FLAC__ASSERT(0 != encoder->private_);
574         return FLAC__seekable_stream_encoder_get_blocksize(encoder->private_->seekable_stream_encoder);
575 }
576
577 FLAC_API unsigned FLAC__file_encoder_get_max_lpc_order(const FLAC__FileEncoder *encoder)
578 {
579         FLAC__ASSERT(0 != encoder);
580         FLAC__ASSERT(0 != encoder->private_);
581         return FLAC__seekable_stream_encoder_get_max_lpc_order(encoder->private_->seekable_stream_encoder);
582 }
583
584 FLAC_API unsigned FLAC__file_encoder_get_qlp_coeff_precision(const FLAC__FileEncoder *encoder)
585 {
586         FLAC__ASSERT(0 != encoder);
587         FLAC__ASSERT(0 != encoder->private_);
588         return FLAC__seekable_stream_encoder_get_qlp_coeff_precision(encoder->private_->seekable_stream_encoder);
589 }
590
591 FLAC_API FLAC__bool FLAC__file_encoder_get_do_qlp_coeff_prec_search(const FLAC__FileEncoder *encoder)
592 {
593         FLAC__ASSERT(0 != encoder);
594         FLAC__ASSERT(0 != encoder->private_);
595         return FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder);
596 }
597
598 FLAC_API FLAC__bool FLAC__file_encoder_get_do_escape_coding(const FLAC__FileEncoder *encoder)
599 {
600         FLAC__ASSERT(0 != encoder);
601         FLAC__ASSERT(0 != encoder->private_);
602         return FLAC__seekable_stream_encoder_get_do_escape_coding(encoder->private_->seekable_stream_encoder);
603 }
604
605 FLAC_API FLAC__bool FLAC__file_encoder_get_do_exhaustive_model_search(const FLAC__FileEncoder *encoder)
606 {
607         FLAC__ASSERT(0 != encoder);
608         FLAC__ASSERT(0 != encoder->private_);
609         return FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder);
610 }
611
612 FLAC_API unsigned FLAC__file_encoder_get_min_residual_partition_order(const FLAC__FileEncoder *encoder)
613 {
614         FLAC__ASSERT(0 != encoder);
615         FLAC__ASSERT(0 != encoder->private_);
616         return FLAC__seekable_stream_encoder_get_min_residual_partition_order(encoder->private_->seekable_stream_encoder);
617 }
618
619 FLAC_API unsigned FLAC__file_encoder_get_max_residual_partition_order(const FLAC__FileEncoder *encoder)
620 {
621         FLAC__ASSERT(0 != encoder);
622         FLAC__ASSERT(0 != encoder->private_);
623         return FLAC__seekable_stream_encoder_get_max_residual_partition_order(encoder->private_->seekable_stream_encoder);
624 }
625
626 FLAC_API unsigned FLAC__file_encoder_get_rice_parameter_search_dist(const FLAC__FileEncoder *encoder)
627 {
628         FLAC__ASSERT(0 != encoder);
629         FLAC__ASSERT(0 != encoder->private_);
630         return FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder);
631 }
632
633 FLAC_API FLAC__uint64 FLAC__file_encoder_get_total_samples_estimate(const FLAC__FileEncoder *encoder)
634 {
635         FLAC__ASSERT(0 != encoder);
636         FLAC__ASSERT(0 != encoder->private_);
637         return FLAC__seekable_stream_encoder_get_total_samples_estimate(encoder->private_->seekable_stream_encoder);
638 }
639
640 FLAC_API FLAC__bool FLAC__file_encoder_process(FLAC__FileEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
641 {
642         FLAC__ASSERT(0 != encoder);
643         FLAC__ASSERT(0 != encoder->private_);
644         if(!FLAC__seekable_stream_encoder_process(encoder->private_->seekable_stream_encoder, buffer, samples)) {
645                 encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
646                 return false;
647         }
648         else
649                 return true;
650 }
651
652 /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
653 FLAC_API FLAC__bool FLAC__file_encoder_process_interleaved(FLAC__FileEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
654 {
655         FLAC__ASSERT(0 != encoder);
656         FLAC__ASSERT(0 != encoder->private_);
657         if(!FLAC__seekable_stream_encoder_process_interleaved(encoder->private_->seekable_stream_encoder, buffer, samples)) {
658                 encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
659                 return false;
660         }
661         else
662                 return true;
663 }
664
665
666 /***********************************************************************
667  *
668  * Private class methods
669  *
670  ***********************************************************************/
671
672 void set_defaults_(FLAC__FileEncoder *encoder)
673 {
674         FLAC__ASSERT(0 != encoder);
675         FLAC__ASSERT(0 != encoder->private_);
676
677         encoder->private_->progress_callback = 0;
678         encoder->private_->client_data = 0;
679         encoder->private_->total_frames_estimate = 0;
680         encoder->private_->filename = 0;
681 }
682
683 FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
684 {
685         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
686
687         (void)encoder;
688
689         FLAC__ASSERT(0 != file_encoder);
690
691         if(fseek(file_encoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
692                 return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR;
693         else
694                 return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK;
695 }
696
697 FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
698 {
699         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
700
701         (void)encoder, (void)samples, (void)current_frame;
702
703         FLAC__ASSERT(0 != file_encoder);
704
705         if(fwrite(buffer, sizeof(FLAC__byte), bytes, file_encoder->private_->file) == bytes) {
706                 file_encoder->private_->bytes_written += bytes;
707                 file_encoder->private_->samples_written += samples;
708                 if(0 != file_encoder->private_->progress_callback && samples > 0)
709                         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);
710                 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
711         }
712         else
713                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
714 }