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