1 /* flac - Command-line FLAC encoder/decoder
2 * Copyright (C) 2000,2001 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 <math.h> /* for floor() */
26 #include <stdio.h> /* for FILE et al. */
27 #include <string.h> /* for strcmp() */
33 const char *inbasefilename;
37 analysis_options aopts;
41 bool is_unsigned_samples;
48 bool skip_count_too_high;
49 uint64 samples_processed;
50 unsigned frame_counter;
53 static FLAC__FileDecoder *decoder;
54 static bool is_big_endian_host;
57 static bool init(const char *infilename, stream_info_struct *stream_info);
58 static bool write_little_endian_uint16(FILE *f, uint16 val);
59 static bool write_little_endian_uint32(FILE *f, uint32 val);
60 static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const int32 *buffer[], void *client_data);
61 static void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);
62 static void error_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
63 static void print_stats(const stream_info_struct *stream_info);
65 int flac__decode_wav(const char *infile, const char *outfile, bool analysis_mode, analysis_options aopts, bool verbose, uint64 skip)
67 bool md5_failure = false;
68 stream_info_struct stream_info;
71 stream_info.abort_flag = false;
72 stream_info.analysis_mode = analysis_mode;
73 stream_info.aopts = aopts;
74 stream_info.test_only = (outfile == 0);
75 stream_info.is_wave_out = true;
76 stream_info.verbose = verbose;
77 stream_info.skip = skip;
78 stream_info.skip_count_too_high = false;
79 stream_info.samples_processed = 0;
80 stream_info.frame_counter = 0;
81 stream_info.inbasefilename = flac__file_get_basename(infile);
82 stream_info.fout = 0; /* initialized with an open file later if necessary */
84 FLAC__ASSERT(!(stream_info.test_only && stream_info.analysis_mode));
86 if(!stream_info.test_only) {
87 if(0 == strcmp(outfile, "-")) {
88 stream_info.fout = stdout;
91 if(0 == (stream_info.fout = fopen(outfile, "wb"))) {
92 fprintf(stderr, "%s: ERROR: can't open output file %s\n", stream_info.inbasefilename, outfile);
99 flac__analyze_init(aopts);
101 if(!init(infile, &stream_info))
105 if(!FLAC__file_decoder_process_metadata(decoder)) {
106 fprintf(stderr, "%s: ERROR while decoding metadata, state=%d:%s\n", stream_info.inbasefilename, FLAC__file_decoder_get_state(decoder), FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
109 if(stream_info.skip_count_too_high) {
110 fprintf(stderr, "%s: ERROR trying to skip more samples than in stream\n", stream_info.inbasefilename);
113 if(!FLAC__file_decoder_seek_absolute(decoder, skip)) {
114 fprintf(stderr, "%s: ERROR seeking while skipping bytes, state=%d:%s\n", stream_info.inbasefilename, FLAC__file_decoder_get_state(decoder), FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
117 if(!FLAC__file_decoder_process_remaining_frames(decoder)) {
118 if(verbose) fprintf(stderr, "\n");
119 fprintf(stderr, "%s: ERROR while decoding frames, state=%d:%s\n", stream_info.inbasefilename, FLAC__file_decoder_get_state(decoder), FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
122 if(FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_END_OF_FILE) {
123 if(verbose) fprintf(stderr, "\n");
124 fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", stream_info.inbasefilename, FLAC__file_decoder_get_state(decoder), FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
129 if(!FLAC__file_decoder_process_whole_file(decoder)) {
130 if(verbose) fprintf(stderr, "\n");
131 fprintf(stderr, "%s: ERROR while decoding data, state=%d:%s\n", stream_info.inbasefilename, FLAC__file_decoder_get_state(decoder), FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
134 if(FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_END_OF_FILE) {
135 if(verbose) fprintf(stderr, "\n");
136 fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", stream_info.inbasefilename, FLAC__file_decoder_get_state(decoder), FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
142 if(FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_UNINITIALIZED)
143 md5_failure = !FLAC__file_decoder_finish(decoder);
144 print_stats(&stream_info);
145 FLAC__file_decoder_delete(decoder);
147 if(0 != stream_info.fout && stream_info.fout != stdout)
148 fclose(stream_info.fout);
150 flac__analyze_finish(aopts);
152 fprintf(stderr, "\r%s: WARNING, MD5 signature mismatch\n", stream_info.inbasefilename);
156 fprintf(stderr, "\r%s: %s \n", stream_info.inbasefilename, stream_info.test_only? "ok ":analysis_mode?"done ":"done");
161 if(FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_UNINITIALIZED)
162 FLAC__file_decoder_finish(decoder);
163 FLAC__file_decoder_delete(decoder);
165 if(0 != stream_info.fout && stream_info.fout != stdout) {
166 fclose(stream_info.fout);
170 flac__analyze_finish(aopts);
174 int flac__decode_raw(const char *infile, const char *outfile, bool analysis_mode, analysis_options aopts, bool verbose, uint64 skip, bool is_big_endian, bool is_unsigned_samples)
176 bool md5_failure = false;
177 stream_info_struct stream_info;
180 stream_info.abort_flag = false;
181 stream_info.analysis_mode = analysis_mode;
182 stream_info.aopts = aopts;
183 stream_info.test_only = (outfile == 0);
184 stream_info.is_wave_out = false;
185 stream_info.is_big_endian = is_big_endian;
186 stream_info.is_unsigned_samples = is_unsigned_samples;
187 stream_info.verbose = verbose;
188 stream_info.skip = skip;
189 stream_info.skip_count_too_high = false;
190 stream_info.samples_processed = 0;
191 stream_info.frame_counter = 0;
192 stream_info.inbasefilename = flac__file_get_basename(infile);
193 stream_info.fout = 0; /* initialized with an open file later if necessary */
195 FLAC__ASSERT(!(stream_info.test_only && stream_info.analysis_mode));
197 if(!stream_info.test_only) {
198 if(0 == strcmp(outfile, "-")) {
199 stream_info.fout = stdout;
202 if(0 == (stream_info.fout = fopen(outfile, "wb"))) {
203 fprintf(stderr, "%s: ERROR: can't open output file %s\n", stream_info.inbasefilename, outfile);
210 flac__analyze_init(aopts);
212 if(!init(infile, &stream_info))
216 if(!FLAC__file_decoder_process_metadata(decoder)) {
217 fprintf(stderr, "%s: ERROR while decoding metadata, state=%d:%s\n", stream_info.inbasefilename, FLAC__file_decoder_get_state(decoder), FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
220 if(stream_info.skip_count_too_high) {
221 fprintf(stderr, "%s: ERROR trying to skip more samples than in stream\n", stream_info.inbasefilename);
224 if(!FLAC__file_decoder_seek_absolute(decoder, skip)) {
225 fprintf(stderr, "%s: ERROR seeking while skipping bytes, state=%d:%s\n", stream_info.inbasefilename, FLAC__file_decoder_get_state(decoder), FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
228 if(!FLAC__file_decoder_process_remaining_frames(decoder)) {
229 if(verbose) fprintf(stderr, "\n");
230 fprintf(stderr, "%s: ERROR while decoding frames, state=%d:%s\n", stream_info.inbasefilename, FLAC__file_decoder_get_state(decoder), FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
233 if(FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_END_OF_FILE) {
234 if(verbose) fprintf(stderr, "\n");
235 fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", stream_info.inbasefilename, FLAC__file_decoder_get_state(decoder), FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
240 if(!FLAC__file_decoder_process_whole_file(decoder)) {
241 if(verbose) fprintf(stderr, "\n");
242 fprintf(stderr, "%s: ERROR while decoding data, state=%d:%s\n", stream_info.inbasefilename, FLAC__file_decoder_get_state(decoder), FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
245 if(FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_END_OF_FILE) {
246 if(verbose) fprintf(stderr, "\n");
247 fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", stream_info.inbasefilename, FLAC__file_decoder_get_state(decoder), FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
253 if(FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_UNINITIALIZED)
254 md5_failure = !FLAC__file_decoder_finish(decoder);
255 print_stats(&stream_info);
256 FLAC__file_decoder_delete(decoder);
258 if(0 != stream_info.fout && stream_info.fout != stdout)
259 fclose(stream_info.fout);
261 flac__analyze_finish(aopts);
263 fprintf(stderr, "\r%s: WARNING, MD5 signature mismatch\n", stream_info.inbasefilename);
267 fprintf(stderr, "\r%s: %s \n", stream_info.inbasefilename, stream_info.test_only? "ok ":analysis_mode?"done ":"done");
272 if(FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_UNINITIALIZED)
273 FLAC__file_decoder_finish(decoder);
274 FLAC__file_decoder_delete(decoder);
276 if(0 != stream_info.fout && stream_info.fout != stdout) {
277 fclose(stream_info.fout);
281 flac__analyze_finish(aopts);
285 bool init(const char *infilename, stream_info_struct *stream_info)
289 is_big_endian_host = (*((byte*)(&test)))? false : true;
291 decoder = FLAC__file_decoder_new();
293 fprintf(stderr, "%s: ERROR creating the decoder instance\n", stream_info->inbasefilename);
297 FLAC__file_decoder_set_md5_checking(decoder, true);
298 FLAC__file_decoder_set_filename(decoder, infilename);
299 FLAC__file_decoder_set_write_callback(decoder, write_callback);
300 FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback);
301 FLAC__file_decoder_set_error_callback(decoder, error_callback);
302 FLAC__file_decoder_set_client_data(decoder, stream_info);
304 if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK) {
305 fprintf(stderr, "%s: ERROR initializing decoder, state=%d:%s\n", stream_info->inbasefilename, FLAC__file_decoder_get_state(decoder), FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
312 bool write_little_endian_uint16(FILE *f, uint16 val)
314 byte *b = (byte*)(&val);
315 if(is_big_endian_host) {
317 tmp = b[1]; b[1] = b[0]; b[0] = tmp;
319 return fwrite(b, 1, 2, f) == 2;
322 bool write_little_endian_uint32(FILE *f, uint32 val)
324 byte *b = (byte*)(&val);
325 if(is_big_endian_host) {
327 tmp = b[3]; b[3] = b[0]; b[0] = tmp;
328 tmp = b[2]; b[2] = b[1]; b[1] = tmp;
330 return fwrite(b, 1, 4, f) == 4;
333 FLAC__StreamDecoderWriteStatus write_callback(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const int32 *buffer[], void *client_data)
335 stream_info_struct *stream_info = (stream_info_struct *)client_data;
336 FILE *fout = stream_info->fout;
337 unsigned bps = stream_info->bps, channels = stream_info->channels;
338 bool is_big_endian = (stream_info->is_wave_out? false : stream_info->is_big_endian);
339 bool is_unsigned_samples = (stream_info->is_wave_out? bps<=8 : stream_info->is_unsigned_samples);
340 unsigned wide_samples = frame->header.blocksize, wide_sample, sample, channel, byte;
341 static int8 s8buffer[FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * sizeof(int32)]; /* WATCHOUT: can be up to 2 megs */
342 /* WATCHOUT: we say 'sizeof(int32)' above instead of '(FLAC__MAX_BITS_PER_SAMPLE+7)/8' because we have to use an array int32 even for 24 bps */
343 uint8 *u8buffer = (uint8 *)s8buffer;
344 int16 *s16buffer = (int16 *)s8buffer;
345 uint16 *u16buffer = (uint16 *)s8buffer;
346 int32 *s32buffer = (int32 *)s8buffer;
347 uint32 *u32buffer = (uint32 *)s8buffer;
351 if(stream_info->abort_flag)
352 return FLAC__STREAM_DECODER_WRITE_ABORT;
354 stream_info->samples_processed += wide_samples;
355 stream_info->frame_counter++;
357 if(stream_info->verbose && !(stream_info->frame_counter & 0x7f))
358 print_stats(stream_info);
360 if(stream_info->analysis_mode) {
361 flac__analyze_frame(frame, stream_info->frame_counter-1, stream_info->aopts, fout);
363 else if(!stream_info->test_only) {
365 if(is_unsigned_samples) {
366 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
367 for(channel = 0; channel < channels; channel++, sample++)
368 u8buffer[sample] = buffer[channel][wide_sample] + 0x80;
371 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
372 for(channel = 0; channel < channels; channel++, sample++)
373 s8buffer[sample] = buffer[channel][wide_sample];
375 if(fwrite(u8buffer, 1, sample, fout) != sample)
376 return FLAC__STREAM_DECODER_WRITE_ABORT;
379 if(is_unsigned_samples) {
380 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
381 for(channel = 0; channel < channels; channel++, sample++)
382 u16buffer[sample] = buffer[channel][wide_sample] + 0x8000;
385 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
386 for(channel = 0; channel < channels; channel++, sample++)
387 s16buffer[sample] = buffer[channel][wide_sample];
389 if(is_big_endian != is_big_endian_host) {
391 const unsigned bytes = sample * 2;
392 for(byte = 0; byte < bytes; byte += 2) {
393 tmp = u8buffer[byte];
394 u8buffer[byte] = u8buffer[byte+1];
395 u8buffer[byte+1] = tmp;
398 if(fwrite(u16buffer, 2, sample, fout) != sample)
399 return FLAC__STREAM_DECODER_WRITE_ABORT;
402 if(is_unsigned_samples) {
403 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
404 for(channel = 0; channel < channels; channel++, sample++)
405 u32buffer[sample] = buffer[channel][wide_sample] + 0x800000;
408 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
409 for(channel = 0; channel < channels; channel++, sample++)
410 s32buffer[sample] = buffer[channel][wide_sample];
412 if(is_big_endian != is_big_endian_host) {
414 const unsigned bytes = sample * 4;
415 for(byte = 0; byte < bytes; byte += 4) {
416 tmp = u8buffer[byte];
417 u8buffer[byte] = u8buffer[byte+3];
418 u8buffer[byte+3] = tmp;
419 tmp = u8buffer[byte+1];
420 u8buffer[byte+1] = u8buffer[byte+2];
421 u8buffer[byte+2] = tmp;
426 const unsigned bytes = sample * 4;
427 for(lbyte = byte = 0; byte < bytes; ) {
429 u8buffer[lbyte++] = u8buffer[byte++];
430 u8buffer[lbyte++] = u8buffer[byte++];
431 u8buffer[lbyte++] = u8buffer[byte++];
436 const unsigned bytes = sample * 4;
437 for(lbyte = byte = 0; byte < bytes; ) {
438 u8buffer[lbyte++] = u8buffer[byte++];
439 u8buffer[lbyte++] = u8buffer[byte++];
440 u8buffer[lbyte++] = u8buffer[byte++];
444 if(fwrite(u8buffer, 3, sample, fout) != sample)
445 return FLAC__STREAM_DECODER_WRITE_ABORT;
451 return FLAC__STREAM_DECODER_WRITE_CONTINUE;
454 void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data)
456 stream_info_struct *stream_info = (stream_info_struct *)client_data;
458 if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
459 /* remember, metadata->data.stream_info.total_samples can be 0, meaning 'unknown' */
460 if(metadata->data.stream_info.total_samples > 0 && stream_info->skip >= metadata->data.stream_info.total_samples) {
461 stream_info->total_samples = 0;
462 stream_info->skip_count_too_high = true;
465 stream_info->total_samples = metadata->data.stream_info.total_samples - stream_info->skip;
466 stream_info->bps = metadata->data.stream_info.bits_per_sample;
467 stream_info->channels = metadata->data.stream_info.channels;
468 stream_info->sample_rate = metadata->data.stream_info.sample_rate;
470 if(stream_info->bps != 8 && stream_info->bps != 16 && stream_info->bps != 24) {
471 fprintf(stderr, "%s: ERROR: bits per sample is not 8/16/24\n", stream_info->inbasefilename);
472 stream_info->abort_flag = true;
476 /* write the WAVE headers if necessary */
477 if(!stream_info->analysis_mode && !stream_info->test_only && stream_info->is_wave_out) {
478 uint64 data_size = stream_info->total_samples * stream_info->channels * ((stream_info->bps+7)/8);
479 if(data_size >= 0xFFFFFFDC) {
480 fprintf(stderr, "%s: ERROR: stream is too big to fit in a single WAVE file chunk\n", stream_info->inbasefilename);
481 stream_info->abort_flag = true;
484 if(fwrite("RIFF", 1, 4, stream_info->fout) != 4) stream_info->abort_flag = true;
485 if(!write_little_endian_uint32(stream_info->fout, (uint32)(data_size+36))) stream_info->abort_flag = true; /* filesize-8 */
486 if(fwrite("WAVEfmt ", 1, 8, stream_info->fout) != 8) stream_info->abort_flag = true;
487 if(fwrite("\020\000\000\000", 1, 4, stream_info->fout) != 4) stream_info->abort_flag = true; /* chunk size = 16 */
488 if(fwrite("\001\000", 1, 2, stream_info->fout) != 2) stream_info->abort_flag = true; /* compression code == 1 */
489 if(!write_little_endian_uint16(stream_info->fout, (uint16)(stream_info->channels))) stream_info->abort_flag = true;
490 if(!write_little_endian_uint32(stream_info->fout, stream_info->sample_rate)) stream_info->abort_flag = true;
491 if(!write_little_endian_uint32(stream_info->fout, stream_info->sample_rate * stream_info->channels * ((stream_info->bps+7) / 8))) stream_info->abort_flag = true; /* @@@ or is it (sample_rate*channels*bps) / 8 ??? */
492 if(!write_little_endian_uint16(stream_info->fout, (uint16)(stream_info->channels * ((stream_info->bps+7) / 8)))) stream_info->abort_flag = true; /* block align */
493 if(!write_little_endian_uint16(stream_info->fout, (uint16)(stream_info->bps))) stream_info->abort_flag = true; /* bits per sample */
494 if(fwrite("data", 1, 4, stream_info->fout) != 4) stream_info->abort_flag = true;
495 if(!write_little_endian_uint32(stream_info->fout, (uint32)data_size)) stream_info->abort_flag = true; /* data size */
500 void error_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
502 stream_info_struct *stream_info = (stream_info_struct *)client_data;
504 fprintf(stderr, "%s: *** Got error code %d:%s\n", stream_info->inbasefilename, status, FLAC__StreamDecoderErrorStatusString[status]);
505 stream_info->abort_flag = true;
508 void print_stats(const stream_info_struct *stream_info)
510 if(stream_info->verbose) {
512 /* with VC++ you have to spoon feed it the casting */
513 const double progress = (double)(int64)stream_info->samples_processed / (double)(int64)stream_info->total_samples * 100.0;
515 const double progress = (double)stream_info->samples_processed / (double)stream_info->total_samples * 100.0;
517 if(stream_info->total_samples > 0) {
518 fprintf(stderr, "\r%s: %s%u%% complete",
519 stream_info->inbasefilename,
520 stream_info->test_only? "testing, " : stream_info->analysis_mode? "analyzing, " : "",
521 (unsigned)floor(progress + 0.5)
525 fprintf(stderr, "\r%s: %s %u samples",
526 stream_info->inbasefilename,
527 stream_info->test_only? "tested" : stream_info->analysis_mode? "analyzed" : "wrote",
528 (unsigned)stream_info->samples_processed