1 /* libFLAC - Free Lossless Audio Codec library
2 * Copyright (C) 2002,2003,2004,2005,2006 Josh Coalson
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
33 #include <stdlib.h> /* for malloc() */
34 #include <string.h> /* for strlen(), strcpy() */
35 #include "FLAC/assert.h"
36 #include "protected/file_encoder.h"
41 #define max(x,y) ((x)>(y)?(x):(y))
43 /***********************************************************************
45 * Private class method prototypes
47 ***********************************************************************/
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);
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);
59 /***********************************************************************
63 ***********************************************************************/
65 typedef struct FLAC__FileEncoderPrivate {
66 FLAC__FileEncoderProgressCallback progress_callback;
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;
75 } FLAC__FileEncoderPrivate;
77 /***********************************************************************
79 * Public static class data
81 ***********************************************************************/
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"
95 /***********************************************************************
97 * Class constructor/destructor
99 ***********************************************************************/
101 FLAC_API FLAC__FileEncoder *FLAC__file_encoder_new()
103 FLAC__FileEncoder *encoder;
105 FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
107 encoder = (FLAC__FileEncoder*)calloc(1, sizeof(FLAC__FileEncoder));
112 encoder->protected_ = (FLAC__FileEncoderProtected*)calloc(1, sizeof(FLAC__FileEncoderProtected));
113 if(encoder->protected_ == 0) {
118 encoder->private_ = (FLAC__FileEncoderPrivate*)calloc(1, sizeof(FLAC__FileEncoderPrivate));
119 if(encoder->private_ == 0) {
120 free(encoder->protected_);
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_);
133 encoder->private_->file = 0;
135 set_defaults_(encoder);
137 encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED;
142 FLAC_API void FLAC__file_encoder_delete(FLAC__FileEncoder *encoder)
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);
149 (void)FLAC__file_encoder_finish(encoder);
151 FLAC__seekable_stream_encoder_delete(encoder->private_->seekable_stream_encoder);
153 free(encoder->private_);
154 free(encoder->protected_);
158 /***********************************************************************
160 * Public class methods
162 ***********************************************************************/
164 FLAC_API FLAC__FileEncoderState FLAC__file_encoder_init(FLAC__FileEncoder *encoder)
166 FLAC__ASSERT(0 != encoder);
168 if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
169 return encoder->protected_->state = FLAC__FILE_ENCODER_ALREADY_INITIALIZED;
171 if(0 == encoder->private_->filename)
172 return encoder->protected_->state = FLAC__FILE_ENCODER_NO_FILENAME;
174 encoder->private_->file = fopen(encoder->private_->filename, "w+b");
176 if(encoder->private_->file == 0)
177 return encoder->protected_->state = FLAC__FILE_ENCODER_ERROR_OPENING_FILE;
179 encoder->private_->bytes_written = 0;
180 encoder->private_->samples_written = 0;
181 encoder->private_->frames_written = 0;
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);
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;
192 unsigned blocksize = FLAC__file_encoder_get_blocksize(encoder);
194 FLAC__ASSERT(blocksize != 0);
195 encoder->private_->total_frames_estimate = (unsigned)((FLAC__file_encoder_get_total_samples_estimate(encoder) + blocksize - 1) / blocksize);
198 return encoder->protected_->state = FLAC__FILE_ENCODER_OK;
201 FLAC_API void FLAC__file_encoder_finish(FLAC__FileEncoder *encoder)
203 FLAC__ASSERT(0 != encoder);
205 if(encoder->protected_->state == FLAC__FILE_ENCODER_UNINITIALIZED)
208 FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
210 /* FLAC__seekable_stream_encoder_finish() might write data so we must close the file after it. */
212 FLAC__seekable_stream_encoder_finish(encoder->private_->seekable_stream_encoder);
214 if(0 != encoder->private_->file) {
215 fclose(encoder->private_->file);
216 encoder->private_->file = 0;
219 if(0 != encoder->private_->filename) {
220 free(encoder->private_->filename);
221 encoder->private_->filename = 0;
224 set_defaults_(encoder);
226 encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED;
229 FLAC_API FLAC__bool FLAC__file_encoder_set_verify(FLAC__FileEncoder *encoder, FLAC__bool value)
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)
237 return FLAC__seekable_stream_encoder_set_verify(encoder->private_->seekable_stream_encoder, value);
240 FLAC_API FLAC__bool FLAC__file_encoder_set_streamable_subset(FLAC__FileEncoder *encoder, FLAC__bool value)
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)
248 return FLAC__seekable_stream_encoder_set_streamable_subset(encoder->private_->seekable_stream_encoder, value);
251 FLAC_API FLAC__bool FLAC__file_encoder_set_do_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value)
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)
259 return FLAC__seekable_stream_encoder_set_do_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
262 FLAC_API FLAC__bool FLAC__file_encoder_set_loose_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value)
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)
270 return FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
273 FLAC_API FLAC__bool FLAC__file_encoder_set_channels(FLAC__FileEncoder *encoder, unsigned value)
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)
281 return FLAC__seekable_stream_encoder_set_channels(encoder->private_->seekable_stream_encoder, value);
284 FLAC_API FLAC__bool FLAC__file_encoder_set_bits_per_sample(FLAC__FileEncoder *encoder, unsigned value)
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)
292 return FLAC__seekable_stream_encoder_set_bits_per_sample(encoder->private_->seekable_stream_encoder, value);
295 FLAC_API FLAC__bool FLAC__file_encoder_set_sample_rate(FLAC__FileEncoder *encoder, unsigned value)
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)
303 return FLAC__seekable_stream_encoder_set_sample_rate(encoder->private_->seekable_stream_encoder, value);
306 FLAC_API FLAC__bool FLAC__file_encoder_set_blocksize(FLAC__FileEncoder *encoder, unsigned value)
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)
314 return FLAC__seekable_stream_encoder_set_blocksize(encoder->private_->seekable_stream_encoder, value);
317 FLAC_API FLAC__bool FLAC__file_encoder_set_apodization(FLAC__FileEncoder *encoder, const char *specification)
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)
325 return FLAC__seekable_stream_encoder_set_apodization(encoder->private_->seekable_stream_encoder, specification);
328 FLAC_API FLAC__bool FLAC__file_encoder_set_max_lpc_order(FLAC__FileEncoder *encoder, unsigned value)
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)
336 return FLAC__seekable_stream_encoder_set_max_lpc_order(encoder->private_->seekable_stream_encoder, value);
339 FLAC_API FLAC__bool FLAC__file_encoder_set_qlp_coeff_precision(FLAC__FileEncoder *encoder, unsigned value)
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)
347 return FLAC__seekable_stream_encoder_set_qlp_coeff_precision(encoder->private_->seekable_stream_encoder, value);
350 FLAC_API FLAC__bool FLAC__file_encoder_set_do_qlp_coeff_prec_search(FLAC__FileEncoder *encoder, FLAC__bool value)
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)
358 return FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder, value);
361 FLAC_API FLAC__bool FLAC__file_encoder_set_do_escape_coding(FLAC__FileEncoder *encoder, FLAC__bool value)
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)
369 return FLAC__seekable_stream_encoder_set_do_escape_coding(encoder->private_->seekable_stream_encoder, value);
372 FLAC_API FLAC__bool FLAC__file_encoder_set_do_exhaustive_model_search(FLAC__FileEncoder *encoder, FLAC__bool value)
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)
380 return FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder, value);
383 FLAC_API FLAC__bool FLAC__file_encoder_set_min_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value)
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)
391 return FLAC__seekable_stream_encoder_set_min_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
394 FLAC_API FLAC__bool FLAC__file_encoder_set_max_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value)
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)
402 return FLAC__seekable_stream_encoder_set_max_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
405 FLAC_API FLAC__bool FLAC__file_encoder_set_rice_parameter_search_dist(FLAC__FileEncoder *encoder, unsigned value)
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)
413 return FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder, value);
416 FLAC_API FLAC__bool FLAC__file_encoder_set_total_samples_estimate(FLAC__FileEncoder *encoder, FLAC__uint64 value)
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)
424 return FLAC__seekable_stream_encoder_set_total_samples_estimate(encoder->private_->seekable_stream_encoder, value);
427 FLAC_API FLAC__bool FLAC__file_encoder_set_metadata(FLAC__FileEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
429 FLAC__ASSERT(0 != encoder);
430 FLAC__ASSERT(0 != encoder->private_);
431 FLAC__ASSERT(0 != encoder->protected_);
432 FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
433 if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
435 return FLAC__seekable_stream_encoder_set_metadata(encoder->private_->seekable_stream_encoder, metadata, num_blocks);
438 FLAC_API FLAC__bool FLAC__file_encoder_set_filename(FLAC__FileEncoder *encoder, const char *value)
440 FLAC__ASSERT(0 != encoder);
441 FLAC__ASSERT(0 != encoder->private_);
442 FLAC__ASSERT(0 != encoder->protected_);
443 FLAC__ASSERT(0 != value);
444 if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
446 if(0 != encoder->private_->filename) {
447 free(encoder->private_->filename);
448 encoder->private_->filename = 0;
450 if(0 == (encoder->private_->filename = (char*)malloc(strlen(value)+1))) {
451 encoder->protected_->state = FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR;
454 strcpy(encoder->private_->filename, value);
458 FLAC_API FLAC__bool FLAC__file_encoder_set_progress_callback(FLAC__FileEncoder *encoder, FLAC__FileEncoderProgressCallback value)
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)
465 encoder->private_->progress_callback = value;
469 FLAC_API FLAC__bool FLAC__file_encoder_set_client_data(FLAC__FileEncoder *encoder, void *value)
471 FLAC__ASSERT(0 != encoder);
472 FLAC__ASSERT(0 != encoder->private_);
473 FLAC__ASSERT(0 != encoder->protected_);
474 if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
476 encoder->private_->client_data = value;
481 * These three functions are not static, but not publically exposed in
482 * include/FLAC/ either. They are used by the test suite.
484 FLAC_API FLAC__bool FLAC__file_encoder_disable_constant_subframes(FLAC__FileEncoder *encoder, FLAC__bool value)
486 FLAC__ASSERT(0 != encoder);
487 FLAC__ASSERT(0 != encoder->private_);
488 FLAC__ASSERT(0 != encoder->protected_);
489 if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
491 return FLAC__seekable_stream_encoder_disable_constant_subframes(encoder->private_->seekable_stream_encoder, value);
494 FLAC_API FLAC__bool FLAC__file_encoder_disable_fixed_subframes(FLAC__FileEncoder *encoder, FLAC__bool value)
496 FLAC__ASSERT(0 != encoder);
497 FLAC__ASSERT(0 != encoder->private_);
498 FLAC__ASSERT(0 != encoder->protected_);
499 if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
501 return FLAC__seekable_stream_encoder_disable_fixed_subframes(encoder->private_->seekable_stream_encoder, value);
504 FLAC_API FLAC__bool FLAC__file_encoder_disable_verbatim_subframes(FLAC__FileEncoder *encoder, FLAC__bool value)
506 FLAC__ASSERT(0 != encoder);
507 FLAC__ASSERT(0 != encoder->private_);
508 FLAC__ASSERT(0 != encoder->protected_);
509 if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
511 return FLAC__seekable_stream_encoder_disable_verbatim_subframes(encoder->private_->seekable_stream_encoder, value);
514 FLAC_API FLAC__FileEncoderState FLAC__file_encoder_get_state(const FLAC__FileEncoder *encoder)
516 FLAC__ASSERT(0 != encoder);
517 FLAC__ASSERT(0 != encoder->protected_);
518 return encoder->protected_->state;
521 FLAC_API FLAC__SeekableStreamEncoderState FLAC__file_encoder_get_seekable_stream_encoder_state(const FLAC__FileEncoder *encoder)
523 FLAC__ASSERT(0 != encoder);
524 FLAC__ASSERT(0 != encoder->private_);
525 return FLAC__seekable_stream_encoder_get_state(encoder->private_->seekable_stream_encoder);
528 FLAC_API FLAC__StreamEncoderState FLAC__file_encoder_get_stream_encoder_state(const FLAC__FileEncoder *encoder)
530 FLAC__ASSERT(0 != encoder);
531 FLAC__ASSERT(0 != encoder->private_);
532 return FLAC__seekable_stream_encoder_get_stream_encoder_state(encoder->private_->seekable_stream_encoder);
535 FLAC_API FLAC__StreamDecoderState FLAC__file_encoder_get_verify_decoder_state(const FLAC__FileEncoder *encoder)
537 FLAC__ASSERT(0 != encoder);
538 FLAC__ASSERT(0 != encoder->private_);
539 return FLAC__seekable_stream_encoder_get_verify_decoder_state(encoder->private_->seekable_stream_encoder);
542 FLAC_API const char *FLAC__file_encoder_get_resolved_state_string(const FLAC__FileEncoder *encoder)
544 if(encoder->protected_->state != FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR)
545 return FLAC__FileEncoderStateString[encoder->protected_->state];
547 return FLAC__seekable_stream_encoder_get_resolved_state_string(encoder->private_->seekable_stream_encoder);
550 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)
552 FLAC__ASSERT(0 != encoder);
553 FLAC__ASSERT(0 != encoder->private_);
554 FLAC__seekable_stream_encoder_get_verify_decoder_error_stats(encoder->private_->seekable_stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
557 FLAC_API FLAC__bool FLAC__file_encoder_get_verify(const FLAC__FileEncoder *encoder)
559 FLAC__ASSERT(0 != encoder);
560 FLAC__ASSERT(0 != encoder->private_);
561 return FLAC__seekable_stream_encoder_get_verify(encoder->private_->seekable_stream_encoder);
564 FLAC_API FLAC__bool FLAC__file_encoder_get_streamable_subset(const FLAC__FileEncoder *encoder)
566 FLAC__ASSERT(0 != encoder);
567 FLAC__ASSERT(0 != encoder->private_);
568 return FLAC__seekable_stream_encoder_get_streamable_subset(encoder->private_->seekable_stream_encoder);
571 FLAC_API FLAC__bool FLAC__file_encoder_get_do_mid_side_stereo(const FLAC__FileEncoder *encoder)
573 FLAC__ASSERT(0 != encoder);
574 FLAC__ASSERT(0 != encoder->private_);
575 return FLAC__seekable_stream_encoder_get_do_mid_side_stereo(encoder->private_->seekable_stream_encoder);
578 FLAC_API FLAC__bool FLAC__file_encoder_get_loose_mid_side_stereo(const FLAC__FileEncoder *encoder)
580 FLAC__ASSERT(0 != encoder);
581 FLAC__ASSERT(0 != encoder->private_);
582 return FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder);
585 FLAC_API unsigned FLAC__file_encoder_get_channels(const FLAC__FileEncoder *encoder)
587 FLAC__ASSERT(0 != encoder);
588 FLAC__ASSERT(0 != encoder->private_);
589 return FLAC__seekable_stream_encoder_get_channels(encoder->private_->seekable_stream_encoder);
592 FLAC_API unsigned FLAC__file_encoder_get_bits_per_sample(const FLAC__FileEncoder *encoder)
594 FLAC__ASSERT(0 != encoder);
595 FLAC__ASSERT(0 != encoder->private_);
596 return FLAC__seekable_stream_encoder_get_bits_per_sample(encoder->private_->seekable_stream_encoder);
599 FLAC_API unsigned FLAC__file_encoder_get_sample_rate(const FLAC__FileEncoder *encoder)
601 FLAC__ASSERT(0 != encoder);
602 FLAC__ASSERT(0 != encoder->private_);
603 return FLAC__seekable_stream_encoder_get_sample_rate(encoder->private_->seekable_stream_encoder);
606 FLAC_API unsigned FLAC__file_encoder_get_blocksize(const FLAC__FileEncoder *encoder)
608 FLAC__ASSERT(0 != encoder);
609 FLAC__ASSERT(0 != encoder->private_);
610 return FLAC__seekable_stream_encoder_get_blocksize(encoder->private_->seekable_stream_encoder);
613 FLAC_API unsigned FLAC__file_encoder_get_max_lpc_order(const FLAC__FileEncoder *encoder)
615 FLAC__ASSERT(0 != encoder);
616 FLAC__ASSERT(0 != encoder->private_);
617 return FLAC__seekable_stream_encoder_get_max_lpc_order(encoder->private_->seekable_stream_encoder);
620 FLAC_API unsigned FLAC__file_encoder_get_qlp_coeff_precision(const FLAC__FileEncoder *encoder)
622 FLAC__ASSERT(0 != encoder);
623 FLAC__ASSERT(0 != encoder->private_);
624 return FLAC__seekable_stream_encoder_get_qlp_coeff_precision(encoder->private_->seekable_stream_encoder);
627 FLAC_API FLAC__bool FLAC__file_encoder_get_do_qlp_coeff_prec_search(const FLAC__FileEncoder *encoder)
629 FLAC__ASSERT(0 != encoder);
630 FLAC__ASSERT(0 != encoder->private_);
631 return FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder);
634 FLAC_API FLAC__bool FLAC__file_encoder_get_do_escape_coding(const FLAC__FileEncoder *encoder)
636 FLAC__ASSERT(0 != encoder);
637 FLAC__ASSERT(0 != encoder->private_);
638 return FLAC__seekable_stream_encoder_get_do_escape_coding(encoder->private_->seekable_stream_encoder);
641 FLAC_API FLAC__bool FLAC__file_encoder_get_do_exhaustive_model_search(const FLAC__FileEncoder *encoder)
643 FLAC__ASSERT(0 != encoder);
644 FLAC__ASSERT(0 != encoder->private_);
645 return FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder);
648 FLAC_API unsigned FLAC__file_encoder_get_min_residual_partition_order(const FLAC__FileEncoder *encoder)
650 FLAC__ASSERT(0 != encoder);
651 FLAC__ASSERT(0 != encoder->private_);
652 return FLAC__seekable_stream_encoder_get_min_residual_partition_order(encoder->private_->seekable_stream_encoder);
655 FLAC_API unsigned FLAC__file_encoder_get_max_residual_partition_order(const FLAC__FileEncoder *encoder)
657 FLAC__ASSERT(0 != encoder);
658 FLAC__ASSERT(0 != encoder->private_);
659 return FLAC__seekable_stream_encoder_get_max_residual_partition_order(encoder->private_->seekable_stream_encoder);
662 FLAC_API unsigned FLAC__file_encoder_get_rice_parameter_search_dist(const FLAC__FileEncoder *encoder)
664 FLAC__ASSERT(0 != encoder);
665 FLAC__ASSERT(0 != encoder->private_);
666 return FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder);
669 FLAC_API FLAC__uint64 FLAC__file_encoder_get_total_samples_estimate(const FLAC__FileEncoder *encoder)
671 FLAC__ASSERT(0 != encoder);
672 FLAC__ASSERT(0 != encoder->private_);
673 return FLAC__seekable_stream_encoder_get_total_samples_estimate(encoder->private_->seekable_stream_encoder);
676 FLAC_API FLAC__bool FLAC__file_encoder_process(FLAC__FileEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
678 FLAC__ASSERT(0 != encoder);
679 FLAC__ASSERT(0 != encoder->private_);
680 if(!FLAC__seekable_stream_encoder_process(encoder->private_->seekable_stream_encoder, buffer, samples)) {
681 encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
688 /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
689 FLAC_API FLAC__bool FLAC__file_encoder_process_interleaved(FLAC__FileEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
691 FLAC__ASSERT(0 != encoder);
692 FLAC__ASSERT(0 != encoder->private_);
693 if(!FLAC__seekable_stream_encoder_process_interleaved(encoder->private_->seekable_stream_encoder, buffer, samples)) {
694 encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
702 /***********************************************************************
704 * Private class methods
706 ***********************************************************************/
708 void set_defaults_(FLAC__FileEncoder *encoder)
710 FLAC__ASSERT(0 != encoder);
711 FLAC__ASSERT(0 != encoder->private_);
713 encoder->private_->progress_callback = 0;
714 encoder->private_->client_data = 0;
715 encoder->private_->total_frames_estimate = 0;
716 encoder->private_->filename = 0;
719 FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
721 FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
725 FLAC__ASSERT(0 != file_encoder);
727 if(fseek(file_encoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
728 return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR;
730 return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK;
733 FLAC__SeekableStreamEncoderTellStatus tell_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
735 FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
740 FLAC__ASSERT(0 != file_encoder);
742 offset = ftell(file_encoder->private_->file);
745 return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_ERROR;
748 *absolute_byte_offset = (FLAC__uint64)offset;
749 return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK;
753 #ifdef FLAC__VALGRIND_TESTING
754 static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
756 size_t ret = fwrite(ptr, size, nmemb, stream);
762 #define local__fwrite fwrite
765 FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
767 FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
769 (void)encoder, (void)samples, (void)current_frame;
771 FLAC__ASSERT(0 != file_encoder);
773 if(local__fwrite(buffer, sizeof(FLAC__byte), bytes, file_encoder->private_->file) == bytes) {
774 file_encoder->private_->bytes_written += bytes;
775 file_encoder->private_->samples_written += samples;
776 /* we keep a high watermark on the number of frames written because
777 * when the encoder goes back to write metadata, 'current_frame'
778 * will drop back to 0.
780 file_encoder->private_->frames_written = max(file_encoder->private_->frames_written, current_frame+1);
781 if(0 != file_encoder->private_->progress_callback && samples > 0)
782 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);
783 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
786 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;