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;
91 FLAC__StreamMetadata *seek_table_template;
94 /* this is data attached to the FLAC decoder when encoding from a FLAC file */
96 EncoderSession *encoder_session;
98 const FLAC__byte *lookahead;
99 unsigned lookahead_length;
100 size_t num_metadata_blocks;
101 FLAC__StreamMetadata *metadata_blocks[1024]; /*@@@ BAD MAGIC number */
102 FLAC__uint64 samples_left_to_process;
103 FLAC__bool fatal_error;
106 const int FLAC_ENCODE__DEFAULT_PADDING = 4096;
108 static FLAC__bool is_big_endian_host_;
110 static unsigned char ucbuffer_[CHUNK_OF_SAMPLES*FLAC__MAX_CHANNELS*((FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE+7)/8)];
111 static signed char *scbuffer_ = (signed char *)ucbuffer_;
112 static FLAC__uint16 *usbuffer_ = (FLAC__uint16 *)ucbuffer_;
113 static FLAC__int16 *ssbuffer_ = (FLAC__int16 *)ucbuffer_;
115 static FLAC__int32 in_[FLAC__MAX_CHANNELS][CHUNK_OF_SAMPLES];
116 static FLAC__int32 *input_[FLAC__MAX_CHANNELS];
120 * unpublished debug routines from the FLAC libs
122 extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
123 extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
124 extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
126 extern FLAC__bool OggFLAC__stream_encoder_disable_constant_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value);
127 extern FLAC__bool OggFLAC__stream_encoder_disable_fixed_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value);
128 extern FLAC__bool OggFLAC__stream_encoder_disable_verbatim_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value);
134 static FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FILE *infile, const char *infilename, const char *outfilename);
135 static void EncoderSession_destroy(EncoderSession *e);
136 static int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero);
137 static int EncoderSession_finish_error(EncoderSession *e);
138 static FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, unsigned channels, unsigned bps, unsigned sample_rate, FLACDecoderData *flac_decoder_data);
139 static FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples);
140 static FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int num_requested_seek_points, FLAC__StreamMetadata *cuesheet, EncoderSession *e);
141 static FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input);
142 static void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps);
143 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);
144 static FLAC__StreamDecoderReadStatus flac_decoder_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
145 static FLAC__StreamDecoderSeekStatus flac_decoder_seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
146 static FLAC__StreamDecoderTellStatus flac_decoder_tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
147 static FLAC__StreamDecoderLengthStatus flac_decoder_length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
148 static FLAC__bool flac_decoder_eof_callback(const FLAC__StreamDecoder *decoder, void *client_data);
149 static FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
150 static void flac_decoder_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
151 static void flac_decoder_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
152 static FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset);
153 static void print_stats(const EncoderSession *encoder_session);
154 static void print_error_with_init_status(const EncoderSession *e, const char *message, FLAC__StreamEncoderInitStatus init_status);
155 static void print_error_with_state(const EncoderSession *e, const char *message);
156 static void print_verify_error(EncoderSession *e);
157 static FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn);
158 static FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
159 static FLAC__bool read_big_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn);
160 static FLAC__bool read_big_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
161 static FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
162 static FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset);
167 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)
169 EncoderSession encoder_session;
172 unsigned int channels= 0U, bps= 0U, sample_rate= 0U, sample_frames= 0U;
173 FLAC__bool got_comm_chunk= false, got_ssnd_chunk= false;
174 int info_align_carry= -1, info_align_zero= -1;
175 FLAC__bool is_big_endian_pcm = true;
177 (void)infilesize; /* silence compiler warning about unused parameter */
178 (void)lookahead; /* silence compiler warning about unused parameter */
179 (void)lookahead_length; /* silence compiler warning about unused parameter */
182 EncoderSession_construct(
185 options.common.use_ogg,
189 options.common.verify,
197 /* lookahead[] already has "FORMxxxxAIFF", do sub-chunks */
201 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 */
203 /* chunk identifier; really conservative about behavior of fread() and feof() */
204 if(feof(infile) || ((c= fread(chunk_id, 1U, 4U, infile)), c==0U && feof(infile)))
206 else if(c<4U || feof(infile)) {
207 flac__utils_printf(stderr, 1, "%s: ERROR: incomplete chunk identifier\n", encoder_session.inbasefilename);
208 return EncoderSession_finish_error(&encoder_session);
211 if(got_comm_chunk==false && !memcmp(chunk_id, "COMM", 4)) { /* common chunk */
213 const FLAC__uint32 minimum_comm_size = (is_aifc? 22 : 18);
215 /* COMM chunk size */
216 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
217 return EncoderSession_finish_error(&encoder_session);
218 else if(xx<minimum_comm_size) {
219 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);
220 return EncoderSession_finish_error(&encoder_session);
222 else if(!is_aifc && xx!=minimum_comm_size) {
223 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);
225 skip= (xx-minimum_comm_size)+(xx & 1U);
227 /* number of channels */
228 if(!read_big_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
229 return EncoderSession_finish_error(&encoder_session);
230 else if(x==0U || x>FLAC__MAX_CHANNELS) {
231 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported number channels %u\n", encoder_session.inbasefilename, (unsigned int)x);
232 return EncoderSession_finish_error(&encoder_session);
234 else if(options.common.sector_align && x!=2U) {
235 flac__utils_printf(stderr, 1, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_session.inbasefilename, (unsigned int)x);
236 return EncoderSession_finish_error(&encoder_session);
240 /* number of sample frames */
241 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
242 return EncoderSession_finish_error(&encoder_session);
245 /* bits per sample */
246 if(!read_big_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
247 return EncoderSession_finish_error(&encoder_session);
248 else if(x!=8U && x!=16U && x!=24U) {
249 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported bits per sample %u\n", encoder_session.inbasefilename, (unsigned int)x);
250 return EncoderSession_finish_error(&encoder_session);
252 else if(options.common.sector_align && x!=16U) {
253 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);
254 return EncoderSession_finish_error(&encoder_session);
259 if(!read_sane_extended(infile, &xx, false, encoder_session.inbasefilename))
260 return EncoderSession_finish_error(&encoder_session);
261 else if(!FLAC__format_sample_rate_is_valid(xx)) {
262 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported sample rate %u\n", encoder_session.inbasefilename, (unsigned int)xx);
263 return EncoderSession_finish_error(&encoder_session);
265 else if(options.common.sector_align && xx!=44100U) {
266 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);
267 return EncoderSession_finish_error(&encoder_session);
271 /* check compression type for AIFF-C */
273 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
274 return EncoderSession_finish_error(&encoder_session);
275 if(xx == 0x736F7774) /* "sowt" */
276 is_big_endian_pcm = false;
277 else if(xx == 0x4E4F4E45) /* "NONE" */
278 ; /* nothing to do, we already default to big-endian */
280 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));
281 return EncoderSession_finish_error(&encoder_session);
285 /* skip any extra data in the COMM chunk */
286 if(!fskip_ahead(infile, skip)) {
287 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping extra COMM data\n", encoder_session.inbasefilename);
288 return EncoderSession_finish_error(&encoder_session);
292 * now that we know the sample rate, canonicalize the
293 * --skip string to a number of samples:
295 flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, sample_rate);
296 FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
297 encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
298 FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
300 got_comm_chunk= true;
302 else if(got_ssnd_chunk==false && !memcmp(chunk_id, "SSND", 4)) { /* sound data chunk */
303 unsigned int offset= 0U, block_size= 0U, align_remainder= 0U, data_bytes;
304 size_t bytes_per_frame= channels*(bps>>3);
305 FLAC__uint64 total_samples_in_input, trim = 0;
306 FLAC__bool pad= false;
308 if(got_comm_chunk==false) {
309 flac__utils_printf(stderr, 1, "%s: ERROR: got 'SSND' chunk before 'COMM' chunk\n", encoder_session.inbasefilename);
310 return EncoderSession_finish_error(&encoder_session);
313 /* SSND chunk size */
314 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
315 return EncoderSession_finish_error(&encoder_session);
317 pad= (data_bytes & 1U) ? true : false;
318 data_bytes-= 8U; /* discount the offset and block size fields */
321 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
322 return EncoderSession_finish_error(&encoder_session);
327 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
328 return EncoderSession_finish_error(&encoder_session);
330 flac__utils_printf(stderr, 1, "%s: ERROR: block size is %u; must be 0\n", encoder_session.inbasefilename, (unsigned int)xx);
331 return EncoderSession_finish_error(&encoder_session);
335 /* skip any SSND offset bytes */
336 FLAC__ASSERT(offset<=LONG_MAX);
337 if(!fskip_ahead(infile, offset)) {
338 flac__utils_printf(stderr, 1, "%s: ERROR: skipping offset in SSND chunk\n", encoder_session.inbasefilename);
339 return EncoderSession_finish_error(&encoder_session);
341 if(data_bytes!=(sample_frames*bytes_per_frame)) {
342 flac__utils_printf(stderr, 1, "%s: ERROR: SSND chunk size inconsistent with sample frame count\n", encoder_session.inbasefilename);
343 return EncoderSession_finish_error(&encoder_session);
346 /* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
347 FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
348 total_samples_in_input = data_bytes / bytes_per_frame + *options.common.align_reservoir_samples;
351 * now that we know the input size, canonicalize the
352 * --until string to an absolute sample number:
354 if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, sample_rate, encoder_session.skip, total_samples_in_input))
355 return EncoderSession_finish_error(&encoder_session);
356 encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
357 FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
359 if(encoder_session.skip>0U) {
360 if(!fskip_ahead(infile, encoder_session.skip*bytes_per_frame)) {
361 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
362 return EncoderSession_finish_error(&encoder_session);
366 data_bytes-= (unsigned int)encoder_session.skip*bytes_per_frame; /*@@@ WATCHOUT: 4GB limit */
367 encoder_session.total_samples_to_encode= total_samples_in_input - encoder_session.skip;
368 if(encoder_session.until > 0) {
369 trim = total_samples_in_input - encoder_session.until;
370 FLAC__ASSERT(total_samples_in_input > 0);
371 FLAC__ASSERT(!options.common.sector_align);
372 data_bytes-= (unsigned int)trim*bytes_per_frame;
373 encoder_session.total_samples_to_encode-= trim;
375 if(options.common.sector_align) {
376 align_remainder= (unsigned int)(encoder_session.total_samples_to_encode % 588U);
377 if(options.common.is_last_file)
378 encoder_session.total_samples_to_encode+= (588U-align_remainder); /* will pad with zeroes */
380 encoder_session.total_samples_to_encode-= align_remainder; /* will stop short and carry over to next file */
383 /* +54 for the size of the AIFF headers; this is just an estimate for the progress indicator and doesn't need to be exact */
384 encoder_session.unencoded_size= encoder_session.total_samples_to_encode*bytes_per_frame+54;
386 if(!EncoderSession_init_encoder(&encoder_session, options.common, channels, bps, sample_rate, /*flac_decoder_data=*/0))
387 return EncoderSession_finish_error(&encoder_session);
389 /* first do any samples in the reservoir */
390 if(options.common.sector_align && *options.common.align_reservoir_samples>0U) {
392 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
393 print_error_with_state(&encoder_session, "ERROR during encoding");
394 return EncoderSession_finish_error(&encoder_session);
398 /* decrement the data_bytes counter if we need to align the file */
399 if(options.common.sector_align) {
400 if(options.common.is_last_file)
401 *options.common.align_reservoir_samples= 0U;
403 *options.common.align_reservoir_samples= align_remainder;
404 data_bytes-= (*options.common.align_reservoir_samples)*bytes_per_frame;
408 /* now do from the file */
409 while(data_bytes>0) {
410 size_t bytes_read= fread(ucbuffer_, 1U, min(data_bytes, CHUNK_OF_SAMPLES*bytes_per_frame), infile);
414 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
415 return EncoderSession_finish_error(&encoder_session);
417 else if(feof(infile)) {
418 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);
423 if(bytes_read % bytes_per_frame != 0U) {
424 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
425 return EncoderSession_finish_error(&encoder_session);
428 unsigned int frames= bytes_read/bytes_per_frame;
429 format_input(input_, frames, is_big_endian_pcm, /*is_unsigned_samples=*/false, channels, bps);
431 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)input_, frames)) {
432 print_error_with_state(&encoder_session, "ERROR during encoding");
433 return EncoderSession_finish_error(&encoder_session);
436 data_bytes-= bytes_read;
442 FLAC__ASSERT(!options.common.sector_align);
443 if(!fskip_ahead(infile, trim*bytes_per_frame)) {
444 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
445 return EncoderSession_finish_error(&encoder_session);
449 /* now read unaligned samples into reservoir or pad with zeroes if necessary */
450 if(options.common.sector_align) {
451 if(options.common.is_last_file) {
452 unsigned int pad_frames= 588U-align_remainder;
454 if(pad_frames<588U) {
457 info_align_zero= pad_frames;
458 for(i= 0U; i<channels; ++i)
459 memset(input_[i], 0, sizeof(input_[0][0])*pad_frames);
461 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)input_, pad_frames)) {
462 print_error_with_state(&encoder_session, "ERROR during encoding");
463 return EncoderSession_finish_error(&encoder_session);
468 if(*options.common.align_reservoir_samples > 0) {
469 size_t bytes_read= fread(ucbuffer_, 1U, (*options.common.align_reservoir_samples)*bytes_per_frame, infile);
471 FLAC__ASSERT(CHUNK_OF_SAMPLES>=588U);
472 if(bytes_read==0U && ferror(infile)) {
473 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
474 return EncoderSession_finish_error(&encoder_session);
476 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_frame) {
477 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);
480 info_align_carry= *options.common.align_reservoir_samples;
481 format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, is_big_endian_pcm, /*is_unsigned_samples=*/false, channels, bps);
490 if(fread(&tmp, 1U, 1U, infile)<1U) {
491 flac__utils_printf(stderr, 1, "%s: ERROR during read of SSND pad byte\n", encoder_session.inbasefilename);
492 return EncoderSession_finish_error(&encoder_session);
496 got_ssnd_chunk= true;
498 else { /* other chunk */
499 if(!memcmp(chunk_id, "COMM", 4)) {
500 flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'COMM' chunk\n", encoder_session.inbasefilename);
502 else if(!memcmp(chunk_id, "SSND", 4)) {
503 flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'SSND' chunk\n", encoder_session.inbasefilename);
506 flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown chunk '%s'\n", encoder_session.inbasefilename, chunk_id);
510 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
511 return EncoderSession_finish_error(&encoder_session);
513 unsigned long skip= xx+(xx & 1U);
515 FLAC__ASSERT(skip<=LONG_MAX);
516 if(!fskip_ahead(infile, skip)) {
517 fprintf(stderr, "%s: ERROR during read while skipping unknown chunk\n", encoder_session.inbasefilename);
518 return EncoderSession_finish_error(&encoder_session);
524 if(got_ssnd_chunk==false && sample_frames!=0U) {
525 flac__utils_printf(stderr, 1, "%s: ERROR: missing SSND chunk\n", encoder_session.inbasefilename);
526 return EncoderSession_finish_error(&encoder_session);
529 return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
532 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)
534 EncoderSession encoder_session;
535 FLAC__bool is_unsigned_samples = false;
536 unsigned channels = 0, bps = 0, sample_rate = 0;
537 size_t bytes_per_wide_sample, bytes_read;
540 FLAC__bool got_fmt_chunk = false, got_data_chunk = false;
541 unsigned align_remainder = 0;
542 int info_align_carry = -1, info_align_zero = -1;
546 (void)lookahead_length;
549 EncoderSession_construct(
552 options.common.use_ogg,
556 options.common.verify,
565 * lookahead[] already has "RIFFxxxxWAVE", do sub-chunks
567 while(!feof(infile)) {
568 if(!read_little_endian_uint32(infile, &xx, true, encoder_session.inbasefilename))
569 return EncoderSession_finish_error(&encoder_session);
572 if(xx == 0x20746d66 && !got_fmt_chunk) { /* "fmt " */
573 unsigned block_align, data_bytes;
575 /* fmt sub-chunk size */
576 if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
577 return EncoderSession_finish_error(&encoder_session);
579 flac__utils_printf(stderr, 1, "%s: ERROR: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_session.inbasefilename, (unsigned)xx);
580 return EncoderSession_finish_error(&encoder_session);
582 else if(xx != 16 && xx != 18) {
583 flac__utils_printf(stderr, 1, "%s: WARNING: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_session.inbasefilename, (unsigned)xx);
586 /* compression code */
587 if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
588 return EncoderSession_finish_error(&encoder_session);
590 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported compression type %u\n", encoder_session.inbasefilename, (unsigned)x);
591 return EncoderSession_finish_error(&encoder_session);
593 /* number of channels */
594 if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
595 return EncoderSession_finish_error(&encoder_session);
596 if(x == 0 || x > FLAC__MAX_CHANNELS) {
597 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported number channels %u\n", encoder_session.inbasefilename, (unsigned)x);
598 return EncoderSession_finish_error(&encoder_session);
600 else if(options.common.sector_align && x != 2) {
601 flac__utils_printf(stderr, 1, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_session.inbasefilename, (unsigned)x);
602 return EncoderSession_finish_error(&encoder_session);
606 if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
607 return EncoderSession_finish_error(&encoder_session);
608 if(!FLAC__format_sample_rate_is_valid(xx)) {
609 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported sample rate %u\n", encoder_session.inbasefilename, (unsigned)xx);
610 return EncoderSession_finish_error(&encoder_session);
612 else if(options.common.sector_align && xx != 44100) {
613 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);
614 return EncoderSession_finish_error(&encoder_session);
617 /* avg bytes per second (ignored) */
618 if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
619 return EncoderSession_finish_error(&encoder_session);
621 if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
622 return EncoderSession_finish_error(&encoder_session);
624 /* bits per sample */
625 if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
626 return EncoderSession_finish_error(&encoder_session);
627 if(x != 8 && x != 16 && x != 24) {
628 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported bits-per-sample %u\n", encoder_session.inbasefilename, (unsigned)x);
629 return EncoderSession_finish_error(&encoder_session);
631 else if(options.common.sector_align && x != 16) {
632 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);
633 return EncoderSession_finish_error(&encoder_session);
636 if(bps * channels != block_align * 8) {
637 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);
638 return EncoderSession_finish_error(&encoder_session);
640 is_unsigned_samples = (x == 8);
642 /* skip any extra data in the fmt sub-chunk */
643 FLAC__ASSERT(data_bytes >= 16);
645 if(!fskip_ahead(infile, data_bytes)) {
646 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping extra 'fmt' data\n", encoder_session.inbasefilename);
647 return EncoderSession_finish_error(&encoder_session);
651 * now that we know the sample rate, canonicalize the
652 * --skip string to a number of samples:
654 flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, sample_rate);
655 FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
656 encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
657 FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
659 got_fmt_chunk = true;
661 else if(xx == 0x61746164 && !got_data_chunk && got_fmt_chunk) { /* "data" */
662 FLAC__uint64 total_samples_in_input, trim = 0;
663 FLAC__bool pad = false;
667 if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
668 return EncoderSession_finish_error(&encoder_session);
670 pad = (data_bytes & 1U) ? true : false;
672 bytes_per_wide_sample = channels * (bps >> 3);
674 /* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
675 FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
676 total_samples_in_input = data_bytes / bytes_per_wide_sample + *options.common.align_reservoir_samples;
679 * now that we know the input size, canonicalize the
680 * --until string to an absolute sample number:
682 if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, sample_rate, encoder_session.skip, total_samples_in_input))
683 return EncoderSession_finish_error(&encoder_session);
684 encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
685 FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
687 if(encoder_session.skip > 0) {
688 if(!fskip_ahead(infile, encoder_session.skip * bytes_per_wide_sample)) {
689 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
690 return EncoderSession_finish_error(&encoder_session);
694 data_bytes -= (unsigned)encoder_session.skip * bytes_per_wide_sample; /*@@@ WATCHOUT: 4GB limit */
695 encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
696 if(encoder_session.until > 0) {
697 trim = total_samples_in_input - encoder_session.until;
698 FLAC__ASSERT(total_samples_in_input > 0);
699 FLAC__ASSERT(!options.common.sector_align);
700 data_bytes -= (unsigned int)trim * bytes_per_wide_sample;
701 encoder_session.total_samples_to_encode -= trim;
703 if(options.common.sector_align) {
704 align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
705 if(options.common.is_last_file)
706 encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
708 encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
711 /* +44 for the size of the WAV headers; this is just an estimate for the progress indicator and doesn't need to be exact */
712 encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample + 44;
714 if(!EncoderSession_init_encoder(&encoder_session, options.common, channels, bps, sample_rate, /*flac_decoder_data=*/0))
715 return EncoderSession_finish_error(&encoder_session);
718 * first do any samples in the reservoir
720 if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
721 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
722 print_error_with_state(&encoder_session, "ERROR during encoding");
723 return EncoderSession_finish_error(&encoder_session);
728 * decrement the data_bytes counter if we need to align the file
730 if(options.common.sector_align) {
731 if(options.common.is_last_file) {
732 *options.common.align_reservoir_samples = 0;
735 *options.common.align_reservoir_samples = align_remainder;
736 data_bytes -= (*options.common.align_reservoir_samples) * bytes_per_wide_sample;
741 * now do from the file
743 while(data_bytes > 0) {
744 bytes_read = fread(ucbuffer_, sizeof(unsigned char), min(data_bytes, CHUNK_OF_SAMPLES * bytes_per_wide_sample), infile);
745 if(bytes_read == 0) {
747 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
748 return EncoderSession_finish_error(&encoder_session);
750 else if(feof(infile)) {
751 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);
756 if(bytes_read % bytes_per_wide_sample != 0) {
757 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
758 return EncoderSession_finish_error(&encoder_session);
761 unsigned wide_samples = bytes_read / bytes_per_wide_sample;
762 format_input(input_, wide_samples, /*is_big_endian=*/false, is_unsigned_samples, channels, bps);
764 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
765 print_error_with_state(&encoder_session, "ERROR during encoding");
766 return EncoderSession_finish_error(&encoder_session);
768 data_bytes -= bytes_read;
774 FLAC__ASSERT(!options.common.sector_align);
775 if(!fskip_ahead(infile, trim * bytes_per_wide_sample)) {
776 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
777 return EncoderSession_finish_error(&encoder_session);
782 * now read unaligned samples into reservoir or pad with zeroes if necessary
784 if(options.common.sector_align) {
785 if(options.common.is_last_file) {
786 unsigned wide_samples = 588 - align_remainder;
787 if(wide_samples < 588) {
790 info_align_zero = wide_samples;
791 for(channel = 0; channel < channels; channel++)
792 memset(input_[channel], 0, sizeof(input_[0][0]) * wide_samples);
794 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
795 print_error_with_state(&encoder_session, "ERROR during encoding");
796 return EncoderSession_finish_error(&encoder_session);
801 if(*options.common.align_reservoir_samples > 0) {
802 FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
803 bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
804 if(bytes_read == 0 && ferror(infile)) {
805 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
806 return EncoderSession_finish_error(&encoder_session);
808 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
809 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);
812 info_align_carry = *options.common.align_reservoir_samples;
813 format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, /*is_big_endian=*/false, is_unsigned_samples, channels, bps);
822 if(fread(&tmp, 1U, 1U, infile) < 1U) {
823 flac__utils_printf(stderr, 1, "%s: ERROR during read of data pad byte\n", encoder_session.inbasefilename);
824 return EncoderSession_finish_error(&encoder_session);
828 got_data_chunk = true;
831 if(xx == 0x20746d66 && got_fmt_chunk) { /* "fmt " */
832 flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'fmt ' sub-chunk\n", encoder_session.inbasefilename);
834 else if(xx == 0x61746164) { /* "data" */
836 flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'data' sub-chunk\n", encoder_session.inbasefilename);
838 else if(!got_fmt_chunk) {
839 flac__utils_printf(stderr, 1, "%s: ERROR: got 'data' sub-chunk before 'fmt' sub-chunk\n", encoder_session.inbasefilename);
840 return EncoderSession_finish_error(&encoder_session);
847 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));
850 if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
851 return EncoderSession_finish_error(&encoder_session);
853 unsigned long skip = xx+(xx & 1U);
855 FLAC__ASSERT(skip<=LONG_MAX);
856 if(!fskip_ahead(infile, skip)) {
857 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping unsupported sub-chunk\n", encoder_session.inbasefilename);
858 return EncoderSession_finish_error(&encoder_session);
864 return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
867 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)
869 EncoderSession encoder_session;
871 const size_t bytes_per_wide_sample = options.channels * (options.bps >> 3);
872 unsigned align_remainder = 0;
873 int info_align_carry = -1, info_align_zero = -1;
874 FLAC__uint64 total_samples_in_input = 0;
876 FLAC__ASSERT(!options.common.sector_align || options.channels == 2);
877 FLAC__ASSERT(!options.common.sector_align || options.bps == 16);
878 FLAC__ASSERT(!options.common.sector_align || options.sample_rate == 44100);
879 FLAC__ASSERT(!options.common.sector_align || infilesize >= 0);
880 FLAC__ASSERT(!options.common.replay_gain || options.channels <= 2);
881 FLAC__ASSERT(!options.common.replay_gain || grabbag__replaygain_is_valid_sample_frequency(options.sample_rate));
884 EncoderSession_construct(
887 options.common.use_ogg,
891 options.common.verify,
900 * now that we know the sample rate, canonicalize the
901 * --skip string to a number of samples:
903 flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, options.sample_rate);
904 FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
905 encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
906 FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
909 total_samples_in_input = 0;
911 /* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
912 FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
913 total_samples_in_input = (FLAC__uint64)infilesize / bytes_per_wide_sample + *options.common.align_reservoir_samples;
917 * now that we know the input size, canonicalize the
918 * --until strings to a number of samples:
920 if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, options.sample_rate, encoder_session.skip, total_samples_in_input))
921 return EncoderSession_finish_error(&encoder_session);
922 encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
923 FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
925 infilesize -= (off_t)encoder_session.skip * bytes_per_wide_sample;
926 encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
927 if(encoder_session.until > 0) {
928 const FLAC__uint64 trim = total_samples_in_input - encoder_session.until;
929 FLAC__ASSERT(total_samples_in_input > 0);
930 FLAC__ASSERT(!options.common.sector_align);
931 infilesize -= (off_t)trim * bytes_per_wide_sample;
932 encoder_session.total_samples_to_encode -= trim;
934 if(infilesize >= 0 && options.common.sector_align) {
935 FLAC__ASSERT(encoder_session.skip == 0);
936 align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
937 if(options.common.is_last_file)
938 encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
940 encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
942 encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample;
944 if(encoder_session.total_samples_to_encode <= 0)
945 flac__utils_printf(stderr, 2, "(No runtime statistics possible; please wait for encoding to finish...)\n");
947 if(encoder_session.skip > 0) {
948 unsigned skip_bytes = bytes_per_wide_sample * (unsigned)encoder_session.skip;
949 if(skip_bytes > lookahead_length) {
950 skip_bytes -= lookahead_length;
951 lookahead_length = 0;
952 if(!fskip_ahead(infile, skip_bytes)) {
953 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
954 return EncoderSession_finish_error(&encoder_session);
958 lookahead += skip_bytes;
959 lookahead_length -= skip_bytes;
963 if(!EncoderSession_init_encoder(&encoder_session, options.common, options.channels, options.bps, options.sample_rate, /*flac_decoder_data=*/0))
964 return EncoderSession_finish_error(&encoder_session);
967 * first do any samples in the reservoir
969 if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
970 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
971 print_error_with_state(&encoder_session, "ERROR during encoding");
972 return EncoderSession_finish_error(&encoder_session);
977 * decrement infilesize if we need to align the file
979 if(options.common.sector_align) {
980 FLAC__ASSERT(infilesize >= 0);
981 if(options.common.is_last_file) {
982 *options.common.align_reservoir_samples = 0;
985 *options.common.align_reservoir_samples = align_remainder;
986 infilesize -= (off_t)((*options.common.align_reservoir_samples) * bytes_per_wide_sample);
987 FLAC__ASSERT(infilesize >= 0);
992 * now do from the file
995 while(!feof(infile)) {
996 if(lookahead_length > 0) {
997 FLAC__ASSERT(lookahead_length < CHUNK_OF_SAMPLES * bytes_per_wide_sample);
998 memcpy(ucbuffer_, lookahead, lookahead_length);
999 bytes_read = fread(ucbuffer_+lookahead_length, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample - lookahead_length, infile) + lookahead_length;
1000 if(ferror(infile)) {
1001 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1002 return EncoderSession_finish_error(&encoder_session);
1004 lookahead_length = 0;
1007 bytes_read = fread(ucbuffer_, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample, infile);
1009 if(bytes_read == 0) {
1010 if(ferror(infile)) {
1011 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1012 return EncoderSession_finish_error(&encoder_session);
1015 else if(bytes_read % bytes_per_wide_sample != 0) {
1016 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
1017 return EncoderSession_finish_error(&encoder_session);
1020 unsigned wide_samples = bytes_read / bytes_per_wide_sample;
1021 format_input(input_, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);
1023 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1024 print_error_with_state(&encoder_session, "ERROR during encoding");
1025 return EncoderSession_finish_error(&encoder_session);
1031 const FLAC__uint64 max_input_bytes = infilesize;
1032 FLAC__uint64 total_input_bytes_read = 0;
1033 while(total_input_bytes_read < max_input_bytes) {
1035 size_t wanted = (CHUNK_OF_SAMPLES * bytes_per_wide_sample);
1036 wanted = (size_t) min((FLAC__uint64)wanted, max_input_bytes - total_input_bytes_read);
1038 if(lookahead_length > 0) {
1039 FLAC__ASSERT(lookahead_length <= wanted);
1040 memcpy(ucbuffer_, lookahead, lookahead_length);
1041 wanted -= lookahead_length;
1042 bytes_read = lookahead_length;
1044 bytes_read += fread(ucbuffer_+lookahead_length, sizeof(unsigned char), wanted, infile);
1045 if(ferror(infile)) {
1046 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1047 return EncoderSession_finish_error(&encoder_session);
1050 lookahead_length = 0;
1053 bytes_read = fread(ucbuffer_, sizeof(unsigned char), wanted, infile);
1056 if(bytes_read == 0) {
1057 if(ferror(infile)) {
1058 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1059 return EncoderSession_finish_error(&encoder_session);
1061 else if(feof(infile)) {
1062 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);
1063 total_input_bytes_read = max_input_bytes;
1067 if(bytes_read % bytes_per_wide_sample != 0) {
1068 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
1069 return EncoderSession_finish_error(&encoder_session);
1072 unsigned wide_samples = bytes_read / bytes_per_wide_sample;
1073 format_input(input_, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);
1075 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1076 print_error_with_state(&encoder_session, "ERROR during encoding");
1077 return EncoderSession_finish_error(&encoder_session);
1079 total_input_bytes_read += bytes_read;
1086 * now read unaligned samples into reservoir or pad with zeroes if necessary
1088 if(options.common.sector_align) {
1089 if(options.common.is_last_file) {
1090 unsigned wide_samples = 588 - align_remainder;
1091 if(wide_samples < 588) {
1094 info_align_zero = wide_samples;
1095 for(channel = 0; channel < options.channels; channel++)
1096 memset(input_[channel], 0, sizeof(input_[0][0]) * wide_samples);
1098 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1099 print_error_with_state(&encoder_session, "ERROR during encoding");
1100 return EncoderSession_finish_error(&encoder_session);
1105 if(*options.common.align_reservoir_samples > 0) {
1106 FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
1107 bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
1108 if(bytes_read == 0 && ferror(infile)) {
1109 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1110 return EncoderSession_finish_error(&encoder_session);
1112 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
1113 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);
1116 info_align_carry = *options.common.align_reservoir_samples;
1117 format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);
1123 return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
1126 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)
1128 EncoderSession encoder_session;
1129 FLAC__StreamDecoder *decoder = 0;
1130 FLACDecoderData decoder_data;
1135 EncoderSession_construct(
1137 #ifdef FLAC__HAS_OGG
1138 options.common.use_ogg,
1142 options.common.verify,
1150 decoder_data.encoder_session = &encoder_session;
1151 decoder_data.filesize = (infilesize == (off_t)(-1)? 0 : infilesize);
1152 decoder_data.lookahead = lookahead;
1153 decoder_data.lookahead_length = lookahead_length;
1154 decoder_data.num_metadata_blocks = 0;
1155 decoder_data.samples_left_to_process = 0;
1156 decoder_data.fatal_error = false;
1159 * set up FLAC decoder for the input
1161 if (0 == (decoder = FLAC__stream_decoder_new())) {
1162 flac__utils_printf(stderr, 1, "%s: ERROR: creating decoder for FLAC input\n", encoder_session.inbasefilename);
1163 return EncoderSession_finish_error(&encoder_session);
1166 FLAC__stream_decoder_set_md5_checking(decoder, false) &&
1167 FLAC__stream_decoder_set_metadata_respond_all(decoder)
1169 flac__utils_printf(stderr, 1, "%s: ERROR: setting up decoder for FLAC input\n", encoder_session.inbasefilename);
1170 goto fubar1; /*@@@ yuck */
1173 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) {
1174 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));
1175 goto fubar1; /*@@@ yuck */
1178 if (!FLAC__stream_decoder_process_until_end_of_metadata(decoder) || decoder_data.fatal_error) {
1179 if (decoder_data.fatal_error)
1180 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);
1182 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));
1183 goto fubar1; /*@@@ yuck */
1186 if (decoder_data.num_metadata_blocks == 0) {
1187 flac__utils_printf(stderr, 1, "%s: ERROR: reading metadata in FLAC input, got no metadata blocks\n", encoder_session.inbasefilename);
1188 goto fubar2; /*@@@ yuck */
1190 else if (decoder_data.metadata_blocks[0]->type != FLAC__METADATA_TYPE_STREAMINFO) {
1191 flac__utils_printf(stderr, 1, "%s: ERROR: reading metadata in FLAC input, first metadata block is not STREAMINFO\n", encoder_session.inbasefilename);
1192 goto fubar2; /*@@@ yuck */
1194 else if (decoder_data.metadata_blocks[0]->data.stream_info.total_samples == 0) {
1195 flac__utils_printf(stderr, 1, "%s: ERROR: FLAC input has STREAMINFO with unknown total samples which is not supported\n", encoder_session.inbasefilename);
1196 goto fubar2; /*@@@ yuck */
1200 * now that we have the STREAMINFO and know the sample rate,
1201 * canonicalize the --skip string to a number of samples:
1203 flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, decoder_data.metadata_blocks[0]->data.stream_info.sample_rate);
1204 FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
1205 encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
1206 FLAC__ASSERT(!options.common.sector_align); /* --sector-align with FLAC input is not supported */
1209 FLAC__uint64 total_samples_in_input, trim = 0;
1211 total_samples_in_input = decoder_data.metadata_blocks[0]->data.stream_info.total_samples;
1214 * now that we know the input size, canonicalize the
1215 * --until string to an absolute sample number:
1217 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))
1218 goto fubar2; /*@@@ yuck */
1219 encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
1221 encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
1222 if(encoder_session.until > 0) {
1223 trim = total_samples_in_input - encoder_session.until;
1224 FLAC__ASSERT(total_samples_in_input > 0);
1225 encoder_session.total_samples_to_encode -= trim;
1228 encoder_session.unencoded_size = decoder_data.filesize;
1230 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))
1231 return EncoderSession_finish_error(&encoder_session);
1234 * have to wait until the FLAC encoder is set up for writing
1235 * before any seeking in the input FLAC file, because the seek
1236 * itself will usually call the decoder's write callback, and
1237 * our decoder's write callback passes samples to our FLAC
1240 decoder_data.samples_left_to_process = encoder_session.total_samples_to_encode;
1241 if(encoder_session.skip > 0) {
1242 if(!FLAC__stream_decoder_seek_absolute(decoder, encoder_session.skip)) {
1243 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));
1244 goto fubar2; /*@@@ yuck */
1249 * now do samples from the file
1251 while(!decoder_data.fatal_error && decoder_data.samples_left_to_process > 0) {
1252 if(!FLAC__stream_decoder_process_single(decoder)) {
1253 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));
1254 goto fubar2; /*@@@ yuck */
1259 FLAC__stream_decoder_delete(decoder);
1260 retval = EncoderSession_finish_ok(&encoder_session, -1, -1);
1261 /* have to wail until encoder is completely finished before deleting because of the final step of writing the seekpoint offsets */
1262 for(i = 0; i < decoder_data.num_metadata_blocks; i++)
1263 free(decoder_data.metadata_blocks[i]);
1267 for(i = 0; i < decoder_data.num_metadata_blocks; i++)
1268 free(decoder_data.metadata_blocks[i]);
1270 FLAC__stream_decoder_delete(decoder);
1271 return EncoderSession_finish_error(&encoder_session);
1274 FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FILE *infile, const char *infilename, const char *outfilename)
1277 FLAC__uint32 test = 1;
1280 * initialize globals
1283 is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;
1285 for(i = 0; i < FLAC__MAX_CHANNELS; i++)
1286 input_[i] = &(in_[i][0]);
1290 * initialize instance
1293 #ifdef FLAC__HAS_OGG
1294 e->use_ogg = use_ogg;
1300 e->is_stdout = (0 == strcmp(outfilename, "-"));
1302 e->inbasefilename = grabbag__file_get_basename(infilename);
1303 e->outfilename = outfilename;
1305 e->skip = 0; /* filled in later after the sample_rate is known */
1306 e->unencoded_size = 0;
1307 e->total_samples_to_encode = 0;
1308 e->bytes_written = 0;
1309 e->samples_written = 0;
1313 e->encoder.flac = 0;
1314 #ifdef FLAC__HAS_OGG
1319 e->seek_table_template = 0;
1321 if(0 == (e->seek_table_template = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE))) {
1322 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1326 #ifdef FLAC__HAS_OGG
1328 e->encoder.ogg = OggFLAC__stream_encoder_new();
1329 if(0 == e->encoder.ogg) {
1330 flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1331 EncoderSession_destroy(e);
1337 e->encoder.flac = FLAC__stream_encoder_new();
1338 if(0 == e->encoder.flac) {
1339 flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1340 EncoderSession_destroy(e);
1347 void EncoderSession_destroy(EncoderSession *e)
1352 #ifdef FLAC__HAS_OGG
1354 if(0 != e->encoder.ogg) {
1355 OggFLAC__stream_encoder_delete(e->encoder.ogg);
1361 if(0 != e->encoder.flac) {
1362 FLAC__stream_encoder_delete(e->encoder.flac);
1363 e->encoder.flac = 0;
1366 if(0 != e->seek_table_template) {
1367 FLAC__metadata_object_delete(e->seek_table_template);
1368 e->seek_table_template = 0;
1372 int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero)
1374 FLAC__StreamEncoderState fse_state = FLAC__STREAM_ENCODER_OK;
1377 #ifdef FLAC__HAS_OGG
1379 if(e->encoder.ogg) {
1380 fse_state = OggFLAC__stream_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg);
1381 OggFLAC__stream_encoder_finish(e->encoder.ogg);
1386 if(e->encoder.flac) {
1387 fse_state = FLAC__stream_encoder_get_state(e->encoder.flac);
1388 FLAC__stream_encoder_finish(e->encoder.flac);
1391 if(e->total_samples_to_encode > 0) {
1393 flac__utils_printf(stderr, 2, "\n");
1396 if(fse_state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA) {
1397 print_verify_error(e);
1401 if(info_align_carry >= 0) {
1402 flac__utils_printf(stderr, 1, "%s: INFO: sector alignment causing %d samples to be carried over\n", e->inbasefilename, info_align_carry);
1404 if(info_align_zero >= 0) {
1405 flac__utils_printf(stderr, 1, "%s: INFO: sector alignment causing %d zero samples to be appended\n", e->inbasefilename, info_align_zero);
1409 EncoderSession_destroy(e);
1414 int EncoderSession_finish_error(EncoderSession *e)
1416 FLAC__StreamEncoderState fse_state;
1418 if(e->total_samples_to_encode > 0)
1419 flac__utils_printf(stderr, 2, "\n");
1421 #ifdef FLAC__HAS_OGG
1423 fse_state = OggFLAC__stream_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg);
1428 fse_state = FLAC__stream_encoder_get_state(e->encoder.flac);
1431 if(fse_state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA)
1432 print_verify_error(e);
1434 /*@@@@@@@@@ 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 */
1435 unlink(e->outfilename);
1437 EncoderSession_destroy(e);
1442 FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, unsigned channels, unsigned bps, unsigned sample_rate, FLACDecoderData *flac_decoder_data)
1444 unsigned num_metadata;
1445 FLAC__StreamMetadata padding, *cuesheet = 0;
1446 FLAC__StreamMetadata *static_metadata[4];
1447 FLAC__StreamMetadata **metadata = static_metadata;
1448 FLAC__StreamEncoderInitStatus init_status;
1449 const FLAC__bool is_cdda = (channels == 1 || channels == 2) && (bps == 16) && (sample_rate == 44100);
1451 e->replay_gain = options.replay_gain;
1452 e->channels = channels;
1453 e->bits_per_sample = bps;
1454 e->sample_rate = sample_rate;
1456 if(e->replay_gain) {
1457 if(channels != 1 && channels != 2) {
1458 flac__utils_printf(stderr, 1, "%s: ERROR, number of channels (%u) must be 1 or 2 for --replay-gain\n", e->inbasefilename, channels);
1461 if(!grabbag__replaygain_is_valid_sample_frequency(sample_rate)) {
1462 flac__utils_printf(stderr, 1, "%s: ERROR, invalid sample rate (%u) for --replay-gain\n", e->inbasefilename, sample_rate);
1465 if(options.is_first_file) {
1466 if(!grabbag__replaygain_init(sample_rate)) {
1467 flac__utils_printf(stderr, 1, "%s: ERROR initializing ReplayGain stage\n", e->inbasefilename);
1474 options.do_mid_side = options.loose_mid_side = false;
1476 if(!parse_cuesheet(&cuesheet, options.cuesheet_filename, e->inbasefilename, is_cdda, e->total_samples_to_encode))
1479 if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, options.cued_seekpoints? cuesheet : 0, e)) {
1480 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1482 FLAC__metadata_object_delete(cuesheet);
1486 if(flac_decoder_data) {
1488 * we're encoding from FLAC so we will use the FLAC file's
1489 * metadata as the basic for the encoded file
1493 * first handle padding: if --no-padding was specified,
1494 * then delete all padding; else if -P was specified,
1495 * use that instead of existing padding (if any); else
1496 * if existing file has padding, move all existing
1497 * padding blocks to one padding block at the end; else
1498 * use default padding.
1502 for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1503 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_PADDING) {
1506 p += flac_decoder_data->metadata_blocks[i]->length;
1507 FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1508 flac_decoder_data->metadata_blocks[i] = 0;
1511 flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1513 flac_decoder_data->num_metadata_blocks = j;
1514 if(options.padding > 0)
1515 p = options.padding;
1517 p = FLAC_ENCODE__DEFAULT_PADDING;
1518 if(options.padding != 0) {
1519 if(p > 0 && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
1520 flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING);
1521 if(0 == flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]) {
1522 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for PADDING block\n", e->inbasefilename);
1524 FLAC__metadata_object_delete(cuesheet);
1527 flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]->is_last = false; /* the encoder will set this for us */
1528 flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]->length = p;
1529 flac_decoder_data->num_metadata_blocks++;
1535 * next handle vorbis comment: if any tags were specified
1536 * or there is no existing vorbis comment, we create a
1537 * new vorbis comment (discarding any existing one); else
1538 * we keep the existing one
1541 FLAC__bool vc_found = false;
1542 for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1543 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
1545 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT && options.vorbis_comment->data.vorbis_comment.num_comments > 0) {
1546 if(options.vorbis_comment->data.vorbis_comment.num_comments > 0)
1547 flac__utils_printf(stderr, 1, "%s: WARNING, replacing tags from input FLAC file with those given on the command-line\n", e->inbasefilename);
1548 FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1549 flac_decoder_data->metadata_blocks[i] = 0;
1552 flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1554 flac_decoder_data->num_metadata_blocks = j;
1555 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])) {
1557 FLAC__StreamMetadata *vc = FLAC__metadata_object_clone(options.vorbis_comment);
1559 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for VORBIS_COMMENT block\n", e->inbasefilename);
1561 FLAC__metadata_object_delete(cuesheet);
1564 for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1565 flac_decoder_data->metadata_blocks[i] = flac_decoder_data->metadata_blocks[i-1];
1566 flac_decoder_data->metadata_blocks[1] = vc;
1567 flac_decoder_data->num_metadata_blocks++;
1572 * next handle cuesheet: if --cuesheet was specified, use
1573 * it; else if file has existing CUESHEET and cuesheet's
1574 * lead-out offset is correct, keep it; else no CUESHEET
1577 for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1578 FLAC__bool existing_cuesheet_is_bad = false;
1579 /* check if existing cuesheet matches the input audio */
1580 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && 0 == cuesheet) {
1581 const FLAC__StreamMetadata_CueSheet *cs = &flac_decoder_data->metadata_blocks[i]->data.cue_sheet;
1582 if(e->total_samples_to_encode == 0) {
1583 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);
1584 existing_cuesheet_is_bad = true;
1586 else if(e->total_samples_to_encode != cs->tracks[cs->num_tracks-1].offset) {
1587 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);
1588 existing_cuesheet_is_bad = true;
1591 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && (existing_cuesheet_is_bad || 0 != cuesheet)) {
1593 flac__utils_printf(stderr, 1, "%s: WARNING, replacing cuesheet in input FLAC file with the one given on the command-line\n", e->inbasefilename);
1594 FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1595 flac_decoder_data->metadata_blocks[i] = 0;
1598 flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1600 flac_decoder_data->num_metadata_blocks = j;
1601 if(0 != cuesheet && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
1603 FLAC__StreamMetadata *cs = FLAC__metadata_object_clone(cuesheet);
1605 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for CUESHEET block\n", e->inbasefilename);
1607 FLAC__metadata_object_delete(cuesheet);
1610 for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1611 flac_decoder_data->metadata_blocks[i] = flac_decoder_data->metadata_blocks[i-1];
1612 flac_decoder_data->metadata_blocks[1] = cs;
1613 flac_decoder_data->num_metadata_blocks++;
1618 * finally handle seektable: if -S- was specified, no
1619 * SEEKTABLE; else if -S was specified, use it/them;
1620 * else if file has existing SEEKTABLE and input size is
1621 * preserved (no --skip/--until/etc specified), keep it;
1622 * else use default seektable options
1624 * note: meanings of num_requested_seek_points:
1625 * -1 : no -S option given, default to some value
1626 * 0 : -S- given (no seektable)
1627 * >0 : one or more -S options given
1630 FLAC__bool existing_seektable = false;
1631 for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1632 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_SEEKTABLE)
1633 existing_seektable = true;
1634 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)) {
1635 if(options.num_requested_seek_points > 0)
1636 flac__utils_printf(stderr, 1, "%s: WARNING, replacing seektable in input FLAC file with the one given on the command-line\n", e->inbasefilename);
1637 else if(options.num_requested_seek_points == 0)
1638 ; /* no warning, silently delete existing SEEKTABLE since user specified --no-seektable (-S-) */
1640 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);
1641 FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1642 flac_decoder_data->metadata_blocks[i] = 0;
1643 existing_seektable = false;
1646 flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1648 flac_decoder_data->num_metadata_blocks = j;
1649 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])) {
1651 FLAC__StreamMetadata *st = FLAC__metadata_object_clone(e->seek_table_template);
1653 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for SEEKTABLE block\n", e->inbasefilename);
1655 FLAC__metadata_object_delete(cuesheet);
1658 for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1659 flac_decoder_data->metadata_blocks[i] = flac_decoder_data->metadata_blocks[i-1];
1660 flac_decoder_data->metadata_blocks[1] = st;
1661 flac_decoder_data->num_metadata_blocks++;
1664 metadata = &flac_decoder_data->metadata_blocks[1]; /* don't include STREAMINFO */
1665 num_metadata = flac_decoder_data->num_metadata_blocks - 1;
1669 * we're not encoding from FLAC so we will build the metadata
1673 if(e->seek_table_template->data.seek_table.num_points > 0) {
1674 e->seek_table_template->is_last = false; /* the encoder will set this for us */
1675 metadata[num_metadata++] = e->seek_table_template;
1678 metadata[num_metadata++] = cuesheet;
1679 metadata[num_metadata++] = options.vorbis_comment;
1680 if(options.padding != 0) {
1681 padding.is_last = false; /* the encoder will set this for us */
1682 padding.type = FLAC__METADATA_TYPE_PADDING;
1683 padding.length = (unsigned)(options.padding>0? options.padding : FLAC_ENCODE__DEFAULT_PADDING);
1684 metadata[num_metadata++] = &padding;
1688 e->blocksize = options.blocksize;
1689 e->stats_mask = (options.do_exhaustive_model_search || options.do_qlp_coeff_prec_search)? 0x0f : 0x3f;
1691 #ifdef FLAC__HAS_OGG
1693 OggFLAC__stream_encoder_set_serial_number(e->encoder.ogg, options.serial_number);
1694 OggFLAC__stream_encoder_set_verify(e->encoder.ogg, options.verify);
1695 OggFLAC__stream_encoder_set_streamable_subset(e->encoder.ogg, !options.lax);
1696 OggFLAC__stream_encoder_set_do_mid_side_stereo(e->encoder.ogg, options.do_mid_side);
1697 OggFLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder.ogg, options.loose_mid_side);
1698 OggFLAC__stream_encoder_set_channels(e->encoder.ogg, channels);
1699 OggFLAC__stream_encoder_set_bits_per_sample(e->encoder.ogg, bps);
1700 OggFLAC__stream_encoder_set_sample_rate(e->encoder.ogg, sample_rate);
1701 OggFLAC__stream_encoder_set_blocksize(e->encoder.ogg, options.blocksize);
1702 OggFLAC__stream_encoder_set_apodization(e->encoder.ogg, options.apodizations);
1703 OggFLAC__stream_encoder_set_max_lpc_order(e->encoder.ogg, options.max_lpc_order);
1704 OggFLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.ogg, options.qlp_coeff_precision);
1705 OggFLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.ogg, options.do_qlp_coeff_prec_search);
1706 OggFLAC__stream_encoder_set_do_escape_coding(e->encoder.ogg, options.do_escape_coding);
1707 OggFLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder.ogg, options.do_exhaustive_model_search);
1708 OggFLAC__stream_encoder_set_min_residual_partition_order(e->encoder.ogg, options.min_residual_partition_order);
1709 OggFLAC__stream_encoder_set_max_residual_partition_order(e->encoder.ogg, options.max_residual_partition_order);
1710 OggFLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder.ogg, options.rice_parameter_search_dist);
1711 OggFLAC__stream_encoder_set_total_samples_estimate(e->encoder.ogg, e->total_samples_to_encode);
1712 OggFLAC__stream_encoder_set_metadata(e->encoder.ogg, (num_metadata > 0)? metadata : 0, num_metadata);
1714 OggFLAC__stream_encoder_disable_constant_subframes(e->encoder.ogg, options.debug.disable_constant_subframes);
1715 OggFLAC__stream_encoder_disable_fixed_subframes(e->encoder.ogg, options.debug.disable_fixed_subframes);
1716 OggFLAC__stream_encoder_disable_verbatim_subframes(e->encoder.ogg, options.debug.disable_verbatim_subframes);
1718 init_status = OggFLAC__stream_encoder_init_file(e->encoder.ogg, e->is_stdout? 0 : e->outfilename, encoder_progress_callback, /*client_data=*/e);
1719 if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
1720 print_error_with_init_status(e, "ERROR initializing encoder", init_status);
1722 FLAC__metadata_object_delete(cuesheet);
1729 FLAC__stream_encoder_set_verify(e->encoder.flac, options.verify);
1730 FLAC__stream_encoder_set_streamable_subset(e->encoder.flac, !options.lax);
1731 FLAC__stream_encoder_set_do_mid_side_stereo(e->encoder.flac, options.do_mid_side);
1732 FLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder.flac, options.loose_mid_side);
1733 FLAC__stream_encoder_set_channels(e->encoder.flac, channels);
1734 FLAC__stream_encoder_set_bits_per_sample(e->encoder.flac, bps);
1735 FLAC__stream_encoder_set_sample_rate(e->encoder.flac, sample_rate);
1736 FLAC__stream_encoder_set_blocksize(e->encoder.flac, options.blocksize);
1737 FLAC__stream_encoder_set_apodization(e->encoder.flac, options.apodizations);
1738 FLAC__stream_encoder_set_max_lpc_order(e->encoder.flac, options.max_lpc_order);
1739 FLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.flac, options.qlp_coeff_precision);
1740 FLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.flac, options.do_qlp_coeff_prec_search);
1741 FLAC__stream_encoder_set_do_escape_coding(e->encoder.flac, options.do_escape_coding);
1742 FLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder.flac, options.do_exhaustive_model_search);
1743 FLAC__stream_encoder_set_min_residual_partition_order(e->encoder.flac, options.min_residual_partition_order);
1744 FLAC__stream_encoder_set_max_residual_partition_order(e->encoder.flac, options.max_residual_partition_order);
1745 FLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder.flac, options.rice_parameter_search_dist);
1746 FLAC__stream_encoder_set_total_samples_estimate(e->encoder.flac, e->total_samples_to_encode);
1747 FLAC__stream_encoder_set_metadata(e->encoder.flac, (num_metadata > 0)? metadata : 0, num_metadata);
1749 FLAC__stream_encoder_disable_constant_subframes(e->encoder.flac, options.debug.disable_constant_subframes);
1750 FLAC__stream_encoder_disable_fixed_subframes(e->encoder.flac, options.debug.disable_fixed_subframes);
1751 FLAC__stream_encoder_disable_verbatim_subframes(e->encoder.flac, options.debug.disable_verbatim_subframes);
1753 init_status = FLAC__stream_encoder_init_file(e->encoder.flac, e->is_stdout? 0 : e->outfilename, encoder_progress_callback, /*client_data=*/e);
1754 if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
1755 print_error_with_init_status(e, "ERROR initializing encoder", init_status);
1757 FLAC__metadata_object_delete(cuesheet);
1763 FLAC__metadata_object_delete(cuesheet);
1768 FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples)
1770 if(e->replay_gain) {
1771 if(!grabbag__replaygain_analyze(buffer, e->channels==2, e->bits_per_sample, samples)) {
1772 flac__utils_printf(stderr, 1, "%s: WARNING, error while calculating ReplayGain\n", e->inbasefilename);
1776 #ifdef FLAC__HAS_OGG
1778 return OggFLAC__stream_encoder_process(e->encoder.ogg, buffer, samples);
1781 return FLAC__stream_encoder_process(e->encoder.flac, buffer, samples);
1784 FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int num_requested_seek_points, FLAC__StreamMetadata *cuesheet, EncoderSession *e)
1786 const FLAC__bool only_placeholders = e->is_stdout;
1787 FLAC__bool has_real_points;
1789 if(num_requested_seek_points == 0 && 0 == cuesheet)
1792 if(num_requested_seek_points < 0) {
1793 requested_seek_points = "10s;";
1794 num_requested_seek_points = 1;
1797 if(num_requested_seek_points > 0) {
1798 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))
1804 const FLAC__StreamMetadata_CueSheet *cs = &cuesheet->data.cue_sheet;
1805 for(i = 0; i < cs->num_tracks; i++) {
1806 const FLAC__StreamMetadata_CueSheet_Track *tr = cs->tracks+i;
1807 for(j = 0; j < tr->num_indices; j++) {
1808 if(!FLAC__metadata_object_seektable_template_append_point(e->seek_table_template, tr->offset + tr->indices[j].offset))
1810 has_real_points = true;
1814 if(!FLAC__metadata_object_seektable_template_sort(e->seek_table_template, /*compact=*/true))
1818 if(has_real_points) {
1820 flac__utils_printf(stderr, 1, "%s: WARNING, cannot write back seekpoints when encoding to stdout\n", e->inbasefilename);
1827 FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input)
1829 /* convert from mm:ss.sss to sample number if necessary */
1830 flac__utils_canonicalize_skip_until_specification(spec, sample_rate);
1832 /* special case: if "--until=-0", use the special value '0' to mean "end-of-stream" */
1833 if(spec->is_relative && spec->value.samples == 0) {
1834 spec->is_relative = false;
1838 /* in any other case the total samples in the input must be known */
1839 if(total_samples_in_input == 0) {
1840 flac__utils_printf(stderr, 1, "%s: ERROR, cannot use --until when input length is unknown\n", inbasefilename);
1844 FLAC__ASSERT(spec->value_is_samples);
1846 /* convert relative specifications to absolute */
1847 if(spec->is_relative) {
1848 if(spec->value.samples <= 0)
1849 spec->value.samples += (FLAC__int64)total_samples_in_input;
1851 spec->value.samples += skip;
1852 spec->is_relative = false;
1856 if(spec->value.samples < 0) {
1857 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before beginning of input\n", inbasefilename);
1860 if((FLAC__uint64)spec->value.samples <= skip) {
1861 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before --skip point\n", inbasefilename);
1864 if((FLAC__uint64)spec->value.samples > total_samples_in_input) {
1865 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is after end of input\n", inbasefilename);
1872 void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps)
1874 unsigned wide_sample, sample, channel, byte;
1877 if(is_unsigned_samples) {
1878 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1879 for(channel = 0; channel < channels; channel++, sample++)
1880 dest[channel][wide_sample] = (FLAC__int32)ucbuffer_[sample] - 0x80;
1883 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1884 for(channel = 0; channel < channels; channel++, sample++)
1885 dest[channel][wide_sample] = (FLAC__int32)scbuffer_[sample];
1888 else if(bps == 16) {
1889 if(is_big_endian != is_big_endian_host_) {
1891 const unsigned bytes = wide_samples * channels * (bps >> 3);
1892 for(byte = 0; byte < bytes; byte += 2) {
1893 tmp = ucbuffer_[byte];
1894 ucbuffer_[byte] = ucbuffer_[byte+1];
1895 ucbuffer_[byte+1] = tmp;
1898 if(is_unsigned_samples) {
1899 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1900 for(channel = 0; channel < channels; channel++, sample++)
1901 dest[channel][wide_sample] = (FLAC__int32)usbuffer_[sample] - 0x8000;
1904 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1905 for(channel = 0; channel < channels; channel++, sample++)
1906 dest[channel][wide_sample] = (FLAC__int32)ssbuffer_[sample];
1909 else if(bps == 24) {
1910 if(!is_big_endian) {
1912 const unsigned bytes = wide_samples * channels * (bps >> 3);
1913 for(byte = 0; byte < bytes; byte += 3) {
1914 tmp = ucbuffer_[byte];
1915 ucbuffer_[byte] = ucbuffer_[byte+2];
1916 ucbuffer_[byte+2] = tmp;
1919 if(is_unsigned_samples) {
1920 for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1921 for(channel = 0; channel < channels; channel++, sample++) {
1922 dest[channel][wide_sample] = ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1923 dest[channel][wide_sample] |= ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1924 dest[channel][wide_sample] |= ucbuffer_[byte++];
1925 dest[channel][wide_sample] -= 0x800000;
1929 for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1930 for(channel = 0; channel < channels; channel++, sample++) {
1931 dest[channel][wide_sample] = scbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1932 dest[channel][wide_sample] |= ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1933 dest[channel][wide_sample] |= ucbuffer_[byte++];
1942 #if 0 /*@@@@@@ old ogg progress callback, I don't think the comment about samples_written is true anymore but keep around until verified */
1943 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)
1945 EncoderSession *encoder_session = (EncoderSession*)client_data;
1950 * With Ogg FLAC we don't get a value for 'samples_written', so we
1951 * estimate based on the frames written and the knowledge that all
1952 * blocks (except the last) are the same size.
1954 samples_written = frames_written * encoder_session->blocksize;
1955 flac_file_encoder_progress_callback(0, bytes_written, samples_written, frames_written, total_frames_estimate, client_data);
1960 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)
1962 EncoderSession *encoder_session = (EncoderSession*)client_data;
1964 (void)encoder, (void)total_frames_estimate;
1966 encoder_session->bytes_written = bytes_written;
1967 encoder_session->samples_written = samples_written;
1969 if(encoder_session->total_samples_to_encode > 0 && !((frames_written-1) & encoder_session->stats_mask))
1970 print_stats(encoder_session);
1973 FLAC__StreamDecoderReadStatus flac_decoder_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
1976 FLACDecoderData *data = (FLACDecoderData*)client_data;
1979 if (data->fatal_error)
1980 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
1982 /* use up lookahead first */
1983 if (data->lookahead_length) {
1984 n = min(data->lookahead_length, *bytes);
1985 memcpy(buffer, data->lookahead, n);
1987 data->lookahead += n;
1988 data->lookahead_length -= n;
1991 /* get the rest from file */
1993 *bytes = n + fread(buffer, 1, *bytes-n, data->encoder_session->fin);
1994 return ferror(data->encoder_session->fin)? FLAC__STREAM_DECODER_READ_STATUS_ABORT : FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
1997 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
2000 FLAC__StreamDecoderSeekStatus flac_decoder_seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
2002 FLACDecoderData *data = (FLACDecoderData*)client_data;
2005 if(fseeko(data->encoder_session->fin, (off_t)absolute_byte_offset, SEEK_SET) < 0)
2006 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
2008 return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
2011 FLAC__StreamDecoderTellStatus flac_decoder_tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
2013 FLACDecoderData *data = (FLACDecoderData*)client_data;
2017 if((pos = ftello(data->encoder_session->fin)) < 0)
2018 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
2020 *absolute_byte_offset = (FLAC__uint64)pos;
2021 return FLAC__STREAM_DECODER_TELL_STATUS_OK;
2025 FLAC__StreamDecoderLengthStatus flac_decoder_length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
2027 FLACDecoderData *data = (FLACDecoderData*)client_data;
2030 if(0 == data->filesize)
2031 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
2033 *stream_length = (FLAC__uint64)data->filesize;
2034 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
2038 FLAC__bool flac_decoder_eof_callback(const FLAC__StreamDecoder *decoder, void *client_data)
2040 FLACDecoderData *data = (FLACDecoderData*)client_data;
2043 return feof(data->encoder_session->fin)? true : false;
2046 FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
2048 FLACDecoderData *data = (FLACDecoderData*)client_data;
2049 FLAC__uint64 n = min(data->samples_left_to_process, frame->header.blocksize);
2052 if(!EncoderSession_process(data->encoder_session, buffer, (unsigned)n)) {
2053 print_error_with_state(data->encoder_session, "ERROR during encoding");
2054 data->fatal_error = true;
2055 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
2058 data->samples_left_to_process -= n;
2059 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
2062 void flac_decoder_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
2064 FLACDecoderData *data = (FLACDecoderData*)client_data;
2067 if (data->fatal_error)
2071 data->num_metadata_blocks == sizeof(data->metadata_blocks)/sizeof(data->metadata_blocks[0]) ||
2072 0 == (data->metadata_blocks[data->num_metadata_blocks] = FLAC__metadata_object_clone(metadata))
2074 data->fatal_error = true;
2076 data->num_metadata_blocks++;
2079 void flac_decoder_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
2081 FLACDecoderData *data = (FLACDecoderData*)client_data;
2084 flac__utils_printf(stderr, 1, "%s: ERROR got %s while decoding FLAC input\n", data->encoder_session->inbasefilename, FLAC__StreamDecoderErrorStatusString[status]);
2085 data->fatal_error = true;
2088 FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset)
2091 unsigned last_line_read;
2092 const char *error_message;
2094 if(0 == cuesheet_filename)
2097 if(lead_out_offset == 0) {
2098 flac__utils_printf(stderr, 1, "%s: ERROR cannot import cuesheet when the number of input samples to encode is unknown\n", inbasefilename);
2102 if(0 == (f = fopen(cuesheet_filename, "r"))) {
2103 flac__utils_printf(stderr, 1, "%s: ERROR opening cuesheet \"%s\" for reading: %s\n", inbasefilename, cuesheet_filename, strerror(errno));
2107 *cuesheet = grabbag__cuesheet_parse(f, &error_message, &last_line_read, is_cdda, lead_out_offset);
2111 if(0 == *cuesheet) {
2112 flac__utils_printf(stderr, 1, "%s: ERROR parsing cuesheet \"%s\" on line %u: %s\n", inbasefilename, cuesheet_filename, last_line_read, error_message);
2116 if(!FLAC__format_cuesheet_is_legal(&(*cuesheet)->data.cue_sheet, /*check_cd_da_subset=*/false, &error_message)) {
2117 flac__utils_printf(stderr, 1, "%s: ERROR parsing cuesheet \"%s\": %s\n", inbasefilename, cuesheet_filename, error_message);
2121 /* if we're expecting CDDA, warn about non-compliance */
2122 if(is_cdda && !FLAC__format_cuesheet_is_legal(&(*cuesheet)->data.cue_sheet, /*check_cd_da_subset=*/true, &error_message)) {
2123 flac__utils_printf(stderr, 1, "%s: WARNING cuesheet \"%s\" is not audio CD compliant: %s\n", inbasefilename, cuesheet_filename, error_message);
2124 (*cuesheet)->data.cue_sheet.is_cd = false;
2130 void print_stats(const EncoderSession *encoder_session)
2132 const FLAC__uint64 samples_written = min(encoder_session->total_samples_to_encode, encoder_session->samples_written);
2133 #if defined _MSC_VER || defined __MINGW32__
2134 /* with MSVC you have to spoon feed it the casting */
2135 const double progress = (double)(FLAC__int64)samples_written / (double)(FLAC__int64)encoder_session->total_samples_to_encode;
2136 const double ratio = (double)(FLAC__int64)encoder_session->bytes_written / ((double)(FLAC__int64)encoder_session->unencoded_size * min(1.0, progress));
2138 const double progress = (double)samples_written / (double)encoder_session->total_samples_to_encode;
2139 const double ratio = (double)encoder_session->bytes_written / ((double)encoder_session->unencoded_size * min(1.0, progress));
2143 if(samples_written == encoder_session->total_samples_to_encode) {
2144 flac__utils_printf(stderr, 2, "\r%s:%s wrote %u bytes, ratio=%0.3f",
2145 encoder_session->inbasefilename,
2146 encoder_session->verify? " Verify OK," : "",
2147 (unsigned)encoder_session->bytes_written,
2152 flac__utils_printf(stderr, 2, "\r%s: %u%% complete, ratio=%0.3f", encoder_session->inbasefilename, (unsigned)floor(progress * 100.0 + 0.5), ratio);
2156 void print_error_with_init_status(const EncoderSession *e, const char *message, FLAC__StreamEncoderInitStatus init_status)
2158 const int ilen = strlen(e->inbasefilename) + 1;
2159 const char *state_string = "";
2161 flac__utils_printf(stderr, 1, "\n%s: %s\n", e->inbasefilename, message);
2163 flac__utils_printf(stderr, 1, "%*s init_status = %s\n", ilen, "", FLAC__StreamEncoderInitStatusString[init_status]);
2165 if(init_status == FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR) {
2166 #ifdef FLAC__HAS_OGG
2168 state_string = OggFLAC__stream_encoder_get_resolved_state_string(e->encoder.ogg);
2171 state_string = FLAC__stream_encoder_get_resolved_state_string(e->encoder.flac);
2173 flac__utils_printf(stderr, 1, "%*s state = %s\n", ilen, "", state_string);
2175 /* print out some more info for some errors: */
2177 0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_CLIENT_ERROR])
2178 #ifdef FLAC__HAS_OGG
2179 || 0 == strcmp(state_string, OggFLAC__StreamEncoderStateString[OggFLAC__STREAM_ENCODER_CLIENT_ERROR])
2182 flac__utils_printf(stderr, 1,
2184 "An error occurred while writing; the most common cause is that the disk is full.\n"
2188 0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_IO_ERROR])
2189 #ifdef FLAC__HAS_OGG
2190 || 0 == strcmp(state_string, OggFLAC__StreamEncoderStateString[OggFLAC__STREAM_ENCODER_IO_ERROR])
2193 flac__utils_printf(stderr, 1,
2195 "An error occurred opening the output file; it is likely that the output\n"
2196 "directory does not exist or is not writable, the output file already exists and\n"
2197 "is not writable, or the disk is full.\n"
2201 else if(init_status == FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE) {
2202 flac__utils_printf(stderr, 1,
2204 "The encoding parameters specified do not conform to the FLAC Subset and may not\n"
2205 "be streamable or playable in hardware devices. Add --lax to the command-line\n"
2206 "options to encode with these parameters anyway.\n"
2211 void print_error_with_state(const EncoderSession *e, const char *message)
2213 const int ilen = strlen(e->inbasefilename) + 1;
2214 const char *state_string;
2216 flac__utils_printf(stderr, 1, "\n%s: %s\n", e->inbasefilename, message);
2218 #ifdef FLAC__HAS_OGG
2220 state_string = OggFLAC__stream_encoder_get_resolved_state_string(e->encoder.ogg);
2223 state_string = FLAC__stream_encoder_get_resolved_state_string(e->encoder.flac);
2225 flac__utils_printf(stderr, 1, "%*s state = %s\n", ilen, "", state_string);
2227 /* print out some more info for some errors: */
2229 0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_CLIENT_ERROR])
2230 #ifdef FLAC__HAS_OGG
2231 || 0 == strcmp(state_string, OggFLAC__StreamEncoderStateString[OggFLAC__STREAM_ENCODER_CLIENT_ERROR])
2234 flac__utils_printf(stderr, 1,
2236 "An error occurred while writing; the most common cause is that the disk is full.\n"
2241 void print_verify_error(EncoderSession *e)
2243 FLAC__uint64 absolute_sample;
2244 unsigned frame_number;
2247 FLAC__int32 expected;
2250 #ifdef FLAC__HAS_OGG
2252 OggFLAC__stream_encoder_get_verify_decoder_error_stats(e->encoder.ogg, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
2255 FLAC__stream_encoder_get_verify_decoder_error_stats(e->encoder.flac, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
2257 flac__utils_printf(stderr, 1, "%s: ERROR: mismatch in decoded data, verify FAILED!\n", e->inbasefilename);
2258 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);
2259 flac__utils_printf(stderr, 1, " In all known cases, verify errors are caused by hardware problems,\n");
2260 flac__utils_printf(stderr, 1, " usually overclocking or bad RAM. Delete %s\n", e->outfilename);
2261 flac__utils_printf(stderr, 1, " and repeat the flac command exactly as before. If it does not give a\n");
2262 flac__utils_printf(stderr, 1, " verify error in the exact same place each time you try it, then there is\n");
2263 flac__utils_printf(stderr, 1, " a problem with your hardware; please see the FAQ:\n");
2264 flac__utils_printf(stderr, 1, " http://flac.sourceforge.net/faq.html#tools__hardware_prob\n");
2265 flac__utils_printf(stderr, 1, " If it does fail in the exact same place every time, keep\n");
2266 flac__utils_printf(stderr, 1, " %s and submit a bug report to:\n", e->outfilename);
2267 flac__utils_printf(stderr, 1, " https://sourceforge.net/bugs/?func=addbug&group_id=13478\n");
2268 flac__utils_printf(stderr, 1, " Make sure to upload the FLAC file and use the \"Monitor\" feature to\n");
2269 flac__utils_printf(stderr, 1, " monitor the bug status.\n");
2270 flac__utils_printf(stderr, 1, "Verify FAILED! Do not trust %s\n", e->outfilename);
2273 FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
2275 size_t bytes_read = fread(val, 1, 2, f);
2277 if(bytes_read == 0) {
2279 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2285 else if(bytes_read < 2) {
2286 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2290 if(is_big_endian_host_) {
2291 FLAC__byte tmp, *b = (FLAC__byte*)val;
2292 tmp = b[1]; b[1] = b[0]; b[0] = tmp;
2298 FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2300 size_t bytes_read = fread(val, 1, 4, f);
2302 if(bytes_read == 0) {
2304 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2310 else if(bytes_read < 4) {
2311 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2315 if(is_big_endian_host_) {
2316 FLAC__byte tmp, *b = (FLAC__byte*)val;
2317 tmp = b[3]; b[3] = b[0]; b[0] = tmp;
2318 tmp = b[2]; b[2] = b[1]; b[1] = tmp;
2324 FLAC__bool read_big_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
2326 unsigned char buf[4];
2327 size_t bytes_read= fread(buf, 1, 2, f);
2329 if(bytes_read==0U && eof_ok)
2331 else if(bytes_read<2U) {
2332 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2336 /* this is independent of host endianness */
2337 *val= (FLAC__uint16)(buf[0])<<8 | buf[1];
2342 FLAC__bool read_big_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2344 unsigned char buf[4];
2345 size_t bytes_read= fread(buf, 1, 4, f);
2347 if(bytes_read==0U && eof_ok)
2349 else if(bytes_read<4U) {
2350 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2354 /* this is independent of host endianness */
2355 *val= (FLAC__uint32)(buf[0])<<24 | (FLAC__uint32)(buf[1])<<16 |
2356 (FLAC__uint32)(buf[2])<<8 | buf[3];
2361 FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2362 /* Read an IEEE 754 80-bit (aka SANE) extended floating point value from 'f',
2363 * convert it into an integral value and store in 'val'. Return false if only
2364 * between 1 and 9 bytes remain in 'f', if 0 bytes remain in 'f' and 'eof_ok' is
2365 * false, or if the value is negative, between zero and one, or too large to be
2366 * represented by 'val'; return true otherwise.
2370 unsigned char buf[10];
2371 size_t bytes_read= fread(buf, 1U, 10U, f);
2372 FLAC__int16 e= ((FLAC__uint16)(buf[0])<<8 | (FLAC__uint16)(buf[1]))-0x3FFF;
2373 FLAC__int16 shift= 63-e;
2376 if(bytes_read==0U && eof_ok)
2378 else if(bytes_read<10U) {
2379 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2382 else if((buf[0]>>7)==1U || e<0 || e>63) {
2383 flac__utils_printf(stderr, 1, "%s: ERROR: invalid floating-point value\n", fn);
2387 for(i= 0U; i<8U; ++i)
2388 p|= (FLAC__uint64)(buf[i+2])<<(56U-i*8);
2389 *val= (FLAC__uint32)((p>>shift)+(p>>(shift-1) & 0x1));
2394 FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset)
2396 static unsigned char dump[8192];
2399 long need = (long)min(offset, LONG_MAX);
2400 if(fseeko(f, need, SEEK_CUR) < 0) {
2401 need = (long)min(offset, sizeof(dump));
2402 if((long)fread(dump, 1, need, f) < need)
2407 #if 0 /* pure non-fseek() version */
2409 const long need = (long)min(offset, sizeof(dump));
2410 if(fread(dump, 1, need, f) < need)