1 /* libFLAC - Free Lossless Audio Codec library
2 * Copyright (C) 2002,2003 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__uint64 samples_written;
64 } FLAC__SeekableStreamEncoderPrivate;
66 /***********************************************************************
68 * Public static class data
70 ***********************************************************************/
72 FLAC_API const char * const FLAC__SeekableStreamEncoderStateString[] = {
73 "FLAC__SEEKABLE_STREAM_ENCODER_OK",
74 "FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR",
75 "FLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR",
76 "FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR",
77 "FLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR",
78 "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR",
79 "FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED",
80 "FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK",
81 "FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE",
82 "FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED"
85 FLAC_API const char * const FLAC__SeekableStreamEncoderSeekStatusString[] = {
86 "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK",
87 "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR"
91 /***********************************************************************
93 * Class constructor/destructor
95 ***********************************************************************/
97 FLAC_API FLAC__SeekableStreamEncoder *FLAC__seekable_stream_encoder_new()
99 FLAC__SeekableStreamEncoder *encoder;
101 FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
103 encoder = (FLAC__SeekableStreamEncoder*)calloc(1, sizeof(FLAC__SeekableStreamEncoder));
108 encoder->protected_ = (FLAC__SeekableStreamEncoderProtected*)calloc(1, sizeof(FLAC__SeekableStreamEncoderProtected));
109 if(encoder->protected_ == 0) {
114 encoder->private_ = (FLAC__SeekableStreamEncoderPrivate*)calloc(1, sizeof(FLAC__SeekableStreamEncoderPrivate));
115 if(encoder->private_ == 0) {
116 free(encoder->protected_);
121 encoder->private_->stream_encoder = FLAC__stream_encoder_new();
122 if(0 == encoder->private_->stream_encoder) {
123 free(encoder->private_);
124 free(encoder->protected_);
129 set_defaults_(encoder);
131 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
136 FLAC_API void FLAC__seekable_stream_encoder_delete(FLAC__SeekableStreamEncoder *encoder)
138 FLAC__ASSERT(0 != encoder);
139 FLAC__ASSERT(0 != encoder->protected_);
140 FLAC__ASSERT(0 != encoder->private_);
141 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
143 (void)FLAC__seekable_stream_encoder_finish(encoder);
145 FLAC__stream_encoder_delete(encoder->private_->stream_encoder);
147 free(encoder->private_);
148 free(encoder->protected_);
153 /***********************************************************************
155 * Public class methods
157 ***********************************************************************/
159 FLAC_API FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_init(FLAC__SeekableStreamEncoder *encoder)
161 FLAC__ASSERT(0 != encoder);
163 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
164 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED;
166 if(0 == encoder->private_->seek_callback || 0 == encoder->private_->write_callback)
167 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK;
169 if(0 != encoder->private_->seek_table && !FLAC__format_seektable_is_legal(encoder->private_->seek_table))
170 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE;
173 * This must be done before we init the stream encoder because that
174 * calls the write_callback, which uses these values.
176 encoder->private_->first_seekpoint_to_check = 0;
177 encoder->private_->stream_offset = 0;
178 encoder->private_->seektable_offset = 0;
179 encoder->private_->bytes_written = 0;
180 encoder->private_->samples_written = 0;
182 FLAC__stream_encoder_set_write_callback(encoder->private_->stream_encoder, write_callback_);
183 FLAC__stream_encoder_set_metadata_callback(encoder->private_->stream_encoder, metadata_callback_);
184 FLAC__stream_encoder_set_client_data(encoder->private_->stream_encoder, encoder);
186 if(FLAC__stream_encoder_init(encoder->private_->stream_encoder) != FLAC__STREAM_ENCODER_OK)
187 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
190 * Initializing the stream encoder writes all the metadata, so we
191 * save the stream offset now.
193 encoder->private_->stream_offset = encoder->private_->bytes_written;
195 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_OK;
198 FLAC_API void FLAC__seekable_stream_encoder_finish(FLAC__SeekableStreamEncoder *encoder)
200 FLAC__ASSERT(0 != encoder);
201 FLAC__ASSERT(0 != encoder->private_);
202 FLAC__ASSERT(0 != encoder->protected_);
204 if(encoder->protected_->state == FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
207 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
209 FLAC__stream_encoder_finish(encoder->private_->stream_encoder);
211 set_defaults_(encoder);
213 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
216 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_verify(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
218 FLAC__ASSERT(0 != encoder);
219 FLAC__ASSERT(0 != encoder->private_);
220 FLAC__ASSERT(0 != encoder->protected_);
221 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
222 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
224 return FLAC__stream_encoder_set_verify(encoder->private_->stream_encoder, value);
227 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_streamable_subset(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
229 FLAC__ASSERT(0 != encoder);
230 FLAC__ASSERT(0 != encoder->private_);
231 FLAC__ASSERT(0 != encoder->protected_);
232 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
233 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
235 return FLAC__stream_encoder_set_streamable_subset(encoder->private_->stream_encoder, value);
238 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
240 FLAC__ASSERT(0 != encoder);
241 FLAC__ASSERT(0 != encoder->private_);
242 FLAC__ASSERT(0 != encoder->protected_);
243 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
244 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
246 return FLAC__stream_encoder_set_do_mid_side_stereo(encoder->private_->stream_encoder, value);
249 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
251 FLAC__ASSERT(0 != encoder);
252 FLAC__ASSERT(0 != encoder->private_);
253 FLAC__ASSERT(0 != encoder->protected_);
254 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
255 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
257 return FLAC__stream_encoder_set_loose_mid_side_stereo(encoder->private_->stream_encoder, value);
260 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_channels(FLAC__SeekableStreamEncoder *encoder, unsigned value)
262 FLAC__ASSERT(0 != encoder);
263 FLAC__ASSERT(0 != encoder->private_);
264 FLAC__ASSERT(0 != encoder->protected_);
265 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
266 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
268 return FLAC__stream_encoder_set_channels(encoder->private_->stream_encoder, value);
271 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_bits_per_sample(FLAC__SeekableStreamEncoder *encoder, unsigned value)
273 FLAC__ASSERT(0 != encoder);
274 FLAC__ASSERT(0 != encoder->private_);
275 FLAC__ASSERT(0 != encoder->protected_);
276 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
277 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
279 return FLAC__stream_encoder_set_bits_per_sample(encoder->private_->stream_encoder, value);
282 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_sample_rate(FLAC__SeekableStreamEncoder *encoder, unsigned value)
284 FLAC__ASSERT(0 != encoder);
285 FLAC__ASSERT(0 != encoder->private_);
286 FLAC__ASSERT(0 != encoder->protected_);
287 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
288 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
290 return FLAC__stream_encoder_set_sample_rate(encoder->private_->stream_encoder, value);
293 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_blocksize(FLAC__SeekableStreamEncoder *encoder, unsigned value)
295 FLAC__ASSERT(0 != encoder);
296 FLAC__ASSERT(0 != encoder->private_);
297 FLAC__ASSERT(0 != encoder->protected_);
298 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
299 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
301 return FLAC__stream_encoder_set_blocksize(encoder->private_->stream_encoder, value);
304 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_lpc_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
306 FLAC__ASSERT(0 != encoder);
307 FLAC__ASSERT(0 != encoder->private_);
308 FLAC__ASSERT(0 != encoder->protected_);
309 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
310 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
312 return FLAC__stream_encoder_set_max_lpc_order(encoder->private_->stream_encoder, value);
315 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_qlp_coeff_precision(FLAC__SeekableStreamEncoder *encoder, unsigned value)
317 FLAC__ASSERT(0 != encoder);
318 FLAC__ASSERT(0 != encoder->private_);
319 FLAC__ASSERT(0 != encoder->protected_);
320 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
321 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
323 return FLAC__stream_encoder_set_qlp_coeff_precision(encoder->private_->stream_encoder, value);
326 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
328 FLAC__ASSERT(0 != encoder);
329 FLAC__ASSERT(0 != encoder->private_);
330 FLAC__ASSERT(0 != encoder->protected_);
331 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
332 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
334 return FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->stream_encoder, value);
337 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_escape_coding(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
339 FLAC__ASSERT(0 != encoder);
340 FLAC__ASSERT(0 != encoder->private_);
341 FLAC__ASSERT(0 != encoder->protected_);
342 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
343 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
345 return FLAC__stream_encoder_set_do_escape_coding(encoder->private_->stream_encoder, value);
348 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
350 FLAC__ASSERT(0 != encoder);
351 FLAC__ASSERT(0 != encoder->private_);
352 FLAC__ASSERT(0 != encoder->protected_);
353 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
354 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
356 return FLAC__stream_encoder_set_do_exhaustive_model_search(encoder->private_->stream_encoder, value);
359 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_min_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
361 FLAC__ASSERT(0 != encoder);
362 FLAC__ASSERT(0 != encoder->private_);
363 FLAC__ASSERT(0 != encoder->protected_);
364 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
365 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
367 return FLAC__stream_encoder_set_min_residual_partition_order(encoder->private_->stream_encoder, value);
370 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
372 FLAC__ASSERT(0 != encoder);
373 FLAC__ASSERT(0 != encoder->private_);
374 FLAC__ASSERT(0 != encoder->protected_);
375 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
376 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
378 return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->stream_encoder, value);
381 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(FLAC__SeekableStreamEncoder *encoder, unsigned value)
383 FLAC__ASSERT(0 != encoder);
384 FLAC__ASSERT(0 != encoder->private_);
385 FLAC__ASSERT(0 != encoder->protected_);
386 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
387 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
389 return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->stream_encoder, value);
392 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_total_samples_estimate(FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 value)
394 FLAC__ASSERT(0 != encoder);
395 FLAC__ASSERT(0 != encoder->private_);
396 FLAC__ASSERT(0 != encoder->protected_);
397 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
398 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
400 return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->stream_encoder, value);
403 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_metadata(FLAC__SeekableStreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
405 FLAC__ASSERT(0 != encoder);
406 FLAC__ASSERT(0 != encoder->private_);
407 FLAC__ASSERT(0 != encoder->protected_);
408 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
409 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
411 if(0 != metadata && num_blocks > 0) {
413 for(i = 0; i < num_blocks; i++) {
414 if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) {
415 encoder->private_->seek_table = &metadata[i]->data.seek_table;
416 break; /* take only the first one */
420 return FLAC__stream_encoder_set_metadata(encoder->private_->stream_encoder, metadata, num_blocks);
423 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_seek_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderSeekCallback value)
425 FLAC__ASSERT(0 != encoder);
426 FLAC__ASSERT(0 != encoder->private_);
427 FLAC__ASSERT(0 != encoder->protected_);
428 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
430 encoder->private_->seek_callback = value;
434 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_write_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderWriteCallback value)
436 FLAC__ASSERT(0 != encoder);
437 FLAC__ASSERT(0 != encoder->private_);
438 FLAC__ASSERT(0 != encoder->protected_);
439 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
441 encoder->private_->write_callback = value;
445 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_client_data(FLAC__SeekableStreamEncoder *encoder, void *value)
447 FLAC__ASSERT(0 != encoder);
448 FLAC__ASSERT(0 != encoder->private_);
449 FLAC__ASSERT(0 != encoder->protected_);
450 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
452 encoder->private_->client_data = value;
457 * These three functions are not static, but not publically exposed in
458 * include/FLAC/ either. They are used by the test suite.
460 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_constant_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
462 FLAC__ASSERT(0 != encoder);
463 FLAC__ASSERT(0 != encoder->private_);
464 FLAC__ASSERT(0 != encoder->protected_);
465 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
467 return FLAC__stream_encoder_disable_constant_subframes(encoder->private_->stream_encoder, value);
470 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_fixed_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
472 FLAC__ASSERT(0 != encoder);
473 FLAC__ASSERT(0 != encoder->private_);
474 FLAC__ASSERT(0 != encoder->protected_);
475 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
477 return FLAC__stream_encoder_disable_fixed_subframes(encoder->private_->stream_encoder, value);
480 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_verbatim_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
482 FLAC__ASSERT(0 != encoder);
483 FLAC__ASSERT(0 != encoder->private_);
484 FLAC__ASSERT(0 != encoder->protected_);
485 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
487 return FLAC__stream_encoder_disable_verbatim_subframes(encoder->private_->stream_encoder, value);
490 FLAC_API FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_get_state(const FLAC__SeekableStreamEncoder *encoder)
492 FLAC__ASSERT(0 != encoder);
493 FLAC__ASSERT(0 != encoder->protected_);
494 return encoder->protected_->state;
497 FLAC_API FLAC__StreamEncoderState FLAC__seekable_stream_encoder_get_stream_encoder_state(const FLAC__SeekableStreamEncoder *encoder)
499 FLAC__ASSERT(0 != encoder);
500 FLAC__ASSERT(0 != encoder->private_);
501 return FLAC__stream_encoder_get_state(encoder->private_->stream_encoder);
504 FLAC_API FLAC__StreamDecoderState FLAC__seekable_stream_encoder_get_verify_decoder_state(const FLAC__SeekableStreamEncoder *encoder)
506 FLAC__ASSERT(0 != encoder);
507 FLAC__ASSERT(0 != encoder->private_);
508 return FLAC__stream_encoder_get_verify_decoder_state(encoder->private_->stream_encoder);
511 FLAC_API const char *FLAC__seekable_stream_encoder_get_resolved_state_string(const FLAC__SeekableStreamEncoder *encoder)
513 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR)
514 return FLAC__SeekableStreamEncoderStateString[encoder->protected_->state];
516 return FLAC__stream_encoder_get_resolved_state_string(encoder->private_->stream_encoder);
519 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)
521 FLAC__ASSERT(0 != encoder);
522 FLAC__ASSERT(0 != encoder->private_);
523 FLAC__stream_encoder_get_verify_decoder_error_stats(encoder->private_->stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
526 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_verify(const FLAC__SeekableStreamEncoder *encoder)
528 FLAC__ASSERT(0 != encoder);
529 FLAC__ASSERT(0 != encoder->private_);
530 return FLAC__stream_encoder_get_verify(encoder->private_->stream_encoder);
533 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_streamable_subset(const FLAC__SeekableStreamEncoder *encoder)
535 FLAC__ASSERT(0 != encoder);
536 FLAC__ASSERT(0 != encoder->private_);
537 return FLAC__stream_encoder_get_streamable_subset(encoder->private_->stream_encoder);
540 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder)
542 FLAC__ASSERT(0 != encoder);
543 FLAC__ASSERT(0 != encoder->private_);
544 return FLAC__stream_encoder_get_do_mid_side_stereo(encoder->private_->stream_encoder);
547 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder)
549 FLAC__ASSERT(0 != encoder);
550 FLAC__ASSERT(0 != encoder->private_);
551 return FLAC__stream_encoder_get_loose_mid_side_stereo(encoder->private_->stream_encoder);
554 FLAC_API unsigned FLAC__seekable_stream_encoder_get_channels(const FLAC__SeekableStreamEncoder *encoder)
556 FLAC__ASSERT(0 != encoder);
557 FLAC__ASSERT(0 != encoder->private_);
558 return FLAC__stream_encoder_get_channels(encoder->private_->stream_encoder);
561 FLAC_API unsigned FLAC__seekable_stream_encoder_get_bits_per_sample(const FLAC__SeekableStreamEncoder *encoder)
563 FLAC__ASSERT(0 != encoder);
564 FLAC__ASSERT(0 != encoder->private_);
565 return FLAC__stream_encoder_get_bits_per_sample(encoder->private_->stream_encoder);
568 FLAC_API unsigned FLAC__seekable_stream_encoder_get_sample_rate(const FLAC__SeekableStreamEncoder *encoder)
570 FLAC__ASSERT(0 != encoder);
571 FLAC__ASSERT(0 != encoder->private_);
572 return FLAC__stream_encoder_get_sample_rate(encoder->private_->stream_encoder);
575 FLAC_API unsigned FLAC__seekable_stream_encoder_get_blocksize(const FLAC__SeekableStreamEncoder *encoder)
577 FLAC__ASSERT(0 != encoder);
578 FLAC__ASSERT(0 != encoder->private_);
579 return FLAC__stream_encoder_get_blocksize(encoder->private_->stream_encoder);
582 FLAC_API unsigned FLAC__seekable_stream_encoder_get_max_lpc_order(const FLAC__SeekableStreamEncoder *encoder)
584 FLAC__ASSERT(0 != encoder);
585 FLAC__ASSERT(0 != encoder->private_);
586 return FLAC__stream_encoder_get_max_lpc_order(encoder->private_->stream_encoder);
589 FLAC_API unsigned FLAC__seekable_stream_encoder_get_qlp_coeff_precision(const FLAC__SeekableStreamEncoder *encoder)
591 FLAC__ASSERT(0 != encoder);
592 FLAC__ASSERT(0 != encoder->private_);
593 return FLAC__stream_encoder_get_qlp_coeff_precision(encoder->private_->stream_encoder);
596 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__SeekableStreamEncoder *encoder)
598 FLAC__ASSERT(0 != encoder);
599 FLAC__ASSERT(0 != encoder->private_);
600 return FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->stream_encoder);
603 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_escape_coding(const FLAC__SeekableStreamEncoder *encoder)
605 FLAC__ASSERT(0 != encoder);
606 FLAC__ASSERT(0 != encoder->private_);
607 return FLAC__stream_encoder_get_do_escape_coding(encoder->private_->stream_encoder);
610 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(const FLAC__SeekableStreamEncoder *encoder)
612 FLAC__ASSERT(0 != encoder);
613 FLAC__ASSERT(0 != encoder->private_);
614 return FLAC__stream_encoder_get_do_exhaustive_model_search(encoder->private_->stream_encoder);
617 FLAC_API unsigned FLAC__seekable_stream_encoder_get_min_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder)
619 FLAC__ASSERT(0 != encoder);
620 FLAC__ASSERT(0 != encoder->private_);
621 return FLAC__stream_encoder_get_min_residual_partition_order(encoder->private_->stream_encoder);
624 FLAC_API unsigned FLAC__seekable_stream_encoder_get_max_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder)
626 FLAC__ASSERT(0 != encoder);
627 FLAC__ASSERT(0 != encoder->private_);
628 return FLAC__stream_encoder_get_max_residual_partition_order(encoder->private_->stream_encoder);
631 FLAC_API unsigned FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(const FLAC__SeekableStreamEncoder *encoder)
633 FLAC__ASSERT(0 != encoder);
634 FLAC__ASSERT(0 != encoder->private_);
635 return FLAC__stream_encoder_get_rice_parameter_search_dist(encoder->private_->stream_encoder);
638 FLAC_API FLAC__uint64 FLAC__seekable_stream_encoder_get_total_samples_estimate(const FLAC__SeekableStreamEncoder *encoder)
640 FLAC__ASSERT(0 != encoder);
641 FLAC__ASSERT(0 != encoder->private_);
642 return FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->stream_encoder);
645 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_process(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
647 FLAC__ASSERT(0 != encoder);
648 FLAC__ASSERT(0 != encoder->private_);
649 if(!FLAC__stream_encoder_process(encoder->private_->stream_encoder, buffer, samples)) {
650 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
657 /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
658 FLAC_API FLAC__bool FLAC__seekable_stream_encoder_process_interleaved(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
660 FLAC__ASSERT(0 != encoder);
661 FLAC__ASSERT(0 != encoder->private_);
662 if(!FLAC__stream_encoder_process_interleaved(encoder->private_->stream_encoder, buffer, samples)) {
663 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
670 /***********************************************************************
672 * Private class methods
674 ***********************************************************************/
676 void set_defaults_(FLAC__SeekableStreamEncoder *encoder)
678 FLAC__ASSERT(0 != encoder);
679 FLAC__ASSERT(0 != encoder->private_);
680 FLAC__ASSERT(0 != encoder->protected_);
682 encoder->private_->seek_callback = 0;
683 encoder->private_->write_callback = 0;
684 encoder->private_->client_data = 0;
686 encoder->private_->seek_table = 0;
689 FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
691 FLAC__SeekableStreamEncoder *seekable_stream_encoder = (FLAC__SeekableStreamEncoder*)client_data;
692 FLAC__StreamEncoderWriteStatus status;
695 * Watch for the first SEEKTABLE block to go by and store its offset.
697 if(samples == 0 && (buffer[0] & 0x7f) == FLAC__METADATA_TYPE_SEEKTABLE)
698 seekable_stream_encoder->private_->seektable_offset = seekable_stream_encoder->private_->bytes_written;
701 * Mark the current seek point if hit (if stream_offset == 0 that
702 * means we're still writing metadata and haven't hit the first
705 if(0 != seekable_stream_encoder->private_->seek_table && seekable_stream_encoder->private_->stream_offset > 0 && seekable_stream_encoder->private_->seek_table->num_points > 0) {
706 const unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder);
707 const FLAC__uint64 frame_first_sample = seekable_stream_encoder->private_->samples_written;
708 const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1;
709 FLAC__uint64 test_sample;
711 for(i = seekable_stream_encoder->private_->first_seekpoint_to_check; i < seekable_stream_encoder->private_->seek_table->num_points; i++) {
712 test_sample = seekable_stream_encoder->private_->seek_table->points[i].sample_number;
713 if(test_sample > frame_last_sample) {
716 else if(test_sample >= frame_first_sample) {
717 seekable_stream_encoder->private_->seek_table->points[i].sample_number = frame_first_sample;
718 seekable_stream_encoder->private_->seek_table->points[i].stream_offset = seekable_stream_encoder->private_->bytes_written - seekable_stream_encoder->private_->stream_offset;
719 seekable_stream_encoder->private_->seek_table->points[i].frame_samples = blocksize;
720 seekable_stream_encoder->private_->first_seekpoint_to_check++;
721 /* DO NOT: "break;" and here's why:
722 * The seektable template may contain more than one target
723 * sample for any given frame; we will keep looping, generating
724 * duplicate seekpoints for them, and we'll clean it up later,
725 * just before writing the seektable back to the metadata.
729 seekable_stream_encoder->private_->first_seekpoint_to_check++;
734 status = seekable_stream_encoder->private_->write_callback(seekable_stream_encoder, buffer, bytes, samples, current_frame, seekable_stream_encoder->private_->client_data);
736 if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
737 seekable_stream_encoder->private_->bytes_written += bytes;
738 seekable_stream_encoder->private_->samples_written += samples;
741 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
746 void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
748 FLAC__SeekableStreamEncoder *seekable_stream_encoder = (FLAC__SeekableStreamEncoder*)client_data;
749 FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
750 const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
751 const unsigned min_framesize = metadata->data.stream_info.min_framesize;
752 const unsigned max_framesize = metadata->data.stream_info.max_framesize;
753 const unsigned bps = metadata->data.stream_info.bits_per_sample;
755 FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
757 /* We get called by the stream encoder when the encoding process
758 * has finished so that we can update the STREAMINFO and SEEKTABLE
762 (void)encoder; /* silence compiler warning about unused parameter */
764 /*@@@ reopen callback here? The docs currently require user to open files in update mode from the start */
766 /* All this is based on intimate knowledge of the stream header
767 * layout, but a change to the header format that would break this
768 * would also break all streams encoded in the previous format.
772 * Write MD5 signature
774 if(seekable_stream_encoder->private_->seek_callback(seekable_stream_encoder, 26, seekable_stream_encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
775 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
778 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) {
779 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
784 * Write total samples
786 b[0] = ((FLAC__byte)(bps-1) << 4) | (FLAC__byte)((samples >> 32) & 0x0F);
787 b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
788 b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
789 b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
790 b[4] = (FLAC__byte)(samples & 0xFF);
791 if(seekable_stream_encoder->private_->seek_callback(seekable_stream_encoder, 21, seekable_stream_encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
792 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
795 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) {
796 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
801 * Write min/max framesize
803 b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
804 b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
805 b[2] = (FLAC__byte)(min_framesize & 0xFF);
806 b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
807 b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
808 b[5] = (FLAC__byte)(max_framesize & 0xFF);
809 if(seekable_stream_encoder->private_->seek_callback(seekable_stream_encoder, 12, seekable_stream_encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
810 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
813 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) {
814 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
821 if(0 != seekable_stream_encoder->private_->seek_table && seekable_stream_encoder->private_->seek_table->num_points > 0 && seekable_stream_encoder->private_->seektable_offset > 0) {
824 FLAC__format_seektable_sort(seekable_stream_encoder->private_->seek_table);
826 FLAC__ASSERT(FLAC__format_seektable_is_legal(seekable_stream_encoder->private_->seek_table));
828 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) {
829 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
833 for(i = 0; i < seekable_stream_encoder->private_->seek_table->num_points; i++) {
836 xx = seekable_stream_encoder->private_->seek_table->points[i].sample_number;
837 b[7] = (FLAC__byte)xx; xx >>= 8;
838 b[6] = (FLAC__byte)xx; xx >>= 8;
839 b[5] = (FLAC__byte)xx; xx >>= 8;
840 b[4] = (FLAC__byte)xx; xx >>= 8;
841 b[3] = (FLAC__byte)xx; xx >>= 8;
842 b[2] = (FLAC__byte)xx; xx >>= 8;
843 b[1] = (FLAC__byte)xx; xx >>= 8;
844 b[0] = (FLAC__byte)xx; xx >>= 8;
845 xx = seekable_stream_encoder->private_->seek_table->points[i].stream_offset;
846 b[15] = (FLAC__byte)xx; xx >>= 8;
847 b[14] = (FLAC__byte)xx; xx >>= 8;
848 b[13] = (FLAC__byte)xx; xx >>= 8;
849 b[12] = (FLAC__byte)xx; xx >>= 8;
850 b[11] = (FLAC__byte)xx; xx >>= 8;
851 b[10] = (FLAC__byte)xx; xx >>= 8;
852 b[9] = (FLAC__byte)xx; xx >>= 8;
853 b[8] = (FLAC__byte)xx; xx >>= 8;
854 x = seekable_stream_encoder->private_->seek_table->points[i].frame_samples;
855 b[17] = (FLAC__byte)x; x >>= 8;
856 b[16] = (FLAC__byte)x; x >>= 8;
857 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) {
858 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;