00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00088
00089 sound_file_format input_format;
00090 int swapbytes = 0;
00091 int silent;
00092 int ignore_tag_errors;
00093 int brhist;
00094 float update_interval;
00095 int mp3_delay;
00096
00097 int mp3_delay_set;
00098
00099
00100 int disable_wav_header;
00101 mp3data_struct mp3input_data;
00102 int print_clipping_info;
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;
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
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,
00198 PRTYC_IDLE,
00199 0,
00200 0);
00201 console_printf("==> Priority set to 0 (Low priority).\n");
00202 break;
00203
00204 case 1:
00205 rc = DosSetPriority(0,
00206 PRTYC_IDLE,
00207 PRTYD_MAXIMUM,
00208 0);
00209 console_printf("==> Priority set to 1 (Medium priority).\n");
00210 break;
00211
00212 case 2:
00213 rc = DosSetPriority(0,
00214 PRTYC_REGULAR,
00215 PRTYD_MINIMUM,
00216 0);
00217 console_printf("==> Priority set to 2 (Regular priority).\n");
00218 break;
00219
00220 case 3:
00221 rc = DosSetPriority(0,
00222 PRTYC_REGULAR,
00223 0,
00224 0);
00225 console_printf("==> Priority set to 3 (High priority).\n");
00226 break;
00227
00228 case 4:
00229 rc = DosSetPriority(0,
00230 PRTYC_REGULAR,
00231 PRTYD_MAXIMUM,
00232 0);
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
00249
00250
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;
00264 const size_t sw = 16;
00265
00266 if (lw >= lenb + lenv + lenu + sw || lw < lenu + 2)
00267
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
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 {
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
00331
00332
00333
00334
00335
00336 int
00337 usage(FILE * const fp, const char *ProgramName)
00338 {
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
00360
00361
00362
00363
00364
00365
00366 int
00367 short_help(const lame_global_flags * gfp, FILE * const fp, const char *ProgramName)
00368 {
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
00414
00415
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 {
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
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
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
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
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
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
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
01007
01008
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
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;
01088 int i;
01089 int autoconvert = 0;
01090 double val;
01091 int nogap = 0;
01092 int nogap_tags = 0;
01093 const char *ProgramName = argv[0];
01094 int count_nogap = 0;
01095 int noreplaygain = 0;
01096 int id3tag_mode = ID3TAG_MODE_DEFAULT;
01097
01098 inPath[0] = '\0';
01099 outPath[0] = '\0';
01100
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
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) {
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 == '-') {
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
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
01308 setWin32Priority(gfp, priority);
01309 # endif
01310 #endif
01311
01312
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
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
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
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
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
01566
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
01586
01587
01588
01589
01590
01591
01592 T_ELIF2("quiet", "silent")
01593 silent = 10;
01594
01595 T_ELIF("brief")
01596 silent = -5;
01597
01598 T_ELIF("verbose")
01599 silent = -10;
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 );
01613 return -2;
01614
01615 T_ELIF("?")
01616 #ifdef __unix__
01617 FILE *fp = popen("less -Mqc", "w");
01618 long_help(gfp, fp, ProgramName, 0 );
01619 pclose(fp);
01620 #else
01621 long_help(gfp, stdout, ProgramName, 1 );
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")
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
01669
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")
01684 argUsed = 1;
01685 (void) lame_set_maskingadjust(gfp, (float) atof(nextArg));
01686
01687 T_ELIF_INTERNAL("maskingadjustshort")
01688 argUsed = 1;
01689 (void) lame_set_maskingadjust_short(gfp, (float) atof(nextArg));
01690
01691 T_ELIF_INTERNAL("athcurve")
01692 argUsed = 1;
01693 (void) lame_set_ATHcurve(gfp, (float) atof(nextArg));
01694
01695 T_ELIF_INTERNAL("no-preset-tune")
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")
01703 argUsed = 1;
01704 (void) lame_set_subblock_gain(gfp, atoi(nextArg));
01705
01706 T_ELIF_INTERNAL("sfscale")
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")
01727 argUsed = 1;
01728 lame_set_athaa_type(gfp, atoi(nextArg));
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
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")
01749 argUsed = 1;
01750 {
01751 extern void lame_set_quantization_type(lame_t, int);
01752 lame_set_quantization_type(gfp, atoi(nextArg));
01753 }
01754
01755 T_ELIF_INTERNAL("debug-file")
01756 argUsed = 1;
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
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
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
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
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':
01859 (void) lame_set_bWriteVbrTag(gfp, 0);
01860 disable_wav_header = 1;
01861 break;
01862 case 'T':
01863 (void) lame_set_bWriteVbrTag(gfp, 1);
01864 nogap_tags = 1;
01865 disable_wav_header = 0;
01866 break;
01867 case 'r':
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':
01876 swapbytes = 1;
01877 break;
01878 case 'p':
01879 lame_set_error_protection(gfp, 1);
01880 break;
01881 case 'a':
01882 autoconvert = 1;
01883 (void) lame_set_mode(gfp, MONO);
01884 break;
01885 case 'd':
01886 case 'k':
01887
01888 error_printf("WARNING: -%c is obsolete.\n", c);
01889 break;
01890 case 'S':
01891 silent = 10;
01892 break;
01893 case 'X':
01894
01895
01896
01897
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
01917
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 );
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 = "";
01963 else
01964 ++i;
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
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
01988
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 }
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
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
02034 if (!noreplaygain)
02035 lame_set_findReplayGain(gfp, 1);
02036
02037
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
02044 if (outPath[0] == '-') {
02045 (void) lame_set_bWriteVbrTag(gfp, 0);
02046 }
02047
02048
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
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