fixes based on Windows testing
[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 static void set_defaults_(FLAC__FileEncoder *encoder);
34 static FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data);
35 static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
36
37 /***********************************************************************
38  *
39  * Private class data
40  *
41  ***********************************************************************/
42
43 typedef struct FLAC__FileEncoderPrivate {
44         FLAC__FileEncoderProgressCallback progress_callback;
45         void *client_data;
46         char *filename;
47         FLAC__uint64 bytes_written;
48         FLAC__uint64 samples_written;
49         unsigned total_frames_estimate;
50         FLAC__SeekableStreamEncoder *seekable_stream_encoder;
51         FILE *file;
52 } FLAC__FileEncoderPrivate;
53
54 /***********************************************************************
55  *
56  * Public static class data
57  *
58  ***********************************************************************/
59
60 const char * const FLAC__FileEncoderStateString[] = {
61         "FLAC__FILE_ENCODER_OK",
62         "FLAC__FILE_ENCODER_NO_FILENAME",
63         "FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR",
64         "FLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING",
65         "FLAC__FILE_ENCODER_ERROR_OPENING_FILE",
66         "FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR",
67         "FLAC__FILE_ENCODER_ALREADY_INITIALIZED",
68         "FLAC__FILE_ENCODER_UNINITIALIZED"
69 };
70
71
72 /***********************************************************************
73  *
74  * Class constructor/destructor
75  *
76  ***********************************************************************/
77
78 FLAC__FileEncoder *FLAC__file_encoder_new()
79 {
80         FLAC__FileEncoder *encoder;
81
82         FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
83
84         encoder = (FLAC__FileEncoder*)malloc(sizeof(FLAC__FileEncoder));
85         if(encoder == 0) {
86                 return 0;
87         }
88         memset(encoder, 0, sizeof(FLAC__FileEncoder));
89
90         encoder->protected_ = (FLAC__FileEncoderProtected*)malloc(sizeof(FLAC__FileEncoderProtected));
91         if(encoder->protected_ == 0) {
92                 free(encoder);
93                 return 0;
94         }
95         memset(encoder->protected_, 0, sizeof(FLAC__FileEncoderProtected));
96
97         encoder->private_ = (FLAC__FileEncoderPrivate*)malloc(sizeof(FLAC__FileEncoderPrivate));
98         if(encoder->private_ == 0) {
99                 free(encoder->protected_);
100                 free(encoder);
101                 return 0;
102         }
103         memset(encoder->private_, 0, sizeof(FLAC__FileEncoderPrivate));
104
105         encoder->private_->seekable_stream_encoder = FLAC__seekable_stream_encoder_new();
106         if(0 == encoder->private_->seekable_stream_encoder) {
107                 free(encoder->private_);
108                 free(encoder->protected_);
109                 free(encoder);
110                 return 0;
111         }
112
113         encoder->private_->file = 0;
114
115         set_defaults_(encoder);
116
117         encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED;
118
119         return encoder;
120 }
121
122 void FLAC__file_encoder_delete(FLAC__FileEncoder *encoder)
123 {
124         FLAC__ASSERT(0 != encoder);
125         FLAC__ASSERT(0 != encoder->protected_);
126         FLAC__ASSERT(0 != encoder->private_);
127         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
128
129         (void)FLAC__file_encoder_finish(encoder);
130
131         FLAC__seekable_stream_encoder_delete(encoder->private_->seekable_stream_encoder);
132
133         free(encoder->private_);
134         free(encoder->protected_);
135         free(encoder);
136 }
137
138 /***********************************************************************
139  *
140  * Public class methods
141  *
142  ***********************************************************************/
143
144 FLAC__FileEncoderState FLAC__file_encoder_init(FLAC__FileEncoder *encoder)
145 {
146         FLAC__ASSERT(0 != encoder);
147
148         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
149                 return encoder->protected_->state = FLAC__FILE_ENCODER_ALREADY_INITIALIZED;
150
151         if(0 == encoder->private_->filename)
152                 return encoder->protected_->state = FLAC__FILE_ENCODER_NO_FILENAME;
153
154         encoder->private_->file = fopen(encoder->private_->filename, "w+b");
155
156         if(encoder->private_->file == 0)
157                 return encoder->protected_->state = FLAC__FILE_ENCODER_ERROR_OPENING_FILE;
158
159         encoder->private_->bytes_written = 0;
160         encoder->private_->samples_written = 0;
161
162         FLAC__seekable_stream_encoder_set_seek_callback(encoder->private_->seekable_stream_encoder, seek_callback_);
163         FLAC__seekable_stream_encoder_set_write_callback(encoder->private_->seekable_stream_encoder, write_callback_);
164         FLAC__seekable_stream_encoder_set_client_data(encoder->private_->seekable_stream_encoder, encoder);
165
166         if(FLAC__seekable_stream_encoder_init(encoder->private_->seekable_stream_encoder) != FLAC__SEEKABLE_STREAM_ENCODER_OK)
167                 return encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
168
169         {
170                 unsigned blocksize = FLAC__file_encoder_get_blocksize(encoder);
171
172                 FLAC__ASSERT(blocksize != 0);
173                 encoder->private_->total_frames_estimate = (unsigned)((FLAC__file_encoder_get_total_samples_estimate(encoder) + blocksize - 1) / blocksize);
174         }
175
176         return encoder->protected_->state = FLAC__FILE_ENCODER_OK;
177 }
178
179 void FLAC__file_encoder_finish(FLAC__FileEncoder *encoder)
180 {
181         FLAC__ASSERT(0 != encoder);
182
183         if(encoder->protected_->state == FLAC__FILE_ENCODER_UNINITIALIZED)
184                 return;
185
186         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
187
188         /* FLAC__seekable_stream_encoder_finish() might write data so we must close the file after it. */
189
190         FLAC__seekable_stream_encoder_finish(encoder->private_->seekable_stream_encoder);
191
192         if(0 != encoder->private_->file) {
193                 fclose(encoder->private_->file);
194                 encoder->private_->file = 0;
195         }
196
197         if(0 != encoder->private_->filename) {
198                 free(encoder->private_->filename);
199                 encoder->private_->filename = 0;
200         }
201
202         set_defaults_(encoder);
203
204         encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED;
205 }
206
207 FLAC__bool FLAC__file_encoder_set_verify(FLAC__FileEncoder *encoder, FLAC__bool value)
208 {
209         FLAC__ASSERT(0 != encoder);
210         FLAC__ASSERT(0 != encoder->private_);
211         FLAC__ASSERT(0 != encoder->protected_);
212         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
213         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
214                 return false;
215         return FLAC__seekable_stream_encoder_set_verify(encoder->private_->seekable_stream_encoder, value);
216 }
217
218 FLAC__bool FLAC__file_encoder_set_streamable_subset(FLAC__FileEncoder *encoder, FLAC__bool value)
219 {
220         FLAC__ASSERT(0 != encoder);
221         FLAC__ASSERT(0 != encoder->private_);
222         FLAC__ASSERT(0 != encoder->protected_);
223         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
224         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
225                 return false;
226         return FLAC__seekable_stream_encoder_set_streamable_subset(encoder->private_->seekable_stream_encoder, value);
227 }
228
229 FLAC__bool FLAC__file_encoder_set_do_mid_side_stereo(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_do_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
238 }
239
240 FLAC__bool FLAC__file_encoder_set_loose_mid_side_stereo(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_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
249 }
250
251 FLAC__bool FLAC__file_encoder_set_channels(FLAC__FileEncoder *encoder, unsigned 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_channels(encoder->private_->seekable_stream_encoder, value);
260 }
261
262 FLAC__bool FLAC__file_encoder_set_bits_per_sample(FLAC__FileEncoder *encoder, unsigned 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_bits_per_sample(encoder->private_->seekable_stream_encoder, value);
271 }
272
273 FLAC__bool FLAC__file_encoder_set_sample_rate(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_sample_rate(encoder->private_->seekable_stream_encoder, value);
282 }
283
284 FLAC__bool FLAC__file_encoder_set_blocksize(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_blocksize(encoder->private_->seekable_stream_encoder, value);
293 }
294
295 FLAC__bool FLAC__file_encoder_set_max_lpc_order(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_max_lpc_order(encoder->private_->seekable_stream_encoder, value);
304 }
305
306 FLAC__bool FLAC__file_encoder_set_qlp_coeff_precision(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_qlp_coeff_precision(encoder->private_->seekable_stream_encoder, value);
315 }
316
317 FLAC__bool FLAC__file_encoder_set_do_qlp_coeff_prec_search(FLAC__FileEncoder *encoder, FLAC__bool value)
318 {
319         FLAC__ASSERT(0 != encoder);
320         FLAC__ASSERT(0 != encoder->private_);
321         FLAC__ASSERT(0 != encoder->protected_);
322         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
323         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
324                 return false;
325         return FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder, value);
326 }
327
328 FLAC__bool FLAC__file_encoder_set_do_escape_coding(FLAC__FileEncoder *encoder, FLAC__bool 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_do_escape_coding(encoder->private_->seekable_stream_encoder, value);
337 }
338
339 FLAC__bool FLAC__file_encoder_set_do_exhaustive_model_search(FLAC__FileEncoder *encoder, FLAC__bool value)
340 {
341         FLAC__ASSERT(0 != encoder);
342         FLAC__ASSERT(0 != encoder->private_);
343         FLAC__ASSERT(0 != encoder->protected_);
344         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
345         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
346                 return false;
347         return FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder, value);
348 }
349
350 FLAC__bool FLAC__file_encoder_set_min_residual_partition_order(FLAC__FileEncoder *encoder, unsigned 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_min_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
359 }
360
361 FLAC__bool FLAC__file_encoder_set_max_residual_partition_order(FLAC__FileEncoder *encoder, unsigned 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_max_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
370 }
371
372 FLAC__bool FLAC__file_encoder_set_rice_parameter_search_dist(FLAC__FileEncoder *encoder, unsigned value)
373 {
374         FLAC__ASSERT(0 != encoder);
375         FLAC__ASSERT(0 != encoder->private_);
376         FLAC__ASSERT(0 != encoder->protected_);
377         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
378         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
379                 return false;
380         return FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder, value);
381 }
382
383 FLAC__bool FLAC__file_encoder_set_total_samples_estimate(FLAC__FileEncoder *encoder, FLAC__uint64 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_total_samples_estimate(encoder->private_->seekable_stream_encoder, value);
392 }
393
394 FLAC__bool FLAC__file_encoder_set_metadata(FLAC__FileEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
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_metadata(encoder->private_->seekable_stream_encoder, metadata, num_blocks);
403 }
404
405 FLAC__bool FLAC__file_encoder_set_filename(FLAC__FileEncoder *encoder, const char *value)
406 {
407         FLAC__ASSERT(0 != encoder);
408         FLAC__ASSERT(0 != encoder->private_);
409         FLAC__ASSERT(0 != encoder->protected_);
410         FLAC__ASSERT(0 != value);
411         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
412                 return false;
413         if(0 != encoder->private_->filename) {
414                 free(encoder->private_->filename);
415                 encoder->private_->filename = 0;
416         }
417         if(0 == (encoder->private_->filename = (char*)malloc(strlen(value)+1))) {
418                 encoder->protected_->state = FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR;
419                 return false;
420         }
421         strcpy(encoder->private_->filename, value);
422         return true;
423 }
424
425 FLAC__bool FLAC__file_encoder_set_progress_callback(FLAC__FileEncoder *encoder, FLAC__FileEncoderProgressCallback value)
426 {
427         FLAC__ASSERT(0 != encoder);
428         FLAC__ASSERT(0 != encoder->private_);
429         FLAC__ASSERT(0 != encoder->protected_);
430         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
431                 return false;
432         encoder->private_->progress_callback = value;
433         return true;
434 }
435
436 FLAC__bool FLAC__file_encoder_set_client_data(FLAC__FileEncoder *encoder, void *value)
437 {
438         FLAC__ASSERT(0 != encoder);
439         FLAC__ASSERT(0 != encoder->private_);
440         FLAC__ASSERT(0 != encoder->protected_);
441         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
442                 return false;
443         encoder->private_->client_data = value;
444         return true;
445 }
446
447 FLAC__FileEncoderState FLAC__file_encoder_get_state(const FLAC__FileEncoder *encoder)
448 {
449         FLAC__ASSERT(0 != encoder);
450         FLAC__ASSERT(0 != encoder->protected_);
451         return encoder->protected_->state;
452 }
453
454 FLAC__SeekableStreamEncoderState FLAC__file_encoder_get_seekable_stream_encoder_state(const FLAC__FileEncoder *encoder)
455 {
456         FLAC__ASSERT(0 != encoder);
457         FLAC__ASSERT(0 != encoder->private_);
458         return FLAC__seekable_stream_encoder_get_state(encoder->private_->seekable_stream_encoder);
459 }
460
461 FLAC__StreamEncoderState FLAC__file_encoder_get_stream_encoder_state(const FLAC__FileEncoder *encoder)
462 {
463         FLAC__ASSERT(0 != encoder);
464         FLAC__ASSERT(0 != encoder->private_);
465         return FLAC__seekable_stream_encoder_get_stream_encoder_state(encoder->private_->seekable_stream_encoder);
466 }
467
468 FLAC__StreamDecoderState FLAC__file_encoder_get_verify_decoder_state(const FLAC__FileEncoder *encoder)
469 {
470         FLAC__ASSERT(0 != encoder);
471         FLAC__ASSERT(0 != encoder->private_);
472         return FLAC__seekable_stream_encoder_get_verify_decoder_state(encoder->private_->seekable_stream_encoder);
473 }
474
475 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)
476 {
477         FLAC__ASSERT(0 != encoder);
478         FLAC__ASSERT(0 != encoder->private_);
479         FLAC__seekable_stream_encoder_get_verify_decoder_error_stats(encoder->private_->seekable_stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
480 }
481
482 FLAC__bool FLAC__file_encoder_get_verify(const FLAC__FileEncoder *encoder)
483 {
484         FLAC__ASSERT(0 != encoder);
485         FLAC__ASSERT(0 != encoder->private_);
486         return FLAC__seekable_stream_encoder_get_verify(encoder->private_->seekable_stream_encoder);
487 }
488
489 FLAC__bool FLAC__file_encoder_get_streamable_subset(const FLAC__FileEncoder *encoder)
490 {
491         FLAC__ASSERT(0 != encoder);
492         FLAC__ASSERT(0 != encoder->private_);
493         return FLAC__seekable_stream_encoder_get_streamable_subset(encoder->private_->seekable_stream_encoder);
494 }
495
496 FLAC__bool FLAC__file_encoder_get_do_mid_side_stereo(const FLAC__FileEncoder *encoder)
497 {
498         FLAC__ASSERT(0 != encoder);
499         FLAC__ASSERT(0 != encoder->private_);
500         return FLAC__seekable_stream_encoder_get_do_mid_side_stereo(encoder->private_->seekable_stream_encoder);
501 }
502
503 FLAC__bool FLAC__file_encoder_get_loose_mid_side_stereo(const FLAC__FileEncoder *encoder)
504 {
505         FLAC__ASSERT(0 != encoder);
506         FLAC__ASSERT(0 != encoder->private_);
507         return FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder);
508 }
509
510 unsigned FLAC__file_encoder_get_channels(const FLAC__FileEncoder *encoder)
511 {
512         FLAC__ASSERT(0 != encoder);
513         FLAC__ASSERT(0 != encoder->private_);
514         return FLAC__seekable_stream_encoder_get_channels(encoder->private_->seekable_stream_encoder);
515 }
516
517 unsigned FLAC__file_encoder_get_bits_per_sample(const FLAC__FileEncoder *encoder)
518 {
519         FLAC__ASSERT(0 != encoder);
520         FLAC__ASSERT(0 != encoder->private_);
521         return FLAC__seekable_stream_encoder_get_bits_per_sample(encoder->private_->seekable_stream_encoder);
522 }
523
524 unsigned FLAC__file_encoder_get_sample_rate(const FLAC__FileEncoder *encoder)
525 {
526         FLAC__ASSERT(0 != encoder);
527         FLAC__ASSERT(0 != encoder->private_);
528         return FLAC__seekable_stream_encoder_get_sample_rate(encoder->private_->seekable_stream_encoder);
529 }
530
531 unsigned FLAC__file_encoder_get_blocksize(const FLAC__FileEncoder *encoder)
532 {
533         FLAC__ASSERT(0 != encoder);
534         FLAC__ASSERT(0 != encoder->private_);
535         return FLAC__seekable_stream_encoder_get_blocksize(encoder->private_->seekable_stream_encoder);
536 }
537
538 unsigned FLAC__file_encoder_get_max_lpc_order(const FLAC__FileEncoder *encoder)
539 {
540         FLAC__ASSERT(0 != encoder);
541         FLAC__ASSERT(0 != encoder->private_);
542         return FLAC__seekable_stream_encoder_get_max_lpc_order(encoder->private_->seekable_stream_encoder);
543 }
544
545 unsigned FLAC__file_encoder_get_qlp_coeff_precision(const FLAC__FileEncoder *encoder)
546 {
547         FLAC__ASSERT(0 != encoder);
548         FLAC__ASSERT(0 != encoder->private_);
549         return FLAC__seekable_stream_encoder_get_qlp_coeff_precision(encoder->private_->seekable_stream_encoder);
550 }
551
552 FLAC__bool FLAC__file_encoder_get_do_qlp_coeff_prec_search(const FLAC__FileEncoder *encoder)
553 {
554         FLAC__ASSERT(0 != encoder);
555         FLAC__ASSERT(0 != encoder->private_);
556         return FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder);
557 }
558
559 FLAC__bool FLAC__file_encoder_get_do_escape_coding(const FLAC__FileEncoder *encoder)
560 {
561         FLAC__ASSERT(0 != encoder);
562         FLAC__ASSERT(0 != encoder->private_);
563         return FLAC__seekable_stream_encoder_get_do_escape_coding(encoder->private_->seekable_stream_encoder);
564 }
565
566 FLAC__bool FLAC__file_encoder_get_do_exhaustive_model_search(const FLAC__FileEncoder *encoder)
567 {
568         FLAC__ASSERT(0 != encoder);
569         FLAC__ASSERT(0 != encoder->private_);
570         return FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder);
571 }
572
573 unsigned FLAC__file_encoder_get_min_residual_partition_order(const FLAC__FileEncoder *encoder)
574 {
575         FLAC__ASSERT(0 != encoder);
576         FLAC__ASSERT(0 != encoder->private_);
577         return FLAC__seekable_stream_encoder_get_min_residual_partition_order(encoder->private_->seekable_stream_encoder);
578 }
579
580 unsigned FLAC__file_encoder_get_max_residual_partition_order(const FLAC__FileEncoder *encoder)
581 {
582         FLAC__ASSERT(0 != encoder);
583         FLAC__ASSERT(0 != encoder->private_);
584         return FLAC__seekable_stream_encoder_get_max_residual_partition_order(encoder->private_->seekable_stream_encoder);
585 }
586
587 unsigned FLAC__file_encoder_get_rice_parameter_search_dist(const FLAC__FileEncoder *encoder)
588 {
589         FLAC__ASSERT(0 != encoder);
590         FLAC__ASSERT(0 != encoder->private_);
591         return FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder);
592 }
593
594 FLAC__uint64 FLAC__file_encoder_get_total_samples_estimate(const FLAC__FileEncoder *encoder)
595 {
596         FLAC__ASSERT(0 != encoder);
597         FLAC__ASSERT(0 != encoder->private_);
598         return FLAC__seekable_stream_encoder_get_total_samples_estimate(encoder->private_->seekable_stream_encoder);
599 }
600
601 FLAC__bool FLAC__file_encoder_process(FLAC__FileEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
602 {
603         FLAC__ASSERT(0 != encoder);
604         FLAC__ASSERT(0 != encoder->private_);
605         if(!FLAC__seekable_stream_encoder_process(encoder->private_->seekable_stream_encoder, buffer, samples)) {
606                 encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
607                 return false;
608         }
609         else
610                 return true;
611 }
612
613 /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
614 FLAC__bool FLAC__file_encoder_process_interleaved(FLAC__FileEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
615 {
616         FLAC__ASSERT(0 != encoder);
617         FLAC__ASSERT(0 != encoder->private_);
618         if(!FLAC__seekable_stream_encoder_process_interleaved(encoder->private_->seekable_stream_encoder, buffer, samples)) {
619                 encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
620                 return false;
621         }
622         else
623                 return true;
624 }
625
626
627 /***********************************************************************
628  *
629  * Private class methods
630  *
631  ***********************************************************************/
632
633 void set_defaults_(FLAC__FileEncoder *encoder)
634 {
635         FLAC__ASSERT(0 != encoder);
636         FLAC__ASSERT(0 != encoder->private_);
637
638         encoder->private_->progress_callback = 0;
639         encoder->private_->client_data = 0;
640         encoder->private_->total_frames_estimate = 0;
641         encoder->private_->filename = 0;
642 }
643
644 FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
645 {
646         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
647
648         (void)encoder;
649
650         FLAC__ASSERT(0 != file_encoder);
651
652         if(fseek(file_encoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
653                 return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR;
654         else
655                 return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK;
656 }
657
658 FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
659 {
660         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
661
662         (void)encoder, (void)samples, (void)current_frame;
663
664         FLAC__ASSERT(0 != file_encoder);
665
666         if(fwrite(buffer, sizeof(FLAC__byte), bytes, file_encoder->private_->file) == bytes) {
667                 file_encoder->private_->bytes_written += bytes;
668                 file_encoder->private_->samples_written += samples;
669                 if(0 != file_encoder->private_->progress_callback && samples > 0)
670                         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);
671                 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
672         }
673         else
674                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
675 }