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"
30 #define max(a,b) ((a)>(b)?(a):(b))
32 /***********************************************************************
34 * Private class method prototypes
36 ***********************************************************************/
38 static void set_defaults_(FLAC__SeekableStreamEncoder *encoder);
39 static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
40 static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
42 /***********************************************************************
46 ***********************************************************************/
48 typedef struct FLAC__SeekableStreamEncoderPrivate {
49 FLAC__SeekableStreamEncoderSeekCallback seek_callback;
50 FLAC__SeekableStreamEncoderWriteCallback write_callback;
52 FLAC__StreamEncoder *stream_encoder;
53 FLAC__StreamMetadata_SeekTable *seek_table;
54 /* internal vars (all the above are class settings) */
55 unsigned first_seekpoint_to_check;
56 FLAC__uint64 stream_offset, seektable_offset;
57 FLAC__uint64 bytes_written;
58 } FLAC__SeekableStreamEncoderPrivate;
60 /***********************************************************************
62 * Public static class data
64 ***********************************************************************/
66 const char * const FLAC__SeekableStreamEncoderStateString[] = {
67 "FLAC__SEEKABLE_STREAM_ENCODER_OK",
68 "FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR",
69 "FLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR",
70 "FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR",
71 "FLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR",
72 "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR",
73 "FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED",
74 "FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK",
75 "FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE",
76 "FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED"
79 const char * const FLAC__SeekableStreamEncoderSeekStatusString[] = {
80 "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK",
81 "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR"
85 /***********************************************************************
87 * Class constructor/destructor
89 ***********************************************************************/
91 FLAC__SeekableStreamEncoder *FLAC__seekable_stream_encoder_new()
93 FLAC__SeekableStreamEncoder *encoder;
95 FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
97 encoder = (FLAC__SeekableStreamEncoder*)malloc(sizeof(FLAC__SeekableStreamEncoder));
101 memset(encoder, 0, sizeof(FLAC__SeekableStreamEncoder));
103 encoder->protected_ = (FLAC__SeekableStreamEncoderProtected*)malloc(sizeof(FLAC__SeekableStreamEncoderProtected));
104 if(encoder->protected_ == 0) {
108 memset(encoder->protected_, 0, sizeof(FLAC__SeekableStreamEncoderProtected));
110 encoder->private_ = (FLAC__SeekableStreamEncoderPrivate*)malloc(sizeof(FLAC__SeekableStreamEncoderPrivate));
111 if(encoder->private_ == 0) {
112 free(encoder->protected_);
116 memset(encoder->private_, 0, sizeof(FLAC__SeekableStreamEncoderPrivate));
118 encoder->private_->stream_encoder = FLAC__stream_encoder_new();
119 if(0 == encoder->private_->stream_encoder) {
120 free(encoder->private_);
121 free(encoder->protected_);
126 set_defaults_(encoder);
128 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
133 void FLAC__seekable_stream_encoder_delete(FLAC__SeekableStreamEncoder *encoder)
135 FLAC__ASSERT(0 != encoder);
136 FLAC__ASSERT(0 != encoder->protected_);
137 FLAC__ASSERT(0 != encoder->private_);
138 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
140 (void)FLAC__seekable_stream_encoder_finish(encoder);
142 FLAC__stream_encoder_delete(encoder->private_->stream_encoder);
144 free(encoder->private_);
145 free(encoder->protected_);
150 /***********************************************************************
152 * Public class methods
154 ***********************************************************************/
156 FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_init(FLAC__SeekableStreamEncoder *encoder)
158 FLAC__ASSERT(0 != encoder);
160 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
161 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED;
163 if(0 == encoder->private_->seek_callback || 0 == encoder->private_->write_callback)
164 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK;
166 if(0 != encoder->private_->seek_table && !FLAC__format_seektable_is_legal(encoder->private_->seek_table))
167 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE;
170 * This must be done before we init the stream encoder because that
171 * calls the write_callback, which uses these values.
173 encoder->private_->first_seekpoint_to_check = 0;
174 encoder->private_->stream_offset = 0;
175 encoder->private_->seektable_offset = 0;
176 encoder->private_->bytes_written = 0;
178 FLAC__stream_encoder_set_write_callback(encoder->private_->stream_encoder, write_callback_);
179 FLAC__stream_encoder_set_metadata_callback(encoder->private_->stream_encoder, metadata_callback_);
180 FLAC__stream_encoder_set_client_data(encoder->private_->stream_encoder, encoder);
182 if(FLAC__stream_encoder_init(encoder->private_->stream_encoder) != FLAC__STREAM_ENCODER_OK)
183 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
186 * Initializing the stream encoder writes all the metadata, so we
187 * save the stream offset now.
189 encoder->private_->stream_offset = encoder->private_->bytes_written;
191 return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_OK;
194 void FLAC__seekable_stream_encoder_finish(FLAC__SeekableStreamEncoder *encoder)
196 FLAC__ASSERT(0 != encoder);
197 FLAC__ASSERT(0 != encoder->private_);
198 FLAC__ASSERT(0 != encoder->protected_);
200 if(encoder->protected_->state == FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
203 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
205 FLAC__stream_encoder_finish(encoder->private_->stream_encoder);
207 set_defaults_(encoder);
209 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
212 FLAC__bool FLAC__seekable_stream_encoder_set_verify(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
214 FLAC__ASSERT(0 != encoder);
215 FLAC__ASSERT(0 != encoder->private_);
216 FLAC__ASSERT(0 != encoder->protected_);
217 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
218 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
220 return FLAC__stream_encoder_set_verify(encoder->private_->stream_encoder, value);
223 FLAC__bool FLAC__seekable_stream_encoder_set_streamable_subset(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
225 FLAC__ASSERT(0 != encoder);
226 FLAC__ASSERT(0 != encoder->private_);
227 FLAC__ASSERT(0 != encoder->protected_);
228 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
229 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
231 return FLAC__stream_encoder_set_streamable_subset(encoder->private_->stream_encoder, value);
234 FLAC__bool FLAC__seekable_stream_encoder_set_do_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
236 FLAC__ASSERT(0 != encoder);
237 FLAC__ASSERT(0 != encoder->private_);
238 FLAC__ASSERT(0 != encoder->protected_);
239 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
240 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
242 return FLAC__stream_encoder_set_do_mid_side_stereo(encoder->private_->stream_encoder, value);
245 FLAC__bool FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
247 FLAC__ASSERT(0 != encoder);
248 FLAC__ASSERT(0 != encoder->private_);
249 FLAC__ASSERT(0 != encoder->protected_);
250 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
251 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
253 return FLAC__stream_encoder_set_loose_mid_side_stereo(encoder->private_->stream_encoder, value);
256 FLAC__bool FLAC__seekable_stream_encoder_set_channels(FLAC__SeekableStreamEncoder *encoder, unsigned value)
258 FLAC__ASSERT(0 != encoder);
259 FLAC__ASSERT(0 != encoder->private_);
260 FLAC__ASSERT(0 != encoder->protected_);
261 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
262 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
264 return FLAC__stream_encoder_set_channels(encoder->private_->stream_encoder, value);
267 FLAC__bool FLAC__seekable_stream_encoder_set_bits_per_sample(FLAC__SeekableStreamEncoder *encoder, unsigned value)
269 FLAC__ASSERT(0 != encoder);
270 FLAC__ASSERT(0 != encoder->private_);
271 FLAC__ASSERT(0 != encoder->protected_);
272 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
273 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
275 return FLAC__stream_encoder_set_bits_per_sample(encoder->private_->stream_encoder, value);
278 FLAC__bool FLAC__seekable_stream_encoder_set_sample_rate(FLAC__SeekableStreamEncoder *encoder, unsigned value)
280 FLAC__ASSERT(0 != encoder);
281 FLAC__ASSERT(0 != encoder->private_);
282 FLAC__ASSERT(0 != encoder->protected_);
283 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
284 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
286 return FLAC__stream_encoder_set_sample_rate(encoder->private_->stream_encoder, value);
289 FLAC__bool FLAC__seekable_stream_encoder_set_blocksize(FLAC__SeekableStreamEncoder *encoder, unsigned value)
291 FLAC__ASSERT(0 != encoder);
292 FLAC__ASSERT(0 != encoder->private_);
293 FLAC__ASSERT(0 != encoder->protected_);
294 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
295 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
297 return FLAC__stream_encoder_set_blocksize(encoder->private_->stream_encoder, value);
300 FLAC__bool FLAC__seekable_stream_encoder_set_max_lpc_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
302 FLAC__ASSERT(0 != encoder);
303 FLAC__ASSERT(0 != encoder->private_);
304 FLAC__ASSERT(0 != encoder->protected_);
305 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
306 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
308 return FLAC__stream_encoder_set_max_lpc_order(encoder->private_->stream_encoder, value);
311 FLAC__bool FLAC__seekable_stream_encoder_set_qlp_coeff_precision(FLAC__SeekableStreamEncoder *encoder, unsigned value)
313 FLAC__ASSERT(0 != encoder);
314 FLAC__ASSERT(0 != encoder->private_);
315 FLAC__ASSERT(0 != encoder->protected_);
316 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
317 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
319 return FLAC__stream_encoder_set_qlp_coeff_precision(encoder->private_->stream_encoder, value);
322 FLAC__bool FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
324 FLAC__ASSERT(0 != encoder);
325 FLAC__ASSERT(0 != encoder->private_);
326 FLAC__ASSERT(0 != encoder->protected_);
327 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
328 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
330 return FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->stream_encoder, value);
333 FLAC__bool FLAC__seekable_stream_encoder_set_do_escape_coding(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
335 FLAC__ASSERT(0 != encoder);
336 FLAC__ASSERT(0 != encoder->private_);
337 FLAC__ASSERT(0 != encoder->protected_);
338 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
339 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
341 return FLAC__stream_encoder_set_do_escape_coding(encoder->private_->stream_encoder, value);
344 FLAC__bool FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
346 FLAC__ASSERT(0 != encoder);
347 FLAC__ASSERT(0 != encoder->private_);
348 FLAC__ASSERT(0 != encoder->protected_);
349 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
350 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
352 return FLAC__stream_encoder_set_do_exhaustive_model_search(encoder->private_->stream_encoder, value);
355 FLAC__bool FLAC__seekable_stream_encoder_set_min_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
357 FLAC__ASSERT(0 != encoder);
358 FLAC__ASSERT(0 != encoder->private_);
359 FLAC__ASSERT(0 != encoder->protected_);
360 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
361 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
363 return FLAC__stream_encoder_set_min_residual_partition_order(encoder->private_->stream_encoder, value);
366 FLAC__bool FLAC__seekable_stream_encoder_set_max_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
368 FLAC__ASSERT(0 != encoder);
369 FLAC__ASSERT(0 != encoder->private_);
370 FLAC__ASSERT(0 != encoder->protected_);
371 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
372 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
374 return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->stream_encoder, value);
377 FLAC__bool FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(FLAC__SeekableStreamEncoder *encoder, unsigned value)
379 FLAC__ASSERT(0 != encoder);
380 FLAC__ASSERT(0 != encoder->private_);
381 FLAC__ASSERT(0 != encoder->protected_);
382 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
383 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
385 return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->stream_encoder, value);
388 FLAC__bool FLAC__seekable_stream_encoder_set_total_samples_estimate(FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 value)
390 FLAC__ASSERT(0 != encoder);
391 FLAC__ASSERT(0 != encoder->private_);
392 FLAC__ASSERT(0 != encoder->protected_);
393 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
394 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
396 return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->stream_encoder, value);
399 FLAC__bool FLAC__seekable_stream_encoder_set_metadata(FLAC__SeekableStreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
401 FLAC__ASSERT(0 != encoder);
402 FLAC__ASSERT(0 != encoder->private_);
403 FLAC__ASSERT(0 != encoder->protected_);
404 FLAC__ASSERT(0 != encoder->private_->stream_encoder);
405 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
407 if(0 != metadata && num_blocks > 0) {
409 for(i = 0; i < num_blocks; i++) {
410 if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) {
411 encoder->private_->seek_table = &metadata[i]->data.seek_table;
412 break; /* take only the first one */
416 return FLAC__stream_encoder_set_metadata(encoder->private_->stream_encoder, metadata, num_blocks);
419 FLAC__bool FLAC__seekable_stream_encoder_set_seek_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderSeekCallback value)
421 FLAC__ASSERT(0 != encoder);
422 FLAC__ASSERT(0 != encoder->private_);
423 FLAC__ASSERT(0 != encoder->protected_);
424 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
426 encoder->private_->seek_callback = value;
430 FLAC__bool FLAC__seekable_stream_encoder_set_write_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderWriteCallback value)
432 FLAC__ASSERT(0 != encoder);
433 FLAC__ASSERT(0 != encoder->private_);
434 FLAC__ASSERT(0 != encoder->protected_);
435 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
437 encoder->private_->write_callback = value;
441 FLAC__bool FLAC__seekable_stream_encoder_set_client_data(FLAC__SeekableStreamEncoder *encoder, void *value)
443 FLAC__ASSERT(0 != encoder);
444 FLAC__ASSERT(0 != encoder->private_);
445 FLAC__ASSERT(0 != encoder->protected_);
446 if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
448 encoder->private_->client_data = value;
452 FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_get_state(const FLAC__SeekableStreamEncoder *encoder)
454 FLAC__ASSERT(0 != encoder);
455 FLAC__ASSERT(0 != encoder->protected_);
456 return encoder->protected_->state;
459 FLAC__StreamEncoderState FLAC__seekable_stream_encoder_get_stream_encoder_state(const FLAC__SeekableStreamEncoder *encoder)
461 FLAC__ASSERT(0 != encoder);
462 FLAC__ASSERT(0 != encoder->private_);
463 return FLAC__stream_encoder_get_state(encoder->private_->stream_encoder);
466 FLAC__StreamDecoderState FLAC__seekable_stream_encoder_get_verify_decoder_state(const FLAC__SeekableStreamEncoder *encoder)
468 FLAC__ASSERT(0 != encoder);
469 FLAC__ASSERT(0 != encoder->private_);
470 return FLAC__stream_encoder_get_verify_decoder_state(encoder->private_->stream_encoder);
473 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)
475 FLAC__ASSERT(0 != encoder);
476 FLAC__ASSERT(0 != encoder->private_);
477 FLAC__stream_encoder_get_verify_decoder_error_stats(encoder->private_->stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
480 FLAC__bool FLAC__seekable_stream_encoder_get_verify(const FLAC__SeekableStreamEncoder *encoder)
482 FLAC__ASSERT(0 != encoder);
483 FLAC__ASSERT(0 != encoder->private_);
484 return FLAC__stream_encoder_get_verify(encoder->private_->stream_encoder);
487 FLAC__bool FLAC__seekable_stream_encoder_get_streamable_subset(const FLAC__SeekableStreamEncoder *encoder)
489 FLAC__ASSERT(0 != encoder);
490 FLAC__ASSERT(0 != encoder->private_);
491 return FLAC__stream_encoder_get_streamable_subset(encoder->private_->stream_encoder);
494 FLAC__bool FLAC__seekable_stream_encoder_get_do_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder)
496 FLAC__ASSERT(0 != encoder);
497 FLAC__ASSERT(0 != encoder->private_);
498 return FLAC__stream_encoder_get_do_mid_side_stereo(encoder->private_->stream_encoder);
501 FLAC__bool FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder)
503 FLAC__ASSERT(0 != encoder);
504 FLAC__ASSERT(0 != encoder->private_);
505 return FLAC__stream_encoder_get_loose_mid_side_stereo(encoder->private_->stream_encoder);
508 unsigned FLAC__seekable_stream_encoder_get_channels(const FLAC__SeekableStreamEncoder *encoder)
510 FLAC__ASSERT(0 != encoder);
511 FLAC__ASSERT(0 != encoder->private_);
512 return FLAC__stream_encoder_get_channels(encoder->private_->stream_encoder);
515 unsigned FLAC__seekable_stream_encoder_get_bits_per_sample(const FLAC__SeekableStreamEncoder *encoder)
517 FLAC__ASSERT(0 != encoder);
518 FLAC__ASSERT(0 != encoder->private_);
519 return FLAC__stream_encoder_get_bits_per_sample(encoder->private_->stream_encoder);
522 unsigned FLAC__seekable_stream_encoder_get_sample_rate(const FLAC__SeekableStreamEncoder *encoder)
524 FLAC__ASSERT(0 != encoder);
525 FLAC__ASSERT(0 != encoder->private_);
526 return FLAC__stream_encoder_get_sample_rate(encoder->private_->stream_encoder);
529 unsigned FLAC__seekable_stream_encoder_get_blocksize(const FLAC__SeekableStreamEncoder *encoder)
531 FLAC__ASSERT(0 != encoder);
532 FLAC__ASSERT(0 != encoder->private_);
533 return FLAC__stream_encoder_get_blocksize(encoder->private_->stream_encoder);
536 unsigned FLAC__seekable_stream_encoder_get_max_lpc_order(const FLAC__SeekableStreamEncoder *encoder)
538 FLAC__ASSERT(0 != encoder);
539 FLAC__ASSERT(0 != encoder->private_);
540 return FLAC__stream_encoder_get_max_lpc_order(encoder->private_->stream_encoder);
543 unsigned FLAC__seekable_stream_encoder_get_qlp_coeff_precision(const FLAC__SeekableStreamEncoder *encoder)
545 FLAC__ASSERT(0 != encoder);
546 FLAC__ASSERT(0 != encoder->private_);
547 return FLAC__stream_encoder_get_qlp_coeff_precision(encoder->private_->stream_encoder);
550 FLAC__bool FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__SeekableStreamEncoder *encoder)
552 FLAC__ASSERT(0 != encoder);
553 FLAC__ASSERT(0 != encoder->private_);
554 return FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->stream_encoder);
557 FLAC__bool FLAC__seekable_stream_encoder_get_do_escape_coding(const FLAC__SeekableStreamEncoder *encoder)
559 FLAC__ASSERT(0 != encoder);
560 FLAC__ASSERT(0 != encoder->private_);
561 return FLAC__stream_encoder_get_do_escape_coding(encoder->private_->stream_encoder);
564 FLAC__bool FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(const FLAC__SeekableStreamEncoder *encoder)
566 FLAC__ASSERT(0 != encoder);
567 FLAC__ASSERT(0 != encoder->private_);
568 return FLAC__stream_encoder_get_do_exhaustive_model_search(encoder->private_->stream_encoder);
571 unsigned FLAC__seekable_stream_encoder_get_min_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder)
573 FLAC__ASSERT(0 != encoder);
574 FLAC__ASSERT(0 != encoder->private_);
575 return FLAC__stream_encoder_get_min_residual_partition_order(encoder->private_->stream_encoder);
578 unsigned FLAC__seekable_stream_encoder_get_max_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder)
580 FLAC__ASSERT(0 != encoder);
581 FLAC__ASSERT(0 != encoder->private_);
582 return FLAC__stream_encoder_get_max_residual_partition_order(encoder->private_->stream_encoder);
585 unsigned FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(const FLAC__SeekableStreamEncoder *encoder)
587 FLAC__ASSERT(0 != encoder);
588 FLAC__ASSERT(0 != encoder->private_);
589 return FLAC__stream_encoder_get_rice_parameter_search_dist(encoder->private_->stream_encoder);
592 FLAC__uint64 FLAC__seekable_stream_encoder_get_total_samples_estimate(const FLAC__SeekableStreamEncoder *encoder)
594 FLAC__ASSERT(0 != encoder);
595 FLAC__ASSERT(0 != encoder->private_);
596 return FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->stream_encoder);
599 FLAC__bool FLAC__seekable_stream_encoder_process(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
601 FLAC__ASSERT(0 != encoder);
602 FLAC__ASSERT(0 != encoder->private_);
603 if(!FLAC__stream_encoder_process(encoder->private_->stream_encoder, buffer, samples)) {
604 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
611 /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
612 FLAC__bool FLAC__seekable_stream_encoder_process_interleaved(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
614 FLAC__ASSERT(0 != encoder);
615 FLAC__ASSERT(0 != encoder->private_);
616 if(!FLAC__stream_encoder_process_interleaved(encoder->private_->stream_encoder, buffer, samples)) {
617 encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
624 /***********************************************************************
626 * Private class methods
628 ***********************************************************************/
630 void set_defaults_(FLAC__SeekableStreamEncoder *encoder)
632 FLAC__ASSERT(0 != encoder);
633 FLAC__ASSERT(0 != encoder->private_);
634 FLAC__ASSERT(0 != encoder->protected_);
636 encoder->private_->seek_callback = 0;
637 encoder->private_->write_callback = 0;
638 encoder->private_->client_data = 0;
640 encoder->private_->seek_table = 0;
643 FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
645 FLAC__SeekableStreamEncoder *seekable_stream_encoder = (FLAC__SeekableStreamEncoder*)client_data;
646 FLAC__StreamEncoderWriteStatus status;
649 * Watch for the first SEEKTABLE block to go by and store its offset.
651 if(samples == 0 && (buffer[0] & 0x7f) == FLAC__METADATA_TYPE_SEEKTABLE)
652 seekable_stream_encoder->private_->seektable_offset = seekable_stream_encoder->private_->bytes_written;
655 * Mark the current seek point if hit (if stream_offset == 0 that
656 * means we're still writing metadata and haven't hit the first
659 if(seekable_stream_encoder->private_->stream_offset > 0 && seekable_stream_encoder->private_->seek_table->num_points > 0) {
660 /*@@@ WATCHOUT: assumes the encoder is fixed-blocksize, which will be true indefinitely: */
661 const unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder);
662 const FLAC__uint64 frame_first_sample = (FLAC__uint64)current_frame * (FLAC__uint64)blocksize;
663 const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1;
664 FLAC__uint64 test_sample;
666 for(i = seekable_stream_encoder->private_->first_seekpoint_to_check; i < seekable_stream_encoder->private_->seek_table->num_points; i++) {
667 test_sample = seekable_stream_encoder->private_->seek_table->points[i].sample_number;
668 if(test_sample > frame_last_sample) {
671 else if(test_sample >= frame_first_sample) {
672 seekable_stream_encoder->private_->seek_table->points[i].sample_number = frame_first_sample;
673 seekable_stream_encoder->private_->seek_table->points[i].stream_offset = seekable_stream_encoder->private_->bytes_written - seekable_stream_encoder->private_->stream_offset;
674 seekable_stream_encoder->private_->seek_table->points[i].frame_samples = blocksize;
675 seekable_stream_encoder->private_->first_seekpoint_to_check++;
676 /* DO NOT: "break;" and here's why:
677 * The seektable template may contain more than one target
678 * sample for any given frame; we will keep looping, generating
679 * duplicate seekpoints for them, and we'll clean it up later,
680 * just before writing the seektable back to the metadata.
684 seekable_stream_encoder->private_->first_seekpoint_to_check++;
689 status = seekable_stream_encoder->private_->write_callback(seekable_stream_encoder, buffer, bytes, samples, current_frame, seekable_stream_encoder->private_->client_data);
691 if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
692 seekable_stream_encoder->private_->bytes_written += bytes;
694 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
699 void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
701 FLAC__SeekableStreamEncoder *seekable_stream_encoder = (FLAC__SeekableStreamEncoder*)client_data;
702 FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
703 const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
704 const unsigned min_framesize = metadata->data.stream_info.min_framesize;
705 const unsigned max_framesize = metadata->data.stream_info.max_framesize;
706 const unsigned bps = metadata->data.stream_info.bits_per_sample;
708 FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
710 /* We get called by the stream encoder when the encoding process
711 * has finished so that we can update the STREAMINFO and SEEKTABLE
715 (void)encoder; /* silence compiler warning about unused parameter */
717 /*@@@ reopen callback here? */
719 /* All this is based on intimate knowledge of the stream header
720 * layout, but a change to the header format that would break this
721 * would also break all streams encoded in the previous format.
725 * Write MD5 signature
727 if(seekable_stream_encoder->private_->seek_callback(seekable_stream_encoder, 26, seekable_stream_encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
728 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
731 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) {
732 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
737 * Write total samples
739 b[0] = ((FLAC__byte)(bps-1) << 4) | (FLAC__byte)((samples >> 32) & 0x0F);
740 b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
741 b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
742 b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
743 b[4] = (FLAC__byte)(samples & 0xFF);
744 if(seekable_stream_encoder->private_->seek_callback(seekable_stream_encoder, 21, seekable_stream_encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
745 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
748 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) {
749 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
754 * Write min/max framesize
756 b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
757 b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
758 b[2] = (FLAC__byte)(min_framesize & 0xFF);
759 b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
760 b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
761 b[5] = (FLAC__byte)(max_framesize & 0xFF);
762 if(seekable_stream_encoder->private_->seek_callback(seekable_stream_encoder, 12, seekable_stream_encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
763 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
766 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) {
767 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
774 if(seekable_stream_encoder->private_->seek_table->num_points > 0 && seekable_stream_encoder->private_->seektable_offset > 0) {
777 FLAC__format_seektable_sort(seekable_stream_encoder->private_->seek_table);
779 FLAC__ASSERT(FLAC__format_seektable_is_legal(seekable_stream_encoder->private_->seek_table));
781 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) {
782 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
786 for(i = 0; i < seekable_stream_encoder->private_->seek_table->num_points; i++) {
789 xx = seekable_stream_encoder->private_->seek_table->points[i].sample_number;
790 b[7] = (FLAC__byte)xx; xx >>= 8;
791 b[6] = (FLAC__byte)xx; xx >>= 8;
792 b[5] = (FLAC__byte)xx; xx >>= 8;
793 b[4] = (FLAC__byte)xx; xx >>= 8;
794 b[3] = (FLAC__byte)xx; xx >>= 8;
795 b[2] = (FLAC__byte)xx; xx >>= 8;
796 b[1] = (FLAC__byte)xx; xx >>= 8;
797 b[0] = (FLAC__byte)xx; xx >>= 8;
798 xx = seekable_stream_encoder->private_->seek_table->points[i].stream_offset;
799 b[15] = (FLAC__byte)xx; xx >>= 8;
800 b[14] = (FLAC__byte)xx; xx >>= 8;
801 b[13] = (FLAC__byte)xx; xx >>= 8;
802 b[12] = (FLAC__byte)xx; xx >>= 8;
803 b[11] = (FLAC__byte)xx; xx >>= 8;
804 b[10] = (FLAC__byte)xx; xx >>= 8;
805 b[9] = (FLAC__byte)xx; xx >>= 8;
806 b[8] = (FLAC__byte)xx; xx >>= 8;
807 x = seekable_stream_encoder->private_->seek_table->points[i].frame_samples;
808 b[17] = (FLAC__byte)x; x >>= 8;
809 b[16] = (FLAC__byte)x; x >>= 8;
810 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) {
811 seekable_stream_encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;