add support for specifying which apodization functions to use to window data before...
[flac.git] / src / libFLAC / file_encoder.c
1 /* libFLAC - Free Lossless Audio Codec library
2  * Copyright (C) 2002,2003,2004,2005  Josh Coalson
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * - Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * - Neither the name of the Xiph.org Foundation nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include <stdio.h>
33 #include <stdlib.h> /* for malloc() */
34 #include <string.h> /* for strlen(), strcpy() */
35 #include "FLAC/assert.h"
36 #include "protected/file_encoder.h"
37
38 #ifdef max
39 #undef max
40 #endif
41 #define max(x,y) ((x)>(y)?(x):(y))
42
43 /***********************************************************************
44  *
45  * Private class method prototypes
46  *
47  ***********************************************************************/
48
49 /* unpublished debug routines */
50 extern FLAC__bool FLAC__seekable_stream_encoder_disable_constant_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
51 extern FLAC__bool FLAC__seekable_stream_encoder_disable_fixed_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
52 extern FLAC__bool FLAC__seekable_stream_encoder_disable_verbatim_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
53
54 static void set_defaults_(FLAC__FileEncoder *encoder);
55 static FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data);
56 static FLAC__SeekableStreamEncoderTellStatus tell_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
57 static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
58
59 /***********************************************************************
60  *
61  * Private class data
62  *
63  ***********************************************************************/
64
65 typedef struct FLAC__FileEncoderPrivate {
66         FLAC__FileEncoderProgressCallback progress_callback;
67         void *client_data;
68         char *filename;
69         FLAC__uint64 bytes_written;
70         FLAC__uint64 samples_written;
71         unsigned frames_written;
72         unsigned total_frames_estimate;
73         FLAC__SeekableStreamEncoder *seekable_stream_encoder;
74         FILE *file;
75 } FLAC__FileEncoderPrivate;
76
77 /***********************************************************************
78  *
79  * Public static class data
80  *
81  ***********************************************************************/
82
83 FLAC_API const char * const FLAC__FileEncoderStateString[] = {
84         "FLAC__FILE_ENCODER_OK",
85         "FLAC__FILE_ENCODER_NO_FILENAME",
86         "FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR",
87         "FLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING",
88         "FLAC__FILE_ENCODER_ERROR_OPENING_FILE",
89         "FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR",
90         "FLAC__FILE_ENCODER_ALREADY_INITIALIZED",
91         "FLAC__FILE_ENCODER_UNINITIALIZED"
92 };
93
94
95 /***********************************************************************
96  *
97  * Class constructor/destructor
98  *
99  ***********************************************************************/
100
101 FLAC_API FLAC__FileEncoder *FLAC__file_encoder_new()
102 {
103         FLAC__FileEncoder *encoder;
104
105         FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
106
107         encoder = (FLAC__FileEncoder*)calloc(1, sizeof(FLAC__FileEncoder));
108         if(encoder == 0) {
109                 return 0;
110         }
111
112         encoder->protected_ = (FLAC__FileEncoderProtected*)calloc(1, sizeof(FLAC__FileEncoderProtected));
113         if(encoder->protected_ == 0) {
114                 free(encoder);
115                 return 0;
116         }
117
118         encoder->private_ = (FLAC__FileEncoderPrivate*)calloc(1, sizeof(FLAC__FileEncoderPrivate));
119         if(encoder->private_ == 0) {
120                 free(encoder->protected_);
121                 free(encoder);
122                 return 0;
123         }
124
125         encoder->private_->seekable_stream_encoder = FLAC__seekable_stream_encoder_new();
126         if(0 == encoder->private_->seekable_stream_encoder) {
127                 free(encoder->private_);
128                 free(encoder->protected_);
129                 free(encoder);
130                 return 0;
131         }
132
133         encoder->private_->file = 0;
134
135         set_defaults_(encoder);
136
137         encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED;
138
139         return encoder;
140 }
141
142 FLAC_API void FLAC__file_encoder_delete(FLAC__FileEncoder *encoder)
143 {
144         FLAC__ASSERT(0 != encoder);
145         FLAC__ASSERT(0 != encoder->protected_);
146         FLAC__ASSERT(0 != encoder->private_);
147         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
148
149         (void)FLAC__file_encoder_finish(encoder);
150
151         FLAC__seekable_stream_encoder_delete(encoder->private_->seekable_stream_encoder);
152
153         free(encoder->private_);
154         free(encoder->protected_);
155         free(encoder);
156 }
157
158 /***********************************************************************
159  *
160  * Public class methods
161  *
162  ***********************************************************************/
163
164 FLAC_API FLAC__FileEncoderState FLAC__file_encoder_init(FLAC__FileEncoder *encoder)
165 {
166         FLAC__ASSERT(0 != encoder);
167
168         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
169                 return encoder->protected_->state = FLAC__FILE_ENCODER_ALREADY_INITIALIZED;
170
171         if(0 == encoder->private_->filename)
172                 return encoder->protected_->state = FLAC__FILE_ENCODER_NO_FILENAME;
173
174         encoder->private_->file = fopen(encoder->private_->filename, "w+b");
175
176         if(encoder->private_->file == 0)
177                 return encoder->protected_->state = FLAC__FILE_ENCODER_ERROR_OPENING_FILE;
178
179         encoder->private_->bytes_written = 0;
180         encoder->private_->samples_written = 0;
181         encoder->private_->frames_written = 0;
182
183         FLAC__seekable_stream_encoder_set_seek_callback(encoder->private_->seekable_stream_encoder, seek_callback_);
184         FLAC__seekable_stream_encoder_set_tell_callback(encoder->private_->seekable_stream_encoder, tell_callback_);
185         FLAC__seekable_stream_encoder_set_write_callback(encoder->private_->seekable_stream_encoder, write_callback_);
186         FLAC__seekable_stream_encoder_set_client_data(encoder->private_->seekable_stream_encoder, encoder);
187
188         if(FLAC__seekable_stream_encoder_init(encoder->private_->seekable_stream_encoder) != FLAC__SEEKABLE_STREAM_ENCODER_OK)
189                 return encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
190
191         {
192                 unsigned blocksize = FLAC__file_encoder_get_blocksize(encoder);
193
194                 FLAC__ASSERT(blocksize != 0);
195                 encoder->private_->total_frames_estimate = (unsigned)((FLAC__file_encoder_get_total_samples_estimate(encoder) + blocksize - 1) / blocksize);
196         }
197
198         return encoder->protected_->state = FLAC__FILE_ENCODER_OK;
199 }
200
201 FLAC_API void FLAC__file_encoder_finish(FLAC__FileEncoder *encoder)
202 {
203         FLAC__ASSERT(0 != encoder);
204
205         if(encoder->protected_->state == FLAC__FILE_ENCODER_UNINITIALIZED)
206                 return;
207
208         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
209
210         /* FLAC__seekable_stream_encoder_finish() might write data so we must close the file after it. */
211
212         FLAC__seekable_stream_encoder_finish(encoder->private_->seekable_stream_encoder);
213
214         if(0 != encoder->private_->file) {
215                 fclose(encoder->private_->file);
216                 encoder->private_->file = 0;
217         }
218
219         if(0 != encoder->private_->filename) {
220                 free(encoder->private_->filename);
221                 encoder->private_->filename = 0;
222         }
223
224         set_defaults_(encoder);
225
226         encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED;
227 }
228
229 FLAC_API FLAC__bool FLAC__file_encoder_set_verify(FLAC__FileEncoder *encoder, FLAC__bool value)
230 {
231         FLAC__ASSERT(0 != encoder);
232         FLAC__ASSERT(0 != encoder->private_);
233         FLAC__ASSERT(0 != encoder->protected_);
234         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
235         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
236                 return false;
237         return FLAC__seekable_stream_encoder_set_verify(encoder->private_->seekable_stream_encoder, value);
238 }
239
240 FLAC_API FLAC__bool FLAC__file_encoder_set_streamable_subset(FLAC__FileEncoder *encoder, FLAC__bool value)
241 {
242         FLAC__ASSERT(0 != encoder);
243         FLAC__ASSERT(0 != encoder->private_);
244         FLAC__ASSERT(0 != encoder->protected_);
245         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
246         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
247                 return false;
248         return FLAC__seekable_stream_encoder_set_streamable_subset(encoder->private_->seekable_stream_encoder, value);
249 }
250
251 FLAC_API FLAC__bool FLAC__file_encoder_set_do_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value)
252 {
253         FLAC__ASSERT(0 != encoder);
254         FLAC__ASSERT(0 != encoder->private_);
255         FLAC__ASSERT(0 != encoder->protected_);
256         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
257         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
258                 return false;
259         return FLAC__seekable_stream_encoder_set_do_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
260 }
261
262 FLAC_API FLAC__bool FLAC__file_encoder_set_loose_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value)
263 {
264         FLAC__ASSERT(0 != encoder);
265         FLAC__ASSERT(0 != encoder->private_);
266         FLAC__ASSERT(0 != encoder->protected_);
267         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
268         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
269                 return false;
270         return FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
271 }
272
273 FLAC_API FLAC__bool FLAC__file_encoder_set_channels(FLAC__FileEncoder *encoder, unsigned value)
274 {
275         FLAC__ASSERT(0 != encoder);
276         FLAC__ASSERT(0 != encoder->private_);
277         FLAC__ASSERT(0 != encoder->protected_);
278         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
279         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
280                 return false;
281         return FLAC__seekable_stream_encoder_set_channels(encoder->private_->seekable_stream_encoder, value);
282 }
283
284 FLAC_API FLAC__bool FLAC__file_encoder_set_bits_per_sample(FLAC__FileEncoder *encoder, unsigned value)
285 {
286         FLAC__ASSERT(0 != encoder);
287         FLAC__ASSERT(0 != encoder->private_);
288         FLAC__ASSERT(0 != encoder->protected_);
289         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
290         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
291                 return false;
292         return FLAC__seekable_stream_encoder_set_bits_per_sample(encoder->private_->seekable_stream_encoder, value);
293 }
294
295 FLAC_API FLAC__bool FLAC__file_encoder_set_sample_rate(FLAC__FileEncoder *encoder, unsigned value)
296 {
297         FLAC__ASSERT(0 != encoder);
298         FLAC__ASSERT(0 != encoder->private_);
299         FLAC__ASSERT(0 != encoder->protected_);
300         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
301         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
302                 return false;
303         return FLAC__seekable_stream_encoder_set_sample_rate(encoder->private_->seekable_stream_encoder, value);
304 }
305
306 FLAC_API FLAC__bool FLAC__file_encoder_set_blocksize(FLAC__FileEncoder *encoder, unsigned value)
307 {
308         FLAC__ASSERT(0 != encoder);
309         FLAC__ASSERT(0 != encoder->private_);
310         FLAC__ASSERT(0 != encoder->protected_);
311         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
312         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
313                 return false;
314         return FLAC__seekable_stream_encoder_set_blocksize(encoder->private_->seekable_stream_encoder, value);
315 }
316
317 FLAC_API FLAC__bool FLAC__file_encoder_set_apodization(FLAC__FileEncoder *encoder, const char *specification)
318 {
319         FLAC__ASSERT(0 != encoder);
320         FLAC__ASSERT(0 != encoder->private_);
321         FLAC__ASSERT(0 != encoder->protected_);
322         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
323         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
324                 return false;
325         return FLAC__seekable_stream_encoder_set_apodization(encoder->private_->seekable_stream_encoder, specification);
326 }
327
328 FLAC_API FLAC__bool FLAC__file_encoder_set_max_lpc_order(FLAC__FileEncoder *encoder, unsigned value)
329 {
330         FLAC__ASSERT(0 != encoder);
331         FLAC__ASSERT(0 != encoder->private_);
332         FLAC__ASSERT(0 != encoder->protected_);
333         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
334         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
335                 return false;
336         return FLAC__seekable_stream_encoder_set_max_lpc_order(encoder->private_->seekable_stream_encoder, value);
337 }
338
339 FLAC_API FLAC__bool FLAC__file_encoder_set_qlp_coeff_precision(FLAC__FileEncoder *encoder, unsigned value)
340 {
341         FLAC__ASSERT(0 != encoder);
342         FLAC__ASSERT(0 != encoder->private_);
343         FLAC__ASSERT(0 != encoder->protected_);
344         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
345         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
346                 return false;
347         return FLAC__seekable_stream_encoder_set_qlp_coeff_precision(encoder->private_->seekable_stream_encoder, value);
348 }
349
350 FLAC_API FLAC__bool FLAC__file_encoder_set_do_qlp_coeff_prec_search(FLAC__FileEncoder *encoder, FLAC__bool value)
351 {
352         FLAC__ASSERT(0 != encoder);
353         FLAC__ASSERT(0 != encoder->private_);
354         FLAC__ASSERT(0 != encoder->protected_);
355         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
356         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
357                 return false;
358         return FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder, value);
359 }
360
361 FLAC_API FLAC__bool FLAC__file_encoder_set_do_escape_coding(FLAC__FileEncoder *encoder, FLAC__bool value)
362 {
363         FLAC__ASSERT(0 != encoder);
364         FLAC__ASSERT(0 != encoder->private_);
365         FLAC__ASSERT(0 != encoder->protected_);
366         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
367         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
368                 return false;
369         return FLAC__seekable_stream_encoder_set_do_escape_coding(encoder->private_->seekable_stream_encoder, value);
370 }
371
372 FLAC_API FLAC__bool FLAC__file_encoder_set_do_exhaustive_model_search(FLAC__FileEncoder *encoder, FLAC__bool value)
373 {
374         FLAC__ASSERT(0 != encoder);
375         FLAC__ASSERT(0 != encoder->private_);
376         FLAC__ASSERT(0 != encoder->protected_);
377         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
378         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
379                 return false;
380         return FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder, value);
381 }
382
383 FLAC_API FLAC__bool FLAC__file_encoder_set_min_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value)
384 {
385         FLAC__ASSERT(0 != encoder);
386         FLAC__ASSERT(0 != encoder->private_);
387         FLAC__ASSERT(0 != encoder->protected_);
388         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
389         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
390                 return false;
391         return FLAC__seekable_stream_encoder_set_min_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
392 }
393
394 FLAC_API FLAC__bool FLAC__file_encoder_set_max_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value)
395 {
396         FLAC__ASSERT(0 != encoder);
397         FLAC__ASSERT(0 != encoder->private_);
398         FLAC__ASSERT(0 != encoder->protected_);
399         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
400         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
401                 return false;
402         return FLAC__seekable_stream_encoder_set_max_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
403 }
404
405 FLAC_API FLAC__bool FLAC__file_encoder_set_rice_parameter_search_dist(FLAC__FileEncoder *encoder, unsigned value)
406 {
407         FLAC__ASSERT(0 != encoder);
408         FLAC__ASSERT(0 != encoder->private_);
409         FLAC__ASSERT(0 != encoder->protected_);
410         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
411         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
412                 return false;
413         return FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder, value);
414 }
415
416 FLAC_API FLAC__bool FLAC__file_encoder_set_total_samples_estimate(FLAC__FileEncoder *encoder, FLAC__uint64 value)
417 {
418         FLAC__ASSERT(0 != encoder);
419         FLAC__ASSERT(0 != encoder->private_);
420         FLAC__ASSERT(0 != encoder->protected_);
421         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
422         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
423                 return false;
424         return FLAC__seekable_stream_encoder_set_total_samples_estimate(encoder->private_->seekable_stream_encoder, value);
425 }
426
427 FLAC_API FLAC__bool FLAC__file_encoder_set_metadata(FLAC__FileEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
428 {
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)
434                 return false;
435         return FLAC__seekable_stream_encoder_set_metadata(encoder->private_->seekable_stream_encoder, metadata, num_blocks);
436 }
437
438 FLAC_API FLAC__bool FLAC__file_encoder_set_filename(FLAC__FileEncoder *encoder, const char *value)
439 {
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)
445                 return false;
446         if(0 != encoder->private_->filename) {
447                 free(encoder->private_->filename);
448                 encoder->private_->filename = 0;
449         }
450         if(0 == (encoder->private_->filename = (char*)malloc(strlen(value)+1))) {
451                 encoder->protected_->state = FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR;
452                 return false;
453         }
454         strcpy(encoder->private_->filename, value);
455         return true;
456 }
457
458 FLAC_API FLAC__bool FLAC__file_encoder_set_progress_callback(FLAC__FileEncoder *encoder, FLAC__FileEncoderProgressCallback value)
459 {
460         FLAC__ASSERT(0 != encoder);
461         FLAC__ASSERT(0 != encoder->private_);
462         FLAC__ASSERT(0 != encoder->protected_);
463         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
464                 return false;
465         encoder->private_->progress_callback = value;
466         return true;
467 }
468
469 FLAC_API FLAC__bool FLAC__file_encoder_set_client_data(FLAC__FileEncoder *encoder, void *value)
470 {
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)
475                 return false;
476         encoder->private_->client_data = value;
477         return true;
478 }
479
480 /*
481  * These three functions are not static, but not publically exposed in
482  * include/FLAC/ either.  They are used by the test suite.
483  */
484 FLAC_API FLAC__bool FLAC__file_encoder_disable_constant_subframes(FLAC__FileEncoder *encoder, FLAC__bool value)
485 {
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)
490                 return false;
491         return FLAC__seekable_stream_encoder_disable_constant_subframes(encoder->private_->seekable_stream_encoder, value);
492 }
493
494 FLAC_API FLAC__bool FLAC__file_encoder_disable_fixed_subframes(FLAC__FileEncoder *encoder, FLAC__bool value)
495 {
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)
500                 return false;
501         return FLAC__seekable_stream_encoder_disable_fixed_subframes(encoder->private_->seekable_stream_encoder, value);
502 }
503
504 FLAC_API FLAC__bool FLAC__file_encoder_disable_verbatim_subframes(FLAC__FileEncoder *encoder, FLAC__bool value)
505 {
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)
510                 return false;
511         return FLAC__seekable_stream_encoder_disable_verbatim_subframes(encoder->private_->seekable_stream_encoder, value);
512 }
513
514 FLAC_API FLAC__FileEncoderState FLAC__file_encoder_get_state(const FLAC__FileEncoder *encoder)
515 {
516         FLAC__ASSERT(0 != encoder);
517         FLAC__ASSERT(0 != encoder->protected_);
518         return encoder->protected_->state;
519 }
520
521 FLAC_API FLAC__SeekableStreamEncoderState FLAC__file_encoder_get_seekable_stream_encoder_state(const FLAC__FileEncoder *encoder)
522 {
523         FLAC__ASSERT(0 != encoder);
524         FLAC__ASSERT(0 != encoder->private_);
525         return FLAC__seekable_stream_encoder_get_state(encoder->private_->seekable_stream_encoder);
526 }
527
528 FLAC_API FLAC__StreamEncoderState FLAC__file_encoder_get_stream_encoder_state(const FLAC__FileEncoder *encoder)
529 {
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);
533 }
534
535 FLAC_API FLAC__StreamDecoderState FLAC__file_encoder_get_verify_decoder_state(const FLAC__FileEncoder *encoder)
536 {
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);
540 }
541
542 FLAC_API const char *FLAC__file_encoder_get_resolved_state_string(const FLAC__FileEncoder *encoder)
543 {
544         if(encoder->protected_->state != FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR)
545                 return FLAC__FileEncoderStateString[encoder->protected_->state];
546         else
547                 return FLAC__seekable_stream_encoder_get_resolved_state_string(encoder->private_->seekable_stream_encoder);
548 }
549
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)
551 {
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);
555 }
556
557 FLAC_API FLAC__bool FLAC__file_encoder_get_verify(const FLAC__FileEncoder *encoder)
558 {
559         FLAC__ASSERT(0 != encoder);
560         FLAC__ASSERT(0 != encoder->private_);
561         return FLAC__seekable_stream_encoder_get_verify(encoder->private_->seekable_stream_encoder);
562 }
563
564 FLAC_API FLAC__bool FLAC__file_encoder_get_streamable_subset(const FLAC__FileEncoder *encoder)
565 {
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);
569 }
570
571 FLAC_API FLAC__bool FLAC__file_encoder_get_do_mid_side_stereo(const FLAC__FileEncoder *encoder)
572 {
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);
576 }
577
578 FLAC_API FLAC__bool FLAC__file_encoder_get_loose_mid_side_stereo(const FLAC__FileEncoder *encoder)
579 {
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);
583 }
584
585 FLAC_API unsigned FLAC__file_encoder_get_channels(const FLAC__FileEncoder *encoder)
586 {
587         FLAC__ASSERT(0 != encoder);
588         FLAC__ASSERT(0 != encoder->private_);
589         return FLAC__seekable_stream_encoder_get_channels(encoder->private_->seekable_stream_encoder);
590 }
591
592 FLAC_API unsigned FLAC__file_encoder_get_bits_per_sample(const FLAC__FileEncoder *encoder)
593 {
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);
597 }
598
599 FLAC_API unsigned FLAC__file_encoder_get_sample_rate(const FLAC__FileEncoder *encoder)
600 {
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);
604 }
605
606 FLAC_API unsigned FLAC__file_encoder_get_blocksize(const FLAC__FileEncoder *encoder)
607 {
608         FLAC__ASSERT(0 != encoder);
609         FLAC__ASSERT(0 != encoder->private_);
610         return FLAC__seekable_stream_encoder_get_blocksize(encoder->private_->seekable_stream_encoder);
611 }
612
613 FLAC_API unsigned FLAC__file_encoder_get_max_lpc_order(const FLAC__FileEncoder *encoder)
614 {
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);
618 }
619
620 FLAC_API unsigned FLAC__file_encoder_get_qlp_coeff_precision(const FLAC__FileEncoder *encoder)
621 {
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);
625 }
626
627 FLAC_API FLAC__bool FLAC__file_encoder_get_do_qlp_coeff_prec_search(const FLAC__FileEncoder *encoder)
628 {
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);
632 }
633
634 FLAC_API FLAC__bool FLAC__file_encoder_get_do_escape_coding(const FLAC__FileEncoder *encoder)
635 {
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);
639 }
640
641 FLAC_API FLAC__bool FLAC__file_encoder_get_do_exhaustive_model_search(const FLAC__FileEncoder *encoder)
642 {
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);
646 }
647
648 FLAC_API unsigned FLAC__file_encoder_get_min_residual_partition_order(const FLAC__FileEncoder *encoder)
649 {
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);
653 }
654
655 FLAC_API unsigned FLAC__file_encoder_get_max_residual_partition_order(const FLAC__FileEncoder *encoder)
656 {
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);
660 }
661
662 FLAC_API unsigned FLAC__file_encoder_get_rice_parameter_search_dist(const FLAC__FileEncoder *encoder)
663 {
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);
667 }
668
669 FLAC_API FLAC__uint64 FLAC__file_encoder_get_total_samples_estimate(const FLAC__FileEncoder *encoder)
670 {
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);
674 }
675
676 FLAC_API FLAC__bool FLAC__file_encoder_process(FLAC__FileEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
677 {
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;
682                 return false;
683         }
684         else
685                 return true;
686 }
687
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)
690 {
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;
695                 return false;
696         }
697         else
698                 return true;
699 }
700
701
702 /***********************************************************************
703  *
704  * Private class methods
705  *
706  ***********************************************************************/
707
708 void set_defaults_(FLAC__FileEncoder *encoder)
709 {
710         FLAC__ASSERT(0 != encoder);
711         FLAC__ASSERT(0 != encoder->private_);
712
713         encoder->private_->progress_callback = 0;
714         encoder->private_->client_data = 0;
715         encoder->private_->total_frames_estimate = 0;
716         encoder->private_->filename = 0;
717 }
718
719 FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
720 {
721         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
722
723         (void)encoder;
724
725         FLAC__ASSERT(0 != file_encoder);
726
727         if(fseek(file_encoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
728                 return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR;
729         else
730                 return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK;
731 }
732
733 FLAC__SeekableStreamEncoderTellStatus tell_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
734 {
735         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
736         long offset;
737
738         (void)encoder;
739
740         FLAC__ASSERT(0 != file_encoder);
741
742         offset = ftell(file_encoder->private_->file);
743
744         if(offset < 0) {
745                 return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_ERROR;
746         }
747         else {
748                 *absolute_byte_offset = (FLAC__uint64)offset;
749                 return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK;
750         }
751 }
752
753 #ifdef FLAC__VALGRIND_TESTING
754 static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
755 {
756         size_t ret = fwrite(ptr, size, nmemb, stream);
757         if(!ferror(stream))
758                 fflush(stream);
759         return ret;
760 }
761 #else
762 #define local__fwrite fwrite
763 #endif
764
765 FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
766 {
767         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
768
769         (void)encoder, (void)samples, (void)current_frame;
770
771         FLAC__ASSERT(0 != file_encoder);
772
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.
779                  */
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;
784         }
785         else
786                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
787 }