1 /* libFLAC - Free Lossless Audio Codec library
2 * Copyright (C) 2002 Josh Coalson
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.
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.
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.
21 #include <stdlib.h> /* for malloc() */
22 #include <string.h> /* for memcpy() */
23 #include "FLAC/assert.h"
24 #include "protected/seekable_stream_encoder.h"
25 #include "protected/stream_encoder.h"
27 /***********************************************************************
29 * Private class method prototypes
31 ***********************************************************************/
33 static void set_defaults_(FLAC__SeekableStreamEncoder *encoder);
34 static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
35 static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
37 /***********************************************************************
41 ***********************************************************************/
43 typedef struct FLAC__SeekableStreamEncoderPrivate {
46 FLAC__StreamEncoder *stream_encoder;
47 } FLAC__SeekableStreamEncoderPrivate;
49 /***********************************************************************
51 * Public static class data
53 ***********************************************************************/
55 const char * const FLAC__SeekableStreamEncoderStateString[] = {
56 "FLAC__SEEKABLE_STREAM_ENCODER_OK",
57 "FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR",
58 "FLAC__SEEKABLE_STREAM_ENCODER_ERROR_OPENING_FILE",
59 "FLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR",
60 "FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED",
61 "FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED"
65 /***********************************************************************
67 * Class constructor/destructor
69 ***********************************************************************/
70 FLAC__SeekableStreamEncoder *FLAC__seekable_stream_encoder_new()
72 FLAC__SeekableStreamEncoder *encoder;
74 FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
76 encoder = (FLAC__SeekableStreamEncoder*)malloc(sizeof(FLAC__SeekableStreamEncoder));
80 encoder->protected_ = (FLAC__SeekableStreamEncoderProtected*)malloc(sizeof(FLAC__SeekableStreamEncoderProtected));
81 if(encoder->protected_ == 0) {
85 encoder->private_ = (FLAC__SeekableStreamEncoderPrivate*)malloc(sizeof(FLAC__SeekableStreamEncoderPrivate));
86 if(encoder->private_ == 0) {
87 free(encoder->protected_);
92 encoder->private_->stream_encoder = FLAC__stream_encoder_new();
94 if(0 == encoder->private_->stream_encoder) {
95 free(encoder->private_);
96 free(encoder->protected_);
101 set_defaults_(encoder);
103 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
108 void FLAC__seekable_stream_encoder_delete(FLAC__SeekableStreamEncoder *encoder)
110 FLAC__ASSERT(0 != encoder);
111 FLAC__ASSERT(0 != encoder->protected_);
112 FLAC__ASSERT(0 != encoder->private_);
113 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
115 (void)FLAC__seekable_stream_encoder_finish(encoder);
117 FLAC__stream_encoder_delete(encoder->private_->stream_encoder);
119 free(encoder->private_);
120 free(encoder->protected_);
124 /***********************************************************************
126 * Public class methods
128 ***********************************************************************/
130 FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_init(FLAC__SeekableStreamEncoder *encoder)
132 FLAC__ASSERT(0 != encoder);
134 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
135 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED;
137 if(0 == encoder->private_->filename)
138 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_NO_FILENAME;
140 encoder->private_->file = fopen(encoder->private_->filename, "wb");
142 if(encoder->private_->file == 0)
143 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_ERROR_OPENING_FILE;
145 FLAC__stream_encoder_set_write_callback(encoder->private_->stream_encoder, write_callback_);
146 FLAC__stream_encoder_set_metadata_callback(encoder->private_->stream_encoder, metadata_callback_);
147 FLAC__stream_encoder_set_client_data(encoder->private_->stream_encoder, encoder);
149 if(FLAC__stream_encoder_init(encoder->private_->stream_encoder) != FLAC__STREAM_ENCODER_OK)
150 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
152 return decoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_OK;
155 void FLAC__seekable_stream_encoder_finish(FLAC__SeekableStreamEncoder *encoder)
157 FLAC__ASSERT(0 != encoder);
159 if(encoder->protected_->state == FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
162 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
164 if(0 != encoder->private_->file) {
165 fclose(encoder->private_->file);
166 encoder->private_->file = 0;
169 if(0 != encoder->private_->filename) {
170 free(encoder->private_->filename);
171 encoder->private_->filename = 0;
174 set_defaults_(encoder);
176 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
178 return FLAC__stream_encoder_finish(encoder->private_->stream_encoder);
181 FLAC__bool FLAC__seekable_stream_encoder_set_streamable_subset(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
183 FLAC__ASSERT(0 != encoder);
184 FLAC__ASSERT(0 != encoder->private_);
185 FLAC__ASSERT(0 != encoder->protected_);
186 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
187 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
189 return FLAC__stream_encoder_set_streamable_subset(encoder->private_->stream_encoder, value);
192 FLAC__bool FLAC__seekable_stream_encoder_set_do_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
194 FLAC__ASSERT(0 != encoder);
195 FLAC__ASSERT(0 != encoder->private_);
196 FLAC__ASSERT(0 != encoder->protected_);
197 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
198 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
200 return FLAC__stream_encoder_set_do_mid_side_stereo(encoder->private_->stream_encoder, value);
203 FLAC__bool FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
205 FLAC__ASSERT(0 != encoder);
206 FLAC__ASSERT(0 != encoder->private_);
207 FLAC__ASSERT(0 != encoder->protected_);
208 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
209 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
211 return FLAC__stream_encoder_set_loose_mid_side_stereo(encoder->private_->stream_encoder, value);
214 FLAC__bool FLAC__seekable_stream_encoder_set_channels(FLAC__SeekableStreamEncoder *encoder, unsigned value)
216 FLAC__ASSERT(0 != encoder);
217 FLAC__ASSERT(0 != encoder->private_);
218 FLAC__ASSERT(0 != encoder->protected_);
219 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
220 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
222 return FLAC__stream_encoder_set_channels(encoder->private_->stream_encoder, value);
225 FLAC__bool FLAC__seekable_stream_encoder_set_bits_per_sample(FLAC__SeekableStreamEncoder *encoder, unsigned value)
227 FLAC__ASSERT(0 != encoder);
228 FLAC__ASSERT(0 != encoder->private_);
229 FLAC__ASSERT(0 != encoder->protected_);
230 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
231 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
233 return FLAC__stream_encoder_set_bits_per_sample(encoder->private_->stream_encoder, value);
236 FLAC__bool FLAC__seekable_stream_encoder_set_sample_rate(FLAC__SeekableStreamEncoder *encoder, unsigned value)
238 FLAC__ASSERT(0 != encoder);
239 FLAC__ASSERT(0 != encoder->private_);
240 FLAC__ASSERT(0 != encoder->protected_);
241 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
242 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
244 return FLAC__stream_encoder_set_sample_rate(encoder->private_->stream_encoder, value);
247 FLAC__bool FLAC__seekable_stream_encoder_set_blocksize(FLAC__SeekableStreamEncoder *encoder, unsigned value)
249 FLAC__ASSERT(0 != encoder);
250 FLAC__ASSERT(0 != encoder->private_);
251 FLAC__ASSERT(0 != encoder->protected_);
252 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
253 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
255 return FLAC__stream_encoder_set_blocksize(encoder->private_->stream_encoder, value);
258 FLAC__bool FLAC__seekable_stream_encoder_set_max_lpc_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
260 FLAC__ASSERT(0 != encoder);
261 FLAC__ASSERT(0 != encoder->private_);
262 FLAC__ASSERT(0 != encoder->protected_);
263 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
264 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
266 return FLAC__stream_encoder_set_max_lpc_order(encoder->private_->stream_encoder, value);
269 FLAC__bool FLAC__seekable_stream_encoder_set_qlp_coeff_precision(FLAC__SeekableStreamEncoder *encoder, unsigned value)
271 FLAC__ASSERT(0 != encoder);
272 FLAC__ASSERT(0 != encoder->private_);
273 FLAC__ASSERT(0 != encoder->protected_);
274 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
275 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
277 return FLAC__stream_encoder_set_qlp_coeff_precision(encoder->private_->stream_encoder, value);
280 FLAC__bool FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
282 FLAC__ASSERT(0 != encoder);
283 FLAC__ASSERT(0 != encoder->private_);
284 FLAC__ASSERT(0 != encoder->protected_);
285 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
286 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
288 return FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->stream_encoder, value);
291 FLAC__bool FLAC__seekable_stream_encoder_set_do_escape_coding(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
293 FLAC__ASSERT(0 != encoder);
294 FLAC__ASSERT(0 != encoder->private_);
295 FLAC__ASSERT(0 != encoder->protected_);
296 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
297 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
299 return FLAC__stream_encoder_set_do_escape_coding(encoder->private_->stream_encoder, value);
302 FLAC__bool FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
304 FLAC__ASSERT(0 != encoder);
305 FLAC__ASSERT(0 != encoder->private_);
306 FLAC__ASSERT(0 != encoder->protected_);
307 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
308 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
310 return FLAC__stream_encoder_set_do_exhaustive_model_search(encoder->private_->stream_encoder, value);
313 FLAC__bool FLAC__seekable_stream_encoder_set_min_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
315 FLAC__ASSERT(0 != encoder);
316 FLAC__ASSERT(0 != encoder->private_);
317 FLAC__ASSERT(0 != encoder->protected_);
318 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
319 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
321 return FLAC__stream_encoder_set_min_residual_partition_order(encoder->private_->stream_encoder, value);
324 FLAC__bool FLAC__seekable_stream_encoder_set_max_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
326 FLAC__ASSERT(0 != encoder);
327 FLAC__ASSERT(0 != encoder->private_);
328 FLAC__ASSERT(0 != encoder->protected_);
329 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
330 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
332 return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->stream_encoder, value);
335 FLAC__bool FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(FLAC__SeekableStreamEncoder *encoder, unsigned value)
337 FLAC__ASSERT(0 != encoder);
338 FLAC__ASSERT(0 != encoder->private_);
339 FLAC__ASSERT(0 != encoder->protected_);
340 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
341 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
343 return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->stream_encoder, value);
346 FLAC__bool FLAC__seekable_stream_encoder_set_total_samples_estimate(FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 value)
348 FLAC__ASSERT(0 != encoder);
349 FLAC__ASSERT(0 != encoder->private_);
350 FLAC__ASSERT(0 != encoder->protected_);
351 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
352 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
354 return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->stream_encoder, value);
357 FLAC__bool FLAC__seekable_stream_encoder_set_metadata(FLAC__SeekableStreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
359 FLAC__ASSERT(0 != encoder);
360 FLAC__ASSERT(0 != encoder->private_);
361 FLAC__ASSERT(0 != encoder->protected_);
362 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
363 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
365 return FLAC__stream_encoder_set_metadata(encoder->private_->stream_encoder, value);
368 FLAC__bool FLAC__seekable_stream_encoder_set_seek_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderSeekStatus (*value)(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data))
370 FLAC__ASSERT(0 != encoder);
371 FLAC__ASSERT(0 != encoder->private_);
372 FLAC__ASSERT(0 != encoder->protected_);
373 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
375 encoder->private_->seek_callback = value;
379 FLAC__bool FLAC__stream_encoder_set_write_callback(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderWriteStatus (*value)(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data))
381 FLAC__ASSERT(0 != encoder);
382 FLAC__ASSERT(0 != encoder->private_);
383 FLAC__ASSERT(0 != encoder->protected_);
384 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
386 encoder->private_->write_callback = value;
390 FLAC__bool FLAC__stream_encoder_set_client_data(FLAC__StreamEncoder *encoder, void *value)
392 FLAC__ASSERT(0 != encoder);
393 FLAC__ASSERT(0 != encoder->private_);
394 FLAC__ASSERT(0 != encoder->protected_);
395 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
397 encoder->private_->client_data = value;
401 FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_get_state(const FLAC__SeekableStreamEncoder *encoder)
403 FLAC__ASSERT(0 != encoder);
404 FLAC__ASSERT(0 != encoder->protected_);
405 return encoder->protected_->state;
408 FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_get_stream_encoder_state(const FLAC__SeekableStreamEncoder *encoder)
410 FLAC__ASSERT(0 != encoder);
411 FLAC__ASSERT(0 != encoder->private_);
412 return FLAC__stream_encoder_get_state(encoder->private_->stream_encoder);
415 FLAC__bool FLAC__seekable_stream_encoder_get_streamable_subset(const FLAC__SeekableStreamEncoder *encoder)
417 FLAC__ASSERT(0 != encoder);
418 FLAC__ASSERT(0 != encoder->private_);
419 return FLAC__stream_encoder_get_streamable_subset(encoder->private_->stream_encoder);
422 FLAC__bool FLAC__seekable_stream_encoder_get_do_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder)
424 FLAC__ASSERT(0 != encoder);
425 FLAC__ASSERT(0 != encoder->private_);
426 return FLAC__stream_encoder_get_do_mid_side_stereo(encoder->private_->stream_encoder);
429 FLAC__bool FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder)
431 FLAC__ASSERT(0 != encoder);
432 FLAC__ASSERT(0 != encoder->private_);
433 return FLAC__stream_encoder_get_loose_mid_side_stereo(encoder->private_->stream_encoder);
436 unsigned FLAC__seekable_stream_encoder_get_channels(const FLAC__SeekableStreamEncoder *encoder)
438 FLAC__ASSERT(0 != encoder);
439 FLAC__ASSERT(0 != encoder->private_);
440 return FLAC__stream_encoder_get_channels(encoder->private_->stream_encoder);
443 unsigned FLAC__seekable_stream_encoder_get_bits_per_sample(const FLAC__SeekableStreamEncoder *encoder)
445 FLAC__ASSERT(0 != encoder);
446 FLAC__ASSERT(0 != encoder->private_);
447 return FLAC__stream_encoder_get_bits_per_sample(encoder->private_->stream_encoder);
450 unsigned FLAC__seekable_stream_encoder_get_sample_rate(const FLAC__SeekableStreamEncoder *encoder)
452 FLAC__ASSERT(0 != encoder);
453 FLAC__ASSERT(0 != encoder->private_);
454 return FLAC__stream_encoder_get_sample_rate(encoder->private_->stream_encoder);
457 unsigned FLAC__seekable_stream_encoder_get_blocksize(const FLAC__SeekableStreamEncoder *encoder)
459 FLAC__ASSERT(0 != encoder);
460 FLAC__ASSERT(0 != encoder->private_);
461 return FLAC__stream_encoder_get_blocksize(encoder->private_->stream_encoder);
464 unsigned FLAC__seekable_stream_encoder_get_max_lpc_order(const FLAC__SeekableStreamEncoder *encoder)
466 FLAC__ASSERT(0 != encoder);
467 FLAC__ASSERT(0 != encoder->private_);
468 return FLAC__stream_encoder_get_max_lpc_order(encoder->private_->stream_encoder);
471 unsigned FLAC__seekable_stream_encoder_get_qlp_coeff_precision(const FLAC__SeekableStreamEncoder *encoder)
473 FLAC__ASSERT(0 != encoder);
474 FLAC__ASSERT(0 != encoder->private_);
475 return FLAC__stream_encoder_get_qlp_coeff_precision(encoder->private_->stream_encoder);
478 FLAC__bool FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__SeekableStreamEncoder *encoder)
480 FLAC__ASSERT(0 != encoder);
481 FLAC__ASSERT(0 != encoder->private_);
482 return FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->stream_encoder);
485 FLAC__bool FLAC__seekable_stream_encoder_get_do_escape_coding(const FLAC__SeekableStreamEncoder *encoder)
487 FLAC__ASSERT(0 != encoder);
488 FLAC__ASSERT(0 != encoder->private_);
489 return FLAC__stream_encoder_get_do_escape_coding(encoder->private_->stream_encoder);
492 FLAC__bool FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(const FLAC__SeekableStreamEncoder *encoder)
494 FLAC__ASSERT(0 != encoder);
495 FLAC__ASSERT(0 != encoder->private_);
496 return FLAC__stream_encoder_get_do_exhaustive_model_search(encoder->private_->stream_encoder);
499 unsigned FLAC__seekable_stream_encoder_get_min_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder)
501 FLAC__ASSERT(0 != encoder);
502 FLAC__ASSERT(0 != encoder->private_);
503 return FLAC__stream_encoder_get_min_residual_partition_order(encoder->private_->stream_encoder);
506 unsigned FLAC__seekable_stream_encoder_get_max_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder)
508 FLAC__ASSERT(0 != encoder);
509 FLAC__ASSERT(0 != encoder->private_);
510 return FLAC__stream_encoder_get_max_residual_partition_order(encoder->private_->stream_encoder);
513 unsigned FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(const FLAC__SeekableStreamEncoder *encoder)
515 FLAC__ASSERT(0 != encoder);
516 FLAC__ASSERT(0 != encoder->private_);
517 return FLAC__stream_encoder_get_rice_parameter_search_dist(encoder->private_->stream_encoder);
520 FLAC__bool FLAC__seekable_stream_encoder_process(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
522 FLAC__ASSERT(0 != encoder);
523 FLAC__ASSERT(0 != encoder->private_);
524 return FLAC__stream_encoder_process(encoder->private_->stream_encoder, buffer, samples);
527 /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
528 FLAC__bool FLAC__seekable_stream_encoder_process_interleaved(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
530 FLAC__ASSERT(0 != encoder);
531 FLAC__ASSERT(0 != encoder->private_);
532 return FLAC__stream_encoder_process_interleaved(encoder->private_->stream_encoder, buffer, samples);
535 /***********************************************************************
537 * Private class methods
539 ***********************************************************************/
541 void set_defaults_(FLAC__SeekableStreamEncoder *encoder)
543 FLAC__ASSERT(0 != encoder);
544 FLAC__ASSERT(0 != encoder->private_);
545 FLAC__ASSERT(0 != encoder->protected_);
547 encoder->protected_->filename = 0;
550 FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
552 FLAC__SeekableStreamEncoder *seekable_stream_encoder = (FLAC__SeekableStreamEncoder*)client_data;
554 /* mark the current seek point if hit (if stream_offset == 0 that means we're still writing metadata and haven't hit the first frame yet) */
555 if(seekable_stream_encoder->private_->stream_offset > 0 && seekable_stream_encoder->private_->seek_table.num_points > 0) {
556 FLAC__uint64 current_sample = (FLAC__uint64)current_frame * (FLAC__uint64)FLAC__stream_encoder_get_blocksize(encoder), test_sample;
558 for(i = seekable_stream_encoder->private_->first_seek_point_to_check; i < seekable_stream_encoder->private_->seek_table.num_points; i++) {
559 test_sample = seekable_stream_encoder->private_->seek_table.points[i].sample_number;
560 if(test_sample > current_sample) {
563 else if(test_sample == current_sample) {
564 seekable_stream_encoder->private_->seek_table.points[i].stream_offset = seekable_stream_encoder->private_->bytes_written - seekable_stream_encoder->private_->stream_offset;
565 seekable_stream_encoder->private_->seek_table.points[i].frame_samples = FLAC__stream_encoder_get_blocksize(encoder);
566 seekable_stream_encoder->private_->first_seek_point_to_check++;
570 seekable_stream_encoder->private_->first_seek_point_to_check++;
575 seekable_stream_encoder->private_->bytes_written += bytes;
576 seekable_stream_encoder->private_->samples_written += samples;
577 seekable_stream_encoder->private_->current_frame = current_frame;
579 if(samples && seekable_stream_encoder->private_->verbose && seekable_stream_encoder->private_->total_samples_to_encode > 0 && !(current_frame & mask))
580 print_stats(seekable_stream_encoder->private_);
582 if(seekable_stream_encoder->private_->verify) {
583 seekable_stream_encoder->private_->verify_fifo.encoded_signal = buffer;
584 seekable_stream_encoder->private_->verify_fifo.encoded_bytes = bytes;
585 if(seekable_stream_encoder->private_->verify_fifo.into_frames) {
586 if(!FLAC__stream_decoder_process_one_frame(seekable_stream_encoder->private_->verify_fifo.decoder)) {
587 seekable_stream_encoder->private_->verify_fifo.result = FLAC__VERIFY_FAILED_IN_FRAME;
588 return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR;
592 if(!FLAC__stream_decoder_process_metadata(seekable_stream_encoder->private_->verify_fifo.decoder)) {
593 seekable_stream_encoder->private_->verify_fifo.result = FLAC__VERIFY_FAILED_IN_METADATA;
594 return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR;
600 if(seekable_stream_encoder->private_->use_ogg) {
603 memset(&op, 0, sizeof(op));
604 op.packet = (unsigned char *)buffer;
605 op.granulepos = seekable_stream_encoder->private_->samples_written - 1;
607 * this depends on the behavior of libFLAC that we will get one
608 * write_callback first with all the metadata (and 'samples'
609 * will be 0), then one write_callback for each frame.
611 op.packetno = (samples == 0? -1 : (int)seekable_stream_encoder->private_->current_frame);
614 if (seekable_stream_encoder->private_->bytes_written == bytes)
617 if (seekable_stream_encoder->private_->total_samples_to_encode == seekable_stream_encoder->private_->samples_written)
620 ogg_stream_packetin(&seekable_stream_encoder->private_->ogg.os, &op);
622 while(ogg_stream_pageout(&seekable_stream_encoder->private_->ogg.os, &seekable_stream_encoder->private_->ogg.og) != 0) {
624 written = fwrite(seekable_stream_encoder->private_->ogg.og.header, 1, seekable_stream_encoder->private_->ogg.og.header_len, seekable_stream_encoder->private_->fout);
625 if (written != seekable_stream_encoder->private_->ogg.og.header_len)
626 return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR;
628 written = fwrite(seekable_stream_encoder->private_->ogg.og.body, 1, seekable_stream_encoder->private_->ogg.og.body_len, seekable_stream_encoder->private_->fout);
629 if (written != seekable_stream_encoder->private_->ogg.og.body_len)
630 return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR;
633 return FLAC__STREAM_ENCODER_WRITE_OK;
638 if(fwrite(buffer, sizeof(FLAC__byte), bytes, seekable_stream_encoder->private_->fout) == bytes)
639 return FLAC__STREAM_ENCODER_WRITE_OK;
641 return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR;
645 void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
647 seekable_stream_encoder->private_ *seekable_stream_encoder->private_ = (seekable_stream_encoder->private_ *)client_data;
649 FILE *f = seekable_stream_encoder->private_->fout;
650 const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
651 const unsigned min_framesize = metadata->data.stream_info.min_framesize;
652 const unsigned max_framesize = metadata->data.stream_info.max_framesize;
654 FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
657 * If we are writing to an ogg stream, there is no need to go back
658 * and update the STREAMINFO or SEEKTABLE blocks; the values we would
659 * update are not necessary with Ogg as the transport. We can't do
660 * it reliably anyway without knowing the Ogg structure.
663 if(seekable_stream_encoder->private_->use_ogg)
668 * we get called by the encoder when the encoding process has
669 * finished so that we can update the STREAMINFO and SEEKTABLE
673 (void)encoder; /* silence compiler warning about unused parameter */
676 fclose(seekable_stream_encoder->private_->fout);
677 if(0 == (f = fopen(seekable_stream_encoder->private_->outfilename, "r+b")))
681 /* all this is based on intimate knowledge of the stream header
682 * layout, but a change to the header format that would break this
683 * would also break all streams encoded in the previous format.
686 if(-1 == fseek(f, 26, SEEK_SET)) goto end_;
687 fwrite(metadata->data.stream_info.md5sum, 1, 16, f);
689 /* if we get this far we know we can seek so no need to check the
690 * return value from fseek()
692 fseek(f, 21, SEEK_SET);
693 if(fread(&b, 1, 1, f) != 1) goto framesize_;
694 fseek(f, 21, SEEK_SET);
695 b = (b & 0xf0) | (FLAC__byte)((samples >> 32) & 0x0F);
696 if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
697 b = (FLAC__byte)((samples >> 24) & 0xFF);
698 if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
699 b = (FLAC__byte)((samples >> 16) & 0xFF);
700 if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
701 b = (FLAC__byte)((samples >> 8) & 0xFF);
702 if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
703 b = (FLAC__byte)(samples & 0xFF);
704 if(fwrite(&b, 1, 1, f) != 1) goto framesize_;
707 fseek(f, 12, SEEK_SET);
708 b = (FLAC__byte)((min_framesize >> 16) & 0xFF);
709 if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
710 b = (FLAC__byte)((min_framesize >> 8) & 0xFF);
711 if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
712 b = (FLAC__byte)(min_framesize & 0xFF);
713 if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
714 b = (FLAC__byte)((max_framesize >> 16) & 0xFF);
715 if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
716 b = (FLAC__byte)((max_framesize >> 8) & 0xFF);
717 if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
718 b = (FLAC__byte)(max_framesize & 0xFF);
719 if(fwrite(&b, 1, 1, f) != 1) goto seektable_;
722 if(seekable_stream_encoder->private_->seek_table.num_points > 0) {
726 /* convert any unused seek points to placeholders */
727 for(i = 0; i < seekable_stream_encoder->private_->seek_table.num_points; i++) {
728 if(seekable_stream_encoder->private_->seek_table.points[i].sample_number == FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER)
730 else if(seekable_stream_encoder->private_->seek_table.points[i].frame_samples == 0)
731 seekable_stream_encoder->private_->seek_table.points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
734 /* the offset of the seek table data 'pos' should be after then stream sync and STREAMINFO block and SEEKTABLE header */
735 pos = (FLAC__STREAM_SYNC_LEN + FLAC__STREAM_METADATA_IS_LAST_LEN + FLAC__STREAM_METADATA_TYPE_LEN + FLAC__STREAM_METADATA_LENGTH_LEN) / 8;
736 pos += metadata->length;
737 pos += (FLAC__STREAM_METADATA_IS_LAST_LEN + FLAC__STREAM_METADATA_TYPE_LEN + FLAC__STREAM_METADATA_LENGTH_LEN) / 8;
738 fseek(f, pos, SEEK_SET);
739 for(i = 0; i < seekable_stream_encoder->private_->seek_table.num_points; i++) {
740 if(!write_big_endian_uint64(f, seekable_stream_encoder->private_->seek_table.points[i].sample_number)) goto end_;
741 if(!write_big_endian_uint64(f, seekable_stream_encoder->private_->seek_table.points[i].stream_offset)) goto end_;
742 if(!write_big_endian_uint16(f, (FLAC__uint16)seekable_stream_encoder->private_->seek_table.points[i].frame_samples)) goto end_;