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;
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, rice_optimization_level = -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 */
48 aopts.do_residual_text = false;
49 aopts.do_residual_gnuplot = false;
55 for(i = 1; i < argc; i++) {
56 if(argv[i][0] != '-' || argv[i][1] == 0)
58 if(0 == strcmp(argv[i], "-d"))
60 else if(0 == strcmp(argv[i], "-a")) {
64 else if(0 == strcmp(argv[i], "-t")) {
68 else if(0 == strcmp(argv[i], "-s"))
70 else if(0 == strcmp(argv[i], "-s-"))
72 else if(0 == strcmp(argv[i], "-S")) {
73 if(num_requested_seek_points < 0)
74 num_requested_seek_points = 0;
75 num_requested_seek_points++;
76 strcat(requested_seek_points, argv[++i]);
77 strcat(requested_seek_points, "<");
79 else if(0 == strcmp(argv[i], "-S-")) {
80 num_requested_seek_points = 0;
81 requested_seek_points[0] = '\0';
83 else if(0 == strcmp(argv[i], "--skip"))
84 skip = (uint64)atoi(argv[++i]); /* @@@ takes a pretty damn big file to overflow atoi() here, but it could happen */
85 else if(0 == strcmp(argv[i], "--lax"))
87 else if(0 == strcmp(argv[i], "--lax-"))
89 else if(0 == strcmp(argv[i], "-b"))
90 blocksize = atoi(argv[++i]);
91 else if(0 == strcmp(argv[i], "-e"))
92 do_exhaustive_model_search = true;
93 else if(0 == strcmp(argv[i], "-e-"))
94 do_exhaustive_model_search = false;
95 else if(0 == strcmp(argv[i], "-l"))
96 max_lpc_order = atoi(argv[++i]);
97 else if(0 == strcmp(argv[i], "-m"))
99 else if(0 == strcmp(argv[i], "-m-"))
101 else if(0 == strcmp(argv[i], "-M"))
102 loose_mid_side = do_mid_side = true;
103 else if(0 == strcmp(argv[i], "-M-"))
104 loose_mid_side = do_mid_side = false;
105 else if(0 == strcmp(argv[i], "-p"))
106 do_qlp_coeff_prec_search = true;
107 else if(0 == strcmp(argv[i], "-p-"))
108 do_qlp_coeff_prec_search = false;
109 else if(0 == strcmp(argv[i], "-P"))
110 padding = atoi(argv[++i]);
111 else if(0 == strcmp(argv[i], "-q"))
112 qlp_coeff_precision = atoi(argv[++i]);
113 else if(0 == strcmp(argv[i], "-r"))
114 rice_optimization_level = atoi(argv[++i]);
115 else if(0 == strcmp(argv[i], "-V"))
117 else if(0 == strcmp(argv[i], "-V-"))
119 else if(0 == strcmp(argv[i], "-fb"))
120 format_is_big_endian = true;
121 else if(0 == strcmp(argv[i], "-fl"))
122 format_is_big_endian = false;
123 else if(0 == strcmp(argv[i], "-fc"))
124 format_channels = atoi(argv[++i]);
125 else if(0 == strcmp(argv[i], "-fp"))
126 format_bps = atoi(argv[++i]);
127 else if(0 == strcmp(argv[i], "-fs"))
128 format_sample_rate = atoi(argv[++i]);
129 else if(0 == strcmp(argv[i], "-fu"))
130 format_is_unsigned_samples = true;
131 else if(0 == strcmp(argv[i], "-fr"))
132 format_is_wave = false;
133 else if(0 == strcmp(argv[i], "-fw"))
134 format_is_wave = true;
135 else if(0 == strcmp(argv[i], "--a-rgp"))
136 aopts.do_residual_gnuplot = true;
137 else if(0 == strcmp(argv[i], "--a-rgp-"))
138 aopts.do_residual_gnuplot = false;
139 else if(0 == strcmp(argv[i], "-0")) {
140 do_exhaustive_model_search = false;
142 loose_mid_side = false;
143 qlp_coeff_precision = 0;
144 rice_optimization_level = 0;
147 else if(0 == strcmp(argv[i], "-1")) {
148 do_exhaustive_model_search = false;
150 loose_mid_side = true;
151 qlp_coeff_precision = 0;
152 rice_optimization_level = 0;
155 else if(0 == strcmp(argv[i], "-2")) {
156 do_exhaustive_model_search = false;
158 loose_mid_side = false;
159 qlp_coeff_precision = 0;
162 else if(0 == strcmp(argv[i], "-4")) {
163 do_exhaustive_model_search = false;
165 loose_mid_side = false;
166 qlp_coeff_precision = 0;
167 rice_optimization_level = 0;
170 else if(0 == strcmp(argv[i], "-5")) {
171 do_exhaustive_model_search = false;
173 loose_mid_side = true;
174 qlp_coeff_precision = 0;
175 rice_optimization_level = 0;
178 else if(0 == strcmp(argv[i], "-6")) {
179 do_exhaustive_model_search = false;
181 loose_mid_side = false;
182 qlp_coeff_precision = 0;
185 else if(0 == strcmp(argv[i], "-8")) {
186 do_exhaustive_model_search = false;
188 loose_mid_side = false;
189 qlp_coeff_precision = 0;
192 else if(0 == strcmp(argv[i], "-9")) {
193 do_exhaustive_model_search = true;
195 loose_mid_side = false;
196 do_qlp_coeff_prec_search = true;
197 rice_optimization_level = 99;
200 else if(isdigit((int)(argv[i][1]))) {
201 return usage("ERROR: compression level '%s' is still reserved\n", argv[i]);
204 return usage("ERROR: invalid option '%s'\n", argv[i]);
207 if(i + (test_only? 1:2) != argc)
208 return usage("ERROR: invalid arguments (more/less than %d filename%s?)\n", (test_only? 1:2), (test_only? "":"s"));
210 /* tweak options based on the filenames; validate the values */
212 if(format_is_wave < 0) {
213 if(strstr(argv[i], ".wav") == argv[i] + (strlen(argv[i]) - strlen(".wav")))
214 format_is_wave = true;
216 format_is_wave = false;
218 if(!format_is_wave) {
219 if(format_is_big_endian < 0 || format_channels < 0 || format_bps < 0 || format_sample_rate < 0)
220 return usage("ERROR: for encoding a raw file you must specify { -fb or -fl }, -fc, -fp, and -fs\n");
223 if(max_lpc_order == 0)
228 if(rice_optimization_level < 0) {
229 if(blocksize <= 1152)
230 rice_optimization_level = 4;
231 else if(blocksize <= 2304)
232 rice_optimization_level = 4;
233 else if(blocksize <= 4608)
234 rice_optimization_level = 4;
236 rice_optimization_level = 5;
242 return usage("ERROR: --skip is not allowed in test mode\n");
245 if(format_is_wave < 0) {
246 if(strstr(argv[i+1], ".wav") == argv[i+1] + (strlen(argv[i+1]) - strlen(".wav")))
247 format_is_wave = true;
249 format_is_wave = false;
251 if(!format_is_wave) {
252 if(format_is_big_endian < 0)
253 return usage("ERROR: for decoding to a raw file you must specify -fb or -fl\n");
258 assert(blocksize >= 0 || mode_decode);
260 if(format_channels >= 0) {
261 if(format_channels == 0 || (unsigned)format_channels > FLAC__MAX_CHANNELS)
262 return usage("ERROR: invalid number of channels '%u', must be > 0 and <= %u\n", format_channels, FLAC__MAX_CHANNELS);
264 if(format_bps >= 0) {
265 if(format_bps != 8 && format_bps != 16 && format_bps != 24)
266 return usage("ERROR: invalid bits per sample '%u' (must be 8/16/24)\n", format_bps);
268 if(format_sample_rate >= 0) {
269 if(format_sample_rate == 0 || (unsigned)format_sample_rate > FLAC__MAX_SAMPLE_RATE)
270 return usage("ERROR: invalid sample rate '%u', must be > 0 and <= %u\n", format_sample_rate, FLAC__MAX_SAMPLE_RATE);
272 if(!mode_decode && ((unsigned)blocksize < FLAC__MIN_BLOCK_SIZE || (unsigned)blocksize > FLAC__MAX_BLOCK_SIZE)) {
273 return usage("ERROR: invalid blocksize '%u', must be >= %u and <= %u\n", (unsigned)blocksize, FLAC__MIN_BLOCK_SIZE, FLAC__MAX_BLOCK_SIZE);
275 if(qlp_coeff_precision > 0 && qlp_coeff_precision < FLAC__MIN_QLP_COEFF_PRECISION) {
276 return usage("ERROR: invalid value for -q '%u', must be 0 or >= %u\n", qlp_coeff_precision, FLAC__MIN_QLP_COEFF_PRECISION);
279 /* turn off verbosity if the output stream is going to stdout */
280 if(!test_only && 0 == strcmp(argv[i+1], "-"))
285 printf("flac %s, Copyright (C) 2000,2001 Josh Coalson\n", FLAC__VERSION_STRING);
286 printf("flac comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n");
287 printf("welcome to redistribute it under certain conditions. Type `flac' for details.\n\n");
290 printf("options:%s -P %u -b %u%s -l %u%s%s -q %u -r %u%s\n",
291 lax?" --lax":"", padding, (unsigned)blocksize, loose_mid_side?" -M":do_mid_side?" -m":"", max_lpc_order,
292 do_exhaustive_model_search?" -e":"", do_qlp_coeff_prec_search?" -p":"",
293 qlp_coeff_precision, (unsigned)rice_optimization_level,
301 return decode_wav(argv[i], test_only? 0 : argv[i+1], analyze, aopts, verbose, skip);
303 return decode_raw(argv[i], test_only? 0 : argv[i+1], analyze, aopts, verbose, skip, format_is_big_endian, format_is_unsigned_samples);
306 return encode_wav(argv[i], argv[i+1], verbose, skip, verify, lax, do_mid_side, loose_mid_side, do_exhaustive_model_search, do_qlp_coeff_prec_search, rice_optimization_level, max_lpc_order, (unsigned)blocksize, qlp_coeff_precision, padding, requested_seek_points, num_requested_seek_points);
308 return encode_raw(argv[i], argv[i+1], verbose, skip, verify, lax, do_mid_side, loose_mid_side, do_exhaustive_model_search, do_qlp_coeff_prec_search, rice_optimization_level, 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);
313 int usage(const char *message, ...)
318 va_start(args, message);
320 (void) vfprintf(stderr, message, args);
325 printf("==============================================================================\n");
326 printf("flac - Command-line FLAC encoder/decoder version %s\n", FLAC__VERSION_STRING);
327 printf("Copyright (C) 2000,2001 Josh Coalson\n");
329 printf("This program is free software; you can redistribute it and/or\n");
330 printf("modify it under the terms of the GNU General Public License\n");
331 printf("as published by the Free Software Foundation; either version 2\n");
332 printf("of the License, or (at your option) any later version.\n");
334 printf("This program is distributed in the hope that it will be useful,\n");
335 printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
336 printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
337 printf("GNU General Public License for more details.\n");
339 printf("You should have received a copy of the GNU General Public License\n");
340 printf("along with this program; if not, write to the Free Software\n");
341 printf("Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n");
342 printf("==============================================================================\n");
344 printf(" flac [options] infile outfile\n");
346 printf("For encoding:\n");
347 printf(" infile may be a PCM RIFF WAVE file or raw samples\n");
348 printf(" outfile will be in FLAC format\n");
349 printf("For decoding, the reverse is be true\n");
351 printf("infile may be - for stdin, outfile may be - for stdout\n");
353 printf("If the unencoded filename ends with '.wav' or -fw is used, it's assumed to be\n");
354 printf("RIFF WAVE. Otherwise, it's assumed to be raw samples and you have to specify\n");
355 printf("all the format options. You can force a .wav file to be treated as a raw file\n");
356 printf("using -fr.\n");
358 printf("generic options:\n");
359 printf(" -d : decode (default behavior is encode)\n");
360 printf(" -t : test (same as -d except no decoded file is written)\n");
361 printf(" -a : analyze (same as -d except an analysis file is written)\n");
362 printf(" -s : silent (do not write runtime encode/decode statistics to stdout)\n");
363 printf(" --skip samples : can be used both for encoding and decoding\n");
364 printf("analyze options:\n");
365 printf(" --a-rtext : include residual signal in text output\n");
366 printf(" --a-rgp : generate gnuplot files of residual distribution of each subframe\n");
367 printf("encoding options:\n");
368 printf(" --lax : allow encoder to generate non-Subset files\n");
369 printf(" -S { # | X | #x } : include a point or points in a SEEKTABLE\n");
370 printf(" # : a specific sample number for a seek point\n");
371 printf(" X : a placeholder point (always goes at the end of the SEEKTABLE)\n");
372 printf(" #x : # evenly spaced seekpoints, the first being at sample 0\n");
373 printf(" You may use many -S options; the resulting SEEKTABLE will be the unique-\n");
374 printf(" ified union of all such values.\n");
375 printf(" With no -S options, flac defaults to '-S 100x'. Use -S- for no SEEKTABLE.\n");
376 printf(" Note: -S #x will not work if the encoder can't determine the input size\n");
377 printf(" before starting.\n");
378 printf(" Note: if you use -S # and # is >= samples in the input, there will be\n");
379 printf(" either no seek point entered (if the input size is determinable\n");
380 printf(" before encoding starts) or a placeholder point (if input size is not\n");
381 printf(" determinable)\n");
382 printf(" -P # : write a PADDING block of # bytes (goes after SEEKTABLE)\n");
383 printf(" (0 => no PADDING block, default is -P 0)\n");
384 printf(" -b # : specify blocksize in samples; default is 1152 for -l 0, else 4608;\n");
385 printf(" should be 192/576/1152//4608 (unless --lax is used)\n");
386 printf(" -m : try mid-side coding for each frame (stereo input only)\n");
387 printf(" -M : loose mid-side coding for all frames (stereo input only)\n");
388 printf(" -0 .. -9 : fastest compression .. highest compression, default is -6\n");
389 printf(" these are synonyms for other options:\n");
390 printf(" -0 : synonymous with -l 0 -b 1152\n");
391 printf(" -1 : synonymous with -l 0 -b 1152 -M\n");
392 printf(" -2 : synonymous with -l 0 -b 1152 -m -r 2\n");
393 printf(" -3 : reserved\n");
394 printf(" -4 : synonymous with -l 8 -b 4608 \n");
395 printf(" -5 : synonymous with -l 8 -b 4608 -M\n");
396 printf(" -6 : synonymous with -l 8 -b 4608 -m -r 4\n");
397 printf(" -7 : reserved\n");
398 printf(" -8 : synonymous with -l 32 -b 4608 -m -r 4\n");
399 printf(" -9 : synonymous with -l 32 -m -e -r 99 -p (very slow!)\n");
400 printf(" -e : do exhaustive model search (expensive!)\n");
401 printf(" -l # : specify max LPC order; 0 => use only fixed predictors\n");
402 printf(" -p : do exhaustive search of LP coefficient quantization (expensive!);\n");
403 printf(" overrides -q, does nothing if using -l 0\n");
404 printf(" -q # : specify precision in bits of quantized linear-predictor coefficients;\n");
405 printf(" 0 => let encoder decide (min is %u, default is -q 0)\n", FLAC__MIN_QLP_COEFF_PRECISION);
406 printf(" -r # : rice parameter optimization level (# is 0..99, 0 => none, default is\n");
407 printf(" -r 0, above 4 doesn't usually help much)\n");
408 printf(" -V : verify a correct encoding by decoding the output in parallel and\n")
409 printf(" comparing to the original\n");
410 printf(" -S-, -m-, -M-, -e-, -p-, -V-, --lax- can all be used to turn off a particular\n");
412 printf("format options:\n");
413 printf(" -fb | -fl : big-endian | little-endian byte order\n");
414 printf(" -fc channels\n");
415 printf(" -fp bits_per_sample\n");
416 printf(" -fs sample_rate : in Hz\n");
417 printf(" -fu : unsigned samples (default is signed)\n");
418 printf(" -fr : force to raw format (even if filename ends in .wav)\n");
419 printf(" -fw : force to RIFF WAVE\n");