add the --output-prefix option
[flac.git] / src / flac / main.c
1 /* flac - Command-line FLAC encoder/decoder
2  * Copyright (C) 2000,2001  Josh Coalson
3  *
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.
8  *
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.
13  *
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.
17  */
18
19 #include <ctype.h>
20 #include <stdarg.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #ifndef _MSC_VER
25 /* unlink is in stdio.h in VC++ */
26 #include <unistd.h> /* for unlink() */
27 #endif
28 #include "FLAC/all.h"
29 #include "analyze.h"
30 #include "decode.h"
31 #include "encode.h"
32 #include "file.h"
33
34 static int usage(const char *message, ...);
35 static int encode_file(const char *infilename, const char *forced_outfilename, FLAC__bool is_last_file);
36 static int decode_file(const char *infilename, const char *forced_outfilename);
37
38 FLAC__bool verify = false, verbose = true, lax = false, test_only = false, analyze = false;
39 FLAC__bool do_mid_side = true, loose_mid_side = false, do_exhaustive_model_search = false, do_qlp_coeff_prec_search = false;
40 FLAC__bool force_to_stdout = false, delete_input = false, sector_align = false;
41 const char *cmdline_forced_outfilename = 0, *output_prefix = 0;
42 analysis_options aopts = { false, false };
43 unsigned padding = 0;
44 unsigned max_lpc_order = 8;
45 unsigned qlp_coeff_precision = 0;
46 FLAC__uint64 skip = 0;
47 int format_is_wave = -1, format_is_big_endian = -1, format_is_unsigned_samples = false;
48 int format_channels = -1, format_bps = -1, format_sample_rate = -1;
49 int blocksize = -1, min_residual_partition_order = -1, max_residual_partition_order = -1, rice_parameter_search_dist = -1;
50 char requested_seek_points[50000]; /* @@@ bad MAGIC NUMBER */
51 int num_requested_seek_points = -1; /* -1 => no -S options were given, 0 => -S- was given */
52 FLAC__int32 align_reservoir_0[588], align_reservoir_1[588]; /* for carrying over samples from --sector-align */
53 FLAC__int32 *align_reservoir[2] = { align_reservoir_0, align_reservoir_1 };
54 unsigned align_reservoir_samples = 0; /* 0 .. 587 */
55
56 int main(int argc, char *argv[])
57 {
58         int i, retval = 0;
59         FLAC__bool mode_decode = false;
60
61         if(argc <= 1)
62                 return usage(0);
63
64         /* get the options */
65         for(i = 1; i < argc; i++) {
66                 if(argv[i][0] != '-' || argv[i][1] == 0)
67                         break;
68                 if(0 == strcmp(argv[i], "-d"))
69                         mode_decode = true;
70                 else if(0 == strcmp(argv[i], "-a")) {
71                         mode_decode = true;
72                         analyze = true;
73                 }
74                 else if(0 == strcmp(argv[i], "-t")) {
75                         mode_decode = true;
76                         test_only = true;
77                 }
78                 else if(0 == strcmp(argv[i], "-c"))
79                         force_to_stdout = true;
80                 else if(0 == strcmp(argv[i], "-s"))
81                         verbose = false;
82                 else if(0 == strcmp(argv[i], "-s-"))
83                         verbose = true;
84                 else if(0 == strcmp(argv[i], "-S")) {
85                         if(num_requested_seek_points < 0)
86                                 num_requested_seek_points = 0;
87                         num_requested_seek_points++;
88                         strcat(requested_seek_points, argv[++i]);
89                         strcat(requested_seek_points, "<");
90                 }
91                 else if(0 == strcmp(argv[i], "-S-")) {
92                         num_requested_seek_points = 0;
93                         requested_seek_points[0] = '\0';
94                 }
95                 else if(0 == strcmp(argv[i], "--delete-input-file"))
96                         delete_input = true;
97                 else if(0 == strcmp(argv[i], "--delete-input-file-"))
98                         delete_input = false;
99                 else if(0 == strcmp(argv[i], "--output-prefix"))
100                         output_prefix = argv[++i];
101                 else if(0 == strcmp(argv[i], "--sector-align"))
102                         sector_align = true;
103                 else if(0 == strcmp(argv[i], "--sector-align-"))
104                         sector_align = false;
105                 else if(0 == strcmp(argv[i], "--skip"))
106                         skip = (FLAC__uint64)atoi(argv[++i]); /* @@@ takes a pretty damn big file to overflow atoi() here, but it could happen */
107                 else if(0 == strcmp(argv[i], "--lax"))
108                         lax = true;
109                 else if(0 == strcmp(argv[i], "--lax-"))
110                         lax = false;
111                 else if(0 == strcmp(argv[i], "-b"))
112                         blocksize = atoi(argv[++i]);
113                 else if(0 == strcmp(argv[i], "-e"))
114                         do_exhaustive_model_search = true;
115                 else if(0 == strcmp(argv[i], "-e-"))
116                         do_exhaustive_model_search = false;
117                 else if(0 == strcmp(argv[i], "-l"))
118                         max_lpc_order = atoi(argv[++i]);
119                 else if(0 == strcmp(argv[i], "-m")) {
120                         do_mid_side = true;
121                         loose_mid_side = false;
122                 }
123                 else if(0 == strcmp(argv[i], "-m-"))
124                         do_mid_side = loose_mid_side = false;
125                 else if(0 == strcmp(argv[i], "-M"))
126                         loose_mid_side = do_mid_side = true;
127                 else if(0 == strcmp(argv[i], "-M-"))
128                         loose_mid_side = do_mid_side = false;
129                 else if(0 == strcmp(argv[i], "-o"))
130                         cmdline_forced_outfilename = argv[++i];
131                 else if(0 == strcmp(argv[i], "-p"))
132                         do_qlp_coeff_prec_search = true;
133                 else if(0 == strcmp(argv[i], "-p-"))
134                         do_qlp_coeff_prec_search = false;
135                 else if(0 == strcmp(argv[i], "-P"))
136                         padding = atoi(argv[++i]);
137                 else if(0 == strcmp(argv[i], "-q"))
138                         qlp_coeff_precision = atoi(argv[++i]);
139                 else if(0 == strcmp(argv[i], "-r")) {
140                         char *p = strchr(argv[++i], ',');
141                         if(0 == p) {
142                                 min_residual_partition_order = 0;
143                                 max_residual_partition_order = atoi(argv[i]);
144                         }
145                         else {
146                                 min_residual_partition_order = atoi(argv[i]);
147                                 max_residual_partition_order = atoi(++p);
148                         }
149                 }
150                 else if(0 == strcmp(argv[i], "-R"))
151                         rice_parameter_search_dist = atoi(argv[++i]);
152                 else if(0 == strcmp(argv[i], "-V"))
153                         verify = true;
154                 else if(0 == strcmp(argv[i], "-V-"))
155                         verify = false;
156                 else if(0 == strcmp(argv[i], "-fb"))
157                         format_is_big_endian = true;
158                 else if(0 == strcmp(argv[i], "-fl"))
159                         format_is_big_endian = false;
160                 else if(0 == strcmp(argv[i], "-fc"))
161                         format_channels = atoi(argv[++i]);
162                 else if(0 == strcmp(argv[i], "-fp"))
163                         format_bps = atoi(argv[++i]);
164                 else if(0 == strcmp(argv[i], "-fs"))
165                         format_sample_rate = atoi(argv[++i]);
166                 else if(0 == strcmp(argv[i], "-fu"))
167                         format_is_unsigned_samples = true;
168                 else if(0 == strcmp(argv[i], "-fr"))
169                         format_is_wave = false;
170                 else if(0 == strcmp(argv[i], "-fw"))
171                         format_is_wave = true;
172                 else if(0 == strcmp(argv[i], "--a-rgp"))
173                         aopts.do_residual_gnuplot = true;
174                 else if(0 == strcmp(argv[i], "--a-rgp-"))
175                         aopts.do_residual_gnuplot = false;
176                 else if(0 == strcmp(argv[i], "--a-rtext"))
177                         aopts.do_residual_text = true;
178                 else if(0 == strcmp(argv[i], "--a-rtext-"))
179                         aopts.do_residual_text = false;
180                 else if(0 == strcmp(argv[i], "-0")) {
181                         do_exhaustive_model_search = false;
182                         do_mid_side = false;
183                         loose_mid_side = false;
184                         qlp_coeff_precision = 0;
185                         min_residual_partition_order = max_residual_partition_order = 2;
186                         rice_parameter_search_dist = 0;
187                         max_lpc_order = 0;
188                 }
189                 else if(0 == strcmp(argv[i], "-1")) {
190                         do_exhaustive_model_search = false;
191                         do_mid_side = true;
192                         loose_mid_side = true;
193                         qlp_coeff_precision = 0;
194                         min_residual_partition_order = max_residual_partition_order = 2;
195                         rice_parameter_search_dist = 0;
196                         max_lpc_order = 0;
197                 }
198                 else if(0 == strcmp(argv[i], "-2")) {
199                         do_exhaustive_model_search = false;
200                         do_mid_side = true;
201                         loose_mid_side = false;
202                         qlp_coeff_precision = 0;
203                         min_residual_partition_order = 0;
204                         max_residual_partition_order = 3;
205                         rice_parameter_search_dist = 0;
206                         max_lpc_order = 0;
207                 }
208                 else if(0 == strcmp(argv[i], "-3")) {
209                         do_exhaustive_model_search = false;
210                         do_mid_side = false;
211                         loose_mid_side = false;
212                         qlp_coeff_precision = 0;
213                         min_residual_partition_order = max_residual_partition_order = 3;
214                         rice_parameter_search_dist = 0;
215                         max_lpc_order = 6;
216                 }
217                 else if(0 == strcmp(argv[i], "-4")) {
218                         do_exhaustive_model_search = false;
219                         do_mid_side = true;
220                         loose_mid_side = true;
221                         qlp_coeff_precision = 0;
222                         min_residual_partition_order = max_residual_partition_order = 3;
223                         rice_parameter_search_dist = 0;
224                         max_lpc_order = 8;
225                 }
226                 else if(0 == strcmp(argv[i], "-5")) {
227                         do_exhaustive_model_search = false;
228                         do_mid_side = true;
229                         loose_mid_side = false;
230                         qlp_coeff_precision = 0;
231                         min_residual_partition_order = max_residual_partition_order = 3;
232                         rice_parameter_search_dist = 0;
233                         max_lpc_order = 8;
234                 }
235                 else if(0 == strcmp(argv[i], "-6")) {
236                         do_exhaustive_model_search = false;
237                         do_mid_side = true;
238                         loose_mid_side = false;
239                         qlp_coeff_precision = 0;
240                         min_residual_partition_order = 0;
241                         max_residual_partition_order = 4;
242                         rice_parameter_search_dist = 0;
243                         max_lpc_order = 8;
244                 }
245                 else if(0 == strcmp(argv[i], "-7")) {
246                         do_exhaustive_model_search = true;
247                         do_mid_side = true;
248                         loose_mid_side = false;
249                         qlp_coeff_precision = 0;
250                         min_residual_partition_order = 0;
251                         max_residual_partition_order = 6;
252                         rice_parameter_search_dist = 0;
253                         max_lpc_order = 8;
254                 }
255                 else if(0 == strcmp(argv[i], "-8")) {
256                         do_exhaustive_model_search = true;
257                         do_mid_side = true;
258                         loose_mid_side = false;
259                         qlp_coeff_precision = 0;
260                         min_residual_partition_order = 0;
261                         max_residual_partition_order = 6;
262                         rice_parameter_search_dist = 0;
263                         max_lpc_order = 12;
264                 }
265                 else if(0 == strcmp(argv[i], "-9")) {
266                         do_exhaustive_model_search = true;
267                         do_mid_side = true;
268                         loose_mid_side = false;
269                         do_qlp_coeff_prec_search = true;
270                         min_residual_partition_order = 0;
271                         max_residual_partition_order = 16;
272                         rice_parameter_search_dist = 0;
273                         max_lpc_order = 32;
274                 }
275                 else if(isdigit((int)(argv[i][1]))) {
276                         return usage("ERROR: compression level '%s' is still reserved\n", argv[i]);
277                 }
278                 else {
279                         return usage("ERROR: invalid option '%s'\n", argv[i]);
280                 }
281         }
282
283         /* tweak options; validate the values */
284         if(!mode_decode) {
285                 if(blocksize < 0) {
286                         if(max_lpc_order == 0)
287                                 blocksize = 1152;
288                         else
289                                 blocksize = 4608;
290                 }
291                 if(max_residual_partition_order < 0) {
292                         if(blocksize <= 1152)
293                                 max_residual_partition_order = 2;
294                         else if(blocksize <= 2304)
295                                 max_residual_partition_order = 3;
296                         else if(blocksize <= 4608)
297                                 max_residual_partition_order = 3;
298                         else
299                                 max_residual_partition_order = 4;
300                         min_residual_partition_order = max_residual_partition_order;
301                 }
302                 if(rice_parameter_search_dist < 0) {
303                         rice_parameter_search_dist = 0;
304                 }
305         }
306         else {
307                 if(test_only) {
308                         if(skip > 0)
309                                 return usage("ERROR: --skip is not allowed in test mode\n");
310                 }
311         }
312
313         FLAC__ASSERT(blocksize >= 0 || mode_decode);
314
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);
318         }
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);
322         }
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);
326         }
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);
329         }
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);
332         }
333
334         if(sector_align) {
335                 if(mode_decode)
336                         return usage("ERROR: --sector-align only allowed for encoding\n");
337                 else if(skip > 0)
338                         return usage("ERROR: --sector-align not allowed with --skip\n");
339                 else if(format_channels >= 0 && format_channels != 2)
340                         return usage("ERROR: --sector-align can only be done with stereo input\n");
341                 else if(format_sample_rate >= 0 && format_sample_rate != 2)
342                         return usage("ERROR: --sector-align can only be done with sample rate of 44100\n");
343         }
344         if(argc - i > 1 && cmdline_forced_outfilename) {
345                 return usage("ERROR: -o cannot be used with multiple files\n");
346         }
347         if(cmdline_forced_outfilename && output_prefix) {
348                 return usage("ERROR: --output-prefix conflicts with -o\n");
349         }
350
351         if(verbose) {
352                 fprintf(stderr, "\n");
353                 fprintf(stderr, "flac %s, Copyright (C) 2000,2001 Josh Coalson\n", FLAC__VERSION_STRING);
354                 fprintf(stderr, "flac comes with ABSOLUTELY NO WARRANTY.  This is free software, and you are\n");
355                 fprintf(stderr, "welcome to redistribute it under certain conditions.  Type `flac' for details.\n\n");
356
357                 if(!mode_decode) {
358                         fprintf(stderr, "options:%s%s%s -P %u -b %u%s -l %u%s%s -q %u -r %u,%u -R %u%s\n",
359                                 delete_input?" --delete-input-file":"", sector_align?" --sector-align":"", lax?" --lax":"",
360                                 padding, (unsigned)blocksize, loose_mid_side?" -M":do_mid_side?" -m":"", max_lpc_order,
361                                 do_exhaustive_model_search?" -e":"", do_qlp_coeff_prec_search?" -p":"",
362                                 qlp_coeff_precision,
363                                 (unsigned)min_residual_partition_order, (unsigned)max_residual_partition_order, (unsigned)rice_parameter_search_dist,
364                                 verify? " -V":""
365                         );
366                 }
367         }
368
369         if(mode_decode) {
370                 FLAC__bool first = true;
371                 int save_format;
372
373                 if(i == argc) {
374                         retval = decode_file("-", 0);
375                 }
376                 else {
377                         if(i + 1 != argc)
378                                 cmdline_forced_outfilename = 0;
379                         for(retval = 0; i < argc && retval == 0; i++) {
380                                 if(0 == strcmp(argv[i], "-") && !first)
381                                         continue;
382                                 save_format = format_is_wave;
383                                 retval = decode_file(argv[i], 0);
384                                 format_is_wave = save_format;
385                                 first = false;
386                         }
387                 }
388         }
389         else { /* encode */
390                 FLAC__bool first = true;
391                 int save_format;
392
393                 if(i == argc) {
394                         retval = encode_file("-", 0, true);
395                 }
396                 else {
397                         if(i + 1 != argc)
398                                 cmdline_forced_outfilename = 0;
399                         for(retval = 0; i < argc && retval == 0; i++) {
400                                 if(0 == strcmp(argv[i], "-") && !first)
401                                         continue;
402                                 save_format = format_is_wave;
403                                 retval = encode_file(argv[i], 0, i == (argc-1));
404                                 format_is_wave = save_format;
405                                 first = false;
406                         }
407                 }
408         }
409
410         return retval;
411 }
412
413 int usage(const char *message, ...)
414 {
415         va_list args;
416
417         if(message) {
418                 va_start(args, message);
419
420                 (void) vfprintf(stderr, message, args);
421
422                 va_end(args);
423
424         }
425         fprintf(stderr, "===============================================================================\n");
426         fprintf(stderr, "flac - Command-line FLAC encoder/decoder version %s\n", FLAC__VERSION_STRING);
427         fprintf(stderr, "Copyright (C) 2000,2001  Josh Coalson\n");
428         fprintf(stderr, "\n");
429         fprintf(stderr, "This program is free software; you can redistribute it and/or\n");
430         fprintf(stderr, "modify it under the terms of the GNU General Public License\n");
431         fprintf(stderr, "as published by the Free Software Foundation; either version 2\n");
432         fprintf(stderr, "of the License, or (at your option) any later version.\n");
433         fprintf(stderr, "\n");
434         fprintf(stderr, "This program is distributed in the hope that it will be useful,\n");
435         fprintf(stderr, "but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
436         fprintf(stderr, "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n");
437         fprintf(stderr, "GNU General Public License for more details.\n");
438         fprintf(stderr, "\n");
439         fprintf(stderr, "You should have received a copy of the GNU General Public License\n");
440         fprintf(stderr, "along with this program; if not, write to the Free Software\n");
441         fprintf(stderr, "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\n");
442         fprintf(stderr, "===============================================================================\n");
443         fprintf(stderr, "Usage:\n");
444         fprintf(stderr, "  flac [options] [infile [...]]\n");
445         fprintf(stderr, "\n");
446         fprintf(stderr, "For encoding:\n");
447         fprintf(stderr, "  the input file(s) may be a PCM RIFF WAVE file or raw samples\n");
448         fprintf(stderr, "  the output file(s) will be in FLAC format\n");
449         fprintf(stderr, "For decoding, the reverse is true\n");
450         fprintf(stderr, "\n");
451         fprintf(stderr, "A single 'infile' may be - for stdin.  No 'infile' implies stdin.  Use of\n");
452         fprintf(stderr, "stdin implies -c (write to stdout).  Normally you should use:\n");
453         fprintf(stderr, "   flac [options] -o outfilename  or  flac -d [options] -o outfilename\n");
454         fprintf(stderr, "instead of:\n");
455         fprintf(stderr, "   flac [options] > outfilename   or  flac -d [options] > outfilename\n");
456         fprintf(stderr, "since the former allows flac to seek backwards to write the STREAMINFO or\n");
457         fprintf(stderr, "RIFF WAVE header contents when necessary.\n");
458         fprintf(stderr, "\n");
459         fprintf(stderr, "If the unencoded filename ends with '.wav' or -fw is used, it's assumed to be\n");
460         fprintf(stderr, "RIFF WAVE.  Otherwise, flac will check for the presence of a RIFF header.  If\n");
461         fprintf(stderr, "any infile is raw you must specify the format options {-fb|fl} -fc -fp and -fs,\n");
462         fprintf(stderr, "which will apply to all raw files.  You can force a .wav file to be treated as\n");
463         fprintf(stderr, "a raw file using -fr.\n");
464         fprintf(stderr, "\n");
465         fprintf(stderr, "generic options:\n");
466         fprintf(stderr, "  -d : decode (default behavior is encode)\n");
467         fprintf(stderr, "  -t : test (same as -d except no decoded file is written)\n");
468         fprintf(stderr, "  -a : analyze (same as -d except an analysis file is written)\n");
469         fprintf(stderr, "  -c : write output to stdout\n");
470         fprintf(stderr, "  -s : silent (do not write runtime encode/decode statistics)\n");
471         fprintf(stderr, "  -o filename : force the output file name (usually flac just changes the\n");
472         fprintf(stderr, "                extension)\n");
473         fprintf(stderr, "  --delete-input-file : deletes the input file after a successful encode/decode\n");
474         fprintf(stderr, "  --skip samples : can be used both for encoding and decoding\n");
475         fprintf(stderr, "analyze options:\n");
476         fprintf(stderr, "  --a-rtext : include residual signal in text output\n");
477         fprintf(stderr, "  --a-rgp : generate gnuplot files of residual distribution of each subframe\n");
478         fprintf(stderr, "encoding options:\n");
479         fprintf(stderr, "  --lax : allow encoder to generate non-Subset files\n");
480         fprintf(stderr, "  --sector-align : align encoding of multiple files on sector boundaries\n");
481         fprintf(stderr, "  -S { # | X | #x } : include a point or points in a SEEKTABLE\n");
482         fprintf(stderr, "       #  : a specific sample number for a seek point\n");
483         fprintf(stderr, "       X  : a placeholder point (always goes at the end of the SEEKTABLE)\n");
484         fprintf(stderr, "       #x : # evenly spaced seekpoints, the first being at sample 0\n");
485         fprintf(stderr, "     You may use many -S options; the resulting SEEKTABLE will be the unique-\n");
486         fprintf(stderr, "           ified union of all such values.\n");
487         fprintf(stderr, "     With no -S options, flac defaults to '-S 100x'.  Use -S- for no SEEKTABLE.\n");
488         fprintf(stderr, "     Note: -S #x will not work if the encoder can't determine the input size\n");
489         fprintf(stderr, "           before starting.\n");
490         fprintf(stderr, "     Note: if you use -S # and # is >= samples in the input, there will be\n");
491         fprintf(stderr, "           either no seek point entered (if the input size is determinable\n");
492         fprintf(stderr, "           before encoding starts) or a placeholder point (if input size is not\n");
493         fprintf(stderr, "           determinable)\n");
494         fprintf(stderr, "  -P # : write a PADDING block of # bytes (goes after SEEKTABLE)\n");
495         fprintf(stderr, "         (0 => no PADDING block, default is -P 0)\n");
496         fprintf(stderr, "  -b # : specify blocksize in samples; default is 1152 for -l 0, else 4608;\n");
497         fprintf(stderr, "         must be 192/576/1152/2304/4608/256/512/1024/2048/4096/8192/16384/32768\n");
498         fprintf(stderr, "         (unless --lax is used)\n");
499         fprintf(stderr, "  -m   : try mid-side coding for each frame (stereo input only)\n");
500         fprintf(stderr, "  -M   : loose mid-side coding for all frames (stereo input only)\n");
501         fprintf(stderr, "  -0 .. -9 : fastest compression .. highest compression, default is -5\n");
502         fprintf(stderr, "             these are synonyms for other options:\n");
503         fprintf(stderr, "  -0   : synonymous with -l 0 -b 1152 -r 2,2\n");
504         fprintf(stderr, "  -1   : synonymous with -l 0 -b 1152 -M -r 2,2\n");
505         fprintf(stderr, "  -2   : synonymous with -l 0 -b 1152 -m -r 3\n");
506         fprintf(stderr, "  -3   : synonymous with -l 6 -b 4608 -r 3,3\n");
507         fprintf(stderr, "  -4   : synonymous with -l 8 -b 4608 -M -r 3,3\n");
508         fprintf(stderr, "  -5   : synonymous with -l 8 -b 4608 -m -r 3,3\n");
509         fprintf(stderr, "  -6   : synonymous with -l 8 -b 4608 -m -r 4\n");
510         fprintf(stderr, "  -7   : synonymous with -l 8 -b 4608 -m -e -r 6\n");
511         fprintf(stderr, "  -8   : synonymous with -l 12 -b 4608 -m -e -r 6\n");
512         fprintf(stderr, "  -9   : synonymous with -l 32 -b 4608 -m -e -r 16 -p (very slow!)\n");
513         fprintf(stderr, "  -e   : do exhaustive model search (expensive!)\n");
514         fprintf(stderr, "  -l # : specify max LPC order; 0 => use only fixed predictors\n");
515         fprintf(stderr, "  -p   : do exhaustive search of LP coefficient quantization (expensive!);\n");
516         fprintf(stderr, "         overrides -q, does nothing if using -l 0\n");
517         fprintf(stderr, "  -q # : specify precision in bits of quantized linear-predictor coefficients;\n");
518         fprintf(stderr, "         0 => let encoder decide (min is %u, default is -q 0)\n", FLAC__MIN_QLP_COEFF_PRECISION);
519         fprintf(stderr, "  -r [#,]# : [min,]max residual partition order (# is 0..16; min defaults to 0;\n");
520         fprintf(stderr, "         default is -r 0; above 4 doesn't usually help much)\n");
521         fprintf(stderr, "  -R # : Rice parameter search distance (# is 0..32; above 2 doesn't help much)\n");
522         fprintf(stderr, "  -V   : verify a correct encoding by decoding the output in parallel and\n");
523         fprintf(stderr, "         comparing to the original\n");
524         fprintf(stderr, "  -S-, -m-, -M-, -e-, -p-, -V-, --delete-input-file-, --lax-, --sector-align-\n");
525         fprintf(stderr, "  can all be used to turn off a particular option\n");
526         fprintf(stderr, "format options:\n");
527         fprintf(stderr, "  -fb | -fl : big-endian | little-endian byte order\n");
528         fprintf(stderr, "  -fc channels\n");
529         fprintf(stderr, "  -fp bits_per_sample\n");
530         fprintf(stderr, "  -fs sample_rate : in Hz\n");
531         fprintf(stderr, "  -fu : unsigned samples (default is signed)\n");
532         fprintf(stderr, "  -fr : force to raw format (even if filename ends in .wav)\n");
533         fprintf(stderr, "  -fw : force to RIFF WAVE\n");
534
535         return message? 1 : 0;
536 }
537
538 int encode_file(const char *infilename, const char *forced_outfilename, FLAC__bool is_last_file)
539 {
540         FILE *encode_infile;
541         char outfilename[4096]; /* @@@ bad MAGIC NUMBER */
542         char *p;
543         FLAC__byte lookahead[12];
544         unsigned lookahead_length = 0;
545         int retval;
546         long infilesize;
547
548         if(0 == strcmp(infilename, "-")) {
549                 infilesize = -1;
550                 encode_infile = stdin;
551         }
552         else {
553                 infilesize = flac__file_get_filesize(infilename);
554                 if(0 == (encode_infile = fopen(infilename, "rb"))) {
555                         fprintf(stderr, "ERROR: can't open input file %s\n", infilename);
556                         return 1;
557                 }
558         }
559
560         if(sector_align && !format_is_wave && infilesize < 0) {
561                 fprintf(stderr, "ERROR: can't --sector-align when the input size is unknown\n");
562                 return 1;
563         }
564
565         if(format_is_wave < 0) {
566                 /* first set format based on name */
567                 if(0 == strcasecmp(infilename+(strlen(infilename)-4), ".wav"))
568                         format_is_wave = true;
569                 else
570                         format_is_wave = false;
571
572                 /* attempt to guess the file type based on the first 12 bytes */
573                 if((lookahead_length = fread(lookahead, 1, 12, encode_infile)) < 12) {
574                         if(format_is_wave)
575                                 fprintf(stderr, "WARNING: %s is not a WAVE file, treating as a raw file\n", infilename);
576                         format_is_wave = false;
577                 }
578                 else {
579                         if(strncmp(lookahead, "RIFF", 4) || strncmp(lookahead+8, "WAVE", 4)) {
580                                 if(format_is_wave)
581                                         fprintf(stderr, "WARNING: %s is not a WAVE file, treating as a raw file\n", infilename);
582                                 format_is_wave = false;
583                         }
584                         else
585                                 format_is_wave = true;
586                 }
587         }
588
589         if(!format_is_wave) {
590                 if(format_is_big_endian < 0 || format_channels < 0 || format_bps < 0 || format_sample_rate < 0)
591                         return usage("ERROR: for encoding a raw file you must specify { -fb or -fl }, -fc, -fp, and -fs\n");
592         }
593
594         if(encode_infile == stdin || force_to_stdout)
595                 strcpy(outfilename, "-");
596         else {
597                 strcpy(outfilename, output_prefix? output_prefix : "");
598                 strcat(outfilename, infilename);
599                 if(0 == (p = strrchr(outfilename, '.')))
600                         strcat(outfilename, ".flac");
601                 else {
602                         if(0 == strcmp(p, ".flac"))
603                                 strcpy(p, "_new.flac");
604                         else
605                                 strcpy(p, ".flac");
606                 }
607         }
608         if(0 == forced_outfilename)
609                 forced_outfilename = outfilename;
610         if(0 != cmdline_forced_outfilename)
611                 forced_outfilename = cmdline_forced_outfilename;
612
613         if(format_is_wave)
614                 retval = flac__encode_wav(encode_infile, infilesize, infilename, forced_outfilename, lookahead, lookahead_length, align_reservoir, &align_reservoir_samples, sector_align, is_last_file, 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);
615         else
616                 retval = flac__encode_raw(encode_infile, infilesize, infilename, forced_outfilename, lookahead, lookahead_length, is_last_file, 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);
617
618         if(retval == 0 && strcmp(infilename, "-")) {
619                 if(strcmp(forced_outfilename, "-"))
620                         flac__file_copy_metadata(infilename, forced_outfilename);
621                 if(delete_input)
622                         unlink(infilename);
623         }
624
625         return 0;
626 }
627
628 int decode_file(const char *infilename, const char *forced_outfilename)
629 {
630         static const char *suffixes[] = { ".wav", ".raw", ".ana" };
631         char outfilename[4096]; /* @@@ bad MAGIC NUMBER */
632         char *p;
633         int retval;
634
635         if(!test_only && !analyze) {
636                 if(format_is_wave < 0) {
637                         format_is_wave = true;
638                 }
639                 if(!format_is_wave) {
640                         if(format_is_big_endian < 0)
641                                 return usage("ERROR: for decoding to a raw file you must specify -fb or -fl\n");
642                 }
643         }
644
645         if(0 == strcmp(infilename, "-") || force_to_stdout)
646                 strcpy(outfilename, "-");
647         else {
648                 const char *suffix = suffixes[analyze? 2 : format_is_wave? 0 : 1];
649                 strcpy(outfilename, output_prefix? output_prefix : "");
650                 strcat(outfilename, infilename);
651                 if(0 == (p = strrchr(outfilename, '.')))
652                         strcat(outfilename, suffix);
653                 else {
654                         if(0 == strcmp(p, suffix)) {
655                                 strcpy(p, "_new");
656                                 strcat(p, suffix);
657                         }
658                         else
659                                 strcpy(p, suffix);
660                 }
661         }
662         if(0 == forced_outfilename)
663                 forced_outfilename = outfilename;
664         if(0 != cmdline_forced_outfilename)
665                 forced_outfilename = cmdline_forced_outfilename;
666
667         if(format_is_wave)
668                 retval = flac__decode_wav(infilename, test_only? 0 : forced_outfilename, analyze, aopts, verbose, skip);
669         else
670                 retval = flac__decode_raw(infilename, test_only? 0 : forced_outfilename, analyze, aopts, verbose, skip, format_is_big_endian, format_is_unsigned_samples);
671
672         if(retval == 0 && strcmp(infilename, "-")) {
673                 if(strcmp(forced_outfilename, "-"))
674                         flac__file_copy_metadata(infilename, forced_outfilename);
675                 if(delete_input)
676                         unlink(infilename);
677         }
678
679         return 0;
680 }