2 * Command line parsing related functions
4 * Copyright (c) 1999 Mark Taylor
5 * 2000-2011 Robert Hegemann
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 /* $Id: parse.c,v 1.292 2011/11/01 16:59:57 robert Exp $ */
39 # define strrchr rindex
41 char *strchr(), *strrchr();
43 # define memcpy(d, s, n) bcopy ((s), (d), (n))
44 # define memmove(d, s, n) bcopy ((s), (d), (n))
57 #include "get_audio.h"
71 #if defined _ALLOW_INTERNAL_OPTIONS
72 #define INTERNAL_OPTS 1
74 #define INTERNAL_OPTS 0
77 #if (INTERNAL_OPTS!=0)
84 static int const lame_alpha_version_enabled = LAME_ALPHA_VERSION;
85 static int const internal_opts_enabled = INTERNAL_OPTS;
87 /* GLOBAL VARIABLES. set by parse_args() */
88 /* we need to clean this up */
90 ReaderConfig global_reader = { sf_unknown, 0, 0, 0 };
91 WriterConfig global_writer = { 0 };
93 UiConfig global_ui_config = {0,0,0,0};
95 DecoderConfig global_decoder;
97 RawPCMConfig global_raw_pcm =
98 { /* in_bitwidth */ 16
100 , /* in_endian */ ByteOrderLittleEndian
105 /* possible text encodings */
106 typedef enum TextEncoding
107 { TENC_RAW /* bytes will be stored as-is into ID3 tags, which are Latin1 per definition */
108 , TENC_LATIN1 /* text will be converted from local encoding to Latin1, as ID3 needs it */
109 , TENC_UTF16 /* text will be converted from local encoding to Unicode, as ID3v2 wants it */
113 #define ID3TAGS_EXTENDED
114 /* search for Zero termination in multi-byte strings */
116 strlenMultiByte(char const* str, size_t w)
123 for (i = 0; i < w; ++i) {
124 x += *str++ == 0 ? 1 : 0;
136 currCharCodeSize(void)
141 char* env_lang = getenv("LANG");
142 char* xxx_code = env_lang == NULL ? NULL : strrchr(env_lang, '.');
143 char* cur_code = xxx_code == NULL ? "" : xxx_code+1;
144 iconv_t xiconv = iconv_open(cur_code, "ISO_8859-1");
145 if (xiconv != (iconv_t)-1) {
146 for (n = 0; n < 32; ++n) {
151 size_t rc = iconv(xiconv, &i_ptr, &srcln, &o_ptr, &avail);
152 if (rc != (size_t)-1) {
163 char* fromLatin1( char* src )
167 size_t const l = strlen(src);
168 size_t const n = l*4;
169 dst = calloc(n+4, 4);
171 char* env_lang = getenv("LANG");
172 char* xxx_code = env_lang == NULL ? NULL : strrchr(env_lang, '.');
173 char* cur_code = xxx_code == NULL ? "" : xxx_code+1;
174 iconv_t xiconv = iconv_open(cur_code, "ISO_8859-1");
175 if (xiconv != (iconv_t)-1) {
180 iconv(xiconv, &i_ptr, &srcln, &o_ptr, &avail);
189 char* fromUtf16( char* src )
193 size_t const l = strlenMultiByte(src, 2);
194 size_t const n = l*4;
195 dst = calloc(n+4, 4);
197 char* env_lang = getenv("LANG");
198 char* xxx_code = env_lang == NULL ? NULL : strrchr(env_lang, '.');
199 char* cur_code = xxx_code == NULL ? "" : xxx_code+1;
200 iconv_t xiconv = iconv_open(cur_code, "UTF-16LE");
201 if (xiconv != (iconv_t)-1) {
202 char* i_ptr = (char*)src;
206 iconv(xiconv, &i_ptr, &srcln, &o_ptr, &avail);
216 char* toLatin1( char* src )
218 size_t w = currCharCodeSize();
221 size_t const l = strlenMultiByte(src, w);
222 size_t const n = l*4;
223 dst = calloc(n+4, 4);
225 char* env_lang = getenv("LANG");
226 char* xxx_code = env_lang == NULL ? NULL : strrchr(env_lang, '.');
227 char* cur_code = xxx_code == NULL ? "" : xxx_code+1;
228 iconv_t xiconv = iconv_open("ISO_8859-1//TRANSLIT", cur_code);
229 if (xiconv != (iconv_t)-1) {
230 char* i_ptr = (char*)src;
234 iconv(xiconv, &i_ptr, &srcln, &o_ptr, &avail);
244 char* toUtf16( char* src )
246 size_t w = currCharCodeSize();
249 size_t const l = strlenMultiByte(src, w);
250 size_t const n = (l+1)*4;
251 dst = calloc(n+4, 4);
253 char* env_lang = getenv("LANG");
254 char* xxx_code = env_lang == NULL ? NULL : strrchr(env_lang, '.');
255 char* cur_code = xxx_code == NULL ? "" : xxx_code+1;
256 iconv_t xiconv = iconv_open("UTF-16LE//TRANSLIT", cur_code);
259 if (xiconv != (iconv_t)-1) {
260 char* i_ptr = (char*)src;
261 char* o_ptr = &dst[2];
264 iconv(xiconv, &i_ptr, &srcln, &o_ptr, &avail);
273 #if defined( _WIN32 ) && !defined(__MINGW32__)
274 #define ID3TAGS_EXTENDED
276 char* toLatin1(char const* s)
278 return utf8ToLatin1(s);
281 unsigned short* toUtf16(char const* s)
283 return utf8ToUtf16(s);
289 set_id3v2tag(lame_global_flags* gfp, int type, unsigned short const* str)
293 case 'a': return id3tag_set_textinfo_utf16(gfp, "TPE1", str);
294 case 't': return id3tag_set_textinfo_utf16(gfp, "TIT2", str);
295 case 'l': return id3tag_set_textinfo_utf16(gfp, "TALB", str);
296 case 'g': return id3tag_set_textinfo_utf16(gfp, "TCON", str);
297 case 'c': return id3tag_set_comment_utf16(gfp, 0, 0, str);
298 case 'n': return id3tag_set_textinfo_utf16(gfp, "TRCK", str);
299 case 'y': return id3tag_set_textinfo_utf16(gfp, "TYER", str);
300 case 'v': return id3tag_set_fieldvalue_utf16(gfp, str);
307 set_id3tag(lame_global_flags* gfp, int type, char const* str)
311 case 'a': return id3tag_set_artist(gfp, str), 0;
312 case 't': return id3tag_set_title(gfp, str), 0;
313 case 'l': return id3tag_set_album(gfp, str), 0;
314 case 'g': return id3tag_set_genre(gfp, str);
315 case 'c': return id3tag_set_comment(gfp, str), 0;
316 case 'n': return id3tag_set_track(gfp, str);
317 case 'y': return id3tag_set_year(gfp, str), 0;
318 case 'v': return id3tag_set_fieldvalue(gfp, str);
324 id3_tag(lame_global_flags* gfp, int type, TextEncoding enc, char* str)
328 if (enc == TENC_UTF16 && type != 'v' ) {
329 id3_tag(gfp, type, TENC_LATIN1, str); /* for id3v1 */
334 #ifdef ID3TAGS_EXTENDED
335 case TENC_LATIN1: x = toLatin1(str); break;
336 case TENC_UTF16: x = toUtf16(str); break;
338 case TENC_RAW: x = strdup(str); break;
344 #ifdef ID3TAGS_EXTENDED
345 case TENC_LATIN1: result = set_id3tag(gfp, type, x); break;
346 case TENC_UTF16: result = set_id3v2tag(gfp, type, x); break;
348 case TENC_RAW: result = set_id3tag(gfp, type, x); break;
358 /************************************************************************
362 * PURPOSE: Writes version and license to the file specified by fp
364 ************************************************************************/
367 lame_version_print(FILE * const fp)
369 const char *b = get_lame_os_bitness();
370 const char *v = get_lame_version();
371 const char *u = get_lame_url();
372 const size_t lenb = strlen(b);
373 const size_t lenv = strlen(v);
374 const size_t lenu = strlen(u);
375 const size_t lw = 80; /* line width of terminal in characters */
376 const size_t sw = 16; /* static width of text */
378 if (lw >= lenb + lenv + lenu + sw || lw < lenu + 2)
379 /* text fits in 80 chars per line, or line even too small for url */
381 fprintf(fp, "LAME %s version %s (%s)\n\n", b, v, u);
383 fprintf(fp, "LAME version %s (%s)\n\n", v, u);
385 int const n_white_spaces = ((lenu+2) > lw ? 0 : lw-2-lenu);
386 /* text too long, wrap url into next line, right aligned */
388 fprintf(fp, "LAME %s version %s\n%*s(%s)\n\n", b, v, n_white_spaces, "", u);
390 fprintf(fp, "LAME version %s\n%*s(%s)\n\n", v, n_white_spaces, "", u);
392 if (lame_alpha_version_enabled)
393 fprintf(fp, "warning: alpha versions should be used for testing only\n\n");
400 print_license(FILE * const fp)
401 { /* print version & license */
402 lame_version_print(fp);
404 "Copyright (c) 1999-2011 by The LAME Project\n"
405 "Copyright (c) 1999,2000,2001 by Mark Taylor\n"
406 "Copyright (c) 1998 by Michael Cheng\n"
407 "Copyright (c) 1995,1996,1997 by Michael Hipp: mpglib\n" "\n");
409 "This library is free software; you can redistribute it and/or\n"
410 "modify it under the terms of the GNU Library General Public\n"
411 "License as published by the Free Software Foundation; either\n"
412 "version 2 of the License, or (at your option) any later version.\n"
414 "This library is distributed in the hope that it will be useful,\n"
415 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
416 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
417 "Library General Public License for more details.\n"
419 "You should have received a copy of the GNU Library General Public\n"
420 "License along with this program. If not, see\n"
421 "<http://www.gnu.org/licenses/>.\n");
426 /************************************************************************
430 * PURPOSE: Writes command line syntax to the file specified by fp
432 ************************************************************************/
435 usage(FILE * const fp, const char *ProgramName)
436 { /* print general syntax */
437 lame_version_print(fp);
439 "usage: %s [options] <infile> [outfile]\n"
441 " <infile> and/or <outfile> can be \"-\", which means stdin/stdout.\n"
444 " \"%s --help\" for general usage information\n"
446 " \"%s --preset help\" for information on suggested predefined settings\n"
448 " \"%s --longhelp\"\n"
449 " or \"%s -?\" for a complete options list\n\n",
450 ProgramName, ProgramName, ProgramName, ProgramName, ProgramName);
455 /************************************************************************
459 * PURPOSE: Writes command line syntax to the file specified by fp
460 * but only the most important ones, to fit on a vt100 terminal
462 ************************************************************************/
465 short_help(const lame_global_flags * gfp, FILE * const fp, const char *ProgramName)
466 { /* print short syntax help */
467 lame_version_print(fp);
469 "usage: %s [options] <infile> [outfile]\n"
471 " <infile> and/or <outfile> can be \"-\", which means stdin/stdout.\n"
472 "\n" "RECOMMENDED:\n" " lame -V2 input.wav output.mp3\n" "\n", ProgramName);
475 " -b bitrate set the bitrate, default 128 kbps\n"
476 " -h higher quality, but a little slower. Recommended.\n"
477 " -f fast mode (lower quality)\n"
478 " -V n quality setting for VBR. default n=%i\n"
479 " 0=high quality,bigger files. 9=smaller files\n",
480 lame_get_VBR_q(gfp));
482 " --preset type type must be \"medium\", \"standard\", \"extreme\", \"insane\",\n"
483 " or a value for an average desired bitrate and depending\n"
484 " on the value specified, appropriate quality settings will\n"
486 " \"--preset help\" gives more info on these\n" "\n");
489 " --priority type sets the process priority\n"
490 " 0,1 = Low priority\n"
491 " 2 = normal priority\n"
492 " 3,4 = High priority\n" "\n"
495 " --priority type sets the process priority\n"
496 " 0 = Low priority\n"
497 " 1 = Medium priority\n"
498 " 2 = Regular priority\n"
499 " 3 = High priority\n"
500 " 4 = Maximum priority\n" "\n"
502 " --help id3 ID3 tagging related options\n" "\n"
504 " --help dev developer options\n" "\n"
506 " --longhelp full list of options\n" "\n"
507 " --license print License information\n\n"
513 /************************************************************************
517 * PURPOSE: Writes command line syntax to the file specified by fp
519 ************************************************************************/
522 wait_for(FILE * const fp, int lessmode)
535 help_id3tag(FILE * const fp)
538 " ID3 tag options:\n"
539 " --tt <title> audio/song title (max 30 chars for version 1 tag)\n"
540 " --ta <artist> audio/song artist (max 30 chars for version 1 tag)\n"
541 " --tl <album> audio/song album (max 30 chars for version 1 tag)\n"
542 " --ty <year> audio/song year of issue (1 to 9999)\n"
543 " --tc <comment> user-defined text (max 30 chars for v1 tag, 28 for v1.1)\n"
544 " --tn <track[/total]> audio/song track number and (optionally) the total\n"
545 " number of tracks on the original recording. (track\n"
546 " and total each 1 to 255. just the track number\n"
547 " creates v1.1 tag, providing a total forces v2.0).\n"
548 " --tg <genre> audio/song genre (name or number in list)\n"
549 " --ti <file> audio/song albumArt (jpeg/png/gif file, v2.3 tag)\n"
550 " --tv <id=value> user-defined frame specified by id and value (v2.3 tag)\n"
553 " --add-id3v2 force addition of version 2 tag\n"
554 " --id3v1-only add only a version 1 tag\n"
555 " --id3v2-only add only a version 2 tag\n"
556 #ifdef ID3TAGS_EXTENDED
557 " --id3v2-utf16 add following options in unicode text encoding\n"
558 " --id3v2-latin1 add following options in latin-1 text encoding\n"
560 " --space-id3v1 pad version 1 tag with spaces instead of nulls\n"
561 " --pad-id3v2 same as '--pad-id3v2-size 128'\n"
562 " --pad-id3v2-size <value> adds version 2 tag, pad with extra <value> bytes\n"
563 " --genre-list print alphabetically sorted ID3 genre list and exit\n"
564 " --ignore-tag-errors ignore errors in values passed for tags\n" "\n"
567 " Note: A version 2 tag will NOT be added unless one of the input fields\n"
568 " won't fit in a version 1 tag (e.g. the title string is longer than 30\n"
569 " characters), or the '--add-id3v2' or '--id3v2-only' options are used,\n"
570 " or output is redirected to stdout.\n"
575 help_developer_switches(FILE * const fp)
577 if ( !internal_opts_enabled ) {
579 " Note: Almost all of the following switches aren't available in this build!\n\n"
584 " --noath turns ATH down to a flat noise floor\n"
585 " --athshort ignore GPSYCHO for short blocks, use ATH only\n"
586 " --athonly ignore GPSYCHO completely, use ATH only\n"
587 " --athtype n selects between different ATH types [0-4]\n"
588 " --athlower x lowers ATH by x dB\n"
591 " --athaa-type n ATH auto adjust: 0 'no' else 'loudness based'\n"
592 /** OBSOLETE " --athaa-loudapprox n n=1 total energy or n=2 equal loudness curve\n"*/
593 " --athaa-sensitivity x activation offset in -/+ dB for ATH auto-adjustment\n"
597 " --short use short blocks when appropriate\n"
598 " --noshort do not use short blocks\n"
599 " --allshort use only short blocks\n"
602 "(1) --temporal-masking x x=0 disables, x=1 enables temporal masking effect\n"
603 " --nssafejoint M/S switching criterion\n"
604 " --nsmsfix <arg> M/S switching tuning [effective 0-3.5]\n"
605 "(2) --interch x adjust inter-channel masking ratio\n"
606 " --ns-bass x adjust masking for sfbs 0 - 6 (long) 0 - 5 (short)\n"
607 " --ns-alto x adjust masking for sfbs 7 - 13 (long) 6 - 10 (short)\n"
608 " --ns-treble x adjust masking for sfbs 14 - 21 (long) 11 - 12 (short)\n"
611 " --ns-sfb21 x change ns-treble by x dB for sfb21\n"
612 " --shortthreshold x,y short block switching threshold,\n"
613 " x for L/R/M channel, y for S channel\n"
614 " -Z [n] always do calculate short block maskings\n"
615 " Noise Shaping related:\n"
616 "(1) --substep n use pseudo substep noise shaping method types 0-2\n"
617 "(1) -X n[,m] selects between different noise measurements\n"
618 " n for long block, m for short. if m is omitted, m = n\n"
619 " 1: CBR, ABR and VBR-old encoding modes only\n"
625 long_help(const lame_global_flags * gfp, FILE * const fp, const char *ProgramName, int lessmode)
626 { /* print long syntax help */
627 lame_version_print(fp);
629 "usage: %s [options] <infile> [outfile]\n"
631 " <infile> and/or <outfile> can be \"-\", which means stdin/stdout.\n"
632 "\n" "RECOMMENDED:\n" " lame -V2 input.wav output.mp3\n" "\n", ProgramName);
636 " --scale <arg> scale input (multiply PCM data) by <arg>\n"
637 " --scale-l <arg> scale channel 0 (left) input (multiply PCM data) by <arg>\n"
638 " --scale-r <arg> scale channel 1 (right) input (multiply PCM data) by <arg>\n"
639 #if (defined HAVE_MPGLIB || defined AMIGA_MPEGA)
640 " --mp1input input file is a MPEG Layer I file\n"
641 " --mp2input input file is a MPEG Layer II file\n"
642 " --mp3input input file is a MPEG Layer III file\n"
644 " --nogap <file1> <file2> <...>\n"
645 " gapless encoding for a set of contiguous files\n"
646 " --nogapout <dir>\n"
647 " output dir for gapless encoding (must precede --nogap)\n"
648 " --nogaptags allow the use of VBR tags in gapless encoding\n"
652 " Input options for RAW PCM:\n"
653 " -r input is raw pcm\n"
654 " -x force byte-swapping of input\n"
655 " -s sfreq sampling frequency of input file (kHz) - default 44.1 kHz\n"
656 " --bitwidth w input bit width is w (default 16)\n"
657 " --signed input is signed (default)\n"
658 " --unsigned input is unsigned\n"
659 " --little-endian input is little-endian (default)\n"
660 " --big-endian input is big-endian\n"
663 wait_for(fp, lessmode);
665 " Operational options:\n"
666 " -a downmix from stereo to mono file for mono encoding\n"
667 " -m <mode> (j)oint, (s)imple, (f)orce, (d)ual-mono, (m)ono (l)eft (r)ight\n"
668 " default is (j) or (s) depending on bitrate\n"
669 " joint = joins the best possible of MS and LR stereo\n"
670 " simple = force LR stereo on all frames\n"
671 " force = force MS stereo on all frames.\n"
672 " --preset type type must be \"medium\", \"standard\", \"extreme\", \"insane\",\n"
673 " or a value for an average desired bitrate and depending\n"
674 " on the value specified, appropriate quality settings will\n"
676 " \"--preset help\" gives more info on these\n"
677 " --comp <arg> choose bitrate to achieve a compression ratio of <arg>\n");
678 fprintf(fp, " --replaygain-fast compute RG fast but slightly inaccurately (default)\n"
679 #ifdef DECODE_ON_THE_FLY
680 " --replaygain-accurate compute RG more accurately and find the peak sample\n"
682 " --noreplaygain disable ReplayGain analysis\n"
683 #ifdef DECODE_ON_THE_FLY
684 " --clipdetect enable --replaygain-accurate and print a message whether\n"
685 " clipping occurs and how far the waveform is from full scale\n"
689 " --flush flush output stream as soon as possible\n"
690 " --freeformat produce a free format bitstream\n"
691 " --decode input=mp3 file, output=wav\n"
692 " --swap-channel swap L/R channels\n"
693 " -t disable writing wav header when using --decode\n");
695 wait_for(fp, lessmode);
698 " --disptime <arg>print progress report every arg seconds\n"
699 " -S don't print progress report, VBR histograms\n"
700 " --nohist disable VBR histogram display\n"
701 " --quiet don't print anything on screen\n"
702 " --silent don't print anything on screen, but fatal errors\n"
703 " --brief print more useful information\n"
704 " --verbose print a lot of useful information\n" "\n");
706 " Noise shaping & psycho acoustic algorithms:\n"
707 " -q <arg> <arg> = 0...9. Default -q 5 \n"
708 " -q 0: Highest quality, very slow \n"
709 " -q 9: Poor quality, but fast \n"
710 " -h Same as -q 2. Recommended.\n"
711 " -f Same as -q 7. Fast, ok quality\n");
713 wait_for(fp, lessmode);
715 " CBR (constant bitrate, the default) options:\n"
716 " -b <bitrate> set the bitrate in kbps, default 128 kbps\n"
717 " --cbr enforce use of constant bitrate\n"
720 " --abr <bitrate> specify average bitrate desired (instead of quality)\n" "\n");
723 " -V n quality setting for VBR. default n=%i\n"
724 " 0=high quality,bigger files. 9=smaller files\n"
725 " -v the same as -V 4\n"
726 " --vbr-old use old variable bitrate (VBR) routine\n"
727 " --vbr-new use new variable bitrate (VBR) routine (default)\n"
728 " -Y lets LAME ignore noise in sfb21, like in CBR\n"
730 lame_get_VBR_q(gfp));
732 " -b <bitrate> specify minimum allowed bitrate, default 32 kbps\n"
733 " -B <bitrate> specify maximum allowed bitrate, default 320 kbps\n"
734 " -F strictly enforce the -b option, for use with players that\n"
735 " do not support low bitrate mp3\n"
736 " -t disable writing LAME Tag\n"
737 " -T enable and force writing LAME Tag\n");
739 wait_for(fp, lessmode);
741 help_developer_switches(fp);
742 wait_for(fp, lessmode);
746 " MP3 header/stream options:\n"
747 " -e <emp> de-emphasis n/5/c (obsolete)\n"
748 " -c mark as copyright\n"
749 " -o mark as non-original\n"
750 " -p error protection. adds 16 bit checksum to every frame\n"
751 " (the checksum is computed correctly)\n"
752 " --nores disable the bit reservoir\n"
753 " --strictly-enforce-ISO comply as much as possible to ISO MPEG spec\n");
755 " --buffer-constraint <constraint> available values for constraint:\n"
756 " default, strict, maximum\n"
761 " --lowpass <freq> frequency(kHz), lowpass filter cutoff above freq\n"
762 " --lowpass-width <freq> frequency(kHz) - default 15%% of lowpass freq\n"
763 " --highpass <freq> frequency(kHz), highpass filter cutoff below freq\n"
764 " --highpass-width <freq> frequency(kHz) - default 15%% of highpass freq\n");
766 " --resample <sfreq> sampling frequency of output file(kHz)- default=automatic\n");
768 wait_for(fp, lessmode);
772 "\n\nMS-Windows-specific options:\n"
773 " --priority <type> sets the process priority:\n"
774 " 0,1 = Low priority (IDLE_PRIORITY_CLASS)\n"
775 " 2 = normal priority (NORMAL_PRIORITY_CLASS, default)\n"
776 " 3,4 = High priority (HIGH_PRIORITY_CLASS))\n"
777 " Note: Calling '--priority' without a parameter will select priority 0.\n"
780 "\n\nOS/2-specific options:\n"
781 " --priority <type> sets the process priority:\n"
782 " 0 = Low priority (IDLE, delta = 0)\n"
783 " 1 = Medium priority (IDLE, delta = +31)\n"
784 " 2 = Regular priority (REGULAR, delta = -31)\n"
785 " 3 = High priority (REGULAR, delta = 0)\n"
786 " 4 = Maximum priority (REGULAR, delta = +31)\n"
787 " Note: Calling '--priority' without a parameter will select priority 0.\n"
789 "\nMisc:\n --license print License information\n\n"
792 #if defined(HAVE_NASM)
793 wait_for(fp, lessmode);
795 " Platform specific:\n"
796 " --noasm <instructions> disable assembly optimizations for mmx/3dnow/sse\n");
797 wait_for(fp, lessmode);
800 display_bitrates(fp);
806 display_bitrate(FILE * const fp, const char *const version, const int d, const int indx)
815 "\nMPEG-%-3s layer III sample frequencies (kHz): %2d %2d %g\n"
816 "bitrates (kbps):", version, 32 / d, 48 / d, 44.1 / d);
817 for (i = 1; i <= nBitrates; i++)
818 fprintf(fp, " %2i", lame_get_bitrate(indx, i));
823 display_bitrates(FILE * const fp)
825 display_bitrate(fp, "1", 1, 1);
826 display_bitrate(fp, "2", 2, 0);
827 display_bitrate(fp, "2.5", 4, 0);
834 /* note: for presets it would be better to externalize them in a file.
835 suggestion: lame --preset <file-name> ...
836 or: lame --preset my-setting ... and my-setting is defined in lame.ini
840 Note from GB on 08/25/2002:
841 I am merging --presets and --alt-presets. Old presets are now aliases for
842 corresponding abr values from old alt-presets. This way we now have a
843 unified preset system, and I hope than more people will use the new tuned
844 presets instead of the old unmaintained ones.
849 /************************************************************************
853 * PURPOSE: Writes presetting info to #stdout#
855 ************************************************************************/
859 presets_longinfo_dm(FILE * msgfp)
863 "The --preset switches are aliases over LAME settings.\n"
866 "To activate these presets:\n"
867 "\n" " For VBR modes (generally highest quality):\n" "\n");
869 " \"--preset medium\" This preset should provide near transparency\n"
870 " to most people on most music.\n"
872 " \"--preset standard\" This preset should generally be transparent\n"
873 " to most people on most music and is already\n"
874 " quite high in quality.\n" "\n");
876 " \"--preset extreme\" If you have extremely good hearing and similar\n"
877 " equipment, this preset will generally provide\n"
878 " slightly higher quality than the \"standard\"\n"
881 " For CBR 320kbps (highest quality possible from the --preset switches):\n"
883 " \"--preset insane\" This preset will usually be overkill for most\n"
884 " people and most situations, but if you must\n"
885 " have the absolute highest quality with no\n"
886 " regard to filesize, this is the way to go.\n" "\n");
888 " For ABR modes (high quality per given bitrate but not as high as VBR):\n"
890 " \"--preset <kbps>\" Using this preset will usually give you good\n"
891 " quality at a specified bitrate. Depending on the\n"
892 " bitrate entered, this preset will determine the\n");
894 " optimal settings for that particular situation.\n"
895 " While this approach works, it is not nearly as\n"
896 " flexible as VBR, and usually will not attain the\n"
897 " same level of quality as VBR at higher bitrates.\n" "\n");
899 "The following options are also available for the corresponding profiles:\n"
904 " <cbr> (ABR Mode) - The ABR Mode is implied. To use it,\n"
905 " simply specify a bitrate. For example:\n"
906 " \"--preset 185\" activates this\n"
907 " preset and uses 185 as an average kbps.\n" "\n");
909 " \"cbr\" - If you use the ABR mode (read above) with a significant\n"
910 " bitrate such as 80, 96, 112, 128, 160, 192, 224, 256, 320,\n"
911 " you can use the \"cbr\" option to force CBR mode encoding\n"
912 " instead of the standard abr mode. ABR does provide higher\n"
913 " quality but CBR may be useful in situations such as when\n"
914 " streaming an mp3 over the internet may be important.\n" "\n");
918 " \"--preset standard <input file> <output file>\"\n"
919 " or \"--preset cbr 192 <input file> <output file>\"\n"
920 " or \"--preset 172 <input file> <output file>\"\n"
921 " or \"--preset extreme <input file> <output file>\"\n" "\n" "\n");
923 "A few aliases are also available for ABR mode:\n"
924 "phone => 16kbps/mono phon+/lw/mw-eu/sw => 24kbps/mono\n"
925 "mw-us => 40kbps/mono voice => 56kbps/mono\n"
926 "fm/radio/tape => 112kbps hifi => 160kbps\n"
927 "cd => 192kbps studio => 256kbps\n");
932 presets_set(lame_t gfp, int fast, int cbr, const char *preset_name, const char *ProgramName)
936 if ((strcmp(preset_name, "help") == 0) && (fast < 1)
938 lame_version_print(stdout);
939 presets_longinfo_dm(stdout);
943 /*aliases for compatibility with old presets */
945 if (strcmp(preset_name, "phone") == 0) {
949 if ((strcmp(preset_name, "phon+") == 0) ||
950 (strcmp(preset_name, "lw") == 0) ||
951 (strcmp(preset_name, "mw-eu") == 0) || (strcmp(preset_name, "sw") == 0)) {
955 if (strcmp(preset_name, "mw-us") == 0) {
959 if (strcmp(preset_name, "voice") == 0) {
963 if (strcmp(preset_name, "fm") == 0) {
966 if ((strcmp(preset_name, "radio") == 0) || (strcmp(preset_name, "tape") == 0)) {
969 if (strcmp(preset_name, "hifi") == 0) {
972 if (strcmp(preset_name, "cd") == 0) {
975 if (strcmp(preset_name, "studio") == 0) {
979 if (strcmp(preset_name, "medium") == 0) {
980 lame_set_VBR_q(gfp, 4);
981 lame_set_VBR(gfp, vbr_default);
985 if (strcmp(preset_name, "standard") == 0) {
986 lame_set_VBR_q(gfp, 2);
987 lame_set_VBR(gfp, vbr_default);
991 else if (strcmp(preset_name, "extreme") == 0) {
992 lame_set_VBR_q(gfp, 0);
993 lame_set_VBR(gfp, vbr_default);
997 else if ((strcmp(preset_name, "insane") == 0) && (fast < 1)) {
999 lame_set_preset(gfp, INSANE);
1004 /* Generic ABR Preset */
1005 if (((atoi(preset_name)) > 0) && (fast < 1)) {
1006 if ((atoi(preset_name)) >= 8 && (atoi(preset_name)) <= 320) {
1007 lame_set_preset(gfp, atoi(preset_name));
1010 lame_set_VBR(gfp, vbr_off);
1013 lame_set_mode(gfp, MONO);
1020 lame_version_print(Console_IO.Error_fp);
1021 error_printf("Error: The bitrate specified is out of the valid range for this preset\n"
1023 "When using this mode you must enter a value between \"32\" and \"320\"\n"
1024 "\n" "For further information try: \"%s --preset help\"\n", ProgramName);
1029 lame_version_print(Console_IO.Error_fp);
1030 error_printf("Error: You did not enter a valid profile and/or options with --preset\n"
1032 "Available profiles are:\n"
1038 " <cbr> (ABR Mode) - The ABR Mode is implied. To use it,\n"
1039 " simply specify a bitrate. For example:\n"
1040 " \"--preset 185\" activates this\n"
1041 " preset and uses 185 as an average kbps.\n" "\n");
1042 error_printf(" Some examples:\n"
1044 " or \"%s --preset standard <input file> <output file>\"\n"
1045 " or \"%s --preset cbr 192 <input file> <output file>\"\n"
1046 " or \"%s --preset 172 <input file> <output file>\"\n"
1047 " or \"%s --preset extreme <input file> <output file>\"\n"
1049 "For further information try: \"%s --preset help\"\n", ProgramName, ProgramName,
1050 ProgramName, ProgramName, ProgramName);
1055 genre_list_handler(int num, const char *name, void *cookie)
1058 console_printf("%3d %s\n", num, name);
1062 /************************************************************************
1066 * PURPOSE: Sets encoding parameters to the specifications of the
1067 * command line. Default settings are used for parameters
1068 * not specified in the command line.
1070 * If the input file is in WAVE or AIFF format, the sampling frequency is read
1071 * from the AIFF header.
1073 * The input and output filenames are read into #inpath# and #outpath#.
1075 ************************************************************************/
1077 /* would use real "strcasecmp" but it isn't portable */
1079 local_strcasecmp(const char *s1, const char *s2)
1085 c1 = (unsigned char) tolower(*s1);
1086 c2 = (unsigned char) tolower(*s2);
1097 local_strncasecmp(const char *s1, const char *s2, int n)
1099 unsigned char c1 = 0;
1100 unsigned char c2 = 0;
1107 c1 = (unsigned char) tolower(*s1);
1108 c2 = (unsigned char) tolower(*s2);
1121 /* LAME is a simple frontend which just uses the file extension */
1122 /* to determine the file type. Trying to analyze the file */
1123 /* contents is well beyond the scope of LAME and should not be added. */
1125 filename_to_type(const char *FileName)
1127 size_t len = strlen(FileName);
1132 FileName += len - 4;
1133 if (0 == local_strcasecmp(FileName, ".mpg"))
1135 if (0 == local_strcasecmp(FileName, ".mp1"))
1137 if (0 == local_strcasecmp(FileName, ".mp2"))
1139 if (0 == local_strcasecmp(FileName, ".mp3"))
1141 if (0 == local_strcasecmp(FileName, ".wav"))
1143 if (0 == local_strcasecmp(FileName, ".aif"))
1145 if (0 == local_strcasecmp(FileName, ".raw"))
1147 if (0 == local_strcasecmp(FileName, ".ogg"))
1153 resample_rate(double freq)
1158 switch ((int) freq) {
1178 error_printf("Illegal resample frequency: %.3f kHz\n", freq);
1192 size_t scanPath(char const* s, char const** a, char const** b)
1219 size_t scanBasename(char const* s, char const** a, char const** b)
1238 if (*s1 == SLASH || *s1 == ':') {
1252 int isCommonSuffix(char const* s_ext)
1255 { ".WAV", ".RAW", ".MP1", ".MP2"
1256 , ".MP3", ".MPG", ".MPA", ".CDA"
1257 , ".OGG", ".AIF", ".AIFF", ".AU"
1258 , ".SND", ".FLAC", ".WV", ".OFR"
1259 , ".TAK", ".MP4", ".M4A", ".PCM"
1262 for (i = 0; i < sizeof(suffixes); ++i) {
1263 if (local_strcasecmp(s_ext, suffixes[i]) == 0) {
1272 int generateOutPath(lame_t gfp, char const* inPath, char const* outDir, char* outPath)
1274 size_t const max_path = PATH_MAX;
1275 char const* s_ext = lame_get_decode_only(gfp) ? ".wav" : ".mp3";
1278 int out_dir_used = 0;
1280 if (outDir != 0 && outDir[0] != 0) {
1283 outPath[i++] = *outDir++;
1284 if (i >= max_path) {
1285 goto err_generateOutPath;
1288 if (i > 0 && outPath[i-1] != SLASH) {
1289 outPath[i++] = SLASH;
1290 if (i >= max_path) {
1291 goto err_generateOutPath;
1299 size_t j, n = scanPath(inPath, &pa, &pb);
1300 if (i+n >= max_path) {
1301 goto err_generateOutPath;
1303 for (j = 0; j < n; ++j) {
1304 outPath[i++] = pa[j];
1307 outPath[i++] = SLASH;
1308 if (i >= max_path) {
1309 goto err_generateOutPath;
1315 int replace_suffix = 0;
1318 size_t j, n = scanBasename(inPath, &na, &nb);
1319 if (i+n >= max_path) {
1320 goto err_generateOutPath;
1322 for (j = 0; j < n; ++j) {
1323 outPath[i++] = na[j];
1326 if (isCommonSuffix(nb) == 1) {
1328 if (out_dir_used == 0) {
1329 if (local_strcasecmp(nb, s_ext) == 0) {
1334 if (replace_suffix == 0) {
1336 outPath[i++] = *nb++;
1337 if (i >= max_path) {
1338 goto err_generateOutPath;
1344 if (i+5 >= max_path) {
1345 goto err_generateOutPath;
1348 outPath[i++] = *s_ext++;
1352 err_generateOutPath:
1353 error_printf( "error: output file name too long" );
1356 strncpy(outPath, inPath, PATH_MAX + 1 - 4);
1357 strncat(outPath, s_ext, 4);
1364 set_id3_albumart(lame_t gfp, char const* file_name)
1370 if (file_name == 0) {
1373 fpi = lame_fopen(file_name, "rb");
1380 fseek(fpi, 0, SEEK_END);
1382 fseek(fpi, 0, SEEK_SET);
1383 albumart = (char *)malloc(size);
1388 if (fread(albumart, 1, size, fpi) != size) {
1392 ret = id3tag_set_albumart(gfp, albumart, size) ? 4 : 0;
1399 case 1: error_printf("Could not find: '%s'.\n", file_name); break;
1400 case 2: error_printf("Insufficient memory for reading the albumart.\n"); break;
1401 case 3: error_printf("Read error: '%s'.\n", file_name); break;
1402 case 4: error_printf("Unsupported image: '%s'.\nSpecify JPEG/PNG/GIF image\n", file_name); break;
1410 { ID3TAG_MODE_DEFAULT
1411 , ID3TAG_MODE_V1_ONLY
1412 , ID3TAG_MODE_V2_ONLY
1415 /* Ugly, NOT final version */
1417 #define T_IF(str) if ( 0 == local_strcasecmp (token,str) ) {
1418 #define T_ELIF(str) } else if ( 0 == local_strcasecmp (token,str) ) {
1419 #define T_ELIF_INTERNAL(str) } else if (internal_opts_enabled && (0 == local_strcasecmp (token,str)) ) {
1420 #define T_ELIF2(str1,str2) } else if ( 0 == local_strcasecmp (token,str1) || 0 == local_strcasecmp (token,str2) ) {
1421 #define T_ELSE } else {
1425 parse_args(lame_global_flags * gfp, int argc, char **argv,
1426 char *const inPath, char *const outPath, char **nogap_inPath, int *num_nogap)
1428 char outDir[1024] = "";
1429 int input_file = 0; /* set to 1 if we parse an input file name */
1431 int autoconvert = 0;
1434 int nogap_tags = 0; /* set to 1 to use VBR tags in NOGAP mode */
1435 const char *ProgramName = argv[0];
1436 int count_nogap = 0;
1437 int noreplaygain = 0; /* is RG explicitly disabled by the user */
1438 int id3tag_mode = ID3TAG_MODE_DEFAULT;
1439 int ignore_tag_errors = 0; /* Ignore errors in values passed for tags */
1440 #ifdef ID3TAGS_EXTENDED
1441 enum TextEncoding id3_tenc = TENC_UTF16;
1443 enum TextEncoding id3_tenc = TENC_LATIN1;
1448 /* turn on display options. user settings may turn them off below */
1449 global_ui_config.silent = 0;
1450 global_ui_config.brhist = 1;
1451 global_decoder.mp3_delay = 0;
1452 global_decoder.mp3_delay_set = 0;
1453 global_decoder.disable_wav_header = 0;
1454 global_ui_config.print_clipping_info = 0;
1458 for (i = 0; ++i < argc;) {
1466 if (*token++ == '-') {
1468 nextArg = i + 1 < argc ? argv[i + 1] : "";
1470 if (!*token) { /* The user wants to use stdin and/or stdout. */
1472 if (inPath[0] == '\0')
1473 strncpy(inPath, argv[i], PATH_MAX + 1);
1474 else if (outPath[0] == '\0')
1475 strncpy(outPath, argv[i], PATH_MAX + 1);
1477 if (*token == '-') { /* GNU style */
1482 (void) lame_set_out_samplerate(gfp, resample_rate(atof(nextArg)));
1485 lame_set_VBR(gfp, vbr_rh);
1488 lame_set_VBR(gfp, vbr_mt);
1491 lame_set_VBR(gfp, vbr_mtrh);
1494 lame_set_VBR(gfp, vbr_off);
1497 /* values larger than 8000 are bps (like Fraunhofer), so it's strange to get 320000 bps MP3 when specifying 8000 bps MP3 */
1498 int m = atoi(nextArg);
1501 m = (m + 500) / 1000;
1509 lame_set_VBR(gfp, vbr_abr);
1510 lame_set_VBR_mean_bitrate_kbps(gfp, m);
1513 lame_set_preset(gfp, R3MIX);
1517 global_raw_pcm.in_bitwidth = atoi(nextArg);
1520 global_raw_pcm.in_signed = 1;
1523 global_raw_pcm.in_signed = 0;
1525 T_ELIF("little-endian")
1526 global_raw_pcm.in_endian = ByteOrderLittleEndian;
1528 T_ELIF("big-endian")
1529 global_raw_pcm.in_endian = ByteOrderBigEndian;
1532 global_reader.input_format = sf_mp1;
1535 global_reader.input_format = sf_mp2;
1538 global_reader.input_format = sf_mp3;
1541 error_printf("sorry, vorbis support in LAME is deprecated.\n");
1544 T_ELIF_INTERNAL("noshort")
1545 (void) lame_set_no_short_blocks(gfp, 1);
1547 T_ELIF_INTERNAL("short")
1548 (void) lame_set_no_short_blocks(gfp, 0);
1550 T_ELIF_INTERNAL("allshort")
1551 (void) lame_set_force_short_blocks(gfp, 1);
1555 (void) lame_set_decode_only(gfp, 1);
1558 global_writer.flush_write = 1;
1560 T_ELIF("decode-mp3delay")
1561 global_decoder.mp3_delay = atoi(nextArg);
1562 global_decoder.mp3_delay_set = 1;
1566 lame_set_disable_reservoir(gfp, 1);
1568 T_ELIF("strictly-enforce-ISO")
1569 lame_set_strict_ISO(gfp, MDB_STRICT_ISO);
1571 T_ELIF("buffer-constraint")
1573 if (strcmp(nextArg, "default") == 0)
1574 (void) lame_set_strict_ISO(gfp, MDB_DEFAULT);
1575 else if (strcmp(nextArg, "strict") == 0)
1576 (void) lame_set_strict_ISO(gfp, MDB_STRICT_ISO);
1577 else if (strcmp(nextArg, "maximum") == 0)
1578 (void) lame_set_strict_ISO(gfp, MDB_MAXIMUM);
1580 error_printf("unknown buffer constraint '%s'\n", nextArg);
1586 (void) lame_set_scale(gfp, (float) atof(nextArg));
1590 (void) lame_set_scale_left(gfp, (float) atof(nextArg));
1594 (void) lame_set_scale_right(gfp, (float) atof(nextArg));
1598 if (!strcmp(nextArg, "mmx"))
1599 (void) lame_set_asm_optimizations(gfp, MMX, 0);
1600 if (!strcmp(nextArg, "3dnow"))
1601 (void) lame_set_asm_optimizations(gfp, AMD_3DNOW, 0);
1602 if (!strcmp(nextArg, "sse"))
1603 (void) lame_set_asm_optimizations(gfp, SSE, 0);
1605 T_ELIF("freeformat")
1606 lame_set_free_format(gfp, 1);
1608 T_ELIF("replaygain-fast")
1609 lame_set_findReplayGain(gfp, 1);
1611 #ifdef DECODE_ON_THE_FLY
1612 T_ELIF("replaygain-accurate")
1613 lame_set_decode_on_the_fly(gfp, 1);
1614 lame_set_findReplayGain(gfp, 1);
1617 T_ELIF("noreplaygain")
1619 lame_set_findReplayGain(gfp, 0);
1622 #ifdef DECODE_ON_THE_FLY
1623 T_ELIF("clipdetect")
1624 global_ui_config.print_clipping_info = 1;
1625 lame_set_decode_on_the_fly(gfp, 1);
1629 global_ui_config.brhist = 0;
1631 #if defined(__OS2__) || defined(WIN32)
1634 int priority = (int) strtol(nextArg, &endptr, 10);
1635 if (endptr != nextArg) {
1638 setProcessPriority(priority);
1641 /* options for ID3 tag */
1642 #ifdef ID3TAGS_EXTENDED
1643 T_ELIF2("id3v2-utf16","id3v2-ucs2") /* id3v2-ucs2 for compatibility only */
1644 id3_tenc = TENC_UTF16;
1647 T_ELIF("id3v2-latin1")
1648 id3_tenc = TENC_LATIN1;
1654 id3_tag(gfp, 't', id3_tenc, nextArg);
1658 id3_tag(gfp, 'a', id3_tenc, nextArg);
1662 id3_tag(gfp, 'l', id3_tenc, nextArg);
1666 id3_tag(gfp, 'y', id3_tenc, nextArg);
1670 id3_tag(gfp, 'c', id3_tenc, nextArg);
1673 int ret = id3_tag(gfp, 'n', id3_tenc, nextArg);
1676 if (0 == ignore_tag_errors) {
1677 if (id3tag_mode == ID3TAG_MODE_V1_ONLY) {
1678 if (global_ui_config.silent < 9) {
1679 error_printf("The track number has to be between 1 and 255 for ID3v1.\n");
1683 else if (id3tag_mode == ID3TAG_MODE_V2_ONLY) {
1684 /* track will be stored as-is in ID3v2 case, so no problem here */
1687 if (global_ui_config.silent < 9) {
1688 error_printf("The track number has to be between 1 and 255 for ID3v1, ignored for ID3v1.\n");
1695 int ret = id3_tag(gfp, 'g', id3_tenc, nextArg);
1698 if (0 == ignore_tag_errors) {
1700 error_printf("Unknown ID3v1 genre number: '%s'.\n", nextArg);
1703 else if (ret == -2) {
1704 if (id3tag_mode == ID3TAG_MODE_V1_ONLY) {
1705 error_printf("Unknown ID3v1 genre: '%s'.\n", nextArg);
1708 else if (id3tag_mode == ID3TAG_MODE_V2_ONLY) {
1709 /* genre will be stored as-is in ID3v2 case, so no problem here */
1712 if (global_ui_config.silent < 9) {
1713 error_printf("Unknown ID3v1 genre: '%s'. Setting ID3v1 genre to 'Other'\n", nextArg);
1718 if (global_ui_config.silent < 10)
1719 error_printf("Internal error.\n");
1727 if (id3_tag(gfp, 'v', id3_tenc, nextArg)) {
1728 if (global_ui_config.silent < 9) {
1729 error_printf("Invalid field value: '%s'. Ignored\n", nextArg);
1735 if (set_id3_albumart(gfp, nextArg) != 0) {
1736 if (! ignore_tag_errors) {
1741 T_ELIF("ignore-tag-errors")
1742 ignore_tag_errors = 1;
1747 T_ELIF("id3v1-only")
1748 id3tag_v1_only(gfp);
1749 id3tag_mode = ID3TAG_MODE_V1_ONLY;
1751 T_ELIF("id3v2-only")
1752 id3tag_v2_only(gfp);
1753 id3tag_mode = ID3TAG_MODE_V2_ONLY;
1755 T_ELIF("space-id3v1")
1756 id3tag_space_v1(gfp);
1761 T_ELIF("pad-id3v2-size")
1762 int n = atoi(nextArg);
1763 n = n <= 128000 ? n : 128000;
1765 id3tag_set_pad(gfp, n);
1769 T_ELIF("genre-list")
1770 id3tag_genre_list(genre_list_handler, NULL);
1775 val = atof(nextArg);
1778 lame_set_lowpassfreq(gfp, -1);
1781 /* useful are 0.001 kHz...50 kHz, 50 Hz...50000 Hz */
1782 if (val < 0.001 || val > 50000.) {
1783 error_printf("Must specify lowpass with --lowpass freq, freq >= 0.001 kHz\n");
1786 lame_set_lowpassfreq(gfp, (int) (val * (val < 50. ? 1.e3 : 1.e0) + 0.5));
1789 T_ELIF("lowpass-width")
1790 val = atof(nextArg);
1792 /* useful are 0.001 kHz...16 kHz, 16 Hz...50000 Hz */
1793 if (val < 0.001 || val > 50000.) {
1795 ("Must specify lowpass width with --lowpass-width freq, freq >= 0.001 kHz\n");
1798 lame_set_lowpasswidth(gfp, (int) (val * (val < 16. ? 1.e3 : 1.e0) + 0.5));
1801 val = atof(nextArg);
1804 lame_set_highpassfreq(gfp, -1);
1807 /* useful are 0.001 kHz...16 kHz, 16 Hz...50000 Hz */
1808 if (val < 0.001 || val > 50000.) {
1809 error_printf("Must specify highpass with --highpass freq, freq >= 0.001 kHz\n");
1812 lame_set_highpassfreq(gfp, (int) (val * (val < 16. ? 1.e3 : 1.e0) + 0.5));
1815 T_ELIF("highpass-width")
1816 val = atof(nextArg);
1818 /* useful are 0.001 kHz...16 kHz, 16 Hz...50000 Hz */
1819 if (val < 0.001 || val > 50000.) {
1821 ("Must specify highpass width with --highpass-width freq, freq >= 0.001 kHz\n");
1824 lame_set_highpasswidth(gfp, (int) val);
1828 val = atof(nextArg);
1830 error_printf("Must specify compression ratio >= 1.0\n");
1833 lame_set_compression_ratio(gfp, (float) val);
1835 T_ELIF_INTERNAL("notemp")
1836 (void) lame_set_useTemporal(gfp, 0);
1838 T_ELIF_INTERNAL("interch")
1840 (void) lame_set_interChRatio(gfp, (float) atof(nextArg));
1842 T_ELIF_INTERNAL("temporal-masking")
1844 (void) lame_set_useTemporal(gfp, atoi(nextArg) ? 1 : 0);
1846 T_ELIF_INTERNAL("nspsytune")
1849 T_ELIF_INTERNAL("nssafejoint")
1850 lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2);
1852 T_ELIF_INTERNAL("nsmsfix")
1854 (void) lame_set_msfix(gfp, atof(nextArg));
1856 T_ELIF_INTERNAL("ns-bass")
1869 lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (k << 2));
1872 T_ELIF_INTERNAL("ns-alto")
1885 lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (k << 8));
1888 T_ELIF_INTERNAL("ns-treble")
1901 lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (k << 14));
1904 T_ELIF_INTERNAL("ns-sfb21")
1905 /* to be compatible with Naoki's original code,
1906 * ns-sfb21 specifies how to change ns-treble for sfb21 */
1919 lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (k << 20));
1922 /* some more GNU-ish options could be added
1923 * brief => few messages on screen (name, status report)
1924 * o/output file => specifies output filename
1926 * i/input file => specifies input filename
1930 global_ui_config.silent = 10; /* on a scale from 1 to 10 be very silent */
1933 global_ui_config.silent = 9;
1936 global_ui_config.silent = -5; /* print few info on screen */
1939 global_ui_config.silent = -10; /* print a lot on screen */
1941 T_ELIF2("version", "license")
1942 print_license(stdout);
1945 T_ELIF2("help", "usage")
1946 if (0 == local_strncasecmp(nextArg, "id3", 3)) {
1947 help_id3tag(stdout);
1949 else if (0 == local_strncasecmp(nextArg, "dev", 3)) {
1950 help_developer_switches(stdout);
1953 short_help(gfp, stdout, ProgramName);
1958 long_help(gfp, stdout, ProgramName, 0 /* lessmode=NO */ );
1963 FILE *fp = popen("less -Mqc", "w");
1964 long_help(gfp, fp, ProgramName, 0 /* lessmode=NO */ );
1967 long_help(gfp, stdout, ProgramName, 1 /* lessmode=YES */ );
1971 T_ELIF2("preset", "alt-preset")
1974 int fast = 0, cbr = 0;
1976 while ((strcmp(nextArg, "fast") == 0) || (strcmp(nextArg, "cbr") == 0)) {
1978 if ((strcmp(nextArg, "fast") == 0) && (fast < 1))
1980 if ((strcmp(nextArg, "cbr") == 0) && (cbr < 1))
1984 nextArg = i + argUsed < argc ? argv[i + argUsed] : "";
1987 if (presets_set(gfp, fast, cbr, nextArg, ProgramName) < 0)
1993 global_ui_config.update_interval = (float) atof(nextArg);
1999 /* FIXME: replace strcpy by safer strncpy */
2000 strcpy(outPath, nextArg);
2004 /* FIXME: replace strcpy by safer strncpy */
2005 strcpy(outDir, nextArg);
2011 T_ELIF("swap-channel")
2012 global_reader.swap_channel = 1;
2014 T_ELIF_INTERNAL("tune") /*without helptext */
2016 lame_set_tune(gfp, (float) atof(nextArg));
2018 T_ELIF_INTERNAL("shortthreshold") {
2020 int n = sscanf(nextArg, "%f,%f", &x, &y);
2025 (void) lame_set_short_threshold(gfp, x, y);
2028 T_ELIF_INTERNAL("maskingadjust") /*without helptext */
2030 (void) lame_set_maskingadjust(gfp, (float) atof(nextArg));
2032 T_ELIF_INTERNAL("maskingadjustshort") /*without helptext */
2034 (void) lame_set_maskingadjust_short(gfp, (float) atof(nextArg));
2036 T_ELIF_INTERNAL("athcurve") /*without helptext */
2038 (void) lame_set_ATHcurve(gfp, (float) atof(nextArg));
2040 T_ELIF_INTERNAL("no-preset-tune") /*without helptext */
2041 (void) lame_set_preset_notune(gfp, 0);
2043 T_ELIF_INTERNAL("substep")
2045 (void) lame_set_substep(gfp, atoi(nextArg));
2047 T_ELIF_INTERNAL("sbgain") /*without helptext */
2049 (void) lame_set_subblock_gain(gfp, atoi(nextArg));
2051 T_ELIF_INTERNAL("sfscale") /*without helptext */
2052 (void) lame_set_sfscale(gfp, 1);
2054 T_ELIF_INTERNAL("noath")
2055 (void) lame_set_noATH(gfp, 1);
2057 T_ELIF_INTERNAL("athonly")
2058 (void) lame_set_ATHonly(gfp, 1);
2060 T_ELIF_INTERNAL("athshort")
2061 (void) lame_set_ATHshort(gfp, 1);
2063 T_ELIF_INTERNAL("athlower")
2065 (void) lame_set_ATHlower(gfp, (float) atof(nextArg));
2067 T_ELIF_INTERNAL("athtype")
2069 (void) lame_set_ATHtype(gfp, atoi(nextArg));
2071 T_ELIF_INTERNAL("athaa-type") /* switch for developing, no DOCU */
2072 argUsed = 1; /* once was 1:Gaby, 2:Robert, 3:Jon, else:off */
2073 lame_set_athaa_type(gfp, atoi(nextArg)); /* now: 0:off else:Jon */
2075 T_ELIF ("athaa-sensitivity")
2077 lame_set_athaa_sensitivity(gfp, (float) atof(nextArg));
2079 T_ELIF_INTERNAL("debug-file") /* switch for developing, no DOCU */
2080 argUsed = 1; /* file name to print debug info into */
2082 set_debug_file(nextArg);
2086 error_printf("%s: unrecognized option --%s\n", ProgramName, token);
2093 while ((c = *token++) != '\0') {
2094 arg = *token ? token : nextArg;
2101 (void) lame_set_mode(gfp, STEREO);
2104 (void) lame_set_mode(gfp, DUAL_CHANNEL);
2107 lame_set_force_ms(gfp, 1);
2110 (void) lame_set_mode(gfp, JOINT_STEREO);
2113 (void) lame_set_mode(gfp, MONO);
2116 (void) lame_set_mode(gfp, MONO);
2117 (void) lame_set_scale_left(gfp, 2);
2118 (void) lame_set_scale_right(gfp, 0);
2121 (void) lame_set_mode(gfp, MONO);
2122 (void) lame_set_scale_left(gfp, 0);
2123 (void) lame_set_scale_right(gfp, 2);
2126 (void) lame_set_mode(gfp, JOINT_STEREO);
2129 error_printf("%s: -m mode must be s/d/j/f/m not %s\n", ProgramName,
2137 /* to change VBR default look in lame.h */
2138 if (lame_get_VBR(gfp) == vbr_off)
2139 lame_set_VBR(gfp, vbr_default);
2140 lame_set_VBR_quality(gfp, (float)atof(arg));
2143 /* to change VBR default look in lame.h */
2144 if (lame_get_VBR(gfp) == vbr_off)
2145 lame_set_VBR(gfp, vbr_default);
2150 (void) lame_set_quality(gfp, atoi(arg));
2153 (void) lame_set_quality(gfp, 7);
2156 (void) lame_set_quality(gfp, 2);
2162 val = (int) (val * (val <= 192 ? 1.e3 : 1.e0) + 0.5);
2163 global_reader.input_samplerate = (int)val;
2164 (void) lame_set_in_samplerate(gfp, (int)val);
2168 lame_set_brate(gfp, atoi(arg));
2169 lame_set_VBR_min_bitrate_kbps(gfp, lame_get_brate(gfp));
2173 lame_set_VBR_max_bitrate_kbps(gfp, atoi(arg));
2176 lame_set_VBR_hard_min(gfp, 1);
2178 case 't': /* dont write VBR tag */
2179 (void) lame_set_bWriteVbrTag(gfp, 0);
2180 global_decoder.disable_wav_header = 1;
2182 case 'T': /* do write VBR tag */
2183 (void) lame_set_bWriteVbrTag(gfp, 1);
2185 global_decoder.disable_wav_header = 0;
2187 case 'r': /* force raw pcm input file */
2188 #if defined(LIBSNDFILE)
2190 ("WARNING: libsndfile may ignore -r and perform fseek's on the input.\n"
2191 "Compile without libsndfile if this is a problem.\n");
2193 global_reader.input_format = sf_raw;
2195 case 'x': /* force byte swapping */
2196 global_reader.swapbytes = 1;
2198 case 'p': /* (jo) error_protection: add crc16 information to stream */
2199 lame_set_error_protection(gfp, 1);
2201 case 'a': /* autoconvert input file from stereo to mono - for mono mp3 encoding */
2203 (void) lame_set_mode(gfp, MONO);
2205 case 'd': /*(void) lame_set_allow_diff_short( gfp, 1 ); */
2206 case 'k': /*lame_set_lowpassfreq(gfp, -1);
2207 lame_set_highpassfreq(gfp, -1); */
2208 error_printf("WARNING: -%c is obsolete.\n", c);
2211 global_ui_config.silent = 5;
2214 /* experimental switch -X:
2215 the differnt types of quant compare are tough
2216 to communicate to endusers, so they shouldn't
2217 bother to toy around with them
2221 int n = sscanf(arg, "%d,%d", &x, &y);
2226 if (internal_opts_enabled) {
2227 lame_set_quant_comp(gfp, x);
2228 lame_set_quant_comp_short(gfp, y);
2233 lame_set_experimentalY(gfp, 1);
2236 /* experimental switch -Z:
2240 argUsed = sscanf(arg, "%d", &n);
2241 /*if (internal_opts_enabled)*/
2243 lame_set_experimentalZ(gfp, n);
2252 lame_set_emphasis(gfp, 0);
2255 lame_set_emphasis(gfp, 1);
2258 lame_set_emphasis(gfp, 3);
2261 error_printf("%s: -e emp must be n/5/c not %s\n", ProgramName, arg);
2266 lame_set_copyright(gfp, 1);
2269 lame_set_original(gfp, 0);
2273 long_help(gfp, stdout, ProgramName, 0 /* LESSMODE=NO */ );
2277 error_printf("%s: unrecognized option -%c\n", ProgramName, c);
2282 token = ""; /* no more from token */
2284 ++i; /* skip arg we used */
2293 if ((num_nogap != NULL) && (count_nogap < *num_nogap)) {
2294 strncpy(nogap_inPath[count_nogap++], argv[i], PATH_MAX + 1);
2298 /* sorry, calling program did not allocate enough space */
2300 ("Error: 'nogap option'. Calling program does not allow nogap option, or\n"
2301 "you have exceeded maximum number of input files for the nogap option\n");
2307 /* normal options: inputfile [outputfile], and
2308 either one can be a '-' for stdin/stdout */
2309 if (inPath[0] == '\0') {
2310 strncpy(inPath, argv[i], PATH_MAX + 1);
2314 if (outPath[0] == '\0')
2315 strncpy(outPath, argv[i], PATH_MAX + 1);
2317 error_printf("%s: excess arg %s\n", ProgramName, argv[i]);
2323 } /* loop over args */
2326 usage(Console_IO.Console_fp, ProgramName);
2330 if (inPath[0] == '-')
2331 global_ui_config.silent = (global_ui_config.silent <= 1 ? 1 : global_ui_config.silent);
2334 dosToLongFileName(inPath);
2337 if (outPath[0] == '\0' && count_nogap == 0) {
2338 if (inPath[0] == '-') {
2339 /* if input is stdin, default output is stdout */
2340 strcpy(outPath, "-");
2343 if (generateOutPath(gfp, inPath, outDir, outPath) != 0) {
2349 /* RG is enabled by default */
2351 lame_set_findReplayGain(gfp, 1);
2353 /* disable VBR tags with nogap unless the VBR tags are forced */
2354 if (nogap && lame_get_bWriteVbrTag(gfp) && nogap_tags == 0) {
2355 console_printf("Note: Disabling VBR Xing/Info tag since it interferes with --nogap\n");
2356 lame_set_bWriteVbrTag(gfp, 0);
2359 /* some file options not allowed with stdout */
2360 if (outPath[0] == '-') {
2361 (void) lame_set_bWriteVbrTag(gfp, 0); /* turn off VBR tag */
2364 /* if user did not explicitly specify input is mp3, check file name */
2365 if (global_reader.input_format == sf_unknown)
2366 global_reader.input_format = filename_to_type(inPath);
2368 #if !(defined HAVE_MPGLIB || defined AMIGA_MPEGA)
2369 if (is_mpeg_file_format(global_reader.input_format)) {
2370 error_printf("Error: libmp3lame not compiled with mpg123 *decoding* support \n");
2375 /* default guess for number of channels */
2377 (void) lame_set_num_channels(gfp, 2);
2378 else if (MONO == lame_get_mode(gfp))
2379 (void) lame_set_num_channels(gfp, 1);
2381 (void) lame_set_num_channels(gfp, 2);
2383 if (lame_get_free_format(gfp)) {
2384 if (lame_get_brate(gfp) < 8 || lame_get_brate(gfp) > 640) {
2385 error_printf("For free format, specify a bitrate between 8 and 640 kbps\n");
2386 error_printf("with the -b <bitrate> option\n");
2390 if (num_nogap != NULL)
2391 *num_nogap = count_nogap;
2396 /* end of parse.c */