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() */
38 bool is_unsigned_samples;
45 uint64 samples_processed;
46 unsigned frame_counter;
49 static FLAC__FileDecoder *decoder;
50 static bool is_big_endian_host;
53 static bool init(const char *infile, stream_info_struct *stream_info);
54 static bool write_little_endian_uint16(FILE *f, uint16 val);
55 static bool write_little_endian_uint32(FILE *f, uint32 val);
56 static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const int32 *buffer[], void *client_data);
57 static void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);
58 static void error_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
59 static void print_stats(const stream_info_struct *stream_info);
61 int decode_wav(const char *infile, const char *outfile, bool analysis_mode, bool verbose, uint64 skip)
63 bool md5_failure = false;
64 stream_info_struct stream_info;
67 stream_info.abort_flag = false;
68 stream_info.analysis_mode = analysis_mode;
69 stream_info.test_only = (outfile == 0);
70 stream_info.is_wave_out = true;
71 stream_info.verbose = verbose;
72 stream_info.skip = skip;
73 stream_info.samples_processed = 0;
74 stream_info.frame_counter = 0;
76 assert(!(stream_info.test_only && stream_info.analysis_mode));
78 if(!stream_info.test_only) {
79 if(0 == strcmp(outfile, "-")) {
80 stream_info.fout = stdout;
83 if(0 == (stream_info.fout = fopen(outfile, "wb"))) {
84 fprintf(stderr, "ERROR: can't open output file %s\n", outfile);
90 if(!init(infile, &stream_info))
94 if(!FLAC__file_decoder_process_metadata(decoder)) {
95 fprintf(stderr, "%s: ERROR during decoding\n", infile);
98 if(!FLAC__file_decoder_seek_absolute(decoder, skip)) {
99 fprintf(stderr, "%s: ERROR seeking while skipping bytes\n", infile);
102 if(!FLAC__file_decoder_process_remaining_frames(decoder)) {
103 if(verbose) { printf("\n"); fflush(stdout); }
104 fprintf(stderr, "%s: ERROR during decoding\n", infile);
107 if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
108 if(verbose) { printf("\n"); fflush(stdout); }
109 fprintf(stderr, "%s: ERROR during decoding\n", infile);
114 if(!FLAC__file_decoder_process_whole_file(decoder)) {
115 if(verbose) { printf("\n"); fflush(stdout); }
116 fprintf(stderr, "%s: ERROR during decoding\n", infile);
119 if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
120 if(verbose) { printf("\n"); fflush(stdout); }
121 fprintf(stderr, "%s: ERROR during decoding, state=%d:%s\n", infile, decoder->state, FLAC__FileDecoderStateString[decoder->state]);
127 if(decoder->state != FLAC__FILE_DECODER_UNINITIALIZED)
128 md5_failure = !FLAC__file_decoder_finish(decoder);
129 print_stats(&stream_info);
130 FLAC__file_decoder_free_instance(decoder);
132 if(!stream_info.test_only)
133 fclose(stream_info.fout);
138 fprintf(stderr, "%s: WARNING, MD5 signature mismatch\n", infile);
142 if(stream_info.test_only)
143 printf("%s: ok\n", infile);
148 if(decoder->state != FLAC__FILE_DECODER_UNINITIALIZED)
149 FLAC__file_decoder_finish(decoder);
150 FLAC__file_decoder_free_instance(decoder);
152 if(!stream_info.test_only) {
153 fclose(stream_info.fout);
159 int decode_raw(const char *infile, const char *outfile, bool analysis_mode, bool verbose, uint64 skip, bool is_big_endian, bool is_unsigned_samples)
161 bool md5_failure = false;
162 stream_info_struct stream_info;
165 stream_info.abort_flag = false;
166 stream_info.analysis_mode = analysis_mode;
167 stream_info.test_only = (outfile == 0);
168 stream_info.is_wave_out = false;
169 stream_info.is_big_endian = is_big_endian;
170 stream_info.is_unsigned_samples = is_unsigned_samples;
171 stream_info.verbose = verbose;
172 stream_info.skip = skip;
173 stream_info.samples_processed = 0;
174 stream_info.frame_counter = 0;
176 assert(!(stream_info.test_only && stream_info.analysis_mode));
178 if(!stream_info.test_only) {
179 if(0 == strcmp(outfile, "-")) {
180 stream_info.fout = stdout;
183 if(0 == (stream_info.fout = fopen(outfile, "wb"))) {
184 fprintf(stderr, "ERROR: can't open output file %s\n", outfile);
190 if(!init(infile, &stream_info))
194 if(!FLAC__file_decoder_process_metadata(decoder)) {
195 fprintf(stderr, "%s: ERROR during decoding\n", infile);
198 if(!FLAC__file_decoder_seek_absolute(decoder, skip)) {
199 fprintf(stderr, "%s: ERROR seeking while skipping bytes\n", infile);
202 if(!FLAC__file_decoder_process_remaining_frames(decoder)) {
203 if(verbose) { printf("\n"); fflush(stdout); }
204 fprintf(stderr, "%s: ERROR during decoding\n", infile);
207 if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
208 if(verbose) { printf("\n"); fflush(stdout); }
209 fprintf(stderr, "%s: ERROR during decoding\n", infile);
214 if(!FLAC__file_decoder_process_whole_file(decoder)) {
215 if(verbose) { printf("\n"); fflush(stdout); }
216 fprintf(stderr, "%s: ERROR during decoding\n", infile);
219 if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
220 if(verbose) { printf("\n"); fflush(stdout); }
221 fprintf(stderr, "%s: ERROR during decoding\n", infile);
227 if(decoder->state != FLAC__FILE_DECODER_UNINITIALIZED)
228 md5_failure = !FLAC__file_decoder_finish(decoder);
229 print_stats(&stream_info);
230 FLAC__file_decoder_free_instance(decoder);
232 if(!stream_info.test_only)
233 fclose(stream_info.fout);
238 fprintf(stderr, "%s: WARNING, MD5 signature mismatch\n", infile);
242 if(stream_info.test_only)
243 printf("%s: ok\n", infile);
248 if(decoder->state != FLAC__FILE_DECODER_UNINITIALIZED)
249 FLAC__file_decoder_finish(decoder);
250 FLAC__file_decoder_free_instance(decoder);
252 if(!stream_info.test_only) {
253 fclose(stream_info.fout);
259 bool init(const char *infile, stream_info_struct *stream_info)
263 is_big_endian_host = (*((byte*)(&test)))? false : true;
265 decoder = FLAC__file_decoder_get_new_instance();
267 fprintf(stderr, "ERROR creating the decoder instance\n");
270 decoder->check_md5 = true;
272 if(FLAC__file_decoder_init(decoder, infile, write_callback, metadata_callback, error_callback, stream_info) != FLAC__FILE_DECODER_OK) {
273 fprintf(stderr, "ERROR initializing decoder, state = %d\n", decoder->state);
280 bool write_little_endian_uint16(FILE *f, uint16 val)
282 byte *b = (byte*)(&val);
283 if(is_big_endian_host) {
285 tmp = b[1]; b[1] = b[0]; b[0] = tmp;
287 return fwrite(b, 1, 2, f) == 2;
290 bool write_little_endian_uint32(FILE *f, uint32 val)
292 byte *b = (byte*)(&val);
293 if(is_big_endian_host) {
295 tmp = b[3]; b[3] = b[0]; b[0] = tmp;
296 tmp = b[2]; b[2] = b[1]; b[1] = tmp;
298 return fwrite(b, 1, 4, f) == 4;
301 FLAC__StreamDecoderWriteStatus write_callback(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const int32 *buffer[], void *client_data)
303 stream_info_struct *stream_info = (stream_info_struct *)client_data;
304 FILE *fout = stream_info->fout;
305 unsigned bps = stream_info->bps, channels = stream_info->channels;
306 bool is_big_endian = (stream_info->is_wave_out? false : stream_info->is_big_endian);
307 bool is_unsigned_samples = (stream_info->is_wave_out? bps==8 : stream_info->is_unsigned_samples);
308 unsigned wide_samples = frame->header.blocksize, wide_sample, sample, channel, byte;
309 static signed char scbuffer[FLAC__MAX_BLOCK_SIZE * FLAC__MAX_CHANNELS * ((FLAC__MAX_BITS_PER_SAMPLE+7)>>3)]; /* WATCHOUT: can be up to 2 megs */
310 unsigned char *ucbuffer = (unsigned char *)scbuffer;
311 signed short *ssbuffer = (signed short *)scbuffer;
312 unsigned short *usbuffer = (unsigned short *)scbuffer;
316 if(stream_info->abort_flag)
317 return FLAC__STREAM_DECODER_WRITE_ABORT;
319 stream_info->samples_processed += wide_samples;
320 stream_info->frame_counter++;
322 if(stream_info->verbose && !(stream_info->frame_counter & 0x1f))
323 print_stats(stream_info);
325 if(stream_info->analysis_mode) {
327 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]);
328 for(channel = 0; channel < channels; channel++) {
329 const FLAC__Subframe *subframe = frame->subframes+channel;
330 fprintf(fout, "\tsubframe=%u\ttype=%s", channel, FLAC__SubframeTypeString[subframe->type]);
331 switch(subframe->type) {
332 case FLAC__SUBFRAME_TYPE_CONSTANT:
333 fprintf(fout, "\tvalue=%d\n", subframe->data.constant.value);
335 case FLAC__SUBFRAME_TYPE_FIXED:
336 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 */
337 for(i = 0; i < subframe->data.fixed.order; i++)
338 fprintf(fout, "\twarmup[%u]=%d\n", i, subframe->data.fixed.warmup[i]);
340 case FLAC__SUBFRAME_TYPE_LPC:
341 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 */
342 for(i = 0; i < subframe->data.lpc.order; i++)
343 fprintf(fout, "\twarmup[%u]=%d\n", i, subframe->data.lpc.warmup[i]);
345 case FLAC__SUBFRAME_TYPE_VERBATIM:
351 else if(!stream_info->test_only) {
353 if(is_unsigned_samples) {
354 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
355 for(channel = 0; channel < channels; channel++, sample++)
356 ucbuffer[sample] = buffer[channel][wide_sample] + 128;
359 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
360 for(channel = 0; channel < channels; channel++, sample++)
361 scbuffer[sample] = buffer[channel][wide_sample];
363 if(fwrite(ucbuffer, 1, sample, fout) != sample)
364 return FLAC__STREAM_DECODER_WRITE_ABORT;
366 else { /* bps == 16 */
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 usbuffer[sample] = buffer[channel][wide_sample] + 32768;
373 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
374 for(channel = 0; channel < channels; channel++, sample++)
375 ssbuffer[sample] = buffer[channel][wide_sample];
377 if(is_big_endian != is_big_endian_host) {
379 for(byte = 0; byte < sample<<1; byte += 2) {
380 tmp = ucbuffer[byte];
381 ucbuffer[byte] = ucbuffer[byte+1];
382 ucbuffer[byte+1] = tmp;
385 if(fwrite(usbuffer, 2, sample, fout) != sample)
386 return FLAC__STREAM_DECODER_WRITE_ABORT;
389 return FLAC__STREAM_DECODER_WRITE_CONTINUE;
392 void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data)
394 stream_info_struct *stream_info = (stream_info_struct *)client_data;
396 if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
397 stream_info->total_samples = metadata->data.stream_info.total_samples - stream_info->skip;
398 stream_info->bps = metadata->data.stream_info.bits_per_sample;
399 stream_info->channels = metadata->data.stream_info.channels;
400 stream_info->sample_rate = metadata->data.stream_info.sample_rate;
402 if(stream_info->bps != 8 && stream_info->bps != 16) {
403 fprintf(stderr, "ERROR: bits per sample is not 8 or 16\n");
404 stream_info->abort_flag = true;
408 /* write the WAVE headers if necessary */
409 if(!stream_info->analysis_mode && !stream_info->test_only && stream_info->is_wave_out) {
410 uint64 data_size = stream_info->total_samples * stream_info->channels * ((stream_info->bps+7)/8);
411 if(data_size >= 0xFFFFFFDC) {
412 fprintf(stderr, "ERROR: stream is too big for a wave file\n");
413 stream_info->abort_flag = true;
416 if(fwrite("RIFF", 1, 4, stream_info->fout) != 4) stream_info->abort_flag = true;
417 if(!write_little_endian_uint32(stream_info->fout, (uint32)(data_size+36))) stream_info->abort_flag = true; /* filesize-8 */
418 if(fwrite("WAVEfmt ", 1, 8, stream_info->fout) != 8) stream_info->abort_flag = true;
419 if(fwrite("\020\000\000\000", 1, 4, stream_info->fout) != 4) stream_info->abort_flag = true; /* chunk size = 16 */
420 if(fwrite("\001\000", 1, 2, stream_info->fout) != 2) stream_info->abort_flag = true; /* compression code == 1 */
421 if(!write_little_endian_uint16(stream_info->fout, (uint16)(stream_info->channels))) stream_info->abort_flag = true;
422 if(!write_little_endian_uint32(stream_info->fout, stream_info->sample_rate)) stream_info->abort_flag = true;
423 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 ??? */
424 if(!write_little_endian_uint16(stream_info->fout, (uint16)(stream_info->channels * ((stream_info->bps+7) / 8)))) stream_info->abort_flag = true; /* block align */
425 if(!write_little_endian_uint16(stream_info->fout, (uint16)(stream_info->bps))) stream_info->abort_flag = true; /* bits per sample */
426 if(fwrite("data", 1, 4, stream_info->fout) != 4) stream_info->abort_flag = true;
427 if(!write_little_endian_uint32(stream_info->fout, (uint32)data_size)) stream_info->abort_flag = true; /* data size */
432 void error_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
434 stream_info_struct *stream_info = (stream_info_struct *)client_data;
436 fprintf(stderr, "*** Got error code %d\n", status);
437 stream_info->abort_flag = true;
440 void print_stats(const stream_info_struct *stream_info)
442 if(stream_info->verbose) {
443 printf("\r%s %u of %u samples, %6.2f%% complete",
444 stream_info->test_only? "tested" : stream_info->analysis_mode? "analyzed" : "wrote",
445 (unsigned)stream_info->samples_processed,
446 (unsigned)stream_info->total_samples,
448 /* with VC++ you have to spoon feed it the casting */
449 (double)(int64)stream_info->samples_processed / (double)(int64)stream_info->total_samples * 100.0
451 (double)stream_info->samples_processed / (double)stream_info->total_samples * 100.0