fix bug where encoder was closing file too soon in finish()
[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         /* FLAC__seekable_stream_encoder_finish() might write data so we must close the file after it. */
170
171         FLAC__seekable_stream_encoder_finish(encoder->private_->seekable_stream_encoder);
172
173         if(0 != encoder->private_->file) {
174                 fclose(encoder->private_->file);
175                 encoder->private_->file = 0;
176         }
177
178         if(0 != encoder->private_->filename) {
179                 free(encoder->private_->filename);
180                 encoder->private_->filename = 0;
181         }
182
183         set_defaults_(encoder);
184
185         encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED;
186 }
187
188 FLAC__bool FLAC__file_encoder_set_streamable_subset(FLAC__FileEncoder *encoder, FLAC__bool value)
189 {
190         FLAC__ASSERT(0 != encoder);
191         FLAC__ASSERT(0 != encoder->private_);
192         FLAC__ASSERT(0 != encoder->protected_);
193         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
194         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
195                 return false;
196         return FLAC__seekable_stream_encoder_set_streamable_subset(encoder->private_->seekable_stream_encoder, value);
197 }
198
199 FLAC__bool FLAC__file_encoder_set_do_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value)
200 {
201         FLAC__ASSERT(0 != encoder);
202         FLAC__ASSERT(0 != encoder->private_);
203         FLAC__ASSERT(0 != encoder->protected_);
204         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
205         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
206                 return false;
207         return FLAC__seekable_stream_encoder_set_do_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
208 }
209
210 FLAC__bool FLAC__file_encoder_set_loose_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value)
211 {
212         FLAC__ASSERT(0 != encoder);
213         FLAC__ASSERT(0 != encoder->private_);
214         FLAC__ASSERT(0 != encoder->protected_);
215         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
216         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
217                 return false;
218         return FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
219 }
220
221 FLAC__bool FLAC__file_encoder_set_channels(FLAC__FileEncoder *encoder, unsigned value)
222 {
223         FLAC__ASSERT(0 != encoder);
224         FLAC__ASSERT(0 != encoder->private_);
225         FLAC__ASSERT(0 != encoder->protected_);
226         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
227         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
228                 return false;
229         return FLAC__seekable_stream_encoder_set_channels(encoder->private_->seekable_stream_encoder, value);
230 }
231
232 FLAC__bool FLAC__file_encoder_set_bits_per_sample(FLAC__FileEncoder *encoder, unsigned value)
233 {
234         FLAC__ASSERT(0 != encoder);
235         FLAC__ASSERT(0 != encoder->private_);
236         FLAC__ASSERT(0 != encoder->protected_);
237         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
238         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
239                 return false;
240         return FLAC__seekable_stream_encoder_set_bits_per_sample(encoder->private_->seekable_stream_encoder, value);
241 }
242
243 FLAC__bool FLAC__file_encoder_set_sample_rate(FLAC__FileEncoder *encoder, unsigned value)
244 {
245         FLAC__ASSERT(0 != encoder);
246         FLAC__ASSERT(0 != encoder->private_);
247         FLAC__ASSERT(0 != encoder->protected_);
248         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
249         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
250                 return false;
251         return FLAC__seekable_stream_encoder_set_sample_rate(encoder->private_->seekable_stream_encoder, value);
252 }
253
254 FLAC__bool FLAC__file_encoder_set_blocksize(FLAC__FileEncoder *encoder, unsigned value)
255 {
256         FLAC__ASSERT(0 != encoder);
257         FLAC__ASSERT(0 != encoder->private_);
258         FLAC__ASSERT(0 != encoder->protected_);
259         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
260         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
261                 return false;
262         return FLAC__seekable_stream_encoder_set_blocksize(encoder->private_->seekable_stream_encoder, value);
263 }
264
265 FLAC__bool FLAC__file_encoder_set_max_lpc_order(FLAC__FileEncoder *encoder, unsigned value)
266 {
267         FLAC__ASSERT(0 != encoder);
268         FLAC__ASSERT(0 != encoder->private_);
269         FLAC__ASSERT(0 != encoder->protected_);
270         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
271         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
272                 return false;
273         return FLAC__seekable_stream_encoder_set_max_lpc_order(encoder->private_->seekable_stream_encoder, value);
274 }
275
276 FLAC__bool FLAC__file_encoder_set_qlp_coeff_precision(FLAC__FileEncoder *encoder, unsigned value)
277 {
278         FLAC__ASSERT(0 != encoder);
279         FLAC__ASSERT(0 != encoder->private_);
280         FLAC__ASSERT(0 != encoder->protected_);
281         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
282         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
283                 return false;
284         return FLAC__seekable_stream_encoder_set_qlp_coeff_precision(encoder->private_->seekable_stream_encoder, value);
285 }
286
287 FLAC__bool FLAC__file_encoder_set_do_qlp_coeff_prec_search(FLAC__FileEncoder *encoder, FLAC__bool value)
288 {
289         FLAC__ASSERT(0 != encoder);
290         FLAC__ASSERT(0 != encoder->private_);
291         FLAC__ASSERT(0 != encoder->protected_);
292         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
293         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
294                 return false;
295         return FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder, value);
296 }
297
298 FLAC__bool FLAC__file_encoder_set_do_escape_coding(FLAC__FileEncoder *encoder, FLAC__bool value)
299 {
300         FLAC__ASSERT(0 != encoder);
301         FLAC__ASSERT(0 != encoder->private_);
302         FLAC__ASSERT(0 != encoder->protected_);
303         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
304         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
305                 return false;
306         return FLAC__seekable_stream_encoder_set_do_escape_coding(encoder->private_->seekable_stream_encoder, value);
307 }
308
309 FLAC__bool FLAC__file_encoder_set_do_exhaustive_model_search(FLAC__FileEncoder *encoder, FLAC__bool value)
310 {
311         FLAC__ASSERT(0 != encoder);
312         FLAC__ASSERT(0 != encoder->private_);
313         FLAC__ASSERT(0 != encoder->protected_);
314         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
315         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
316                 return false;
317         return FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder, value);
318 }
319
320 FLAC__bool FLAC__file_encoder_set_min_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value)
321 {
322         FLAC__ASSERT(0 != encoder);
323         FLAC__ASSERT(0 != encoder->private_);
324         FLAC__ASSERT(0 != encoder->protected_);
325         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
326         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
327                 return false;
328         return FLAC__seekable_stream_encoder_set_min_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
329 }
330
331 FLAC__bool FLAC__file_encoder_set_max_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value)
332 {
333         FLAC__ASSERT(0 != encoder);
334         FLAC__ASSERT(0 != encoder->private_);
335         FLAC__ASSERT(0 != encoder->protected_);
336         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
337         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
338                 return false;
339         return FLAC__seekable_stream_encoder_set_max_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
340 }
341
342 FLAC__bool FLAC__file_encoder_set_rice_parameter_search_dist(FLAC__FileEncoder *encoder, unsigned value)
343 {
344         FLAC__ASSERT(0 != encoder);
345         FLAC__ASSERT(0 != encoder->private_);
346         FLAC__ASSERT(0 != encoder->protected_);
347         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
348         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
349                 return false;
350         return FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder, value);
351 }
352
353 FLAC__bool FLAC__file_encoder_set_total_samples_estimate(FLAC__FileEncoder *encoder, FLAC__uint64 value)
354 {
355         FLAC__ASSERT(0 != encoder);
356         FLAC__ASSERT(0 != encoder->private_);
357         FLAC__ASSERT(0 != encoder->protected_);
358         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
359         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
360                 return false;
361         return FLAC__seekable_stream_encoder_set_total_samples_estimate(encoder->private_->seekable_stream_encoder, value);
362 }
363
364 FLAC__bool FLAC__file_encoder_set_metadata(FLAC__FileEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
365 {
366         FLAC__ASSERT(0 != encoder);
367         FLAC__ASSERT(0 != encoder->private_);
368         FLAC__ASSERT(0 != encoder->protected_);
369         FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
370         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
371                 return false;
372         return FLAC__seekable_stream_encoder_set_metadata(encoder->private_->seekable_stream_encoder, metadata, num_blocks);
373 }
374
375 FLAC__bool FLAC__file_encoder_set_filename(FLAC__FileEncoder *encoder, const char *value)
376 {
377         FLAC__ASSERT(0 != encoder);
378         FLAC__ASSERT(0 != encoder->private_);
379         FLAC__ASSERT(0 != encoder->protected_);
380         FLAC__ASSERT(0 != value);
381         if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED)
382                 return false;
383         if(0 != encoder->private_->filename) {
384                 free(encoder->private_->filename);
385                 encoder->private_->filename = 0;
386         }
387         if(0 == (encoder->private_->filename = (char*)malloc(strlen(value)+1))) {
388                 encoder->protected_->state = FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR;
389                 return false;
390         }
391         strcpy(encoder->private_->filename, value);
392         return true;
393 }
394
395 FLAC__FileEncoderState FLAC__file_encoder_get_state(const FLAC__FileEncoder *encoder)
396 {
397         FLAC__ASSERT(0 != encoder);
398         FLAC__ASSERT(0 != encoder->protected_);
399         return encoder->protected_->state;
400 }
401
402 FLAC__SeekableStreamEncoderState FLAC__file_encoder_get_seekable_stream_encoder_state(const FLAC__FileEncoder *encoder)
403 {
404         FLAC__ASSERT(0 != encoder);
405         FLAC__ASSERT(0 != encoder->private_);
406         return FLAC__seekable_stream_encoder_get_state(encoder->private_->seekable_stream_encoder);
407 }
408
409 FLAC__StreamEncoderState FLAC__file_encoder_get_stream_encoder_state(const FLAC__FileEncoder *encoder)
410 {
411         FLAC__ASSERT(0 != encoder);
412         FLAC__ASSERT(0 != encoder->private_);
413         return FLAC__seekable_stream_encoder_get_stream_encoder_state(encoder->private_->seekable_stream_encoder);
414 }
415
416 FLAC__bool FLAC__file_encoder_get_streamable_subset(const FLAC__FileEncoder *encoder)
417 {
418         FLAC__ASSERT(0 != encoder);
419         FLAC__ASSERT(0 != encoder->private_);
420         return FLAC__seekable_stream_encoder_get_streamable_subset(encoder->private_->seekable_stream_encoder);
421 }
422
423 FLAC__bool FLAC__file_encoder_get_do_mid_side_stereo(const FLAC__FileEncoder *encoder)
424 {
425         FLAC__ASSERT(0 != encoder);
426         FLAC__ASSERT(0 != encoder->private_);
427         return FLAC__seekable_stream_encoder_get_do_mid_side_stereo(encoder->private_->seekable_stream_encoder);
428 }
429
430 FLAC__bool FLAC__file_encoder_get_loose_mid_side_stereo(const FLAC__FileEncoder *encoder)
431 {
432         FLAC__ASSERT(0 != encoder);
433         FLAC__ASSERT(0 != encoder->private_);
434         return FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder);
435 }
436
437 unsigned FLAC__file_encoder_get_channels(const FLAC__FileEncoder *encoder)
438 {
439         FLAC__ASSERT(0 != encoder);
440         FLAC__ASSERT(0 != encoder->private_);
441         return FLAC__seekable_stream_encoder_get_channels(encoder->private_->seekable_stream_encoder);
442 }
443
444 unsigned FLAC__file_encoder_get_bits_per_sample(const FLAC__FileEncoder *encoder)
445 {
446         FLAC__ASSERT(0 != encoder);
447         FLAC__ASSERT(0 != encoder->private_);
448         return FLAC__seekable_stream_encoder_get_bits_per_sample(encoder->private_->seekable_stream_encoder);
449 }
450
451 unsigned FLAC__file_encoder_get_sample_rate(const FLAC__FileEncoder *encoder)
452 {
453         FLAC__ASSERT(0 != encoder);
454         FLAC__ASSERT(0 != encoder->private_);
455         return FLAC__seekable_stream_encoder_get_sample_rate(encoder->private_->seekable_stream_encoder);
456 }
457
458 unsigned FLAC__file_encoder_get_blocksize(const FLAC__FileEncoder *encoder)
459 {
460         FLAC__ASSERT(0 != encoder);
461         FLAC__ASSERT(0 != encoder->private_);
462         return FLAC__seekable_stream_encoder_get_blocksize(encoder->private_->seekable_stream_encoder);
463 }
464
465 unsigned FLAC__file_encoder_get_max_lpc_order(const FLAC__FileEncoder *encoder)
466 {
467         FLAC__ASSERT(0 != encoder);
468         FLAC__ASSERT(0 != encoder->private_);
469         return FLAC__seekable_stream_encoder_get_max_lpc_order(encoder->private_->seekable_stream_encoder);
470 }
471
472 unsigned FLAC__file_encoder_get_qlp_coeff_precision(const FLAC__FileEncoder *encoder)
473 {
474         FLAC__ASSERT(0 != encoder);
475         FLAC__ASSERT(0 != encoder->private_);
476         return FLAC__seekable_stream_encoder_get_qlp_coeff_precision(encoder->private_->seekable_stream_encoder);
477 }
478
479 FLAC__bool FLAC__file_encoder_get_do_qlp_coeff_prec_search(const FLAC__FileEncoder *encoder)
480 {
481         FLAC__ASSERT(0 != encoder);
482         FLAC__ASSERT(0 != encoder->private_);
483         return FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder);
484 }
485
486 FLAC__bool FLAC__file_encoder_get_do_escape_coding(const FLAC__FileEncoder *encoder)
487 {
488         FLAC__ASSERT(0 != encoder);
489         FLAC__ASSERT(0 != encoder->private_);
490         return FLAC__seekable_stream_encoder_get_do_escape_coding(encoder->private_->seekable_stream_encoder);
491 }
492
493 FLAC__bool FLAC__file_encoder_get_do_exhaustive_model_search(const FLAC__FileEncoder *encoder)
494 {
495         FLAC__ASSERT(0 != encoder);
496         FLAC__ASSERT(0 != encoder->private_);
497         return FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder);
498 }
499
500 unsigned FLAC__file_encoder_get_min_residual_partition_order(const FLAC__FileEncoder *encoder)
501 {
502         FLAC__ASSERT(0 != encoder);
503         FLAC__ASSERT(0 != encoder->private_);
504         return FLAC__seekable_stream_encoder_get_min_residual_partition_order(encoder->private_->seekable_stream_encoder);
505 }
506
507 unsigned FLAC__file_encoder_get_max_residual_partition_order(const FLAC__FileEncoder *encoder)
508 {
509         FLAC__ASSERT(0 != encoder);
510         FLAC__ASSERT(0 != encoder->private_);
511         return FLAC__seekable_stream_encoder_get_max_residual_partition_order(encoder->private_->seekable_stream_encoder);
512 }
513
514 unsigned FLAC__file_encoder_get_rice_parameter_search_dist(const FLAC__FileEncoder *encoder)
515 {
516         FLAC__ASSERT(0 != encoder);
517         FLAC__ASSERT(0 != encoder->private_);
518         return FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder);
519 }
520
521 FLAC__bool FLAC__file_encoder_process(FLAC__FileEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
522 {
523         FLAC__ASSERT(0 != encoder);
524         FLAC__ASSERT(0 != encoder->private_);
525         return FLAC__seekable_stream_encoder_process(encoder->private_->seekable_stream_encoder, buffer, samples);
526 }
527
528 /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
529 FLAC__bool FLAC__file_encoder_process_interleaved(FLAC__FileEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
530 {
531         FLAC__ASSERT(0 != encoder);
532         FLAC__ASSERT(0 != encoder->private_);
533         return FLAC__seekable_stream_encoder_process_interleaved(encoder->private_->seekable_stream_encoder, buffer, samples);
534 }
535
536
537 /***********************************************************************
538  *
539  * Private class methods
540  *
541  ***********************************************************************/
542
543 void set_defaults_(FLAC__FileEncoder *encoder)
544 {
545         FLAC__ASSERT(0 != encoder);
546         FLAC__ASSERT(0 != encoder->private_);
547
548         encoder->private_->filename = 0;
549 }
550
551 FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
552 {
553         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
554
555         (void)encoder;
556
557         FLAC__ASSERT(0 != file_encoder);
558
559         if(fseek(file_encoder->private_->file, absolute_byte_offset, SEEK_SET) < 0)
560                 return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR;
561         else
562                 return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK;
563 }
564
565 FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
566 {
567         FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data;
568
569         (void)encoder, (void)samples, (void)current_frame;
570
571         FLAC__ASSERT(0 != file_encoder);
572
573         if(fwrite(buffer, sizeof(FLAC__byte), bytes, file_encoder->private_->file) == bytes)
574                 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
575         else
576                 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
577 }