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