1 /* flac - Command-line FLAC encoder/decoder
2 * Copyright (C) 2000 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 <stdio.h> /* for FILE */
26 #include <string.h> /* for strcmp() */
35 bool is_unsigned_samples;
42 uint64 samples_processed;
43 unsigned frame_counter;
46 static FLAC__FileDecoder *decoder;
47 static bool is_big_endian_host;
50 static bool init(const char *infile, stream_info_struct *stream_info);
51 static bool write_little_endian_uint16(FILE *f, uint16 val);
52 static bool write_little_endian_uint32(FILE *f, uint32 val);
53 static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__FileDecoder *decoder, const FLAC__FrameHeader *header, const int32 *buffer[], void *client_data);
54 static void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data);
55 static void error_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
56 static void print_stats(const stream_info_struct *stream_info);
58 int decode_wav(const char *infile, const char *outfile, bool verbose, uint64 skip)
60 stream_info_struct stream_info;
63 stream_info.abort_flag = false;
64 stream_info.is_wave_out = true;
65 stream_info.verbose = verbose;
66 stream_info.skip = skip;
67 stream_info.samples_processed = 0;
68 stream_info.frame_counter = 0;
70 if(0 == strcmp(outfile, "-")) {
71 stream_info.fout = stdout;
74 if(0 == (stream_info.fout = fopen(outfile, "wb"))) {
75 fprintf(stderr, "ERROR: can't open output file %s\n", outfile);
80 if(!init(infile, &stream_info))
84 if(!FLAC__file_decoder_process_metadata(decoder)) {
85 fprintf(stderr, "ERROR during decoding\n");
88 if(!FLAC__file_decoder_seek_absolute(decoder, skip)) {
89 fprintf(stderr, "ERROR seeking while skipping bytes in input file %s\n", infile);
92 if(!FLAC__file_decoder_process_remaining_frames(decoder)) {
93 fprintf(stderr, "ERROR during decodingg\n");
96 if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
97 fprintf(stderr, "ERROR during decodinggg\n");
102 if(!FLAC__file_decoder_process_whole_file(decoder)) {
103 fprintf(stderr, "ERROR during decoding\n");
106 if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
107 fprintf(stderr, "ERROR during decodingg, state=%u\n", decoder->state);
113 if(decoder->state != FLAC__FILE_DECODER_UNINITIALIZED)
114 FLAC__file_decoder_finish(decoder);
115 print_stats(&stream_info);
116 FLAC__file_decoder_free_instance(decoder);
118 fclose(stream_info.fout);
124 if(decoder->state != FLAC__FILE_DECODER_UNINITIALIZED)
125 FLAC__file_decoder_finish(decoder);
126 FLAC__file_decoder_free_instance(decoder);
128 fclose(stream_info.fout);
133 int decode_raw(const char *infile, const char *outfile, bool verbose, uint64 skip, bool is_big_endian, bool is_unsigned_samples)
135 stream_info_struct stream_info;
138 stream_info.abort_flag = false;
139 stream_info.is_wave_out = false;
140 stream_info.is_big_endian = is_big_endian;
141 stream_info.is_unsigned_samples = is_unsigned_samples;
142 stream_info.verbose = verbose;
143 stream_info.skip = skip;
144 stream_info.samples_processed = 0;
145 stream_info.frame_counter = 0;
147 if(0 == strcmp(outfile, "-")) {
148 stream_info.fout = stdout;
151 if(0 == (stream_info.fout = fopen(outfile, "wb"))) {
152 fprintf(stderr, "ERROR: can't open output file %s\n", outfile);
157 if(!init(infile, &stream_info))
161 if(!FLAC__file_decoder_process_metadata(decoder)) {
162 fprintf(stderr, "ERROR during decoding\n");
165 if(!FLAC__file_decoder_seek_absolute(decoder, skip)) {
166 fprintf(stderr, "ERROR seeking while skipping bytes in input file %s\n", infile);
169 if(!FLAC__file_decoder_process_remaining_frames(decoder)) {
170 fprintf(stderr, "ERROR during decodingg\n");
173 if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
174 fprintf(stderr, "ERROR during decodinggg\n");
179 if(!FLAC__file_decoder_process_whole_file(decoder)) {
180 fprintf(stderr, "ERROR during decoding\n");
183 if(decoder->state != FLAC__FILE_DECODER_OK && decoder->state != FLAC__FILE_DECODER_END_OF_FILE) {
184 fprintf(stderr, "ERROR during decodingg\n");
190 if(decoder->state != FLAC__FILE_DECODER_UNINITIALIZED)
191 FLAC__file_decoder_finish(decoder);
192 print_stats(&stream_info);
193 FLAC__file_decoder_free_instance(decoder);
195 fclose(stream_info.fout);
201 if(decoder->state != FLAC__FILE_DECODER_UNINITIALIZED)
202 FLAC__file_decoder_finish(decoder);
203 FLAC__file_decoder_free_instance(decoder);
205 fclose(stream_info.fout);
210 bool init(const char *infile, stream_info_struct *stream_info)
214 is_big_endian_host = (*((byte*)(&test)))? false : true;
216 decoder = FLAC__file_decoder_get_new_instance();
218 fprintf(stderr, "ERROR creating the decoder instance\n");
222 if(FLAC__file_decoder_init(decoder, infile, write_callback, metadata_callback, error_callback, stream_info) != FLAC__FILE_DECODER_OK) {
223 fprintf(stderr, "ERROR initializing decoder, state = %d\n", decoder->state);
230 bool write_little_endian_uint16(FILE *f, uint16 val)
232 byte *b = (byte*)(&val);
233 if(is_big_endian_host) {
235 tmp = b[1]; b[1] = b[0]; b[0] = tmp;
237 return fwrite(b, 1, 2, f) == 2;
240 bool write_little_endian_uint32(FILE *f, uint32 val)
242 byte *b = (byte*)(&val);
243 if(is_big_endian_host) {
245 tmp = b[3]; b[3] = b[0]; b[0] = tmp;
246 tmp = b[2]; b[2] = b[1]; b[1] = tmp;
248 return fwrite(b, 1, 4, f) == 4;
251 FLAC__StreamDecoderWriteStatus write_callback(const FLAC__FileDecoder *decoder, const FLAC__FrameHeader *header, const int32 *buffer[], void *client_data)
253 stream_info_struct *stream_info = (stream_info_struct *)client_data;
254 FILE *fout = stream_info->fout;
255 unsigned bps = stream_info->bps, channels = stream_info->channels;
256 bool is_big_endian = (stream_info->is_wave_out? false : stream_info->is_big_endian);
257 bool is_unsigned_samples = (stream_info->is_wave_out? bps==8 : stream_info->is_unsigned_samples);
258 unsigned wide_samples = header->blocksize, wide_sample, sample, channel, byte;
259 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 */
260 unsigned char *ucbuffer = (unsigned char *)scbuffer;
261 signed short *ssbuffer = (signed short *)scbuffer;
262 unsigned short *usbuffer = (unsigned short *)scbuffer;
266 if(stream_info->abort_flag)
267 return FLAC__STREAM_DECODER_WRITE_ABORT;
269 stream_info->samples_processed += wide_samples;
270 stream_info->frame_counter++;
272 if(stream_info->verbose && !(stream_info->frame_counter & 0x1f))
273 print_stats(stream_info);
276 if(is_unsigned_samples) {
277 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
278 for(channel = 0; channel < channels; channel++, sample++)
279 ucbuffer[sample] = buffer[channel][wide_sample] + 128;
282 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
283 for(channel = 0; channel < channels; channel++, sample++)
284 scbuffer[sample] = buffer[channel][wide_sample];
286 if(fwrite(ucbuffer, 1, sample, fout) != sample)
287 return FLAC__STREAM_DECODER_WRITE_ABORT;
289 else { /* bps == 16 */
290 if(is_unsigned_samples) {
291 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
292 for(channel = 0; channel < channels; channel++, sample++)
293 usbuffer[sample] = buffer[channel][wide_sample] + 32768;
296 for(sample = wide_sample = 0; wide_sample < wide_samples; wide_sample++)
297 for(channel = 0; channel < channels; channel++, sample++)
298 ssbuffer[sample] = buffer[channel][wide_sample];
300 if(is_big_endian != is_big_endian_host) {
302 for(byte = 0; byte < sample<<1; byte += 2) {
303 tmp = ucbuffer[byte];
304 ucbuffer[byte] = ucbuffer[byte+1];
305 ucbuffer[byte+1] = tmp;
308 if(fwrite(usbuffer, 2, sample, fout) != sample)
309 return FLAC__STREAM_DECODER_WRITE_ABORT;
311 return FLAC__STREAM_DECODER_WRITE_CONTINUE;
314 void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data)
316 stream_info_struct *stream_info = (stream_info_struct *)client_data;
318 if(metadata->type == FLAC__METADATA_TYPE_ENCODING) {
319 stream_info->total_samples = metadata->data.encoding.total_samples - stream_info->skip;
320 stream_info->bps = metadata->data.encoding.bits_per_sample;
321 stream_info->channels = metadata->data.encoding.channels;
322 stream_info->sample_rate = metadata->data.encoding.sample_rate;
324 if(stream_info->bps != 8 && stream_info->bps != 16) {
325 fprintf(stderr, "ERROR: bits per sample is not 8 or 16\n");
326 stream_info->abort_flag = true;
330 /* write the WAVE headers if necessary */
331 if(stream_info->is_wave_out) {
332 uint64 data_size = stream_info->total_samples * stream_info->channels * ((stream_info->bps+7)/8);
333 if(data_size >= 0xFFFFFFDC) {
334 fprintf(stderr, "ERROR: stream is too big for a wave file\n");
335 stream_info->abort_flag = true;
338 if(fwrite("RIFF", 1, 4, stream_info->fout) != 4) stream_info->abort_flag = true;
339 if(!write_little_endian_uint32(stream_info->fout, (uint32)(data_size+36))) stream_info->abort_flag = true; /* filesize-8 */
340 if(fwrite("WAVEfmt ", 1, 8, stream_info->fout) != 8) stream_info->abort_flag = true;
341 if(fwrite("\020\000\000\000", 1, 4, stream_info->fout) != 4) stream_info->abort_flag = true; /* chunk size = 16 */
342 if(fwrite("\001\000", 1, 2, stream_info->fout) != 2) stream_info->abort_flag = true; /* compression code == 1 */
343 if(!write_little_endian_uint16(stream_info->fout, (uint16)(stream_info->channels))) stream_info->abort_flag = true;
344 if(!write_little_endian_uint32(stream_info->fout, stream_info->sample_rate)) stream_info->abort_flag = true;
345 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 ??? */
346 if(!write_little_endian_uint16(stream_info->fout, (uint16)(stream_info->channels * ((stream_info->bps+7) / 8)))) stream_info->abort_flag = true; /* block align */
347 if(!write_little_endian_uint16(stream_info->fout, (uint16)(stream_info->bps))) stream_info->abort_flag = true; /* bits per sample */
348 if(fwrite("data", 1, 4, stream_info->fout) != 4) stream_info->abort_flag = true;
349 if(!write_little_endian_uint32(stream_info->fout, (uint32)data_size)) stream_info->abort_flag = true; /* data size */
354 void error_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
356 stream_info_struct *stream_info = (stream_info_struct *)client_data;
358 fprintf(stderr, "*** Got error code %d\n", status);
359 stream_info->abort_flag = true;
362 void print_stats(const stream_info_struct *stream_info)
364 if(stream_info->verbose) {
365 printf("\rwrote %u of %u samples, %6.2f%% complete",
366 (unsigned)stream_info->samples_processed,
367 (unsigned)stream_info->total_samples,
369 /* with VC++ you have to spoon feed it the casting */
370 (double)(int64)stream_info->samples_processed / (double)(int64)stream_info->total_samples * 100.0
372 (double)stream_info->samples_processed / (double)stream_info->total_samples * 100.0