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.
30 static int usage(const char *message, ...);
32 int main(int argc, char *argv[])
35 bool verify = false, verbose = true, lax = false, mode_decode = false, test_only = false, analyze = false;
36 bool do_mid_side = true, loose_mid_side = false, do_exhaustive_model_search = false, do_qlp_coeff_prec_search = false;
37 analysis_options aopts = { false, false };
39 unsigned max_lpc_order = 8;
40 unsigned qlp_coeff_precision = 0;
42 int format_is_wave = -1, format_is_big_endian = -1, format_is_unsigned_samples = false;
43 int format_channels = -1, format_bps = -1, format_sample_rate = -1;
44 int blocksize = -1, min_residual_partition_order = -1, max_residual_partition_order = -1, rice_parameter_search_dist = -1;
45 char requested_seek_points[50000]; /* @@@ bad MAGIC NUMBER */
46 int num_requested_seek_points = -1; /* -1 => no -S options were given, 0 => -S- was given */
47 FILE *encode_infile = 0;
53 for(i = 1; i < argc; i++) {
54 if(argv[i][0] != '-' || argv[i][1] == 0)
56 if(0 == strcmp(argv[i], "-d"))
58 else if(0 == strcmp(argv[i], "-a")) {
62 else if(0 == strcmp(argv[i], "-t")) {
66 else if(0 == strcmp(argv[i], "-s"))
68 else if(0 == strcmp(argv[i], "-s-"))
70 else if(0 == strcmp(argv[i], "-S")) {
71 if(num_requested_seek_points < 0)
72 num_requested_seek_points = 0;
73 num_requested_seek_points++;
74 strcat(requested_seek_points, argv[++i]);
75 strcat(requested_seek_points, "<");
77 else if(0 == strcmp(argv[i], "-S-")) {
78 num_requested_seek_points = 0;
79 requested_seek_points[0] = '\0';
81 else if(0 == strcmp(argv[i], "--skip"))
82 skip = (uint64)atoi(argv[++i]); /* @@@ takes a pretty damn big file to overflow atoi() here, but it could happen */
83 else if(0 == strcmp(argv[i], "--lax"))
85 else if(0 == strcmp(argv[i], "--lax-"))
87 else if(0 == strcmp(argv[i], "-b"))
88 blocksize = atoi(argv[++i]);
89 else if(0 == strcmp(argv[i], "-e"))
90 do_exhaustive_model_search = true;
91 else if(0 == strcmp(argv[i], "-e-"))
92 do_exhaustive_model_search = false;
93 else if(0 == strcmp(argv[i], "-l"))
94 max_lpc_order = atoi(argv[++i]);
95 else if(0 == strcmp(argv[i], "-m"))
97 else if(0 == strcmp(argv[i], "-m-"))
99 else if(0 == strcmp(argv[i], "-M"))
100 loose_mid_side = do_mid_side = true;
101 else if(0 == strcmp(argv[i], "-M-"))
102 loose_mid_side = do_mid_side = false;
103 else if(0 == strcmp(argv[i], "-p"))
104 do_qlp_coeff_prec_search = true;
105 else if(0 == strcmp(argv[i], "-p-"))
106 do_qlp_coeff_prec_search = false;
107 else if(0 == strcmp(argv[i], "-P"))
108 padding = atoi(argv[++i]);
109 else if(0 == strcmp(argv[i], "-q"))
110 qlp_coeff_precision = atoi(argv[++i]);
111 else if(0 == strcmp(argv[i], "-r")) {
112 char *p = strchr(argv[++i], ',');
114 min_residual_partition_order = 0;
115 max_residual_partition_order = atoi(argv[i]);
118 min_residual_partition_order = atoi(argv[i]);
119 max_residual_partition_order = atoi(++p);
122 else if(0 == strcmp(argv[i], "-R"))
123 rice_parameter_search_dist = atoi(argv[++i]);
124 else if(0 == strcmp(argv[i], "-V"))
126 else if(0 == strcmp(argv[i], "-V-"))
128 else if(0 == strcmp(argv[i], "-fb"))
129 format_is_big_endian = true;
130 else if(0 == strcmp(argv[i], "-fl"))
131 format_is_big_endian = false;
132 else if(0 == strcmp(argv[i], "-fc"))
133 format_channels = atoi(argv[++i]);
134 else if(0 == strcmp(argv[i], "-fp"))
135 format_bps = atoi(argv[++i]);
136 else if(0 == strcmp(argv[i], "-fs"))
137 format_sample_rate = atoi(argv[++i]);
138 else if(0 == strcmp(argv[i], "-fu"))
139 format_is_unsigned_samples = true;
140 else if(0 == strcmp(argv[i], "-fr"))
141 format_is_wave = false;
142 else if(0 == strcmp(argv[i], "-fw"))
143 format_is_wave = true;
144 else if(0 == strcmp(argv[i], "--a-rgp"))
145 aopts.do_residual_gnuplot = true;
146 else if(0 == strcmp(argv[i], "--a-rgp-"))
147 aopts.do_residual_gnuplot = false;
148 else if(0 == strcmp(argv[i], "--a-rtext"))
149 aopts.do_residual_text = true;
150 else if(0 == strcmp(argv[i], "--a-rtext-"))
151 aopts.do_residual_text = false;
152 else if(0 == strcmp(argv[i], "-0")) {
153 do_exhaustive_model_search = false;
155 loose_mid_side = false;
156 qlp_coeff_precision = 0;
157 min_residual_partition_order = max_residual_partition_order = 0;
158 rice_parameter_search_dist = 0;
161 else if(0 == strcmp(argv[i], "-1")) {
162 do_exhaustive_model_search = false;
164 loose_mid_side = true;
165 qlp_coeff_precision = 0;
166 min_residual_partition_order = max_residual_partition_order = 0;
167 rice_parameter_search_dist = 0;
170 else if(0 == strcmp(argv[i], "-2")) {
171 do_exhaustive_model_search = false;
173 loose_mid_side = false;
174 qlp_coeff_precision = 0;
175 rice_parameter_search_dist = 0;
178 else if(0 == strcmp(argv[i], "-4")) {
179 do_exhaustive_model_search = false;
181 loose_mid_side = false;
182 qlp_coeff_precision = 0;
183 min_residual_partition_order = max_residual_partition_order = 0;
184 rice_parameter_search_dist = 0;
187 else if(0 == strcmp(argv[i], "-5")) {
188 do_exhaustive_model_search = false;
190 loose_mid_side = true;
191 qlp_coeff_precision = 0;
192 min_residual_partition_order = max_residual_partition_order = 0;
193 rice_parameter_search_dist = 0;
196 else if(0 == strcmp(argv[i], "-6")) {
197 do_exhaustive_model_search = false;
199 loose_mid_side = false;
200 qlp_coeff_precision = 0;
201 rice_parameter_search_dist = 0;
204 else if(0 == strcmp(argv[i], "-8")) {
205 do_exhaustive_model_search = false;
207 loose_mid_side = false;
208 qlp_coeff_precision = 0;
209 rice_parameter_search_dist = 0;
212 else if(0 == strcmp(argv[i], "-9")) {
213 do_exhaustive_model_search = true;
215 loose_mid_side = false;
216 do_qlp_coeff_prec_search = true;
217 min_residual_partition_order = 0;
218 max_residual_partition_order = 16;
219 rice_parameter_search_dist = 32;
222 else if(isdigit((int)(argv[i][1]))) {
223 return usage("ERROR: compression level '%s' is still reserved\n", argv[i]);
226 return usage("ERROR: invalid option '%s'\n", argv[i]);
229 if(i + (test_only? 1:2) != argc)
230 return usage("ERROR: invalid arguments (more/less than %d filename%s?)\n", (test_only? 1:2), (test_only? "":"s"));
232 /* tweak options based on the filenames; validate the values */
234 if(0 == strcmp(argv[i], "-")) {
235 encode_infile = stdin;
238 if(0 == (encode_infile = fopen(argv[i], "rb"))) {
239 fprintf(stderr, "ERROR: can't open input file %s\n", argv[i]);
243 if(format_is_wave < 0) {
244 /* lamely attempt to guess the file type based on the first 4 bytes (which is all ungetc will guarantee us) */
247 /* first set format based on name */
248 if(strstr(argv[i], ".wav") == argv[i] + (strlen(argv[i]) - strlen(".wav")))
249 format_is_wave = true;
251 format_is_wave = false;
252 if((n = fread(head, 1, 4, encode_infile)) < 4) {
254 fprintf(stderr, "WARNING: %s is not a WAVE file, treating as a raw file\n", argv[i]);
255 format_is_wave = false;
258 if(strncmp(head, "RIFF", 4)) {
260 fprintf(stderr, "WARNING: %s is not a WAVE file, treating as a raw file\n", argv[i]);
261 format_is_wave = false;
264 format_is_wave = true;
266 for(h = n-1; h >= 0; h--)
267 ungetc(head[h], encode_infile);
269 if(!format_is_wave) {
270 if(format_is_big_endian < 0 || format_channels < 0 || format_bps < 0 || format_sample_rate < 0)
271 return usage("ERROR: for encoding a raw file you must specify { -fb or -fl }, -fc, -fp, and -fs\n");
274 if(max_lpc_order == 0)
279 if(min_residual_partition_order < 0) {
280 min_residual_partition_order = 0;
281 if(blocksize <= 1152)
282 max_residual_partition_order = 4;
283 else if(blocksize <= 2304)
284 max_residual_partition_order = 4;
285 else if(blocksize <= 4608)
286 max_residual_partition_order = 4;
288 max_residual_partition_order = 5;
290 if(rice_parameter_search_dist < 0) {
291 rice_parameter_search_dist = 0;
297 return usage("ERROR: --skip is not allowed in test mode\n");
300 if(format_is_wave < 0) {
301 if(strstr(argv[i+1], ".wav") == argv[i+1] + (strlen(argv[i+1]) - strlen(".wav")))
302 format_is_wave = true;
304 format_is_wave = false;
306 if(!format_is_wave) {
307 if(format_is_big_endian < 0)
308 return usage("ERROR: for decoding to a raw file you must specify -fb or -fl\n");
313 assert(blocksize >= 0 || mode_decode);
315 if(format_channels >= 0) {
316 if(format_channels == 0 || (unsigned)format_channels > FLAC__MAX_CHANNELS)
317 return usage("ERROR: invalid number of channels '%u', must be > 0 and <= %u\n", format_channels, FLAC__MAX_CHANNELS);
319 if(format_bps >= 0) {
320 if(format_bps != 8 && format_bps != 16 && format_bps != 24)
321 return usage("ERROR: invalid bits per sample '%u' (must be 8/16/24)\n", format_bps);
323 if(format_sample_rate >= 0) {
324 if(format_sample_rate == 0 || (unsigned)format_sample_rate > FLAC__MAX_SAMPLE_RATE)
325 return usage("ERROR: invalid sample rate '%u', must be > 0 and <= %u\n", format_sample_rate, FLAC__MAX_SAMPLE_RATE);
327 if(!mode_decode && ((unsigned)blocksize < FLAC__MIN_BLOCK_SIZE || (unsigned)blocksize > FLAC__MAX_BLOCK_SIZE)) {
328 return usage("ERROR: invalid blocksize '%u', must be >= %u and <= %u\n", (unsigned)blocksize, FLAC__MIN_BLOCK_SIZE, FLAC__MAX_BLOCK_SIZE);
330 if(qlp_coeff_precision > 0 && qlp_coeff_precision < FLAC__MIN_QLP_COEFF_PRECISION) {
331 return usage("ERROR: invalid value for -q '%u', must be 0 or >= %u\n", qlp_coeff_precision, FLAC__MIN_QLP_COEFF_PRECISION);
334 /* turn off verbosity if the output stream is going to stdout */
335 if(!test_only && 0 == strcmp(argv[i+1], "-"))
340 printf("flac %s, Copyright (C) 2000,2001 Josh Coalson\n", FLAC__VERSION_STRING);
341 printf("flac comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n");
342 printf("welcome to redistribute it under certain conditions. Type `flac' for details.\n\n");
345 printf("options:%s -P %u -b %u%s -l %u%s%s -q %u -r %u,%u -R %u%s\n",
346 lax?" --lax":"", padding, (unsigned)blocksize, loose_mid_side?" -M":do_mid_side?" -m":"", max_lpc_order,
347 do_exhaustive_model_search?" -e":"", do_qlp_coeff_prec_search?" -p":"",
349 (unsigned)min_residual_partition_order, (unsigned)max_residual_partition_order, (unsigned)rice_parameter_search_dist,
357 return decode_wav(argv[i], test_only? 0 : argv[i+1], analyze, aopts, verbose, skip);
359 return decode_raw(argv[i], test_only? 0 : argv[i+1], analyze, aopts, verbose, skip, format_is_big_endian, format_is_unsigned_samples);
362 return encode_wav(encode_infile, argv[i], argv[i+1], verbose, skip, verify, lax, do_mid_side, loose_mid_side, do_exhaustive_model_search, do_qlp_coeff_prec_search, min_residual_partition_order, max_residual_partition_order, rice_parameter_search_dist, max_lpc_order, (unsigned)blocksize, qlp_coeff_precision, padding, requested_seek_points, num_requested_seek_points);
364 return encode_raw(encode_infile, argv[i], argv[i+1], verbose, skip, verify, lax, do_mid_side, loose_mid_side, do_exhaustive_model_search, do_qlp_coeff_prec_search, min_residual_partition_order, max_residual_partition_order, rice_parameter_search_dist, max_lpc_order, (unsigned)blocksize, qlp_coeff_precision, padding, requested_seek_points, num_requested_seek_points, format_is_big_endian, format_is_unsigned_samples, format_channels, format_bps, format_sample_rate);
369 int usage(const char *message, ...)
374 va_start(args, message);
376 (void) vfprintf(stderr, message, args);
381 printf("==============================================================================\n");
382 printf("flac - Command-line FLAC encoder/decoder version %s\n", FLAC__VERSION_STRING);
383 printf("Copyright (C) 2000,2001 Josh Coalson\n");
385 printf("This program is free software; you can redistribute it and/or\n");
386 printf("modify it under the terms of the GNU General Public License\n");
387 printf("as published by the Free Software Foundation; either version 2\n");
388 printf("of the License, or (at your option) any later version.\n");
390 printf("This program is distributed in the hope that it will be useful,\n");
391 printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
392 printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
393 printf("GNU General Public License for more details.\n");
395 printf("You should have received a copy of the GNU General Public License\n");
396 printf("along with this program; if not, write to the Free Software\n");
397 printf("Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n");
398 printf("==============================================================================\n");
400 printf(" flac [options] infile outfile\n");
402 printf("For encoding:\n");
403 printf(" infile may be a PCM RIFF WAVE file or raw samples\n");
404 printf(" outfile will be in FLAC format\n");
405 printf("For decoding, the reverse is be true\n");
407 printf("infile may be - for stdin, outfile may be - for stdout\n");
409 printf("If the unencoded filename ends with '.wav' or -fw is used, it's assumed to be\n");
410 printf("RIFF WAVE. Otherwise, it's assumed to be raw samples and you have to specify\n");
411 printf("all the format options. You can force a .wav file to be treated as a raw file\n");
412 printf("using -fr.\n");
414 printf("generic options:\n");
415 printf(" -d : decode (default behavior is encode)\n");
416 printf(" -t : test (same as -d except no decoded file is written)\n");
417 printf(" -a : analyze (same as -d except an analysis file is written)\n");
418 printf(" -s : silent (do not write runtime encode/decode statistics to stdout)\n");
419 printf(" --skip samples : can be used both for encoding and decoding\n");
420 printf("analyze options:\n");
421 printf(" --a-rtext : include residual signal in text output\n");
422 printf(" --a-rgp : generate gnuplot files of residual distribution of each subframe\n");
423 printf("encoding options:\n");
424 printf(" --lax : allow encoder to generate non-Subset files\n");
425 printf(" -S { # | X | #x } : include a point or points in a SEEKTABLE\n");
426 printf(" # : a specific sample number for a seek point\n");
427 printf(" X : a placeholder point (always goes at the end of the SEEKTABLE)\n");
428 printf(" #x : # evenly spaced seekpoints, the first being at sample 0\n");
429 printf(" You may use many -S options; the resulting SEEKTABLE will be the unique-\n");
430 printf(" ified union of all such values.\n");
431 printf(" With no -S options, flac defaults to '-S 100x'. Use -S- for no SEEKTABLE.\n");
432 printf(" Note: -S #x will not work if the encoder can't determine the input size\n");
433 printf(" before starting.\n");
434 printf(" Note: if you use -S # and # is >= samples in the input, there will be\n");
435 printf(" either no seek point entered (if the input size is determinable\n");
436 printf(" before encoding starts) or a placeholder point (if input size is not\n");
437 printf(" determinable)\n");
438 printf(" -P # : write a PADDING block of # bytes (goes after SEEKTABLE)\n");
439 printf(" (0 => no PADDING block, default is -P 0)\n");
440 printf(" -b # : specify blocksize in samples; default is 1152 for -l 0, else 4608;\n");
441 printf(" must be 192/576/1152/2304/4608/256/512/1024/2048/4096/8192/16384/32768\n");
442 printf(" (unless --lax is used)\n");
443 printf(" -m : try mid-side coding for each frame (stereo input only)\n");
444 printf(" -M : loose mid-side coding for all frames (stereo input only)\n");
445 printf(" -0 .. -9 : fastest compression .. highest compression, default is -6\n");
446 printf(" these are synonyms for other options:\n");
447 printf(" -0 : synonymous with -l 0 -b 1152\n");
448 printf(" -1 : synonymous with -l 0 -b 1152 -M\n");
449 printf(" -2 : synonymous with -l 0 -b 1152 -m -r 4\n");
450 printf(" -3 : reserved\n");
451 printf(" -4 : synonymous with -l 8 -b 4608 \n");
452 printf(" -5 : synonymous with -l 8 -b 4608 -M\n");
453 printf(" -6 : synonymous with -l 8 -b 4608 -m -r 4\n");
454 printf(" -7 : reserved\n");
455 printf(" -8 : synonymous with -l 32 -b 4608 -m -r 4\n");
456 printf(" -9 : synonymous with -l 32 -m -e -r 16 -R 32 -p (very slow!)\n");
457 printf(" -e : do exhaustive model search (expensive!)\n");
458 printf(" -l # : specify max LPC order; 0 => use only fixed predictors\n");
459 printf(" -p : do exhaustive search of LP coefficient quantization (expensive!);\n");
460 printf(" overrides -q, does nothing if using -l 0\n");
461 printf(" -q # : specify precision in bits of quantized linear-predictor coefficients;\n");
462 printf(" 0 => let encoder decide (min is %u, default is -q 0)\n", FLAC__MIN_QLP_COEFF_PRECISION);
463 printf(" -r [#,]# : [min,]max residual partition order (# is 0..16; min defaults to 0;\n");
464 printf(" default is -r 0; above 4 doesn't usually help much)\n");
465 printf(" -R # : Rice parameter search distance (# is 0..32; above 2 doesn't help much\n");
466 printf(" -V : verify a correct encoding by decoding the output in parallel and\n");
467 printf(" comparing to the original\n");
468 printf(" -S-, -m-, -M-, -e-, -p-, -V-, --lax- can all be used to turn off a particular\n");
470 printf("format options:\n");
471 printf(" -fb | -fl : big-endian | little-endian byte order\n");
472 printf(" -fc channels\n");
473 printf(" -fp bits_per_sample\n");
474 printf(" -fs sample_rate : in Hz\n");
475 printf(" -fu : unsigned samples (default is signed)\n");
476 printf(" -fr : force to raw format (even if filename ends in .wav)\n");
477 printf(" -fw : force to RIFF WAVE\n");