1 /* flac - Command-line FLAC encoder/decoder
2 * Copyright (C) 2000,2001,2002,2003,2004,2005,2006 Josh Coalson
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program 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
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #if defined _WIN32 && !defined __CYGWIN__
24 /* where MSVC puts unlink() */
29 #if defined _MSC_VER || defined __MINGW32__
30 #include <sys/types.h> /* for off_t */
31 //@@@ [2G limit] hacks for MSVC6
36 #include <limits.h> /* for LONG_MAX */
37 #include <math.h> /* for floor() */
38 #include <stdio.h> /* for FILE etc. */
39 #include <stdlib.h> /* for malloc */
40 #include <string.h> /* for strcmp(), strerror( */
42 #include "share/grabbag.h"
46 #include "OggFLAC/stream_encoder.h"
52 #define min(x,y) ((x)<(y)?(x):(y))
56 #define max(x,y) ((x)>(y)?(x):(y))
58 /* this MUST be >= 588 so that sector aligning can take place with one read */
59 #define CHUNK_OF_SAMPLES 2048
67 const char *inbasefilename;
68 const char *outfilename;
71 FLAC__uint64 until; /* a value of 0 mean end-of-stream (i.e. --until=-0) */
72 FLAC__bool replay_gain;
74 unsigned bits_per_sample;
76 FLAC__uint64 unencoded_size;
77 FLAC__uint64 total_samples_to_encode;
78 FLAC__uint64 bytes_written;
79 FLAC__uint64 samples_written;
84 FLAC__StreamEncoder *flac;
86 OggFLAC__StreamEncoder *ogg;
92 FLAC__StreamMetadata *seek_table_template;
95 /* this is data attached to the FLAC decoder when encoding from a FLAC file */
97 EncoderSession *encoder_session;
99 const FLAC__byte *lookahead;
100 unsigned lookahead_length;
101 size_t num_metadata_blocks;
102 FLAC__StreamMetadata *metadata_blocks[1024]; /*@@@ BAD MAGIC number */
103 FLAC__uint64 samples_left_to_process;
104 FLAC__bool fatal_error;
107 const int FLAC_ENCODE__DEFAULT_PADDING = 4096;
109 static FLAC__bool is_big_endian_host_;
111 static unsigned char ucbuffer_[CHUNK_OF_SAMPLES*FLAC__MAX_CHANNELS*((FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE+7)/8)];
112 static signed char *scbuffer_ = (signed char *)ucbuffer_;
113 static FLAC__uint16 *usbuffer_ = (FLAC__uint16 *)ucbuffer_;
114 static FLAC__int16 *ssbuffer_ = (FLAC__int16 *)ucbuffer_;
116 static FLAC__int32 in_[FLAC__MAX_CHANNELS][CHUNK_OF_SAMPLES];
117 static FLAC__int32 *input_[FLAC__MAX_CHANNELS];
121 * unpublished debug routines from the FLAC libs
123 extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
124 extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
125 extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
127 extern FLAC__bool OggFLAC__stream_encoder_disable_constant_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value);
128 extern FLAC__bool OggFLAC__stream_encoder_disable_fixed_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value);
129 extern FLAC__bool OggFLAC__stream_encoder_disable_verbatim_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value);
135 static FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FILE *infile, const char *infilename, const char *outfilename);
136 static void EncoderSession_destroy(EncoderSession *e);
137 static int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero);
138 static int EncoderSession_finish_error(EncoderSession *e);
139 static FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, unsigned channels, unsigned bps, unsigned sample_rate, FLACDecoderData *flac_decoder_data);
140 static FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples);
141 static FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int num_requested_seek_points, FLAC__StreamMetadata *cuesheet, EncoderSession *e);
142 static FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input);
143 static void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps);
144 static void encoder_progress_callback(const FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data);
145 static FLAC__StreamDecoderReadStatus flac_decoder_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
146 static FLAC__StreamDecoderSeekStatus flac_decoder_seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
147 static FLAC__StreamDecoderTellStatus flac_decoder_tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
148 static FLAC__StreamDecoderLengthStatus flac_decoder_length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
149 static FLAC__bool flac_decoder_eof_callback(const FLAC__StreamDecoder *decoder, void *client_data);
150 static FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
151 static void flac_decoder_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
152 static void flac_decoder_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
153 static FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset);
154 static void print_stats(const EncoderSession *encoder_session);
155 static void print_error_with_init_status(const EncoderSession *e, const char *message, FLAC__StreamEncoderInitStatus init_status);
156 static void print_error_with_state(const EncoderSession *e, const char *message);
157 static void print_verify_error(EncoderSession *e);
158 static FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn);
159 static FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
160 static FLAC__bool read_big_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn);
161 static FLAC__bool read_big_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
162 static FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
163 static FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset);
168 int flac__encode_aif(FILE *infile, off_t infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options, FLAC__bool is_aifc)
170 EncoderSession encoder_session;
173 unsigned int channels= 0U, bps= 0U, sample_rate= 0U, sample_frames= 0U;
174 FLAC__bool got_comm_chunk= false, got_ssnd_chunk= false;
175 int info_align_carry= -1, info_align_zero= -1;
176 FLAC__bool is_big_endian_pcm = true;
178 (void)infilesize; /* silence compiler warning about unused parameter */
179 (void)lookahead; /* silence compiler warning about unused parameter */
180 (void)lookahead_length; /* silence compiler warning about unused parameter */
183 EncoderSession_construct(
186 options.common.use_ogg,
190 options.common.verify,
198 /* lookahead[] already has "FORMxxxxAIFF", do sub-chunks */
202 char chunk_id[5] = { '\0', '\0', '\0', '\0', '\0' }; /* one extra byte for terminating NUL so we can also treat it like a C string */
204 /* chunk identifier; really conservative about behavior of fread() and feof() */
205 if(feof(infile) || ((c= fread(chunk_id, 1U, 4U, infile)), c==0U && feof(infile)))
207 else if(c<4U || feof(infile)) {
208 flac__utils_printf(stderr, 1, "%s: ERROR: incomplete chunk identifier\n", encoder_session.inbasefilename);
209 return EncoderSession_finish_error(&encoder_session);
212 if(got_comm_chunk==false && !memcmp(chunk_id, "COMM", 4)) { /* common chunk */
214 const FLAC__uint32 minimum_comm_size = (is_aifc? 22 : 18);
216 /* COMM chunk size */
217 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
218 return EncoderSession_finish_error(&encoder_session);
219 else if(xx<minimum_comm_size) {
220 flac__utils_printf(stderr, 1, "%s: ERROR: non-standard %s 'COMM' chunk has length = %u\n", encoder_session.inbasefilename, is_aifc? "AIFF-C" : "AIFF", (unsigned int)xx);
221 return EncoderSession_finish_error(&encoder_session);
223 else if(!is_aifc && xx!=minimum_comm_size) {
224 flac__utils_printf(stderr, 1, "%s: WARNING: non-standard %s 'COMM' chunk has length = %u, expected %u\n", encoder_session.inbasefilename, is_aifc? "AIFF-C" : "AIFF", (unsigned int)xx, minimum_comm_size);
226 skip= (xx-minimum_comm_size)+(xx & 1U);
228 /* number of channels */
229 if(!read_big_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
230 return EncoderSession_finish_error(&encoder_session);
231 else if(x==0U || x>FLAC__MAX_CHANNELS) {
232 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported number channels %u\n", encoder_session.inbasefilename, (unsigned int)x);
233 return EncoderSession_finish_error(&encoder_session);
235 else if(options.common.sector_align && x!=2U) {
236 flac__utils_printf(stderr, 1, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_session.inbasefilename, (unsigned int)x);
237 return EncoderSession_finish_error(&encoder_session);
241 /* number of sample frames */
242 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
243 return EncoderSession_finish_error(&encoder_session);
246 /* bits per sample */
247 if(!read_big_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
248 return EncoderSession_finish_error(&encoder_session);
249 else if(x!=8U && x!=16U && x!=24U) {
250 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported bits per sample %u\n", encoder_session.inbasefilename, (unsigned int)x);
251 return EncoderSession_finish_error(&encoder_session);
253 else if(options.common.sector_align && x!=16U) {
254 flac__utils_printf(stderr, 1, "%s: ERROR: file has %u bits per sample, must be 16 for --sector-align\n", encoder_session.inbasefilename, (unsigned int)x);
255 return EncoderSession_finish_error(&encoder_session);
260 if(!read_sane_extended(infile, &xx, false, encoder_session.inbasefilename))
261 return EncoderSession_finish_error(&encoder_session);
262 else if(!FLAC__format_sample_rate_is_valid(xx)) {
263 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported sample rate %u\n", encoder_session.inbasefilename, (unsigned int)xx);
264 return EncoderSession_finish_error(&encoder_session);
266 else if(options.common.sector_align && xx!=44100U) {
267 flac__utils_printf(stderr, 1, "%s: ERROR: file's sample rate is %u, must be 44100 for --sector-align\n", encoder_session.inbasefilename, (unsigned int)xx);
268 return EncoderSession_finish_error(&encoder_session);
272 /* check compression type for AIFF-C */
274 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
275 return EncoderSession_finish_error(&encoder_session);
276 if(xx == 0x736F7774) /* "sowt" */
277 is_big_endian_pcm = false;
278 else if(xx == 0x4E4F4E45) /* "NONE" */
279 ; /* nothing to do, we already default to big-endian */
281 flac__utils_printf(stderr, 1, "%s: ERROR: can't handle AIFF-C compression type \"%c%c%c%c\"\n", encoder_session.inbasefilename, (char)(xx>>24), (char)((xx>>16)&8), (char)((xx>>8)&8), (char)(xx&8));
282 return EncoderSession_finish_error(&encoder_session);
286 /* skip any extra data in the COMM chunk */
287 if(!fskip_ahead(infile, skip)) {
288 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping extra COMM data\n", encoder_session.inbasefilename);
289 return EncoderSession_finish_error(&encoder_session);
293 * now that we know the sample rate, canonicalize the
294 * --skip string to a number of samples:
296 flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, sample_rate);
297 FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
298 encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
299 FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
301 got_comm_chunk= true;
303 else if(got_ssnd_chunk==false && !memcmp(chunk_id, "SSND", 4)) { /* sound data chunk */
304 unsigned int offset= 0U, block_size= 0U, align_remainder= 0U, data_bytes;
305 size_t bytes_per_frame= channels*(bps>>3);
306 FLAC__uint64 total_samples_in_input, trim = 0;
307 FLAC__bool pad= false;
309 if(got_comm_chunk==false) {
310 flac__utils_printf(stderr, 1, "%s: ERROR: got 'SSND' chunk before 'COMM' chunk\n", encoder_session.inbasefilename);
311 return EncoderSession_finish_error(&encoder_session);
314 /* SSND chunk size */
315 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
316 return EncoderSession_finish_error(&encoder_session);
318 pad= (data_bytes & 1U) ? true : false;
319 data_bytes-= 8U; /* discount the offset and block size fields */
322 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
323 return EncoderSession_finish_error(&encoder_session);
328 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
329 return EncoderSession_finish_error(&encoder_session);
331 flac__utils_printf(stderr, 1, "%s: ERROR: block size is %u; must be 0\n", encoder_session.inbasefilename, (unsigned int)xx);
332 return EncoderSession_finish_error(&encoder_session);
336 /* skip any SSND offset bytes */
337 FLAC__ASSERT(offset<=LONG_MAX);
338 if(!fskip_ahead(infile, offset)) {
339 flac__utils_printf(stderr, 1, "%s: ERROR: skipping offset in SSND chunk\n", encoder_session.inbasefilename);
340 return EncoderSession_finish_error(&encoder_session);
342 if(data_bytes!=(sample_frames*bytes_per_frame)) {
343 flac__utils_printf(stderr, 1, "%s: ERROR: SSND chunk size inconsistent with sample frame count\n", encoder_session.inbasefilename);
344 return EncoderSession_finish_error(&encoder_session);
347 /* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
348 FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
349 total_samples_in_input = data_bytes / bytes_per_frame + *options.common.align_reservoir_samples;
352 * now that we know the input size, canonicalize the
353 * --until string to an absolute sample number:
355 if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, sample_rate, encoder_session.skip, total_samples_in_input))
356 return EncoderSession_finish_error(&encoder_session);
357 encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
358 FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
360 if(encoder_session.skip>0U) {
361 if(!fskip_ahead(infile, encoder_session.skip*bytes_per_frame)) {
362 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
363 return EncoderSession_finish_error(&encoder_session);
367 data_bytes-= (unsigned int)encoder_session.skip*bytes_per_frame; /*@@@ WATCHOUT: 4GB limit */
368 encoder_session.total_samples_to_encode= total_samples_in_input - encoder_session.skip;
369 if(encoder_session.until > 0) {
370 trim = total_samples_in_input - encoder_session.until;
371 FLAC__ASSERT(total_samples_in_input > 0);
372 FLAC__ASSERT(!options.common.sector_align);
373 data_bytes-= (unsigned int)trim*bytes_per_frame;
374 encoder_session.total_samples_to_encode-= trim;
376 if(options.common.sector_align) {
377 align_remainder= (unsigned int)(encoder_session.total_samples_to_encode % 588U);
378 if(options.common.is_last_file)
379 encoder_session.total_samples_to_encode+= (588U-align_remainder); /* will pad with zeroes */
381 encoder_session.total_samples_to_encode-= align_remainder; /* will stop short and carry over to next file */
384 /* +54 for the size of the AIFF headers; this is just an estimate for the progress indicator and doesn't need to be exact */
385 encoder_session.unencoded_size= encoder_session.total_samples_to_encode*bytes_per_frame+54;
387 if(!EncoderSession_init_encoder(&encoder_session, options.common, channels, bps, sample_rate, /*flac_decoder_data=*/0))
388 return EncoderSession_finish_error(&encoder_session);
390 /* first do any samples in the reservoir */
391 if(options.common.sector_align && *options.common.align_reservoir_samples>0U) {
393 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
394 print_error_with_state(&encoder_session, "ERROR during encoding");
395 return EncoderSession_finish_error(&encoder_session);
399 /* decrement the data_bytes counter if we need to align the file */
400 if(options.common.sector_align) {
401 if(options.common.is_last_file)
402 *options.common.align_reservoir_samples= 0U;
404 *options.common.align_reservoir_samples= align_remainder;
405 data_bytes-= (*options.common.align_reservoir_samples)*bytes_per_frame;
409 /* now do from the file */
410 while(data_bytes>0) {
411 size_t bytes_read= fread(ucbuffer_, 1U, min(data_bytes, CHUNK_OF_SAMPLES*bytes_per_frame), infile);
415 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
416 return EncoderSession_finish_error(&encoder_session);
418 else if(feof(infile)) {
419 flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned int)encoder_session.total_samples_to_encode, (unsigned int)encoder_session.samples_written);
424 if(bytes_read % bytes_per_frame != 0U) {
425 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
426 return EncoderSession_finish_error(&encoder_session);
429 unsigned int frames= bytes_read/bytes_per_frame;
430 format_input(input_, frames, is_big_endian_pcm, /*is_unsigned_samples=*/false, channels, bps);
432 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)input_, frames)) {
433 print_error_with_state(&encoder_session, "ERROR during encoding");
434 return EncoderSession_finish_error(&encoder_session);
437 data_bytes-= bytes_read;
443 FLAC__ASSERT(!options.common.sector_align);
444 if(!fskip_ahead(infile, trim*bytes_per_frame)) {
445 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
446 return EncoderSession_finish_error(&encoder_session);
450 /* now read unaligned samples into reservoir or pad with zeroes if necessary */
451 if(options.common.sector_align) {
452 if(options.common.is_last_file) {
453 unsigned int pad_frames= 588U-align_remainder;
455 if(pad_frames<588U) {
458 info_align_zero= pad_frames;
459 for(i= 0U; i<channels; ++i)
460 memset(input_[i], 0, sizeof(input_[0][0])*pad_frames);
462 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)input_, pad_frames)) {
463 print_error_with_state(&encoder_session, "ERROR during encoding");
464 return EncoderSession_finish_error(&encoder_session);
469 if(*options.common.align_reservoir_samples > 0) {
470 size_t bytes_read= fread(ucbuffer_, 1U, (*options.common.align_reservoir_samples)*bytes_per_frame, infile);
472 FLAC__ASSERT(CHUNK_OF_SAMPLES>=588U);
473 if(bytes_read==0U && ferror(infile)) {
474 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
475 return EncoderSession_finish_error(&encoder_session);
477 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_frame) {
478 flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned int)bytes_read, (unsigned int)encoder_session.total_samples_to_encode, (unsigned int)encoder_session.samples_written);
481 info_align_carry= *options.common.align_reservoir_samples;
482 format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, is_big_endian_pcm, /*is_unsigned_samples=*/false, channels, bps);
491 if(fread(&tmp, 1U, 1U, infile)<1U) {
492 flac__utils_printf(stderr, 1, "%s: ERROR during read of SSND pad byte\n", encoder_session.inbasefilename);
493 return EncoderSession_finish_error(&encoder_session);
497 got_ssnd_chunk= true;
499 else { /* other chunk */
500 if(!memcmp(chunk_id, "COMM", 4)) {
501 flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'COMM' chunk\n", encoder_session.inbasefilename);
503 else if(!memcmp(chunk_id, "SSND", 4)) {
504 flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'SSND' chunk\n", encoder_session.inbasefilename);
507 flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown chunk '%s'\n", encoder_session.inbasefilename, chunk_id);
511 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
512 return EncoderSession_finish_error(&encoder_session);
514 unsigned long skip= xx+(xx & 1U);
516 FLAC__ASSERT(skip<=LONG_MAX);
517 if(!fskip_ahead(infile, skip)) {
518 fprintf(stderr, "%s: ERROR during read while skipping unknown chunk\n", encoder_session.inbasefilename);
519 return EncoderSession_finish_error(&encoder_session);
525 if(got_ssnd_chunk==false && sample_frames!=0U) {
526 flac__utils_printf(stderr, 1, "%s: ERROR: missing SSND chunk\n", encoder_session.inbasefilename);
527 return EncoderSession_finish_error(&encoder_session);
530 return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
533 int flac__encode_wav(FILE *infile, off_t infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options)
535 EncoderSession encoder_session;
536 FLAC__bool is_unsigned_samples = false;
537 unsigned channels = 0, bps = 0, sample_rate = 0;
538 size_t bytes_per_wide_sample, bytes_read;
541 FLAC__bool got_fmt_chunk = false, got_data_chunk = false;
542 unsigned align_remainder = 0;
543 int info_align_carry = -1, info_align_zero = -1;
547 (void)lookahead_length;
550 EncoderSession_construct(
553 options.common.use_ogg,
557 options.common.verify,
566 * lookahead[] already has "RIFFxxxxWAVE", do sub-chunks
568 while(!feof(infile)) {
569 if(!read_little_endian_uint32(infile, &xx, true, encoder_session.inbasefilename))
570 return EncoderSession_finish_error(&encoder_session);
573 if(xx == 0x20746d66 && !got_fmt_chunk) { /* "fmt " */
574 unsigned block_align, data_bytes;
576 /* fmt sub-chunk size */
577 if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
578 return EncoderSession_finish_error(&encoder_session);
580 flac__utils_printf(stderr, 1, "%s: ERROR: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_session.inbasefilename, (unsigned)xx);
581 return EncoderSession_finish_error(&encoder_session);
583 else if(xx != 16 && xx != 18) {
584 flac__utils_printf(stderr, 1, "%s: WARNING: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_session.inbasefilename, (unsigned)xx);
587 /* compression code */
588 if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
589 return EncoderSession_finish_error(&encoder_session);
591 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported compression type %u\n", encoder_session.inbasefilename, (unsigned)x);
592 return EncoderSession_finish_error(&encoder_session);
594 /* number of channels */
595 if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
596 return EncoderSession_finish_error(&encoder_session);
597 if(x == 0 || x > FLAC__MAX_CHANNELS) {
598 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported number channels %u\n", encoder_session.inbasefilename, (unsigned)x);
599 return EncoderSession_finish_error(&encoder_session);
601 else if(options.common.sector_align && x != 2) {
602 flac__utils_printf(stderr, 1, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_session.inbasefilename, (unsigned)x);
603 return EncoderSession_finish_error(&encoder_session);
607 if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
608 return EncoderSession_finish_error(&encoder_session);
609 if(!FLAC__format_sample_rate_is_valid(xx)) {
610 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported sample rate %u\n", encoder_session.inbasefilename, (unsigned)xx);
611 return EncoderSession_finish_error(&encoder_session);
613 else if(options.common.sector_align && xx != 44100) {
614 flac__utils_printf(stderr, 1, "%s: ERROR: file's sample rate is %u, must be 44100 for --sector-align\n", encoder_session.inbasefilename, (unsigned)xx);
615 return EncoderSession_finish_error(&encoder_session);
618 /* avg bytes per second (ignored) */
619 if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
620 return EncoderSession_finish_error(&encoder_session);
622 if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
623 return EncoderSession_finish_error(&encoder_session);
625 /* bits per sample */
626 if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
627 return EncoderSession_finish_error(&encoder_session);
628 if(x != 8 && x != 16 && x != 24) {
629 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported bits-per-sample %u\n", encoder_session.inbasefilename, (unsigned)x);
630 return EncoderSession_finish_error(&encoder_session);
632 else if(options.common.sector_align && x != 16) {
633 flac__utils_printf(stderr, 1, "%s: ERROR: file has %u bits per sample, must be 16 for --sector-align\n", encoder_session.inbasefilename, (unsigned)x);
634 return EncoderSession_finish_error(&encoder_session);
637 if(bps * channels != block_align * 8) {
638 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported block alignment (%u), for bits-per-sample=%u, channels=%u\n", encoder_session.inbasefilename, block_align, bps, channels);
639 return EncoderSession_finish_error(&encoder_session);
641 is_unsigned_samples = (x == 8);
643 /* skip any extra data in the fmt sub-chunk */
644 FLAC__ASSERT(data_bytes >= 16);
646 if(!fskip_ahead(infile, data_bytes)) {
647 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping extra 'fmt' data\n", encoder_session.inbasefilename);
648 return EncoderSession_finish_error(&encoder_session);
652 * now that we know the sample rate, canonicalize the
653 * --skip string to a number of samples:
655 flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, sample_rate);
656 FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
657 encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
658 FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
660 got_fmt_chunk = true;
662 else if(xx == 0x61746164 && !got_data_chunk && got_fmt_chunk) { /* "data" */
663 FLAC__uint64 total_samples_in_input, trim = 0;
664 FLAC__bool pad = false;
668 if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
669 return EncoderSession_finish_error(&encoder_session);
671 pad = (data_bytes & 1U) ? true : false;
673 bytes_per_wide_sample = channels * (bps >> 3);
675 /* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
676 FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
677 total_samples_in_input = data_bytes / bytes_per_wide_sample + *options.common.align_reservoir_samples;
680 * now that we know the input size, canonicalize the
681 * --until string to an absolute sample number:
683 if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, sample_rate, encoder_session.skip, total_samples_in_input))
684 return EncoderSession_finish_error(&encoder_session);
685 encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
686 FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
688 if(encoder_session.skip > 0) {
689 if(!fskip_ahead(infile, encoder_session.skip * bytes_per_wide_sample)) {
690 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
691 return EncoderSession_finish_error(&encoder_session);
695 data_bytes -= (unsigned)encoder_session.skip * bytes_per_wide_sample; /*@@@ WATCHOUT: 4GB limit */
696 encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
697 if(encoder_session.until > 0) {
698 trim = total_samples_in_input - encoder_session.until;
699 FLAC__ASSERT(total_samples_in_input > 0);
700 FLAC__ASSERT(!options.common.sector_align);
701 data_bytes -= (unsigned int)trim * bytes_per_wide_sample;
702 encoder_session.total_samples_to_encode -= trim;
704 if(options.common.sector_align) {
705 align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
706 if(options.common.is_last_file)
707 encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
709 encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
712 /* +44 for the size of the WAV headers; this is just an estimate for the progress indicator and doesn't need to be exact */
713 encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample + 44;
715 if(!EncoderSession_init_encoder(&encoder_session, options.common, channels, bps, sample_rate, /*flac_decoder_data=*/0))
716 return EncoderSession_finish_error(&encoder_session);
719 * first do any samples in the reservoir
721 if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
722 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
723 print_error_with_state(&encoder_session, "ERROR during encoding");
724 return EncoderSession_finish_error(&encoder_session);
729 * decrement the data_bytes counter if we need to align the file
731 if(options.common.sector_align) {
732 if(options.common.is_last_file) {
733 *options.common.align_reservoir_samples = 0;
736 *options.common.align_reservoir_samples = align_remainder;
737 data_bytes -= (*options.common.align_reservoir_samples) * bytes_per_wide_sample;
742 * now do from the file
744 while(data_bytes > 0) {
745 bytes_read = fread(ucbuffer_, sizeof(unsigned char), min(data_bytes, CHUNK_OF_SAMPLES * bytes_per_wide_sample), infile);
746 if(bytes_read == 0) {
748 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
749 return EncoderSession_finish_error(&encoder_session);
751 else if(feof(infile)) {
752 flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
757 if(bytes_read % bytes_per_wide_sample != 0) {
758 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
759 return EncoderSession_finish_error(&encoder_session);
762 unsigned wide_samples = bytes_read / bytes_per_wide_sample;
763 format_input(input_, wide_samples, /*is_big_endian=*/false, is_unsigned_samples, channels, bps);
765 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
766 print_error_with_state(&encoder_session, "ERROR during encoding");
767 return EncoderSession_finish_error(&encoder_session);
769 data_bytes -= bytes_read;
775 FLAC__ASSERT(!options.common.sector_align);
776 if(!fskip_ahead(infile, trim * bytes_per_wide_sample)) {
777 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
778 return EncoderSession_finish_error(&encoder_session);
783 * now read unaligned samples into reservoir or pad with zeroes if necessary
785 if(options.common.sector_align) {
786 if(options.common.is_last_file) {
787 unsigned wide_samples = 588 - align_remainder;
788 if(wide_samples < 588) {
791 info_align_zero = wide_samples;
792 for(channel = 0; channel < channels; channel++)
793 memset(input_[channel], 0, sizeof(input_[0][0]) * wide_samples);
795 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
796 print_error_with_state(&encoder_session, "ERROR during encoding");
797 return EncoderSession_finish_error(&encoder_session);
802 if(*options.common.align_reservoir_samples > 0) {
803 FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
804 bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
805 if(bytes_read == 0 && ferror(infile)) {
806 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
807 return EncoderSession_finish_error(&encoder_session);
809 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
810 flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)bytes_read, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
813 info_align_carry = *options.common.align_reservoir_samples;
814 format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, /*is_big_endian=*/false, is_unsigned_samples, channels, bps);
823 if(fread(&tmp, 1U, 1U, infile) < 1U) {
824 flac__utils_printf(stderr, 1, "%s: ERROR during read of data pad byte\n", encoder_session.inbasefilename);
825 return EncoderSession_finish_error(&encoder_session);
829 got_data_chunk = true;
832 if(xx == 0x20746d66 && got_fmt_chunk) { /* "fmt " */
833 flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'fmt ' sub-chunk\n", encoder_session.inbasefilename);
835 else if(xx == 0x61746164) { /* "data" */
837 flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'data' sub-chunk\n", encoder_session.inbasefilename);
839 else if(!got_fmt_chunk) {
840 flac__utils_printf(stderr, 1, "%s: ERROR: got 'data' sub-chunk before 'fmt' sub-chunk\n", encoder_session.inbasefilename);
841 return EncoderSession_finish_error(&encoder_session);
848 flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown sub-chunk '%c%c%c%c'\n", encoder_session.inbasefilename, (char)(xx&255), (char)((xx>>8)&255), (char)((xx>>16)&255), (char)(xx>>24));
851 if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
852 return EncoderSession_finish_error(&encoder_session);
854 unsigned long skip = xx+(xx & 1U);
856 FLAC__ASSERT(skip<=LONG_MAX);
857 if(!fskip_ahead(infile, skip)) {
858 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping unsupported sub-chunk\n", encoder_session.inbasefilename);
859 return EncoderSession_finish_error(&encoder_session);
865 return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
868 int flac__encode_raw(FILE *infile, off_t infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, raw_encode_options_t options)
870 EncoderSession encoder_session;
872 const size_t bytes_per_wide_sample = options.channels * (options.bps >> 3);
873 unsigned align_remainder = 0;
874 int info_align_carry = -1, info_align_zero = -1;
875 FLAC__uint64 total_samples_in_input = 0;
877 FLAC__ASSERT(!options.common.sector_align || options.channels == 2);
878 FLAC__ASSERT(!options.common.sector_align || options.bps == 16);
879 FLAC__ASSERT(!options.common.sector_align || options.sample_rate == 44100);
880 FLAC__ASSERT(!options.common.sector_align || infilesize >= 0);
881 FLAC__ASSERT(!options.common.replay_gain || options.channels <= 2);
882 FLAC__ASSERT(!options.common.replay_gain || grabbag__replaygain_is_valid_sample_frequency(options.sample_rate));
885 EncoderSession_construct(
888 options.common.use_ogg,
892 options.common.verify,
901 * now that we know the sample rate, canonicalize the
902 * --skip string to a number of samples:
904 flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, options.sample_rate);
905 FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
906 encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
907 FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
910 total_samples_in_input = 0;
912 /* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
913 FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
914 total_samples_in_input = (FLAC__uint64)infilesize / bytes_per_wide_sample + *options.common.align_reservoir_samples;
918 * now that we know the input size, canonicalize the
919 * --until strings to a number of samples:
921 if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, options.sample_rate, encoder_session.skip, total_samples_in_input))
922 return EncoderSession_finish_error(&encoder_session);
923 encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
924 FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
926 infilesize -= (off_t)encoder_session.skip * bytes_per_wide_sample;
927 encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
928 if(encoder_session.until > 0) {
929 const FLAC__uint64 trim = total_samples_in_input - encoder_session.until;
930 FLAC__ASSERT(total_samples_in_input > 0);
931 FLAC__ASSERT(!options.common.sector_align);
932 infilesize -= (off_t)trim * bytes_per_wide_sample;
933 encoder_session.total_samples_to_encode -= trim;
935 if(infilesize >= 0 && options.common.sector_align) {
936 FLAC__ASSERT(encoder_session.skip == 0);
937 align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
938 if(options.common.is_last_file)
939 encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
941 encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
943 encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample;
945 if(encoder_session.total_samples_to_encode <= 0)
946 flac__utils_printf(stderr, 2, "(No runtime statistics possible; please wait for encoding to finish...)\n");
948 if(encoder_session.skip > 0) {
949 unsigned skip_bytes = bytes_per_wide_sample * (unsigned)encoder_session.skip;
950 if(skip_bytes > lookahead_length) {
951 skip_bytes -= lookahead_length;
952 lookahead_length = 0;
953 if(!fskip_ahead(infile, skip_bytes)) {
954 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
955 return EncoderSession_finish_error(&encoder_session);
959 lookahead += skip_bytes;
960 lookahead_length -= skip_bytes;
964 if(!EncoderSession_init_encoder(&encoder_session, options.common, options.channels, options.bps, options.sample_rate, /*flac_decoder_data=*/0))
965 return EncoderSession_finish_error(&encoder_session);
968 * first do any samples in the reservoir
970 if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
971 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
972 print_error_with_state(&encoder_session, "ERROR during encoding");
973 return EncoderSession_finish_error(&encoder_session);
978 * decrement infilesize if we need to align the file
980 if(options.common.sector_align) {
981 FLAC__ASSERT(infilesize >= 0);
982 if(options.common.is_last_file) {
983 *options.common.align_reservoir_samples = 0;
986 *options.common.align_reservoir_samples = align_remainder;
987 infilesize -= (off_t)((*options.common.align_reservoir_samples) * bytes_per_wide_sample);
988 FLAC__ASSERT(infilesize >= 0);
993 * now do from the file
996 while(!feof(infile)) {
997 if(lookahead_length > 0) {
998 FLAC__ASSERT(lookahead_length < CHUNK_OF_SAMPLES * bytes_per_wide_sample);
999 memcpy(ucbuffer_, lookahead, lookahead_length);
1000 bytes_read = fread(ucbuffer_+lookahead_length, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample - lookahead_length, infile) + lookahead_length;
1001 if(ferror(infile)) {
1002 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1003 return EncoderSession_finish_error(&encoder_session);
1005 lookahead_length = 0;
1008 bytes_read = fread(ucbuffer_, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample, infile);
1010 if(bytes_read == 0) {
1011 if(ferror(infile)) {
1012 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1013 return EncoderSession_finish_error(&encoder_session);
1016 else if(bytes_read % bytes_per_wide_sample != 0) {
1017 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
1018 return EncoderSession_finish_error(&encoder_session);
1021 unsigned wide_samples = bytes_read / bytes_per_wide_sample;
1022 format_input(input_, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);
1024 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1025 print_error_with_state(&encoder_session, "ERROR during encoding");
1026 return EncoderSession_finish_error(&encoder_session);
1032 const FLAC__uint64 max_input_bytes = infilesize;
1033 FLAC__uint64 total_input_bytes_read = 0;
1034 while(total_input_bytes_read < max_input_bytes) {
1036 size_t wanted = (CHUNK_OF_SAMPLES * bytes_per_wide_sample);
1037 wanted = (size_t) min((FLAC__uint64)wanted, max_input_bytes - total_input_bytes_read);
1039 if(lookahead_length > 0) {
1040 FLAC__ASSERT(lookahead_length <= wanted);
1041 memcpy(ucbuffer_, lookahead, lookahead_length);
1042 wanted -= lookahead_length;
1043 bytes_read = lookahead_length;
1045 bytes_read += fread(ucbuffer_+lookahead_length, sizeof(unsigned char), wanted, infile);
1046 if(ferror(infile)) {
1047 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1048 return EncoderSession_finish_error(&encoder_session);
1051 lookahead_length = 0;
1054 bytes_read = fread(ucbuffer_, sizeof(unsigned char), wanted, infile);
1057 if(bytes_read == 0) {
1058 if(ferror(infile)) {
1059 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1060 return EncoderSession_finish_error(&encoder_session);
1062 else if(feof(infile)) {
1063 flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
1064 total_input_bytes_read = max_input_bytes;
1068 if(bytes_read % bytes_per_wide_sample != 0) {
1069 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
1070 return EncoderSession_finish_error(&encoder_session);
1073 unsigned wide_samples = bytes_read / bytes_per_wide_sample;
1074 format_input(input_, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);
1076 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1077 print_error_with_state(&encoder_session, "ERROR during encoding");
1078 return EncoderSession_finish_error(&encoder_session);
1080 total_input_bytes_read += bytes_read;
1087 * now read unaligned samples into reservoir or pad with zeroes if necessary
1089 if(options.common.sector_align) {
1090 if(options.common.is_last_file) {
1091 unsigned wide_samples = 588 - align_remainder;
1092 if(wide_samples < 588) {
1095 info_align_zero = wide_samples;
1096 for(channel = 0; channel < options.channels; channel++)
1097 memset(input_[channel], 0, sizeof(input_[0][0]) * wide_samples);
1099 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1100 print_error_with_state(&encoder_session, "ERROR during encoding");
1101 return EncoderSession_finish_error(&encoder_session);
1106 if(*options.common.align_reservoir_samples > 0) {
1107 FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
1108 bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
1109 if(bytes_read == 0 && ferror(infile)) {
1110 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1111 return EncoderSession_finish_error(&encoder_session);
1113 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
1114 flac__utils_printf(stderr, 1, "%s: WARNING: unexpected EOF; read %u bytes; expected %u samples, got %u samples\n", encoder_session.inbasefilename, (unsigned)bytes_read, (unsigned)encoder_session.total_samples_to_encode, (unsigned)encoder_session.samples_written);
1117 info_align_carry = *options.common.align_reservoir_samples;
1118 format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);
1124 return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
1127 int flac__encode_flac(FILE *infile, off_t infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, flac_encode_options_t options)
1129 EncoderSession encoder_session;
1130 FLAC__StreamDecoder *decoder = 0;
1131 FLACDecoderData decoder_data;
1136 EncoderSession_construct(
1138 #ifdef FLAC__HAS_OGG
1139 options.common.use_ogg,
1143 options.common.verify,
1151 decoder_data.encoder_session = &encoder_session;
1152 decoder_data.filesize = (infilesize == (off_t)(-1)? 0 : infilesize);
1153 decoder_data.lookahead = lookahead;
1154 decoder_data.lookahead_length = lookahead_length;
1155 decoder_data.num_metadata_blocks = 0;
1156 decoder_data.samples_left_to_process = 0;
1157 decoder_data.fatal_error = false;
1160 * set up FLAC decoder for the input
1162 if (0 == (decoder = FLAC__stream_decoder_new())) {
1163 flac__utils_printf(stderr, 1, "%s: ERROR: creating decoder for FLAC input\n", encoder_session.inbasefilename);
1164 return EncoderSession_finish_error(&encoder_session);
1167 FLAC__stream_decoder_set_md5_checking(decoder, false) &&
1168 FLAC__stream_decoder_set_metadata_respond_all(decoder)
1170 flac__utils_printf(stderr, 1, "%s: ERROR: setting up decoder for FLAC input\n", encoder_session.inbasefilename);
1171 goto fubar1; /*@@@ yuck */
1174 if (FLAC__stream_decoder_init_stream(decoder, flac_decoder_read_callback, flac_decoder_seek_callback, flac_decoder_tell_callback, flac_decoder_length_callback, flac_decoder_eof_callback, flac_decoder_write_callback, flac_decoder_metadata_callback, flac_decoder_error_callback, /*client_data=*/&decoder_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
1175 flac__utils_printf(stderr, 1, "%s: ERROR: initializing decoder for FLAC input, state = %s\n", encoder_session.inbasefilename, FLAC__stream_decoder_get_resolved_state_string(decoder));
1176 goto fubar1; /*@@@ yuck */
1179 if (!FLAC__stream_decoder_process_until_end_of_metadata(decoder) || decoder_data.fatal_error) {
1180 if (decoder_data.fatal_error)
1181 flac__utils_printf(stderr, 1, "%s: ERROR: out of memory or too many metadata blocks while reading metadata in FLAC input\n", encoder_session.inbasefilename);
1183 flac__utils_printf(stderr, 1, "%s: ERROR: reading metadata in FLAC input, state = %s\n", encoder_session.inbasefilename, FLAC__stream_decoder_get_resolved_state_string(decoder));
1184 goto fubar1; /*@@@ yuck */
1187 if (decoder_data.num_metadata_blocks == 0) {
1188 flac__utils_printf(stderr, 1, "%s: ERROR: reading metadata in FLAC input, got no metadata blocks\n", encoder_session.inbasefilename);
1189 goto fubar2; /*@@@ yuck */
1191 else if (decoder_data.metadata_blocks[0]->type != FLAC__METADATA_TYPE_STREAMINFO) {
1192 flac__utils_printf(stderr, 1, "%s: ERROR: reading metadata in FLAC input, first metadata block is not STREAMINFO\n", encoder_session.inbasefilename);
1193 goto fubar2; /*@@@ yuck */
1195 else if (decoder_data.metadata_blocks[0]->data.stream_info.total_samples == 0) {
1196 flac__utils_printf(stderr, 1, "%s: ERROR: FLAC input has STREAMINFO with unknown total samples which is not supported\n", encoder_session.inbasefilename);
1197 goto fubar2; /*@@@ yuck */
1201 * now that we have the STREAMINFO and know the sample rate,
1202 * canonicalize the --skip string to a number of samples:
1204 flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, decoder_data.metadata_blocks[0]->data.stream_info.sample_rate);
1205 FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
1206 encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
1207 FLAC__ASSERT(!options.common.sector_align); /* --sector-align with FLAC input is not supported */
1210 FLAC__uint64 total_samples_in_input, trim = 0;
1212 total_samples_in_input = decoder_data.metadata_blocks[0]->data.stream_info.total_samples;
1215 * now that we know the input size, canonicalize the
1216 * --until string to an absolute sample number:
1218 if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, decoder_data.metadata_blocks[0]->data.stream_info.sample_rate, encoder_session.skip, total_samples_in_input))
1219 goto fubar2; /*@@@ yuck */
1220 encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
1222 encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
1223 if(encoder_session.until > 0) {
1224 trim = total_samples_in_input - encoder_session.until;
1225 FLAC__ASSERT(total_samples_in_input > 0);
1226 encoder_session.total_samples_to_encode -= trim;
1229 encoder_session.unencoded_size = decoder_data.filesize;
1231 if(!EncoderSession_init_encoder(&encoder_session, options.common, decoder_data.metadata_blocks[0]->data.stream_info.channels, decoder_data.metadata_blocks[0]->data.stream_info.bits_per_sample, decoder_data.metadata_blocks[0]->data.stream_info.sample_rate, &decoder_data))
1232 return EncoderSession_finish_error(&encoder_session);
1235 * have to wait until the FLAC encoder is set up for writing
1236 * before any seeking in the input FLAC file, because the seek
1237 * itself will usually call the decoder's write callback, and
1238 * our decoder's write callback passes samples to our FLAC
1241 decoder_data.samples_left_to_process = encoder_session.total_samples_to_encode;
1242 if(encoder_session.skip > 0) {
1243 if(!FLAC__stream_decoder_seek_absolute(decoder, encoder_session.skip)) {
1244 flac__utils_printf(stderr, 1, "%s: ERROR while skipping samples, FLAC decoder state = %s\n", encoder_session.inbasefilename, FLAC__stream_decoder_get_resolved_state_string(decoder));
1245 goto fubar2; /*@@@ yuck */
1250 * now do samples from the file
1252 while(!decoder_data.fatal_error && decoder_data.samples_left_to_process > 0) {
1253 if(!FLAC__stream_decoder_process_single(decoder)) {
1254 flac__utils_printf(stderr, 1, "%s: ERROR: while decoding FLAC input, state = %s\n", encoder_session.inbasefilename, FLAC__stream_decoder_get_resolved_state_string(decoder));
1255 goto fubar2; /*@@@ yuck */
1260 FLAC__stream_decoder_delete(decoder);
1261 retval = EncoderSession_finish_ok(&encoder_session, -1, -1);
1262 /* have to wail until encoder is completely finished before deleting because of the final step of writing the seekpoint offsets */
1263 for(i = 0; i < decoder_data.num_metadata_blocks; i++)
1264 free(decoder_data.metadata_blocks[i]);
1268 for(i = 0; i < decoder_data.num_metadata_blocks; i++)
1269 free(decoder_data.metadata_blocks[i]);
1271 FLAC__stream_decoder_delete(decoder);
1272 return EncoderSession_finish_error(&encoder_session);
1275 FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FILE *infile, const char *infilename, const char *outfilename)
1278 FLAC__uint32 test = 1;
1281 * initialize globals
1284 is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;
1286 for(i = 0; i < FLAC__MAX_CHANNELS; i++)
1287 input_[i] = &(in_[i][0]);
1291 * initialize instance
1294 #ifdef FLAC__HAS_OGG
1295 e->use_ogg = use_ogg;
1301 e->is_stdout = (0 == strcmp(outfilename, "-"));
1303 e->inbasefilename = grabbag__file_get_basename(infilename);
1304 e->outfilename = outfilename;
1306 e->skip = 0; /* filled in later after the sample_rate is known */
1307 e->unencoded_size = 0;
1308 e->total_samples_to_encode = 0;
1309 e->bytes_written = 0;
1310 e->samples_written = 0;
1314 e->encoder.flac = 0;
1315 #ifdef FLAC__HAS_OGG
1321 e->seek_table_template = 0;
1324 e->fout = grabbag__file_get_binary_stdout();
1327 if(0 == (e->seek_table_template = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE))) {
1328 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1332 #ifdef FLAC__HAS_OGG
1334 e->encoder.ogg = OggFLAC__stream_encoder_new();
1335 if(0 == e->encoder.ogg) {
1336 flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1337 EncoderSession_destroy(e);
1343 e->encoder.flac = FLAC__stream_encoder_new();
1344 if(0 == e->encoder.flac) {
1345 flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1346 EncoderSession_destroy(e);
1353 void EncoderSession_destroy(EncoderSession *e)
1357 if(0 != e->fout && e->fout != stdout)
1360 #ifdef FLAC__HAS_OGG
1362 if(0 != e->encoder.ogg) {
1363 OggFLAC__stream_encoder_delete(e->encoder.ogg);
1369 if(0 != e->encoder.flac) {
1370 FLAC__stream_encoder_delete(e->encoder.flac);
1371 e->encoder.flac = 0;
1374 if(0 != e->seek_table_template) {
1375 FLAC__metadata_object_delete(e->seek_table_template);
1376 e->seek_table_template = 0;
1380 int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero)
1382 FLAC__StreamEncoderState fse_state = FLAC__STREAM_ENCODER_OK;
1385 #ifdef FLAC__HAS_OGG
1387 if(e->encoder.ogg) {
1388 fse_state = OggFLAC__stream_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg);
1389 OggFLAC__stream_encoder_finish(e->encoder.ogg);
1394 if(e->encoder.flac) {
1395 fse_state = FLAC__stream_encoder_get_state(e->encoder.flac);
1396 FLAC__stream_encoder_finish(e->encoder.flac);
1399 if(e->total_samples_to_encode > 0) {
1401 flac__utils_printf(stderr, 2, "\n");
1404 if(fse_state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA) {
1405 print_verify_error(e);
1409 if(info_align_carry >= 0) {
1410 flac__utils_printf(stderr, 1, "%s: INFO: sector alignment causing %d samples to be carried over\n", e->inbasefilename, info_align_carry);
1412 if(info_align_zero >= 0) {
1413 flac__utils_printf(stderr, 1, "%s: INFO: sector alignment causing %d zero samples to be appended\n", e->inbasefilename, info_align_zero);
1417 EncoderSession_destroy(e);
1422 int EncoderSession_finish_error(EncoderSession *e)
1424 FLAC__StreamEncoderState fse_state;
1426 if(e->total_samples_to_encode > 0)
1427 flac__utils_printf(stderr, 2, "\n");
1429 #ifdef FLAC__HAS_OGG
1431 fse_state = OggFLAC__stream_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg);
1436 fse_state = FLAC__stream_encoder_get_state(e->encoder.flac);
1439 if(fse_state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA)
1440 print_verify_error(e);
1442 /*@@@@@@@@@ BUG: if error was caused because the output file already exists but the file encoder could not write on top of it (i.e. it's not writable), this will delete the pre-existing file, which is not what we want */
1443 unlink(e->outfilename);
1445 EncoderSession_destroy(e);
1450 FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, unsigned channels, unsigned bps, unsigned sample_rate, FLACDecoderData *flac_decoder_data)
1452 unsigned num_metadata;
1453 FLAC__StreamMetadata padding, *cuesheet = 0;
1454 FLAC__StreamMetadata *static_metadata[4];
1455 FLAC__StreamMetadata **metadata = static_metadata;
1456 FLAC__StreamEncoderInitStatus init_status;
1457 const FLAC__bool is_cdda = (channels == 1 || channels == 2) && (bps == 16) && (sample_rate == 44100);
1459 e->replay_gain = options.replay_gain;
1460 e->channels = channels;
1461 e->bits_per_sample = bps;
1462 e->sample_rate = sample_rate;
1464 if(e->replay_gain) {
1465 if(channels != 1 && channels != 2) {
1466 flac__utils_printf(stderr, 1, "%s: ERROR, number of channels (%u) must be 1 or 2 for --replay-gain\n", e->inbasefilename, channels);
1469 if(!grabbag__replaygain_is_valid_sample_frequency(sample_rate)) {
1470 flac__utils_printf(stderr, 1, "%s: ERROR, invalid sample rate (%u) for --replay-gain\n", e->inbasefilename, sample_rate);
1473 if(options.is_first_file) {
1474 if(!grabbag__replaygain_init(sample_rate)) {
1475 flac__utils_printf(stderr, 1, "%s: ERROR initializing ReplayGain stage\n", e->inbasefilename);
1482 options.do_mid_side = options.loose_mid_side = false;
1484 if(!parse_cuesheet(&cuesheet, options.cuesheet_filename, e->inbasefilename, is_cdda, e->total_samples_to_encode))
1487 if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, options.cued_seekpoints? cuesheet : 0, e)) {
1488 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1490 FLAC__metadata_object_delete(cuesheet);
1494 if(flac_decoder_data) {
1496 * we're encoding from FLAC so we will use the FLAC file's
1497 * metadata as the basic for the encoded file
1501 * first handle padding: if --no-padding was specified,
1502 * then delete all padding; else if -P was specified,
1503 * use that instead of existing padding (if any); else
1504 * if existing file has padding, move all existing
1505 * padding blocks to one padding block at the end; else
1506 * use default padding.
1510 for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1511 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_PADDING) {
1514 p += flac_decoder_data->metadata_blocks[i]->length;
1515 FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1516 flac_decoder_data->metadata_blocks[i] = 0;
1519 flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1521 flac_decoder_data->num_metadata_blocks = j;
1522 if(options.padding > 0)
1523 p = options.padding;
1525 p = FLAC_ENCODE__DEFAULT_PADDING;
1526 if(options.padding != 0) {
1527 if(p > 0 && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
1528 flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING);
1529 if(0 == flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]) {
1530 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for PADDING block\n", e->inbasefilename);
1532 FLAC__metadata_object_delete(cuesheet);
1535 flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]->is_last = false; /* the encoder will set this for us */
1536 flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]->length = p;
1537 flac_decoder_data->num_metadata_blocks++;
1543 * next handle vorbis comment: if any tags were specified
1544 * or there is no existing vorbis comment, we create a
1545 * new vorbis comment (discarding any existing one); else
1546 * we keep the existing one
1549 FLAC__bool vc_found = false;
1550 for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1551 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
1553 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT && options.vorbis_comment->data.vorbis_comment.num_comments > 0) {
1554 if(options.vorbis_comment->data.vorbis_comment.num_comments > 0)
1555 flac__utils_printf(stderr, 1, "%s: WARNING, replacing tags from input FLAC file with those given on the command-line\n", e->inbasefilename);
1556 FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1557 flac_decoder_data->metadata_blocks[i] = 0;
1560 flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1562 flac_decoder_data->num_metadata_blocks = j;
1563 if((!vc_found || options.vorbis_comment->data.vorbis_comment.num_comments > 0) && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
1565 FLAC__StreamMetadata *vc = FLAC__metadata_object_clone(options.vorbis_comment);
1567 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for VORBIS_COMMENT block\n", e->inbasefilename);
1569 FLAC__metadata_object_delete(cuesheet);
1572 for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1573 flac_decoder_data->metadata_blocks[i] = flac_decoder_data->metadata_blocks[i-1];
1574 flac_decoder_data->metadata_blocks[1] = vc;
1575 flac_decoder_data->num_metadata_blocks++;
1580 * next handle cuesheet: if --cuesheet was specified, use
1581 * it; else if file has existing CUESHEET and cuesheet's
1582 * lead-out offset is correct, keep it; else no CUESHEET
1585 for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1586 FLAC__bool existing_cuesheet_is_bad = false;
1587 /* check if existing cuesheet matches the input audio */
1588 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && 0 == cuesheet) {
1589 const FLAC__StreamMetadata_CueSheet *cs = &flac_decoder_data->metadata_blocks[i]->data.cue_sheet;
1590 if(e->total_samples_to_encode == 0) {
1591 flac__utils_printf(stderr, 1, "%s: WARNING, cuesheet in input FLAC file cannot be kept if input size is not known, dropping it...\n", e->inbasefilename);
1592 existing_cuesheet_is_bad = true;
1594 else if(e->total_samples_to_encode != cs->tracks[cs->num_tracks-1].offset) {
1595 flac__utils_printf(stderr, 1, "%s: WARNING, lead-out offset of cuesheet in input FLAC file does not match input length, dropping existing cuesheet...\n", e->inbasefilename);
1596 existing_cuesheet_is_bad = true;
1599 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && (existing_cuesheet_is_bad || 0 != cuesheet)) {
1601 flac__utils_printf(stderr, 1, "%s: WARNING, replacing cuesheet in input FLAC file with the one given on the command-line\n", e->inbasefilename);
1602 FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1603 flac_decoder_data->metadata_blocks[i] = 0;
1606 flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1608 flac_decoder_data->num_metadata_blocks = j;
1609 if(0 != cuesheet && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
1611 FLAC__StreamMetadata *cs = FLAC__metadata_object_clone(cuesheet);
1613 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for CUESHEET block\n", e->inbasefilename);
1615 FLAC__metadata_object_delete(cuesheet);
1618 for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1619 flac_decoder_data->metadata_blocks[i] = flac_decoder_data->metadata_blocks[i-1];
1620 flac_decoder_data->metadata_blocks[1] = cs;
1621 flac_decoder_data->num_metadata_blocks++;
1626 * finally handle seektable: if -S- was specified, no
1627 * SEEKTABLE; else if -S was specified, use it/them;
1628 * else if file has existing SEEKTABLE and input size is
1629 * preserved (no --skip/--until/etc specified), keep it;
1630 * else use default seektable options
1632 * note: meanings of num_requested_seek_points:
1633 * -1 : no -S option given, default to some value
1634 * 0 : -S- given (no seektable)
1635 * >0 : one or more -S options given
1638 FLAC__bool existing_seektable = false;
1639 for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1640 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_SEEKTABLE)
1641 existing_seektable = true;
1642 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_SEEKTABLE && (e->total_samples_to_encode != flac_decoder_data->metadata_blocks[0]->data.stream_info.total_samples || options.num_requested_seek_points >= 0)) {
1643 if(options.num_requested_seek_points > 0)
1644 flac__utils_printf(stderr, 1, "%s: WARNING, replacing seektable in input FLAC file with the one given on the command-line\n", e->inbasefilename);
1645 else if(options.num_requested_seek_points == 0)
1646 ; /* no warning, silently delete existing SEEKTABLE since user specified --no-seektable (-S-) */
1648 flac__utils_printf(stderr, 1, "%s: WARNING, can't use existing seektable in input FLAC since the input size is changing or unknown, dropping existing SEEKTABLE block...\n", e->inbasefilename);
1649 FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1650 flac_decoder_data->metadata_blocks[i] = 0;
1651 existing_seektable = false;
1654 flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1656 flac_decoder_data->num_metadata_blocks = j;
1657 if((options.num_requested_seek_points > 0 || (options.num_requested_seek_points < 0 && !existing_seektable)) && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
1659 FLAC__StreamMetadata *st = FLAC__metadata_object_clone(e->seek_table_template);
1661 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for SEEKTABLE block\n", e->inbasefilename);
1663 FLAC__metadata_object_delete(cuesheet);
1666 for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1667 flac_decoder_data->metadata_blocks[i] = flac_decoder_data->metadata_blocks[i-1];
1668 flac_decoder_data->metadata_blocks[1] = st;
1669 flac_decoder_data->num_metadata_blocks++;
1672 metadata = &flac_decoder_data->metadata_blocks[1]; /* don't include STREAMINFO */
1673 num_metadata = flac_decoder_data->num_metadata_blocks - 1;
1677 * we're not encoding from FLAC so we will build the metadata
1681 if(e->seek_table_template->data.seek_table.num_points > 0) {
1682 e->seek_table_template->is_last = false; /* the encoder will set this for us */
1683 metadata[num_metadata++] = e->seek_table_template;
1686 metadata[num_metadata++] = cuesheet;
1687 metadata[num_metadata++] = options.vorbis_comment;
1688 if(options.padding != 0) {
1689 padding.is_last = false; /* the encoder will set this for us */
1690 padding.type = FLAC__METADATA_TYPE_PADDING;
1691 padding.length = (unsigned)(options.padding>0? options.padding : FLAC_ENCODE__DEFAULT_PADDING);
1692 metadata[num_metadata++] = &padding;
1696 e->blocksize = options.blocksize;
1697 e->stats_mask = (options.do_exhaustive_model_search || options.do_qlp_coeff_prec_search)? 0x0f : 0x3f;
1699 #ifdef FLAC__HAS_OGG
1701 OggFLAC__stream_encoder_set_serial_number(e->encoder.ogg, options.serial_number);
1702 OggFLAC__stream_encoder_set_verify(e->encoder.ogg, options.verify);
1703 OggFLAC__stream_encoder_set_streamable_subset(e->encoder.ogg, !options.lax);
1704 OggFLAC__stream_encoder_set_do_mid_side_stereo(e->encoder.ogg, options.do_mid_side);
1705 OggFLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder.ogg, options.loose_mid_side);
1706 OggFLAC__stream_encoder_set_channels(e->encoder.ogg, channels);
1707 OggFLAC__stream_encoder_set_bits_per_sample(e->encoder.ogg, bps);
1708 OggFLAC__stream_encoder_set_sample_rate(e->encoder.ogg, sample_rate);
1709 OggFLAC__stream_encoder_set_blocksize(e->encoder.ogg, options.blocksize);
1710 OggFLAC__stream_encoder_set_apodization(e->encoder.ogg, options.apodizations);
1711 OggFLAC__stream_encoder_set_max_lpc_order(e->encoder.ogg, options.max_lpc_order);
1712 OggFLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.ogg, options.qlp_coeff_precision);
1713 OggFLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.ogg, options.do_qlp_coeff_prec_search);
1714 OggFLAC__stream_encoder_set_do_escape_coding(e->encoder.ogg, options.do_escape_coding);
1715 OggFLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder.ogg, options.do_exhaustive_model_search);
1716 OggFLAC__stream_encoder_set_min_residual_partition_order(e->encoder.ogg, options.min_residual_partition_order);
1717 OggFLAC__stream_encoder_set_max_residual_partition_order(e->encoder.ogg, options.max_residual_partition_order);
1718 OggFLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder.ogg, options.rice_parameter_search_dist);
1719 OggFLAC__stream_encoder_set_total_samples_estimate(e->encoder.ogg, e->total_samples_to_encode);
1720 OggFLAC__stream_encoder_set_metadata(e->encoder.ogg, (num_metadata > 0)? metadata : 0, num_metadata);
1722 OggFLAC__stream_encoder_disable_constant_subframes(e->encoder.ogg, options.debug.disable_constant_subframes);
1723 OggFLAC__stream_encoder_disable_fixed_subframes(e->encoder.ogg, options.debug.disable_fixed_subframes);
1724 OggFLAC__stream_encoder_disable_verbatim_subframes(e->encoder.ogg, options.debug.disable_verbatim_subframes);
1726 init_status = OggFLAC__stream_encoder_init_file(e->encoder.ogg, e->is_stdout? 0 : e->outfilename, encoder_progress_callback, /*client_data=*/e);
1727 if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
1728 print_error_with_init_status(e, "ERROR initializing encoder", init_status);
1730 FLAC__metadata_object_delete(cuesheet);
1737 FLAC__stream_encoder_set_verify(e->encoder.flac, options.verify);
1738 FLAC__stream_encoder_set_streamable_subset(e->encoder.flac, !options.lax);
1739 FLAC__stream_encoder_set_do_mid_side_stereo(e->encoder.flac, options.do_mid_side);
1740 FLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder.flac, options.loose_mid_side);
1741 FLAC__stream_encoder_set_channels(e->encoder.flac, channels);
1742 FLAC__stream_encoder_set_bits_per_sample(e->encoder.flac, bps);
1743 FLAC__stream_encoder_set_sample_rate(e->encoder.flac, sample_rate);
1744 FLAC__stream_encoder_set_blocksize(e->encoder.flac, options.blocksize);
1745 FLAC__stream_encoder_set_apodization(e->encoder.flac, options.apodizations);
1746 FLAC__stream_encoder_set_max_lpc_order(e->encoder.flac, options.max_lpc_order);
1747 FLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.flac, options.qlp_coeff_precision);
1748 FLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.flac, options.do_qlp_coeff_prec_search);
1749 FLAC__stream_encoder_set_do_escape_coding(e->encoder.flac, options.do_escape_coding);
1750 FLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder.flac, options.do_exhaustive_model_search);
1751 FLAC__stream_encoder_set_min_residual_partition_order(e->encoder.flac, options.min_residual_partition_order);
1752 FLAC__stream_encoder_set_max_residual_partition_order(e->encoder.flac, options.max_residual_partition_order);
1753 FLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder.flac, options.rice_parameter_search_dist);
1754 FLAC__stream_encoder_set_total_samples_estimate(e->encoder.flac, e->total_samples_to_encode);
1755 FLAC__stream_encoder_set_metadata(e->encoder.flac, (num_metadata > 0)? metadata : 0, num_metadata);
1757 FLAC__stream_encoder_disable_constant_subframes(e->encoder.flac, options.debug.disable_constant_subframes);
1758 FLAC__stream_encoder_disable_fixed_subframes(e->encoder.flac, options.debug.disable_fixed_subframes);
1759 FLAC__stream_encoder_disable_verbatim_subframes(e->encoder.flac, options.debug.disable_verbatim_subframes);
1761 init_status = FLAC__stream_encoder_init_file(e->encoder.flac, e->is_stdout? 0 : e->outfilename, encoder_progress_callback, /*client_data=*/e);
1762 if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
1763 print_error_with_init_status(e, "ERROR initializing encoder", init_status);
1765 FLAC__metadata_object_delete(cuesheet);
1771 FLAC__metadata_object_delete(cuesheet);
1776 FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples)
1778 if(e->replay_gain) {
1779 if(!grabbag__replaygain_analyze(buffer, e->channels==2, e->bits_per_sample, samples)) {
1780 flac__utils_printf(stderr, 1, "%s: WARNING, error while calculating ReplayGain\n", e->inbasefilename);
1784 #ifdef FLAC__HAS_OGG
1786 return OggFLAC__stream_encoder_process(e->encoder.ogg, buffer, samples);
1789 return FLAC__stream_encoder_process(e->encoder.flac, buffer, samples);
1792 FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int num_requested_seek_points, FLAC__StreamMetadata *cuesheet, EncoderSession *e)
1794 const FLAC__bool only_placeholders = e->is_stdout;
1795 FLAC__bool has_real_points;
1797 if(num_requested_seek_points == 0 && 0 == cuesheet)
1800 if(num_requested_seek_points < 0) {
1801 requested_seek_points = "10s;";
1802 num_requested_seek_points = 1;
1805 if(num_requested_seek_points > 0) {
1806 if(!grabbag__seektable_convert_specification_to_template(requested_seek_points, only_placeholders, e->total_samples_to_encode, e->sample_rate, e->seek_table_template, &has_real_points))
1812 const FLAC__StreamMetadata_CueSheet *cs = &cuesheet->data.cue_sheet;
1813 for(i = 0; i < cs->num_tracks; i++) {
1814 const FLAC__StreamMetadata_CueSheet_Track *tr = cs->tracks+i;
1815 for(j = 0; j < tr->num_indices; j++) {
1816 if(!FLAC__metadata_object_seektable_template_append_point(e->seek_table_template, tr->offset + tr->indices[j].offset))
1818 has_real_points = true;
1822 if(!FLAC__metadata_object_seektable_template_sort(e->seek_table_template, /*compact=*/true))
1826 if(has_real_points) {
1828 flac__utils_printf(stderr, 1, "%s: WARNING, cannot write back seekpoints when encoding to stdout\n", e->inbasefilename);
1835 FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input)
1837 /* convert from mm:ss.sss to sample number if necessary */
1838 flac__utils_canonicalize_skip_until_specification(spec, sample_rate);
1840 /* special case: if "--until=-0", use the special value '0' to mean "end-of-stream" */
1841 if(spec->is_relative && spec->value.samples == 0) {
1842 spec->is_relative = false;
1846 /* in any other case the total samples in the input must be known */
1847 if(total_samples_in_input == 0) {
1848 flac__utils_printf(stderr, 1, "%s: ERROR, cannot use --until when input length is unknown\n", inbasefilename);
1852 FLAC__ASSERT(spec->value_is_samples);
1854 /* convert relative specifications to absolute */
1855 if(spec->is_relative) {
1856 if(spec->value.samples <= 0)
1857 spec->value.samples += (FLAC__int64)total_samples_in_input;
1859 spec->value.samples += skip;
1860 spec->is_relative = false;
1864 if(spec->value.samples < 0) {
1865 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before beginning of input\n", inbasefilename);
1868 if((FLAC__uint64)spec->value.samples <= skip) {
1869 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before --skip point\n", inbasefilename);
1872 if((FLAC__uint64)spec->value.samples > total_samples_in_input) {
1873 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is after end of input\n", inbasefilename);
1880 void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps)
1882 unsigned wide_sample, sample, channel, byte;
1885 if(is_unsigned_samples) {
1886 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1887 for(channel = 0; channel < channels; channel++, sample++)
1888 dest[channel][wide_sample] = (FLAC__int32)ucbuffer_[sample] - 0x80;
1891 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1892 for(channel = 0; channel < channels; channel++, sample++)
1893 dest[channel][wide_sample] = (FLAC__int32)scbuffer_[sample];
1896 else if(bps == 16) {
1897 if(is_big_endian != is_big_endian_host_) {
1899 const unsigned bytes = wide_samples * channels * (bps >> 3);
1900 for(byte = 0; byte < bytes; byte += 2) {
1901 tmp = ucbuffer_[byte];
1902 ucbuffer_[byte] = ucbuffer_[byte+1];
1903 ucbuffer_[byte+1] = tmp;
1906 if(is_unsigned_samples) {
1907 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1908 for(channel = 0; channel < channels; channel++, sample++)
1909 dest[channel][wide_sample] = (FLAC__int32)usbuffer_[sample] - 0x8000;
1912 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1913 for(channel = 0; channel < channels; channel++, sample++)
1914 dest[channel][wide_sample] = (FLAC__int32)ssbuffer_[sample];
1917 else if(bps == 24) {
1918 if(!is_big_endian) {
1920 const unsigned bytes = wide_samples * channels * (bps >> 3);
1921 for(byte = 0; byte < bytes; byte += 3) {
1922 tmp = ucbuffer_[byte];
1923 ucbuffer_[byte] = ucbuffer_[byte+2];
1924 ucbuffer_[byte+2] = tmp;
1927 if(is_unsigned_samples) {
1928 for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1929 for(channel = 0; channel < channels; channel++, sample++) {
1930 dest[channel][wide_sample] = ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1931 dest[channel][wide_sample] |= ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1932 dest[channel][wide_sample] |= ucbuffer_[byte++];
1933 dest[channel][wide_sample] -= 0x800000;
1937 for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1938 for(channel = 0; channel < channels; channel++, sample++) {
1939 dest[channel][wide_sample] = scbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1940 dest[channel][wide_sample] |= ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1941 dest[channel][wide_sample] |= ucbuffer_[byte++];
1950 #if 0 /*@@@@@@ old ogg progress callback, I don't think the comment about samples_written is true anymore but keep around until verified */
1951 void ogg_file_encoder_progress_callback(const OggFLAC__FileEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data)
1953 EncoderSession *encoder_session = (EncoderSession*)client_data;
1958 * With Ogg FLAC we don't get a value for 'samples_written', so we
1959 * estimate based on the frames written and the knowledge that all
1960 * blocks (except the last) are the same size.
1962 samples_written = frames_written * encoder_session->blocksize;
1963 flac_file_encoder_progress_callback(0, bytes_written, samples_written, frames_written, total_frames_estimate, client_data);
1968 void encoder_progress_callback(const FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data)
1970 EncoderSession *encoder_session = (EncoderSession*)client_data;
1972 (void)encoder, (void)total_frames_estimate;
1974 encoder_session->bytes_written = bytes_written;
1975 encoder_session->samples_written = samples_written;
1977 if(encoder_session->total_samples_to_encode > 0 && !((frames_written-1) & encoder_session->stats_mask))
1978 print_stats(encoder_session);
1981 FLAC__StreamDecoderReadStatus flac_decoder_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
1984 FLACDecoderData *data = (FLACDecoderData*)client_data;
1987 if (data->fatal_error)
1988 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
1990 /* use up lookahead first */
1991 if (data->lookahead_length) {
1992 n = min(data->lookahead_length, *bytes);
1993 memcpy(buffer, data->lookahead, n);
1995 data->lookahead += n;
1996 data->lookahead_length -= n;
1999 /* get the rest from file */
2001 *bytes = n + fread(buffer, 1, *bytes-n, data->encoder_session->fin);
2002 return ferror(data->encoder_session->fin)? FLAC__STREAM_DECODER_READ_STATUS_ABORT : FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
2005 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
2008 FLAC__StreamDecoderSeekStatus flac_decoder_seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
2010 FLACDecoderData *data = (FLACDecoderData*)client_data;
2013 if(fseeko(data->encoder_session->fin, (off_t)absolute_byte_offset, SEEK_SET) < 0)
2014 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
2016 return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
2019 FLAC__StreamDecoderTellStatus flac_decoder_tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
2021 FLACDecoderData *data = (FLACDecoderData*)client_data;
2025 if((pos = ftello(data->encoder_session->fin)) < 0)
2026 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
2028 *absolute_byte_offset = (FLAC__uint64)pos;
2029 return FLAC__STREAM_DECODER_TELL_STATUS_OK;
2033 FLAC__StreamDecoderLengthStatus flac_decoder_length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
2035 FLACDecoderData *data = (FLACDecoderData*)client_data;
2038 if(0 == data->filesize)
2039 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
2041 *stream_length = (FLAC__uint64)data->filesize;
2042 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
2046 FLAC__bool flac_decoder_eof_callback(const FLAC__StreamDecoder *decoder, void *client_data)
2048 FLACDecoderData *data = (FLACDecoderData*)client_data;
2051 return feof(data->encoder_session->fin)? true : false;
2054 FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
2056 FLACDecoderData *data = (FLACDecoderData*)client_data;
2057 FLAC__uint64 n = min(data->samples_left_to_process, frame->header.blocksize);
2060 if(!EncoderSession_process(data->encoder_session, buffer, (unsigned)n)) {
2061 print_error_with_state(data->encoder_session, "ERROR during encoding");
2062 data->fatal_error = true;
2063 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
2066 data->samples_left_to_process -= n;
2067 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
2070 void flac_decoder_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
2072 FLACDecoderData *data = (FLACDecoderData*)client_data;
2075 if (data->fatal_error)
2079 data->num_metadata_blocks == sizeof(data->metadata_blocks)/sizeof(data->metadata_blocks[0]) ||
2080 0 == (data->metadata_blocks[data->num_metadata_blocks] = FLAC__metadata_object_clone(metadata))
2082 data->fatal_error = true;
2084 data->num_metadata_blocks++;
2087 void flac_decoder_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
2089 FLACDecoderData *data = (FLACDecoderData*)client_data;
2092 flac__utils_printf(stderr, 1, "%s: ERROR got %s while decoding FLAC input\n", data->encoder_session->inbasefilename, FLAC__StreamDecoderErrorStatusString[status]);
2093 data->fatal_error = true;
2096 FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset)
2099 unsigned last_line_read;
2100 const char *error_message;
2102 if(0 == cuesheet_filename)
2105 if(lead_out_offset == 0) {
2106 flac__utils_printf(stderr, 1, "%s: ERROR cannot import cuesheet when the number of input samples to encode is unknown\n", inbasefilename);
2110 if(0 == (f = fopen(cuesheet_filename, "r"))) {
2111 flac__utils_printf(stderr, 1, "%s: ERROR opening cuesheet \"%s\" for reading: %s\n", inbasefilename, cuesheet_filename, strerror(errno));
2115 *cuesheet = grabbag__cuesheet_parse(f, &error_message, &last_line_read, is_cdda, lead_out_offset);
2119 if(0 == *cuesheet) {
2120 flac__utils_printf(stderr, 1, "%s: ERROR parsing cuesheet \"%s\" on line %u: %s\n", inbasefilename, cuesheet_filename, last_line_read, error_message);
2124 if(!FLAC__format_cuesheet_is_legal(&(*cuesheet)->data.cue_sheet, /*check_cd_da_subset=*/false, &error_message)) {
2125 flac__utils_printf(stderr, 1, "%s: ERROR parsing cuesheet \"%s\": %s\n", inbasefilename, cuesheet_filename, error_message);
2129 /* if we're expecting CDDA, warn about non-compliance */
2130 if(is_cdda && !FLAC__format_cuesheet_is_legal(&(*cuesheet)->data.cue_sheet, /*check_cd_da_subset=*/true, &error_message)) {
2131 flac__utils_printf(stderr, 1, "%s: WARNING cuesheet \"%s\" is not audio CD compliant: %s\n", inbasefilename, cuesheet_filename, error_message);
2132 (*cuesheet)->data.cue_sheet.is_cd = false;
2138 void print_stats(const EncoderSession *encoder_session)
2140 const FLAC__uint64 samples_written = min(encoder_session->total_samples_to_encode, encoder_session->samples_written);
2141 #if defined _MSC_VER || defined __MINGW32__
2142 /* with MSVC you have to spoon feed it the casting */
2143 const double progress = (double)(FLAC__int64)samples_written / (double)(FLAC__int64)encoder_session->total_samples_to_encode;
2144 const double ratio = (double)(FLAC__int64)encoder_session->bytes_written / ((double)(FLAC__int64)encoder_session->unencoded_size * min(1.0, progress));
2146 const double progress = (double)samples_written / (double)encoder_session->total_samples_to_encode;
2147 const double ratio = (double)encoder_session->bytes_written / ((double)encoder_session->unencoded_size * min(1.0, progress));
2151 if(samples_written == encoder_session->total_samples_to_encode) {
2152 flac__utils_printf(stderr, 2, "\r%s:%s wrote %u bytes, ratio=%0.3f",
2153 encoder_session->inbasefilename,
2154 encoder_session->verify? " Verify OK," : "",
2155 (unsigned)encoder_session->bytes_written,
2160 flac__utils_printf(stderr, 2, "\r%s: %u%% complete, ratio=%0.3f", encoder_session->inbasefilename, (unsigned)floor(progress * 100.0 + 0.5), ratio);
2164 void print_error_with_init_status(const EncoderSession *e, const char *message, FLAC__StreamEncoderInitStatus init_status)
2166 const int ilen = strlen(e->inbasefilename) + 1;
2167 const char *state_string = "";
2169 flac__utils_printf(stderr, 1, "\n%s: %s\n", e->inbasefilename, message);
2171 flac__utils_printf(stderr, 1, "%*s init_status = %s\n", ilen, "", FLAC__StreamEncoderInitStatusString[init_status]);
2173 if(init_status == FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR) {
2174 #ifdef FLAC__HAS_OGG
2176 state_string = OggFLAC__stream_encoder_get_resolved_state_string(e->encoder.ogg);
2179 state_string = FLAC__stream_encoder_get_resolved_state_string(e->encoder.flac);
2181 flac__utils_printf(stderr, 1, "%*s state = %s\n", ilen, "", state_string);
2183 /* print out some more info for some errors: */
2185 0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_CLIENT_ERROR])
2186 #ifdef FLAC__HAS_OGG
2187 || 0 == strcmp(state_string, OggFLAC__StreamEncoderStateString[OggFLAC__STREAM_ENCODER_CLIENT_ERROR])
2190 flac__utils_printf(stderr, 1,
2192 "An error occurred while writing; the most common cause is that the disk is full.\n"
2196 0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_IO_ERROR])
2197 #ifdef FLAC__HAS_OGG
2198 || 0 == strcmp(state_string, OggFLAC__StreamEncoderStateString[OggFLAC__STREAM_ENCODER_IO_ERROR])
2201 flac__utils_printf(stderr, 1,
2203 "An error occurred opening the output file; it is likely that the output\n"
2204 "directory does not exist or is not writable, the output file already exists and\n"
2205 "is not writable, or the disk is full.\n"
2209 else if(init_status == FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE) {
2210 flac__utils_printf(stderr, 1,
2212 "The encoding parameters specified do not conform to the FLAC Subset and may not\n"
2213 "be streamable or playable in hardware devices. Add --lax to the command-line\n"
2214 "options to encode with these parameters anyway.\n"
2219 void print_error_with_state(const EncoderSession *e, const char *message)
2221 const int ilen = strlen(e->inbasefilename) + 1;
2222 const char *state_string;
2224 flac__utils_printf(stderr, 1, "\n%s: %s\n", e->inbasefilename, message);
2226 #ifdef FLAC__HAS_OGG
2228 state_string = OggFLAC__stream_encoder_get_resolved_state_string(e->encoder.ogg);
2231 state_string = FLAC__stream_encoder_get_resolved_state_string(e->encoder.flac);
2233 flac__utils_printf(stderr, 1, "%*s state = %s\n", ilen, "", state_string);
2235 /* print out some more info for some errors: */
2237 0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_CLIENT_ERROR])
2238 #ifdef FLAC__HAS_OGG
2239 || 0 == strcmp(state_string, OggFLAC__StreamEncoderStateString[OggFLAC__STREAM_ENCODER_CLIENT_ERROR])
2242 flac__utils_printf(stderr, 1,
2244 "An error occurred while writing; the most common cause is that the disk is full.\n"
2249 void print_verify_error(EncoderSession *e)
2251 FLAC__uint64 absolute_sample;
2252 unsigned frame_number;
2255 FLAC__int32 expected;
2258 #ifdef FLAC__HAS_OGG
2260 OggFLAC__stream_encoder_get_verify_decoder_error_stats(e->encoder.ogg, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
2263 FLAC__stream_encoder_get_verify_decoder_error_stats(e->encoder.flac, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
2265 flac__utils_printf(stderr, 1, "%s: ERROR: mismatch in decoded data, verify FAILED!\n", e->inbasefilename);
2266 flac__utils_printf(stderr, 1, " Absolute sample=%u, frame=%u, channel=%u, sample=%u, expected %d, got %d\n", (unsigned)absolute_sample, frame_number, channel, sample, expected, got);
2267 flac__utils_printf(stderr, 1, " In all known cases, verify errors are caused by hardware problems,\n");
2268 flac__utils_printf(stderr, 1, " usually overclocking or bad RAM. Delete %s\n", e->outfilename);
2269 flac__utils_printf(stderr, 1, " and repeat the flac command exactly as before. If it does not give a\n");
2270 flac__utils_printf(stderr, 1, " verify error in the exact same place each time you try it, then there is\n");
2271 flac__utils_printf(stderr, 1, " a problem with your hardware; please see the FAQ:\n");
2272 flac__utils_printf(stderr, 1, " http://flac.sourceforge.net/faq.html#tools__hardware_prob\n");
2273 flac__utils_printf(stderr, 1, " If it does fail in the exact same place every time, keep\n");
2274 flac__utils_printf(stderr, 1, " %s and submit a bug report to:\n", e->outfilename);
2275 flac__utils_printf(stderr, 1, " https://sourceforge.net/bugs/?func=addbug&group_id=13478\n");
2276 flac__utils_printf(stderr, 1, " Make sure to upload the FLAC file and use the \"Monitor\" feature to\n");
2277 flac__utils_printf(stderr, 1, " monitor the bug status.\n");
2278 flac__utils_printf(stderr, 1, "Verify FAILED! Do not trust %s\n", e->outfilename);
2281 FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
2283 size_t bytes_read = fread(val, 1, 2, f);
2285 if(bytes_read == 0) {
2287 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2293 else if(bytes_read < 2) {
2294 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2298 if(is_big_endian_host_) {
2299 FLAC__byte tmp, *b = (FLAC__byte*)val;
2300 tmp = b[1]; b[1] = b[0]; b[0] = tmp;
2306 FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2308 size_t bytes_read = fread(val, 1, 4, f);
2310 if(bytes_read == 0) {
2312 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2318 else if(bytes_read < 4) {
2319 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2323 if(is_big_endian_host_) {
2324 FLAC__byte tmp, *b = (FLAC__byte*)val;
2325 tmp = b[3]; b[3] = b[0]; b[0] = tmp;
2326 tmp = b[2]; b[2] = b[1]; b[1] = tmp;
2332 FLAC__bool read_big_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
2334 unsigned char buf[4];
2335 size_t bytes_read= fread(buf, 1, 2, f);
2337 if(bytes_read==0U && eof_ok)
2339 else if(bytes_read<2U) {
2340 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2344 /* this is independent of host endianness */
2345 *val= (FLAC__uint16)(buf[0])<<8 | buf[1];
2350 FLAC__bool read_big_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2352 unsigned char buf[4];
2353 size_t bytes_read= fread(buf, 1, 4, f);
2355 if(bytes_read==0U && eof_ok)
2357 else if(bytes_read<4U) {
2358 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2362 /* this is independent of host endianness */
2363 *val= (FLAC__uint32)(buf[0])<<24 | (FLAC__uint32)(buf[1])<<16 |
2364 (FLAC__uint32)(buf[2])<<8 | buf[3];
2369 FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2370 /* Read an IEEE 754 80-bit (aka SANE) extended floating point value from 'f',
2371 * convert it into an integral value and store in 'val'. Return false if only
2372 * between 1 and 9 bytes remain in 'f', if 0 bytes remain in 'f' and 'eof_ok' is
2373 * false, or if the value is negative, between zero and one, or too large to be
2374 * represented by 'val'; return true otherwise.
2378 unsigned char buf[10];
2379 size_t bytes_read= fread(buf, 1U, 10U, f);
2380 FLAC__int16 e= ((FLAC__uint16)(buf[0])<<8 | (FLAC__uint16)(buf[1]))-0x3FFF;
2381 FLAC__int16 shift= 63-e;
2384 if(bytes_read==0U && eof_ok)
2386 else if(bytes_read<10U) {
2387 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2390 else if((buf[0]>>7)==1U || e<0 || e>63) {
2391 flac__utils_printf(stderr, 1, "%s: ERROR: invalid floating-point value\n", fn);
2395 for(i= 0U; i<8U; ++i)
2396 p|= (FLAC__uint64)(buf[i+2])<<(56U-i*8);
2397 *val= (FLAC__uint32)((p>>shift)+(p>>(shift-1) & 0x1));
2402 FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset)
2404 static unsigned char dump[8192];
2407 long need = (long)min(offset, LONG_MAX);
2408 if(fseeko(f, need, SEEK_CUR) < 0) {
2409 need = (long)min(offset, sizeof(dump));
2410 if((long)fread(dump, 1, need, f) < need)
2415 #if 0 /* pure non-fseek() version */
2417 const long need = (long)min(offset, sizeof(dump));
2418 if(fread(dump, 1, need, f) < need)