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, i;
1445 FLAC__StreamMetadata padding, *cuesheet = 0;
1446 FLAC__StreamMetadata *static_metadata[4+64]; /* MAGIC +64 is for pictures metadata in options.pictures */
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 FLAC__ASSERT(sizeof(options.pictures)/sizeof(options.pictures[0]) <= 64);
1453 e->replay_gain = options.replay_gain;
1454 e->channels = channels;
1455 e->bits_per_sample = bps;
1456 e->sample_rate = sample_rate;
1458 if(e->replay_gain) {
1459 if(channels != 1 && channels != 2) {
1460 flac__utils_printf(stderr, 1, "%s: ERROR, number of channels (%u) must be 1 or 2 for --replay-gain\n", e->inbasefilename, channels);
1463 if(!grabbag__replaygain_is_valid_sample_frequency(sample_rate)) {
1464 flac__utils_printf(stderr, 1, "%s: ERROR, invalid sample rate (%u) for --replay-gain\n", e->inbasefilename, sample_rate);
1467 if(options.is_first_file) {
1468 if(!grabbag__replaygain_init(sample_rate)) {
1469 flac__utils_printf(stderr, 1, "%s: ERROR initializing ReplayGain stage\n", e->inbasefilename);
1476 options.do_mid_side = options.loose_mid_side = false;
1478 if(!parse_cuesheet(&cuesheet, options.cuesheet_filename, e->inbasefilename, is_cdda, e->total_samples_to_encode))
1481 if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, options.cued_seekpoints? cuesheet : 0, e)) {
1482 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1484 FLAC__metadata_object_delete(cuesheet);
1488 if(flac_decoder_data) {
1490 * we're encoding from FLAC so we will use the FLAC file's
1491 * metadata as the basic for the encoded file
1495 * first handle padding: if --no-padding was specified,
1496 * then delete all padding; else if -P was specified,
1497 * use that instead of existing padding (if any); else
1498 * if existing file has padding, move all existing
1499 * padding blocks to one padding block at the end; else
1500 * use default padding.
1504 for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1505 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_PADDING) {
1508 p += flac_decoder_data->metadata_blocks[i]->length;
1509 FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1510 flac_decoder_data->metadata_blocks[i] = 0;
1513 flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1515 flac_decoder_data->num_metadata_blocks = j;
1516 if(options.padding > 0)
1517 p = options.padding;
1519 p = FLAC_ENCODE__DEFAULT_PADDING;
1520 if(options.padding != 0) {
1521 if(p > 0 && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
1522 flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING);
1523 if(0 == flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]) {
1524 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for PADDING block\n", e->inbasefilename);
1526 FLAC__metadata_object_delete(cuesheet);
1529 flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]->is_last = false; /* the encoder will set this for us */
1530 flac_decoder_data->metadata_blocks[flac_decoder_data->num_metadata_blocks]->length = p;
1531 flac_decoder_data->num_metadata_blocks++;
1537 * next handle vorbis comment: if any tags were specified
1538 * or there is no existing vorbis comment, we create a
1539 * new vorbis comment (discarding any existing one); else
1540 * we keep the existing one
1543 FLAC__bool vc_found = false;
1544 for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1545 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
1547 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT && options.vorbis_comment->data.vorbis_comment.num_comments > 0) {
1548 if(options.vorbis_comment->data.vorbis_comment.num_comments > 0)
1549 flac__utils_printf(stderr, 1, "%s: WARNING, replacing tags from input FLAC file with those given on the command-line\n", e->inbasefilename);
1550 FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1551 flac_decoder_data->metadata_blocks[i] = 0;
1554 flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1556 flac_decoder_data->num_metadata_blocks = j;
1557 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])) {
1559 FLAC__StreamMetadata *vc = FLAC__metadata_object_clone(options.vorbis_comment);
1561 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for VORBIS_COMMENT block\n", e->inbasefilename);
1563 FLAC__metadata_object_delete(cuesheet);
1566 for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1567 flac_decoder_data->metadata_blocks[i] = flac_decoder_data->metadata_blocks[i-1];
1568 flac_decoder_data->metadata_blocks[1] = vc;
1569 flac_decoder_data->num_metadata_blocks++;
1574 * next handle cuesheet: if --cuesheet was specified, use
1575 * it; else if file has existing CUESHEET and cuesheet's
1576 * lead-out offset is correct, keep it; else no CUESHEET
1579 for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1580 FLAC__bool existing_cuesheet_is_bad = false;
1581 /* check if existing cuesheet matches the input audio */
1582 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && 0 == cuesheet) {
1583 const FLAC__StreamMetadata_CueSheet *cs = &flac_decoder_data->metadata_blocks[i]->data.cue_sheet;
1584 if(e->total_samples_to_encode == 0) {
1585 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);
1586 existing_cuesheet_is_bad = true;
1588 else if(e->total_samples_to_encode != cs->tracks[cs->num_tracks-1].offset) {
1589 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);
1590 existing_cuesheet_is_bad = true;
1593 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_CUESHEET && (existing_cuesheet_is_bad || 0 != cuesheet)) {
1595 flac__utils_printf(stderr, 1, "%s: WARNING, replacing cuesheet in input FLAC file with the one given on the command-line\n", e->inbasefilename);
1596 FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1597 flac_decoder_data->metadata_blocks[i] = 0;
1600 flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1602 flac_decoder_data->num_metadata_blocks = j;
1603 if(0 != cuesheet && flac_decoder_data->num_metadata_blocks < sizeof(flac_decoder_data->metadata_blocks)/sizeof(flac_decoder_data->metadata_blocks[0])) {
1605 FLAC__StreamMetadata *cs = FLAC__metadata_object_clone(cuesheet);
1607 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for CUESHEET block\n", e->inbasefilename);
1609 FLAC__metadata_object_delete(cuesheet);
1612 for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1613 flac_decoder_data->metadata_blocks[i] = flac_decoder_data->metadata_blocks[i-1];
1614 flac_decoder_data->metadata_blocks[1] = cs;
1615 flac_decoder_data->num_metadata_blocks++;
1620 * finally handle seektable: if -S- was specified, no
1621 * SEEKTABLE; else if -S was specified, use it/them;
1622 * else if file has existing SEEKTABLE and input size is
1623 * preserved (no --skip/--until/etc specified), keep it;
1624 * else use default seektable options
1626 * note: meanings of num_requested_seek_points:
1627 * -1 : no -S option given, default to some value
1628 * 0 : -S- given (no seektable)
1629 * >0 : one or more -S options given
1632 FLAC__bool existing_seektable = false;
1633 for(i = 0, j = 0; i < flac_decoder_data->num_metadata_blocks; i++) {
1634 if(flac_decoder_data->metadata_blocks[i]->type == FLAC__METADATA_TYPE_SEEKTABLE)
1635 existing_seektable = true;
1636 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)) {
1637 if(options.num_requested_seek_points > 0)
1638 flac__utils_printf(stderr, 1, "%s: WARNING, replacing seektable in input FLAC file with the one given on the command-line\n", e->inbasefilename);
1639 else if(options.num_requested_seek_points == 0)
1640 ; /* no warning, silently delete existing SEEKTABLE since user specified --no-seektable (-S-) */
1642 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);
1643 FLAC__metadata_object_delete(flac_decoder_data->metadata_blocks[i]);
1644 flac_decoder_data->metadata_blocks[i] = 0;
1645 existing_seektable = false;
1648 flac_decoder_data->metadata_blocks[j++] = flac_decoder_data->metadata_blocks[i];
1650 flac_decoder_data->num_metadata_blocks = j;
1651 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])) {
1653 FLAC__StreamMetadata *st = FLAC__metadata_object_clone(e->seek_table_template);
1655 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for SEEKTABLE block\n", e->inbasefilename);
1657 FLAC__metadata_object_delete(cuesheet);
1660 for(i = flac_decoder_data->num_metadata_blocks; i > 1; i--)
1661 flac_decoder_data->metadata_blocks[i] = flac_decoder_data->metadata_blocks[i-1];
1662 flac_decoder_data->metadata_blocks[1] = st;
1663 flac_decoder_data->num_metadata_blocks++;
1666 metadata = &flac_decoder_data->metadata_blocks[1]; /* don't include STREAMINFO */
1667 num_metadata = flac_decoder_data->num_metadata_blocks - 1;
1671 * we're not encoding from FLAC so we will build the metadata
1675 if(e->seek_table_template->data.seek_table.num_points > 0) {
1676 e->seek_table_template->is_last = false; /* the encoder will set this for us */
1677 metadata[num_metadata++] = e->seek_table_template;
1680 metadata[num_metadata++] = cuesheet;
1681 metadata[num_metadata++] = options.vorbis_comment;
1682 for(i = 0; i < options.num_pictures; i++)
1683 metadata[num_metadata++] = options.pictures[i];
1684 if(options.padding != 0) {
1685 padding.is_last = false; /* the encoder will set this for us */
1686 padding.type = FLAC__METADATA_TYPE_PADDING;
1687 padding.length = (unsigned)(options.padding>0? options.padding : FLAC_ENCODE__DEFAULT_PADDING);
1688 metadata[num_metadata++] = &padding;
1692 e->blocksize = options.blocksize;
1693 e->stats_mask = (options.do_exhaustive_model_search || options.do_qlp_coeff_prec_search)? 0x0f : 0x3f;
1695 #ifdef FLAC__HAS_OGG
1697 OggFLAC__stream_encoder_set_serial_number(e->encoder.ogg, options.serial_number);
1698 OggFLAC__stream_encoder_set_verify(e->encoder.ogg, options.verify);
1699 OggFLAC__stream_encoder_set_streamable_subset(e->encoder.ogg, !options.lax);
1700 OggFLAC__stream_encoder_set_do_mid_side_stereo(e->encoder.ogg, options.do_mid_side);
1701 OggFLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder.ogg, options.loose_mid_side);
1702 OggFLAC__stream_encoder_set_channels(e->encoder.ogg, channels);
1703 OggFLAC__stream_encoder_set_bits_per_sample(e->encoder.ogg, bps);
1704 OggFLAC__stream_encoder_set_sample_rate(e->encoder.ogg, sample_rate);
1705 OggFLAC__stream_encoder_set_blocksize(e->encoder.ogg, options.blocksize);
1706 OggFLAC__stream_encoder_set_apodization(e->encoder.ogg, options.apodizations);
1707 OggFLAC__stream_encoder_set_max_lpc_order(e->encoder.ogg, options.max_lpc_order);
1708 OggFLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.ogg, options.qlp_coeff_precision);
1709 OggFLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.ogg, options.do_qlp_coeff_prec_search);
1710 OggFLAC__stream_encoder_set_do_escape_coding(e->encoder.ogg, options.do_escape_coding);
1711 OggFLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder.ogg, options.do_exhaustive_model_search);
1712 OggFLAC__stream_encoder_set_min_residual_partition_order(e->encoder.ogg, options.min_residual_partition_order);
1713 OggFLAC__stream_encoder_set_max_residual_partition_order(e->encoder.ogg, options.max_residual_partition_order);
1714 OggFLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder.ogg, options.rice_parameter_search_dist);
1715 OggFLAC__stream_encoder_set_total_samples_estimate(e->encoder.ogg, e->total_samples_to_encode);
1716 OggFLAC__stream_encoder_set_metadata(e->encoder.ogg, (num_metadata > 0)? metadata : 0, num_metadata);
1718 OggFLAC__stream_encoder_disable_constant_subframes(e->encoder.ogg, options.debug.disable_constant_subframes);
1719 OggFLAC__stream_encoder_disable_fixed_subframes(e->encoder.ogg, options.debug.disable_fixed_subframes);
1720 OggFLAC__stream_encoder_disable_verbatim_subframes(e->encoder.ogg, options.debug.disable_verbatim_subframes);
1722 init_status = OggFLAC__stream_encoder_init_file(e->encoder.ogg, e->is_stdout? 0 : e->outfilename, encoder_progress_callback, /*client_data=*/e);
1723 if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
1724 print_error_with_init_status(e, "ERROR initializing encoder", init_status);
1726 FLAC__metadata_object_delete(cuesheet);
1733 FLAC__stream_encoder_set_verify(e->encoder.flac, options.verify);
1734 FLAC__stream_encoder_set_streamable_subset(e->encoder.flac, !options.lax);
1735 FLAC__stream_encoder_set_do_mid_side_stereo(e->encoder.flac, options.do_mid_side);
1736 FLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder.flac, options.loose_mid_side);
1737 FLAC__stream_encoder_set_channels(e->encoder.flac, channels);
1738 FLAC__stream_encoder_set_bits_per_sample(e->encoder.flac, bps);
1739 FLAC__stream_encoder_set_sample_rate(e->encoder.flac, sample_rate);
1740 FLAC__stream_encoder_set_blocksize(e->encoder.flac, options.blocksize);
1741 FLAC__stream_encoder_set_apodization(e->encoder.flac, options.apodizations);
1742 FLAC__stream_encoder_set_max_lpc_order(e->encoder.flac, options.max_lpc_order);
1743 FLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.flac, options.qlp_coeff_precision);
1744 FLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.flac, options.do_qlp_coeff_prec_search);
1745 FLAC__stream_encoder_set_do_escape_coding(e->encoder.flac, options.do_escape_coding);
1746 FLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder.flac, options.do_exhaustive_model_search);
1747 FLAC__stream_encoder_set_min_residual_partition_order(e->encoder.flac, options.min_residual_partition_order);
1748 FLAC__stream_encoder_set_max_residual_partition_order(e->encoder.flac, options.max_residual_partition_order);
1749 FLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder.flac, options.rice_parameter_search_dist);
1750 FLAC__stream_encoder_set_total_samples_estimate(e->encoder.flac, e->total_samples_to_encode);
1751 FLAC__stream_encoder_set_metadata(e->encoder.flac, (num_metadata > 0)? metadata : 0, num_metadata);
1753 FLAC__stream_encoder_disable_constant_subframes(e->encoder.flac, options.debug.disable_constant_subframes);
1754 FLAC__stream_encoder_disable_fixed_subframes(e->encoder.flac, options.debug.disable_fixed_subframes);
1755 FLAC__stream_encoder_disable_verbatim_subframes(e->encoder.flac, options.debug.disable_verbatim_subframes);
1757 init_status = FLAC__stream_encoder_init_file(e->encoder.flac, e->is_stdout? 0 : e->outfilename, encoder_progress_callback, /*client_data=*/e);
1758 if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
1759 print_error_with_init_status(e, "ERROR initializing encoder", init_status);
1761 FLAC__metadata_object_delete(cuesheet);
1767 FLAC__metadata_object_delete(cuesheet);
1772 FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples)
1774 if(e->replay_gain) {
1775 if(!grabbag__replaygain_analyze(buffer, e->channels==2, e->bits_per_sample, samples)) {
1776 flac__utils_printf(stderr, 1, "%s: WARNING, error while calculating ReplayGain\n", e->inbasefilename);
1780 #ifdef FLAC__HAS_OGG
1782 return OggFLAC__stream_encoder_process(e->encoder.ogg, buffer, samples);
1785 return FLAC__stream_encoder_process(e->encoder.flac, buffer, samples);
1788 FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int num_requested_seek_points, FLAC__StreamMetadata *cuesheet, EncoderSession *e)
1790 const FLAC__bool only_placeholders = e->is_stdout;
1791 FLAC__bool has_real_points;
1793 if(num_requested_seek_points == 0 && 0 == cuesheet)
1796 if(num_requested_seek_points < 0) {
1797 requested_seek_points = "10s;";
1798 num_requested_seek_points = 1;
1801 if(num_requested_seek_points > 0) {
1802 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))
1808 const FLAC__StreamMetadata_CueSheet *cs = &cuesheet->data.cue_sheet;
1809 for(i = 0; i < cs->num_tracks; i++) {
1810 const FLAC__StreamMetadata_CueSheet_Track *tr = cs->tracks+i;
1811 for(j = 0; j < tr->num_indices; j++) {
1812 if(!FLAC__metadata_object_seektable_template_append_point(e->seek_table_template, tr->offset + tr->indices[j].offset))
1814 has_real_points = true;
1818 if(!FLAC__metadata_object_seektable_template_sort(e->seek_table_template, /*compact=*/true))
1822 if(has_real_points) {
1824 flac__utils_printf(stderr, 1, "%s: WARNING, cannot write back seekpoints when encoding to stdout\n", e->inbasefilename);
1831 FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input)
1833 /* convert from mm:ss.sss to sample number if necessary */
1834 flac__utils_canonicalize_skip_until_specification(spec, sample_rate);
1836 /* special case: if "--until=-0", use the special value '0' to mean "end-of-stream" */
1837 if(spec->is_relative && spec->value.samples == 0) {
1838 spec->is_relative = false;
1842 /* in any other case the total samples in the input must be known */
1843 if(total_samples_in_input == 0) {
1844 flac__utils_printf(stderr, 1, "%s: ERROR, cannot use --until when input length is unknown\n", inbasefilename);
1848 FLAC__ASSERT(spec->value_is_samples);
1850 /* convert relative specifications to absolute */
1851 if(spec->is_relative) {
1852 if(spec->value.samples <= 0)
1853 spec->value.samples += (FLAC__int64)total_samples_in_input;
1855 spec->value.samples += skip;
1856 spec->is_relative = false;
1860 if(spec->value.samples < 0) {
1861 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before beginning of input\n", inbasefilename);
1864 if((FLAC__uint64)spec->value.samples <= skip) {
1865 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before --skip point\n", inbasefilename);
1868 if((FLAC__uint64)spec->value.samples > total_samples_in_input) {
1869 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is after end of input\n", inbasefilename);
1876 void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps)
1878 unsigned wide_sample, sample, channel, byte;
1881 if(is_unsigned_samples) {
1882 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1883 for(channel = 0; channel < channels; channel++, sample++)
1884 dest[channel][wide_sample] = (FLAC__int32)ucbuffer_[sample] - 0x80;
1887 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1888 for(channel = 0; channel < channels; channel++, sample++)
1889 dest[channel][wide_sample] = (FLAC__int32)scbuffer_[sample];
1892 else if(bps == 16) {
1893 if(is_big_endian != is_big_endian_host_) {
1895 const unsigned bytes = wide_samples * channels * (bps >> 3);
1896 for(byte = 0; byte < bytes; byte += 2) {
1897 tmp = ucbuffer_[byte];
1898 ucbuffer_[byte] = ucbuffer_[byte+1];
1899 ucbuffer_[byte+1] = tmp;
1902 if(is_unsigned_samples) {
1903 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1904 for(channel = 0; channel < channels; channel++, sample++)
1905 dest[channel][wide_sample] = (FLAC__int32)usbuffer_[sample] - 0x8000;
1908 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1909 for(channel = 0; channel < channels; channel++, sample++)
1910 dest[channel][wide_sample] = (FLAC__int32)ssbuffer_[sample];
1913 else if(bps == 24) {
1914 if(!is_big_endian) {
1916 const unsigned bytes = wide_samples * channels * (bps >> 3);
1917 for(byte = 0; byte < bytes; byte += 3) {
1918 tmp = ucbuffer_[byte];
1919 ucbuffer_[byte] = ucbuffer_[byte+2];
1920 ucbuffer_[byte+2] = tmp;
1923 if(is_unsigned_samples) {
1924 for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1925 for(channel = 0; channel < channels; channel++, sample++) {
1926 dest[channel][wide_sample] = ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1927 dest[channel][wide_sample] |= ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1928 dest[channel][wide_sample] |= ucbuffer_[byte++];
1929 dest[channel][wide_sample] -= 0x800000;
1933 for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1934 for(channel = 0; channel < channels; channel++, sample++) {
1935 dest[channel][wide_sample] = scbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1936 dest[channel][wide_sample] |= ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1937 dest[channel][wide_sample] |= ucbuffer_[byte++];
1946 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)
1948 EncoderSession *encoder_session = (EncoderSession*)client_data;
1950 (void)encoder, (void)total_frames_estimate;
1952 encoder_session->bytes_written = bytes_written;
1953 encoder_session->samples_written = samples_written;
1955 if(encoder_session->total_samples_to_encode > 0 && !((frames_written-1) & encoder_session->stats_mask))
1956 print_stats(encoder_session);
1959 FLAC__StreamDecoderReadStatus flac_decoder_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
1962 FLACDecoderData *data = (FLACDecoderData*)client_data;
1965 if (data->fatal_error)
1966 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
1968 /* use up lookahead first */
1969 if (data->lookahead_length) {
1970 n = min(data->lookahead_length, *bytes);
1971 memcpy(buffer, data->lookahead, n);
1973 data->lookahead += n;
1974 data->lookahead_length -= n;
1977 /* get the rest from file */
1979 *bytes = n + fread(buffer, 1, *bytes-n, data->encoder_session->fin);
1980 return ferror(data->encoder_session->fin)? FLAC__STREAM_DECODER_READ_STATUS_ABORT : FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
1983 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
1986 FLAC__StreamDecoderSeekStatus flac_decoder_seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
1988 FLACDecoderData *data = (FLACDecoderData*)client_data;
1991 if(fseeko(data->encoder_session->fin, (off_t)absolute_byte_offset, SEEK_SET) < 0)
1992 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
1994 return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
1997 FLAC__StreamDecoderTellStatus flac_decoder_tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
1999 FLACDecoderData *data = (FLACDecoderData*)client_data;
2003 if((pos = ftello(data->encoder_session->fin)) < 0)
2004 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
2006 *absolute_byte_offset = (FLAC__uint64)pos;
2007 return FLAC__STREAM_DECODER_TELL_STATUS_OK;
2011 FLAC__StreamDecoderLengthStatus flac_decoder_length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
2013 FLACDecoderData *data = (FLACDecoderData*)client_data;
2016 if(0 == data->filesize)
2017 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
2019 *stream_length = (FLAC__uint64)data->filesize;
2020 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
2024 FLAC__bool flac_decoder_eof_callback(const FLAC__StreamDecoder *decoder, void *client_data)
2026 FLACDecoderData *data = (FLACDecoderData*)client_data;
2029 return feof(data->encoder_session->fin)? true : false;
2032 FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
2034 FLACDecoderData *data = (FLACDecoderData*)client_data;
2035 FLAC__uint64 n = min(data->samples_left_to_process, frame->header.blocksize);
2038 if(!EncoderSession_process(data->encoder_session, buffer, (unsigned)n)) {
2039 print_error_with_state(data->encoder_session, "ERROR during encoding");
2040 data->fatal_error = true;
2041 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
2044 data->samples_left_to_process -= n;
2045 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
2048 void flac_decoder_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
2050 FLACDecoderData *data = (FLACDecoderData*)client_data;
2053 if (data->fatal_error)
2057 data->num_metadata_blocks == sizeof(data->metadata_blocks)/sizeof(data->metadata_blocks[0]) ||
2058 0 == (data->metadata_blocks[data->num_metadata_blocks] = FLAC__metadata_object_clone(metadata))
2060 data->fatal_error = true;
2062 data->num_metadata_blocks++;
2065 void flac_decoder_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
2067 FLACDecoderData *data = (FLACDecoderData*)client_data;
2070 flac__utils_printf(stderr, 1, "%s: ERROR got %s while decoding FLAC input\n", data->encoder_session->inbasefilename, FLAC__StreamDecoderErrorStatusString[status]);
2071 data->fatal_error = true;
2074 FLAC__bool parse_cuesheet(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset)
2077 unsigned last_line_read;
2078 const char *error_message;
2080 if(0 == cuesheet_filename)
2083 if(lead_out_offset == 0) {
2084 flac__utils_printf(stderr, 1, "%s: ERROR cannot import cuesheet when the number of input samples to encode is unknown\n", inbasefilename);
2088 if(0 == (f = fopen(cuesheet_filename, "r"))) {
2089 flac__utils_printf(stderr, 1, "%s: ERROR opening cuesheet \"%s\" for reading: %s\n", inbasefilename, cuesheet_filename, strerror(errno));
2093 *cuesheet = grabbag__cuesheet_parse(f, &error_message, &last_line_read, is_cdda, lead_out_offset);
2097 if(0 == *cuesheet) {
2098 flac__utils_printf(stderr, 1, "%s: ERROR parsing cuesheet \"%s\" on line %u: %s\n", inbasefilename, cuesheet_filename, last_line_read, error_message);
2102 if(!FLAC__format_cuesheet_is_legal(&(*cuesheet)->data.cue_sheet, /*check_cd_da_subset=*/false, &error_message)) {
2103 flac__utils_printf(stderr, 1, "%s: ERROR parsing cuesheet \"%s\": %s\n", inbasefilename, cuesheet_filename, error_message);
2107 /* if we're expecting CDDA, warn about non-compliance */
2108 if(is_cdda && !FLAC__format_cuesheet_is_legal(&(*cuesheet)->data.cue_sheet, /*check_cd_da_subset=*/true, &error_message)) {
2109 flac__utils_printf(stderr, 1, "%s: WARNING cuesheet \"%s\" is not audio CD compliant: %s\n", inbasefilename, cuesheet_filename, error_message);
2110 (*cuesheet)->data.cue_sheet.is_cd = false;
2116 void print_stats(const EncoderSession *encoder_session)
2118 const FLAC__uint64 samples_written = min(encoder_session->total_samples_to_encode, encoder_session->samples_written);
2119 #if defined _MSC_VER || defined __MINGW32__
2120 /* with MSVC you have to spoon feed it the casting */
2121 const double progress = (double)(FLAC__int64)samples_written / (double)(FLAC__int64)encoder_session->total_samples_to_encode;
2122 const double ratio = (double)(FLAC__int64)encoder_session->bytes_written / ((double)(FLAC__int64)encoder_session->unencoded_size * min(1.0, progress));
2124 const double progress = (double)samples_written / (double)encoder_session->total_samples_to_encode;
2125 const double ratio = (double)encoder_session->bytes_written / ((double)encoder_session->unencoded_size * min(1.0, progress));
2129 if(samples_written == encoder_session->total_samples_to_encode) {
2130 flac__utils_printf(stderr, 2, "\r%s:%s wrote %u bytes, ratio=%0.3f",
2131 encoder_session->inbasefilename,
2132 encoder_session->verify? " Verify OK," : "",
2133 (unsigned)encoder_session->bytes_written,
2138 flac__utils_printf(stderr, 2, "\r%s: %u%% complete, ratio=%0.3f", encoder_session->inbasefilename, (unsigned)floor(progress * 100.0 + 0.5), ratio);
2142 void print_error_with_init_status(const EncoderSession *e, const char *message, FLAC__StreamEncoderInitStatus init_status)
2144 const int ilen = strlen(e->inbasefilename) + 1;
2145 const char *state_string = "";
2147 flac__utils_printf(stderr, 1, "\n%s: %s\n", e->inbasefilename, message);
2149 flac__utils_printf(stderr, 1, "%*s init_status = %s\n", ilen, "", FLAC__StreamEncoderInitStatusString[init_status]);
2151 if(init_status == FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR) {
2152 #ifdef FLAC__HAS_OGG
2154 state_string = OggFLAC__stream_encoder_get_resolved_state_string(e->encoder.ogg);
2157 state_string = FLAC__stream_encoder_get_resolved_state_string(e->encoder.flac);
2159 flac__utils_printf(stderr, 1, "%*s state = %s\n", ilen, "", state_string);
2161 /* print out some more info for some errors: */
2163 0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_CLIENT_ERROR])
2164 #ifdef FLAC__HAS_OGG
2165 || 0 == strcmp(state_string, OggFLAC__StreamEncoderStateString[OggFLAC__STREAM_ENCODER_CLIENT_ERROR])
2168 flac__utils_printf(stderr, 1,
2170 "An error occurred while writing; the most common cause is that the disk is full.\n"
2174 0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_IO_ERROR])
2175 #ifdef FLAC__HAS_OGG
2176 || 0 == strcmp(state_string, OggFLAC__StreamEncoderStateString[OggFLAC__STREAM_ENCODER_IO_ERROR])
2179 flac__utils_printf(stderr, 1,
2181 "An error occurred opening the output file; it is likely that the output\n"
2182 "directory does not exist or is not writable, the output file already exists and\n"
2183 "is not writable, or the disk is full.\n"
2187 else if(init_status == FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE) {
2188 flac__utils_printf(stderr, 1,
2190 "The encoding parameters specified do not conform to the FLAC Subset and may not\n"
2191 "be streamable or playable in hardware devices. Add --lax to the command-line\n"
2192 "options to encode with these parameters anyway.\n"
2197 void print_error_with_state(const EncoderSession *e, const char *message)
2199 const int ilen = strlen(e->inbasefilename) + 1;
2200 const char *state_string;
2202 flac__utils_printf(stderr, 1, "\n%s: %s\n", e->inbasefilename, message);
2204 #ifdef FLAC__HAS_OGG
2206 state_string = OggFLAC__stream_encoder_get_resolved_state_string(e->encoder.ogg);
2209 state_string = FLAC__stream_encoder_get_resolved_state_string(e->encoder.flac);
2211 flac__utils_printf(stderr, 1, "%*s state = %s\n", ilen, "", state_string);
2213 /* print out some more info for some errors: */
2215 0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_CLIENT_ERROR])
2216 #ifdef FLAC__HAS_OGG
2217 || 0 == strcmp(state_string, OggFLAC__StreamEncoderStateString[OggFLAC__STREAM_ENCODER_CLIENT_ERROR])
2220 flac__utils_printf(stderr, 1,
2222 "An error occurred while writing; the most common cause is that the disk is full.\n"
2227 void print_verify_error(EncoderSession *e)
2229 FLAC__uint64 absolute_sample;
2230 unsigned frame_number;
2233 FLAC__int32 expected;
2236 #ifdef FLAC__HAS_OGG
2238 OggFLAC__stream_encoder_get_verify_decoder_error_stats(e->encoder.ogg, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
2241 FLAC__stream_encoder_get_verify_decoder_error_stats(e->encoder.flac, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
2243 flac__utils_printf(stderr, 1, "%s: ERROR: mismatch in decoded data, verify FAILED!\n", e->inbasefilename);
2244 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);
2245 flac__utils_printf(stderr, 1, " In all known cases, verify errors are caused by hardware problems,\n");
2246 flac__utils_printf(stderr, 1, " usually overclocking or bad RAM. Delete %s\n", e->outfilename);
2247 flac__utils_printf(stderr, 1, " and repeat the flac command exactly as before. If it does not give a\n");
2248 flac__utils_printf(stderr, 1, " verify error in the exact same place each time you try it, then there is\n");
2249 flac__utils_printf(stderr, 1, " a problem with your hardware; please see the FAQ:\n");
2250 flac__utils_printf(stderr, 1, " http://flac.sourceforge.net/faq.html#tools__hardware_prob\n");
2251 flac__utils_printf(stderr, 1, " If it does fail in the exact same place every time, keep\n");
2252 flac__utils_printf(stderr, 1, " %s and submit a bug report to:\n", e->outfilename);
2253 flac__utils_printf(stderr, 1, " https://sourceforge.net/bugs/?func=addbug&group_id=13478\n");
2254 flac__utils_printf(stderr, 1, " Make sure to upload the FLAC file and use the \"Monitor\" feature to\n");
2255 flac__utils_printf(stderr, 1, " monitor the bug status.\n");
2256 flac__utils_printf(stderr, 1, "Verify FAILED! Do not trust %s\n", e->outfilename);
2259 FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
2261 size_t bytes_read = fread(val, 1, 2, f);
2263 if(bytes_read == 0) {
2265 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2271 else if(bytes_read < 2) {
2272 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2276 if(is_big_endian_host_) {
2277 FLAC__byte tmp, *b = (FLAC__byte*)val;
2278 tmp = b[1]; b[1] = b[0]; b[0] = tmp;
2284 FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2286 size_t bytes_read = fread(val, 1, 4, f);
2288 if(bytes_read == 0) {
2290 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2296 else if(bytes_read < 4) {
2297 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2301 if(is_big_endian_host_) {
2302 FLAC__byte tmp, *b = (FLAC__byte*)val;
2303 tmp = b[3]; b[3] = b[0]; b[0] = tmp;
2304 tmp = b[2]; b[2] = b[1]; b[1] = tmp;
2310 FLAC__bool read_big_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
2312 unsigned char buf[4];
2313 size_t bytes_read= fread(buf, 1, 2, f);
2315 if(bytes_read==0U && eof_ok)
2317 else if(bytes_read<2U) {
2318 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2322 /* this is independent of host endianness */
2323 *val= (FLAC__uint16)(buf[0])<<8 | buf[1];
2328 FLAC__bool read_big_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2330 unsigned char buf[4];
2331 size_t bytes_read= fread(buf, 1, 4, f);
2333 if(bytes_read==0U && eof_ok)
2335 else if(bytes_read<4U) {
2336 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2340 /* this is independent of host endianness */
2341 *val= (FLAC__uint32)(buf[0])<<24 | (FLAC__uint32)(buf[1])<<16 |
2342 (FLAC__uint32)(buf[2])<<8 | buf[3];
2347 FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2348 /* Read an IEEE 754 80-bit (aka SANE) extended floating point value from 'f',
2349 * convert it into an integral value and store in 'val'. Return false if only
2350 * between 1 and 9 bytes remain in 'f', if 0 bytes remain in 'f' and 'eof_ok' is
2351 * false, or if the value is negative, between zero and one, or too large to be
2352 * represented by 'val'; return true otherwise.
2356 unsigned char buf[10];
2357 size_t bytes_read= fread(buf, 1U, 10U, f);
2358 FLAC__int16 e= ((FLAC__uint16)(buf[0])<<8 | (FLAC__uint16)(buf[1]))-0x3FFF;
2359 FLAC__int16 shift= 63-e;
2362 if(bytes_read==0U && eof_ok)
2364 else if(bytes_read<10U) {
2365 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2368 else if((buf[0]>>7)==1U || e<0 || e>63) {
2369 flac__utils_printf(stderr, 1, "%s: ERROR: invalid floating-point value\n", fn);
2373 for(i= 0U; i<8U; ++i)
2374 p|= (FLAC__uint64)(buf[i+2])<<(56U-i*8);
2375 *val= (FLAC__uint32)((p>>shift)+(p>>(shift-1) & 0x1));
2380 FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset)
2382 static unsigned char dump[8192];
2385 long need = (long)min(offset, LONG_MAX);
2386 if(fseeko(f, need, SEEK_CUR) < 0) {
2387 need = (long)min(offset, sizeof(dump));
2388 if((long)fread(dump, 1, need, f) < need)
2393 #if 0 /* pure non-fseek() version */
2395 const long need = (long)min(offset, sizeof(dump));
2396 if(fread(dump, 1, need, f) < need)