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