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