1
/* libFLAC - Free Lossless Audio Codec library
2
* Copyright (C) 2002,2003,2004,2005 Josh Coalson
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
8
* - Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
15
* - Neither the name of the Xiph.org Foundation nor the names of its
16
* contributors may be used to endorse or promote products derived from
17
* this software without specific prior written permission.
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
#include <stdlib.h> /* for calloc() */
34
#include <string.h> /* for memcpy() */
35
#include "FLAC/assert.h"
36
#include "protected/seekable_stream_encoder.h"
41
#define max(a,b) ((a)>(b)?(a):(b))
43
/***********************************************************************
45
* Private class method prototypes
47
***********************************************************************/
49
/* unpublished debug routines */
50
extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
51
extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
52
extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
54
static void set_defaults_(FLAC__SeekableStreamEncoder *encoder);
55
static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
56
static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
58
/***********************************************************************
62
***********************************************************************/
64
typedef struct FLAC__SeekableStreamEncoderPrivate {
65
FLAC__SeekableStreamEncoderSeekCallback seek_callback;
66
FLAC__SeekableStreamEncoderTellCallback tell_callback;
67
FLAC__SeekableStreamEncoderWriteCallback write_callback;
69
FLAC__StreamEncoder *stream_encoder;
70
FLAC__StreamMetadata_SeekTable *seek_table;
71
/* internal vars (all the above are class settings) */
72
unsigned first_seekpoint_to_check;
73
FLAC__uint64 samples_written;
74
} FLAC__SeekableStreamEncoderPrivate;
76
/***********************************************************************
78
* Public static class data
80
***********************************************************************/
82
FLAC_API const char * const FLAC__SeekableStreamEncoderStateString[] = {
83
"FLAC__SEEKABLE_STREAM_ENCODER_OK",
84
"FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR",
85
"FLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR",
86
"FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR",
87
"FLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR",
88
"FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR",
89
"FLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR",
90
"FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED",
91
"FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK",
92
"FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE",
93
"FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED"
96
FLAC_API const char * const FLAC__SeekableStreamEncoderSeekStatusString[] = {
97
"FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK",
98
"FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR"
101
FLAC_API const char * const FLAC__SeekableStreamEncoderTellStatusString[] = {
102
"FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK",
103
"FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_ERROR"
107
/***********************************************************************
109
* Class constructor/destructor
111
***********************************************************************/
113
FLAC_API FLAC__SeekableStreamEncoder *FLAC__seekable_stream_encoder_new()
115
FLAC__SeekableStreamEncoder *encoder;
117
FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
119
encoder = (FLAC__SeekableStreamEncoder*)calloc(1, sizeof(FLAC__SeekableStreamEncoder));
124
encoder->protected_ = (FLAC__SeekableStreamEncoderProtected*)calloc(1, sizeof(FLAC__SeekableStreamEncoderProtected));
125
if(encoder->protected_ == 0) {
130
encoder->private_ = (FLAC__SeekableStreamEncoderPrivate*)calloc(1, sizeof(FLAC__SeekableStreamEncoderPrivate));
131
if(encoder->private_ == 0) {
132
free(encoder->protected_);
137
encoder->private_->stream_encoder = FLAC__stream_encoder_new();
138
if(0 == encoder->private_->stream_encoder) {
139
free(encoder->private_);
140
free(encoder->protected_);
145
set_defaults_(encoder);
147
encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
152
FLAC_API void FLAC__seekable_stream_encoder_delete(FLAC__SeekableStreamEncoder *encoder)
154
FLAC__ASSERT(0 != encoder);
155
FLAC__ASSERT(0 != encoder->protected_);
156
FLAC__ASSERT(0 != encoder->private_);
157
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
159
(void)FLAC__seekable_stream_encoder_finish(encoder);
161
FLAC__stream_encoder_delete(encoder->private_->stream_encoder);
163
free(encoder->private_);
164
free(encoder->protected_);
169
/***********************************************************************
171
* Public class methods
173
***********************************************************************/
175
FLAC_API FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_init(FLAC__SeekableStreamEncoder *encoder)
177
FLAC__ASSERT(0 != encoder);
179
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
180
return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED;
182
if(0 == encoder->private_->seek_callback || 0 == encoder->private_->tell_callback || 0 == encoder->private_->write_callback)
183
return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK;
185
if(0 != encoder->private_->seek_table && !FLAC__format_seektable_is_legal(encoder->private_->seek_table))
186
return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE;
189
* These must be done before we init the stream encoder because that
190
* calls the write_callback, which uses these values.
192
encoder->private_->first_seekpoint_to_check = 0;
193
encoder->private_->samples_written = 0;
194
encoder->protected_->streaminfo_offset = 0;
195
encoder->protected_->seektable_offset = 0;
196
encoder->protected_->audio_offset = 0;
198
FLAC__stream_encoder_set_write_callback(encoder->private_->stream_encoder, write_callback_);
199
FLAC__stream_encoder_set_metadata_callback(encoder->private_->stream_encoder, metadata_callback_);
200
FLAC__stream_encoder_set_client_data(encoder->private_->stream_encoder, encoder);
202
if(FLAC__stream_encoder_init(encoder->private_->stream_encoder) != FLAC__STREAM_ENCODER_OK)
203
return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
206
* Initializing the stream encoder writes all the metadata, so we
207
* save the stream offset now.
209
if(encoder->private_->tell_callback(encoder, &encoder->protected_->audio_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK)
210
return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR;
212
return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_OK;
215
FLAC_API void FLAC__seekable_stream_encoder_finish(FLAC__SeekableStreamEncoder *encoder)
217
FLAC__ASSERT(0 != encoder);
218
FLAC__ASSERT(0 != encoder->private_);
219
FLAC__ASSERT(0 != encoder->protected_);
221
if(encoder->protected_->state == FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
224
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
226
FLAC__stream_encoder_finish(encoder->private_->stream_encoder);
228
set_defaults_(encoder);
230
encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
233
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_verify(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
235
FLAC__ASSERT(0 != encoder);
236
FLAC__ASSERT(0 != encoder->private_);
237
FLAC__ASSERT(0 != encoder->protected_);
238
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
239
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
241
return FLAC__stream_encoder_set_verify(encoder->private_->stream_encoder, value);
244
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_streamable_subset(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
246
FLAC__ASSERT(0 != encoder);
247
FLAC__ASSERT(0 != encoder->private_);
248
FLAC__ASSERT(0 != encoder->protected_);
249
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
250
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
252
return FLAC__stream_encoder_set_streamable_subset(encoder->private_->stream_encoder, value);
255
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
257
FLAC__ASSERT(0 != encoder);
258
FLAC__ASSERT(0 != encoder->private_);
259
FLAC__ASSERT(0 != encoder->protected_);
260
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
261
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
263
return FLAC__stream_encoder_set_do_mid_side_stereo(encoder->private_->stream_encoder, value);
266
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
268
FLAC__ASSERT(0 != encoder);
269
FLAC__ASSERT(0 != encoder->private_);
270
FLAC__ASSERT(0 != encoder->protected_);
271
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
272
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
274
return FLAC__stream_encoder_set_loose_mid_side_stereo(encoder->private_->stream_encoder, value);
277
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_channels(FLAC__SeekableStreamEncoder *encoder, unsigned value)
279
FLAC__ASSERT(0 != encoder);
280
FLAC__ASSERT(0 != encoder->private_);
281
FLAC__ASSERT(0 != encoder->protected_);
282
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
283
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
285
return FLAC__stream_encoder_set_channels(encoder->private_->stream_encoder, value);
288
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_bits_per_sample(FLAC__SeekableStreamEncoder *encoder, unsigned value)
290
FLAC__ASSERT(0 != encoder);
291
FLAC__ASSERT(0 != encoder->private_);
292
FLAC__ASSERT(0 != encoder->protected_);
293
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
294
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
296
return FLAC__stream_encoder_set_bits_per_sample(encoder->private_->stream_encoder, value);
299
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_sample_rate(FLAC__SeekableStreamEncoder *encoder, unsigned value)
301
FLAC__ASSERT(0 != encoder);
302
FLAC__ASSERT(0 != encoder->private_);
303
FLAC__ASSERT(0 != encoder->protected_);
304
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
305
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
307
return FLAC__stream_encoder_set_sample_rate(encoder->private_->stream_encoder, value);
310
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_blocksize(FLAC__SeekableStreamEncoder *encoder, unsigned value)
312
FLAC__ASSERT(0 != encoder);
313
FLAC__ASSERT(0 != encoder->private_);
314
FLAC__ASSERT(0 != encoder->protected_);
315
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
316
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
318
return FLAC__stream_encoder_set_blocksize(encoder->private_->stream_encoder, value);
321
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_lpc_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
323
FLAC__ASSERT(0 != encoder);
324
FLAC__ASSERT(0 != encoder->private_);
325
FLAC__ASSERT(0 != encoder->protected_);
326
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
327
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
329
return FLAC__stream_encoder_set_max_lpc_order(encoder->private_->stream_encoder, value);
332
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_qlp_coeff_precision(FLAC__SeekableStreamEncoder *encoder, unsigned value)
334
FLAC__ASSERT(0 != encoder);
335
FLAC__ASSERT(0 != encoder->private_);
336
FLAC__ASSERT(0 != encoder->protected_);
337
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
338
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
340
return FLAC__stream_encoder_set_qlp_coeff_precision(encoder->private_->stream_encoder, value);
343
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
345
FLAC__ASSERT(0 != encoder);
346
FLAC__ASSERT(0 != encoder->private_);
347
FLAC__ASSERT(0 != encoder->protected_);
348
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
349
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
351
return FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->stream_encoder, value);
354
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_escape_coding(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
356
FLAC__ASSERT(0 != encoder);
357
FLAC__ASSERT(0 != encoder->private_);
358
FLAC__ASSERT(0 != encoder->protected_);
359
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
360
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
362
return FLAC__stream_encoder_set_do_escape_coding(encoder->private_->stream_encoder, value);
365
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
367
FLAC__ASSERT(0 != encoder);
368
FLAC__ASSERT(0 != encoder->private_);
369
FLAC__ASSERT(0 != encoder->protected_);
370
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
371
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
373
return FLAC__stream_encoder_set_do_exhaustive_model_search(encoder->private_->stream_encoder, value);
376
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_min_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
378
FLAC__ASSERT(0 != encoder);
379
FLAC__ASSERT(0 != encoder->private_);
380
FLAC__ASSERT(0 != encoder->protected_);
381
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
382
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
384
return FLAC__stream_encoder_set_min_residual_partition_order(encoder->private_->stream_encoder, value);
387
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
389
FLAC__ASSERT(0 != encoder);
390
FLAC__ASSERT(0 != encoder->private_);
391
FLAC__ASSERT(0 != encoder->protected_);
392
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
393
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
395
return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->stream_encoder, value);
398
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(FLAC__SeekableStreamEncoder *encoder, unsigned value)
400
FLAC__ASSERT(0 != encoder);
401
FLAC__ASSERT(0 != encoder->private_);
402
FLAC__ASSERT(0 != encoder->protected_);
403
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
404
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
406
return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->stream_encoder, value);
409
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_total_samples_estimate(FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 value)
411
FLAC__ASSERT(0 != encoder);
412
FLAC__ASSERT(0 != encoder->private_);
413
FLAC__ASSERT(0 != encoder->protected_);
414
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
415
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
417
return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->stream_encoder, value);
420
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_metadata(FLAC__SeekableStreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
422
FLAC__ASSERT(0 != encoder);
423
FLAC__ASSERT(0 != encoder->private_);
424
FLAC__ASSERT(0 != encoder->protected_);
425
FLAC__ASSERT(0 != encoder->private_->stream_encoder);
426
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
428
if(0 != metadata && num_blocks > 0) {
430
for(i = 0; i < num_blocks; i++) {
431
if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) {
432
encoder->private_->seek_table = &metadata[i]->data.seek_table;
433
break; /* take only the first one */
437
return FLAC__stream_encoder_set_metadata(encoder->private_->stream_encoder, metadata, num_blocks);
440
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_seek_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderSeekCallback value)
442
FLAC__ASSERT(0 != encoder);
443
FLAC__ASSERT(0 != encoder->private_);
444
FLAC__ASSERT(0 != encoder->protected_);
445
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
447
encoder->private_->seek_callback = value;
451
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_tell_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderTellCallback value)
453
FLAC__ASSERT(0 != encoder);
454
FLAC__ASSERT(0 != encoder->private_);
455
FLAC__ASSERT(0 != encoder->protected_);
456
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
458
encoder->private_->tell_callback = value;
462
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_write_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderWriteCallback value)
464
FLAC__ASSERT(0 != encoder);
465
FLAC__ASSERT(0 != encoder->private_);
466
FLAC__ASSERT(0 != encoder->protected_);
467
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
469
encoder->private_->write_callback = value;
473
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_client_data(FLAC__SeekableStreamEncoder *encoder, void *value)
475
FLAC__ASSERT(0 != encoder);
476
FLAC__ASSERT(0 != encoder->private_);
477
FLAC__ASSERT(0 != encoder->protected_);
478
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
480
encoder->private_->client_data = value;
485
* These three functions are not static, but not publically exposed in
486
* include/FLAC/ either. They are used by the test suite.
488
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_constant_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
490
FLAC__ASSERT(0 != encoder);
491
FLAC__ASSERT(0 != encoder->private_);
492
FLAC__ASSERT(0 != encoder->protected_);
493
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
495
return FLAC__stream_encoder_disable_constant_subframes(encoder->private_->stream_encoder, value);
498
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_fixed_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
500
FLAC__ASSERT(0 != encoder);
501
FLAC__ASSERT(0 != encoder->private_);
502
FLAC__ASSERT(0 != encoder->protected_);
503
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
505
return FLAC__stream_encoder_disable_fixed_subframes(encoder->private_->stream_encoder, value);
508
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_verbatim_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
510
FLAC__ASSERT(0 != encoder);
511
FLAC__ASSERT(0 != encoder->private_);
512
FLAC__ASSERT(0 != encoder->protected_);
513
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
515
return FLAC__stream_encoder_disable_verbatim_subframes(encoder->private_->stream_encoder, value);
518
FLAC_API FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_get_state(const FLAC__SeekableStreamEncoder *encoder)
520
FLAC__ASSERT(0 != encoder);
521
FLAC__ASSERT(0 != encoder->protected_);
522
return encoder->protected_->state;
525
FLAC_API FLAC__StreamEncoderState FLAC__seekable_stream_encoder_get_stream_encoder_state(const FLAC__SeekableStreamEncoder *encoder)
527
FLAC__ASSERT(0 != encoder);
528
FLAC__ASSERT(0 != encoder->private_);
529
return FLAC__stream_encoder_get_state(encoder->private_->stream_encoder);
532
FLAC_API FLAC__StreamDecoderState FLAC__seekable_stream_encoder_get_verify_decoder_state(const FLAC__SeekableStreamEncoder *encoder)
534
FLAC__ASSERT(0 != encoder);
535
FLAC__ASSERT(0 != encoder->private_);
536
return FLAC__stream_encoder_get_verify_decoder_state(encoder->private_->stream_encoder);
539
FLAC_API const char *FLAC__seekable_stream_encoder_get_resolved_state_string(const FLAC__SeekableStreamEncoder *encoder)
541
if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR)
542
return FLAC__SeekableStreamEncoderStateString[encoder->protected_->state];
544
return FLAC__stream_encoder_get_resolved_state_string(encoder->private_->stream_encoder);
547
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)
549
FLAC__ASSERT(0 != encoder);
550
FLAC__ASSERT(0 != encoder->private_);
551
FLAC__stream_encoder_get_verify_decoder_error_stats(encoder->private_->stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
554
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_verify(const FLAC__SeekableStreamEncoder *encoder)
556
FLAC__ASSERT(0 != encoder);
557
FLAC__ASSERT(0 != encoder->private_);
558
return FLAC__stream_encoder_get_verify(encoder->private_->stream_encoder);
561
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_streamable_subset(const FLAC__SeekableStreamEncoder *encoder)
563
FLAC__ASSERT(0 != encoder);
564
FLAC__ASSERT(0 != encoder->private_);
565
return FLAC__stream_encoder_get_streamable_subset(encoder->private_->stream_encoder);
568
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder)
570
FLAC__ASSERT(0 != encoder);
571
FLAC__ASSERT(0 != encoder->private_);
572
return FLAC__stream_encoder_get_do_mid_side_stereo(encoder->private_->stream_encoder);
575
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder)
577
FLAC__ASSERT(0 != encoder);
578
FLAC__ASSERT(0 != encoder->private_);
579
return FLAC__stream_encoder_get_loose_mid_side_stereo(encoder->private_->stream_encoder);
582
FLAC_API unsigned FLAC__seekable_stream_encoder_get_channels(const FLAC__SeekableStreamEncoder *encoder)
584
FLAC__ASSERT(0 != encoder);
585
FLAC__ASSERT(0 != encoder->private_);
586
return FLAC__stream_encoder_get_channels(encoder->private_->stream_encoder);
589
FLAC_API unsigned FLAC__seekable_stream_encoder_get_bits_per_sample(const FLAC__SeekableStreamEncoder *encoder)
591
FLAC__ASSERT(0 != encoder);
592
FLAC__ASSERT(0 != encoder->private_);
593
return FLAC__stream_encoder_get_bits_per_sample(encoder->private_->stream_encoder);
596
FLAC_API unsigned FLAC__seekable_stream_encoder_get_sample_rate(const FLAC__SeekableStreamEncoder *encoder)
598
FLAC__ASSERT(0 != encoder);
599
FLAC__ASSERT(0 != encoder->private_);
600
return FLAC__stream_encoder_get_sample_rate(encoder->private_->stream_encoder);
603
FLAC_API unsigned FLAC__seekable_stream_encoder_get_blocksize(const FLAC__SeekableStreamEncoder *encoder)
605
FLAC__ASSERT(0 != encoder);
606
FLAC__ASSERT(0 != encoder->private_);
607
return FLAC__stream_encoder_get_blocksize(encoder->private_->stream_encoder);
610
FLAC_API unsigned FLAC__seekable_stream_encoder_get_max_lpc_order(const FLAC__SeekableStreamEncoder *encoder)
612
FLAC__ASSERT(0 != encoder);
613
FLAC__ASSERT(0 != encoder->private_);
614
return FLAC__stream_encoder_get_max_lpc_order(encoder->private_->stream_encoder);
617
FLAC_API unsigned FLAC__seekable_stream_encoder_get_qlp_coeff_precision(const FLAC__SeekableStreamEncoder *encoder)
619
FLAC__ASSERT(0 != encoder);
620
FLAC__ASSERT(0 != encoder->private_);
621
return FLAC__stream_encoder_get_qlp_coeff_precision(encoder->private_->stream_encoder);
624
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__SeekableStreamEncoder *encoder)
626
FLAC__ASSERT(0 != encoder);
627
FLAC__ASSERT(0 != encoder->private_);
628
return FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->stream_encoder);
631
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_escape_coding(const FLAC__SeekableStreamEncoder *encoder)
633
FLAC__ASSERT(0 != encoder);
634
FLAC__ASSERT(0 != encoder->private_);
635
return FLAC__stream_encoder_get_do_escape_coding(encoder->private_->stream_encoder);
638
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(const FLAC__SeekableStreamEncoder *encoder)
640
FLAC__ASSERT(0 != encoder);
641
FLAC__ASSERT(0 != encoder->private_);
642
return FLAC__stream_encoder_get_do_exhaustive_model_search(encoder->private_->stream_encoder);
645
FLAC_API unsigned FLAC__seekable_stream_encoder_get_min_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder)
647
FLAC__ASSERT(0 != encoder);
648
FLAC__ASSERT(0 != encoder->private_);
649
return FLAC__stream_encoder_get_min_residual_partition_order(encoder->private_->stream_encoder);
652
FLAC_API unsigned FLAC__seekable_stream_encoder_get_max_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder)
654
FLAC__ASSERT(0 != encoder);
655
FLAC__ASSERT(0 != encoder->private_);
656
return FLAC__stream_encoder_get_max_residual_partition_order(encoder->private_->stream_encoder);
659
FLAC_API unsigned FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(const FLAC__SeekableStreamEncoder *encoder)
661
FLAC__ASSERT(0 != encoder);
662
FLAC__ASSERT(0 != encoder->private_);
663
return FLAC__stream_encoder_get_rice_parameter_search_dist(encoder->private_->stream_encoder);
666
FLAC_API FLAC__uint64 FLAC__seekable_stream_encoder_get_total_samples_estimate(const FLAC__SeekableStreamEncoder *encoder)
668
FLAC__ASSERT(0 != encoder);
669
FLAC__ASSERT(0 != encoder->private_);
670
return FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->stream_encoder);
673
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_process(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
675
FLAC__ASSERT(0 != encoder);
676
FLAC__ASSERT(0 != encoder->private_);
677
if(!FLAC__stream_encoder_process(encoder->private_->stream_encoder, buffer, samples)) {
678
encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
685
/* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
686
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_process_interleaved(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
688
FLAC__ASSERT(0 != encoder);
689
FLAC__ASSERT(0 != encoder->private_);
690
if(!FLAC__stream_encoder_process_interleaved(encoder->private_->stream_encoder, buffer, samples)) {
691
encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR;
698
/***********************************************************************
700
* Private class methods
702
***********************************************************************/
704
void set_defaults_(FLAC__SeekableStreamEncoder *encoder)
706
FLAC__ASSERT(0 != encoder);
707
FLAC__ASSERT(0 != encoder->private_);
708
FLAC__ASSERT(0 != encoder->protected_);
710
encoder->private_->seek_callback = 0;
711
encoder->private_->tell_callback = 0;
712
encoder->private_->write_callback = 0;
713
encoder->private_->client_data = 0;
715
encoder->private_->seek_table = 0;
718
FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *unused, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
720
FLAC__SeekableStreamEncoder *encoder = (FLAC__SeekableStreamEncoder*)client_data;
721
FLAC__StreamEncoderWriteStatus status;
722
FLAC__uint64 output_position;
724
(void)unused; /* silence compiler warning about unused parameter */
725
FLAC__ASSERT(encoder->private_->stream_encoder == unused);
727
if(encoder->private_->tell_callback(encoder, &output_position, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK)
728
return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR;
731
* Watch for the STREAMINFO block and first SEEKTABLE block to go by and store their offsets.
734
FLAC__MetadataType type = (buffer[0] & 0x7f);
735
if(type == FLAC__METADATA_TYPE_STREAMINFO)
736
encoder->protected_->streaminfo_offset = output_position;
737
else if(type == FLAC__METADATA_TYPE_SEEKTABLE && encoder->protected_->seektable_offset == 0)
738
encoder->protected_->seektable_offset = output_position;
742
* Mark the current seek point if hit (if audio_offset == 0 that
743
* means we're still writing metadata and haven't hit the first
746
if(0 != encoder->private_->seek_table && encoder->protected_->audio_offset > 0 && encoder->private_->seek_table->num_points > 0) {
747
const unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder->private_->stream_encoder);
748
const FLAC__uint64 frame_first_sample = encoder->private_->samples_written;
749
const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1;
750
FLAC__uint64 test_sample;
752
for(i = encoder->private_->first_seekpoint_to_check; i < encoder->private_->seek_table->num_points; i++) {
753
test_sample = encoder->private_->seek_table->points[i].sample_number;
754
if(test_sample > frame_last_sample) {
757
else if(test_sample >= frame_first_sample) {
758
encoder->private_->seek_table->points[i].sample_number = frame_first_sample;
759
encoder->private_->seek_table->points[i].stream_offset = output_position - encoder->protected_->audio_offset;
760
encoder->private_->seek_table->points[i].frame_samples = blocksize;
761
encoder->private_->first_seekpoint_to_check++;
762
/* DO NOT: "break;" and here's why:
763
* The seektable template may contain more than one target
764
* sample for any given frame; we will keep looping, generating
765
* duplicate seekpoints for them, and we'll clean it up later,
766
* just before writing the seektable back to the metadata.
770
encoder->private_->first_seekpoint_to_check++;
775
status = encoder->private_->write_callback(encoder, buffer, bytes, samples, current_frame, encoder->private_->client_data);
777
if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
778
encoder->private_->samples_written += samples;
781
encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
786
void metadata_callback_(const FLAC__StreamEncoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
788
FLAC__SeekableStreamEncoder *encoder = (FLAC__SeekableStreamEncoder*)client_data;
789
FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
790
const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
791
const unsigned min_framesize = metadata->data.stream_info.min_framesize;
792
const unsigned max_framesize = metadata->data.stream_info.max_framesize;
793
const unsigned bps = metadata->data.stream_info.bits_per_sample;
795
FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
797
/* We get called by the stream encoder when the encoding process
798
* has finished so that we can update the STREAMINFO and SEEKTABLE
802
(void)unused; /* silence compiler warning about unused parameter */
803
FLAC__ASSERT(encoder->private_->stream_encoder == unused);
805
/*@@@ reopen callback here? The docs currently require user to open files in update mode from the start */
807
/* All this is based on intimate knowledge of the stream header
808
* layout, but a change to the header format that would break this
809
* would also break all streams encoded in the previous format.
813
* Write MD5 signature
816
const unsigned md5_offset =
817
FLAC__STREAM_METADATA_HEADER_LENGTH +
819
FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
820
FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
821
FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
822
FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
823
FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
824
FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
825
FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN +
826
FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN
829
if(encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + md5_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
830
encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
833
if(encoder->private_->write_callback(encoder, metadata->data.stream_info.md5sum, 16, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
834
encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
840
* Write total samples
843
const unsigned total_samples_byte_offset =
844
FLAC__STREAM_METADATA_HEADER_LENGTH +
846
FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
847
FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
848
FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
849
FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
850
FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
851
FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
852
FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN
856
b[0] = ((FLAC__byte)(bps-1) << 4) | (FLAC__byte)((samples >> 32) & 0x0F);
857
b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
858
b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
859
b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
860
b[4] = (FLAC__byte)(samples & 0xFF);
861
if(encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + total_samples_byte_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
862
encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
865
if(encoder->private_->write_callback(encoder, b, 5, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
866
encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
872
* Write min/max framesize
875
const unsigned min_framesize_offset =
876
FLAC__STREAM_METADATA_HEADER_LENGTH +
878
FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
879
FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN
882
b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
883
b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
884
b[2] = (FLAC__byte)(min_framesize & 0xFF);
885
b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
886
b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
887
b[5] = (FLAC__byte)(max_framesize & 0xFF);
888
if(encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + min_framesize_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
889
encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
892
if(encoder->private_->write_callback(encoder, b, 6, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
893
encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
901
if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) {
904
FLAC__format_seektable_sort(encoder->private_->seek_table);
906
FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table));
908
if(encoder->private_->seek_callback(encoder, encoder->protected_->seektable_offset + FLAC__STREAM_METADATA_HEADER_LENGTH, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) {
909
encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR;
913
for(i = 0; i < encoder->private_->seek_table->num_points; i++) {
916
xx = encoder->private_->seek_table->points[i].sample_number;
917
b[7] = (FLAC__byte)xx; xx >>= 8;
918
b[6] = (FLAC__byte)xx; xx >>= 8;
919
b[5] = (FLAC__byte)xx; xx >>= 8;
920
b[4] = (FLAC__byte)xx; xx >>= 8;
921
b[3] = (FLAC__byte)xx; xx >>= 8;
922
b[2] = (FLAC__byte)xx; xx >>= 8;
923
b[1] = (FLAC__byte)xx; xx >>= 8;
924
b[0] = (FLAC__byte)xx; xx >>= 8;
925
xx = encoder->private_->seek_table->points[i].stream_offset;
926
b[15] = (FLAC__byte)xx; xx >>= 8;
927
b[14] = (FLAC__byte)xx; xx >>= 8;
928
b[13] = (FLAC__byte)xx; xx >>= 8;
929
b[12] = (FLAC__byte)xx; xx >>= 8;
930
b[11] = (FLAC__byte)xx; xx >>= 8;
931
b[10] = (FLAC__byte)xx; xx >>= 8;
932
b[9] = (FLAC__byte)xx; xx >>= 8;
933
b[8] = (FLAC__byte)xx; xx >>= 8;
934
x = encoder->private_->seek_table->points[i].frame_samples;
935
b[17] = (FLAC__byte)x; x >>= 8;
936
b[16] = (FLAC__byte)x; x >>= 8;
937
if(encoder->private_->write_callback(encoder, b, 18, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
938
encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;