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