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 <assert.h> /* for FILE */
26 #include <stdio.h> /* for FILE */
27 #include <string.h> /* for strcmp() */
35 bool analyze_residual;
39 bool is_unsigned_samples;
46 uint64 samples_processed;
47 unsigned frame_counter;
50 static FLAC__FileDecoder *decoder;
51 static bool is_big_endian_host;
54 static bool init(const char *infile, stream_info_struct *stream_info);
55 static bool write_little_endian_uint16(FILE *f, uint16 val);
56 static bool write_little_endian_uint32(FILE *f, uint32 val);
57 static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const int32 *buffer[], void *client_data);
58 static void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);
59 static void error_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
60 static void print_stats(const stream_info_struct *stream_info);
62 int decode_wav(const char *infile, const char *outfile, bool analysis_mode, bool analyze_residual, bool verbose, uint64 skip)
64 bool md5_failure = false;
65 stream_info_struct stream_info;
68 stream_info.abort_flag = false;
69 stream_info.analysis_mode = analysis_mode;
70 stream_info.analyze_residual = analyze_residual;
71 stream_info.test_only = (outfile == 0);
72 stream_info.is_wave_out = true;
73 stream_info.verbose = verbose;
74 stream_info.skip = skip;
75 stream_info.samples_processed = 0;
76 stream_info.frame_counter = 0;
78 assert(!(stream_info.test_only && stream_info.analysis_mode));
80 if(!stream_info.test_only) {
81 if(0 == strcmp(outfile, "-")) {
82 stream_info.fout = stdout;
85 if(0 == (stream_info.fout = fopen(outfile, "wb"))) {
86 fprintf(stderr, "ERROR: can't open output file %s\n", outfile);
92 if(!init(infile, &stream_info))
96 if(!FLAC__file_decoder_process_metadata(decoder)) {
97 fprintf(stderr, "%s: ERROR during decoding\n", infile);
100 if(!FLAC__file_decoder_seek_absolute(decoder, skip)) {
101 fprintf(stderr, "%s: ERROR seeking while skipping bytes\n", infile);
104 if(!FLAC__file_decoder_process_remaining_frames(decoder)) {
105 if(verbose) { printf("\n"); fflush(stdout); }
106 fprintf(stderr, "%s: ERROR during decoding\n", infile);
109 if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
110 if(verbose) { printf("\n"); fflush(stdout); }
111 fprintf(stderr, "%s: ERROR during decoding\n", infile);
116 if(!FLAC__file_decoder_process_whole_file(decoder)) {
117 if(verbose) { printf("\n"); fflush(stdout); }
118 fprintf(stderr, "%s: ERROR during decoding\n", infile);
121 if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
122 if(verbose) { printf("\n"); fflush(stdout); }
123 fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
129 if(decoder->state != FLAC__FILE_DECODER_UNINITIALIZED)
130 md5_failure = !FLAC__file_decoder_finish(decoder);
131 print_stats(&stream_info);
132 FLAC__file_decoder_free_instance(decoder);
134 if(!stream_info.test_only)
135 fclose(stream_info.fout);
140 fprintf(stderr, "%s: WARNING, MD5 signature mismatch\n", infile);
144 if(stream_info.test_only)
145 printf("%s: ok\n", infile);
150 if(decoder->state != FLAC__FILE_DECODER_UNINITIALIZED)
151 FLAC__file_decoder_finish(decoder);
152 FLAC__file_decoder_free_instance(decoder);
154 if(!stream_info.test_only) {
155 fclose(stream_info.fout);
161 int decode_raw(const char *infile, const char *outfile, bool analysis_mode, bool analyze_residual, bool verbose, uint64 skip, bool is_big_endian, bool is_unsigned_samples)
163 bool md5_failure = false;
164 stream_info_struct stream_info;
167 stream_info.abort_flag = false;
168 stream_info.analysis_mode = analysis_mode;
169 stream_info.analyze_residual = analyze_residual;
170 stream_info.test_only = (outfile == 0);
171 stream_info.is_wave_out = false;
172 stream_info.is_big_endian = is_big_endian;
173 stream_info.is_unsigned_samples = is_unsigned_samples;
174 stream_info.verbose = verbose;
175 stream_info.skip = skip;
176 stream_info.samples_processed = 0;
177 stream_info.frame_counter = 0;
179 assert(!(stream_info.test_only && stream_info.analysis_mode));
181 if(!stream_info.test_only) {
182 if(0 == strcmp(outfile, "-")) {
183 stream_info.fout = stdout;
186 if(0 == (stream_info.fout = fopen(outfile, "wb"))) {
187 fprintf(stderr, "ERROR: can't open output file %s\n", outfile);
193 if(!init(infile, &stream_info))
197 if(!FLAC__file_decoder_process_metadata(decoder)) {
198 fprintf(stderr, "%s: ERROR during decoding\n", infile);
201 if(!FLAC__file_decoder_seek_absolute(decoder, skip)) {
202 fprintf(stderr, "%s: ERROR seeking while skipping bytes\n", infile);
205 if(!FLAC__file_decoder_process_remaining_frames(decoder)) {
206 if(verbose) { printf("\n"); fflush(stdout); }
207 fprintf(stderr, "%s: ERROR during decoding\n", infile);
210 if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
211 if(verbose) { printf("\n"); fflush(stdout); }
212 fprintf(stderr, "%s: ERROR during decoding\n", infile);
217 if(!FLAC__file_decoder_process_whole_file(decoder)) {
218 if(verbose) { printf("\n"); fflush(stdout); }
219 fprintf(stderr, "%s: ERROR during decoding\n", infile);
222 if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
223 if(verbose) { printf("\n"); fflush(stdout); }
224 fprintf(stderr, "%s: ERROR during decoding\n", infile);
230 if(decoder->state != FLAC__FILE_DECODER_UNINITIALIZED)
231 md5_failure = !FLAC__file_decoder_finish(decoder);
232 print_stats(&stream_info);
233 FLAC__file_decoder_free_instance(decoder);
235 if(!stream_info.test_only)
236 fclose(stream_info.fout);
241 fprintf(stderr, "%s: WARNING, MD5 signature mismatch\n", infile);
245 if(stream_info.test_only)
246 printf("%s: ok\n", infile);
251 if(decoder->state != FLAC__FILE_DECODER_UNINITIALIZED)
252 FLAC__file_decoder_finish(decoder);
253 FLAC__file_decoder_free_instance(decoder);
255 if(!stream_info.test_only) {
256 fclose(stream_info.fout);
262 bool init(const char *infile, stream_info_struct *stream_info)
266 is_big_endian_host = (*((byte*)(&test)))? false : true;
268 decoder = FLAC__file_decoder_get_new_instance();
270 fprintf(stderr, "ERROR creating the decoder instance\n");
273 decoder->check_md5 = true;
275 if(FLAC__file_decoder_init(decoder, infile, write_callback, metadata_callback, error_callback, stream_info) != FLAC__FILE_DECODER_OK) {
276 fprintf(stderr, "ERROR initializing decoder, state = %d\n", decoder->state);
283 bool write_little_endian_uint16(FILE *f, uint16 val)
285 byte *b = (byte*)(&val);
286 if(is_big_endian_host) {
288 tmp = b[1]; b[1] = b[0]; b[0] = tmp;
290 return fwrite(b, 1, 2, f) == 2;
293 bool write_little_endian_uint32(FILE *f, uint32 val)
295 byte *b = (byte*)(&val);
296 if(is_big_endian_host) {
298 tmp = b[3]; b[3] = b[0]; b[0] = tmp;
299 tmp = b[2]; b[2] = b[1]; b[1] = tmp;
301 return fwrite(b, 1, 4, f) == 4;
304 FLAC__StreamDecoderWriteStatus write_callback(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const int32 *buffer[], void *client_data)
306 stream_info_struct *stream_info = (stream_info_struct *)client_data;
307 FILE *fout = stream_info->fout;
308 unsigned bps = stream_info->bps, channels = stream_info->channels;
309 bool is_big_endian = (stream_info->is_wave_out? false : stream_info->is_big_endian);
310 bool is_unsigned_samples = (stream_info->is_wave_out? bps<=8 : stream_info->is_unsigned_samples);
311 unsigned wide_samples = frame->header.blocksize, wide_sample, sample, channel, byte;
312 static int8 s8buffer[FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * sizeof(int32)]; /* WATCHOUT: can be up to 2 megs */
313 /* 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 */
314 uint8 *u8buffer = (uint8 *)s8buffer;
315 int16 *s16buffer = (int16 *)s8buffer;
316 uint16 *u16buffer = (uint16 *)s8buffer;
317 int32 *s32buffer = (int32 *)s8buffer;
318 uint32 *u32buffer = (uint32 *)s8buffer;
322 if(stream_info->abort_flag)
323 return FLAC__STREAM_DECODER_WRITE_ABORT;
325 stream_info->samples_processed += wide_samples;
326 stream_info->frame_counter++;
328 if(stream_info->verbose && !(stream_info->frame_counter & 0x1f))
329 print_stats(stream_info);
331 if(stream_info->analysis_mode) {
333 fprintf(fout, "frame=%u\tblocksize=%u\tsample_rate=%u\tchannels=%u\tchannel_assignment=%s\n", stream_info->frame_counter-1, frame->header.blocksize, frame->header.sample_rate, frame->header.channels, FLAC__ChannelAssignmentString[frame->header.channel_assignment]);
334 for(channel = 0; channel < channels; channel++) {
335 const FLAC__Subframe *subframe = frame->subframes+channel;
336 fprintf(fout, "\tsubframe=%u\ttype=%s", channel, FLAC__SubframeTypeString[subframe->type]);
337 switch(subframe->type) {
338 case FLAC__SUBFRAME_TYPE_CONSTANT:
339 fprintf(fout, "\tvalue=%d\n", subframe->data.constant.value);
341 case FLAC__SUBFRAME_TYPE_FIXED:
342 fprintf(fout, "\torder=%u\tpartition_order=%u\n", subframe->data.fixed.order, subframe->data.fixed.entropy_coding_method.data.partitioned_rice.order); /*@@@ assumes method is partitioned-rice */
343 for(i = 0; i < subframe->data.fixed.order; i++)
344 fprintf(fout, "\t\twarmup[%u]=%d\n", i, subframe->data.fixed.warmup[i]);
345 if(stream_info->analyze_residual) {
346 for(i = 0; i < frame->header.blocksize-subframe->data.fixed.order; i++)
347 fprintf(fout, "\t\tresidual[%u]=%d\n", i, subframe->data.fixed.residual[i]);
350 case FLAC__SUBFRAME_TYPE_LPC:
351 fprintf(fout, "\torder=%u\tpartition_order=%u\tqlp_coeff_precision=%u\tquantization_level=%d\n", subframe->data.lpc.order, subframe->data.lpc.entropy_coding_method.data.partitioned_rice.order, subframe->data.lpc.qlp_coeff_precision, subframe->data.lpc.quantization_level); /*@@@ assumes method is partitioned-rice */
352 for(i = 0; i < subframe->data.lpc.order; i++)
353 fprintf(fout, "\t\twarmup[%u]=%d\n", i, subframe->data.lpc.warmup[i]);
354 if(stream_info->analyze_residual) {
355 for(i = 0; i < frame->header.blocksize-subframe->data.lpc.order; i++)
356 fprintf(fout, "\t\tresidual[%u]=%d\n", i, subframe->data.lpc.residual[i]);
359 case FLAC__SUBFRAME_TYPE_VERBATIM:
365 else if(!stream_info->test_only) {
367 if(is_unsigned_samples) {
368 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
369 for(channel = 0; channel < channels; channel++, sample++)
370 u8buffer[sample] = buffer[channel][wide_sample] + 0x80;
373 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
374 for(channel = 0; channel < channels; channel++, sample++)
375 s8buffer[sample] = buffer[channel][wide_sample];
377 if(fwrite(u8buffer, 1, sample, fout) != sample)
378 return FLAC__STREAM_DECODER_WRITE_ABORT;
381 if(is_unsigned_samples) {
382 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
383 for(channel = 0; channel < channels; channel++, sample++)
384 u16buffer[sample] = buffer[channel][wide_sample] + 0x8000;
387 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
388 for(channel = 0; channel < channels; channel++, sample++)
389 s16buffer[sample] = buffer[channel][wide_sample];
391 if(is_big_endian != is_big_endian_host) {
393 const unsigned bytes = sample * 2;
394 for(byte = 0; byte < bytes; byte += 2) {
395 tmp = u8buffer[byte];
396 u8buffer[byte] = u8buffer[byte+1];
397 u8buffer[byte+1] = tmp;
400 if(fwrite(u16buffer, 2, sample, fout) != sample)
401 return FLAC__STREAM_DECODER_WRITE_ABORT;
404 if(is_unsigned_samples) {
405 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
406 for(channel = 0; channel < channels; channel++, sample++)
407 u32buffer[sample] = buffer[channel][wide_sample] + 0x800000;
410 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
411 for(channel = 0; channel < channels; channel++, sample++)
412 s32buffer[sample] = buffer[channel][wide_sample];
414 if(is_big_endian != is_big_endian_host) {
416 const unsigned bytes = sample * 4;
417 for(byte = 0; byte < bytes; byte += 4) {
418 tmp = u8buffer[byte];
419 u8buffer[byte] = u8buffer[byte+3];
420 u8buffer[byte+3] = tmp;
421 tmp = u8buffer[byte+1];
422 u8buffer[byte+1] = u8buffer[byte+2];
423 u8buffer[byte+2] = tmp;
428 const unsigned bytes = sample * 4;
429 for(lbyte = byte = 0; byte < bytes; ) {
431 u8buffer[lbyte++] = u8buffer[byte++];
432 u8buffer[lbyte++] = u8buffer[byte++];
433 u8buffer[lbyte++] = u8buffer[byte++];
438 const unsigned bytes = sample * 4;
439 for(lbyte = byte = 0; byte < bytes; ) {
440 u8buffer[lbyte++] = u8buffer[byte++];
441 u8buffer[lbyte++] = u8buffer[byte++];
442 u8buffer[lbyte++] = u8buffer[byte++];
446 if(fwrite(u8buffer, 3, sample, fout) != sample)
447 return FLAC__STREAM_DECODER_WRITE_ABORT;
453 return FLAC__STREAM_DECODER_WRITE_CONTINUE;
456 void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data)
458 stream_info_struct *stream_info = (stream_info_struct *)client_data;
460 if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
461 stream_info->total_samples = metadata->data.stream_info.total_samples - stream_info->skip;
462 stream_info->bps = metadata->data.stream_info.bits_per_sample;
463 stream_info->channels = metadata->data.stream_info.channels;
464 stream_info->sample_rate = metadata->data.stream_info.sample_rate;
466 if(stream_info->bps != 8 && stream_info->bps != 16 && stream_info->bps != 24) {
467 fprintf(stderr, "ERROR: bits per sample is not 8/16/24\n");
468 stream_info->abort_flag = true;
472 /* write the WAVE headers if necessary */
473 if(!stream_info->analysis_mode && !stream_info->test_only && stream_info->is_wave_out) {
474 uint64 data_size = stream_info->total_samples * stream_info->channels * ((stream_info->bps+7)/8);
475 if(data_size >= 0xFFFFFFDC) {
476 fprintf(stderr, "ERROR: stream is too big for a wave file\n");
477 stream_info->abort_flag = true;
480 if(fwrite("RIFF", 1, 4, stream_info->fout) != 4) stream_info->abort_flag = true;
481 if(!write_little_endian_uint32(stream_info->fout, (uint32)(data_size+36))) stream_info->abort_flag = true; /* filesize-8 */
482 if(fwrite("WAVEfmt ", 1, 8, stream_info->fout) != 8) stream_info->abort_flag = true;
483 if(fwrite("\020\000\000\000", 1, 4, stream_info->fout) != 4) stream_info->abort_flag = true; /* chunk size = 16 */
484 if(fwrite("\001\000", 1, 2, stream_info->fout) != 2) stream_info->abort_flag = true; /* compression code == 1 */
485 if(!write_little_endian_uint16(stream_info->fout, (uint16)(stream_info->channels))) stream_info->abort_flag = true;
486 if(!write_little_endian_uint32(stream_info->fout, stream_info->sample_rate)) stream_info->abort_flag = true;
487 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 ??? */
488 if(!write_little_endian_uint16(stream_info->fout, (uint16)(stream_info->channels * ((stream_info->bps+7) / 8)))) stream_info->abort_flag = true; /* block align */
489 if(!write_little_endian_uint16(stream_info->fout, (uint16)(stream_info->bps))) stream_info->abort_flag = true; /* bits per sample */
490 if(fwrite("data", 1, 4, stream_info->fout) != 4) stream_info->abort_flag = true;
491 if(!write_little_endian_uint32(stream_info->fout, (uint32)data_size)) stream_info->abort_flag = true; /* data size */
496 void error_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
498 stream_info_struct *stream_info = (stream_info_struct *)client_data;
500 fprintf(stderr, "*** Got error code %d\n", status);
501 stream_info->abort_flag = true;
504 void print_stats(const stream_info_struct *stream_info)
506 if(stream_info->verbose) {
507 printf("\r%s %u of %u samples, %6.2f%% complete",
508 stream_info->test_only? "tested" : stream_info->analysis_mode? "analyzed" : "wrote",
509 (unsigned)stream_info->samples_processed,
510 (unsigned)stream_info->total_samples,
512 /* with VC++ you have to spoon feed it the casting */
513 (double)(int64)stream_info->samples_processed / (double)(int64)stream_info->total_samples * 100.0
515 (double)stream_info->samples_processed / (double)stream_info->total_samples * 100.0