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 calloc() */
22 #include <string.h> /* for memcpy() */
23 #include "FLAC/assert.h"
24 #include "protected/seekable_stream_encoder.h"
25 #include "protected/stream_encoder.h"
30 #define max(a,b) ((a)>(b)?(a):(b))
32 /***********************************************************************
34 * Private class method prototypes
36 ***********************************************************************/
38 /* unpublished debug routines */
39 extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
40 extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
41 extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
43 static void set_defaults_(FLAC__SeekableStreamEncoder *encoder);
44 static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
45 static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
47 /***********************************************************************
51 ***********************************************************************/
53 typedef struct FLAC__SeekableStreamEncoderPrivate {
54 FLAC__SeekableStreamEncoderSeekCallback seek_callback;
55 FLAC__SeekableStreamEncoderWriteCallback write_callback;
57 FLAC__StreamEncoder *stream_encoder;
58 FLAC__StreamMetadata_SeekTable *seek_table;
59 /* internal vars (all the above are class settings) */
60 unsigned first_seekpoint_to_check;
61 FLAC__uint64 stream_offset, seektable_offset;
62 FLAC__uint64 bytes_written;
63 } FLAC__SeekableStreamEncoderPrivate;
65 /***********************************************************************
67 * Public static class data
69 ***********************************************************************/
71 FLAC_API const char * const FLAC__SeekableStreamEncoderStateString[] = {
72 "FLAC__SEEKABLE_STREAM_ENCODER_OK",
73 "FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR",
74 "FLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR",
75 "FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR",
76 "FLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR",
77 "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR",
78 "FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED",
79 "FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK",
80 "FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE",
81 "FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED"
84 FLAC_API const char * const FLAC__SeekableStreamEncoderSeekStatusString[] = {
85 "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK",
86 "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR"
90 /***********************************************************************
92 * Class constructor/destructor
94 ***********************************************************************/
96 FLAC_API FLAC__SeekableStreamEncoder *FLAC__seekable_stream_encoder_new()
98 FLAC__SeekableStreamEncoder *encoder;
100 FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
102 encoder = (FLAC__SeekableStreamEncoder*)calloc(1, sizeof(FLAC__SeekableStreamEncoder));
107 encoder->protected_ = (FLAC__SeekableStreamEncoderProtected*)calloc(1, sizeof(FLAC__SeekableStreamEncoderProtected));
108 if(encoder->protected_ == 0) {
113 encoder->private_ = (FLAC__SeekableStreamEncoderPrivate*)calloc(1, sizeof(FLAC__SeekableStreamEncoderPrivate));
114 if(encoder->private_ == 0) {
115 free(encoder->protected_);
120 encoder->private_->stream_encoder = FLAC__stream_encoder_new();
121 if(0 == encoder->private_->stream_encoder) {
122 free(encoder->private_);
123 free(encoder->protected_);
128 set_defaults_(encoder);
130 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
135 FLAC_API void FLAC__seekable_stream_encoder_delete(FLAC__SeekableStreamEncoder *encoder)
137 FLAC__ASSERT(0 != encoder);
138 FLAC__ASSERT(0 != encoder->protected_);
139 FLAC__ASSERT(0 != encoder->private_);
140 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
142 (void)FLAC__seekable_stream_encoder_finish(encoder);
144 FLAC__stream_encoder_delete(encoder->private_->stream_encoder);
146 free(encoder->private_);
147 free(encoder->protected_);
152 /***********************************************************************
154 * Public class methods
156 ***********************************************************************/
158 FLAC_API FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_init(FLAC__SeekableStreamEncoder *encoder)
160 FLAC__ASSERT(0 != encoder);
162 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
163 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED;
165 if(0 == encoder->private_->seek_callback || 0 == encoder->private_->write_callback)
166 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK;
168 if(0 != encoder->private_->seek_table && !FLAC__format_seektable_is_legal(encoder->private_->seek_table))
169 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE;
172 * This must be done before we init the stream encoder because that
173 * calls the write_callback, which uses these values.
175 encoder->private_->first_seekpoint_to_check = 0;
176 encoder->private_->stream_offset = 0;
177 encoder->private_->seektable_offset = 0;
178 encoder->private_->bytes_written = 0;
180 FLAC__stream_encoder_set_write_callback(encoder->private_->stream_encoder, write_callback_);
181 FLAC__stream_encoder_set_metadata_callback(encoder->private_->stream_encoder, metadata_callback_);
182 FLAC__stream_encoder_set_client_data(encoder->private_->stream_encoder, encoder);
184 if(FLAC__stream_encoder_init(encoder->private_->stream_encoder) != FLAC__STREAM_ENCODER_OK)
185 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
188 * Initializing the stream encoder writes all the metadata, so we
189 * save the stream offset now.
191 encoder->private_->stream_offset = encoder->private_->bytes_written;
193 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_OK;
196 FLAC_API void FLAC__seekable_stream_encoder_finish(FLAC__SeekableStreamEncoder *encoder)
198 FLAC__ASSERT(0 != encoder);
199 FLAC__ASSERT(0 != encoder->private_);
200 FLAC__ASSERT(0 != encoder->protected_);
202 if(encoder->protected_->state == FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
205 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
207 FLAC__stream_encoder_finish(encoder->private_->stream_encoder);
209 set_defaults_(encoder);
211 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
214 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_verify(FLAC__SeekableStreamEncoder *encoder, FLAC__bool 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_verify(encoder->private_->stream_encoder, value);
225 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_streamable_subset(FLAC__SeekableStreamEncoder *encoder, FLAC__bool 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_streamable_subset(encoder->private_->stream_encoder, value);
236 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool 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_do_mid_side_stereo(encoder->private_->stream_encoder, value);
247 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool 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_loose_mid_side_stereo(encoder->private_->stream_encoder, value);
258 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_channels(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_channels(encoder->private_->stream_encoder, value);
269 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_bits_per_sample(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_bits_per_sample(encoder->private_->stream_encoder, value);
280 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_sample_rate(FLAC__SeekableStreamEncoder *encoder, unsigned 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_sample_rate(encoder->private_->stream_encoder, value);
291 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_blocksize(FLAC__SeekableStreamEncoder *encoder, unsigned 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_blocksize(encoder->private_->stream_encoder, value);
302 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_lpc_order(FLAC__SeekableStreamEncoder *encoder, unsigned 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_max_lpc_order(encoder->private_->stream_encoder, value);
313 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_qlp_coeff_precision(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_qlp_coeff_precision(encoder->private_->stream_encoder, value);
324 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool 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_do_qlp_coeff_prec_search(encoder->private_->stream_encoder, value);
335 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_escape_coding(FLAC__SeekableStreamEncoder *encoder, FLAC__bool 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_do_escape_coding(encoder->private_->stream_encoder, value);
346 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool 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_do_exhaustive_model_search(encoder->private_->stream_encoder, value);
357 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_min_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
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_min_residual_partition_order(encoder->private_->stream_encoder, value);
368 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
370 FLAC__ASSERT(0 != encoder);
371 FLAC__ASSERT(0 != encoder->private_);
372 FLAC__ASSERT(0 != encoder->protected_);
373 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
374 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
376 return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->stream_encoder, value);
379 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(FLAC__SeekableStreamEncoder *encoder, unsigned value)
381 FLAC__ASSERT(0 != encoder);
382 FLAC__ASSERT(0 != encoder->private_);
383 FLAC__ASSERT(0 != encoder->protected_);
384 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
385 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
387 return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->stream_encoder, value);
390 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_total_samples_estimate(FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 value)
392 FLAC__ASSERT(0 != encoder);
393 FLAC__ASSERT(0 != encoder->private_);
394 FLAC__ASSERT(0 != encoder->protected_);
395 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
396 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
398 return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->stream_encoder, value);
401 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_metadata(FLAC__SeekableStreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
403 FLAC__ASSERT(0 != encoder);
404 FLAC__ASSERT(0 != encoder->private_);
405 FLAC__ASSERT(0 != encoder->protected_);
406 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
407 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
409 if(0 != metadata && num_blocks > 0) {
411 for(i = 0; i < num_blocks; i++) {
412 if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) {
413 encoder->private_->seek_table = &metadata[i]->data.seek_table;
414 break; /* take only the first one */
418 return FLAC__stream_encoder_set_metadata(encoder->private_->stream_encoder, metadata, num_blocks);
421 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_seek_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderSeekCallback value)
423 FLAC__ASSERT(0 != encoder);
424 FLAC__ASSERT(0 != encoder->private_);
425 FLAC__ASSERT(0 != encoder->protected_);
426 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
428 encoder->private_->seek_callback = value;
432 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_write_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderWriteCallback value)
434 FLAC__ASSERT(0 != encoder);
435 FLAC__ASSERT(0 != encoder->private_);
436 FLAC__ASSERT(0 != encoder->protected_);
437 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
439 encoder->private_->write_callback = value;
443 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_client_data(FLAC__SeekableStreamEncoder *encoder, void *value)
445 FLAC__ASSERT(0 != encoder);
446 FLAC__ASSERT(0 != encoder->private_);
447 FLAC__ASSERT(0 != encoder->protected_);
448 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
450 encoder->private_->client_data = value;
455 * These three functions are not static, but not publically exposed in
456 * include/FLAC/ either. They are used by the test suite.
458 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_constant_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
460 FLAC__ASSERT(0 != encoder);
461 FLAC__ASSERT(0 != encoder->private_);
462 FLAC__ASSERT(0 != encoder->protected_);
463 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
465 return FLAC__stream_encoder_disable_constant_subframes(encoder->private_->stream_encoder, value);
468 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_fixed_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
470 FLAC__ASSERT(0 != encoder);
471 FLAC__ASSERT(0 != encoder->private_);
472 FLAC__ASSERT(0 != encoder->protected_);
473 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
475 return FLAC__stream_encoder_disable_fixed_subframes(encoder->private_->stream_encoder, value);
478 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_verbatim_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
480 FLAC__ASSERT(0 != encoder);
481 FLAC__ASSERT(0 != encoder->private_);
482 FLAC__ASSERT(0 != encoder->protected_);
483 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
485 return FLAC__stream_encoder_disable_verbatim_subframes(encoder->private_->stream_encoder, value);
488 FLAC_API FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_get_state(const FLAC__SeekableStreamEncoder *encoder)
490 FLAC__ASSERT(0 != encoder);
491 FLAC__ASSERT(0 != encoder->protected_);
492 return encoder->protected_->state;
495 FLAC_API FLAC__StreamEncoderState FLAC__seekable_stream_encoder_get_stream_encoder_state(const FLAC__SeekableStreamEncoder *encoder)
497 FLAC__ASSERT(0 != encoder);
498 FLAC__ASSERT(0 != encoder->private_);
499 return FLAC__stream_encoder_get_state(encoder->private_->stream_encoder);
502 FLAC_API FLAC__StreamDecoderState FLAC__seekable_stream_encoder_get_verify_decoder_state(const FLAC__SeekableStreamEncoder *encoder)
504 FLAC__ASSERT(0 != encoder);
505 FLAC__ASSERT(0 != encoder->private_);
506 return FLAC__stream_encoder_get_verify_decoder_state(encoder->private_->stream_encoder);
509 FLAC_API void FLAC__seekable_stream_encoder_get_verify_decoder_error_stats(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
511 FLAC__ASSERT(0 != encoder);
512 FLAC__ASSERT(0 != encoder->private_);
513 FLAC__stream_encoder_get_verify_decoder_error_stats(encoder->private_->stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
516 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_verify(const FLAC__SeekableStreamEncoder *encoder)
518 FLAC__ASSERT(0 != encoder);
519 FLAC__ASSERT(0 != encoder->private_);
520 return FLAC__stream_encoder_get_verify(encoder->private_->stream_encoder);
523 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_streamable_subset(const FLAC__SeekableStreamEncoder *encoder)
525 FLAC__ASSERT(0 != encoder);
526 FLAC__ASSERT(0 != encoder->private_);
527 return FLAC__stream_encoder_get_streamable_subset(encoder->private_->stream_encoder);
530 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder)
532 FLAC__ASSERT(0 != encoder);
533 FLAC__ASSERT(0 != encoder->private_);
534 return FLAC__stream_encoder_get_do_mid_side_stereo(encoder->private_->stream_encoder);
537 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder)
539 FLAC__ASSERT(0 != encoder);
540 FLAC__ASSERT(0 != encoder->private_);
541 return FLAC__stream_encoder_get_loose_mid_side_stereo(encoder->private_->stream_encoder);
544 FLAC_API unsigned FLAC__seekable_stream_encoder_get_channels(const FLAC__SeekableStreamEncoder *encoder)
546 FLAC__ASSERT(0 != encoder);
547 FLAC__ASSERT(0 != encoder->private_);
548 return FLAC__stream_encoder_get_channels(encoder->private_->stream_encoder);
551 FLAC_API unsigned FLAC__seekable_stream_encoder_get_bits_per_sample(const FLAC__SeekableStreamEncoder *encoder)
553 FLAC__ASSERT(0 != encoder);
554 FLAC__ASSERT(0 != encoder->private_);
555 return FLAC__stream_encoder_get_bits_per_sample(encoder->private_->stream_encoder);
558 FLAC_API unsigned FLAC__seekable_stream_encoder_get_sample_rate(const FLAC__SeekableStreamEncoder *encoder)
560 FLAC__ASSERT(0 != encoder);
561 FLAC__ASSERT(0 != encoder->private_);
562 return FLAC__stream_encoder_get_sample_rate(encoder->private_->stream_encoder);
565 FLAC_API unsigned FLAC__seekable_stream_encoder_get_blocksize(const FLAC__SeekableStreamEncoder *encoder)
567 FLAC__ASSERT(0 != encoder);
568 FLAC__ASSERT(0 != encoder->private_);
569 return FLAC__stream_encoder_get_blocksize(encoder->private_->stream_encoder);
572 FLAC_API unsigned FLAC__seekable_stream_encoder_get_max_lpc_order(const FLAC__SeekableStreamEncoder *encoder)
574 FLAC__ASSERT(0 != encoder);
575 FLAC__ASSERT(0 != encoder->private_);
576 return FLAC__stream_encoder_get_max_lpc_order(encoder->private_->stream_encoder);
579 FLAC_API unsigned FLAC__seekable_stream_encoder_get_qlp_coeff_precision(const FLAC__SeekableStreamEncoder *encoder)
581 FLAC__ASSERT(0 != encoder);
582 FLAC__ASSERT(0 != encoder->private_);
583 return FLAC__stream_encoder_get_qlp_coeff_precision(encoder->private_->stream_encoder);
586 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__SeekableStreamEncoder *encoder)
588 FLAC__ASSERT(0 != encoder);
589 FLAC__ASSERT(0 != encoder->private_);
590 return FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->stream_encoder);
593 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_escape_coding(const FLAC__SeekableStreamEncoder *encoder)
595 FLAC__ASSERT(0 != encoder);
596 FLAC__ASSERT(0 != encoder->private_);
597 return FLAC__stream_encoder_get_do_escape_coding(encoder->private_->stream_encoder);
600 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(const FLAC__SeekableStreamEncoder *encoder)
602 FLAC__ASSERT(0 != encoder);
603 FLAC__ASSERT(0 != encoder->private_);
604 return FLAC__stream_encoder_get_do_exhaustive_model_search(encoder->private_->stream_encoder);
607 FLAC_API unsigned FLAC__seekable_stream_encoder_get_min_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder)
609 FLAC__ASSERT(0 != encoder);
610 FLAC__ASSERT(0 != encoder->private_);
611 return FLAC__stream_encoder_get_min_residual_partition_order(encoder->private_->stream_encoder);
614 FLAC_API unsigned FLAC__seekable_stream_encoder_get_max_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder)
616 FLAC__ASSERT(0 != encoder);
617 FLAC__ASSERT(0 != encoder->private_);
618 return FLAC__stream_encoder_get_max_residual_partition_order(encoder->private_->stream_encoder);
621 FLAC_API unsigned FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(const FLAC__SeekableStreamEncoder *encoder)
623 FLAC__ASSERT(0 != encoder);
624 FLAC__ASSERT(0 != encoder->private_);
625 return FLAC__stream_encoder_get_rice_parameter_search_dist(encoder->private_->stream_encoder);
628 FLAC_API FLAC__uint64 FLAC__seekable_stream_encoder_get_total_samples_estimate(const FLAC__SeekableStreamEncoder *encoder)
630 FLAC__ASSERT(0 != encoder);
631 FLAC__ASSERT(0 != encoder->private_);
632 return FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->stream_encoder);
635 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_process(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
637 FLAC__ASSERT(0 != encoder);
638 FLAC__ASSERT(0 != encoder->private_);
639 if(!FLAC__stream_encoder_process(encoder->private_->stream_encoder, buffer, samples)) {
640 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
647 /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
648 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_process_interleaved(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
650 FLAC__ASSERT(0 != encoder);
651 FLAC__ASSERT(0 != encoder->private_);
652 if(!FLAC__stream_encoder_process_interleaved(encoder->private_->stream_encoder, buffer, samples)) {
653 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
660 /***********************************************************************
662 * Private class methods
664 ***********************************************************************/
666 void set_defaults_(FLAC__SeekableStreamEncoder *encoder)
668 FLAC__ASSERT(0 != encoder);
669 FLAC__ASSERT(0 != encoder->private_);
670 FLAC__ASSERT(0 != encoder->protected_);
672 encoder->private_->seek_callback = 0;
673 encoder->private_->write_callback = 0;
674 encoder->private_->client_data = 0;
676 encoder->private_->seek_table = 0;
679 FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
681 FLAC__SeekableStreamEncoder *seekable_stream_encoder = (FLAC__SeekableStreamEncoder*)client_data;
682 FLAC__StreamEncoderWriteStatus status;
685 * Watch for the first SEEKTABLE block to go by and store its offset.
687 if(samples == 0 && (buffer[0] & 0x7f) == FLAC__METADATA_TYPE_SEEKTABLE)
688 seekable_stream_encoder->private_->seektable_offset = seekable_stream_encoder->private_->bytes_written;
691 * Mark the current seek point if hit (if stream_offset == 0 that
692 * means we're still writing metadata and haven't hit the first
695 if(0 != seekable_stream_encoder->private_->seek_table && seekable_stream_encoder->private_->stream_offset > 0 && seekable_stream_encoder->private_->seek_table->num_points > 0) {
696 /*@@@ WATCHOUT: assumes the encoder is fixed-blocksize, which will be true indefinitely: */
697 const unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder);
698 const FLAC__uint64 frame_first_sample = (FLAC__uint64)current_frame * (FLAC__uint64)blocksize;
699 const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1;
700 FLAC__uint64 test_sample;
702 for(i = seekable_stream_encoder->private_->first_seekpoint_to_check; i < seekable_stream_encoder->private_->seek_table->num_points; i++) {
703 test_sample = seekable_stream_encoder->private_->seek_table->points[i].sample_number;
704 if(test_sample > frame_last_sample) {
707 else if(test_sample >= frame_first_sample) {
708 seekable_stream_encoder->private_->seek_table->points[i].sample_number = frame_first_sample;
709 seekable_stream_encoder->private_->seek_table->points[i].stream_offset = seekable_stream_encoder->private_->bytes_written - seekable_stream_encoder->private_->stream_offset;
710 seekable_stream_encoder->private_->seek_table->points[i].frame_samples = blocksize;
711 seekable_stream_encoder->private_->first_seekpoint_to_check++;
712 /* DO NOT: "break;" and here's why:
713 * The seektable template may contain more than one target
714 * sample for any given frame; we will keep looping, generating
715 * duplicate seekpoints for them, and we'll clean it up later,
716 * just before writing the seektable back to the metadata.
720 seekable_stream_encoder->private_->first_seekpoint_to_check++;
725 status = seekable_stream_encoder->private_->write_callback(seekable_stream_encoder, buffer, bytes, samples, current_frame, seekable_stream_encoder->private_->client_data);
727 if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
728 seekable_stream_encoder->private_->bytes_written += bytes;
730 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
735 void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
737 FLAC__SeekableStreamEncoder *seekable_stream_encoder = (FLAC__SeekableStreamEncoder*)client_data;
738 FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
739 const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
740 const unsigned min_framesize = metadata->data.stream_info.min_framesize;
741 const unsigned max_framesize = metadata->data.stream_info.max_framesize;
742 const unsigned bps = metadata->data.stream_info.bits_per_sample;
744 FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
746 /* We get called by the stream encoder when the encoding process
747 * has finished so that we can update the STREAMINFO and SEEKTABLE
751 (void)encoder; /* silence compiler warning about unused parameter */
753 /*@@@ reopen callback here? The docs currently require user to open files in update mode from the start */
755 /* All this is based on intimate knowledge of the stream header
756 * layout, but a change to the header format that would break this
757 * would also break all streams encoded in the previous format.
761 * Write MD5 signature
763 if(seekable_stream_encoder->private_->seek_callback(seekable_stream_encoder, 26, seekable_stream_encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
764 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
767 if(seekable_stream_encoder->private_->write_callback(seekable_stream_encoder, metadata->data.stream_info.md5sum, 16, 0, 0, seekable_stream_encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
768 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
773 * Write total samples
775 b[0] = ((FLAC__byte)(bps-1) << 4) | (FLAC__byte)((samples >> 32) & 0x0F);
776 b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
777 b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
778 b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
779 b[4] = (FLAC__byte)(samples & 0xFF);
780 if(seekable_stream_encoder->private_->seek_callback(seekable_stream_encoder, 21, seekable_stream_encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
781 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
784 if(seekable_stream_encoder->private_->write_callback(seekable_stream_encoder, b, 5, 0, 0, seekable_stream_encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
785 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
790 * Write min/max framesize
792 b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
793 b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
794 b[2] = (FLAC__byte)(min_framesize & 0xFF);
795 b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
796 b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
797 b[5] = (FLAC__byte)(max_framesize & 0xFF);
798 if(seekable_stream_encoder->private_->seek_callback(seekable_stream_encoder, 12, seekable_stream_encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
799 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
802 if(seekable_stream_encoder->private_->write_callback(seekable_stream_encoder, b, 6, 0, 0, seekable_stream_encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
803 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
810 if(0 != seekable_stream_encoder->private_->seek_table && seekable_stream_encoder->private_->seek_table->num_points > 0 && seekable_stream_encoder->private_->seektable_offset > 0) {
813 FLAC__format_seektable_sort(seekable_stream_encoder->private_->seek_table);
815 FLAC__ASSERT(FLAC__format_seektable_is_legal(seekable_stream_encoder->private_->seek_table));
817 if(seekable_stream_encoder->private_->seek_callback(seekable_stream_encoder, seekable_stream_encoder->private_->seektable_offset + FLAC__STREAM_METADATA_HEADER_LENGTH, seekable_stream_encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
818 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
822 for(i = 0; i < seekable_stream_encoder->private_->seek_table->num_points; i++) {
825 xx = seekable_stream_encoder->private_->seek_table->points[i].sample_number;
826 b[7] = (FLAC__byte)xx; xx >>= 8;
827 b[6] = (FLAC__byte)xx; xx >>= 8;
828 b[5] = (FLAC__byte)xx; xx >>= 8;
829 b[4] = (FLAC__byte)xx; xx >>= 8;
830 b[3] = (FLAC__byte)xx; xx >>= 8;
831 b[2] = (FLAC__byte)xx; xx >>= 8;
832 b[1] = (FLAC__byte)xx; xx >>= 8;
833 b[0] = (FLAC__byte)xx; xx >>= 8;
834 xx = seekable_stream_encoder->private_->seek_table->points[i].stream_offset;
835 b[15] = (FLAC__byte)xx; xx >>= 8;
836 b[14] = (FLAC__byte)xx; xx >>= 8;
837 b[13] = (FLAC__byte)xx; xx >>= 8;
838 b[12] = (FLAC__byte)xx; xx >>= 8;
839 b[11] = (FLAC__byte)xx; xx >>= 8;
840 b[10] = (FLAC__byte)xx; xx >>= 8;
841 b[9] = (FLAC__byte)xx; xx >>= 8;
842 b[8] = (FLAC__byte)xx; xx >>= 8;
843 x = seekable_stream_encoder->private_->seek_table->points[i].frame_samples;
844 b[17] = (FLAC__byte)x; x >>= 8;
845 b[16] = (FLAC__byte)x; x >>= 8;
846 if(seekable_stream_encoder->private_->write_callback(seekable_stream_encoder, b, 18, 0, 0, seekable_stream_encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
847 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;