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