1 /* flac - Command-line FLAC encoder/decoder
2 * Copyright (C) 2000,2001,2002,2003,2004 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.
19 #if defined _WIN32 && !defined __CYGWIN__
20 /* where MSVC puts unlink() */
25 #include <limits.h> /* for LONG_MAX */
26 #include <math.h> /* for floor() */
27 #include <stdio.h> /* for FILE etc. */
28 #include <stdlib.h> /* for malloc */
29 #include <string.h> /* for strcmp() */
31 #include "share/grabbag.h"
39 #include "OggFLAC/stream_encoder.h"
40 #include "OggFLAC/file_encoder.h"
46 #define min(x,y) ((x)<(y)?(x):(y))
50 #define max(x,y) ((x)>(y)?(x):(y))
52 /* this MUST be >= 588 so that sector aligning can take place with one read */
53 #define CHUNK_OF_SAMPLES 2048
61 const char *inbasefilename;
62 const char *outfilename;
65 FLAC__uint64 until; /* a value of 0 mean end-of-stream (i.e. --until=-0) */
66 FLAC__bool replay_gain;
68 unsigned bits_per_sample;
70 FLAC__uint64 unencoded_size;
71 FLAC__uint64 total_samples_to_encode;
72 FLAC__uint64 bytes_written;
73 FLAC__uint64 samples_written;
78 * We use *.stream for encoding to stdout
79 * We use *.file for encoding to a regular file
83 FLAC__StreamEncoder *stream;
84 FLAC__FileEncoder *file;
88 OggFLAC__StreamEncoder *stream;
89 OggFLAC__FileEncoder *file;
96 FLAC__StreamMetadata *seek_table_template;
100 static FLAC__bool is_big_endian_host_;
102 static unsigned char ucbuffer_[CHUNK_OF_SAMPLES*FLAC__MAX_CHANNELS*((FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE+7)/8)];
103 static signed char *scbuffer_ = (signed char *)ucbuffer_;
104 static FLAC__uint16 *usbuffer_ = (FLAC__uint16 *)ucbuffer_;
105 static FLAC__int16 *ssbuffer_ = (FLAC__int16 *)ucbuffer_;
107 static FLAC__int32 in_[FLAC__MAX_CHANNELS][CHUNK_OF_SAMPLES];
108 static FLAC__int32 *input_[FLAC__MAX_CHANNELS];
112 * unpublished debug routines from the FLAC libs
114 extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
115 extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
116 extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
117 extern FLAC__bool FLAC__file_encoder_disable_constant_subframes(FLAC__FileEncoder *encoder, FLAC__bool value);
118 extern FLAC__bool FLAC__file_encoder_disable_fixed_subframes(FLAC__FileEncoder *encoder, FLAC__bool value);
119 extern FLAC__bool FLAC__file_encoder_disable_verbatim_subframes(FLAC__FileEncoder *encoder, FLAC__bool value);
121 extern FLAC__bool OggFLAC__stream_encoder_disable_constant_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value);
122 extern FLAC__bool OggFLAC__stream_encoder_disable_fixed_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value);
123 extern FLAC__bool OggFLAC__stream_encoder_disable_verbatim_subframes(OggFLAC__StreamEncoder *encoder, FLAC__bool value);
124 extern FLAC__bool OggFLAC__file_encoder_disable_constant_subframes(OggFLAC__FileEncoder *encoder, FLAC__bool value);
125 extern FLAC__bool OggFLAC__file_encoder_disable_fixed_subframes(OggFLAC__FileEncoder *encoder, FLAC__bool value);
126 extern FLAC__bool OggFLAC__file_encoder_disable_verbatim_subframes(OggFLAC__FileEncoder *encoder, FLAC__bool value);
132 static FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FILE *infile, const char *infilename, const char *outfilename);
133 static void EncoderSession_destroy(EncoderSession *e);
134 static int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero);
135 static int EncoderSession_finish_error(EncoderSession *e);
136 static FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, unsigned channels, unsigned bps, unsigned sample_rate);
137 static FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples);
138 static FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int num_requested_seek_points, FLAC__StreamMetadata *cuesheet, EncoderSession *e);
139 static FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input);
140 static void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps);
142 static FLAC__StreamEncoderWriteStatus ogg_stream_encoder_write_callback(const OggFLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
143 static void ogg_stream_encoder_metadata_callback(const OggFLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
144 static void ogg_file_encoder_progress_callback(const OggFLAC__FileEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data);
146 static FLAC__StreamEncoderWriteStatus flac_stream_encoder_write_callback(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
147 static void flac_stream_encoder_metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
148 static void flac_file_encoder_progress_callback(const FLAC__FileEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data);
149 static FLAC__bool parse_cuesheet_(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset);
150 static void print_stats(const EncoderSession *encoder_session);
151 static void print_error_with_state(const EncoderSession *e, const char *message);
152 static void print_verify_error(EncoderSession *e);
153 static FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn);
154 static FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
155 static FLAC__bool read_big_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn);
156 static FLAC__bool read_big_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
157 static FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn);
158 static FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset);
164 flac__encode_aif(FILE *infile, long infilesize, const char *infilename, const char *outfilename,
165 const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options)
167 EncoderSession encoder_session;
170 unsigned int channels= 0U, bps= 0U, sample_rate= 0U, sample_frames= 0U;
171 FLAC__bool got_comm_chunk= false, got_ssnd_chunk= false;
172 int info_align_carry= -1, info_align_zero= -1;
174 (void)infilesize; /* silence compiler warning about unused parameter */
175 (void)lookahead; /* silence compiler warning about unused parameter */
176 (void)lookahead_length; /* silence compiler warning about unused parameter */
179 EncoderSession_construct(
182 options.common.use_ogg,
186 options.common.verify,
194 /* lookahead[] already has "FORMxxxxAIFF", do sub-chunks */
200 /* chunk identifier; really conservative about behavior of fread() and feof() */
201 if(feof(infile) || ((c= fread(chunk_id, 1U, 4U, infile)), c==0U && feof(infile)))
203 else if(c<4U || feof(infile)) {
204 flac__utils_printf(stderr, 1, "%s: ERROR: incomplete chunk identifier\n", encoder_session.inbasefilename);
205 return EncoderSession_finish_error(&encoder_session);
208 if(got_comm_chunk==false && !strncmp(chunk_id, "COMM", 4)) { /* common chunk */
211 /* COMM chunk size */
212 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
213 return EncoderSession_finish_error(&encoder_session);
215 flac__utils_printf(stderr, 1, "%s: ERROR: non-standard 'COMM' chunk has length = %u\n", encoder_session.inbasefilename, (unsigned int)xx);
216 return EncoderSession_finish_error(&encoder_session);
219 flac__utils_printf(stderr, 1, "%s: WARNING: non-standard 'COMM' chunk has length = %u\n", encoder_session.inbasefilename, (unsigned int)xx);
221 skip= (xx-18U)+(xx & 1U);
223 /* number of channels */
224 if(!read_big_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
225 return EncoderSession_finish_error(&encoder_session);
226 else if(x==0U || x>FLAC__MAX_CHANNELS) {
227 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported number channels %u\n", encoder_session.inbasefilename, (unsigned int)x);
228 return EncoderSession_finish_error(&encoder_session);
230 else if(options.common.sector_align && x!=2U) {
231 flac__utils_printf(stderr, 1, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_session.inbasefilename, (unsigned int)x);
232 return EncoderSession_finish_error(&encoder_session);
236 /* number of sample frames */
237 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
238 return EncoderSession_finish_error(&encoder_session);
241 /* bits per sample */
242 if(!read_big_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
243 return EncoderSession_finish_error(&encoder_session);
244 else if(x!=8U && x!=16U && x!=24U) {
245 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported bits per sample %u\n", encoder_session.inbasefilename, (unsigned int)x);
246 return EncoderSession_finish_error(&encoder_session);
248 else if(options.common.sector_align && x!=16U) {
249 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);
250 return EncoderSession_finish_error(&encoder_session);
255 if(!read_sane_extended(infile, &xx, false, encoder_session.inbasefilename))
256 return EncoderSession_finish_error(&encoder_session);
257 else if(!FLAC__format_sample_rate_is_valid(xx)) {
258 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported sample rate %u\n", encoder_session.inbasefilename, (unsigned int)xx);
259 return EncoderSession_finish_error(&encoder_session);
261 else if(options.common.sector_align && xx!=44100U) {
262 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);
263 return EncoderSession_finish_error(&encoder_session);
267 /* skip any extra data in the COMM chunk */
268 if(!fskip_ahead(infile, skip)) {
269 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping extra COMM data\n", encoder_session.inbasefilename);
270 return EncoderSession_finish_error(&encoder_session);
274 * now that we know the sample rate, canonicalize the
275 * --skip string to a number of samples:
277 flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, sample_rate);
278 FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
279 encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
280 FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
282 got_comm_chunk= true;
284 else if(got_ssnd_chunk==false && !strncmp(chunk_id, "SSND", 4)) { /* sound data chunk */
285 unsigned int offset= 0U, block_size= 0U, align_remainder= 0U, data_bytes;
286 size_t bytes_per_frame= channels*(bps>>3);
287 FLAC__uint64 total_samples_in_input, trim = 0;
288 FLAC__bool pad= false;
290 if(got_comm_chunk==false) {
291 flac__utils_printf(stderr, 1, "%s: ERROR: got 'SSND' chunk before 'COMM' chunk\n", encoder_session.inbasefilename);
292 return EncoderSession_finish_error(&encoder_session);
295 /* SSND chunk size */
296 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
297 return EncoderSession_finish_error(&encoder_session);
299 pad= (data_bytes & 1U) ? true : false;
300 data_bytes-= 8U; /* discount the offset and block size fields */
303 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
304 return EncoderSession_finish_error(&encoder_session);
309 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
310 return EncoderSession_finish_error(&encoder_session);
312 flac__utils_printf(stderr, 1, "%s: ERROR: block size is %u; must be 0\n", encoder_session.inbasefilename, (unsigned int)xx);
313 return EncoderSession_finish_error(&encoder_session);
317 /* skip any SSND offset bytes */
318 FLAC__ASSERT(offset<=LONG_MAX);
319 if(!fskip_ahead(infile, offset)) {
320 flac__utils_printf(stderr, 1, "%s: ERROR: skipping offset in SSND chunk\n", encoder_session.inbasefilename);
321 return EncoderSession_finish_error(&encoder_session);
323 if(data_bytes!=(sample_frames*bytes_per_frame)) {
324 flac__utils_printf(stderr, 1, "%s: ERROR: SSND chunk size inconsistent with sample frame count\n", encoder_session.inbasefilename);
325 return EncoderSession_finish_error(&encoder_session);
328 /* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
329 FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
330 total_samples_in_input = data_bytes / bytes_per_frame + *options.common.align_reservoir_samples;
333 * now that we know the input size, canonicalize the
334 * --until string to an absolute sample number:
336 if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, sample_rate, encoder_session.skip, total_samples_in_input))
337 return EncoderSession_finish_error(&encoder_session);
338 encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
339 FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
341 if(encoder_session.skip>0U) {
342 if(!fskip_ahead(infile, encoder_session.skip*bytes_per_frame)) {
343 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
344 return EncoderSession_finish_error(&encoder_session);
348 data_bytes-= (unsigned int)encoder_session.skip*bytes_per_frame; /*@@@ WATCHOUT: 4GB limit */
349 encoder_session.total_samples_to_encode= total_samples_in_input - encoder_session.skip;
350 if(encoder_session.until > 0) {
351 trim = total_samples_in_input - encoder_session.until;
352 FLAC__ASSERT(total_samples_in_input > 0);
353 FLAC__ASSERT(!options.common.sector_align);
354 data_bytes-= (unsigned int)trim*bytes_per_frame;
355 encoder_session.total_samples_to_encode-= trim;
357 if(options.common.sector_align) {
358 align_remainder= (unsigned int)(encoder_session.total_samples_to_encode % 588U);
359 if(options.common.is_last_file)
360 encoder_session.total_samples_to_encode+= (588U-align_remainder); /* will pad with zeroes */
362 encoder_session.total_samples_to_encode-= align_remainder; /* will stop short and carry over to next file */
365 /* +54 for the size of the AIFF headers; this is just an estimate for the progress indicator and doesn't need to be exact */
366 encoder_session.unencoded_size= encoder_session.total_samples_to_encode*bytes_per_frame+54;
368 if(!EncoderSession_init_encoder(&encoder_session, options.common, channels, bps, sample_rate))
369 return EncoderSession_finish_error(&encoder_session);
371 /* first do any samples in the reservoir */
372 if(options.common.sector_align && *options.common.align_reservoir_samples>0U) {
374 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
375 print_error_with_state(&encoder_session, "ERROR during encoding");
376 return EncoderSession_finish_error(&encoder_session);
380 /* decrement the data_bytes counter if we need to align the file */
381 if(options.common.sector_align) {
382 if(options.common.is_last_file)
383 *options.common.align_reservoir_samples= 0U;
385 *options.common.align_reservoir_samples= align_remainder;
386 data_bytes-= (*options.common.align_reservoir_samples)*bytes_per_frame;
390 /* now do from the file */
391 while(data_bytes>0) {
392 size_t bytes_read= fread(ucbuffer_, 1U, min(data_bytes, CHUNK_OF_SAMPLES*bytes_per_frame), infile);
396 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
397 return EncoderSession_finish_error(&encoder_session);
399 else if(feof(infile)) {
400 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);
405 if(bytes_read % bytes_per_frame != 0U) {
406 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
407 return EncoderSession_finish_error(&encoder_session);
410 unsigned int frames= bytes_read/bytes_per_frame;
411 format_input(input_, frames, true, false, channels, bps);
413 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)input_, frames)) {
414 print_error_with_state(&encoder_session, "ERROR during encoding");
415 return EncoderSession_finish_error(&encoder_session);
418 data_bytes-= bytes_read;
424 FLAC__ASSERT(!options.common.sector_align);
425 if(!fskip_ahead(infile, trim*bytes_per_frame)) {
426 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
427 return EncoderSession_finish_error(&encoder_session);
431 /* now read unaligned samples into reservoir or pad with zeroes if necessary */
432 if(options.common.sector_align) {
433 if(options.common.is_last_file) {
434 unsigned int pad_frames= 588U-align_remainder;
436 if(pad_frames<588U) {
439 info_align_zero= pad_frames;
440 for(i= 0U; i<channels; ++i)
441 memset(input_[i], 0, pad_frames*(bps>>3));
443 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 *const *)input_, pad_frames)) {
444 print_error_with_state(&encoder_session, "ERROR during encoding");
445 return EncoderSession_finish_error(&encoder_session);
450 if(*options.common.align_reservoir_samples > 0) {
451 size_t bytes_read= fread(ucbuffer_, 1U, (*options.common.align_reservoir_samples)*bytes_per_frame, infile);
453 FLAC__ASSERT(CHUNK_OF_SAMPLES>=588U);
454 if(bytes_read==0U && ferror(infile)) {
455 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
456 return EncoderSession_finish_error(&encoder_session);
458 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_frame) {
459 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);
462 info_align_carry= *options.common.align_reservoir_samples;
463 format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, true, false, channels, bps);
472 if(fread(&tmp, 1U, 1U, infile)<1U) {
473 flac__utils_printf(stderr, 1, "%s: ERROR during read of SSND pad byte\n", encoder_session.inbasefilename);
474 return EncoderSession_finish_error(&encoder_session);
478 got_ssnd_chunk= true;
480 else { /* other chunk */
481 if(!strncmp(chunk_id, "COMM", 4)) {
482 flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'COMM' chunk\n", encoder_session.inbasefilename);
484 else if(!strncmp(chunk_id, "SSND", 4)) {
485 flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'SSND' chunk\n", encoder_session.inbasefilename);
488 flac__utils_printf(stderr, 1, "%s: WARNING: skipping unknown chunk '%s'\n", encoder_session.inbasefilename, chunk_id);
492 if(!read_big_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
493 return EncoderSession_finish_error(&encoder_session);
495 unsigned long skip= xx+(xx & 1U);
497 FLAC__ASSERT(skip<=LONG_MAX);
498 if(!fskip_ahead(infile, skip)) {
499 fprintf(stderr, "%s: ERROR during read while skipping unknown chunk\n", encoder_session.inbasefilename);
500 return EncoderSession_finish_error(&encoder_session);
506 if(got_ssnd_chunk==false && sample_frames!=0U) {
507 flac__utils_printf(stderr, 1, "%s: ERROR: missing SSND chunk\n", encoder_session.inbasefilename);
508 return EncoderSession_finish_error(&encoder_session);
511 return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
514 int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, wav_encode_options_t options)
516 EncoderSession encoder_session;
517 FLAC__bool is_unsigned_samples = false;
518 unsigned channels = 0, bps = 0, sample_rate = 0, data_bytes;
519 size_t bytes_per_wide_sample, bytes_read;
522 FLAC__bool got_fmt_chunk = false, got_data_chunk = false;
523 unsigned align_remainder = 0;
524 int info_align_carry = -1, info_align_zero = -1;
528 (void)lookahead_length;
531 EncoderSession_construct(
534 options.common.use_ogg,
538 options.common.verify,
547 * lookahead[] already has "RIFFxxxxWAVE", do sub-chunks
549 while(!feof(infile)) {
550 if(!read_little_endian_uint32(infile, &xx, true, encoder_session.inbasefilename))
551 return EncoderSession_finish_error(&encoder_session);
554 if(xx == 0x20746d66 && !got_fmt_chunk) { /* "fmt " */
555 unsigned block_align;
557 /* fmt sub-chunk size */
558 if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
559 return EncoderSession_finish_error(&encoder_session);
561 flac__utils_printf(stderr, 1, "%s: ERROR: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_session.inbasefilename, (unsigned)xx);
562 return EncoderSession_finish_error(&encoder_session);
564 else if(xx != 16 && xx != 18) {
565 flac__utils_printf(stderr, 1, "%s: WARNING: found non-standard 'fmt ' sub-chunk which has length = %u\n", encoder_session.inbasefilename, (unsigned)xx);
568 /* compression code */
569 if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
570 return EncoderSession_finish_error(&encoder_session);
572 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported compression type %u\n", encoder_session.inbasefilename, (unsigned)x);
573 return EncoderSession_finish_error(&encoder_session);
575 /* number of channels */
576 if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
577 return EncoderSession_finish_error(&encoder_session);
578 if(x == 0 || x > FLAC__MAX_CHANNELS) {
579 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported number channels %u\n", encoder_session.inbasefilename, (unsigned)x);
580 return EncoderSession_finish_error(&encoder_session);
582 else if(options.common.sector_align && x != 2) {
583 flac__utils_printf(stderr, 1, "%s: ERROR: file has %u channels, must be 2 for --sector-align\n", encoder_session.inbasefilename, (unsigned)x);
584 return EncoderSession_finish_error(&encoder_session);
588 if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
589 return EncoderSession_finish_error(&encoder_session);
590 if(!FLAC__format_sample_rate_is_valid(xx)) {
591 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported sample rate %u\n", encoder_session.inbasefilename, (unsigned)xx);
592 return EncoderSession_finish_error(&encoder_session);
594 else if(options.common.sector_align && xx != 44100) {
595 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);
596 return EncoderSession_finish_error(&encoder_session);
599 /* avg bytes per second (ignored) */
600 if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
601 return EncoderSession_finish_error(&encoder_session);
603 if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
604 return EncoderSession_finish_error(&encoder_session);
606 /* bits per sample */
607 if(!read_little_endian_uint16(infile, &x, false, encoder_session.inbasefilename))
608 return EncoderSession_finish_error(&encoder_session);
609 if(x != 8 && x != 16 && x != 24) {
610 flac__utils_printf(stderr, 1, "%s: ERROR: unsupported bits-per-sample %u\n", encoder_session.inbasefilename, (unsigned)x);
611 return EncoderSession_finish_error(&encoder_session);
613 else if(options.common.sector_align && x != 16) {
614 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);
615 return EncoderSession_finish_error(&encoder_session);
618 if(bps * channels != block_align * 8) {
619 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);
620 return EncoderSession_finish_error(&encoder_session);
622 is_unsigned_samples = (x == 8);
624 /* skip any extra data in the fmt sub-chunk */
628 for(left = data_bytes; left > 0; ) {
629 need = min(left, CHUNK_OF_SAMPLES);
630 if(fread(ucbuffer_, 1U, need, infile) < need) {
631 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
632 return EncoderSession_finish_error(&encoder_session);
639 * now that we know the sample rate, canonicalize the
640 * --skip string to a number of samples:
642 flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, sample_rate);
643 FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
644 encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
645 FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
647 got_fmt_chunk = true;
649 else if(xx == 0x61746164 && !got_data_chunk && got_fmt_chunk) { /* "data" */
650 FLAC__uint64 total_samples_in_input, trim = 0;
651 FLAC__bool pad = false;
654 if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
655 return EncoderSession_finish_error(&encoder_session);
657 pad = (data_bytes & 1U) ? true : false;
659 bytes_per_wide_sample = channels * (bps >> 3);
661 /* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
662 FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
663 total_samples_in_input = data_bytes / bytes_per_wide_sample + *options.common.align_reservoir_samples;
666 * now that we know the input size, canonicalize the
667 * --until string to an absolute sample number:
669 if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, sample_rate, encoder_session.skip, total_samples_in_input))
670 return EncoderSession_finish_error(&encoder_session);
671 encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
672 FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
674 if(encoder_session.skip > 0) {
675 if(!fskip_ahead(infile, encoder_session.skip * bytes_per_wide_sample)) {
676 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
677 return EncoderSession_finish_error(&encoder_session);
681 data_bytes -= (unsigned)encoder_session.skip * bytes_per_wide_sample; /*@@@ WATCHOUT: 4GB limit */
682 encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
683 if(encoder_session.until > 0) {
684 trim = total_samples_in_input - encoder_session.until;
685 FLAC__ASSERT(total_samples_in_input > 0);
686 FLAC__ASSERT(!options.common.sector_align);
687 data_bytes -= (unsigned int)trim * bytes_per_wide_sample;
688 encoder_session.total_samples_to_encode -= trim;
690 if(options.common.sector_align) {
691 align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
692 if(options.common.is_last_file)
693 encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
695 encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
698 /* +44 for the size of the WAV headers; this is just an estimate for the progress indicator and doesn't need to be exact */
699 encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample + 44;
701 if(!EncoderSession_init_encoder(&encoder_session, options.common, channels, bps, sample_rate))
702 return EncoderSession_finish_error(&encoder_session);
705 * first do any samples in the reservoir
707 if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
708 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
709 print_error_with_state(&encoder_session, "ERROR during encoding");
710 return EncoderSession_finish_error(&encoder_session);
715 * decrement the data_bytes counter if we need to align the file
717 if(options.common.sector_align) {
718 if(options.common.is_last_file) {
719 *options.common.align_reservoir_samples = 0;
722 *options.common.align_reservoir_samples = align_remainder;
723 data_bytes -= (*options.common.align_reservoir_samples) * bytes_per_wide_sample;
728 * now do from the file
730 while(data_bytes > 0) {
731 bytes_read = fread(ucbuffer_, sizeof(unsigned char), min(data_bytes, CHUNK_OF_SAMPLES * bytes_per_wide_sample), infile);
732 if(bytes_read == 0) {
734 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
735 return EncoderSession_finish_error(&encoder_session);
737 else if(feof(infile)) {
738 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);
743 if(bytes_read % bytes_per_wide_sample != 0) {
744 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
745 return EncoderSession_finish_error(&encoder_session);
748 unsigned wide_samples = bytes_read / bytes_per_wide_sample;
749 format_input(input_, wide_samples, false, is_unsigned_samples, channels, bps);
751 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
752 print_error_with_state(&encoder_session, "ERROR during encoding");
753 return EncoderSession_finish_error(&encoder_session);
755 data_bytes -= bytes_read;
761 FLAC__ASSERT(!options.common.sector_align);
762 if(!fskip_ahead(infile, trim * bytes_per_wide_sample)) {
763 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
764 return EncoderSession_finish_error(&encoder_session);
769 * now read unaligned samples into reservoir or pad with zeroes if necessary
771 if(options.common.sector_align) {
772 if(options.common.is_last_file) {
773 unsigned wide_samples = 588 - align_remainder;
774 if(wide_samples < 588) {
777 info_align_zero = wide_samples;
778 data_bytes = wide_samples * (bps >> 3);
779 for(channel = 0; channel < channels; channel++)
780 memset(input_[channel], 0, data_bytes);
782 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
783 print_error_with_state(&encoder_session, "ERROR during encoding");
784 return EncoderSession_finish_error(&encoder_session);
789 if(*options.common.align_reservoir_samples > 0) {
790 FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
791 bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
792 if(bytes_read == 0 && ferror(infile)) {
793 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
794 return EncoderSession_finish_error(&encoder_session);
796 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
797 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);
801 info_align_carry = *options.common.align_reservoir_samples;
802 format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, false, is_unsigned_samples, channels, bps);
811 if(fread(&tmp, 1U, 1U, infile) < 1U) {
812 flac__utils_printf(stderr, 1, "%s: ERROR during read of data pad byte\n", encoder_session.inbasefilename);
813 return EncoderSession_finish_error(&encoder_session);
817 got_data_chunk = true;
820 if(xx == 0x20746d66 && got_fmt_chunk) { /* "fmt " */
821 flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'fmt ' sub-chunk\n", encoder_session.inbasefilename);
823 else if(xx == 0x61746164) { /* "data" */
825 flac__utils_printf(stderr, 1, "%s: WARNING: skipping extra 'data' sub-chunk\n", encoder_session.inbasefilename);
827 else if(!got_fmt_chunk) {
828 flac__utils_printf(stderr, 1, "%s: ERROR: got 'data' sub-chunk before 'fmt' sub-chunk\n", encoder_session.inbasefilename);
829 return EncoderSession_finish_error(&encoder_session);
836 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));
839 if(!read_little_endian_uint32(infile, &xx, false, encoder_session.inbasefilename))
840 return EncoderSession_finish_error(&encoder_session);
842 unsigned long skip = xx+(xx & 1U);
844 FLAC__ASSERT(skip<=LONG_MAX);
845 if(!fskip_ahead(infile, skip)) {
846 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping unsupported sub-chunk\n", encoder_session.inbasefilename);
847 return EncoderSession_finish_error(&encoder_session);
853 return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
856 int flac__encode_raw(FILE *infile, long infilesize, const char *infilename, const char *outfilename, const FLAC__byte *lookahead, unsigned lookahead_length, raw_encode_options_t options)
858 EncoderSession encoder_session;
860 const size_t bytes_per_wide_sample = options.channels * (options.bps >> 3);
861 unsigned align_remainder = 0;
862 int info_align_carry = -1, info_align_zero = -1;
863 FLAC__uint64 total_samples_in_input = 0;;
865 FLAC__ASSERT(!options.common.sector_align || options.channels == 2);
866 FLAC__ASSERT(!options.common.sector_align || options.bps == 16);
867 FLAC__ASSERT(!options.common.sector_align || options.sample_rate == 44100);
868 FLAC__ASSERT(!options.common.sector_align || infilesize >= 0);
869 FLAC__ASSERT(!options.common.replay_gain || options.channels <= 2);
870 FLAC__ASSERT(!options.common.replay_gain || grabbag__replaygain_is_valid_sample_frequency(options.sample_rate));
873 EncoderSession_construct(
876 options.common.use_ogg,
880 options.common.verify,
889 * now that we know the sample rate, canonicalize the
890 * --skip string to a number of samples:
892 flac__utils_canonicalize_skip_until_specification(&options.common.skip_specification, options.sample_rate);
893 FLAC__ASSERT(options.common.skip_specification.value.samples >= 0);
894 encoder_session.skip = (FLAC__uint64)options.common.skip_specification.value.samples;
895 FLAC__ASSERT(!options.common.sector_align || encoder_session.skip == 0);
898 total_samples_in_input = 0;
900 /* *options.common.align_reservoir_samples will be 0 unless --sector-align is used */
901 FLAC__ASSERT(options.common.sector_align || *options.common.align_reservoir_samples == 0);
902 total_samples_in_input = (unsigned)infilesize / bytes_per_wide_sample + *options.common.align_reservoir_samples;
906 * now that we know the input size, canonicalize the
907 * --until strings to a number of samples:
909 if(!canonicalize_until_specification(&options.common.until_specification, encoder_session.inbasefilename, options.sample_rate, encoder_session.skip, total_samples_in_input))
910 return EncoderSession_finish_error(&encoder_session);
911 encoder_session.until = (FLAC__uint64)options.common.until_specification.value.samples;
912 FLAC__ASSERT(!options.common.sector_align || encoder_session.until == 0);
914 encoder_session.total_samples_to_encode = total_samples_in_input - encoder_session.skip;
915 if(encoder_session.until > 0) {
916 const FLAC__uint64 trim = total_samples_in_input - encoder_session.until;
917 FLAC__ASSERT(total_samples_in_input > 0);
918 FLAC__ASSERT(!options.common.sector_align);
919 encoder_session.total_samples_to_encode -= trim;
921 if(infilesize >= 0 && options.common.sector_align) {
922 FLAC__ASSERT(encoder_session.skip == 0);
923 align_remainder = (unsigned)(encoder_session.total_samples_to_encode % 588);
924 if(options.common.is_last_file)
925 encoder_session.total_samples_to_encode += (588-align_remainder); /* will pad with zeroes */
927 encoder_session.total_samples_to_encode -= align_remainder; /* will stop short and carry over to next file */
929 encoder_session.unencoded_size = encoder_session.total_samples_to_encode * bytes_per_wide_sample;
931 if(encoder_session.total_samples_to_encode <= 0)
932 flac__utils_printf(stderr, 2, "(No runtime statistics possible; please wait for encoding to finish...)\n");
934 if(encoder_session.skip > 0) {
935 unsigned skip_bytes = bytes_per_wide_sample * (unsigned)encoder_session.skip;
936 if(skip_bytes > lookahead_length) {
937 skip_bytes -= lookahead_length;
938 lookahead_length = 0;
939 if(!fskip_ahead(infile, skip_bytes)) {
940 flac__utils_printf(stderr, 1, "%s: ERROR during read while skipping samples\n", encoder_session.inbasefilename);
941 return EncoderSession_finish_error(&encoder_session);
945 lookahead += skip_bytes;
946 lookahead_length -= skip_bytes;
950 if(!EncoderSession_init_encoder(&encoder_session, options.common, options.channels, options.bps, options.sample_rate))
951 return EncoderSession_finish_error(&encoder_session);
954 * first do any samples in the reservoir
956 if(options.common.sector_align && *options.common.align_reservoir_samples > 0) {
957 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)options.common.align_reservoir, *options.common.align_reservoir_samples)) {
958 print_error_with_state(&encoder_session, "ERROR during encoding");
959 return EncoderSession_finish_error(&encoder_session);
964 * decrement infilesize if we need to align the file
966 if(options.common.sector_align) {
967 FLAC__ASSERT(infilesize >= 0);
968 if(options.common.is_last_file) {
969 *options.common.align_reservoir_samples = 0;
972 *options.common.align_reservoir_samples = align_remainder;
973 infilesize -= (long)((*options.common.align_reservoir_samples) * bytes_per_wide_sample);
974 FLAC__ASSERT(infilesize >= 0);
979 * now do from the file
982 while(!feof(infile)) {
983 if(lookahead_length > 0) {
984 FLAC__ASSERT(lookahead_length < CHUNK_OF_SAMPLES * bytes_per_wide_sample);
985 memcpy(ucbuffer_, lookahead, lookahead_length);
986 bytes_read = fread(ucbuffer_+lookahead_length, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample - lookahead_length, infile) + lookahead_length;
988 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
989 return EncoderSession_finish_error(&encoder_session);
991 lookahead_length = 0;
994 bytes_read = fread(ucbuffer_, sizeof(unsigned char), CHUNK_OF_SAMPLES * bytes_per_wide_sample, infile);
996 if(bytes_read == 0) {
998 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
999 return EncoderSession_finish_error(&encoder_session);
1002 else if(bytes_read % bytes_per_wide_sample != 0) {
1003 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
1004 return EncoderSession_finish_error(&encoder_session);
1007 unsigned wide_samples = bytes_read / bytes_per_wide_sample;
1008 format_input(input_, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);
1010 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1011 print_error_with_state(&encoder_session, "ERROR during encoding");
1012 return EncoderSession_finish_error(&encoder_session);
1018 const FLAC__uint64 max_input_bytes = encoder_session.total_samples_to_encode * bytes_per_wide_sample;
1019 FLAC__uint64 total_input_bytes_read = 0;
1020 while(total_input_bytes_read < max_input_bytes) {
1022 size_t wanted = (CHUNK_OF_SAMPLES * bytes_per_wide_sample);
1023 wanted = min(wanted, (size_t)(max_input_bytes - total_input_bytes_read));
1025 if(lookahead_length > 0) {
1026 FLAC__ASSERT(lookahead_length <= wanted);
1027 memcpy(ucbuffer_, lookahead, lookahead_length);
1028 wanted -= lookahead_length;
1029 bytes_read = lookahead_length;
1031 bytes_read += fread(ucbuffer_+lookahead_length, sizeof(unsigned char), wanted, infile);
1032 if(ferror(infile)) {
1033 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1034 return EncoderSession_finish_error(&encoder_session);
1037 lookahead_length = 0;
1040 bytes_read = fread(ucbuffer_, sizeof(unsigned char), wanted, infile);
1043 if(bytes_read == 0) {
1044 if(ferror(infile)) {
1045 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1046 return EncoderSession_finish_error(&encoder_session);
1048 else if(feof(infile)) {
1049 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);
1050 total_input_bytes_read = max_input_bytes;
1054 if(bytes_read % bytes_per_wide_sample != 0) {
1055 flac__utils_printf(stderr, 1, "%s: ERROR: got partial sample\n", encoder_session.inbasefilename);
1056 return EncoderSession_finish_error(&encoder_session);
1059 unsigned wide_samples = bytes_read / bytes_per_wide_sample;
1060 format_input(input_, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps);
1062 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1063 print_error_with_state(&encoder_session, "ERROR during encoding");
1064 return EncoderSession_finish_error(&encoder_session);
1066 total_input_bytes_read += bytes_read;
1073 * now read unaligned samples into reservoir or pad with zeroes if necessary
1075 if(options.common.sector_align) {
1076 if(options.common.is_last_file) {
1077 unsigned wide_samples = 588 - align_remainder;
1078 if(wide_samples < 588) {
1079 unsigned channel, data_bytes;
1081 info_align_zero = wide_samples;
1082 data_bytes = wide_samples * (options.bps >> 3);
1083 for(channel = 0; channel < options.channels; channel++)
1084 memset(input_[channel], 0, data_bytes);
1086 if(!EncoderSession_process(&encoder_session, (const FLAC__int32 * const *)input_, wide_samples)) {
1087 print_error_with_state(&encoder_session, "ERROR during encoding");
1088 return EncoderSession_finish_error(&encoder_session);
1093 if(*options.common.align_reservoir_samples > 0) {
1094 FLAC__ASSERT(CHUNK_OF_SAMPLES >= 588);
1095 bytes_read = fread(ucbuffer_, sizeof(unsigned char), (*options.common.align_reservoir_samples) * bytes_per_wide_sample, infile);
1096 if(bytes_read == 0 && ferror(infile)) {
1097 flac__utils_printf(stderr, 1, "%s: ERROR during read\n", encoder_session.inbasefilename);
1098 return EncoderSession_finish_error(&encoder_session);
1100 else if(bytes_read != (*options.common.align_reservoir_samples) * bytes_per_wide_sample) {
1101 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);
1104 info_align_carry = *options.common.align_reservoir_samples;
1105 format_input(options.common.align_reservoir, *options.common.align_reservoir_samples, false, options.is_unsigned_samples, options.channels, options.bps);
1111 return EncoderSession_finish_ok(&encoder_session, info_align_carry, info_align_zero);
1114 FLAC__bool EncoderSession_construct(EncoderSession *e, FLAC__bool use_ogg, FLAC__bool verify, FILE *infile, const char *infilename, const char *outfilename)
1117 FLAC__uint32 test = 1;
1120 * initialize globals
1123 is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;
1125 for(i = 0; i < FLAC__MAX_CHANNELS; i++)
1126 input_[i] = &(in_[i][0]);
1130 * initialize instance
1133 #ifdef FLAC__HAS_OGG
1134 e->use_ogg = use_ogg;
1140 e->is_stdout = (0 == strcmp(outfilename, "-"));
1142 e->inbasefilename = grabbag__file_get_basename(infilename);
1143 e->outfilename = outfilename;
1145 e->skip = 0; /* filled in later after the sample_rate is known */
1146 e->unencoded_size = 0;
1147 e->total_samples_to_encode = 0;
1148 e->bytes_written = 0;
1149 e->samples_written = 0;
1153 e->encoder.flac.stream = 0;
1154 e->encoder.flac.file = 0;
1155 #ifdef FLAC__HAS_OGG
1156 e->encoder.ogg.stream = 0;
1157 e->encoder.ogg.file = 0;
1162 e->seek_table_template = 0;
1165 e->fout = grabbag__file_get_binary_stdout();
1168 if(0 == (e->seek_table_template = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE))) {
1169 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1173 #ifdef FLAC__HAS_OGG
1176 e->encoder.ogg.stream = OggFLAC__stream_encoder_new();
1177 if(0 == e->encoder.ogg.stream) {
1178 flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1179 EncoderSession_destroy(e);
1184 e->encoder.ogg.file = OggFLAC__file_encoder_new();
1185 if(0 == e->encoder.ogg.file) {
1186 flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1187 EncoderSession_destroy(e);
1195 e->encoder.flac.stream = FLAC__stream_encoder_new();
1196 if(0 == e->encoder.flac.stream) {
1197 flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1198 EncoderSession_destroy(e);
1203 e->encoder.flac.file = FLAC__file_encoder_new();
1204 if(0 == e->encoder.flac.file) {
1205 flac__utils_printf(stderr, 1, "%s: ERROR creating the encoder instance\n", e->inbasefilename);
1206 EncoderSession_destroy(e);
1214 void EncoderSession_destroy(EncoderSession *e)
1218 if(0 != e->fout && e->fout != stdout)
1221 #ifdef FLAC__HAS_OGG
1224 if(0 != e->encoder.ogg.stream) {
1225 OggFLAC__stream_encoder_delete(e->encoder.ogg.stream);
1226 e->encoder.ogg.stream = 0;
1230 if(0 != e->encoder.ogg.file) {
1231 OggFLAC__file_encoder_delete(e->encoder.ogg.file);
1232 e->encoder.ogg.file = 0;
1239 if(0 != e->encoder.flac.stream) {
1240 FLAC__stream_encoder_delete(e->encoder.flac.stream);
1241 e->encoder.flac.stream = 0;
1245 if(0 != e->encoder.flac.file) {
1246 FLAC__file_encoder_delete(e->encoder.flac.file);
1247 e->encoder.flac.file = 0;
1251 if(0 != e->seek_table_template) {
1252 FLAC__metadata_object_delete(e->seek_table_template);
1253 e->seek_table_template = 0;
1257 int EncoderSession_finish_ok(EncoderSession *e, int info_align_carry, int info_align_zero)
1259 FLAC__StreamEncoderState fse_state = FLAC__STREAM_ENCODER_OK;
1262 #ifdef FLAC__HAS_OGG
1265 if(e->encoder.ogg.stream) {
1266 fse_state = OggFLAC__stream_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg.stream);
1267 OggFLAC__stream_encoder_finish(e->encoder.ogg.stream);
1271 if(e->encoder.ogg.file) {
1272 fse_state = OggFLAC__file_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg.file);
1273 OggFLAC__file_encoder_finish(e->encoder.ogg.file);
1280 if(e->encoder.flac.stream) {
1281 fse_state = FLAC__stream_encoder_get_state(e->encoder.flac.stream);
1282 FLAC__stream_encoder_finish(e->encoder.flac.stream);
1286 if(e->encoder.flac.file) {
1287 fse_state = FLAC__file_encoder_get_stream_encoder_state(e->encoder.flac.file);
1288 FLAC__file_encoder_finish(e->encoder.flac.file);
1292 if(e->total_samples_to_encode > 0) {
1294 flac__utils_printf(stderr, 2, "\n");
1297 if(fse_state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA) {
1298 print_verify_error(e);
1302 if(info_align_carry >= 0) {
1303 flac__utils_printf(stderr, 1, "%s: INFO: sector alignment causing %d samples to be carried over\n", e->inbasefilename, info_align_carry);
1305 if(info_align_zero >= 0) {
1306 flac__utils_printf(stderr, 1, "%s: INFO: sector alignment causing %d zero samples to be appended\n", e->inbasefilename, info_align_zero);
1310 EncoderSession_destroy(e);
1315 int EncoderSession_finish_error(EncoderSession *e)
1317 FLAC__StreamEncoderState fse_state;
1319 if(e->total_samples_to_encode > 0)
1320 flac__utils_printf(stderr, 2, "\n");
1322 #ifdef FLAC__HAS_OGG
1325 fse_state = OggFLAC__stream_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg.stream);
1328 fse_state = OggFLAC__file_encoder_get_FLAC_stream_encoder_state(e->encoder.ogg.file);
1334 fse_state = FLAC__stream_encoder_get_state(e->encoder.flac.stream);
1337 fse_state = FLAC__file_encoder_get_stream_encoder_state(e->encoder.flac.file);
1340 if(fse_state == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA)
1341 print_verify_error(e);
1343 unlink(e->outfilename);
1345 EncoderSession_destroy(e);
1350 FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t options, unsigned channels, unsigned bps, unsigned sample_rate)
1352 unsigned num_metadata;
1353 FLAC__StreamMetadata padding, *cuesheet = 0;
1354 FLAC__StreamMetadata *metadata[4];
1355 const FLAC__bool is_cdda = (channels == 1 || channels == 2) && (bps == 16) && (sample_rate == 44100);
1357 e->replay_gain = options.replay_gain;
1358 e->channels = channels;
1359 e->bits_per_sample = bps;
1360 e->sample_rate = sample_rate;
1362 if(e->replay_gain) {
1363 if(channels != 1 && channels != 2) {
1364 flac__utils_printf(stderr, 1, "%s: ERROR, number of channels (%u) must be 1 or 2 for --replay-gain\n", e->inbasefilename, channels);
1367 if(!grabbag__replaygain_is_valid_sample_frequency(sample_rate)) {
1368 flac__utils_printf(stderr, 1, "%s: ERROR, invalid sample rate (%u) for --replay-gain\n", e->inbasefilename, sample_rate);
1371 if(options.is_first_file) {
1372 if(!grabbag__replaygain_init(sample_rate)) {
1373 flac__utils_printf(stderr, 1, "%s: ERROR initializing ReplayGain stage\n", e->inbasefilename);
1380 options.do_mid_side = options.loose_mid_side = false;
1382 if(!parse_cuesheet_(&cuesheet, options.cuesheet_filename, e->inbasefilename, is_cdda, e->total_samples_to_encode))
1385 if(!convert_to_seek_table_template(options.requested_seek_points, options.num_requested_seek_points, options.cued_seekpoints? cuesheet : 0, e)) {
1386 flac__utils_printf(stderr, 1, "%s: ERROR allocating memory for seek table\n", e->inbasefilename);
1388 FLAC__metadata_object_delete(cuesheet);
1393 if(e->seek_table_template->data.seek_table.num_points > 0) {
1394 e->seek_table_template->is_last = false; /* the encoder will set this for us */
1395 metadata[num_metadata++] = e->seek_table_template;
1398 metadata[num_metadata++] = cuesheet;
1399 metadata[num_metadata++] = options.vorbis_comment;
1400 if(options.padding > 0) {
1401 padding.is_last = false; /* the encoder will set this for us */
1402 padding.type = FLAC__METADATA_TYPE_PADDING;
1403 padding.length = (unsigned)options.padding;
1404 metadata[num_metadata++] = &padding;
1407 e->blocksize = options.blocksize;
1408 e->stats_mask = (options.do_exhaustive_model_search || options.do_qlp_coeff_prec_search)? 0x0f : 0x3f;
1410 #ifdef FLAC__HAS_OGG
1413 OggFLAC__stream_encoder_set_serial_number(e->encoder.ogg.stream, options.serial_number);
1414 OggFLAC__stream_encoder_set_verify(e->encoder.ogg.stream, options.verify);
1415 OggFLAC__stream_encoder_set_streamable_subset(e->encoder.ogg.stream, !options.lax);
1416 OggFLAC__stream_encoder_set_do_mid_side_stereo(e->encoder.ogg.stream, options.do_mid_side);
1417 OggFLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder.ogg.stream, options.loose_mid_side);
1418 OggFLAC__stream_encoder_set_channels(e->encoder.ogg.stream, channels);
1419 OggFLAC__stream_encoder_set_bits_per_sample(e->encoder.ogg.stream, bps);
1420 OggFLAC__stream_encoder_set_sample_rate(e->encoder.ogg.stream, sample_rate);
1421 OggFLAC__stream_encoder_set_blocksize(e->encoder.ogg.stream, options.blocksize);
1422 OggFLAC__stream_encoder_set_max_lpc_order(e->encoder.ogg.stream, options.max_lpc_order);
1423 OggFLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.ogg.stream, options.qlp_coeff_precision);
1424 OggFLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.ogg.stream, options.do_qlp_coeff_prec_search);
1425 OggFLAC__stream_encoder_set_do_escape_coding(e->encoder.ogg.stream, options.do_escape_coding);
1426 OggFLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder.ogg.stream, options.do_exhaustive_model_search);
1427 OggFLAC__stream_encoder_set_min_residual_partition_order(e->encoder.ogg.stream, options.min_residual_partition_order);
1428 OggFLAC__stream_encoder_set_max_residual_partition_order(e->encoder.ogg.stream, options.max_residual_partition_order);
1429 OggFLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder.ogg.stream, options.rice_parameter_search_dist);
1430 OggFLAC__stream_encoder_set_total_samples_estimate(e->encoder.ogg.stream, e->total_samples_to_encode);
1431 OggFLAC__stream_encoder_set_metadata(e->encoder.ogg.stream, (num_metadata > 0)? metadata : 0, num_metadata);
1432 OggFLAC__stream_encoder_set_write_callback(e->encoder.ogg.stream, ogg_stream_encoder_write_callback);
1433 OggFLAC__stream_encoder_set_metadata_callback(e->encoder.ogg.stream, ogg_stream_encoder_metadata_callback);
1434 OggFLAC__stream_encoder_set_client_data(e->encoder.ogg.stream, e);
1436 OggFLAC__stream_encoder_disable_constant_subframes(e->encoder.ogg.stream, options.debug.disable_constant_subframes);
1437 OggFLAC__stream_encoder_disable_fixed_subframes(e->encoder.ogg.stream, options.debug.disable_fixed_subframes);
1438 OggFLAC__stream_encoder_disable_verbatim_subframes(e->encoder.ogg.stream, options.debug.disable_verbatim_subframes);
1440 if(OggFLAC__stream_encoder_init(e->encoder.ogg.stream) != FLAC__STREAM_ENCODER_OK) {
1441 print_error_with_state(e, "ERROR initializing encoder");
1443 FLAC__metadata_object_delete(cuesheet);
1448 OggFLAC__file_encoder_set_serial_number(e->encoder.ogg.file, options.serial_number);
1449 OggFLAC__file_encoder_set_filename(e->encoder.ogg.file, e->outfilename);
1450 OggFLAC__file_encoder_set_verify(e->encoder.ogg.file, options.verify);
1451 OggFLAC__file_encoder_set_streamable_subset(e->encoder.ogg.file, !options.lax);
1452 OggFLAC__file_encoder_set_do_mid_side_stereo(e->encoder.ogg.file, options.do_mid_side);
1453 OggFLAC__file_encoder_set_loose_mid_side_stereo(e->encoder.ogg.file, options.loose_mid_side);
1454 OggFLAC__file_encoder_set_channels(e->encoder.ogg.file, channels);
1455 OggFLAC__file_encoder_set_bits_per_sample(e->encoder.ogg.file, bps);
1456 OggFLAC__file_encoder_set_sample_rate(e->encoder.ogg.file, sample_rate);
1457 OggFLAC__file_encoder_set_blocksize(e->encoder.ogg.file, options.blocksize);
1458 OggFLAC__file_encoder_set_max_lpc_order(e->encoder.ogg.file, options.max_lpc_order);
1459 OggFLAC__file_encoder_set_qlp_coeff_precision(e->encoder.ogg.file, options.qlp_coeff_precision);
1460 OggFLAC__file_encoder_set_do_qlp_coeff_prec_search(e->encoder.ogg.file, options.do_qlp_coeff_prec_search);
1461 OggFLAC__file_encoder_set_do_escape_coding(e->encoder.ogg.file, options.do_escape_coding);
1462 OggFLAC__file_encoder_set_do_exhaustive_model_search(e->encoder.ogg.file, options.do_exhaustive_model_search);
1463 OggFLAC__file_encoder_set_min_residual_partition_order(e->encoder.ogg.file, options.min_residual_partition_order);
1464 OggFLAC__file_encoder_set_max_residual_partition_order(e->encoder.ogg.file, options.max_residual_partition_order);
1465 OggFLAC__file_encoder_set_rice_parameter_search_dist(e->encoder.ogg.file, options.rice_parameter_search_dist);
1466 OggFLAC__file_encoder_set_total_samples_estimate(e->encoder.ogg.file, e->total_samples_to_encode);
1467 OggFLAC__file_encoder_set_metadata(e->encoder.ogg.file, (num_metadata > 0)? metadata : 0, num_metadata);
1468 OggFLAC__file_encoder_set_progress_callback(e->encoder.ogg.file, ogg_file_encoder_progress_callback);
1469 OggFLAC__file_encoder_set_client_data(e->encoder.ogg.file, e);
1471 OggFLAC__file_encoder_disable_constant_subframes(e->encoder.ogg.file, options.debug.disable_constant_subframes);
1472 OggFLAC__file_encoder_disable_fixed_subframes(e->encoder.ogg.file, options.debug.disable_fixed_subframes);
1473 OggFLAC__file_encoder_disable_verbatim_subframes(e->encoder.ogg.file, options.debug.disable_verbatim_subframes);
1475 if(OggFLAC__file_encoder_init(e->encoder.ogg.file) != OggFLAC__FILE_ENCODER_OK) {
1476 print_error_with_state(e, "ERROR initializing encoder");
1478 FLAC__metadata_object_delete(cuesheet);
1486 FLAC__stream_encoder_set_verify(e->encoder.flac.stream, options.verify);
1487 FLAC__stream_encoder_set_streamable_subset(e->encoder.flac.stream, !options.lax);
1488 FLAC__stream_encoder_set_do_mid_side_stereo(e->encoder.flac.stream, options.do_mid_side);
1489 FLAC__stream_encoder_set_loose_mid_side_stereo(e->encoder.flac.stream, options.loose_mid_side);
1490 FLAC__stream_encoder_set_channels(e->encoder.flac.stream, channels);
1491 FLAC__stream_encoder_set_bits_per_sample(e->encoder.flac.stream, bps);
1492 FLAC__stream_encoder_set_sample_rate(e->encoder.flac.stream, sample_rate);
1493 FLAC__stream_encoder_set_blocksize(e->encoder.flac.stream, options.blocksize);
1494 FLAC__stream_encoder_set_max_lpc_order(e->encoder.flac.stream, options.max_lpc_order);
1495 FLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.flac.stream, options.qlp_coeff_precision);
1496 FLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.flac.stream, options.do_qlp_coeff_prec_search);
1497 FLAC__stream_encoder_set_do_escape_coding(e->encoder.flac.stream, options.do_escape_coding);
1498 FLAC__stream_encoder_set_do_exhaustive_model_search(e->encoder.flac.stream, options.do_exhaustive_model_search);
1499 FLAC__stream_encoder_set_min_residual_partition_order(e->encoder.flac.stream, options.min_residual_partition_order);
1500 FLAC__stream_encoder_set_max_residual_partition_order(e->encoder.flac.stream, options.max_residual_partition_order);
1501 FLAC__stream_encoder_set_rice_parameter_search_dist(e->encoder.flac.stream, options.rice_parameter_search_dist);
1502 FLAC__stream_encoder_set_total_samples_estimate(e->encoder.flac.stream, e->total_samples_to_encode);
1503 FLAC__stream_encoder_set_metadata(e->encoder.flac.stream, (num_metadata > 0)? metadata : 0, num_metadata);
1504 FLAC__stream_encoder_set_write_callback(e->encoder.flac.stream, flac_stream_encoder_write_callback);
1505 FLAC__stream_encoder_set_metadata_callback(e->encoder.flac.stream, flac_stream_encoder_metadata_callback);
1506 FLAC__stream_encoder_set_client_data(e->encoder.flac.stream, e);
1508 FLAC__stream_encoder_disable_constant_subframes(e->encoder.flac.stream, options.debug.disable_constant_subframes);
1509 FLAC__stream_encoder_disable_fixed_subframes(e->encoder.flac.stream, options.debug.disable_fixed_subframes);
1510 FLAC__stream_encoder_disable_verbatim_subframes(e->encoder.flac.stream, options.debug.disable_verbatim_subframes);
1512 if(FLAC__stream_encoder_init(e->encoder.flac.stream) != FLAC__STREAM_ENCODER_OK) {
1513 print_error_with_state(e, "ERROR initializing encoder");
1515 FLAC__metadata_object_delete(cuesheet);
1520 FLAC__file_encoder_set_filename(e->encoder.flac.file, e->outfilename);
1521 FLAC__file_encoder_set_verify(e->encoder.flac.file, options.verify);
1522 FLAC__file_encoder_set_streamable_subset(e->encoder.flac.file, !options.lax);
1523 FLAC__file_encoder_set_do_mid_side_stereo(e->encoder.flac.file, options.do_mid_side);
1524 FLAC__file_encoder_set_loose_mid_side_stereo(e->encoder.flac.file, options.loose_mid_side);
1525 FLAC__file_encoder_set_channels(e->encoder.flac.file, channels);
1526 FLAC__file_encoder_set_bits_per_sample(e->encoder.flac.file, bps);
1527 FLAC__file_encoder_set_sample_rate(e->encoder.flac.file, sample_rate);
1528 FLAC__file_encoder_set_blocksize(e->encoder.flac.file, options.blocksize);
1529 FLAC__file_encoder_set_max_lpc_order(e->encoder.flac.file, options.max_lpc_order);
1530 FLAC__file_encoder_set_qlp_coeff_precision(e->encoder.flac.file, options.qlp_coeff_precision);
1531 FLAC__file_encoder_set_do_qlp_coeff_prec_search(e->encoder.flac.file, options.do_qlp_coeff_prec_search);
1532 FLAC__file_encoder_set_do_escape_coding(e->encoder.flac.file, options.do_escape_coding);
1533 FLAC__file_encoder_set_do_exhaustive_model_search(e->encoder.flac.file, options.do_exhaustive_model_search);
1534 FLAC__file_encoder_set_min_residual_partition_order(e->encoder.flac.file, options.min_residual_partition_order);
1535 FLAC__file_encoder_set_max_residual_partition_order(e->encoder.flac.file, options.max_residual_partition_order);
1536 FLAC__file_encoder_set_rice_parameter_search_dist(e->encoder.flac.file, options.rice_parameter_search_dist);
1537 FLAC__file_encoder_set_total_samples_estimate(e->encoder.flac.file, e->total_samples_to_encode);
1538 FLAC__file_encoder_set_metadata(e->encoder.flac.file, (num_metadata > 0)? metadata : 0, num_metadata);
1539 FLAC__file_encoder_set_progress_callback(e->encoder.flac.file, flac_file_encoder_progress_callback);
1540 FLAC__file_encoder_set_client_data(e->encoder.flac.file, e);
1542 FLAC__file_encoder_disable_constant_subframes(e->encoder.flac.file, options.debug.disable_constant_subframes);
1543 FLAC__file_encoder_disable_fixed_subframes(e->encoder.flac.file, options.debug.disable_fixed_subframes);
1544 FLAC__file_encoder_disable_verbatim_subframes(e->encoder.flac.file, options.debug.disable_verbatim_subframes);
1546 if(FLAC__file_encoder_init(e->encoder.flac.file) != FLAC__FILE_ENCODER_OK) {
1547 print_error_with_state(e, "ERROR initializing encoder");
1549 FLAC__metadata_object_delete(cuesheet);
1555 FLAC__metadata_object_delete(cuesheet);
1560 FLAC__bool EncoderSession_process(EncoderSession *e, const FLAC__int32 * const buffer[], unsigned samples)
1562 if(e->replay_gain) {
1563 if(!grabbag__replaygain_analyze(buffer, e->channels==2, e->bits_per_sample, samples)) {
1564 flac__utils_printf(stderr, 1, "%s: WARNING, error while calculating ReplayGain\n", e->inbasefilename);
1568 #ifdef FLAC__HAS_OGG
1571 return OggFLAC__stream_encoder_process(e->encoder.ogg.stream, buffer, samples);
1574 return OggFLAC__file_encoder_process(e->encoder.ogg.file, buffer, samples);
1580 return FLAC__stream_encoder_process(e->encoder.flac.stream, buffer, samples);
1583 return FLAC__file_encoder_process(e->encoder.flac.file, buffer, samples);
1587 FLAC__bool convert_to_seek_table_template(const char *requested_seek_points, int num_requested_seek_points, FLAC__StreamMetadata *cuesheet, EncoderSession *e)
1589 const FLAC__bool only_placeholders = e->is_stdout;
1590 FLAC__bool has_real_points;
1592 if(num_requested_seek_points == 0 && 0 == cuesheet)
1595 if(num_requested_seek_points < 0) {
1596 requested_seek_points = "10s;";
1597 num_requested_seek_points = 1;
1600 if(num_requested_seek_points > 0) {
1601 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))
1607 const FLAC__StreamMetadata_CueSheet *cs = &cuesheet->data.cue_sheet;
1608 for(i = 0; i < cs->num_tracks; i++) {
1609 const FLAC__StreamMetadata_CueSheet_Track *tr = cs->tracks+i;
1610 for(j = 0; j < tr->num_indices; j++) {
1611 if(!FLAC__metadata_object_seektable_template_append_point(e->seek_table_template, tr->offset + tr->indices[j].offset))
1613 has_real_points = true;
1617 if(!FLAC__metadata_object_seektable_template_sort(e->seek_table_template, /*compact=*/true))
1621 if(has_real_points) {
1623 flac__utils_printf(stderr, 1, "%s: WARNING, cannot write back seekpoints when encoding to stdout\n", e->inbasefilename);
1630 FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input)
1632 /* convert from mm:ss.sss to sample number if necessary */
1633 flac__utils_canonicalize_skip_until_specification(spec, sample_rate);
1635 /* special case: if "--until=-0", use the special value '0' to mean "end-of-stream" */
1636 if(spec->is_relative && spec->value.samples == 0) {
1637 spec->is_relative = false;
1641 /* in any other case the total samples in the input must be known */
1642 if(total_samples_in_input == 0) {
1643 flac__utils_printf(stderr, 1, "%s: ERROR, cannot use --until when input length is unknown\n", inbasefilename);
1647 FLAC__ASSERT(spec->value_is_samples);
1649 /* convert relative specifications to absolute */
1650 if(spec->is_relative) {
1651 if(spec->value.samples <= 0)
1652 spec->value.samples += (FLAC__int64)total_samples_in_input;
1654 spec->value.samples += skip;
1655 spec->is_relative = false;
1659 if(spec->value.samples < 0) {
1660 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before beginning of input\n", inbasefilename);
1663 if((FLAC__uint64)spec->value.samples <= skip) {
1664 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before --skip point\n", inbasefilename);
1667 if((FLAC__uint64)spec->value.samples > total_samples_in_input) {
1668 flac__utils_printf(stderr, 1, "%s: ERROR, --until value is after end of input\n", inbasefilename);
1675 void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps)
1677 unsigned wide_sample, sample, channel, byte;
1680 if(is_unsigned_samples) {
1681 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1682 for(channel = 0; channel < channels; channel++, sample++)
1683 dest[channel][wide_sample] = (FLAC__int32)ucbuffer_[sample] - 0x80;
1686 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1687 for(channel = 0; channel < channels; channel++, sample++)
1688 dest[channel][wide_sample] = (FLAC__int32)scbuffer_[sample];
1691 else if(bps == 16) {
1692 if(is_big_endian != is_big_endian_host_) {
1694 const unsigned bytes = wide_samples * channels * (bps >> 3);
1695 for(byte = 0; byte < bytes; byte += 2) {
1696 tmp = ucbuffer_[byte];
1697 ucbuffer_[byte] = ucbuffer_[byte+1];
1698 ucbuffer_[byte+1] = tmp;
1701 if(is_unsigned_samples) {
1702 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1703 for(channel = 0; channel < channels; channel++, sample++)
1704 dest[channel][wide_sample] = (FLAC__int32)usbuffer_[sample] - 0x8000;
1707 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1708 for(channel = 0; channel < channels; channel++, sample++)
1709 dest[channel][wide_sample] = (FLAC__int32)ssbuffer_[sample];
1712 else if(bps == 24) {
1713 if(!is_big_endian) {
1715 const unsigned bytes = wide_samples * channels * (bps >> 3);
1716 for(byte = 0; byte < bytes; byte += 3) {
1717 tmp = ucbuffer_[byte];
1718 ucbuffer_[byte] = ucbuffer_[byte+2];
1719 ucbuffer_[byte+2] = tmp;
1722 if(is_unsigned_samples) {
1723 for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1724 for(channel = 0; channel < channels; channel++, sample++) {
1725 dest[channel][wide_sample] = ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1726 dest[channel][wide_sample] |= ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1727 dest[channel][wide_sample] |= ucbuffer_[byte++];
1728 dest[channel][wide_sample] -= 0x800000;
1732 for(byte = sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
1733 for(channel = 0; channel < channels; channel++, sample++) {
1734 dest[channel][wide_sample] = scbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1735 dest[channel][wide_sample] |= ucbuffer_[byte++]; dest[channel][wide_sample] <<= 8;
1736 dest[channel][wide_sample] |= ucbuffer_[byte++];
1745 #ifdef FLAC__HAS_OGG
1746 FLAC__StreamEncoderWriteStatus ogg_stream_encoder_write_callback(const OggFLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
1748 EncoderSession *encoder_session = (EncoderSession*)client_data;
1752 encoder_session->bytes_written += bytes;
1754 * With Ogg FLAC we don't get one write callback per frame and
1755 * we don't have a good number for 'samples', so we estimate based
1756 * on the frame number and the knowledge that all blocks (except
1757 * the last) are the same size.
1760 encoder_session->samples_written = (current_frame+1) * encoder_session->blocksize;
1762 if(encoder_session->total_samples_to_encode > 0 && !(current_frame & encoder_session->stats_mask))
1763 print_stats(encoder_session);
1765 if(flac__utils_fwrite(buffer, sizeof(FLAC__byte), bytes, encoder_session->fout) == bytes)
1766 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
1768 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
1771 void ogg_stream_encoder_metadata_callback(const OggFLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
1773 // do nothing, for compatibilty. soon we will be using the ogg file encoder anyway.
1774 (void)encoder, (void)metadata, (void)client_data;
1777 void ogg_file_encoder_progress_callback(const OggFLAC__FileEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data)
1779 EncoderSession *encoder_session = (EncoderSession*)client_data;
1784 * With Ogg FLAC we don't get a value for 'samples_written', so we
1785 * estimate based on the frames written and the knowledge that all
1786 * blocks (except the last) are the same size.
1788 samples_written = frames_written * encoder_session->blocksize;
1789 flac_file_encoder_progress_callback(0, bytes_written, samples_written, frames_written, total_frames_estimate, client_data);
1794 FLAC__StreamEncoderWriteStatus flac_stream_encoder_write_callback(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
1796 EncoderSession *encoder_session = (EncoderSession*)client_data;
1800 encoder_session->bytes_written += bytes;
1801 encoder_session->samples_written += samples;
1803 if(samples && encoder_session->total_samples_to_encode > 0 && !(current_frame & encoder_session->stats_mask))
1804 print_stats(encoder_session);
1806 if(flac__utils_fwrite(buffer, sizeof(FLAC__byte), bytes, encoder_session->fout) == bytes)
1807 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
1809 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
1812 void flac_stream_encoder_metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
1815 * Nothing to do; if we get here, we're decoding to stdout, in
1816 * which case we can't seek backwards to write new metadata.
1818 (void)encoder, (void)metadata, (void)client_data;
1821 void flac_file_encoder_progress_callback(const FLAC__FileEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data)
1823 EncoderSession *encoder_session = (EncoderSession*)client_data;
1825 (void)encoder, (void)total_frames_estimate;
1827 encoder_session->bytes_written = bytes_written;
1828 encoder_session->samples_written = samples_written;
1830 if(encoder_session->total_samples_to_encode > 0 && !((frames_written-1) & encoder_session->stats_mask))
1831 print_stats(encoder_session);
1834 FLAC__bool parse_cuesheet_(FLAC__StreamMetadata **cuesheet, const char *cuesheet_filename, const char *inbasefilename, FLAC__bool is_cdda, FLAC__uint64 lead_out_offset)
1837 unsigned last_line_read;
1838 const char *error_message;
1840 if(0 == cuesheet_filename)
1843 if(lead_out_offset == 0) {
1844 flac__utils_printf(stderr, 1, "%s: ERROR cannot import cuesheet when the number of input samples to encode is unknown\n", inbasefilename);
1848 if(0 == (f = fopen(cuesheet_filename, "r"))) {
1849 flac__utils_printf(stderr, 1, "%s: ERROR opening cuesheet \"%s\" for reading\n", inbasefilename, cuesheet_filename);
1853 *cuesheet = grabbag__cuesheet_parse(f, &error_message, &last_line_read, is_cdda, lead_out_offset);
1857 if(0 == *cuesheet) {
1858 flac__utils_printf(stderr, 1, "%s: ERROR parsing cuesheet \"%s\" on line %u: %s\n", inbasefilename, cuesheet_filename, last_line_read, error_message);
1865 void print_stats(const EncoderSession *encoder_session)
1867 const FLAC__uint64 samples_written = min(encoder_session->total_samples_to_encode, encoder_session->samples_written);
1868 #if defined _MSC_VER || defined __MINGW32__
1869 /* with MSVC you have to spoon feed it the casting */
1870 const double progress = (double)(FLAC__int64)samples_written / (double)(FLAC__int64)encoder_session->total_samples_to_encode;
1871 const double ratio = (double)(FLAC__int64)encoder_session->bytes_written / ((double)(FLAC__int64)encoder_session->unencoded_size * min(1.0, progress));
1873 const double progress = (double)samples_written / (double)encoder_session->total_samples_to_encode;
1874 const double ratio = (double)encoder_session->bytes_written / ((double)encoder_session->unencoded_size * min(1.0, progress));
1878 if(samples_written == encoder_session->total_samples_to_encode) {
1879 flac__utils_printf(stderr, 2, "\r%s:%s wrote %u bytes, ratio=%0.3f",
1880 encoder_session->inbasefilename,
1881 encoder_session->verify? " Verify OK," : "",
1882 (unsigned)encoder_session->bytes_written,
1887 flac__utils_printf(stderr, 2, "\r%s: %u%% complete, ratio=%0.3f", encoder_session->inbasefilename, (unsigned)floor(progress * 100.0 + 0.5), ratio);
1891 void print_error_with_state(const EncoderSession *e, const char *message)
1893 const int ilen = strlen(e->inbasefilename) + 1;
1894 const char *state_string;
1896 flac__utils_printf(stderr, 1, "\n%s: %s\n", e->inbasefilename, message);
1898 #ifdef FLAC__HAS_OGG
1901 state_string = OggFLAC__stream_encoder_get_resolved_state_string(e->encoder.ogg.stream);
1904 state_string = OggFLAC__file_encoder_get_resolved_state_string(e->encoder.ogg.file);
1910 state_string = FLAC__stream_encoder_get_resolved_state_string(e->encoder.flac.stream);
1913 state_string = FLAC__file_encoder_get_resolved_state_string(e->encoder.flac.file);
1916 flac__utils_printf(stderr, 1, "%*s state = %s\n", ilen, "", state_string);
1918 /* print out some more info for some errors: */
1919 if(0 == strcmp(state_string, FLAC__StreamEncoderStateString[FLAC__STREAM_ENCODER_NOT_STREAMABLE])) {
1920 flac__utils_printf(stderr, 1,
1922 "The encoding parameters specified do not conform to the FLAC Subset and may not\n"
1923 "be streamable or playable in hardware devices. Add --lax to the command-line\n"
1924 "options to encode with these parameters.\n"
1928 0 == strcmp(state_string, FLAC__FileEncoderStateString[FLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING])
1929 #ifdef FLAC__HAS_OGG
1930 || 0 == strcmp(state_string, OggFLAC__FileEncoderStateString[OggFLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING])
1933 flac__utils_printf(stderr, 1,
1935 "An error occurred while writing; the most common cause is that the disk is full.\n"
1939 0 == strcmp(state_string, FLAC__FileEncoderStateString[FLAC__FILE_ENCODER_ERROR_OPENING_FILE])
1940 #ifdef FLAC__HAS_OGG
1941 || 0 == strcmp(state_string, OggFLAC__FileEncoderStateString[OggFLAC__FILE_ENCODER_ERROR_OPENING_FILE])
1944 flac__utils_printf(stderr, 1,
1946 "An error occurred opening the output file; it is likely that the output\n"
1947 "directory does not exist or is not writable, the output file already exists and\n"
1948 "is not writable, or the disk is full.\n"
1953 void print_verify_error(EncoderSession *e)
1955 FLAC__uint64 absolute_sample;
1956 unsigned frame_number;
1959 FLAC__int32 expected;
1962 #ifdef FLAC__HAS_OGG
1965 OggFLAC__stream_encoder_get_verify_decoder_error_stats(e->encoder.ogg.stream, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
1968 OggFLAC__file_encoder_get_verify_decoder_error_stats(e->encoder.ogg.file, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
1974 FLAC__stream_encoder_get_verify_decoder_error_stats(e->encoder.flac.stream, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
1977 FLAC__file_encoder_get_verify_decoder_error_stats(e->encoder.flac.file, &absolute_sample, &frame_number, &channel, &sample, &expected, &got);
1980 flac__utils_printf(stderr, 1, "%s: ERROR: mismatch in decoded data, verify FAILED!\n", e->inbasefilename);
1981 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);
1982 flac__utils_printf(stderr, 1, " In all known cases, verify errors are caused by hardware problems,\n");
1983 flac__utils_printf(stderr, 1, " usually overclocking or bad RAM. Delete %s\n", e->inbasefilename);
1984 flac__utils_printf(stderr, 1, " and repeat the flac command exactly as before. If it does not give a\n");
1985 flac__utils_printf(stderr, 1, " verify error in the exact same place each time you try it, then there is\n");
1986 flac__utils_printf(stderr, 1, " a problem with your hardware. If it does, keep the bad FLAC file and\n");
1987 flac__utils_printf(stderr, 1, " submit a bug report to:\n");
1988 flac__utils_printf(stderr, 1, " http://sourceforge.net/bugs/?func=addbug&group_id=13478\n");
1989 flac__utils_printf(stderr, 1, " Make sure to include an email contact in the comment and/or use the\n");
1990 flac__utils_printf(stderr, 1, " \"Monitor\" feature to monitor the bug status.\n");
1991 flac__utils_printf(stderr, 1, "Verify FAILED! Do not trust %s\n", e->outfilename);
1994 FLAC__bool read_little_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
1996 size_t bytes_read = fread(val, 1, 2, f);
1998 if(bytes_read == 0) {
2000 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2006 else if(bytes_read < 2) {
2007 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2011 if(is_big_endian_host_) {
2012 FLAC__byte tmp, *b = (FLAC__byte*)val;
2013 tmp = b[1]; b[1] = b[0]; b[0] = tmp;
2019 FLAC__bool read_little_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2021 size_t bytes_read = fread(val, 1, 4, f);
2023 if(bytes_read == 0) {
2025 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2031 else if(bytes_read < 4) {
2032 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2036 if(is_big_endian_host_) {
2037 FLAC__byte tmp, *b = (FLAC__byte*)val;
2038 tmp = b[3]; b[3] = b[0]; b[0] = tmp;
2039 tmp = b[2]; b[2] = b[1]; b[1] = tmp;
2045 FLAC__bool read_big_endian_uint16(FILE *f, FLAC__uint16 *val, FLAC__bool eof_ok, const char *fn)
2047 unsigned char buf[4];
2048 size_t bytes_read= fread(buf, 1, 2, f);
2050 if(bytes_read==0U && eof_ok)
2052 else if(bytes_read<2U) {
2053 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2057 /* this is independent of host endianness */
2058 *val= (FLAC__uint16)(buf[0])<<8 | buf[1];
2063 FLAC__bool read_big_endian_uint32(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2065 unsigned char buf[4];
2066 size_t bytes_read= fread(buf, 1, 4, f);
2068 if(bytes_read==0U && eof_ok)
2070 else if(bytes_read<4U) {
2071 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2075 /* this is independent of host endianness */
2076 *val= (FLAC__uint32)(buf[0])<<24 | (FLAC__uint32)(buf[1])<<16 |
2077 (FLAC__uint32)(buf[2])<<8 | buf[3];
2082 FLAC__bool read_sane_extended(FILE *f, FLAC__uint32 *val, FLAC__bool eof_ok, const char *fn)
2083 /* Read an IEEE 754 80-bit (aka SANE) extended floating point value from 'f',
2084 * convert it into an integral value and store in 'val'. Return false if only
2085 * between 1 and 9 bytes remain in 'f', if 0 bytes remain in 'f' and 'eof_ok' is
2086 * false, or if the value is negative, between zero and one, or too large to be
2087 * represented by 'val'; return true otherwise.
2091 unsigned char buf[10];
2092 size_t bytes_read= fread(buf, 1U, 10U, f);
2093 FLAC__int16 e= ((FLAC__uint16)(buf[0])<<8 | (FLAC__uint16)(buf[1]))-0x3FFF;
2094 FLAC__int16 shift= 63-e;
2097 if(bytes_read==0U && eof_ok)
2099 else if(bytes_read<10U) {
2100 flac__utils_printf(stderr, 1, "%s: ERROR: unexpected EOF\n", fn);
2103 else if((buf[0]>>7)==1U || e<0 || e>63) {
2104 flac__utils_printf(stderr, 1, "%s: ERROR: invalid floating-point value\n", fn);
2108 for(i= 0U; i<8U; ++i)
2109 p|= (FLAC__uint64)(buf[i+2])<<(56U-i*8);
2110 *val= (FLAC__uint32)((p>>shift)+(p>>(shift-1) & 0x1));
2115 FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset)
2117 static unsigned char dump[8192];
2120 long need = (long)min(offset, LONG_MAX);
2121 if(fseek(f, need, SEEK_CUR) < 0) {
2122 need = (long)min(offset, sizeof(dump));
2123 if(fread(dump, need, 1, f) < 1)