parse.c

Go to the documentation of this file.
00001 /*
00002  *      Command line parsing related functions
00003  *
00004  *      Copyright (c) 1999 Mark Taylor
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Library General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the
00018  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019  * Boston, MA 02111-1307, USA.
00020  */
00021 
00022 /* $Id: parse.c,v 1.233 2007/07/24 17:46:09 bouvigne Exp $ */
00023 
00024 #ifdef HAVE_CONFIG_H
00025 # include <config.h>
00026 #endif
00027 
00028 #include <assert.h>
00029 #include <ctype.h>
00030 
00031 #ifdef STDC_HEADERS
00032 # include <stdlib.h>
00033 # include <string.h>
00034 #else
00035 # ifndef HAVE_STRCHR
00036 #  define strchr index
00037 #  define strrchr rindex
00038 # endif
00039 char   *strchr(), *strrchr();
00040 # ifndef HAVE_MEMCPY
00041 #  define memcpy(d, s, n) bcopy ((s), (d), (n))
00042 #  define memmove(d, s, n) bcopy ((s), (d), (n))
00043 # endif
00044 #endif
00045 
00046 #ifdef __OS2__
00047 #include <os2.h>
00048 #define PRTYC_IDLE 1
00049 #define PRTYC_REGULAR 2
00050 #define PRTYD_MINIMUM -31
00051 #define PRTYD_MAXIMUM 31
00052 #endif
00053 
00054 #ifdef HAVE_LIMITS_H
00055 # include <limits.h>
00056 #endif
00057 
00058 #include "lame.h"
00059 #include "set_get.h"
00060 
00061 #include "brhist.h"
00062 #include "parse.h"
00063 #include "main.h"
00064 #include "get_audio.h"
00065 #include "version.h"
00066 #include "console.h"
00067 
00068 #ifdef WITH_DMALLOC
00069 #include <dmalloc.h>
00070 #endif
00071 
00072 
00073 #if defined DEBUG || _DEBUG
00074 #define INTERNAL_OPTS 1
00075 #else
00076 #define INTERNAL_OPTS LAME_ALPHA_VERSION
00077 #endif
00078 
00079 #if (INTERNAL_OPTS!=0)
00080 #define DEV_HELP(a) a
00081 #else
00082 #define DEV_HELP(a)
00083 #endif
00084 
00085 
00086 
00087 /* GLOBAL VARIABLES.  set by parse_args() */
00088 /* we need to clean this up */
00089 sound_file_format input_format;
00090 int     swapbytes = 0;       /* force byte swapping   default=0 */
00091 int     silent;              /* Verbosity */
00092 int     ignore_tag_errors;   /* Ignore errors in values passed for tags */
00093 int     brhist;
00094 float   update_interval;     /* to use Frank's time status display */
00095 int     mp3_delay;           /* to adjust the number of samples truncated
00096                                 during decode */
00097 int     mp3_delay_set;       /* user specified the value of the mp3 encoder
00098                                 delay to assume for decoding */
00099 
00100 int     disable_wav_header;
00101 mp3data_struct mp3input_data; /* used by MP3 */
00102 int     print_clipping_info; /* print info whether waveform clips */
00103 
00104 #ifdef LIBSNDFILE
00105 int     in_signed = 1;
00106 int     in_unsigned = 0;
00107 #endif
00108 int     in_endian = order_littleEndian;
00109 int     in_bitwidth = 16;
00110 
00111 int     flush_write = 0;
00112 
00113 
00114 
00119 #ifdef WIN32
00120 #include <winbase.h>
00121 static void
00122 dosToLongFileName(char *fn)
00123 {
00124     const int MSIZE = PATH_MAX + 1 - 4; /*  we wanna add ".mp3" later */
00125     WIN32_FIND_DATAA lpFindFileData;
00126     HANDLE  h = FindFirstFileA(fn, &lpFindFileData);
00127     if (h != INVALID_HANDLE_VALUE) {
00128         int     a;
00129         char   *q, *p;
00130         FindClose(h);
00131         for (a = 0; a < MSIZE; a++) {
00132             if ('\0' == lpFindFileData.cFileName[a])
00133                 break;
00134         }
00135         if (a >= MSIZE || a == 0)
00136             return;
00137         q = strrchr(fn, '\\');
00138         p = strrchr(fn, '/');
00139         if (p - q > 0)
00140             q = p;
00141         if (q == NULL)
00142             q = strrchr(fn, ':');
00143         if (q == NULL)
00144             strncpy(fn, lpFindFileData.cFileName, a);
00145         else {
00146             a += q - fn + 1;
00147             if (a >= MSIZE)
00148                 return;
00149             strncpy(++q, lpFindFileData.cFileName, MSIZE - a);
00150         }
00151     }
00152 }
00153 #endif
00154 #if defined(WIN32)
00155 #include <windows.h>
00156 BOOL
00157 SetPriorityClassMacro(DWORD p)
00158 {
00159     HANDLE  op = OpenProcess(PROCESS_ALL_ACCESS, TRUE, GetCurrentProcessId());
00160     return SetPriorityClass(op, p);
00161 }
00162 
00163 static void
00164 setWin32Priority(lame_global_flags * gfp, int Priority)
00165 {
00166     switch (Priority) {
00167     case 0:
00168     case 1:
00169         SetPriorityClassMacro(IDLE_PRIORITY_CLASS);
00170         console_printf("==> Priority set to Low.\n");
00171         break;
00172     default:
00173     case 2:
00174         SetPriorityClassMacro(NORMAL_PRIORITY_CLASS);
00175         console_printf("==> Priority set to Normal.\n");
00176         break;
00177     case 3:
00178     case 4:
00179         SetPriorityClassMacro(HIGH_PRIORITY_CLASS);
00180         console_printf("==> Priority set to High.\n");
00181         break;
00182     }
00183 }
00184 #endif
00185 
00186 
00187 #if defined(__OS2__)
00188 /* OS/2 priority functions */
00189 static int
00190 setOS2Priority(lame_global_flags * gfp, int Priority)
00191 {
00192     int     rc;
00193 
00194     switch (Priority) {
00195 
00196     case 0:
00197         rc = DosSetPriority(0, /* Scope: only one process */
00198                             PRTYC_IDLE, /* select priority class (idle, regular, etc) */
00199                             0, /* set delta */
00200                             0); /* Assume current process */
00201         console_printf("==> Priority set to 0 (Low priority).\n");
00202         break;
00203 
00204     case 1:
00205         rc = DosSetPriority(0, /* Scope: only one process */
00206                             PRTYC_IDLE, /* select priority class (idle, regular, etc) */
00207                             PRTYD_MAXIMUM, /* set delta */
00208                             0); /* Assume current process */
00209         console_printf("==> Priority set to 1 (Medium priority).\n");
00210         break;
00211 
00212     case 2:
00213         rc = DosSetPriority(0, /* Scope: only one process */
00214                             PRTYC_REGULAR, /* select priority class (idle, regular, etc) */
00215                             PRTYD_MINIMUM, /* set delta */
00216                             0); /* Assume current process */
00217         console_printf("==> Priority set to 2 (Regular priority).\n");
00218         break;
00219 
00220     case 3:
00221         rc = DosSetPriority(0, /* Scope: only one process */
00222                             PRTYC_REGULAR, /* select priority class (idle, regular, etc) */
00223                             0, /* set delta */
00224                             0); /* Assume current process */
00225         console_printf("==> Priority set to 3 (High priority).\n");
00226         break;
00227 
00228     case 4:
00229         rc = DosSetPriority(0, /* Scope: only one process */
00230                             PRTYC_REGULAR, /* select priority class (idle, regular, etc) */
00231                             PRTYD_MAXIMUM, /* set delta */
00232                             0); /* Assume current process */
00233         console_printf("==> Priority set to 4 (Maximum priority). I hope you enjoy it :)\n");
00234         break;
00235 
00236     default:
00237         console_printf("==> Invalid priority specified! Assuming idle priority.\n");
00238     }
00239 
00240 
00241     return 0;
00242 }
00243 #endif
00244 
00245 
00246 /************************************************************************
00247 *
00248 * license
00249 *
00250 * PURPOSE:  Writes version and license to the file specified by fp
00251 *
00252 ************************************************************************/
00253 
00254 static int
00255 lame_version_print(FILE * const fp)
00256 {
00257     const char *b = get_lame_os_bitness();
00258     const char *v = get_lame_version();
00259     const char *u = get_lame_url();
00260     const size_t lenb = strlen(b);
00261     const size_t lenv = strlen(v);
00262     const size_t lenu = strlen(u);
00263     const size_t lw = 80;       /* line width of terminal in characters */
00264     const size_t sw = 16;       /* static width of text */
00265 
00266     if (lw >= lenb + lenv + lenu + sw || lw < lenu + 2)
00267         /* text fits in 80 chars per line, or line even too small for url */
00268         if (lenb > 0)
00269             fprintf(fp, "LAME %s version %s (%s)\n\n", b, v, u);
00270         else
00271             fprintf(fp, "LAME version %s (%s)\n\n", v, u);
00272     else
00273         /* text too long, wrap url into next line, right aligned */
00274     if (lenb > 0)
00275         fprintf(fp, "LAME %s version %s\n%*s(%s)\n\n", b, v, lw - 2 - lenu, "", u);
00276     else
00277         fprintf(fp, "LAME version %s\n%*s(%s)\n\n", v, lw - 2 - lenu, "", u);
00278 
00279     if (LAME_ALPHA_VERSION)
00280         fprintf(fp, "warning: alpha versions should be used for testing only\n\n");
00281 
00282 
00283     return 0;
00284 }
00285 
00286 static int
00287 print_license(FILE * const fp)
00288 {                       /* print version & license */
00289     lame_version_print(fp);
00290     fprintf(fp,
00291             "Can I use LAME in my commercial program?\n"
00292             "\n"
00293             "Yes, you can, under the restrictions of the LGPL.  In particular, you\n"
00294             "can include a compiled version of the LAME library (for example,\n"
00295             "lame.dll) with a commercial program.  Some notable requirements of\n"
00296             "the LGPL:\n" "\n");
00297     fprintf(fp,
00298             "1. In your program, you cannot include any source code from LAME, with\n"
00299             "   the exception of files whose only purpose is to describe the library\n"
00300             "   interface (such as lame.h).\n" "\n");
00301     fprintf(fp,
00302             "2. Any modifications of LAME must be released under the LGPL.\n"
00303             "   The LAME project (www.mp3dev.org) would appreciate being\n"
00304             "   notified of any modifications.\n" "\n");
00305     fprintf(fp,
00306             "3. You must give prominent notice that your program is:\n"
00307             "      A. using LAME (including version number)\n"
00308             "      B. LAME is under the LGPL\n"
00309             "      C. Provide a copy of the LGPL.  (the file COPYING contains the LGPL)\n"
00310             "      D. Provide a copy of LAME source, or a pointer where the LAME\n"
00311             "         source can be obtained (such as www.mp3dev.org)\n"
00312             "   An example of prominent notice would be an \"About the LAME encoding engine\"\n"
00313             "   button in some pull down menu within the executable of your program.\n" "\n");
00314     fprintf(fp,
00315             "4. If you determine that distribution of LAME requires a patent license,\n"
00316             "   you must obtain such license.\n" "\n" "\n");
00317     fprintf(fp,
00318             "*** IMPORTANT NOTE ***\n"
00319             "\n"
00320             "The decoding functions provided in LAME use the mpglib decoding engine which\n"
00321             "is under the GPL.  They may not be used by any program not released under the\n"
00322             "GPL unless you obtain such permission from the MPG123 project (www.mpg123.de).\n"
00323             "\n");
00324     return 0;
00325 }
00326 
00327 
00328 /************************************************************************
00329 *
00330 * usage
00331 *
00332 * PURPOSE:  Writes command line syntax to the file specified by fp
00333 *
00334 ************************************************************************/
00335 
00336 int
00337 usage(FILE * const fp, const char *ProgramName)
00338 {                       /* print general syntax */
00339     lame_version_print(fp);
00340     fprintf(fp,
00341             "usage: %s [options] <infile> [outfile]\n"
00342             "\n"
00343             "    <infile> and/or <outfile> can be \"-\", which means stdin/stdout.\n"
00344             "\n"
00345             "Try:\n"
00346             "     \"%s --help\"           for general usage information\n"
00347             " or:\n"
00348             "     \"%s --preset help\"    for information on suggested predefined settings\n"
00349             " or:\n"
00350             "     \"%s --longhelp\"\n"
00351             "  or \"%s -?\"              for a complete options list\n\n",
00352             ProgramName, ProgramName, ProgramName, ProgramName, ProgramName);
00353     return 0;
00354 }
00355 
00356 
00357 /************************************************************************
00358 *
00359 * usage
00360 *
00361 * PURPOSE:  Writes command line syntax to the file specified by fp
00362 *           but only the most important ones, to fit on a vt100 terminal
00363 *
00364 ************************************************************************/
00365 
00366 int
00367 short_help(const lame_global_flags * gfp, FILE * const fp, const char *ProgramName)
00368 {                       /* print short syntax help */
00369     lame_version_print(fp);
00370     fprintf(fp,
00371             "usage: %s [options] <infile> [outfile]\n"
00372             "\n"
00373             "    <infile> and/or <outfile> can be \"-\", which means stdin/stdout.\n"
00374             "\n" "RECOMMENDED:\n" "    lame -V2 input.wav output.mp3\n" "\n", ProgramName);
00375     fprintf(fp,
00376             "OPTIONS:\n"
00377             "    -b bitrate      set the bitrate, default 128 kbps\n"
00378             "    -h              higher quality, but a little slower.  Recommended.\n"
00379             "    -f              fast mode (lower quality)\n"
00380             "    -V n            quality setting for VBR.  default n=%i\n"
00381             "                    0=high quality,bigger files. 9=smaller files\n",
00382             lame_get_VBR_q(gfp));
00383     fprintf(fp,
00384             "    --preset type   type must be \"medium\", \"standard\", \"extreme\", \"insane\",\n"
00385             "                    or a value for an average desired bitrate and depending\n"
00386             "                    on the value specified, appropriate quality settings will\n"
00387             "                    be used.\n"
00388             "                    \"--preset help\" gives more info on these\n" "\n");
00389     fprintf(fp,
00390 #if defined(WIN32)
00391             "    --priority type  sets the process priority\n"
00392             "                     0,1 = Low priority\n"
00393             "                     2   = normal priority\n"
00394             "                     3,4 = High priority\n" "\n"
00395 #endif
00396 #if defined(__OS2__)
00397             "    --priority type  sets the process priority\n"
00398             "                     0 = Low priority\n"
00399             "                     1 = Medium priority\n"
00400             "                     2 = Regular priority\n"
00401             "                     3 = High priority\n"
00402             "                     4 = Maximum priority\n" "\n"
00403 #endif
00404             "    --longhelp      full list of options\n" "\n"
00405             "    --license       print License information\n\n"
00406             );
00407 
00408     return 0;
00409 }
00410 
00411 /************************************************************************
00412 *
00413 * usage
00414 *
00415 * PURPOSE:  Writes command line syntax to the file specified by fp
00416 *
00417 ************************************************************************/
00418 
00419 static void
00420 wait_for(FILE * const fp, int lessmode)
00421 {
00422     if (lessmode) {
00423         fflush(fp);
00424         getchar();
00425     }
00426     else {
00427         fprintf(fp, "\n");
00428     }
00429     fprintf(fp, "\n");
00430 }
00431 
00432 int
00433 long_help(const lame_global_flags * gfp, FILE * const fp, const char *ProgramName, int lessmode)
00434 {                       /* print long syntax help */
00435     lame_version_print(fp);
00436     fprintf(fp,
00437             "usage: %s [options] <infile> [outfile]\n"
00438             "\n"
00439             "    <infile> and/or <outfile> can be \"-\", which means stdin/stdout.\n"
00440             "\n" "RECOMMENDED:\n" "    lame -V2 input.wav output.mp3\n" "\n", ProgramName);
00441     fprintf(fp,
00442             "OPTIONS:\n"
00443             "  Input options:\n"
00444             "    --scale <arg>   scale input (multiply PCM data) by <arg>\n"
00445             "    --scale-l <arg> scale channel 0 (left) input (multiply PCM data) by <arg>\n"
00446             "    --scale-r <arg> scale channel 1 (right) input (multiply PCM data) by <arg>\n"
00447 #if (defined HAVE_MPGLIB || defined AMIGA_MPEGA)
00448             "    --mp1input      input file is a MPEG Layer I   file\n"
00449             "    --mp2input      input file is a MPEG Layer II  file\n"
00450             "    --mp3input      input file is a MPEG Layer III file\n"
00451 #endif
00452             "    --nogap <file1> <file2> <...>\n"
00453             "                    gapless encoding for a set of contiguous files\n"
00454             "    --nogapout <dir>\n"
00455             "                    output dir for gapless encoding (must precede --nogap)\n"
00456             "    --nogaptags     allow the use of VBR tags in gapless encoding\n"
00457            );
00458     fprintf(fp,
00459             "\n"
00460             "  Input options for RAW PCM:\n"
00461             "    -r              input is raw pcm\n"
00462             "    -x              force byte-swapping of input\n"
00463             "    -s sfreq        sampling frequency of input file (kHz) - default 44.1 kHz\n"
00464             "    --bitwidth w    input bit width is w (default 16)\n"
00465 #ifdef LIBSNDFILE
00466             "    --signed        input is signed (default)\n"
00467             "    --unsigned      input is unsigned\n"
00468 #endif
00469             "    --little-endian input is little-endian (default)\n"
00470             "    --big-endian    input is big-endian\n"
00471            );
00472 
00473     wait_for(fp, lessmode);
00474     fprintf(fp,
00475             "  Operational options:\n"
00476             "    -a              downmix from stereo to mono file for mono encoding\n"
00477             "    -m <mode>       (j)oint, (s)imple, (f)orce, (d)dual-mono, (m)ono\n"
00478             "                    default is (j) or (s) depending on bitrate\n"
00479             "                    joint  = joins the best possible of MS and LR stereo\n"
00480             "                    simple = force LR stereo on all frames\n"
00481             "                    force  = force MS stereo on all frames.\n"
00482             "    --preset type   type must be \"medium\", \"standard\", \"extreme\", \"insane\",\n"
00483             "                    or a value for an average desired bitrate and depending\n"
00484             "                    on the value specified, appropriate quality settings will\n"
00485             "                    be used.\n"
00486             "                    \"--preset help\" gives more info on these\n"
00487             "    --comp  <arg>   choose bitrate to achive a compression ratio of <arg>\n");
00488     fprintf(fp, "    --replaygain-fast   compute RG fast but slightly inaccurately (default)\n"
00489 #ifdef DECODE_ON_THE_FLY
00490             "    --replaygain-accurate   compute RG more accurately and find the peak sample\n"
00491 #endif
00492             "    --noreplaygain  disable ReplayGain analysis\n"
00493 #ifdef DECODE_ON_THE_FLY
00494             "    --clipdetect    enable --replaygain-accurate and print a message whether\n"
00495             "                    clipping occurs and how far the waveform is from full scale\n"
00496 #endif
00497         );
00498     fprintf(fp,
00499             "    --flush         flush output stream as soon as possible\n"
00500             "    --freeformat    produce a free format bitstream\n"
00501             "    --decode        input=mp3 file, output=wav\n"
00502             "    -t              disable writing wav header when using --decode\n");
00503 
00504     wait_for(fp, lessmode);
00505     fprintf(fp,
00506             "  Verbosity:\n"
00507             "    --disptime <arg>print progress report every arg seconds\n"
00508             "    -S              don't print progress report, VBR histograms\n"
00509             "    --nohist        disable VBR histogram display\n"
00510             "    --silent        don't print anything on screen\n"
00511             "    --quiet         don't print anything on screen\n"
00512             "    --brief         print more useful information\n"
00513             "    --verbose       print a lot of useful information\n" "\n");
00514     fprintf(fp,
00515             "  Noise shaping & psycho acoustic algorithms:\n"
00516             "    -q <arg>        <arg> = 0...9.  Default  -q 5 \n"
00517             "                    -q 0:  Highest quality, very slow \n"
00518             "                    -q 9:  Poor quality, but fast \n"
00519             "    -h              Same as -q 2.   Recommended.\n"
00520             "    -f              Same as -q 7.   Fast, ok quality\n");
00521 
00522     wait_for(fp, lessmode);
00523     fprintf(fp,
00524             "  CBR (constant bitrate, the default) options:\n"
00525             "    -b <bitrate>    set the bitrate in kbps, default 128 kbps\n"
00526             "    --cbr           enforce use of constant bitrate\n"
00527             "\n"
00528             "  ABR options:\n"
00529             "    --abr <bitrate> specify average bitrate desired (instead of quality)\n" "\n");
00530     fprintf(fp,
00531             "  VBR options:\n"
00532             "    -V n            quality setting for VBR.  default n=%i\n"
00533             "                    0=high quality,bigger files. 9=smaller files\n"
00534             "    -v              the same as -V 4\n"
00535             "    --vbr-old       use old variable bitrate (VBR) routine\n"
00536             "    --vbr-new       use new variable bitrate (VBR) routine (default)\n"
00537             ,
00538             lame_get_VBR_q(gfp));
00539     fprintf(fp,
00540             "    -b <bitrate>    specify minimum allowed bitrate, default  32 kbps\n"
00541             "    -B <bitrate>    specify maximum allowed bitrate, default 320 kbps\n"
00542             "    -F              strictly enforce the -b option, for use with players that\n"
00543             "                    do not support low bitrate mp3\n"
00544             "    -t              disable writing LAME Tag\n"
00545             "    -T              enable and force writing LAME Tag\n");
00546 
00547     wait_for(fp, lessmode);
00548     DEV_HELP(fprintf(fp,
00549                      "  ATH related:\n"
00550                      "    --noath         turns ATH down to a flat noise floor\n"
00551                      "    --athshort      ignore GPSYCHO for short blocks, use ATH only\n"
00552                      "    --athonly       ignore GPSYCHO completely, use ATH only\n"
00553                      "    --athtype n     selects between different ATH types [0-4]\n"
00554                      "    --athlower x    lowers ATH by x dB\n");
00555              fprintf(fp, "    --athaa-type n  ATH auto adjust: 0 'no' else 'loudness based'\n"
00557                      "    --athaa-sensitivity x  activation offset in -/+ dB for ATH auto-adjustment\n"
00558                      "\n");
00559         )
00560         fprintf(fp,
00561                 "  PSY related:\n"
00562                 DEV_HELP(
00563                 "    --short         use short blocks when appropriate\n"
00564                 "    --noshort       do not use short blocks\n"
00565                 "    --allshort      use only short blocks\n"
00566                 "    --cwlimit <freq>  compute tonality up to freq (in kHz) default 8.8717\n"
00567                 )
00568         );
00569     fprintf(fp,
00570             "    --temporal-masking x   x=0 disables, x=1 enables temporal masking effect\n"
00571             "    --nssafejoint   M/S switching criterion\n"
00572             "    --nsmsfix <arg> M/S switching tuning [effective 0-3.5]\n"
00573             "    --interch x     adjust inter-channel masking ratio\n"
00574             "    --ns-bass x     adjust masking for sfbs  0 -  6 (long)  0 -  5 (short)\n"
00575             "    --ns-alto x     adjust masking for sfbs  7 - 13 (long)  6 - 10 (short)\n"
00576             "    --ns-treble x   adjust masking for sfbs 14 - 21 (long) 11 - 12 (short)\n");
00577     fprintf(fp,
00578             "    --ns-sfb21 x    change ns-treble by x dB for sfb21\n"
00579             DEV_HELP("    --shortthreshold x,y  short block switching threshold,\n"
00580                      "                          x for L/R/M channel, y for S channel\n"
00581                      "  Noise Shaping related:\n"
00582                      "    --substep n     use pseudo substep noise shaping method types 0-2\n")
00583         );
00584 
00585     wait_for(fp, lessmode);
00586 
00587     fprintf(fp,
00588             "  experimental switches:\n"
00589             DEV_HELP(
00590             "    -X n[,m]        selects between different noise measurements\n"
00591             "                    n for long block, m for short. if m is omitted, m = n\n"
00592             )
00593             "    -Y              lets LAME ignore noise in sfb21, like in CBR\n"
00594             DEV_HELP(
00595             "    -Z [n]          currently no effects\n"
00596             )
00597             );
00598 
00599     wait_for(fp, lessmode);
00600 
00601     fprintf(fp,
00602             "  MP3 header/stream options:\n"
00603             "    -e <emp>        de-emphasis n/5/c  (obsolete)\n"
00604             "    -c              mark as copyright\n"
00605             "    -o              mark as non-original\n"
00606             "    -p              error protection.  adds 16 bit checksum to every frame\n"
00607             "                    (the checksum is computed correctly)\n"
00608             "    --nores         disable the bit reservoir\n"
00609             "    --strictly-enforce-ISO   comply as much as possible to ISO MPEG spec\n" "\n");
00610     fprintf(fp,
00611             "  Filter options:\n"
00612             "  --lowpass <freq>        frequency(kHz), lowpass filter cutoff above freq\n"
00613             "  --lowpass-width <freq>  frequency(kHz) - default 15%% of lowpass freq\n"
00614             "  --highpass <freq>       frequency(kHz), highpass filter cutoff below freq\n"
00615             "  --highpass-width <freq> frequency(kHz) - default 15%% of highpass freq\n");
00616     fprintf(fp,
00617             "  --resample <sfreq>  sampling frequency of output file(kHz)- default=automatic\n");
00618 
00619     wait_for(fp, lessmode);
00620     fprintf(fp,
00621             "  ID3 tag options:\n"
00622             "    --tt <title>    audio/song title (max 30 chars for version 1 tag)\n"
00623             "    --ta <artist>   audio/song artist (max 30 chars for version 1 tag)\n"
00624             "    --tl <album>    audio/song album (max 30 chars for version 1 tag)\n"
00625             "    --ty <year>     audio/song year of issue (1 to 9999)\n"
00626             "    --tc <comment>  user-defined text (max 30 chars for v1 tag, 28 for v1.1)\n"
00627             "    --tn <track[/total]>   audio/song track number and (optionally) the total\n"
00628             "                           number of tracks on the original recording. (track\n"
00629             "                           and total each 1 to 255. just the track number\n"
00630             "                           creates v1.1 tag, providing a total forces v2.0).\n"
00631             "    --tg <genre>    audio/song genre (name or number in list)\n"
00632             "    --ti <file>     audio/song albumArt (jpeg/png/gif file, 128KB max, v2.3)\n"
00633             "    --tv <id=value> user-defined frame specified by id and value (v2.3 tag)\n");
00634     fprintf(fp,
00635             "    --add-id3v2     force addition of version 2 tag\n"
00636             "    --id3v1-only    add only a version 1 tag\n"
00637             "    --id3v2-only    add only a version 2 tag\n"
00638             "    --space-id3v1   pad version 1 tag with spaces instead of nulls\n"
00639             "    --pad-id3v2     pad version 2 tag with extra 128 bytes\n"
00640             "    --genre-list    print alphabetically sorted ID3 genre list and exit\n"
00641             "    --ignore-tag-errors  ignore errors in values passed for tags\n" "\n");
00642     fprintf(fp,
00643             "    Note: A version 2 tag will NOT be added unless one of the input fields\n"
00644             "    won't fit in a version 1 tag (e.g. the title string is longer than 30\n"
00645             "    characters), or the '--add-id3v2' or '--id3v2-only' options are used,\n"
00646             "    or output is redirected to stdout.\n"
00647 #if defined(WIN32)
00648             "\n\nMS-Windows-specific options:\n"
00649             "    --priority <type>  sets the process priority:\n"
00650             "                         0,1 = Low priority (IDLE_PRIORITY_CLASS)\n"
00651             "                         2 = normal priority (NORMAL_PRIORITY_CLASS, default)\n"
00652             "                         3,4 = High priority (HIGH_PRIORITY_CLASS))\n"
00653             "    Note: Calling '--priority' without a parameter will select priority 0.\n"
00654 #endif
00655 #if defined(__OS2__)
00656             "\n\nOS/2-specific options:\n"
00657             "    --priority <type>  sets the process priority:\n"
00658             "                         0 = Low priority (IDLE, delta = 0)\n"
00659             "                         1 = Medium priority (IDLE, delta = +31)\n"
00660             "                         2 = Regular priority (REGULAR, delta = -31)\n"
00661             "                         3 = High priority (REGULAR, delta = 0)\n"
00662             "                         4 = Maximum priority (REGULAR, delta = +31)\n"
00663             "    Note: Calling '--priority' without a parameter will select priority 0.\n"
00664 #endif
00665             "\nMisc:\n    --license       print License information\n\n"
00666         );
00667 
00668 #if defined(HAVE_NASM)
00669     wait_for(fp, lessmode);
00670     fprintf(fp,
00671             "  Platform specific:\n"
00672             "    --noasm <instructions> disable assembly optimizations for mmx/3dnow/sse\n");
00673     wait_for(fp, lessmode);
00674 #endif
00675 
00676     display_bitrates(fp);
00677 
00678     return 0;
00679 }
00680 
00681 static void
00682 display_bitrate(FILE * const fp, const char *const version, const int d, const int indx)
00683 {
00684     int     i;
00685     int nBitrates = 14;
00686     if (d == 4)
00687         nBitrates = 8;
00688 
00689 
00690     fprintf(fp,
00691             "\nMPEG-%-3s layer III sample frequencies (kHz):  %2d  %2d  %g\n"
00692             "bitrates (kbps):", version, 32 / d, 48 / d, 44.1 / d);
00693     for (i = 1; i <= nBitrates; i++)
00694         fprintf(fp, " %2i", bitrate_table[indx][i]);
00695     fprintf(fp, "\n");
00696 }
00697 
00698 int
00699 display_bitrates(FILE * const fp)
00700 {
00701     display_bitrate(fp, "1", 1, 1);
00702     display_bitrate(fp, "2", 2, 0);
00703     display_bitrate(fp, "2.5", 4, 0);
00704     fprintf(fp, "\n");
00705     fflush(fp);
00706     return 0;
00707 }
00708 
00709 
00710 /*  note: for presets it would be better to externalize them in a file.
00711     suggestion:  lame --preset <file-name> ...
00712             or:  lame --preset my-setting  ... and my-setting is defined in lame.ini
00713  */
00714 
00715 /*
00716 Note from GB on 08/25/2002:
00717 I am merging --presets and --alt-presets. Old presets are now aliases for
00718 corresponding abr values from old alt-presets. This way we now have a
00719 unified preset system, and I hope than more people will use the new tuned
00720 presets instead of the old unmaintained ones.
00721 */
00722 
00723 
00724 
00725 /************************************************************************
00726 *
00727 * usage
00728 *
00729 * PURPOSE:  Writes presetting info to #stdout#
00730 *
00731 ************************************************************************/
00732 
00733 
00734 static void
00735 presets_longinfo_dm(FILE * msgfp)
00736 {
00737     fprintf(msgfp,
00738             "\n"
00739             "The --preset switches are designed to provide the highest possible quality.\n"
00740             "\n"
00741             "They have for the most part been subject to and tuned via rigorous double blind\n"
00742             "listening tests to verify and achieve this objective.\n" "\n");
00743     fprintf(msgfp,
00744             "These are continually updated to coincide with the latest developments that\n"
00745             "occur and as a result should provide you with nearly the best quality\n"
00746             "currently possible from LAME.\n" "\n");
00747     fprintf(msgfp,
00748             "To activate these presets:\n"
00749             "\n" "   For VBR modes (generally highest quality):\n" "\n");
00750     fprintf(msgfp,
00751             "     \"--preset medium\" This preset should provide near transparency\n"
00752             "                             to most people on most music.\n"
00753             "\n"
00754             "     \"--preset standard\" This preset should generally be transparent\n"
00755             "                             to most people on most music and is already\n"
00756             "                             quite high in quality.\n" "\n");
00757     fprintf(msgfp,
00758             "     \"--preset extreme\" If you have extremely good hearing and similar\n"
00759             "                             equipment, this preset will generally provide\n"
00760             "                             slightly higher quality than the \"standard\"\n"
00761             "                             mode.\n" "\n");
00762     fprintf(msgfp,
00763             "   For CBR 320kbps (highest quality possible from the --preset switches):\n"
00764             "\n"
00765             "     \"--preset insane\"  This preset will usually be overkill for most\n"
00766             "                             people and most situations, but if you must\n"
00767             "                             have the absolute highest quality with no\n"
00768             "                             regard to filesize, this is the way to go.\n" "\n");
00769     fprintf(msgfp,
00770             "   For ABR modes (high quality per given bitrate but not as high as VBR):\n"
00771             "\n"
00772             "     \"--preset <kbps>\"  Using this preset will usually give you good\n"
00773             "                             quality at a specified bitrate. Depending on the\n"
00774             "                             bitrate entered, this preset will determine the\n");
00775     fprintf(msgfp,
00776             "                             optimal settings for that particular situation.\n"
00777             "                             While this approach works, it is not nearly as\n"
00778             "                             flexible as VBR, and usually will not attain the\n"
00779             "                             same level of quality as VBR at higher bitrates.\n" "\n");
00780     fprintf(msgfp,
00781             "The following options are also available for the corresponding profiles:\n"
00782             "\n"
00783             "   <fast>        standard\n"
00784             "   <fast>        extreme\n"
00785             "                 insane\n"
00786             "   <cbr> (ABR Mode) - The ABR Mode is implied. To use it,\n"
00787             "                      simply specify a bitrate. For example:\n"
00788             "                      \"--preset 185\" activates this\n"
00789             "                      preset and uses 185 as an average kbps.\n" "\n");
00790     fprintf(msgfp,
00791             "   \"fast\" - Enables the new fast VBR for a particular profile. The\n"
00792             "            disadvantage to the speed switch is that often times the\n"
00793             "            bitrate will be slightly higher than with the normal mode\n"
00794             "            and quality may be slightly lower also.\n" "\n");
00795     fprintf(msgfp,
00796             "   \"cbr\"  - If you use the ABR mode (read above) with a significant\n"
00797             "            bitrate such as 80, 96, 112, 128, 160, 192, 224, 256, 320,\n"
00798             "            you can use the \"cbr\" option to force CBR mode encoding\n"
00799             "            instead of the standard abr mode. ABR does provide higher\n"
00800             "            quality but CBR may be useful in situations such as when\n"
00801             "            streaming an mp3 over the internet may be important.\n" "\n");
00802     fprintf(msgfp,
00803             "    For example:\n"
00804             "\n"
00805             "    \"--preset fast standard <input file> <output file>\"\n"
00806             " or \"--preset cbr 192 <input file> <output file>\"\n"
00807             " or \"--preset 172 <input file> <output file>\"\n"
00808             " or \"--preset extreme <input file> <output file>\"\n" "\n" "\n");
00809     fprintf(msgfp,
00810             "A few aliases are available for ABR mode:\n"
00811             "phone => 16kbps/mono        phon+/lw/mw-eu/sw => 24kbps/mono\n"
00812             "mw-us => 40kbps/mono        voice => 56kbps/mono\n"
00813             "fm/radio/tape => 112kbps    hifi => 160kbps\n"
00814             "cd => 192kbps               studio => 256kbps\n");
00815 }
00816 
00817 
00818 extern void lame_set_msfix(lame_t gfp, double msfix);
00819 
00820 
00821 
00822 static int
00823 presets_set(lame_t gfp, int fast, int cbr, const char *preset_name, const char *ProgramName)
00824 {
00825     int     mono = 0;
00826 
00827     if ((strcmp(preset_name, "help") == 0) && (fast < 1)
00828         && (cbr < 1)) {
00829         lame_version_print(stdout);
00830         presets_longinfo_dm(stdout);
00831         return -1;
00832     }
00833 
00834 
00835 
00836     /*aliases for compatibility with old presets */
00837 
00838     if (strcmp(preset_name, "phone") == 0) {
00839         preset_name = "16";
00840         mono = 1;
00841     }
00842     if ((strcmp(preset_name, "phon+") == 0) ||
00843         (strcmp(preset_name, "lw") == 0) ||
00844         (strcmp(preset_name, "mw-eu") == 0) || (strcmp(preset_name, "sw") == 0)) {
00845         preset_name = "24";
00846         mono = 1;
00847     }
00848     if (strcmp(preset_name, "mw-us") == 0) {
00849         preset_name = "40";
00850         mono = 1;
00851     }
00852     if (strcmp(preset_name, "voice") == 0) {
00853         preset_name = "56";
00854         mono = 1;
00855     }
00856     if (strcmp(preset_name, "fm") == 0) {
00857         preset_name = "112";
00858     }
00859     if ((strcmp(preset_name, "radio") == 0) || (strcmp(preset_name, "tape") == 0)) {
00860         preset_name = "112";
00861     }
00862     if (strcmp(preset_name, "hifi") == 0) {
00863         preset_name = "160";
00864     }
00865     if (strcmp(preset_name, "cd") == 0) {
00866         preset_name = "192";
00867     }
00868     if (strcmp(preset_name, "studio") == 0) {
00869         preset_name = "256";
00870     }
00871 
00872     if (strcmp(preset_name, "medium") == 0) {
00873         lame_set_VBR_q(gfp, 4);
00874         if (fast > 0) {
00875             lame_set_VBR(gfp, vbr_mtrh);
00876         }
00877         else {
00878             lame_set_VBR(gfp, vbr_rh);
00879         }
00880         return 0;
00881     }
00882 
00883     if (strcmp(preset_name, "standard") == 0) {
00884         lame_set_VBR_q(gfp, 2);
00885         if (fast > 0) {
00886             lame_set_VBR(gfp, vbr_mtrh);
00887         }
00888         else {
00889             lame_set_VBR(gfp, vbr_rh);
00890         }
00891         return 0;
00892     }
00893 
00894     else if (strcmp(preset_name, "extreme") == 0) {
00895         lame_set_VBR_q(gfp, 0);
00896         if (fast > 0) {
00897             lame_set_VBR(gfp, vbr_mtrh);
00898         }
00899         else {
00900             lame_set_VBR(gfp, vbr_rh);
00901         }
00902         return 0;
00903     }
00904 
00905     else if (((strcmp(preset_name, "insane") == 0) ||
00906               (strcmp(preset_name, "320") == 0)) && (fast < 1)) {
00907 
00908         lame_set_preset(gfp, INSANE);
00909 
00910         return 0;
00911     }
00912 
00913     /* Generic ABR Preset */
00914     if (((atoi(preset_name)) > 0) && (fast < 1)) {
00915         if ((atoi(preset_name)) >= 8 && (atoi(preset_name)) <= 320) {
00916             lame_set_preset(gfp, atoi(preset_name));
00917 
00918             if (cbr == 1)
00919                 lame_set_VBR(gfp, vbr_off);
00920 
00921             if (mono == 1) {
00922                 lame_set_mode(gfp, MONO);
00923             }
00924 
00925             return 0;
00926 
00927         }
00928         else {
00929             lame_version_print(Console_IO.Error_fp);
00930             error_printf("Error: The bitrate specified is out of the valid range for this preset\n"
00931                          "\n"
00932                          "When using this mode you must enter a value between \"32\" and \"320\"\n"
00933                          "\n" "For further information try: \"%s --preset help\"\n", ProgramName);
00934             return -1;
00935         }
00936     }
00937 
00938     lame_version_print(Console_IO.Error_fp);
00939     error_printf("Error: You did not enter a valid profile and/or options with --preset\n"
00940                  "\n"
00941                  "Available profiles are:\n"
00942                  "\n"
00943                  "   <fast>        medium\n"
00944                  "   <fast>        standard\n"
00945                  "   <fast>        extreme\n"
00946                  "                 insane\n"
00947                  "          <cbr> (ABR Mode) - The ABR Mode is implied. To use it,\n"
00948                  "                             simply specify a bitrate. For example:\n"
00949                  "                             \"--preset 185\" activates this\n"
00950                  "                             preset and uses 185 as an average kbps.\n" "\n");
00951     error_printf("    Some examples:\n"
00952                  "\n"
00953                  " or \"%s --preset fast standard <input file> <output file>\"\n"
00954                  " or \"%s --preset cbr 192 <input file> <output file>\"\n"
00955                  " or \"%s --preset 172 <input file> <output file>\"\n"
00956                  " or \"%s --preset extreme <input file> <output file>\"\n"
00957                  "\n"
00958                  "For further information try: \"%s --preset help\"\n", ProgramName, ProgramName,
00959                  ProgramName, ProgramName, ProgramName);
00960     return -1;
00961 }
00962 
00963 static void
00964 genre_list_handler(int num, const char *name, void *cookie)
00965 {
00966     console_printf("%3d %s\n", num, name);
00967 }
00968 
00969 
00970 /************************************************************************
00971 *
00972 * parse_args
00973 *
00974 * PURPOSE:  Sets encoding parameters to the specifications of the
00975 * command line.  Default settings are used for parameters
00976 * not specified in the command line.
00977 *
00978 * If the input file is in WAVE or AIFF format, the sampling frequency is read
00979 * from the AIFF header.
00980 *
00981 * The input and output filenames are read into #inpath# and #outpath#.
00982 *
00983 ************************************************************************/
00984 
00985 /* would use real "strcasecmp" but it isn't portable */
00986 static int
00987 local_strcasecmp(const char *s1, const char *s2)
00988 {
00989     unsigned char c1;
00990     unsigned char c2;
00991 
00992     do {
00993         c1 = tolower(*s1);
00994         c2 = tolower(*s2);
00995         if (!c1) {
00996             break;
00997         }
00998         ++s1;
00999         ++s2;
01000     } while (c1 == c2);
01001     return c1 - c2;
01002 }
01003 
01004 
01005 
01006 /* LAME is a simple frontend which just uses the file extension */
01007 /* to determine the file type.  Trying to analyze the file */
01008 /* contents is well beyond the scope of LAME and should not be added. */
01009 static int
01010 filename_to_type(const char *FileName)
01011 {
01012     size_t  len = strlen(FileName);
01013 
01014     if (len < 4)
01015         return sf_unknown;
01016 
01017     FileName += len - 4;
01018     if (0 == local_strcasecmp(FileName, ".mpg"))
01019         return sf_mp123;
01020     if (0 == local_strcasecmp(FileName, ".mp1"))
01021         return sf_mp123;
01022     if (0 == local_strcasecmp(FileName, ".mp2"))
01023         return sf_mp123;
01024     if (0 == local_strcasecmp(FileName, ".mp3"))
01025         return sf_mp123;
01026     if (0 == local_strcasecmp(FileName, ".wav"))
01027         return sf_wave;
01028     if (0 == local_strcasecmp(FileName, ".aif"))
01029         return sf_aiff;
01030     if (0 == local_strcasecmp(FileName, ".raw"))
01031         return sf_raw;
01032     if (0 == local_strcasecmp(FileName, ".ogg"))
01033         return sf_ogg;
01034     return sf_unknown;
01035 }
01036 
01037 static int
01038 resample_rate(double freq)
01039 {
01040     if (freq >= 1.e3)
01041         freq *= 1.e-3;
01042 
01043     switch ((int) freq) {
01044     case 8:
01045         return 8000;
01046     case 11:
01047         return 11025;
01048     case 12:
01049         return 12000;
01050     case 16:
01051         return 16000;
01052     case 22:
01053         return 22050;
01054     case 24:
01055         return 24000;
01056     case 32:
01057         return 32000;
01058     case 44:
01059         return 44100;
01060     case 48:
01061         return 48000;
01062     default:
01063         error_printf("Illegal resample frequency: %.3f kHz\n", freq);
01064         return 0;
01065     }
01066 }
01067 
01068 enum ID3TAG_MODE 
01069 { ID3TAG_MODE_DEFAULT
01070 , ID3TAG_MODE_V1_ONLY
01071 , ID3TAG_MODE_V2_ONLY
01072 };
01073 
01074 /* Ugly, NOT final version */
01075 
01076 #define T_IF(str)          if ( 0 == local_strcasecmp (token,str) ) {
01077 #define T_ELIF(str)        } else if ( 0 == local_strcasecmp (token,str) ) {
01078 #define T_ELIF_INTERNAL(str)        } else if (INTERNAL_OPTS && (0 == local_strcasecmp (token,str)) ) {
01079 #define T_ELIF2(str1,str2) } else if ( 0 == local_strcasecmp (token,str1)  ||  0 == local_strcasecmp (token,str2) ) {
01080 #define T_ELSE             } else {
01081 #define T_END              }
01082 
01083 int
01084 parse_args(lame_global_flags * gfp, int argc, char **argv,
01085            char *const inPath, char *const outPath, char **nogap_inPath, int *num_nogap)
01086 {
01087     int     input_file = 0;  /* set to 1 if we parse an input file name  */
01088     int     i;
01089     int     autoconvert = 0;
01090     double  val;
01091     int     nogap = 0;
01092     int     nogap_tags = 0;  /* set to 1 to use VBR tags in NOGAP mode */
01093     const char *ProgramName = argv[0];
01094     int     count_nogap = 0;
01095     int     noreplaygain = 0; /* is RG explicitly disabled by the user */
01096     int     id3tag_mode = ID3TAG_MODE_DEFAULT; 
01097 
01098     inPath[0] = '\0';
01099     outPath[0] = '\0';
01100     /* turn on display options. user settings may turn them off below */
01101     silent = 0;
01102     ignore_tag_errors = 0;
01103     brhist = 1;
01104     mp3_delay = 0;
01105     mp3_delay_set = 0;
01106     print_clipping_info = 0;
01107     disable_wav_header = 0;
01108     id3tag_init(gfp);
01109 
01110     /* process args */
01111     for (i = 0; ++i < argc;) {
01112         char    c;
01113         char   *token;
01114         char   *arg;
01115         char   *nextArg;
01116         int     argUsed;
01117 
01118         token = argv[i];
01119         if (*token++ == '-') {
01120             argUsed = 0;
01121             nextArg = i + 1 < argc ? argv[i + 1] : "";
01122 
01123             if (!*token) { /* The user wants to use stdin and/or stdout. */
01124                 input_file = 1;
01125                 if (inPath[0] == '\0')
01126                     strncpy(inPath, argv[i], PATH_MAX + 1);
01127                 else if (outPath[0] == '\0')
01128                     strncpy(outPath, argv[i], PATH_MAX + 1);
01129             }
01130             if (*token == '-') { /* GNU style */
01131                 token++;
01132 
01133                 T_IF("resample")
01134                     argUsed = 1;
01135                 (void) lame_set_out_samplerate(gfp, resample_rate(atof(nextArg)));
01136 
01137                 T_ELIF("vbr-old")
01138                     lame_set_VBR(gfp, vbr_rh);
01139 
01140                 T_ELIF("vbr-new")
01141                     lame_set_VBR(gfp, vbr_mtrh);
01142 
01143                 T_ELIF("vbr-mtrh")
01144                     lame_set_VBR(gfp, vbr_mtrh);
01145 
01146                 T_ELIF("cbr")
01147                     lame_set_VBR(gfp, vbr_off);
01148 
01149                 T_ELIF("abr")
01150                     argUsed = 1;
01151                 lame_set_VBR(gfp, vbr_abr);
01152                 lame_set_VBR_mean_bitrate_kbps(gfp, atoi(nextArg));
01153                 /* values larger than 8000 are bps (like Fraunhofer), so it's strange to get 320000 bps MP3 when specifying 8000 bps MP3 */
01154                 if (lame_get_VBR_mean_bitrate_kbps(gfp) >= 8000)
01155                     lame_set_VBR_mean_bitrate_kbps(gfp,
01156                                                    (lame_get_VBR_mean_bitrate_kbps(gfp) +
01157                                                     500) / 1000);
01158 
01159                 lame_set_VBR_mean_bitrate_kbps(gfp, Min(lame_get_VBR_mean_bitrate_kbps(gfp), 320));
01160                 lame_set_VBR_mean_bitrate_kbps(gfp, Max(lame_get_VBR_mean_bitrate_kbps(gfp), 8));
01161 
01162                 T_ELIF("r3mix")
01163                     lame_set_preset(gfp, R3MIX);
01164 
01165                 T_ELIF("bitwidth")
01166                     argUsed = 1;
01167                 in_bitwidth = atoi(nextArg);
01168 #ifdef LIBSNDFILE
01169                 T_ELIF("signed")
01170                     in_signed = 1;
01171 
01172                 T_ELIF("unsigned")
01173                     in_signed = 0;
01174 #endif
01175                 T_ELIF("little-endian")
01176                     in_endian = order_littleEndian;
01177 
01178                 T_ELIF("big-endian")
01179                     in_endian = order_bigEndian;
01180 
01181                 T_ELIF("mp1input")
01182                     input_format = sf_mp1;
01183 
01184                 T_ELIF("mp2input")
01185                     input_format = sf_mp2;
01186 
01187                 T_ELIF("mp3input")
01188                     input_format = sf_mp3;
01189 
01190                 T_ELIF("ogginput")
01191                     error_printf("sorry, vorbis support in LAME is deprecated.\n");
01192                 return -1;
01193 
01194                 T_ELIF("phone")
01195                     if (presets_set(gfp, 0, 0, token, ProgramName) < 0)
01196                     return -1;
01197                 error_printf("Warning: --phone is deprecated, use --preset phone instead!");
01198 
01199                 T_ELIF("voice")
01200                     if (presets_set(gfp, 0, 0, token, ProgramName) < 0)
01201                     return -1;
01202                 error_printf("Warning: --voice is deprecated, use --preset voice instead!");
01203 
01204                 T_ELIF("radio")
01205                     if (presets_set(gfp, 0, 0, token, ProgramName) < 0)
01206                     return -1;
01207                 error_printf("Warning: --radio is deprecated, use --preset radio instead!");
01208 
01209                 T_ELIF("tape")
01210                     if (presets_set(gfp, 0, 0, token, ProgramName) < 0)
01211                     return -1;
01212                 error_printf("Warning: --tape is deprecated, use --preset tape instead!");
01213 
01214                 T_ELIF("cd")
01215                     if (presets_set(gfp, 0, 0, token, ProgramName) < 0)
01216                     return -1;
01217                 error_printf("Warning: --cd is deprecated, use --preset cd instead!");
01218 
01219                 T_ELIF("studio")
01220                     if (presets_set(gfp, 0, 0, token, ProgramName) < 0)
01221                     return -1;
01222                 error_printf("Warning: --studio is deprecated, use --preset studio instead!");
01223 
01224                 T_ELIF_INTERNAL("noshort")
01225                     (void) lame_set_no_short_blocks(gfp, 1);
01226 
01227                 T_ELIF_INTERNAL("short")
01228                     (void) lame_set_no_short_blocks(gfp, 0);
01229 
01230                 T_ELIF_INTERNAL("allshort")
01231                     (void) lame_set_force_short_blocks(gfp, 1);
01232 
01233 
01234                 T_ELIF("decode")
01235                     (void) lame_set_decode_only(gfp, 1);
01236 
01237                 T_ELIF("flush")
01238                     flush_write = 1;
01239 
01240                 T_ELIF("decode-mp3delay")
01241                     mp3_delay = atoi(nextArg);
01242                 mp3_delay_set = 1;
01243                 argUsed = 1;
01244 
01245                 T_ELIF("nores")
01246                     lame_set_disable_reservoir(gfp, 1);
01247 
01248                 T_ELIF("strictly-enforce-ISO")
01249                     lame_set_strict_ISO(gfp, 1);
01250 
01251                 T_ELIF("scale")
01252                     argUsed = 1;
01253                 (void) lame_set_scale(gfp, (float) atof(nextArg));
01254 
01255                 T_ELIF("scale-l")
01256                     argUsed = 1;
01257                 (void) lame_set_scale_left(gfp, (float) atof(nextArg));
01258 
01259                 T_ELIF("scale-r")
01260                     argUsed = 1;
01261                 (void) lame_set_scale_right(gfp, (float) atof(nextArg));
01262 
01263                 T_ELIF("noasm")
01264                     argUsed = 1;
01265                 if (!strcmp(nextArg, "mmx"))
01266                     (void) lame_set_asm_optimizations(gfp, MMX, 0);
01267                 if (!strcmp(nextArg, "3dnow"))
01268                     (void) lame_set_asm_optimizations(gfp, AMD_3DNOW, 0);
01269                 if (!strcmp(nextArg, "sse"))
01270                     (void) lame_set_asm_optimizations(gfp, SSE, 0);
01271 
01272                 T_ELIF("freeformat")
01273                     lame_set_free_format(gfp, 1);
01274 
01275                 T_ELIF("replaygain-fast")
01276                     lame_set_findReplayGain(gfp, 1);
01277 
01278 #ifdef DECODE_ON_THE_FLY
01279                 T_ELIF("replaygain-accurate")
01280                     lame_set_decode_on_the_fly(gfp, 1);
01281                 lame_set_findReplayGain(gfp, 1);
01282 #endif
01283 
01284                 T_ELIF("noreplaygain")
01285                     noreplaygain = 1;
01286                 lame_set_findReplayGain(gfp, 0);
01287 
01288 
01289 #ifdef DECODE_ON_THE_FLY
01290                 T_ELIF("clipdetect")
01291                     print_clipping_info = 1;
01292                 lame_set_decode_on_the_fly(gfp, 1);
01293 #endif
01294 
01295                 T_ELIF("nohist")
01296                     brhist = 0;
01297 
01298 #if defined(__OS2__) || defined(WIN32)
01299                 T_ELIF("priority")
01300                 char   *endptr;
01301                 int     priority = (int) strtol(nextArg, &endptr, 10);
01302                 if (endptr != nextArg) {
01303                     argUsed = 1;
01304                 }
01305 # if defined(__OS2__)
01306                 setOS2Priority(gfp, priority);
01307 # else /* WIN32 */
01308                 setWin32Priority(gfp, priority);
01309 # endif
01310 #endif
01311 
01312                 /* options for ID3 tag */
01313                 T_ELIF("tt")
01314                     argUsed = 1;
01315                 id3tag_set_title(gfp, nextArg);
01316 
01317                 T_ELIF("ta")
01318                     argUsed = 1;
01319                 id3tag_set_artist(gfp, nextArg);
01320 
01321                 T_ELIF("tl")
01322                     argUsed = 1;
01323                 id3tag_set_album(gfp, nextArg);
01324 
01325                 T_ELIF("ty")
01326                     argUsed = 1;
01327                 id3tag_set_year(gfp, nextArg);
01328 
01329                 T_ELIF("tc")
01330                     argUsed = 1;
01331                 id3tag_set_comment(gfp, nextArg);
01332 
01333                 T_ELIF("tn")
01334                     int ret = id3tag_set_track(gfp, nextArg);
01335                     argUsed = 1;
01336                     if (ret != 0) {
01337                         if (0 == ignore_tag_errors) {
01338                             if (id3tag_mode == ID3TAG_MODE_V1_ONLY) {
01339                                 error_printf("The track number has to be between 1 and 255 for ID3v1.\n");
01340                                 return -1;
01341                             }
01342                             else if (id3tag_mode == ID3TAG_MODE_V2_ONLY) {
01343                                 /* track will be stored as-is in ID3v2 case, so no problem here */
01344                             }
01345                             else {
01346                                 if (silent < 10) {
01347                                     error_printf("The track number has to be between 1 and 255 for ID3v1, ignored for ID3v1.\n");
01348                                 }
01349                             }
01350                         }
01351                     }
01352 
01353                 T_ELIF("tg")
01354                     int ret = id3tag_set_genre(gfp, nextArg);
01355                     argUsed = 1;
01356                     if (ret != 0) {
01357                         if (0 == ignore_tag_errors) {
01358                             if (ret == -1) {
01359                                 error_printf("Unknown ID3v1 genre number: '%s'.\n", nextArg);
01360                                 return -1;
01361                             }
01362                             else if (ret == -2) {
01363                                 if (id3tag_mode == ID3TAG_MODE_V1_ONLY) {
01364                                     error_printf("Unknown ID3v1 genre: '%s'.\n", nextArg);
01365                                     return -1;
01366                                 }
01367                                 else if (id3tag_mode == ID3TAG_MODE_V2_ONLY) {
01368                                     /* genre will be stored as-is in ID3v2 case, so no problem here */
01369                                 }
01370                                 else {
01371                                     if (silent < 10) {
01372                                         error_printf("Unknown ID3v1 genre: '%s'.  Setting ID3v1 genre to 'Other'\n", nextArg);
01373                                     }
01374                                 }
01375                             }
01376                             else {
01377                                 error_printf("Internal error.\n");
01378                                 return -1;
01379                             }
01380                         }
01381                     }
01382 
01383                 T_ELIF("tv")
01384                     argUsed = 1;
01385                 if (id3tag_set_fieldvalue(gfp, nextArg)) {
01386                     if (silent < 10) {
01387                         error_printf("Invalid field value: '%s'. Ignored\n", nextArg);
01388                     }
01389                 }
01390 
01391                 T_ELIF("ti")
01392                     argUsed = 1;
01393                 if (nextArg) {
01394                     FILE *fpi = fopen(nextArg, "rb");
01395                     char *albumart = 0;
01396                     int ret = 0;
01397                     size_t size = 0;
01398                     if (!fpi) {
01399                         error_printf("Could not find: '%s'.\n", nextArg);
01400                         return -1;
01401                     }
01402                     fseek(fpi, 0, SEEK_END);
01403                     size = ftell(fpi);
01404                     fseek(fpi, 0, SEEK_SET);
01405                     albumart = (char *)malloc(size);
01406                     if (!albumart) {
01407                         error_printf("Insufficient memory for reading the albumart.\n");
01408                         return -1;
01409                     }
01410                     if (fread(albumart, 1, size, fpi) != size) {
01411                         error_printf("Read error: '%s'.\n", nextArg);
01412                         return -1;
01413                     }
01414                     fclose(fpi);
01415                     ret = id3tag_set_albumart(gfp, albumart, size);
01416                     free(albumart);
01417                     albumart = 0;
01418                     if (ret) {
01419                         error_printf("Unsupported image: '%s'.\nSpecify JPEG/PNG/GIF image (128KB maximum)\n",
01420                                      nextArg);
01421                         return -1;
01422                     }
01423                 }
01424 
01425                 T_ELIF("add-id3v2")
01426                     id3tag_add_v2(gfp);
01427 
01428                 T_ELIF("id3v1-only")
01429                     id3tag_v1_only(gfp);
01430                     id3tag_mode = ID3TAG_MODE_V1_ONLY;
01431 
01432                 T_ELIF("id3v2-only")
01433                     id3tag_v2_only(gfp);
01434                     id3tag_mode = ID3TAG_MODE_V2_ONLY;
01435 
01436                 T_ELIF("space-id3v1")
01437                     id3tag_space_v1(gfp);
01438 
01439                 T_ELIF("pad-id3v2")
01440                     id3tag_pad_v2(gfp);
01441 
01442                 T_ELIF("genre-list")
01443                     id3tag_genre_list(genre_list_handler, NULL);
01444                 return -2;
01445 
01446                 T_ELIF("lowpass")
01447                     val = atof(nextArg);
01448                 argUsed = 1;
01449                 /* useful are 0.001 kHz...50 kHz, 50 Hz...50000 Hz */
01450                 if (val < 0.001 || val > 50000.) {
01451                     error_printf("Must specify lowpass with --lowpass freq, freq >= 0.001 kHz\n");
01452                     return -1;
01453                 }
01454                 lame_set_lowpassfreq(gfp, (int) (val * (val < 50. ? 1.e3 : 1.e0) + 0.5));
01455 
01456                 T_ELIF("lowpass-width")
01457                     argUsed = 1;
01458                 val = 1000.0 * atof(nextArg) + 0.5;
01459                 if (val < 0) {
01460                     error_printf
01461                         ("Must specify lowpass width with --lowpass-width freq, freq >= 0 kHz\n");
01462                     return -1;
01463                 }
01464                 lame_set_lowpasswidth(gfp, (int) val);
01465 
01466                 T_ELIF("highpass")
01467                     val = atof(nextArg);
01468                 argUsed = 1;
01469                 /* useful are 0.001 kHz...16 kHz, 16 Hz...50000 Hz */
01470                 if (val < 0.001 || val > 50000.) {
01471                     error_printf("Must specify highpass with --highpass freq, freq >= 0.001 kHz\n");
01472                     return -1;
01473                 }
01474                 lame_set_highpassfreq(gfp, (int) (val * (val < 16. ? 1.e3 : 1.e0) + 0.5));
01475 
01476                 T_ELIF("highpass-width")
01477                     argUsed = 1;
01478                 val = 1000.0 * atof(nextArg) + 0.5;
01479                 if (val < 0) {
01480                     error_printf
01481                         ("Must specify highpass width with --highpass-width freq, freq >= 0 kHz\n");
01482                     return -1;
01483                 }
01484                 lame_set_highpasswidth(gfp, (int) val);
01485 
01486                 T_ELIF("comp")
01487                     argUsed = 1;
01488                 val = atof(nextArg);
01489                 if (val < 1.0) {
01490                     error_printf("Must specify compression ratio >= 1.0\n");
01491                     return -1;
01492                 }
01493                 lame_set_compression_ratio(gfp, (float) val);
01494 
01495                 T_ELIF("notemp")
01496                     (void) lame_set_useTemporal(gfp, 0);
01497 
01498                 T_ELIF("interch")
01499                     argUsed = 1;
01500                 (void) lame_set_interChRatio(gfp, (float) atof(nextArg));
01501 
01502                 T_ELIF("temporal-masking")
01503                     argUsed = 1;
01504                 (void) lame_set_useTemporal(gfp, atoi(nextArg) ? 1 : 0);
01505 
01506                 T_ELIF("nspsytune")
01507                     lame_set_psy_model(gfp, PSY_NSPSYTUNE);
01508 
01509                 T_ELIF("nssafejoint")
01510                     lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2);
01511 
01512                 T_ELIF("nsmsfix")
01513                     argUsed = 1;
01514                 (void) lame_set_msfix(gfp, atof(nextArg));
01515 
01516                 T_ELIF("ns-bass")
01517                     argUsed = 1;
01518                 {
01519                     double  d;
01520                     int     k;
01521                     d = atof(nextArg);
01522                     k = (int) (d * 4);
01523                     if (k < -32)
01524                         k = -32;
01525                     if (k > 31)
01526                         k = 31;
01527                     if (k < 0)
01528                         k += 64;
01529                     lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (k << 2));
01530                 }
01531 
01532                 T_ELIF("ns-alto")
01533                     argUsed = 1;
01534                 {
01535                     double  d;
01536                     int     k;
01537                     d = atof(nextArg);
01538                     k = (int) (d * 4);
01539                     if (k < -32)
01540                         k = -32;
01541                     if (k > 31)
01542                         k = 31;
01543                     if (k < 0)
01544                         k += 64;
01545                     lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (k << 8));
01546                 }
01547 
01548                 T_ELIF("ns-treble")
01549                     argUsed = 1;
01550                 {
01551                     double  d;
01552                     int     k;
01553                     d = atof(nextArg);
01554                     k = (int) (d * 4);
01555                     if (k < -32)
01556                         k = -32;
01557                     if (k > 31)
01558                         k = 31;
01559                     if (k < 0)
01560                         k += 64;
01561                     lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (k << 14));
01562                 }
01563 
01564                 T_ELIF("ns-sfb21")
01565                     /*  to be compatible with Naoki's original code,
01566                      *  ns-sfb21 specifies how to change ns-treble for sfb21 */
01567                     argUsed = 1;
01568                 {
01569                     double  d;
01570                     int     k;
01571                     d = atof(nextArg);
01572                     k = (int) (d * 4);
01573                     if (k < -32)
01574                         k = -32;
01575                     if (k > 31)
01576                         k = 31;
01577                     if (k < 0)
01578                         k += 64;
01579                     lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (k << 20));
01580                 }
01581 
01582                 T_ELIF("nspsytune2") {
01583                 }
01584 
01585                 /* some more GNU-ish options could be added
01586                  * brief         => few messages on screen (name, status report)
01587                  * o/output file => specifies output filename
01588                  * O             => stdout
01589                  * i/input file  => specifies input filename
01590                  * I             => stdin
01591                  */
01592                 T_ELIF2("quiet", "silent")
01593                     silent = 10; /* on a scale from 1 to 10 be very silent */
01594 
01595                 T_ELIF("brief")
01596                     silent = -5; /* print few info on screen */
01597 
01598                 T_ELIF("verbose")
01599                     silent = -10; /* print a lot on screen */
01600                 T_ELIF("ignore-tag-errors")
01601                     ignore_tag_errors = 1;
01602 
01603                 T_ELIF2("version", "license")
01604                     print_license(stdout);
01605                 return -2;
01606 
01607                 T_ELIF2("help", "usage")
01608                     short_help(gfp, stdout, ProgramName);
01609                 return -2;
01610 
01611                 T_ELIF("longhelp")
01612                     long_help(gfp, stdout, ProgramName, 0 /* lessmode=NO */ );
01613                 return -2;
01614 
01615                 T_ELIF("?")
01616 #ifdef __unix__
01617                 FILE   *fp = popen("less -Mqc", "w");
01618                 long_help(gfp, fp, ProgramName, 0 /* lessmode=NO */ );
01619                 pclose(fp);
01620 #else
01621                     long_help(gfp, stdout, ProgramName, 1 /* lessmode=YES */ );
01622 #endif
01623                 return -2;
01624 
01625                 T_ELIF2("preset", "alt-preset")
01626                     argUsed = 1;
01627                 {
01628                     int     fast = 0, cbr = 0;
01629 
01630                     while ((strcmp(nextArg, "fast") == 0) || (strcmp(nextArg, "cbr") == 0)) {
01631 
01632                         if ((strcmp(nextArg, "fast") == 0) && (fast < 1))
01633                             fast = 1;
01634                         if ((strcmp(nextArg, "cbr") == 0) && (cbr < 1))
01635                             cbr = 1;
01636 
01637                         argUsed++;
01638                         nextArg = i + argUsed < argc ? argv[i + argUsed] : "";
01639                     }
01640 
01641                     if (presets_set(gfp, fast, cbr, nextArg, ProgramName) < 0)
01642                         return -1;
01643                 }
01644 
01645                 T_ELIF("disptime")
01646                     argUsed = 1;
01647                 update_interval = (float) atof(nextArg);
01648 
01649                 T_ELIF("nogaptags")
01650                     nogap_tags = 1;
01651 
01652                 T_ELIF("nogapout")
01653                     strcpy(outPath, nextArg);
01654                 argUsed = 1;
01655 
01656                 T_ELIF("nogap")
01657                     nogap = 1;
01658 
01659 
01660                 T_ELIF_INTERNAL("tune") /*without helptext */
01661                     argUsed = 1;
01662                 {
01663                     extern void lame_set_tune(lame_t, float);
01664                     lame_set_tune(gfp, (float) atof(nextArg));
01665                 }
01666 
01667                 T_ELIF_INTERNAL("psymodel")
01668                     /*without helptext */
01669                     /* 1 gpsycho, 2 nspsytune */
01670                     argUsed = 1;
01671                 lame_set_psy_model(gfp, atoi(nextArg));
01672 
01673                 T_ELIF_INTERNAL("shortthreshold") {
01674                     float   x, y;
01675                     int     n = sscanf(nextArg, "%f,%f", &x, &y);
01676                     if (n == 1) {
01677                         y = x;
01678                     }
01679                     argUsed = 1;
01680                     (void) lame_set_short_threshold(gfp, x, y);
01681                 }
01682 
01683                 T_ELIF_INTERNAL("maskingadjust") /*without helptext */
01684                     argUsed = 1;
01685                 (void) lame_set_maskingadjust(gfp, (float) atof(nextArg));
01686 
01687                 T_ELIF_INTERNAL("maskingadjustshort") /*without helptext */
01688                     argUsed = 1;
01689                 (void) lame_set_maskingadjust_short(gfp, (float) atof(nextArg));
01690 
01691                 T_ELIF_INTERNAL("athcurve") /*without helptext */
01692                     argUsed = 1;
01693                 (void) lame_set_ATHcurve(gfp, (float) atof(nextArg));
01694 
01695                 T_ELIF_INTERNAL("no-preset-tune") /*without helptext */
01696                     (void) lame_set_preset_notune(gfp, 0);
01697 
01698                 T_ELIF_INTERNAL("substep")
01699                     argUsed = 1;
01700                 (void) lame_set_substep(gfp, atoi(nextArg));
01701 
01702                 T_ELIF_INTERNAL("sbgain") /*without helptext */
01703                     argUsed = 1;
01704                 (void) lame_set_subblock_gain(gfp, atoi(nextArg));
01705 
01706                 T_ELIF_INTERNAL("sfscale") /*without helptext */
01707                     (void) lame_set_sfscale(gfp, 1);
01708 
01709                 T_ELIF_INTERNAL("noath")
01710                     (void) lame_set_noATH(gfp, 1);
01711 
01712                 T_ELIF_INTERNAL("athonly")
01713                     (void) lame_set_ATHonly(gfp, 1);
01714 
01715                 T_ELIF_INTERNAL("athshort")
01716                     (void) lame_set_ATHshort(gfp, 1);
01717 
01718                 T_ELIF_INTERNAL("athlower")
01719                     argUsed = 1;
01720                 (void) lame_set_ATHlower(gfp, (float) atof(nextArg));
01721 
01722                 T_ELIF_INTERNAL("athtype")
01723                     argUsed = 1;
01724                 (void) lame_set_ATHtype(gfp, atoi(nextArg));
01725 
01726                 T_ELIF_INTERNAL("athaa-type") /*  switch for developing, no DOCU */
01727                     argUsed = 1; /* once was 1:Gaby, 2:Robert, 3:Jon, else:off */
01728                 lame_set_athaa_type(gfp, atoi(nextArg)); /* now: 0:off else:Jon */
01729 
01730                 T_ELIF ("athaa-sensitivity")
01731                     argUsed=1;
01732                 lame_set_athaa_sensitivity(gfp, (float) atof(nextArg));
01733 
01734                 T_ELIF_INTERNAL("cwlimit")
01735                     val = atof(nextArg);
01736                 argUsed = 1;
01737                 /* useful are 0.001 kHz...50 kHz, 50 Hz...50000 Hz */
01738                 {
01739                     int     my_cwlimit = (int) (val * (val <= 50. ? 1.e3 : 1.e0));
01740                     lame_set_cwlimit(gfp, my_cwlimit);
01741                     if (my_cwlimit <= 0) {
01742                         error_printf
01743                             ("Must specify cwlimit with --cwlimit freq, freq >= 0.001 kHz\n");
01744                         return -1;
01745                     }
01746                 }
01747 
01748                 T_ELIF_INTERNAL("quantization-type") /*  switch for developing, no DOCU */
01749                     argUsed = 1; /* 0:depending on quality, 1:ISO, 2:x^3/4 */
01750                 {
01751                     extern void lame_set_quantization_type(lame_t, int);
01752                     lame_set_quantization_type(gfp, atoi(nextArg)); /* now: 0:off else:Jon */
01753                 }
01754 
01755                 T_ELIF_INTERNAL("debug-file") /* switch for developing, no DOCU */
01756                     argUsed = 1; /* file name to print debug info into */
01757                 {
01758                     set_debug_file(nextArg);
01759                 }
01760 
01761                 T_ELSE {
01762                     error_printf("%s: unrecognized option --%s\n", ProgramName, token);
01763                     return -1;
01764                 }
01765                 T_END   i += argUsed;
01766 
01767             }
01768             else {
01769                 while ((c = *token++) != '\0') {
01770                     arg = *token ? token : nextArg;
01771                     switch (c) {
01772                     case 'm':
01773                         argUsed = 1;
01774 
01775                         switch (*arg) {
01776                         case 's':
01777                             (void) lame_set_mode(gfp, STEREO);
01778                             break;
01779                         case 'd':
01780                             (void) lame_set_mode(gfp, DUAL_CHANNEL);
01781                             break;
01782                         case 'f':
01783                             lame_set_force_ms(gfp, 1);
01784                             /* FALLTHROUGH */
01785                         case 'j':
01786                             (void) lame_set_mode(gfp, JOINT_STEREO);
01787                             break;
01788                         case 'm':
01789                             (void) lame_set_mode(gfp, MONO);
01790                             break;
01791                         case 'a':
01792                             (void) lame_set_mode(gfp, JOINT_STEREO);
01793                             break;
01794                         default:
01795                             error_printf("%s: -m mode must be s/d/j/f/m not %s\n", ProgramName,
01796                                          arg);
01797                             return -1;
01798                         }
01799                         break;
01800 
01801                     case 'V':
01802                         argUsed = 1;
01803                         /* to change VBR default look in lame.h */
01804                         if (lame_get_VBR(gfp) == vbr_off)
01805                             lame_set_VBR(gfp, vbr_default);
01806                         lame_set_VBR_q(gfp, atoi(arg));
01807                         if (lame_get_VBR_q(gfp) < 0)
01808                             lame_set_VBR_q(gfp, 0);
01809                         if (lame_get_VBR_q(gfp) > 9)
01810                             lame_set_VBR_q(gfp, 9);
01811                         break;
01812                     case 'v':
01813                         /* to change VBR default look in lame.h */
01814                         if (lame_get_VBR(gfp) == vbr_off)
01815                             lame_set_VBR(gfp, vbr_default);
01816                         break;
01817 
01818                     case 'q':
01819                         argUsed = 1;
01820                         {
01821                             int     tmp_quality = atoi(arg);
01822 
01823                             /* XXX should we move this into lame_set_quality()? */
01824                             if (tmp_quality < 0)
01825                                 tmp_quality = 0;
01826                             if (tmp_quality > 9)
01827                                 tmp_quality = 9;
01828 
01829                             (void) lame_set_quality(gfp, tmp_quality);
01830                         }
01831                         break;
01832                     case 'f':
01833                         (void) lame_set_quality(gfp, 7);
01834                         break;
01835                     case 'h':
01836                         (void) lame_set_quality(gfp, 2);
01837                         break;
01838 
01839                     case 's':
01840                         argUsed = 1;
01841                         val = atof(arg);
01842                         (void) lame_set_in_samplerate(gfp,
01843                                                       (int) (val * (val <= 192 ? 1.e3 : 1.e0) +
01844                                                              0.5));
01845                         break;
01846                     case 'b':
01847                         argUsed = 1;
01848                         lame_set_brate(gfp, atoi(arg));
01849                         lame_set_VBR_min_bitrate_kbps(gfp, lame_get_brate(gfp));
01850                         break;
01851                     case 'B':
01852                         argUsed = 1;
01853                         lame_set_VBR_max_bitrate_kbps(gfp, atoi(arg));
01854                         break;
01855                     case 'F':
01856                         lame_set_VBR_hard_min(gfp, 1);
01857                         break;
01858                     case 't': /* dont write VBR tag */
01859                         (void) lame_set_bWriteVbrTag(gfp, 0);
01860                         disable_wav_header = 1;
01861                         break;
01862                     case 'T': /* do write VBR tag */
01863                         (void) lame_set_bWriteVbrTag(gfp, 1);
01864                         nogap_tags = 1;
01865                         disable_wav_header = 0;
01866                         break;
01867                     case 'r': /* force raw pcm input file */
01868 #if defined(LIBSNDFILE)
01869                         error_printf
01870                             ("WARNING: libsndfile may ignore -r and perform fseek's on the input.\n"
01871                              "Compile without libsndfile if this is a problem.\n");
01872 #endif
01873                         input_format = sf_raw;
01874                         break;
01875                     case 'x': /* force byte swapping */
01876                         swapbytes = 1;
01877                         break;
01878                     case 'p': /* (jo) error_protection: add crc16 information to stream */
01879                         lame_set_error_protection(gfp, 1);
01880                         break;
01881                     case 'a': /* autoconvert input file from stereo to mono - for mono mp3 encoding */
01882                         autoconvert = 1;
01883                         (void) lame_set_mode(gfp, MONO);
01884                         break;
01885                     case 'd':   /*(void) lame_set_allow_diff_short( gfp, 1 ); */
01886                     case 'k':   /*lame_set_lowpassfreq(gfp, -1);
01887                                   lame_set_highpassfreq(gfp, -1); */
01888                         error_printf("WARNING: -%c is obsolete.\n", c);
01889                         break;
01890                     case 'S':
01891                         silent = 10;
01892                         break;
01893                     case 'X':
01894                         /*  experimental switch -X:
01895                             the differnt types of quant compare are tough
01896                             to communicate to endusers, so they shouldn't
01897                             bother to toy around with them
01898                          */
01899                         {
01900                             int     x, y;
01901                             int     n = sscanf(arg, "%d,%d", &x, &y);
01902                             if (n == 1) {
01903                                 y = x;
01904                             }
01905                             argUsed = 1;
01906                             if (INTERNAL_OPTS) {
01907                                 lame_set_quant_comp(gfp, x);
01908                                 lame_set_quant_comp_short(gfp, y);
01909                             }
01910                         }
01911                         break;
01912                     case 'Y':
01913                         lame_set_experimentalY(gfp, 1);
01914                         break;
01915                     case 'Z':
01916                         /*  experimental switch -Z:
01917                             this switch is obsolete
01918                          */
01919                         {
01920                             int     n = 1;
01921                             argUsed = sscanf(arg, "%d", &n);
01922                             if (INTERNAL_OPTS) {
01923                                 lame_set_experimentalZ(gfp, n);
01924                             }
01925                         }
01926                         break;
01927                     case 'e':
01928                         argUsed = 1;
01929 
01930                         switch (*arg) {
01931                         case 'n':
01932                             lame_set_emphasis(gfp, 0);
01933                             break;
01934                         case '5':
01935                             lame_set_emphasis(gfp, 1);
01936                             break;
01937                         case 'c':
01938                             lame_set_emphasis(gfp, 3);
01939                             break;
01940                         default:
01941                             error_printf("%s: -e emp must be n/5/c not %s\n", ProgramName, arg);
01942                             return -1;
01943                         }
01944                         break;
01945                     case 'c':
01946                         lame_set_copyright(gfp, 1);
01947                         break;
01948                     case 'o':
01949                         lame_set_original(gfp, 0);
01950                         break;
01951 
01952                     case '?':
01953                         long_help(gfp, stdout, ProgramName, 0 /* LESSMODE=NO */ );
01954                         return -1;
01955 
01956                     default:
01957                         error_printf("%s: unrecognized option -%c\n", ProgramName, c);
01958                         return -1;
01959                     }
01960                     if (argUsed) {
01961                         if (arg == token)
01962                             token = ""; /* no more from token */
01963                         else
01964                             ++i; /* skip arg we used */
01965                         arg = "";
01966                         argUsed = 0;
01967                     }
01968                 }
01969             }
01970         }
01971         else {
01972             if (nogap) {
01973                 if ((num_nogap != NULL) && (count_nogap < *num_nogap)) {
01974                     strncpy(nogap_inPath[count_nogap++], argv[i], PATH_MAX + 1);
01975                     input_file = 1;
01976                 }
01977                 else {
01978                     /* sorry, calling program did not allocate enough space */
01979                     error_printf
01980                         ("Error: 'nogap option'.  Calling program does not allow nogap option, or\n"
01981                          "you have exceeded maximum number of input files for the nogap option\n");
01982                     *num_nogap = -1;
01983                     return -1;
01984                 }
01985             }
01986             else {
01987                 /* normal options:   inputfile  [outputfile], and
01988                    either one can be a '-' for stdin/stdout */
01989                 if (inPath[0] == '\0') {
01990                     strncpy(inPath, argv[i], PATH_MAX + 1);
01991                     input_file = 1;
01992                 }
01993                 else {
01994                     if (outPath[0] == '\0')
01995                         strncpy(outPath, argv[i], PATH_MAX + 1);
01996                     else {
01997                         error_printf("%s: excess arg %s\n", ProgramName, argv[i]);
01998                         return -1;
01999                     }
02000                 }
02001             }
02002         }
02003     }                   /* loop over args */
02004 
02005     if (!input_file) {
02006         usage(Console_IO.Console_fp, ProgramName);
02007         return -1;
02008     }
02009 
02010     if (inPath[0] == '-')
02011         silent = (silent <= 1 ? 1 : silent);
02012 #ifdef WIN32
02013     else
02014         dosToLongFileName(inPath);
02015 #endif
02016 
02017     if (outPath[0] == '\0' && count_nogap == 0) {
02018         if (inPath[0] == '-') {
02019             /* if input is stdin, default output is stdout */
02020             strcpy(outPath, "-");
02021         }
02022         else {
02023             strncpy(outPath, inPath, PATH_MAX + 1 - 4);
02024             if (lame_get_decode_only(gfp)) {
02025                 strncat(outPath, ".wav", 4);
02026             }
02027             else {
02028                 strncat(outPath, ".mp3", 4);
02029             }
02030         }
02031     }
02032 
02033     /* RG is enabled by default */
02034     if (!noreplaygain)
02035         lame_set_findReplayGain(gfp, 1);
02036 
02037     /* disable VBR tags with nogap unless the VBR tags are forced */
02038     if (nogap && lame_get_bWriteVbrTag(gfp) && nogap_tags == 0) {
02039         console_printf("Note: Disabling VBR Xing/Info tag since it interferes with --nogap\n");
02040         lame_set_bWriteVbrTag(gfp, 0);
02041     }
02042 
02043     /* some file options not allowed with stdout */
02044     if (outPath[0] == '-') {
02045         (void) lame_set_bWriteVbrTag(gfp, 0); /* turn off VBR tag */
02046     }
02047 
02048     /* if user did not explicitly specify input is mp3, check file name */
02049     if (input_format == sf_unknown)
02050         input_format = filename_to_type(inPath);
02051 
02052 #if !(defined HAVE_MPGLIB || defined AMIGA_MPEGA)
02053     if (is_mpeg_file_format(input_format)) {
02054         error_printf("Error: libmp3lame not compiled with mpg123 *decoding* support \n");
02055         return -1;
02056     }
02057 #endif
02058 
02059 
02060     if (is_mpeg_file_format(input_format) && print_clipping_info) {
02061 
02062         error_printf("\nError: input cannot be MPEG when --clipdetect is used\n"
02063                      "\n--clipdetect requires decoding of MPEG *output* on the fly which\n"
02064                      "cannot be performed simultaneously with decoding MPEG *input*.\n"
02065                      "\nUse a plain .wav file as input with --clipdetect.\n");
02066 
02067         return -1;
02068     }
02069 
02070 
02071     if (is_mpeg_file_format(input_format) && lame_get_decode_on_the_fly(gfp)) {
02072 
02073         error_printf("\nError: input cannot be MPEG when --replaygain-accurate is used\n"
02074                      "\n--replaygain-accurate requires decoding of MPEG *output* on the fly which\n"
02075                      "cannot be performed simultaneously with decoding MPEG *input*.\n"
02076                      "\nUse a plain .wav file as input with --replaygain-accurate.\n");
02077 
02078         return -1;
02079     }
02080 
02081 
02082     if (input_format == sf_ogg) {
02083         error_printf("sorry, vorbis support in LAME is deprecated.\n");
02084         return -1;
02085     }
02086     /* default guess for number of channels */
02087     if (autoconvert)
02088         (void) lame_set_num_channels(gfp, 2);
02089     else if (MONO == lame_get_mode(gfp))
02090         (void) lame_set_num_channels(gfp, 1);
02091     else
02092         (void) lame_set_num_channels(gfp, 2);
02093 
02094     if (lame_get_free_format(gfp)) {
02095         if (lame_get_brate(gfp) < 8 || lame_get_brate(gfp) > 640) {
02096             error_printf("For free format, specify a bitrate between 8 and 640 kbps\n");
02097             error_printf("with the -b <bitrate> option\n");
02098             return -1;
02099         }
02100     }
02101     if (num_nogap != NULL)
02102         *num_nogap = count_nogap;
02103     return 0;
02104 }
02105 
02106 
02107 /* end of parse.c */

Generated on Sun Dec 2 11:34:18 2007 for LAME by  doxygen 1.5.2