1 /* flac - Command-line FLAC encoder/decoder
2 * Copyright (C) 2000,2001,2002 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.
24 #if !defined _MSC_VER && !defined __MINGW32__
25 /* unlink is in stdio.h in VC++ */
26 #include <unistd.h> /* for unlink() */
28 #define strcasecmp stricmp
36 static int short_usage(const char *message, ...);
37 static int long_usage(const char *message, ...);
38 static int encode_file(const char *infilename, const char *forced_outfilename, FLAC__bool is_last_file);
39 static int decode_file(const char *infilename, const char *forced_outfilename);
41 FLAC__bool verify = false, verbose = true, continue_through_decode_errors = false, lax = false, test_only = false, analyze = false, use_ogg = false;
42 FLAC__bool do_mid_side = true, loose_mid_side = false, do_exhaustive_model_search = false, do_escape_coding = false, do_qlp_coeff_prec_search = false;
43 FLAC__bool force_to_stdout = false, force_raw_format = false, delete_input = false, sector_align = false;
44 const char *cmdline_forced_outfilename = 0, *output_prefix = 0;
45 analysis_options aopts = { false, false };
47 unsigned max_lpc_order = 8;
48 unsigned qlp_coeff_precision = 0;
49 FLAC__uint64 skip = 0;
50 int format_is_big_endian = -1, format_is_unsigned_samples = false;
51 int format_channels = -1, format_bps = -1, format_sample_rate = -1;
52 int blocksize = -1, min_residual_partition_order = -1, max_residual_partition_order = -1, rice_parameter_search_dist = -1;
53 char requested_seek_points[50000]; /* @@@ bad MAGIC NUMBER */
54 int num_requested_seek_points = -1; /* -1 => no -S options were given, 0 => -S- was given */
55 FLAC__int32 align_reservoir_0[588], align_reservoir_1[588]; /* for carrying over samples from --sector-align */
56 FLAC__int32 *align_reservoir[2] = { align_reservoir_0, align_reservoir_1 };
57 unsigned align_reservoir_samples = 0; /* 0 .. 587 */
59 static const char *flac_suffix = ".flac", *ogg_suffix = ".ogg";
61 int main(int argc, char *argv[])
64 FLAC__bool mode_decode = false;
67 return short_usage(0);
70 for(i = 1; i < argc; i++) {
71 if(argv[i][0] != '-' || argv[i][1] == 0)
73 if(0 == strcmp(argv[i], "-H") || 0 == strcmp(argv[i], "--help"))
75 else if(0 == strcmp(argv[i], "-d"))
77 else if(0 == strcmp(argv[i], "-a")) {
81 else if(0 == strcmp(argv[i], "-t")) {
85 else if(0 == strcmp(argv[i], "-c"))
86 force_to_stdout = true;
87 else if(0 == strcmp(argv[i], "-F"))
88 continue_through_decode_errors = true;
89 else if(0 == strcmp(argv[i], "-F-"))
90 continue_through_decode_errors = false;
91 else if(0 == strcmp(argv[i], "-s"))
93 else if(0 == strcmp(argv[i], "-s-"))
95 else if(0 == strcmp(argv[i], "-S")) {
97 return long_usage("ERROR: must specify a value with -S\n");
98 if(num_requested_seek_points < 0)
99 num_requested_seek_points = 0;
100 num_requested_seek_points++;
101 strcat(requested_seek_points, argv[i]);
102 strcat(requested_seek_points, "<");
104 else if(0 == strcmp(argv[i], "-S-")) {
105 num_requested_seek_points = 0;
106 requested_seek_points[0] = '\0';
108 else if(0 == strcmp(argv[i], "--delete-input-file"))
110 else if(0 == strcmp(argv[i], "--delete-input-file-"))
111 delete_input = false;
112 else if(0 == strcmp(argv[i], "--output-prefix")) {
114 return long_usage("ERROR: must specify a value with --output-prefix\n");
115 output_prefix = argv[i];
117 else if(0 == strcmp(argv[i], "--sector-align"))
119 else if(0 == strcmp(argv[i], "--sector-align-"))
120 sector_align = false;
121 else if(0 == strcmp(argv[i], "--skip")) {
123 return long_usage("ERROR: must specify a value with --skip\n");
124 skip = (FLAC__uint64)atoi(argv[i]); /* @@@ takes a pretty damn big file to overflow atoi() here, but it could happen */
126 else if(0 == strcmp(argv[i], "--lax"))
128 else if(0 == strcmp(argv[i], "--lax-"))
131 else if(0 == strcmp(argv[i], "--ogg"))
133 else if(0 == strcmp(argv[i], "--ogg-"))
136 else if(0 == strcmp(argv[i], "-b")) {
138 return long_usage("ERROR: must specify a value with -b\n");
139 blocksize = atoi(argv[i]);
141 else if(0 == strcmp(argv[i], "-e"))
142 do_exhaustive_model_search = true;
143 else if(0 == strcmp(argv[i], "-e-"))
144 do_exhaustive_model_search = false;
145 else if(0 == strcmp(argv[i], "-E"))
146 do_escape_coding = true;
147 else if(0 == strcmp(argv[i], "-E-"))
148 do_escape_coding = false;
149 else if(0 == strcmp(argv[i], "-l")) {
151 return long_usage("ERROR: must specify a value with -l\n");
152 max_lpc_order = atoi(argv[i]);
154 else if(0 == strcmp(argv[i], "-m")) {
156 loose_mid_side = false;
158 else if(0 == strcmp(argv[i], "-m-"))
159 do_mid_side = loose_mid_side = false;
160 else if(0 == strcmp(argv[i], "-M"))
161 loose_mid_side = do_mid_side = true;
162 else if(0 == strcmp(argv[i], "-M-"))
163 loose_mid_side = do_mid_side = false;
164 else if(0 == strcmp(argv[i], "-o")) {
166 return long_usage("ERROR: must specify a value with -o\n");
167 cmdline_forced_outfilename = argv[i];
169 else if(0 == strcmp(argv[i], "-p"))
170 do_qlp_coeff_prec_search = true;
171 else if(0 == strcmp(argv[i], "-p-"))
172 do_qlp_coeff_prec_search = false;
173 else if(0 == strcmp(argv[i], "-P")) {
175 return long_usage("ERROR: must specify a value with -P\n");
176 padding = atoi(argv[i]);
178 return long_usage("ERROR: argument to -P must be >= 0\n");
180 else if(0 == strcmp(argv[i], "-P-"))
182 else if(0 == strcmp(argv[i], "-q")) {
184 return long_usage("ERROR: must specify a value with -q\n");
185 qlp_coeff_precision = atoi(argv[i]);
187 else if(0 == strcmp(argv[i], "-r")) {
190 return long_usage("ERROR: must specify a value with -r\n");
191 p = strchr(argv[i], ',');
193 min_residual_partition_order = 0;
194 max_residual_partition_order = atoi(argv[i]);
197 min_residual_partition_order = atoi(argv[i]);
198 max_residual_partition_order = atoi(++p);
201 else if(0 == strcmp(argv[i], "--old-unworking-do-not-use-R")) {
203 return long_usage("ERROR: must specify a value with -R\n");
204 rice_parameter_search_dist = atoi(argv[i]);
206 else if(0 == strcmp(argv[i], "-V"))
208 else if(0 == strcmp(argv[i], "-V-"))
210 else if(0 == strcmp(argv[i], "-fb"))
211 format_is_big_endian = true;
212 else if(0 == strcmp(argv[i], "-fl"))
213 format_is_big_endian = false;
214 else if(0 == strcmp(argv[i], "-fc")) {
216 return long_usage("ERROR: must specify a value with -fc\n");
217 format_channels = atoi(argv[i]);
219 else if(0 == strcmp(argv[i], "-fp")) {
221 return long_usage("ERROR: must specify a value with -fp\n");
222 format_bps = atoi(argv[i]);
224 else if(0 == strcmp(argv[i], "-fs")) {
226 return long_usage("ERROR: must specify a value with -fs\n");
227 format_sample_rate = atoi(argv[i]);
229 else if(0 == strcmp(argv[i], "-fu"))
230 format_is_unsigned_samples = true;
231 else if(0 == strcmp(argv[i], "-fr"))
232 force_raw_format = true;
233 else if(0 == strcmp(argv[i], "--a-rgp"))
234 aopts.do_residual_gnuplot = true;
235 else if(0 == strcmp(argv[i], "--a-rgp-"))
236 aopts.do_residual_gnuplot = false;
237 else if(0 == strcmp(argv[i], "--a-rtext"))
238 aopts.do_residual_text = true;
239 else if(0 == strcmp(argv[i], "--a-rtext-"))
240 aopts.do_residual_text = false;
241 else if(0 == strcmp(argv[i], "-0") || 0 == strcmp(argv[i], "--fast")) {
242 do_exhaustive_model_search = false;
243 do_escape_coding = false;
245 loose_mid_side = false;
246 qlp_coeff_precision = 0;
247 min_residual_partition_order = max_residual_partition_order = 2;
248 rice_parameter_search_dist = 0;
251 else if(0 == strcmp(argv[i], "-1")) {
252 do_exhaustive_model_search = false;
253 do_escape_coding = false;
255 loose_mid_side = true;
256 qlp_coeff_precision = 0;
257 min_residual_partition_order = max_residual_partition_order = 2;
258 rice_parameter_search_dist = 0;
261 else if(0 == strcmp(argv[i], "-2")) {
262 do_exhaustive_model_search = false;
263 do_escape_coding = false;
265 loose_mid_side = false;
266 qlp_coeff_precision = 0;
267 min_residual_partition_order = 0;
268 max_residual_partition_order = 3;
269 rice_parameter_search_dist = 0;
272 else if(0 == strcmp(argv[i], "-3")) {
273 do_exhaustive_model_search = false;
274 do_escape_coding = false;
276 loose_mid_side = false;
277 qlp_coeff_precision = 0;
278 min_residual_partition_order = max_residual_partition_order = 3;
279 rice_parameter_search_dist = 0;
282 else if(0 == strcmp(argv[i], "-4")) {
283 do_exhaustive_model_search = false;
284 do_escape_coding = false;
286 loose_mid_side = true;
287 qlp_coeff_precision = 0;
288 min_residual_partition_order = max_residual_partition_order = 3;
289 rice_parameter_search_dist = 0;
292 else if(0 == strcmp(argv[i], "-5")) {
293 do_exhaustive_model_search = false;
294 do_escape_coding = false;
296 loose_mid_side = false;
297 qlp_coeff_precision = 0;
298 min_residual_partition_order = max_residual_partition_order = 3;
299 rice_parameter_search_dist = 0;
302 else if(0 == strcmp(argv[i], "-6")) {
303 do_exhaustive_model_search = false;
304 do_escape_coding = false;
306 loose_mid_side = false;
307 qlp_coeff_precision = 0;
308 min_residual_partition_order = 0;
309 max_residual_partition_order = 4;
310 rice_parameter_search_dist = 0;
313 else if(0 == strcmp(argv[i], "-7")) {
314 do_exhaustive_model_search = true;
315 do_escape_coding = false;
317 loose_mid_side = false;
318 qlp_coeff_precision = 0;
319 min_residual_partition_order = 0;
320 max_residual_partition_order = 6;
321 rice_parameter_search_dist = 0;
324 else if(0 == strcmp(argv[i], "-8") || 0 == strcmp(argv[i], "--best")) {
325 do_exhaustive_model_search = true;
326 do_escape_coding = false;
328 loose_mid_side = false;
329 qlp_coeff_precision = 0;
330 min_residual_partition_order = 0;
331 max_residual_partition_order = 6;
332 rice_parameter_search_dist = 0;
335 else if(0 == strcmp(argv[i], "--super-secret-impractical-compression-level")) {
336 do_exhaustive_model_search = true;
337 do_escape_coding = true;
339 loose_mid_side = false;
340 do_qlp_coeff_prec_search = true;
341 min_residual_partition_order = 0;
342 max_residual_partition_order = 16;
343 rice_parameter_search_dist = 0;
346 else if(isdigit((int)(argv[i][1]))) {
347 return long_usage("ERROR: compression level '%s' is reserved\n", argv[i]);
350 return long_usage("ERROR: invalid option '%s'\n", argv[i]);
354 /* tweak options; validate the values */
357 if(max_lpc_order == 0)
362 if(max_residual_partition_order < 0) {
363 if(blocksize <= 1152)
364 max_residual_partition_order = 2;
365 else if(blocksize <= 2304)
366 max_residual_partition_order = 3;
367 else if(blocksize <= 4608)
368 max_residual_partition_order = 3;
370 max_residual_partition_order = 4;
371 min_residual_partition_order = max_residual_partition_order;
373 if(rice_parameter_search_dist < 0) {
374 rice_parameter_search_dist = 0;
380 return long_usage("ERROR: --skip is not allowed in test mode\n");
384 FLAC__ASSERT(blocksize >= 0 || mode_decode);
386 if(format_channels >= 0) {
387 if(format_channels == 0 || (unsigned)format_channels > FLAC__MAX_CHANNELS)
388 return long_usage("ERROR: invalid number of channels '%u', must be > 0 and <= %u\n", format_channels, FLAC__MAX_CHANNELS);
390 if(format_bps >= 0) {
391 if(format_bps != 8 && format_bps != 16 && format_bps != 24)
392 return long_usage("ERROR: invalid bits per sample '%u' (must be 8/16/24)\n", format_bps);
394 if(format_sample_rate >= 0) {
395 if(!FLAC__format_is_valid_sample_rate(format_sample_rate))
396 return long_usage("ERROR: invalid sample rate '%u', must be > 0 and <= %u\n", format_sample_rate, FLAC__MAX_SAMPLE_RATE);
398 if(!mode_decode && ((unsigned)blocksize < FLAC__MIN_BLOCK_SIZE || (unsigned)blocksize > FLAC__MAX_BLOCK_SIZE)) {
399 return long_usage("ERROR: invalid blocksize '%u', must be >= %u and <= %u\n", (unsigned)blocksize, FLAC__MIN_BLOCK_SIZE, FLAC__MAX_BLOCK_SIZE);
401 if(qlp_coeff_precision > 0 && qlp_coeff_precision < FLAC__MIN_QLP_COEFF_PRECISION) {
402 return long_usage("ERROR: invalid value for -q '%u', must be 0 or >= %u\n", qlp_coeff_precision, FLAC__MIN_QLP_COEFF_PRECISION);
407 return long_usage("ERROR: --sector-align only allowed for encoding\n");
409 return long_usage("ERROR: --sector-align not allowed with --skip\n");
410 else if(format_channels >= 0 && format_channels != 2)
411 return long_usage("ERROR: --sector-align can only be done with stereo input\n");
412 else if(format_sample_rate >= 0 && format_sample_rate != 2)
413 return long_usage("ERROR: --sector-align can only be done with sample rate of 44100\n");
415 if(argc - i > 1 && cmdline_forced_outfilename) {
416 return long_usage("ERROR: -o cannot be used with multiple files\n");
418 if(cmdline_forced_outfilename && output_prefix) {
419 return long_usage("ERROR: --output-prefix conflicts with -o\n");
423 fprintf(stderr, "\n");
424 fprintf(stderr, "flac %s, Copyright (C) 2000,2001,2002 Josh Coalson\n", FLAC__VERSION_STRING);
425 fprintf(stderr, "flac comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n");
426 fprintf(stderr, "welcome to redistribute it under certain conditions. Type `flac' for details.\n\n");
433 sprintf(padopt, " %d", padding);
439 "%s -P%s -b %u%s -l %u%s%s%s -q %u -r %u,%u -R %u%s\n",
440 delete_input?" --delete-input-file":"", sector_align?" --sector-align":"",
445 padopt, (unsigned)blocksize, loose_mid_side?" -M":do_mid_side?" -m":"", max_lpc_order,
446 do_exhaustive_model_search?" -e":"", do_escape_coding?" -E":"", do_qlp_coeff_prec_search?" -p":"",
448 (unsigned)min_residual_partition_order, (unsigned)max_residual_partition_order, (unsigned)rice_parameter_search_dist,
455 FLAC__bool first = true;
458 retval = decode_file("-", 0);
462 cmdline_forced_outfilename = 0;
463 for(retval = 0; i < argc && retval == 0; i++) {
464 if(0 == strcmp(argv[i], "-") && !first)
466 retval = decode_file(argv[i], 0);
472 FLAC__bool first = true;
475 retval = encode_file("-", 0, true);
479 cmdline_forced_outfilename = 0;
480 for(retval = 0; i < argc && retval == 0; i++) {
481 if(0 == strcmp(argv[i], "-") && !first)
483 retval = encode_file(argv[i], 0, i == (argc-1));
492 static void usage_header()
494 fprintf(stderr, "===============================================================================\n");
495 fprintf(stderr, "flac - Command-line FLAC encoder/decoder version %s\n", FLAC__VERSION_STRING);
496 fprintf(stderr, "Copyright (C) 2000,2001,2002 Josh Coalson\n");
497 fprintf(stderr, "\n");
498 fprintf(stderr, "This program is free software; you can redistribute it and/or\n");
499 fprintf(stderr, "modify it under the terms of the GNU General Public License\n");
500 fprintf(stderr, "as published by the Free Software Foundation; either version 2\n");
501 fprintf(stderr, "of the License, or (at your option) any later version.\n");
502 fprintf(stderr, "\n");
503 fprintf(stderr, "This program is distributed in the hope that it will be useful,\n");
504 fprintf(stderr, "but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
505 fprintf(stderr, "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
506 fprintf(stderr, "GNU General Public License for more details.\n");
507 fprintf(stderr, "\n");
508 fprintf(stderr, "You should have received a copy of the GNU General Public License\n");
509 fprintf(stderr, "along with this program; if not, write to the Free Software\n");
510 fprintf(stderr, "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n");
511 fprintf(stderr, "===============================================================================\n");
514 int short_usage(const char *message, ...)
519 va_start(args, message);
521 (void) vfprintf(stderr, message, args);
527 fprintf(stderr, "\n");
528 fprintf(stderr, "This is the short help; for full help use 'flac --help'\n");
529 fprintf(stderr, "\n");
530 fprintf(stderr, "To encode:\n");
531 fprintf(stderr, " flac [-#] [infile [...]]\n");
532 fprintf(stderr, "\n");
533 fprintf(stderr, " -# is -0 (fastest compression) to -8 (highest compression); -5 is the default\n");
534 fprintf(stderr, "\n");
535 fprintf(stderr, "To decode:\n");
536 fprintf(stderr, " flac -d [infile [...]]\n");
537 fprintf(stderr, "\n");
538 fprintf(stderr, "To test:\n");
539 fprintf(stderr, " flac -t [infile [...]]\n");
541 return message? 1 : 0;
544 int long_usage(const char *message, ...)
546 FILE *out = (message? stderr : stdout);
550 va_start(args, message);
552 (void) vfprintf(stderr, message, args);
558 fprintf(out, "Usage:\n");
559 fprintf(out, " flac [options] [infile [...]]\n");
561 fprintf(out, "For encoding:\n");
562 fprintf(out, " the input file(s) may be a PCM RIFF WAVE file or raw samples\n");
563 fprintf(out, " the output file(s) will be in FLAC format\n");
564 fprintf(out, "For decoding, the reverse is true\n");
566 fprintf(out, "A single 'infile' may be - for stdin. No 'infile' implies stdin. Use of\n");
567 fprintf(out, "stdin implies -c (write to stdout). Normally you should use:\n");
568 fprintf(out, " flac [options] -o outfilename or flac -d [options] -o outfilename\n");
569 fprintf(out, "instead of:\n");
570 fprintf(out, " flac [options] > outfilename or flac -d [options] > outfilename\n");
571 fprintf(out, "since the former allows flac to seek backwards to write the STREAMINFO or\n");
572 fprintf(out, "RIFF WAVE header contents when necessary.\n");
574 fprintf(out, "flac checks for the presence of a RIFF WAVE header to decide whether or not\n");
575 fprintf(out, "to treat an input file as WAVE format or raw samples. If any infile is raw\n");
576 fprintf(out, "you must specify the format options {-fb|fl} -fc -fp and -fs, which will\n");
577 fprintf(out, "apply to all raw files. You can force WAVE files to be treated as a raw files\n");
578 fprintf(out, "using -fr.\n");
580 fprintf(out, "generic options:\n");
581 fprintf(out, " -d : decode (default behavior is encode)\n");
582 fprintf(out, " -t : test (same as -d except no decoded file is written)\n");
583 fprintf(out, " -a : analyze (same as -d except an analysis file is written)\n");
584 fprintf(out, " -c : write output to stdout\n");
585 fprintf(out, " -s : silent (do not write runtime encode/decode statistics)\n");
586 fprintf(out, " -o filename : force the output file name (usually flac just changes the\n");
587 fprintf(out, " extension)\n");
588 fprintf(out, " --output-prefix string : prefix each output file name with the given string.\n");
589 fprintf(out, " This can be useful for encoding/decoding files to a different directory.\n");
590 fprintf(out, " Make sure if your string is a path name that it ends with a '/' slash.\n");
591 fprintf(out, " --delete-input-file : deletes the input file after a successful encode/decode\n");
592 fprintf(out, " --skip samples : can be used both for encoding and decoding\n");
593 fprintf(out, "analyze options:\n");
594 fprintf(out, " --a-rtext : include residual signal in text output\n");
595 fprintf(out, " --a-rgp : generate gnuplot files of residual distribution of each subframe\n");
596 fprintf(out, "decoding options:\n");
597 fprintf(out, " -F : force decoder to continue decoding through stream errors\n");
598 fprintf(out, "encoding options:\n");
600 fprintf(out, " --ogg : output Ogg-FLAC stream instead of native FLAC\n");
602 fprintf(out, " --lax : allow encoder to generate non-Subset files\n");
603 fprintf(out, " --sector-align : align encoding of multiple files on sector boundaries\n");
604 fprintf(out, " -S { # | X | #x } : include a point or points in a SEEKTABLE\n");
605 fprintf(out, " # : a specific sample number for a seek point\n");
606 fprintf(out, " X : a placeholder point (always goes at the end of the SEEKTABLE)\n");
607 fprintf(out, " #x : # evenly spaced seekpoints, the first being at sample 0\n");
608 fprintf(out, " You may use many -S options; the resulting SEEKTABLE will be the unique-\n");
609 fprintf(out, " ified union of all such values.\n");
610 fprintf(out, " With no -S options, flac defaults to '-S 100x'. Use -S- for no SEEKTABLE.\n");
611 fprintf(out, " Note: -S #x will not work if the encoder can't determine the input size\n");
612 fprintf(out, " before starting.\n");
613 fprintf(out, " Note: if you use -S # and # is >= samples in the input, there will be\n");
614 fprintf(out, " either no seek point entered (if the input size is determinable\n");
615 fprintf(out, " before encoding starts) or a placeholder point (if input size is not\n");
616 fprintf(out, " determinable)\n");
617 fprintf(out, " -P # : write a PADDING block of length # (goes after SEEKTABLE)\n");
618 fprintf(out, " (# must be >= 0; default is -P-). Note that the overall size in bytes\n");
619 fprintf(out, " of the PADDING block will be # + 4 because of the metadata header.\n");
620 fprintf(out, " -b # : specify blocksize in samples; default is 1152 for -l 0, else 4608;\n");
621 fprintf(out, " must be 192/576/1152/2304/4608/256/512/1024/2048/4096/8192/16384/32768\n");
622 fprintf(out, " (unless --lax is used)\n");
623 fprintf(out, " -m : try mid-side coding for each frame (stereo input only)\n");
624 fprintf(out, " -M : adaptive mid-side coding for all frames (stereo input only)\n");
625 fprintf(out, " -0 .. -8 : fastest compression .. highest compression, default is -5\n");
626 fprintf(out, " these are synonyms for other options:\n");
627 fprintf(out, " -0 : synonymous with -l 0 -b 1152 -r 2,2\n");
628 fprintf(out, " -1 : synonymous with -l 0 -b 1152 -M -r 2,2\n");
629 fprintf(out, " -2 : synonymous with -l 0 -b 1152 -m -r 3\n");
630 fprintf(out, " -3 : synonymous with -l 6 -b 4608 -r 3,3\n");
631 fprintf(out, " -4 : synonymous with -l 8 -b 4608 -M -r 3,3\n");
632 fprintf(out, " -5 : synonymous with -l 8 -b 4608 -m -r 3,3\n");
633 fprintf(out, " -6 : synonymous with -l 8 -b 4608 -m -r 4\n");
634 fprintf(out, " -7 : synonymous with -l 8 -b 4608 -m -e -r 6\n");
635 fprintf(out, " -8 : synonymous with -l 12 -b 4608 -m -e -r 6\n");
636 fprintf(out, " --fast, --best : synonymous with -0 and -8 respectively\n");
637 fprintf(out, " -e : do exhaustive model search (expensive!)\n");
638 fprintf(out, " -E : include escape coding in the entropy coder\n");
639 fprintf(out, " -l # : specify max LPC order; 0 => use only fixed predictors\n");
640 fprintf(out, " -p : do exhaustive search of LP coefficient quantization (expensive!);\n");
641 fprintf(out, " overrides -q, does nothing if using -l 0\n");
642 fprintf(out, " -q # : specify precision in bits of quantized linear-predictor coefficients;\n");
643 fprintf(out, " 0 => let encoder decide (min is %u, default is -q 0)\n", FLAC__MIN_QLP_COEFF_PRECISION);
644 fprintf(out, " -r [#,]# : [min,]max residual partition order (# is 0..16; min defaults to 0;\n");
645 fprintf(out, " default is -r 0; above 4 doesn't usually help much)\n");
647 @@@ removed because it doesnt work yet and is too dangerous for users
648 fprintf(out, " -R # : Rice parameter search distance (# is 0..32; above 2 doesn't help much)\n");
650 fprintf(out, " -V : verify a correct encoding by decoding the output in parallel and\n");
651 fprintf(out, " comparing to the original\n");
652 fprintf(out, " -S-, -P-, -m-, -M-, -e-, -E-, -p-, -V-, --delete-input-file-,%s --lax-,\n",
659 fprintf(out, " --sector-align- can all be used to turn off a particular option\n");
660 fprintf(out, "format options:\n");
661 fprintf(out, " -fb | -fl : big-endian | little-endian byte order\n");
662 fprintf(out, " -fc channels\n");
663 fprintf(out, " -fp bits_per_sample\n");
664 fprintf(out, " -fs sample_rate : in Hz\n");
665 fprintf(out, " -fu : unsigned samples (default is signed)\n");
666 fprintf(out, " -fr : force input to be treated as raw samples\n");
668 return message? 1 : 0;
671 int encode_file(const char *infilename, const char *forced_outfilename, FLAC__bool is_last_file)
674 char outfilename[4096]; /* @@@ bad MAGIC NUMBER */
676 FLAC__byte lookahead[12];
677 unsigned lookahead_length = 0;
678 FLAC__bool treat_as_wave = false;
681 encode_options_t common_options;
683 if(0 == strcmp(infilename, "-")) {
685 encode_infile = file__get_binary_stdin();
688 infilesize = flac__file_get_filesize(infilename);
689 if(0 == (encode_infile = fopen(infilename, "rb"))) {
690 fprintf(stderr, "ERROR: can't open input file %s\n", infilename);
695 if(!force_raw_format) {
696 /* first set format based on name */
697 if(0 == strcasecmp(infilename+(strlen(infilename)-4), ".wav"))
698 treat_as_wave = true;
700 treat_as_wave = false;
702 /* attempt to guess the file type based on the first 12 bytes */
703 if((lookahead_length = fread(lookahead, 1, 12, encode_infile)) < 12) {
705 fprintf(stderr, "WARNING: %s is not a WAVE file, treating as a raw file\n", infilename);
706 treat_as_wave = false;
709 if(strncmp(lookahead, "RIFF", 4) || strncmp(lookahead+8, "WAVE", 4)) {
711 fprintf(stderr, "WARNING: %s is not a WAVE file, treating as a raw file\n", infilename);
712 treat_as_wave = false;
715 treat_as_wave = true;
719 if(sector_align && !treat_as_wave && infilesize < 0) {
720 fprintf(stderr, "ERROR: can't --sector-align when the input size is unknown\n");
725 if(format_is_big_endian < 0 || format_channels < 0 || format_bps < 0 || format_sample_rate < 0)
726 return long_usage("ERROR: for encoding a raw file you must specify { -fb or -fl }, -fc, -fp, and -fs\n");
729 if(encode_infile == stdin || force_to_stdout)
730 strcpy(outfilename, "-");
732 const char *suffix = (use_ogg? ogg_suffix : flac_suffix);
733 strcpy(outfilename, output_prefix? output_prefix : "");
734 strcat(outfilename, infilename);
735 if(0 == (p = strrchr(outfilename, '.')))
736 strcat(outfilename, suffix);
738 if(0 == strcmp(p, suffix)) {
746 if(0 == forced_outfilename)
747 forced_outfilename = outfilename;
748 if(0 != cmdline_forced_outfilename)
749 forced_outfilename = cmdline_forced_outfilename;
751 common_options.verbose = verbose;
752 common_options.skip = skip;
753 common_options.verify = verify;
755 common_options.use_ogg = use_ogg;
757 common_options.lax = lax;
758 common_options.do_mid_side = do_mid_side;
759 common_options.loose_mid_side = loose_mid_side;
760 common_options.do_exhaustive_model_search = do_exhaustive_model_search;
761 common_options.do_escape_coding = do_escape_coding;
762 common_options.do_qlp_coeff_prec_search = do_qlp_coeff_prec_search;
763 common_options.min_residual_partition_order = min_residual_partition_order;
764 common_options.max_residual_partition_order = max_residual_partition_order;
765 common_options.rice_parameter_search_dist = rice_parameter_search_dist;
766 common_options.max_lpc_order = max_lpc_order;
767 common_options.blocksize = (unsigned)blocksize;
768 common_options.qlp_coeff_precision = qlp_coeff_precision;
769 common_options.padding = padding;
770 common_options.requested_seek_points = requested_seek_points;
771 common_options.num_requested_seek_points = num_requested_seek_points;
774 wav_encode_options_t options;
776 options.common = common_options;
777 options.is_last_file = is_last_file;
778 options.align_reservoir = align_reservoir;
779 options.align_reservoir_samples = &align_reservoir_samples;
780 options.sector_align = sector_align;
782 retval = flac__encode_wav(encode_infile, infilesize, infilename, forced_outfilename, lookahead, lookahead_length, options);
785 raw_encode_options_t options;
787 options.common = common_options;
788 options.is_big_endian = format_is_big_endian;
789 options.is_unsigned_samples = format_is_unsigned_samples;
790 options.channels = format_channels;
791 options.bps = format_bps;
792 options.sample_rate = format_sample_rate;
794 retval = flac__encode_raw(encode_infile, infilesize, infilename, forced_outfilename, lookahead, lookahead_length, options);
797 if(retval == 0 && strcmp(infilename, "-")) {
798 if(strcmp(forced_outfilename, "-"))
799 flac__file_copy_metadata(infilename, forced_outfilename);
807 int decode_file(const char *infilename, const char *forced_outfilename)
809 static const char *suffixes[] = { ".wav", ".raw", ".ana" };
810 char outfilename[4096]; /* @@@ bad MAGIC NUMBER */
813 FLAC__bool treat_as_ogg = false;
814 decode_options_t common_options;
816 if(!test_only && !analyze) {
817 if(force_raw_format && format_is_big_endian < 0)
818 return long_usage("ERROR: for decoding to a raw file you must specify -fb or -fl\n");
821 if(0 == strcmp(infilename, "-") || force_to_stdout)
822 strcpy(outfilename, "-");
824 const char *suffix = suffixes[analyze? 2 : force_raw_format? 1 : 0];
825 strcpy(outfilename, output_prefix? output_prefix : "");
826 strcat(outfilename, infilename);
827 if(0 == (p = strrchr(outfilename, '.')))
828 strcat(outfilename, suffix);
830 if(0 == strcmp(p, suffix)) {
838 if(0 == forced_outfilename)
839 forced_outfilename = outfilename;
840 if(0 != cmdline_forced_outfilename)
841 forced_outfilename = cmdline_forced_outfilename;
845 else if(0 == strcasecmp(infilename+(strlen(infilename)-4), ".ogg"))
848 treat_as_ogg = false;
850 #ifndef FLAC__HAS_OGG
852 fprintf(stderr, "%s: Ogg support has not been built into this copy of flac\n", infilename);
857 common_options.verbose = verbose;
858 common_options.continue_through_decode_errors = continue_through_decode_errors;
860 common_options.is_ogg = treat_as_ogg;
862 common_options.skip = skip;
864 if(!force_raw_format) {
865 wav_decode_options_t options;
867 options.common = common_options;
869 retval = flac__decode_wav(infilename, test_only? 0 : forced_outfilename, analyze, aopts, options);
872 raw_decode_options_t options;
874 options.common = common_options;
875 options.is_big_endian = format_is_big_endian;
876 options.is_unsigned_samples = format_is_unsigned_samples;
878 retval = flac__decode_raw(infilename, test_only? 0 : forced_outfilename, analyze, aopts, options);
881 if(retval == 0 && strcmp(infilename, "-")) {
882 if(strcmp(forced_outfilename, "-"))
883 flac__file_copy_metadata(infilename, forced_outfilename);