parse.c 93 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624
  1. /*
  2. * Command line parsing related functions
  3. *
  4. * Copyright (c) 1999 Mark Taylor
  5. * 2000-2017 Robert Hegemann
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Library General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Library General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Library General Public
  18. * License along with this library; if not, write to the
  19. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20. * Boston, MA 02111-1307, USA.
  21. */
  22. /* $Id$ */
  23. #ifdef HAVE_CONFIG_H
  24. # include <config.h>
  25. #endif
  26. #include <assert.h>
  27. #include <ctype.h>
  28. #include <math.h>
  29. #ifdef STDC_HEADERS
  30. # include <stdio.h>
  31. # include <stdlib.h>
  32. # include <string.h>
  33. #else
  34. # ifndef HAVE_STRCHR
  35. # define strchr index
  36. # define strrchr rindex
  37. # endif
  38. char *strchr(), *strrchr();
  39. # ifndef HAVE_MEMCPY
  40. # define memcpy(d, s, n) bcopy ((s), (d), (n))
  41. # define memmove(d, s, n) bcopy ((s), (d), (n))
  42. # endif
  43. #endif
  44. #ifdef HAVE_LIMITS_H
  45. # include <limits.h>
  46. #endif
  47. #include "lame.h"
  48. #include "parse.h"
  49. #include "main.h"
  50. #include "get_audio.h"
  51. #include "version.h"
  52. #include "console.h"
  53. #undef dimension_of
  54. #define dimension_of(array) (sizeof(array)/sizeof(array[0]))
  55. #ifdef WITH_DMALLOC
  56. #include <dmalloc.h>
  57. #endif
  58. #ifdef HAVE_ICONV
  59. #include <iconv.h>
  60. #include <errno.h>
  61. #include <locale.h>
  62. #include <langinfo.h>
  63. #endif
  64. #if defined _ALLOW_INTERNAL_OPTIONS
  65. #define INTERNAL_OPTS 1
  66. #else
  67. #define INTERNAL_OPTS 0
  68. #endif
  69. #if (INTERNAL_OPTS!=0)
  70. #include "set_get.h"
  71. #define DEV_HELP(a) a
  72. #else
  73. #define DEV_HELP(a)
  74. #define lame_set_tune(a,b) (void)0
  75. #define lame_set_short_threshold(a,b,c) (void)0
  76. #define lame_set_maskingadjust(a,b) (void)0
  77. #define lame_set_maskingadjust_short(a,b) (void)0
  78. #define lame_set_ATHcurve(a,b) (void)0
  79. #define lame_set_preset_notune(a,b) (void)0
  80. #define lame_set_substep(a,b) (void)0
  81. #define lame_set_subblock_gain(a,b) (void)0
  82. #define lame_set_sfscale(a,b) (void)0
  83. #endif
  84. static int const lame_alpha_version_enabled = LAME_ALPHA_VERSION;
  85. static int const internal_opts_enabled = INTERNAL_OPTS;
  86. /* GLOBAL VARIABLES. set by parse_args() */
  87. /* we need to clean this up */
  88. ReaderConfig global_reader = { sf_unknown, 0, 0, 0, 0 };
  89. WriterConfig global_writer = { 0 };
  90. UiConfig global_ui_config = {0,0,0,0};
  91. DecoderConfig global_decoder;
  92. RawPCMConfig global_raw_pcm =
  93. { /* in_bitwidth */ 16
  94. , /* in_signed */ -1
  95. , /* in_endian */ ByteOrderLittleEndian
  96. };
  97. /* possible text encodings */
  98. typedef enum TextEncoding
  99. { TENC_RAW /* bytes will be stored as-is into ID3 tags, which are Latin1 per definition */
  100. , TENC_LATIN1 /* text will be converted from local encoding to Latin1, as ID3 needs it */
  101. , TENC_UTF16 /* text will be converted from local encoding to Unicode, as ID3v2 wants it */
  102. } TextEncoding;
  103. #ifdef HAVE_ICONV
  104. #define ID3TAGS_EXTENDED
  105. /* search for Zero termination in multi-byte strings */
  106. static size_t
  107. strlenMultiByte(char const* str, size_t w)
  108. {
  109. size_t n = 0;
  110. if (str != 0) {
  111. size_t i, x = 0;
  112. for (n = 0; ; ++n) {
  113. x = 0;
  114. for (i = 0; i < w; ++i) {
  115. x += *str++ == 0 ? 1 : 0;
  116. }
  117. if (x == w) {
  118. break;
  119. }
  120. }
  121. }
  122. return n;
  123. }
  124. static size_t
  125. currCharCodeSize(void)
  126. {
  127. size_t n = 1;
  128. char dst[32];
  129. char* src = "A";
  130. char* cur_code = nl_langinfo(CODESET);
  131. iconv_t xiconv = iconv_open(cur_code, "ISO_8859-1");
  132. if (xiconv != (iconv_t)-1) {
  133. for (n = 0; n < 32; ++n) {
  134. char* i_ptr = src;
  135. char* o_ptr = dst;
  136. size_t srcln = 1;
  137. size_t avail = n;
  138. size_t rc = iconv(xiconv, &i_ptr, &srcln, &o_ptr, &avail);
  139. if (rc != (size_t)-1) {
  140. break;
  141. }
  142. }
  143. iconv_close(xiconv);
  144. }
  145. return n;
  146. }
  147. #if 0
  148. static
  149. char* fromLatin1( char* src )
  150. {
  151. char* dst = 0;
  152. if (src != 0) {
  153. size_t const l = strlen(src);
  154. size_t const n = l*4;
  155. dst = calloc(n+4, 4);
  156. if (dst != 0) {
  157. char* cur_code = nl_langinfo(CODESET);
  158. iconv_t xiconv = iconv_open(cur_code, "ISO_8859-1");
  159. if (xiconv != (iconv_t)-1) {
  160. char* i_ptr = src;
  161. char* o_ptr = dst;
  162. size_t srcln = l;
  163. size_t avail = n;
  164. iconv(xiconv, &i_ptr, &srcln, &o_ptr, &avail);
  165. iconv_close(xiconv);
  166. }
  167. }
  168. }
  169. return dst;
  170. }
  171. static
  172. char* fromUtf16( char* src )
  173. {
  174. char* dst = 0;
  175. if (src != 0) {
  176. size_t const l = strlenMultiByte(src, 2);
  177. size_t const n = l*4;
  178. dst = calloc(n+4, 4);
  179. if (dst != 0) {
  180. char* cur_code = nl_langinfo(CODESET);
  181. iconv_t xiconv = iconv_open(cur_code, "UTF-16LE");
  182. if (xiconv != (iconv_t)-1) {
  183. char* i_ptr = (char*)src;
  184. char* o_ptr = dst;
  185. size_t srcln = l*2;
  186. size_t avail = n;
  187. iconv(xiconv, &i_ptr, &srcln, &o_ptr, &avail);
  188. iconv_close(xiconv);
  189. }
  190. }
  191. }
  192. return dst;
  193. }
  194. #endif
  195. static
  196. char* toLatin1( char* src )
  197. {
  198. size_t w = currCharCodeSize();
  199. char* dst = 0;
  200. if (src != 0) {
  201. size_t const l = strlenMultiByte(src, w);
  202. size_t const n = l*4;
  203. dst = calloc(n+4, 4);
  204. if (dst != 0) {
  205. char* cur_code = nl_langinfo(CODESET);
  206. iconv_t xiconv = iconv_open("ISO_8859-1//TRANSLIT", cur_code);
  207. if (xiconv != (iconv_t)-1) {
  208. char* i_ptr = (char*)src;
  209. char* o_ptr = dst;
  210. size_t srcln = l*w;
  211. size_t avail = n;
  212. iconv(xiconv, &i_ptr, &srcln, &o_ptr, &avail);
  213. iconv_close(xiconv);
  214. }
  215. }
  216. }
  217. return dst;
  218. }
  219. static
  220. char* toUtf16( char* src )
  221. {
  222. size_t w = currCharCodeSize();
  223. char* dst = 0;
  224. if (src != 0) {
  225. size_t const l = strlenMultiByte(src, w);
  226. size_t const n = (l+1)*4;
  227. dst = calloc(n+4, 4);
  228. if (dst != 0) {
  229. char* cur_code = nl_langinfo(CODESET);
  230. iconv_t xiconv = iconv_open("UTF-16LE//TRANSLIT", cur_code);
  231. dst[0] = 0xff;
  232. dst[1] = 0xfe;
  233. if (xiconv != (iconv_t)-1) {
  234. char* i_ptr = (char*)src;
  235. char* o_ptr = &dst[2];
  236. size_t srcln = l*w;
  237. size_t avail = n;
  238. iconv(xiconv, &i_ptr, &srcln, &o_ptr, &avail);
  239. iconv_close(xiconv);
  240. }
  241. }
  242. }
  243. return dst;
  244. }
  245. #endif
  246. #if defined( _WIN32 ) && !defined(__MINGW32__)
  247. #define ID3TAGS_EXTENDED
  248. char* toLatin1(char const* s)
  249. {
  250. return utf8ToLatin1(s);
  251. }
  252. unsigned short* toUtf16(char const* s)
  253. {
  254. return utf8ToUtf16(s);
  255. }
  256. #endif
  257. static int evaluateArgument(char const* token, char const* arg, char* _EndPtr)
  258. {
  259. if (arg != 0 && arg != _EndPtr)
  260. return 1;
  261. error_printf("WARNING: argument missing for '%s'\n", token);
  262. return 0;
  263. }
  264. static int getDoubleValue(char const* token, char const* arg, double* ptr)
  265. {
  266. char *_EndPtr=0;
  267. double d = strtod(arg, &_EndPtr);
  268. if (ptr != 0) {
  269. *ptr = d;
  270. }
  271. return evaluateArgument(token, arg, _EndPtr);
  272. }
  273. static int getIntValue(char const* token, char const* arg, int* ptr)
  274. {
  275. char *_EndPtr=0;
  276. long d = strtol(arg, &_EndPtr, 10);
  277. if (ptr != 0) {
  278. *ptr = d;
  279. }
  280. return evaluateArgument(token, arg, _EndPtr);
  281. }
  282. #ifdef ID3TAGS_EXTENDED
  283. static int
  284. set_id3v2tag(lame_global_flags* gfp, int type, unsigned short const* str)
  285. {
  286. switch (type)
  287. {
  288. case 'a': return id3tag_set_textinfo_utf16(gfp, "TPE1", str);
  289. case 't': return id3tag_set_textinfo_utf16(gfp, "TIT2", str);
  290. case 'l': return id3tag_set_textinfo_utf16(gfp, "TALB", str);
  291. case 'g': return id3tag_set_textinfo_utf16(gfp, "TCON", str);
  292. case 'c': return id3tag_set_comment_utf16(gfp, 0, 0, str);
  293. case 'n': return id3tag_set_textinfo_utf16(gfp, "TRCK", str);
  294. case 'y': return id3tag_set_textinfo_utf16(gfp, "TYER", str);
  295. case 'v': return id3tag_set_fieldvalue_utf16(gfp, str);
  296. }
  297. return 0;
  298. }
  299. #endif
  300. static int
  301. set_id3tag(lame_global_flags* gfp, int type, char const* str)
  302. {
  303. switch (type)
  304. {
  305. case 'a': return id3tag_set_artist(gfp, str), 0;
  306. case 't': return id3tag_set_title(gfp, str), 0;
  307. case 'l': return id3tag_set_album(gfp, str), 0;
  308. case 'g': return id3tag_set_genre(gfp, str);
  309. case 'c': return id3tag_set_comment(gfp, str), 0;
  310. case 'n': return id3tag_set_track(gfp, str);
  311. case 'y': return id3tag_set_year(gfp, str), 0;
  312. case 'v': return id3tag_set_fieldvalue(gfp, str);
  313. }
  314. return 0;
  315. }
  316. static int
  317. id3_tag(lame_global_flags* gfp, int type, TextEncoding enc, char* str)
  318. {
  319. void* x = 0;
  320. int result;
  321. if (enc == TENC_UTF16 && type != 'v' ) {
  322. id3_tag(gfp, type, TENC_LATIN1, str); /* for id3v1 */
  323. }
  324. switch (enc)
  325. {
  326. default:
  327. #ifdef ID3TAGS_EXTENDED
  328. case TENC_LATIN1: x = toLatin1(str); break;
  329. case TENC_UTF16: x = toUtf16(str); break;
  330. #else
  331. case TENC_RAW: x = strdup(str); break;
  332. #endif
  333. }
  334. switch (enc)
  335. {
  336. default:
  337. #ifdef ID3TAGS_EXTENDED
  338. case TENC_LATIN1: result = set_id3tag(gfp, type, x); break;
  339. case TENC_UTF16: result = set_id3v2tag(gfp, type, x); break;
  340. #else
  341. case TENC_RAW: result = set_id3tag(gfp, type, x); break;
  342. #endif
  343. }
  344. free(x);
  345. return result;
  346. }
  347. /************************************************************************
  348. *
  349. * license
  350. *
  351. * PURPOSE: Writes version and license to the file specified by fp
  352. *
  353. ************************************************************************/
  354. static int
  355. lame_version_print(FILE * const fp)
  356. {
  357. const char *b = get_lame_os_bitness();
  358. const char *v = get_lame_version();
  359. const char *u = get_lame_url();
  360. const size_t lenb = strlen(b);
  361. const size_t lenv = strlen(v);
  362. const size_t lenu = strlen(u);
  363. const size_t lw = 80; /* line width of terminal in characters */
  364. const size_t sw = 16; /* static width of text */
  365. if (lw >= lenb + lenv + lenu + sw || lw < lenu + 2)
  366. /* text fits in 80 chars per line, or line even too small for url */
  367. if (lenb > 0)
  368. fprintf(fp, "LAME %s version %s (%s)\n\n", b, v, u);
  369. else
  370. fprintf(fp, "LAME version %s (%s)\n\n", v, u);
  371. else {
  372. int const n_white_spaces = (int)((lenu+2) > lw ? 0 : lw-2-lenu);
  373. /* text too long, wrap url into next line, right aligned */
  374. if (lenb > 0)
  375. fprintf(fp, "LAME %s version %s\n%*s(%s)\n\n", b, v, n_white_spaces, "", u);
  376. else
  377. fprintf(fp, "LAME version %s\n%*s(%s)\n\n", v, n_white_spaces, "", u);
  378. }
  379. if (lame_alpha_version_enabled)
  380. fprintf(fp, "warning: alpha versions should be used for testing only\n\n");
  381. return 0;
  382. }
  383. static int
  384. print_license(FILE * const fp)
  385. { /* print version & license */
  386. lame_version_print(fp);
  387. fprintf(fp,
  388. "Copyright (c) 1999-2011 by The LAME Project\n"
  389. "Copyright (c) 1999,2000,2001 by Mark Taylor\n"
  390. "Copyright (c) 1998 by Michael Cheng\n"
  391. "Copyright (c) 1995,1996,1997 by Michael Hipp: mpglib\n" "\n");
  392. fprintf(fp,
  393. "This library is free software; you can redistribute it and/or\n"
  394. "modify it under the terms of the GNU Library General Public\n"
  395. "License as published by the Free Software Foundation; either\n"
  396. "version 2 of the License, or (at your option) any later version.\n"
  397. "\n");
  398. fprintf(fp,
  399. "This library is distributed in the hope that it will be useful,\n"
  400. "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
  401. "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
  402. "Library General Public License for more details.\n"
  403. "\n");
  404. fprintf(fp,
  405. "You should have received a copy of the GNU Library General Public\n"
  406. "License along with this program. If not, see\n"
  407. "<http://www.gnu.org/licenses/>.\n");
  408. return 0;
  409. }
  410. /************************************************************************
  411. *
  412. * usage
  413. *
  414. * PURPOSE: Writes command line syntax to the file specified by fp
  415. *
  416. ************************************************************************/
  417. int
  418. usage(FILE * const fp, const char *ProgramName)
  419. { /* print general syntax */
  420. lame_version_print(fp);
  421. fprintf(fp,
  422. "usage: %s [options] <infile> [outfile]\n"
  423. "\n"
  424. " <infile> and/or <outfile> can be \"-\", which means stdin/stdout.\n"
  425. "\n"
  426. "Try:\n"
  427. " \"%s --help\" for general usage information\n"
  428. " or:\n"
  429. " \"%s --preset help\" for information on suggested predefined settings\n"
  430. " or:\n"
  431. " \"%s --longhelp\"\n"
  432. " or \"%s -?\" for a complete options list\n\n",
  433. ProgramName, ProgramName, ProgramName, ProgramName, ProgramName);
  434. return 0;
  435. }
  436. /************************************************************************
  437. *
  438. * usage
  439. *
  440. * PURPOSE: Writes command line syntax to the file specified by fp
  441. * but only the most important ones, to fit on a vt100 terminal
  442. *
  443. ************************************************************************/
  444. int
  445. short_help(const lame_global_flags * gfp, FILE * const fp, const char *ProgramName)
  446. { /* print short syntax help */
  447. lame_version_print(fp);
  448. fprintf(fp,
  449. "usage: %s [options] <infile> [outfile]\n"
  450. "\n"
  451. " <infile> and/or <outfile> can be \"-\", which means stdin/stdout.\n"
  452. "\n" "RECOMMENDED:\n" " lame -V2 input.wav output.mp3\n" "\n", ProgramName);
  453. fprintf(fp,
  454. "OPTIONS:\n"
  455. " -b bitrate set the bitrate, default 128 kbps\n"
  456. " -h higher quality, but a little slower.\n"
  457. " -f fast mode (lower quality)\n"
  458. " -V n quality setting for VBR. default n=%i\n"
  459. " 0=high quality,bigger files. 9.999=smaller files\n",
  460. lame_get_VBR_q(gfp));
  461. fprintf(fp,
  462. " --preset type type must be \"medium\", \"standard\", \"extreme\", \"insane\",\n"
  463. " or a value for an average desired bitrate and depending\n"
  464. " on the value specified, appropriate quality settings will\n"
  465. " be used.\n"
  466. " \"--preset help\" gives more info on these\n" "\n");
  467. fprintf(fp,
  468. #if defined(WIN32)
  469. " --priority type sets the process priority\n"
  470. " 0,1 = Low priority\n"
  471. " 2 = normal priority\n"
  472. " 3,4 = High priority\n" "\n"
  473. #endif
  474. #if defined(__OS2__)
  475. " --priority type sets the process priority\n"
  476. " 0 = Low priority\n"
  477. " 1 = Medium priority\n"
  478. " 2 = Regular priority\n"
  479. " 3 = High priority\n"
  480. " 4 = Maximum priority\n" "\n"
  481. #endif
  482. " --help id3 ID3 tagging related options\n" "\n"
  483. DEV_HELP(
  484. " --help dev developer options\n" "\n"
  485. )
  486. " --longhelp full list of options\n" "\n"
  487. " --license print License information\n\n"
  488. );
  489. return 0;
  490. }
  491. /************************************************************************
  492. *
  493. * usage
  494. *
  495. * PURPOSE: Writes command line syntax to the file specified by fp
  496. *
  497. ************************************************************************/
  498. static void
  499. wait_for(FILE * const fp, int lessmode)
  500. {
  501. if (lessmode) {
  502. fflush(fp);
  503. getchar();
  504. }
  505. else {
  506. fprintf(fp, "\n");
  507. }
  508. fprintf(fp, "\n");
  509. }
  510. static void
  511. help_id3tag(FILE * const fp)
  512. {
  513. fprintf(fp,
  514. " ID3 tag options:\n"
  515. " --tt <title> audio/song title (max 30 chars for version 1 tag)\n"
  516. " --ta <artist> audio/song artist (max 30 chars for version 1 tag)\n"
  517. " --tl <album> audio/song album (max 30 chars for version 1 tag)\n"
  518. " --ty <year> audio/song year of issue (1 to 9999)\n"
  519. " --tc <comment> user-defined text (max 30 chars for v1 tag, 28 for v1.1)\n");
  520. fprintf(fp,
  521. " --tn <track[/total]> audio/song track number and (optionally) the total\n"
  522. " number of tracks on the original recording. (track\n"
  523. " and total each 1 to 255. just the track number\n"
  524. " creates v1.1 tag, providing a total forces v2.0).\n");
  525. fprintf(fp,
  526. " --tg <genre> audio/song genre (name or number in list)\n"
  527. " --ti <file> audio/song albumArt (jpeg/png/gif file, v2.3 tag)\n"
  528. " --tv <id=value> user-defined frame specified by id and value (v2.3 tag)\n"
  529. " syntax: --tv \"TXXX=description=content\"\n"
  530. );
  531. fprintf(fp,
  532. " --add-id3v2 force addition of version 2 tag\n"
  533. " --id3v1-only add only a version 1 tag\n"
  534. " --id3v2-only add only a version 2 tag\n"
  535. #ifdef ID3TAGS_EXTENDED
  536. " --id3v2-utf16 add following options in unicode text encoding\n"
  537. " --id3v2-latin1 add following options in latin-1 text encoding\n"
  538. #endif
  539. " --space-id3v1 pad version 1 tag with spaces instead of nulls\n"
  540. " --pad-id3v2 same as '--pad-id3v2-size 128'\n"
  541. " --pad-id3v2-size <value> adds version 2 tag, pad with extra <value> bytes\n"
  542. " --genre-list print alphabetically sorted ID3 genre list and exit\n"
  543. " --ignore-tag-errors ignore errors in values passed for tags\n" "\n"
  544. );
  545. fprintf(fp,
  546. " Note: A version 2 tag will NOT be added unless one of the input fields\n"
  547. " won't fit in a version 1 tag (e.g. the title string is longer than 30\n"
  548. " characters), or the '--add-id3v2' or '--id3v2-only' options are used,\n"
  549. " or output is redirected to stdout.\n"
  550. );
  551. }
  552. static void
  553. help_developer_switches(FILE * const fp)
  554. {
  555. if ( !internal_opts_enabled ) {
  556. fprintf(fp,
  557. " Note: Almost all of the following switches aren't available in this build!\n\n"
  558. );
  559. }
  560. fprintf(fp,
  561. " ATH related:\n"
  562. " --noath turns ATH down to a flat noise floor\n"
  563. " --athshort ignore GPSYCHO for short blocks, use ATH only\n"
  564. " --athonly ignore GPSYCHO completely, use ATH only\n"
  565. " --athtype n selects between different ATH types [0-4]\n"
  566. " --athlower x lowers ATH by x dB\n"
  567. );
  568. fprintf(fp,
  569. " --athaa-type n ATH auto adjust: 0 'no' else 'loudness based'\n"
  570. /** OBSOLETE " --athaa-loudapprox n n=1 total energy or n=2 equal loudness curve\n"*/
  571. " --athaa-sensitivity x activation offset in -/+ dB for ATH auto-adjustment\n"
  572. "\n");
  573. fprintf(fp,
  574. " PSY related:\n"
  575. " --short use short blocks when appropriate\n"
  576. " --noshort do not use short blocks\n"
  577. " --allshort use only short blocks\n"
  578. );
  579. fprintf(fp,
  580. "(1) --temporal-masking x x=0 disables, x=1 enables temporal masking effect\n"
  581. " --nssafejoint M/S switching criterion\n"
  582. " --nsmsfix <arg> M/S switching tuning [effective 0-3.5]\n"
  583. "(2) --interch x adjust inter-channel masking ratio\n"
  584. " --ns-bass x adjust masking for sfbs 0 - 6 (long) 0 - 5 (short)\n"
  585. " --ns-alto x adjust masking for sfbs 7 - 13 (long) 6 - 10 (short)\n"
  586. " --ns-treble x adjust masking for sfbs 14 - 21 (long) 11 - 12 (short)\n"
  587. );
  588. fprintf(fp,
  589. " --ns-sfb21 x change ns-treble by x dB for sfb21\n"
  590. " --shortthreshold x,y short block switching threshold,\n"
  591. " x for L/R/M channel, y for S channel\n"
  592. " -Z [n] always do calculate short block maskings\n");
  593. fprintf(fp,
  594. " Noise Shaping related:\n"
  595. "(1) --substep n use pseudo substep noise shaping method types 0-2\n"
  596. "(1) -X n[,m] selects between different noise measurements\n"
  597. " n for long block, m for short. if m is omitted, m = n\n"
  598. " 1: CBR, ABR and VBR-old encoding modes only\n"
  599. " 2: ignored\n"
  600. );
  601. }
  602. int
  603. long_help(const lame_global_flags * gfp, FILE * const fp, const char *ProgramName, int lessmode)
  604. { /* print long syntax help */
  605. lame_version_print(fp);
  606. fprintf(fp,
  607. "usage: %s [options] <infile> [outfile]\n"
  608. "\n"
  609. " <infile> and/or <outfile> can be \"-\", which means stdin/stdout.\n"
  610. "\n" "RECOMMENDED:\n" " lame -V2 input.wav output.mp3\n" "\n", ProgramName);
  611. fprintf(fp,
  612. "OPTIONS:\n"
  613. " Input options:\n"
  614. " --scale <arg> scale input (multiply PCM data) by <arg>\n"
  615. " --scale-l <arg> scale channel 0 (left) input (multiply PCM data) by <arg>\n"
  616. " --scale-r <arg> scale channel 1 (right) input (multiply PCM data) by <arg>\n"
  617. " --swap-channel swap L/R channels\n"
  618. " --ignorelength ignore file length in WAV header\n"
  619. " --gain <arg> apply Gain adjustment in decibels, range -20.0 to +12.0\n"
  620. );
  621. #if (defined HAVE_MPGLIB || defined AMIGA_MPEGA)
  622. fprintf(fp,
  623. " --mp1input input file is a MPEG Layer I file\n"
  624. " --mp2input input file is a MPEG Layer II file\n"
  625. " --mp3input input file is a MPEG Layer III file\n"
  626. );
  627. #endif
  628. fprintf(fp,
  629. " --nogap <file1> <file2> <...>\n"
  630. " gapless encoding for a set of contiguous files\n"
  631. " --nogapout <dir>\n"
  632. " output dir for gapless encoding (must precede --nogap)\n"
  633. " --nogaptags allow the use of VBR tags in gapless encoding\n"
  634. " --out-dir <dir> output dir, must exist\n"
  635. );
  636. fprintf(fp,
  637. "\n"
  638. " Input options for RAW PCM:\n"
  639. " -r input is raw pcm\n"
  640. " -s sfreq sampling frequency of input file (kHz) - default 44.1 kHz\n"
  641. " --signed input is signed (default)\n"
  642. " --unsigned input is unsigned\n"
  643. " --bitwidth w input bit width is w (default 16)\n"
  644. " -x force byte-swapping of input\n"
  645. " --little-endian input is little-endian (default)\n"
  646. " --big-endian input is big-endian\n"
  647. " -a downmix from stereo to mono file for mono encoding\n"
  648. );
  649. wait_for(fp, lessmode);
  650. fprintf(fp,
  651. " Operational options:\n"
  652. " -m <mode> (j)oint, (s)imple, (f)orce, (d)ual-mono, (m)ono (l)eft (r)ight\n"
  653. " default is (j)\n"
  654. " joint = Uses the best possible of MS and LR stereo\n"
  655. " simple = force LR stereo on all frames\n"
  656. " force = force MS stereo on all frames.\n"
  657. );
  658. fprintf(fp,
  659. " --preset type type must be \"medium\", \"standard\", \"extreme\", \"insane\",\n"
  660. " or a value for an average desired bitrate and depending\n"
  661. " on the value specified, appropriate quality settings will\n"
  662. " be used.\n"
  663. " \"--preset help\" gives more info on these\n"
  664. " --comp <arg> choose bitrate to achieve a compression ratio of <arg>\n");
  665. fprintf(fp, " --replaygain-fast compute RG fast but slightly inaccurately (default)\n"
  666. #ifdef DECODE_ON_THE_FLY
  667. " --replaygain-accurate compute RG more accurately and find the peak sample\n"
  668. #endif
  669. " --noreplaygain disable ReplayGain analysis\n"
  670. #ifdef DECODE_ON_THE_FLY
  671. " --clipdetect enable --replaygain-accurate and print a message whether\n"
  672. " clipping occurs and how far the waveform is from full scale\n"
  673. #endif
  674. );
  675. fprintf(fp,
  676. " --flush flush output stream as soon as possible\n"
  677. " --freeformat produce a free format bitstream\n"
  678. " --decode input=mp3 file, output=wav\n"
  679. " -t disable writing wav header when using --decode\n");
  680. wait_for(fp, lessmode);
  681. fprintf(fp,
  682. " Verbosity:\n"
  683. " --disptime <arg>print progress report every arg seconds\n"
  684. " -S don't print progress report, VBR histograms\n"
  685. " --nohist disable VBR histogram display\n"
  686. " --quiet don't print anything on screen\n"
  687. " --silent don't print anything on screen, but fatal errors\n"
  688. " --brief print more useful information\n"
  689. " --verbose print a lot of useful information\n" "\n");
  690. fprintf(fp,
  691. " Noise shaping & psycho acoustic algorithms:\n"
  692. " -q <arg> <arg> = 0...9. Default -q 3 \n"
  693. " -q 0: Highest quality, very slow \n"
  694. " -q 9: Poor quality, but fast \n"
  695. " -h Same as -q 2. \n"
  696. " -f Same as -q 7. Fast, ok quality\n");
  697. wait_for(fp, lessmode);
  698. fprintf(fp,
  699. " CBR (constant bitrate, the default) options:\n"
  700. " -b <bitrate> set the bitrate in kbps, default 128 kbps\n"
  701. " --cbr enforce use of constant bitrate\n"
  702. "\n"
  703. " ABR options:\n"
  704. " --abr <bitrate> specify average bitrate desired (instead of quality)\n" "\n");
  705. fprintf(fp,
  706. " VBR options:\n"
  707. " -V n quality setting for VBR. default n=%i\n"
  708. " 0=high quality,bigger files. 9=smaller files\n"
  709. " -v the same as -V 4\n"
  710. " --vbr-old use old variable bitrate (VBR) routine\n"
  711. " --vbr-new use new variable bitrate (VBR) routine (default)\n"
  712. " -Y lets LAME ignore noise in sfb21, like in CBR\n"
  713. " (Default for V3 to V9.999)\n"
  714. ,
  715. lame_get_VBR_q(gfp));
  716. fprintf(fp,
  717. " -b <bitrate> specify minimum allowed bitrate, default 32 kbps\n"
  718. " -B <bitrate> specify maximum allowed bitrate, default 320 kbps\n"
  719. " -F strictly enforce the -b option, for use with players that\n"
  720. " do not support low bitrate mp3\n"
  721. " -t disable writing LAME Tag\n"
  722. " -T enable and force writing LAME Tag\n");
  723. wait_for(fp, lessmode);
  724. DEV_HELP(
  725. help_developer_switches(fp);
  726. wait_for(fp, lessmode);
  727. )
  728. fprintf(fp,
  729. " MP3 header/stream options:\n"
  730. " -e <emp> de-emphasis n/5/c (obsolete)\n"
  731. " -c mark as copyright\n"
  732. " -o mark as non-original\n"
  733. " -p error protection. adds 16 bit checksum to every frame\n"
  734. " (the checksum is computed correctly)\n"
  735. " --nores disable the bit reservoir\n"
  736. " --strictly-enforce-ISO comply as much as possible to ISO MPEG spec\n");
  737. fprintf(fp,
  738. " --buffer-constraint <constraint> available values for constraint:\n"
  739. " default, strict, maximum\n"
  740. "\n"
  741. );
  742. fprintf(fp,
  743. " Filter options:\n"
  744. " --lowpass <freq> frequency(kHz), lowpass filter cutoff above freq\n"
  745. " --lowpass-width <freq> frequency(kHz) - default 15%% of lowpass freq\n"
  746. " --highpass <freq> frequency(kHz), highpass filter cutoff below freq\n"
  747. " --highpass-width <freq> frequency(kHz) - default 15%% of highpass freq\n");
  748. fprintf(fp,
  749. " --resample <sfreq> sampling frequency of output file(kHz)- default=automatic\n");
  750. wait_for(fp, lessmode);
  751. help_id3tag(fp);
  752. fprintf(fp,
  753. #if defined(WIN32)
  754. "\n\nMS-Windows-specific options:\n"
  755. " --priority <type> sets the process priority:\n"
  756. " 0,1 = Low priority (IDLE_PRIORITY_CLASS)\n"
  757. " 2 = normal priority (NORMAL_PRIORITY_CLASS, default)\n"
  758. " 3,4 = High priority (HIGH_PRIORITY_CLASS))\n"
  759. " Note: Calling '--priority' without a parameter will select priority 0.\n"
  760. #endif
  761. #if defined(__OS2__)
  762. "\n\nOS/2-specific options:\n"
  763. " --priority <type> sets the process priority:\n"
  764. " 0 = Low priority (IDLE, delta = 0)\n"
  765. " 1 = Medium priority (IDLE, delta = +31)\n"
  766. " 2 = Regular priority (REGULAR, delta = -31)\n"
  767. " 3 = High priority (REGULAR, delta = 0)\n"
  768. " 4 = Maximum priority (REGULAR, delta = +31)\n"
  769. " Note: Calling '--priority' without a parameter will select priority 0.\n"
  770. #endif
  771. "\nMisc:\n --license print License information\n\n"
  772. );
  773. #if defined(HAVE_NASM)
  774. wait_for(fp, lessmode);
  775. fprintf(fp,
  776. " Platform specific:\n"
  777. " --noasm <instructions> disable assembly optimizations for mmx/3dnow/sse\n");
  778. wait_for(fp, lessmode);
  779. #endif
  780. display_bitrates(fp);
  781. return 0;
  782. }
  783. static void
  784. display_bitrate(FILE * const fp, const char *const version, const int d, const int indx)
  785. {
  786. int i;
  787. int nBitrates = 14;
  788. if (d == 4)
  789. nBitrates = 8;
  790. fprintf(fp,
  791. "\nMPEG-%-3s layer III sample frequencies (kHz): %2d %2d %g\n"
  792. "bitrates (kbps):", version, 32 / d, 48 / d, 44.1 / d);
  793. for (i = 1; i <= nBitrates; i++)
  794. fprintf(fp, " %2i", lame_get_bitrate(indx, i));
  795. fprintf(fp, "\n");
  796. }
  797. int
  798. display_bitrates(FILE * const fp)
  799. {
  800. display_bitrate(fp, "1", 1, 1);
  801. display_bitrate(fp, "2", 2, 0);
  802. display_bitrate(fp, "2.5", 4, 0);
  803. fprintf(fp, "\n");
  804. fflush(fp);
  805. return 0;
  806. }
  807. /* note: for presets it would be better to externalize them in a file.
  808. suggestion: lame --preset <file-name> ...
  809. or: lame --preset my-setting ... and my-setting is defined in lame.ini
  810. */
  811. /*
  812. Note from GB on 08/25/2002:
  813. I am merging --presets and --alt-presets. Old presets are now aliases for
  814. corresponding abr values from old alt-presets. This way we now have a
  815. unified preset system, and I hope than more people will use the new tuned
  816. presets instead of the old unmaintained ones.
  817. */
  818. /************************************************************************
  819. *
  820. * usage
  821. *
  822. * PURPOSE: Writes presetting info to #stdout#
  823. *
  824. ************************************************************************/
  825. static void
  826. presets_longinfo_dm(FILE * msgfp)
  827. {
  828. fprintf(msgfp,
  829. "\n"
  830. "The --preset switches are aliases over LAME settings.\n"
  831. "\n" "\n");
  832. fprintf(msgfp,
  833. "To activate these presets:\n"
  834. "\n" " For VBR modes (generally highest quality):\n" "\n");
  835. fprintf(msgfp,
  836. " --preset medium This preset should provide near transparency to most\n"
  837. " people on most music.\n"
  838. "\n"
  839. " --preset standard This preset should generally be transparent to most\n"
  840. " people on most music and is already quite high\n"
  841. " in quality.\n" "\n");
  842. fprintf(msgfp,
  843. " --preset extreme If you have extremely good hearing and similar\n"
  844. " equipment, this preset will generally provide\n"
  845. " slightly higher quality than the \"standard\" mode.\n" "\n");
  846. fprintf(msgfp,
  847. " For CBR 320kbps (highest quality possible from the --preset switches):\n"
  848. "\n"
  849. " --preset insane This preset will usually be overkill for most people\n"
  850. " and most situations, but if you must have the\n"
  851. " absolute highest quality with no regard to filesize,\n"
  852. " this is the way to go.\n" "\n");
  853. fprintf(msgfp,
  854. " For ABR modes (high quality per given bitrate but not as high as VBR):\n"
  855. "\n"
  856. " --preset <kbps> Using this preset will usually give you good quality\n"
  857. " at a specified bitrate. Depending on the bitrate\n"
  858. " entered, this preset will determine the optimal\n"
  859. " settings for that particular situation. For example:\n"
  860. " \"--preset 185\" activates this preset and uses 185\n"
  861. " as an average kbps.\n" "\n");
  862. fprintf(msgfp,
  863. " \"cbr\" - If you use the ABR mode (read above) with a significant\n"
  864. " bitrate such as 80, 96, 112, 128, 160, 192, 224, 256, 320,\n"
  865. " you can use the \"cbr\" option to force CBR mode encoding\n"
  866. " instead of the standard abr mode. ABR does provide higher\n"
  867. " quality but CBR may be useful in situations such as when\n"
  868. " streaming an mp3 over the internet may be important.\n" "\n");
  869. fprintf(msgfp,
  870. " For example:\n"
  871. "\n"
  872. " --preset standard <input file> <output file>\n"
  873. " or --preset cbr 192 <input file> <output file>\n"
  874. " or --preset 172 <input file> <output file>\n"
  875. " or --preset extreme <input file> <output file>\n" "\n" "\n");
  876. fprintf(msgfp,
  877. "A few aliases are also available for ABR mode:\n"
  878. "phone => 16kbps/mono phon+/lw/mw-eu/sw => 24kbps/mono\n"
  879. "mw-us => 40kbps/mono voice => 56kbps/mono\n"
  880. "fm/radio/tape => 112kbps hifi => 160kbps\n"
  881. "cd => 192kbps studio => 256kbps\n");
  882. }
  883. static int
  884. presets_set(lame_t gfp, int fast, int cbr, const char *preset_name, const char *ProgramName)
  885. {
  886. int mono = 0;
  887. if ((strcmp(preset_name, "help") == 0) && (fast < 1)
  888. && (cbr < 1)) {
  889. lame_version_print(stdout);
  890. presets_longinfo_dm(stdout);
  891. return -1;
  892. }
  893. /*aliases for compatibility with old presets */
  894. if (strcmp(preset_name, "phone") == 0) {
  895. preset_name = "16";
  896. mono = 1;
  897. }
  898. if ((strcmp(preset_name, "phon+") == 0) ||
  899. (strcmp(preset_name, "lw") == 0) ||
  900. (strcmp(preset_name, "mw-eu") == 0) || (strcmp(preset_name, "sw") == 0)) {
  901. preset_name = "24";
  902. mono = 1;
  903. }
  904. if (strcmp(preset_name, "mw-us") == 0) {
  905. preset_name = "40";
  906. mono = 1;
  907. }
  908. if (strcmp(preset_name, "voice") == 0) {
  909. preset_name = "56";
  910. mono = 1;
  911. }
  912. if (strcmp(preset_name, "fm") == 0) {
  913. preset_name = "112";
  914. }
  915. if ((strcmp(preset_name, "radio") == 0) || (strcmp(preset_name, "tape") == 0)) {
  916. preset_name = "112";
  917. }
  918. if (strcmp(preset_name, "hifi") == 0) {
  919. preset_name = "160";
  920. }
  921. if (strcmp(preset_name, "cd") == 0) {
  922. preset_name = "192";
  923. }
  924. if (strcmp(preset_name, "studio") == 0) {
  925. preset_name = "256";
  926. }
  927. if (strcmp(preset_name, "medium") == 0) {
  928. lame_set_VBR_q(gfp, 4);
  929. lame_set_VBR(gfp, vbr_default);
  930. return 0;
  931. }
  932. if (strcmp(preset_name, "standard") == 0) {
  933. lame_set_VBR_q(gfp, 2);
  934. lame_set_VBR(gfp, vbr_default);
  935. return 0;
  936. }
  937. else if (strcmp(preset_name, "extreme") == 0) {
  938. lame_set_VBR_q(gfp, 0);
  939. lame_set_VBR(gfp, vbr_default);
  940. return 0;
  941. }
  942. else if ((strcmp(preset_name, "insane") == 0) && (fast < 1)) {
  943. lame_set_preset(gfp, INSANE);
  944. return 0;
  945. }
  946. /* Generic ABR Preset */
  947. if (((atoi(preset_name)) > 0) && (fast < 1)) {
  948. if ((atoi(preset_name)) >= 8 && (atoi(preset_name)) <= 320) {
  949. lame_set_preset(gfp, atoi(preset_name));
  950. if (cbr == 1)
  951. lame_set_VBR(gfp, vbr_off);
  952. if (mono == 1) {
  953. lame_set_mode(gfp, MONO);
  954. }
  955. return 0;
  956. }
  957. else {
  958. lame_version_print(Console_IO.Error_fp);
  959. error_printf("Error: The bitrate specified is out of the valid range for this preset\n"
  960. "\n"
  961. "When using this mode you must enter a value between \"32\" and \"320\"\n"
  962. "\n" "For further information try: \"%s --preset help\"\n", ProgramName);
  963. return -1;
  964. }
  965. }
  966. lame_version_print(Console_IO.Error_fp);
  967. error_printf("Error: You did not enter a valid profile and/or options with --preset\n"
  968. "\n"
  969. "Available profiles are:\n"
  970. "\n"
  971. " medium\n"
  972. " standard\n"
  973. " extreme\n"
  974. " insane\n"
  975. " <cbr> (ABR Mode) - The ABR Mode is implied. To use it,\n"
  976. " simply specify a bitrate. For example:\n"
  977. " \"--preset 185\" activates this\n"
  978. " preset and uses 185 as an average kbps.\n" "\n");
  979. error_printf(" Some examples:\n"
  980. "\n"
  981. " or \"%s --preset standard <input file> <output file>\"\n"
  982. " or \"%s --preset cbr 192 <input file> <output file>\"\n"
  983. " or \"%s --preset 172 <input file> <output file>\"\n"
  984. " or \"%s --preset extreme <input file> <output file>\"\n"
  985. "\n"
  986. "For further information try: \"%s --preset help\"\n", ProgramName, ProgramName,
  987. ProgramName, ProgramName, ProgramName);
  988. return -1;
  989. }
  990. static void
  991. genre_list_handler(int num, const char *name, void *cookie)
  992. {
  993. (void) cookie;
  994. console_printf("%3d %s\n", num, name);
  995. }
  996. /************************************************************************
  997. *
  998. * parse_args
  999. *
  1000. * PURPOSE: Sets encoding parameters to the specifications of the
  1001. * command line. Default settings are used for parameters
  1002. * not specified in the command line.
  1003. *
  1004. * If the input file is in WAVE or AIFF format, the sampling frequency is read
  1005. * from the AIFF header.
  1006. *
  1007. * The input and output filenames are read into #inpath# and #outpath#.
  1008. *
  1009. ************************************************************************/
  1010. /* would use real "strcasecmp" but it isn't portable */
  1011. static int
  1012. local_strcasecmp(const char *s1, const char *s2)
  1013. {
  1014. unsigned char c1;
  1015. unsigned char c2;
  1016. do {
  1017. c1 = (unsigned char) tolower(*s1);
  1018. c2 = (unsigned char) tolower(*s2);
  1019. if (!c1) {
  1020. break;
  1021. }
  1022. ++s1;
  1023. ++s2;
  1024. } while (c1 == c2);
  1025. return c1 - c2;
  1026. }
  1027. static int
  1028. local_strncasecmp(const char *s1, const char *s2, int n)
  1029. {
  1030. unsigned char c1 = 0;
  1031. unsigned char c2 = 0;
  1032. int cnt = 0;
  1033. do {
  1034. if (cnt == n) {
  1035. break;
  1036. }
  1037. c1 = (unsigned char) tolower(*s1);
  1038. c2 = (unsigned char) tolower(*s2);
  1039. if (!c1) {
  1040. break;
  1041. }
  1042. ++s1;
  1043. ++s2;
  1044. ++cnt;
  1045. } while (c1 == c2);
  1046. return c1 - c2;
  1047. }
  1048. /* LAME is a simple frontend which just uses the file extension */
  1049. /* to determine the file type. Trying to analyze the file */
  1050. /* contents is well beyond the scope of LAME and should not be added. */
  1051. static int
  1052. filename_to_type(const char *FileName)
  1053. {
  1054. size_t len = strlen(FileName);
  1055. if (len < 4)
  1056. return sf_unknown;
  1057. FileName += len - 4;
  1058. if (0 == local_strcasecmp(FileName, ".mpg"))
  1059. return sf_mp123;
  1060. if (0 == local_strcasecmp(FileName, ".mp1"))
  1061. return sf_mp123;
  1062. if (0 == local_strcasecmp(FileName, ".mp2"))
  1063. return sf_mp123;
  1064. if (0 == local_strcasecmp(FileName, ".mp3"))
  1065. return sf_mp123;
  1066. if (0 == local_strcasecmp(FileName, ".wav"))
  1067. return sf_wave;
  1068. if (0 == local_strcasecmp(FileName, ".aif"))
  1069. return sf_aiff;
  1070. if (0 == local_strcasecmp(FileName, ".raw"))
  1071. return sf_raw;
  1072. if (0 == local_strcasecmp(FileName, ".ogg"))
  1073. return sf_ogg;
  1074. return sf_unknown;
  1075. }
  1076. static int
  1077. resample_rate(double freq)
  1078. {
  1079. if (freq >= 1.e3)
  1080. freq *= 1.e-3;
  1081. switch ((int) freq) {
  1082. case 8:
  1083. return 8000;
  1084. case 11:
  1085. return 11025;
  1086. case 12:
  1087. return 12000;
  1088. case 16:
  1089. return 16000;
  1090. case 22:
  1091. return 22050;
  1092. case 24:
  1093. return 24000;
  1094. case 32:
  1095. return 32000;
  1096. case 44:
  1097. return 44100;
  1098. case 48:
  1099. return 48000;
  1100. default:
  1101. error_printf("Illegal resample frequency: %.3f kHz\n", freq);
  1102. return 0;
  1103. }
  1104. }
  1105. #ifdef _WIN32
  1106. #define SLASH '\\'
  1107. #define COLON ':'
  1108. #elif __OS2__
  1109. #define SLASH '\\'
  1110. #else
  1111. #define SLASH '/'
  1112. #endif
  1113. static
  1114. size_t scanPath(char const* s, char const** a, char const** b)
  1115. {
  1116. char const* s1 = s;
  1117. char const* s2 = s;
  1118. if (s != 0) {
  1119. for (; *s; ++s) {
  1120. switch (*s) {
  1121. case SLASH:
  1122. #ifdef _WIN32
  1123. case COLON:
  1124. #endif
  1125. s2 = s;
  1126. break;
  1127. }
  1128. }
  1129. #ifdef _WIN32
  1130. if (*s2 == COLON) {
  1131. ++s2;
  1132. }
  1133. #endif
  1134. }
  1135. if (a) {
  1136. *a = s1;
  1137. }
  1138. if (b) {
  1139. *b = s2;
  1140. }
  1141. return s2-s1;
  1142. }
  1143. static
  1144. size_t scanBasename(char const* s, char const** a, char const** b)
  1145. {
  1146. char const* s1 = s;
  1147. char const* s2 = s;
  1148. if (s != 0) {
  1149. for (; *s; ++s) {
  1150. switch (*s) {
  1151. case SLASH:
  1152. #ifdef _WIN32
  1153. case COLON:
  1154. #endif
  1155. s1 = s2 = s;
  1156. break;
  1157. case '.':
  1158. s2 = s;
  1159. break;
  1160. }
  1161. }
  1162. if (s2 == s1) {
  1163. s2 = s;
  1164. }
  1165. if (*s1 == SLASH
  1166. #ifdef _WIN32
  1167. || *s1 == COLON
  1168. #endif
  1169. ) {
  1170. ++s1;
  1171. }
  1172. }
  1173. if (a != 0) {
  1174. *a = s1;
  1175. }
  1176. if (b != 0) {
  1177. *b = s2;
  1178. }
  1179. return s2-s1;
  1180. }
  1181. static
  1182. int isCommonSuffix(char const* s_ext)
  1183. {
  1184. char const* suffixes[] =
  1185. { ".WAV", ".RAW", ".MP1", ".MP2"
  1186. , ".MP3", ".MPG", ".MPA", ".CDA"
  1187. , ".OGG", ".AIF", ".AIFF", ".AU"
  1188. , ".SND", ".FLAC", ".WV", ".OFR"
  1189. , ".TAK", ".MP4", ".M4A", ".PCM"
  1190. , ".W64"
  1191. };
  1192. size_t i;
  1193. for (i = 0; i < dimension_of(suffixes); ++i) {
  1194. if (local_strcasecmp(s_ext, suffixes[i]) == 0) {
  1195. return 1;
  1196. }
  1197. }
  1198. return 0;
  1199. }
  1200. int generateOutPath(char const* inPath, char const* outDir, char const* s_ext, char* outPath)
  1201. {
  1202. size_t const max_path = PATH_MAX;
  1203. #if 1
  1204. size_t i = 0;
  1205. int out_dir_used = 0;
  1206. if (outDir != 0 && outDir[0] != 0) {
  1207. out_dir_used = 1;
  1208. while (*outDir) {
  1209. outPath[i++] = *outDir++;
  1210. if (i >= max_path) {
  1211. goto err_generateOutPath;
  1212. }
  1213. }
  1214. if (i > 0 && outPath[i-1] != SLASH) {
  1215. outPath[i++] = SLASH;
  1216. if (i >= max_path) {
  1217. goto err_generateOutPath;
  1218. }
  1219. }
  1220. outPath[i] = 0;
  1221. }
  1222. else {
  1223. char const* pa;
  1224. char const* pb;
  1225. size_t j, n = scanPath(inPath, &pa, &pb);
  1226. if (i+n >= max_path) {
  1227. goto err_generateOutPath;
  1228. }
  1229. for (j = 0; j < n; ++j) {
  1230. outPath[i++] = pa[j];
  1231. }
  1232. if (n > 0) {
  1233. outPath[i++] = SLASH;
  1234. if (i >= max_path) {
  1235. goto err_generateOutPath;
  1236. }
  1237. }
  1238. outPath[i] = 0;
  1239. }
  1240. {
  1241. int replace_suffix = 0;
  1242. char const* na;
  1243. char const* nb;
  1244. size_t j, n = scanBasename(inPath, &na, &nb);
  1245. if (i+n >= max_path) {
  1246. goto err_generateOutPath;
  1247. }
  1248. for (j = 0; j < n; ++j) {
  1249. outPath[i++] = na[j];
  1250. }
  1251. outPath[i] = 0;
  1252. if (isCommonSuffix(nb) == 1) {
  1253. replace_suffix = 1;
  1254. if (out_dir_used == 0) {
  1255. if (local_strcasecmp(nb, s_ext) == 0) {
  1256. replace_suffix = 0;
  1257. }
  1258. }
  1259. }
  1260. if (replace_suffix == 0) {
  1261. while (*nb) {
  1262. outPath[i++] = *nb++;
  1263. if (i >= max_path) {
  1264. goto err_generateOutPath;
  1265. }
  1266. }
  1267. outPath[i] = 0;
  1268. }
  1269. }
  1270. if (i+5 >= max_path) {
  1271. goto err_generateOutPath;
  1272. }
  1273. while (*s_ext) {
  1274. outPath[i++] = *s_ext++;
  1275. }
  1276. outPath[i] = 0;
  1277. return 0;
  1278. err_generateOutPath:
  1279. error_printf( "error: output file name too long\n" );
  1280. return 1;
  1281. #else
  1282. strncpy(outPath, inPath, PATH_MAX + 1 - 4);
  1283. strncat(outPath, s_ext, 4);
  1284. return 0;
  1285. #endif
  1286. }
  1287. static int
  1288. set_id3_albumart(lame_t gfp, char const* file_name)
  1289. {
  1290. int ret = -1;
  1291. FILE *fpi = 0;
  1292. char *albumart = 0;
  1293. if (file_name == 0) {
  1294. return 0;
  1295. }
  1296. fpi = lame_fopen(file_name, "rb");
  1297. if (!fpi) {
  1298. ret = 1;
  1299. }
  1300. else {
  1301. size_t size;
  1302. fseek(fpi, 0, SEEK_END);
  1303. size = ftell(fpi);
  1304. fseek(fpi, 0, SEEK_SET);
  1305. albumart = (char *)malloc(size);
  1306. if (!albumart) {
  1307. ret = 2;
  1308. }
  1309. else {
  1310. if (fread(albumart, 1, size, fpi) != size) {
  1311. ret = 3;
  1312. }
  1313. else {
  1314. ret = id3tag_set_albumart(gfp, albumart, size) ? 4 : 0;
  1315. }
  1316. free(albumart);
  1317. }
  1318. fclose(fpi);
  1319. }
  1320. switch (ret) {
  1321. case 1: error_printf("Could not find: '%s'.\n", file_name); break;
  1322. case 2: error_printf("Insufficient memory for reading the albumart.\n"); break;
  1323. case 3: error_printf("Read error: '%s'.\n", file_name); break;
  1324. case 4: error_printf("Unsupported image: '%s'.\nSpecify JPEG/PNG/GIF image\n", file_name); break;
  1325. default: break;
  1326. }
  1327. return ret;
  1328. }
  1329. enum ID3TAG_MODE
  1330. { ID3TAG_MODE_DEFAULT
  1331. , ID3TAG_MODE_V1_ONLY
  1332. , ID3TAG_MODE_V2_ONLY
  1333. };
  1334. static int dev_only_with_arg(char const* str, char const* token, char const* nextArg, int* argIgnored, int* argUsed)
  1335. {
  1336. if (0 != local_strcasecmp(token,str)) return 0;
  1337. *argUsed = 1;
  1338. if (internal_opts_enabled) return 1;
  1339. *argIgnored = 1;
  1340. error_printf("WARNING: ignoring developer-only switch --%s %s\n", token, nextArg);
  1341. return 0;
  1342. }
  1343. static int dev_only_without_arg(char const* str, char const* token, int* argIgnored)
  1344. {
  1345. if (0 != local_strcasecmp(token,str)) return 0;
  1346. if (internal_opts_enabled) return 1;
  1347. *argIgnored = 1;
  1348. error_printf("WARNING: ignoring developer-only switch --%s\n", token);
  1349. return 0;
  1350. }
  1351. /* Ugly, NOT final version */
  1352. #define T_IF(str) if ( 0 == local_strcasecmp (token,str) ) {
  1353. #define T_ELIF(str) } else if ( 0 == local_strcasecmp (token,str) ) {
  1354. #define T_ELIF2(str1,str2) } else if ( 0 == local_strcasecmp (token,str1) || 0 == local_strcasecmp (token,str2) ) {
  1355. #define T_ELSE } else {
  1356. #define T_END }
  1357. #define T_ELIF_INTERNAL(str) \
  1358. } else if (dev_only_without_arg(str,token,&argIgnored)) {
  1359. #define T_ELIF_INTERNAL_WITH_ARG(str) \
  1360. } else if (dev_only_with_arg(str,token,nextArg,&argIgnored,&argUsed)) {
  1361. static int
  1362. parse_args_(lame_global_flags * gfp, int argc, char **argv,
  1363. char *const inPath, char *const outPath, char **nogap_inPath, int *num_nogap)
  1364. {
  1365. char outDir[PATH_MAX+1] = "";
  1366. int input_file = 0; /* set to 1 if we parse an input file name */
  1367. int i;
  1368. int autoconvert = 0;
  1369. int nogap = 0;
  1370. int nogap_tags = 0; /* set to 1 to use VBR tags in NOGAP mode */
  1371. const char *ProgramName = argv[0];
  1372. int count_nogap = 0;
  1373. int noreplaygain = 0; /* is RG explicitly disabled by the user */
  1374. int id3tag_mode = ID3TAG_MODE_DEFAULT;
  1375. int ignore_tag_errors = 0; /* Ignore errors in values passed for tags */
  1376. #ifdef ID3TAGS_EXTENDED
  1377. enum TextEncoding id3_tenc = TENC_UTF16;
  1378. #else
  1379. enum TextEncoding id3_tenc = TENC_LATIN1;
  1380. #endif
  1381. #ifdef HAVE_ICONV
  1382. setlocale(LC_CTYPE, "");
  1383. #endif
  1384. inPath[0] = '\0';
  1385. outPath[0] = '\0';
  1386. /* turn on display options. user settings may turn them off below */
  1387. global_ui_config.silent = 0; /* default */
  1388. global_ui_config.brhist = 1;
  1389. global_decoder.mp3_delay = 0;
  1390. global_decoder.mp3_delay_set = 0;
  1391. global_decoder.disable_wav_header = 0;
  1392. global_ui_config.print_clipping_info = 0;
  1393. id3tag_init(gfp);
  1394. /* process args */
  1395. for (i = 0; ++i < argc;) {
  1396. char c;
  1397. char *token;
  1398. char *arg;
  1399. char *nextArg;
  1400. int argUsed;
  1401. int argIgnored=0;
  1402. token = argv[i];
  1403. if (*token++ == '-') {
  1404. argUsed = 0;
  1405. nextArg = i + 1 < argc ? argv[i + 1] : "";
  1406. if (!*token) { /* The user wants to use stdin and/or stdout. */
  1407. input_file = 1;
  1408. if (inPath[0] == '\0')
  1409. strncpy(inPath, argv[i], PATH_MAX + 1);
  1410. else if (outPath[0] == '\0')
  1411. strncpy(outPath, argv[i], PATH_MAX + 1);
  1412. }
  1413. if (*token == '-') { /* GNU style */
  1414. double double_value = 0;
  1415. int int_value = 0;
  1416. token++;
  1417. T_IF("resample")
  1418. argUsed = getDoubleValue(token, nextArg, &double_value);
  1419. if (argUsed)
  1420. (void) lame_set_out_samplerate(gfp, resample_rate(double_value));
  1421. T_ELIF("vbr-old")
  1422. lame_set_VBR(gfp, vbr_rh);
  1423. T_ELIF("vbr-new")
  1424. lame_set_VBR(gfp, vbr_mt);
  1425. T_ELIF("vbr-mtrh")
  1426. lame_set_VBR(gfp, vbr_mtrh);
  1427. T_ELIF("cbr")
  1428. lame_set_VBR(gfp, vbr_off);
  1429. T_ELIF("abr")
  1430. /* values larger than 8000 are bps (like Fraunhofer), so it's strange to get 320000 bps MP3 when specifying 8000 bps MP3 */
  1431. argUsed = getIntValue(token, nextArg, &int_value);
  1432. if (argUsed) {
  1433. if (int_value >= 8000) {
  1434. int_value = (int_value + 500) / 1000;
  1435. }
  1436. if (int_value > 320) {
  1437. int_value = 320;
  1438. }
  1439. if (int_value < 8) {
  1440. int_value = 8;
  1441. }
  1442. lame_set_VBR(gfp, vbr_abr);
  1443. lame_set_VBR_mean_bitrate_kbps(gfp, int_value);
  1444. }
  1445. T_ELIF("r3mix")
  1446. lame_set_preset(gfp, R3MIX);
  1447. T_ELIF("bitwidth")
  1448. argUsed = getIntValue(token, nextArg, &int_value);
  1449. if (argUsed)
  1450. global_raw_pcm.in_bitwidth = int_value;
  1451. T_ELIF("signed")
  1452. global_raw_pcm.in_signed = 1;
  1453. T_ELIF("unsigned")
  1454. global_raw_pcm.in_signed = 0;
  1455. T_ELIF("little-endian")
  1456. global_raw_pcm.in_endian = ByteOrderLittleEndian;
  1457. T_ELIF("big-endian")
  1458. global_raw_pcm.in_endian = ByteOrderBigEndian;
  1459. T_ELIF("mp1input")
  1460. global_reader.input_format = sf_mp1;
  1461. T_ELIF("mp2input")
  1462. global_reader.input_format = sf_mp2;
  1463. T_ELIF("mp3input")
  1464. global_reader.input_format = sf_mp3;
  1465. T_ELIF("ogginput")
  1466. error_printf("sorry, vorbis support in LAME is deprecated.\n");
  1467. return -1;
  1468. T_ELIF("decode")
  1469. (void) lame_set_decode_only(gfp, 1);
  1470. T_ELIF("flush")
  1471. global_writer.flush_write = 1;
  1472. T_ELIF("decode-mp3delay")
  1473. argUsed = getIntValue(token, nextArg, &int_value);
  1474. if (argUsed) {
  1475. global_decoder.mp3_delay = int_value;
  1476. global_decoder.mp3_delay_set = 1;
  1477. }
  1478. T_ELIF("nores")
  1479. lame_set_disable_reservoir(gfp, 1);
  1480. T_ELIF("strictly-enforce-ISO")
  1481. lame_set_strict_ISO(gfp, MDB_STRICT_ISO);
  1482. T_ELIF("buffer-constraint")
  1483. argUsed = 1;
  1484. if (strcmp(nextArg, "default") == 0)
  1485. (void) lame_set_strict_ISO(gfp, MDB_DEFAULT);
  1486. else if (strcmp(nextArg, "strict") == 0)
  1487. (void) lame_set_strict_ISO(gfp, MDB_STRICT_ISO);
  1488. else if (strcmp(nextArg, "maximum") == 0)
  1489. (void) lame_set_strict_ISO(gfp, MDB_MAXIMUM);
  1490. else {
  1491. error_printf("unknown buffer constraint '%s'\n", nextArg);
  1492. return -1;
  1493. }
  1494. T_ELIF("scale")
  1495. argUsed = getDoubleValue(token, nextArg, &double_value);
  1496. if (argUsed)
  1497. (void) lame_set_scale(gfp, (float) double_value);
  1498. T_ELIF("scale-l")
  1499. argUsed = getDoubleValue(token, nextArg, &double_value);
  1500. if (argUsed)
  1501. (void) lame_set_scale_left(gfp, (float) double_value);
  1502. T_ELIF("scale-r")
  1503. argUsed = getDoubleValue(token, nextArg, &double_value);
  1504. if (argUsed)
  1505. (void) lame_set_scale_right(gfp, (float) double_value);
  1506. T_ELIF("gain")
  1507. argUsed = getDoubleValue(token, nextArg, &double_value);
  1508. if (argUsed) {
  1509. double gain = double_value;
  1510. gain = gain > -20.f ? gain : -20.f;
  1511. gain = gain < 12.f ? gain : 12.f;
  1512. gain = pow(10.f, gain*0.05);
  1513. (void) lame_set_scale(gfp, (float) gain);
  1514. }
  1515. T_ELIF("noasm")
  1516. argUsed = 1;
  1517. if (!strcmp(nextArg, "mmx"))
  1518. (void) lame_set_asm_optimizations(gfp, MMX, 0);
  1519. if (!strcmp(nextArg, "3dnow"))
  1520. (void) lame_set_asm_optimizations(gfp, AMD_3DNOW, 0);
  1521. if (!strcmp(nextArg, "sse"))
  1522. (void) lame_set_asm_optimizations(gfp, SSE, 0);
  1523. T_ELIF("freeformat")
  1524. lame_set_free_format(gfp, 1);
  1525. T_ELIF("replaygain-fast")
  1526. lame_set_findReplayGain(gfp, 1);
  1527. #ifdef DECODE_ON_THE_FLY
  1528. T_ELIF("replaygain-accurate")
  1529. lame_set_decode_on_the_fly(gfp, 1);
  1530. lame_set_findReplayGain(gfp, 1);
  1531. #endif
  1532. T_ELIF("noreplaygain")
  1533. noreplaygain = 1;
  1534. lame_set_findReplayGain(gfp, 0);
  1535. #ifdef DECODE_ON_THE_FLY
  1536. T_ELIF("clipdetect")
  1537. global_ui_config.print_clipping_info = 1;
  1538. lame_set_decode_on_the_fly(gfp, 1);
  1539. #endif
  1540. T_ELIF("nohist")
  1541. global_ui_config.brhist = 0;
  1542. #if defined(__OS2__) || defined(WIN32)
  1543. T_ELIF("priority")
  1544. argUsed = getIntValue(token, nextArg, &int_value);
  1545. if (argUsed)
  1546. setProcessPriority(int_value);
  1547. #endif
  1548. /* options for ID3 tag */
  1549. #ifdef ID3TAGS_EXTENDED
  1550. T_ELIF2("id3v2-utf16","id3v2-ucs2") /* id3v2-ucs2 for compatibility only */
  1551. id3_tenc = TENC_UTF16;
  1552. id3tag_add_v2(gfp);
  1553. T_ELIF("id3v2-latin1")
  1554. id3_tenc = TENC_LATIN1;
  1555. id3tag_add_v2(gfp);
  1556. #endif
  1557. T_ELIF("tt")
  1558. argUsed = 1;
  1559. id3_tag(gfp, 't', id3_tenc, nextArg);
  1560. T_ELIF("ta")
  1561. argUsed = 1;
  1562. id3_tag(gfp, 'a', id3_tenc, nextArg);
  1563. T_ELIF("tl")
  1564. argUsed = 1;
  1565. id3_tag(gfp, 'l', id3_tenc, nextArg);
  1566. T_ELIF("ty")
  1567. argUsed = 1;
  1568. id3_tag(gfp, 'y', id3_tenc, nextArg);
  1569. T_ELIF("tc")
  1570. argUsed = 1;
  1571. id3_tag(gfp, 'c', id3_tenc, nextArg);
  1572. T_ELIF("tn")
  1573. int ret = id3_tag(gfp, 'n', id3_tenc, nextArg);
  1574. argUsed = 1;
  1575. if (ret != 0) {
  1576. if (0 == ignore_tag_errors) {
  1577. if (id3tag_mode == ID3TAG_MODE_V1_ONLY) {
  1578. if (global_ui_config.silent < 9) {
  1579. error_printf("The track number has to be between 1 and 255 for ID3v1.\n");
  1580. }
  1581. return -1;
  1582. }
  1583. else if (id3tag_mode == ID3TAG_MODE_V2_ONLY) {
  1584. /* track will be stored as-is in ID3v2 case, so no problem here */
  1585. }
  1586. else {
  1587. if (global_ui_config.silent < 9) {
  1588. error_printf("The track number has to be between 1 and 255 for ID3v1, ignored for ID3v1.\n");
  1589. }
  1590. }
  1591. }
  1592. }
  1593. T_ELIF("tg")
  1594. int ret = 0;
  1595. argUsed = 1;
  1596. if (nextArg != 0 && strlen(nextArg) > 0) {
  1597. ret = id3_tag(gfp, 'g', id3_tenc, nextArg);
  1598. }
  1599. if (ret != 0) {
  1600. if (0 == ignore_tag_errors) {
  1601. if (ret == -1) {
  1602. error_printf("Unknown ID3v1 genre number: '%s'.\n", nextArg);
  1603. return -1;
  1604. }
  1605. else if (ret == -2) {
  1606. if (id3tag_mode == ID3TAG_MODE_V1_ONLY) {
  1607. error_printf("Unknown ID3v1 genre: '%s'.\n", nextArg);
  1608. return -1;
  1609. }
  1610. else if (id3tag_mode == ID3TAG_MODE_V2_ONLY) {
  1611. /* genre will be stored as-is in ID3v2 case, so no problem here */
  1612. }
  1613. else {
  1614. if (global_ui_config.silent < 9) {
  1615. error_printf("Unknown ID3v1 genre: '%s'. Setting ID3v1 genre to 'Other'\n", nextArg);
  1616. }
  1617. }
  1618. }
  1619. else {
  1620. if (global_ui_config.silent < 10)
  1621. error_printf("Internal error.\n");
  1622. return -1;
  1623. }
  1624. }
  1625. }
  1626. T_ELIF("tv")
  1627. argUsed = 1;
  1628. if (id3_tag(gfp, 'v', id3_tenc, nextArg)) {
  1629. if (global_ui_config.silent < 9) {
  1630. error_printf("Invalid field value: '%s'. Ignored\n", nextArg);
  1631. }
  1632. }
  1633. T_ELIF("ti")
  1634. argUsed = 1;
  1635. if (set_id3_albumart(gfp, nextArg) != 0) {
  1636. if (! ignore_tag_errors) {
  1637. return -1;
  1638. }
  1639. }
  1640. T_ELIF("ignore-tag-errors")
  1641. ignore_tag_errors = 1;
  1642. T_ELIF("add-id3v2")
  1643. id3tag_add_v2(gfp);
  1644. T_ELIF("id3v1-only")
  1645. id3tag_v1_only(gfp);
  1646. id3tag_mode = ID3TAG_MODE_V1_ONLY;
  1647. T_ELIF("id3v2-only")
  1648. id3tag_v2_only(gfp);
  1649. id3tag_mode = ID3TAG_MODE_V2_ONLY;
  1650. T_ELIF("space-id3v1")
  1651. id3tag_space_v1(gfp);
  1652. T_ELIF("pad-id3v2")
  1653. id3tag_pad_v2(gfp);
  1654. T_ELIF("pad-id3v2-size")
  1655. argUsed = getIntValue(token, nextArg, &int_value);
  1656. if (argUsed) {
  1657. int_value = int_value <= 128000 ? int_value : 128000;
  1658. int_value = int_value >= 0 ? int_value : 0;
  1659. id3tag_set_pad(gfp, int_value);
  1660. }
  1661. T_ELIF("genre-list")
  1662. id3tag_genre_list(genre_list_handler, NULL);
  1663. return -2;
  1664. T_ELIF("lowpass")
  1665. argUsed = getDoubleValue(token, nextArg, &double_value);
  1666. if (argUsed) {
  1667. if (double_value < 0) {
  1668. lame_set_lowpassfreq(gfp, -1);
  1669. }
  1670. else {
  1671. /* useful are 0.001 kHz...50 kHz, 50 Hz...50000 Hz */
  1672. if (double_value < 0.001 || double_value > 50000.) {
  1673. error_printf("Must specify lowpass with --lowpass freq, freq >= 0.001 kHz\n");
  1674. return -1;
  1675. }
  1676. lame_set_lowpassfreq(gfp, (int) (double_value * (double_value < 50. ? 1.e3 : 1.e0) + 0.5));
  1677. }
  1678. }
  1679. T_ELIF("lowpass-width")
  1680. argUsed = getDoubleValue(token, nextArg, &double_value);
  1681. if (argUsed) {
  1682. /* useful are 0.001 kHz...16 kHz, 16 Hz...50000 Hz */
  1683. if (double_value < 0.001 || double_value > 50000.) {
  1684. error_printf
  1685. ("Must specify lowpass width with --lowpass-width freq, freq >= 0.001 kHz\n");
  1686. return -1;
  1687. }
  1688. lame_set_lowpasswidth(gfp, (int) (double_value * (double_value < 16. ? 1.e3 : 1.e0) + 0.5));
  1689. }
  1690. T_ELIF("highpass")
  1691. argUsed = getDoubleValue(token, nextArg, &double_value);
  1692. if (argUsed) {
  1693. if (double_value < 0.0) {
  1694. lame_set_highpassfreq(gfp, -1);
  1695. }
  1696. else {
  1697. /* useful are 0.001 kHz...16 kHz, 16 Hz...50000 Hz */
  1698. if (double_value < 0.001 || double_value > 50000.) {
  1699. error_printf("Must specify highpass with --highpass freq, freq >= 0.001 kHz\n");
  1700. return -1;
  1701. }
  1702. lame_set_highpassfreq(gfp, (int) (double_value * (double_value < 16. ? 1.e3 : 1.e0) + 0.5));
  1703. }
  1704. }
  1705. T_ELIF("highpass-width")
  1706. argUsed = getDoubleValue(token, nextArg, &double_value);
  1707. if (argUsed) {
  1708. /* useful are 0.001 kHz...16 kHz, 16 Hz...50000 Hz */
  1709. if (double_value < 0.001 || double_value > 50000.) {
  1710. error_printf
  1711. ("Must specify highpass width with --highpass-width freq, freq >= 0.001 kHz\n");
  1712. return -1;
  1713. }
  1714. lame_set_highpasswidth(gfp, (int) double_value);
  1715. }
  1716. T_ELIF("comp")
  1717. argUsed = getDoubleValue(token, nextArg, &double_value);
  1718. if (argUsed) {
  1719. if (double_value < 1.0) {
  1720. error_printf("Must specify compression ratio >= 1.0\n");
  1721. return -1;
  1722. }
  1723. else {
  1724. lame_set_compression_ratio(gfp, (float) double_value);
  1725. }
  1726. }
  1727. /* some more GNU-ish options could be added
  1728. * brief => few messages on screen (name, status report)
  1729. * o/output file => specifies output filename
  1730. * O => stdout
  1731. * i/input file => specifies input filename
  1732. * I => stdin
  1733. */
  1734. T_ELIF("quiet")
  1735. global_ui_config.silent = 10; /* on a scale from 1 to 10 be very silent */
  1736. T_ELIF("silent")
  1737. global_ui_config.silent = 9;
  1738. T_ELIF("brief")
  1739. global_ui_config.silent = -5; /* print few info on screen */
  1740. T_ELIF("verbose")
  1741. global_ui_config.silent = -10; /* print a lot on screen */
  1742. T_ELIF2("version", "license")
  1743. print_license(stdout);
  1744. return -2;
  1745. T_ELIF2("help", "usage")
  1746. if (0 == local_strncasecmp(nextArg, "id3", 3)) {
  1747. help_id3tag(stdout);
  1748. }
  1749. else if (0 == local_strncasecmp(nextArg, "dev", 3)) {
  1750. help_developer_switches(stdout);
  1751. }
  1752. else {
  1753. short_help(gfp, stdout, ProgramName);
  1754. }
  1755. return -2;
  1756. T_ELIF("longhelp")
  1757. long_help(gfp, stdout, ProgramName, 0 /* lessmode=NO */ );
  1758. return -2;
  1759. T_ELIF("?")
  1760. #ifdef __unix__
  1761. FILE *fp = popen("less -Mqc", "w");
  1762. long_help(gfp, fp, ProgramName, 0 /* lessmode=NO */ );
  1763. pclose(fp);
  1764. #else
  1765. long_help(gfp, stdout, ProgramName, 1 /* lessmode=YES */ );
  1766. #endif
  1767. return -2;
  1768. T_ELIF2("preset", "alt-preset")
  1769. argUsed = 1;
  1770. {
  1771. int fast = 0, cbr = 0;
  1772. while ((strcmp(nextArg, "fast") == 0) || (strcmp(nextArg, "cbr") == 0)) {
  1773. if ((strcmp(nextArg, "fast") == 0) && (fast < 1))
  1774. fast = 1;
  1775. if ((strcmp(nextArg, "cbr") == 0) && (cbr < 1))
  1776. cbr = 1;
  1777. argUsed++;
  1778. nextArg = i + argUsed < argc ? argv[i + argUsed] : "";
  1779. }
  1780. if (presets_set(gfp, fast, cbr, nextArg, ProgramName) < 0)
  1781. return -1;
  1782. }
  1783. T_ELIF("disptime")
  1784. argUsed = getDoubleValue(token, nextArg, &double_value);
  1785. if (argUsed)
  1786. global_ui_config.update_interval = (float) double_value;
  1787. T_ELIF("nogaptags")
  1788. nogap_tags = 1;
  1789. T_ELIF("nogapout")
  1790. int const arg_n = strnlen(nextArg, PATH_MAX);
  1791. if (arg_n >= PATH_MAX) {
  1792. error_printf("%s: %s argument length (%d) exceeds limit (%d)\n", ProgramName, token, arg_n, PATH_MAX);
  1793. return -1;
  1794. }
  1795. strncpy(outPath, nextArg, PATH_MAX);
  1796. outPath[PATH_MAX] = '\0';
  1797. argUsed = 1;
  1798. T_ELIF("out-dir")
  1799. int const arg_n = strnlen(nextArg, PATH_MAX);
  1800. if (arg_n >= PATH_MAX) {
  1801. error_printf("%s: %s argument length (%d) exceeds limit (%d)\n", ProgramName, token, arg_n, PATH_MAX);
  1802. return -1;
  1803. }
  1804. strncpy(outDir, nextArg, PATH_MAX);
  1805. outDir[PATH_MAX] = '\0';
  1806. argUsed = 1;
  1807. T_ELIF("nogap")
  1808. nogap = 1;
  1809. T_ELIF("swap-channel")
  1810. global_reader.swap_channel = 1;
  1811. T_ELIF("ignorelength")
  1812. global_reader.ignorewavlength = 1;
  1813. T_ELIF ("athaa-sensitivity")
  1814. argUsed = getDoubleValue(token, nextArg, &double_value);
  1815. if (argUsed)
  1816. lame_set_athaa_sensitivity(gfp, (float) double_value);
  1817. /* ---------------- lots of dead switches ---------------- */
  1818. T_ELIF_INTERNAL("noshort")
  1819. (void) lame_set_no_short_blocks(gfp, 1);
  1820. T_ELIF_INTERNAL("short")
  1821. (void) lame_set_no_short_blocks(gfp, 0);
  1822. T_ELIF_INTERNAL("allshort")
  1823. (void) lame_set_force_short_blocks(gfp, 1);
  1824. T_ELIF_INTERNAL("notemp")
  1825. (void) lame_set_useTemporal(gfp, 0);
  1826. T_ELIF_INTERNAL_WITH_ARG("interch")
  1827. argUsed = getDoubleValue(token, nextArg, &double_value);
  1828. if (argUsed)
  1829. (void) lame_set_interChRatio(gfp, (float) double_value);
  1830. T_ELIF_INTERNAL_WITH_ARG("temporal-masking")
  1831. argUsed = getIntValue(token, nextArg, &int_value);
  1832. if (argUsed)
  1833. (void) lame_set_useTemporal(gfp, int_value ? 1 : 0);
  1834. T_ELIF_INTERNAL("nspsytune")
  1835. ;
  1836. T_ELIF_INTERNAL("nssafejoint")
  1837. lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2);
  1838. T_ELIF_INTERNAL_WITH_ARG("nsmsfix")
  1839. argUsed = getDoubleValue(token, nextArg, &double_value);
  1840. if (argUsed)
  1841. (void) lame_set_msfix(gfp, double_value);
  1842. T_ELIF_INTERNAL_WITH_ARG("ns-bass")
  1843. argUsed = getDoubleValue(token, nextArg, &double_value);
  1844. if (argUsed) {
  1845. int k = (int) (double_value * 4);
  1846. if (k < -32)
  1847. k = -32;
  1848. if (k > 31)
  1849. k = 31;
  1850. if (k < 0)
  1851. k += 64;
  1852. lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (k << 2));
  1853. }
  1854. T_ELIF_INTERNAL_WITH_ARG("ns-alto")
  1855. argUsed = getDoubleValue(token, nextArg, &double_value);
  1856. if (argUsed) {
  1857. int k = (int) (double_value * 4);
  1858. if (k < -32)
  1859. k = -32;
  1860. if (k > 31)
  1861. k = 31;
  1862. if (k < 0)
  1863. k += 64;
  1864. lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (k << 8));
  1865. }
  1866. T_ELIF_INTERNAL_WITH_ARG("ns-treble")
  1867. argUsed = getDoubleValue(token, nextArg, &double_value);
  1868. if (argUsed) {
  1869. int k = (int) (double_value * 4);
  1870. if (k < -32)
  1871. k = -32;
  1872. if (k > 31)
  1873. k = 31;
  1874. if (k < 0)
  1875. k += 64;
  1876. lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (k << 14));
  1877. }
  1878. T_ELIF_INTERNAL_WITH_ARG("ns-sfb21")
  1879. /* to be compatible with Naoki's original code,
  1880. * ns-sfb21 specifies how to change ns-treble for sfb21 */
  1881. argUsed = getDoubleValue(token, nextArg, &double_value);
  1882. if (argUsed) {
  1883. int k = (int) (double_value * 4);
  1884. if (k < -32)
  1885. k = -32;
  1886. if (k > 31)
  1887. k = 31;
  1888. if (k < 0)
  1889. k += 64;
  1890. lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | (k << 20));
  1891. }
  1892. T_ELIF_INTERNAL_WITH_ARG("tune") /*without helptext */
  1893. argUsed = getDoubleValue(token, nextArg, &double_value);
  1894. if (argUsed)
  1895. lame_set_tune(gfp, (float) double_value);
  1896. T_ELIF_INTERNAL_WITH_ARG("shortthreshold")
  1897. {
  1898. float x, y;
  1899. int n = sscanf(nextArg, "%f,%f", &x, &y);
  1900. if (n == 1) {
  1901. y = x;
  1902. }
  1903. (void) lame_set_short_threshold(gfp, x, y);
  1904. }
  1905. T_ELIF_INTERNAL_WITH_ARG("maskingadjust") /*without helptext */
  1906. argUsed = getDoubleValue(token, nextArg, &double_value);
  1907. if (argUsed)
  1908. (void) lame_set_maskingadjust(gfp, (float) double_value);
  1909. T_ELIF_INTERNAL_WITH_ARG("maskingadjustshort") /*without helptext */
  1910. argUsed = getDoubleValue(token, nextArg, &double_value);
  1911. if (argUsed)
  1912. (void) lame_set_maskingadjust_short(gfp, (float) double_value);
  1913. T_ELIF_INTERNAL_WITH_ARG("athcurve") /*without helptext */
  1914. argUsed = getDoubleValue(token, nextArg, &double_value);
  1915. if (argUsed)
  1916. (void) lame_set_ATHcurve(gfp, (float) double_value);
  1917. T_ELIF_INTERNAL("no-preset-tune") /*without helptext */
  1918. (void) lame_set_preset_notune(gfp, 0);
  1919. T_ELIF_INTERNAL_WITH_ARG("substep")
  1920. argUsed = getIntValue(token, nextArg, &int_value);
  1921. if (argUsed)
  1922. (void) lame_set_substep(gfp, int_value);
  1923. T_ELIF_INTERNAL_WITH_ARG("sbgain") /*without helptext */
  1924. argUsed = getIntValue(token, nextArg, &int_value);
  1925. if (argUsed)
  1926. (void) lame_set_subblock_gain(gfp, int_value);
  1927. T_ELIF_INTERNAL("sfscale") /*without helptext */
  1928. (void) lame_set_sfscale(gfp, 1);
  1929. T_ELIF_INTERNAL("noath")
  1930. (void) lame_set_noATH(gfp, 1);
  1931. T_ELIF_INTERNAL("athonly")
  1932. (void) lame_set_ATHonly(gfp, 1);
  1933. T_ELIF_INTERNAL("athshort")
  1934. (void) lame_set_ATHshort(gfp, 1);
  1935. T_ELIF_INTERNAL_WITH_ARG("athlower")
  1936. argUsed = getDoubleValue(token, nextArg, &double_value);
  1937. if (argUsed)
  1938. (void) lame_set_ATHlower(gfp, (float) double_value);
  1939. T_ELIF_INTERNAL_WITH_ARG("athtype")
  1940. argUsed = getIntValue(token, nextArg, &int_value);
  1941. if (argUsed)
  1942. (void) lame_set_ATHtype(gfp, int_value);
  1943. T_ELIF_INTERNAL_WITH_ARG("athaa-type") /* switch for developing, no DOCU */
  1944. /* once was 1:Gaby, 2:Robert, 3:Jon, else:off */
  1945. argUsed = getIntValue(token, nextArg, &int_value);
  1946. if (argUsed)
  1947. (void) lame_set_athaa_type(gfp, int_value); /* now: 0:off else:Jon */
  1948. T_ELIF_INTERNAL_WITH_ARG("debug-file") /* switch for developing, no DOCU */
  1949. /* file name to print debug info into */
  1950. set_debug_file(nextArg);
  1951. T_ELSE {
  1952. if (!argIgnored) {
  1953. error_printf("%s: unrecognized option --%s\n", ProgramName, token);
  1954. return -1;
  1955. }
  1956. argIgnored = 0;
  1957. }
  1958. T_END i += argUsed;
  1959. }
  1960. else {
  1961. while ((c = *token++) != '\0') {
  1962. double double_value = 0;
  1963. int int_value = 0;
  1964. arg = *token ? token : nextArg;
  1965. switch (c) {
  1966. case 'm':
  1967. argUsed = 1;
  1968. switch (*arg) {
  1969. case 's':
  1970. (void) lame_set_mode(gfp, STEREO);
  1971. break;
  1972. case 'd':
  1973. (void) lame_set_mode(gfp, DUAL_CHANNEL);
  1974. break;
  1975. case 'f':
  1976. lame_set_force_ms(gfp, 1);
  1977. (void) lame_set_mode(gfp, JOINT_STEREO);
  1978. break;
  1979. case 'j':
  1980. lame_set_force_ms(gfp, 0);
  1981. (void) lame_set_mode(gfp, JOINT_STEREO);
  1982. break;
  1983. case 'm':
  1984. (void) lame_set_mode(gfp, MONO);
  1985. break;
  1986. case 'l':
  1987. (void) lame_set_mode(gfp, MONO);
  1988. (void) lame_set_scale_left(gfp, 2);
  1989. (void) lame_set_scale_right(gfp, 0);
  1990. break;
  1991. case 'r':
  1992. (void) lame_set_mode(gfp, MONO);
  1993. (void) lame_set_scale_left(gfp, 0);
  1994. (void) lame_set_scale_right(gfp, 2);
  1995. break;
  1996. case 'a': /* same as 'j' ??? */
  1997. lame_set_force_ms(gfp, 0);
  1998. (void) lame_set_mode(gfp, JOINT_STEREO);
  1999. break;
  2000. default:
  2001. error_printf("%s: -m mode must be s/d/f/j/m/l/r not %s\n", ProgramName,
  2002. arg);
  2003. return -1;
  2004. }
  2005. break;
  2006. case 'V':
  2007. argUsed = getDoubleValue("V", arg, &double_value);
  2008. if (argUsed) {
  2009. /* to change VBR default look in lame.h */
  2010. if (lame_get_VBR(gfp) == vbr_off)
  2011. lame_set_VBR(gfp, vbr_default);
  2012. lame_set_VBR_quality(gfp, (float) double_value);
  2013. }
  2014. break;
  2015. case 'v':
  2016. /* to change VBR default look in lame.h */
  2017. if (lame_get_VBR(gfp) == vbr_off)
  2018. lame_set_VBR(gfp, vbr_default);
  2019. break;
  2020. case 'q':
  2021. argUsed = getIntValue("q", arg, &int_value);
  2022. if (argUsed)
  2023. (void) lame_set_quality(gfp, int_value);
  2024. break;
  2025. case 'f':
  2026. (void) lame_set_quality(gfp, 7);
  2027. break;
  2028. case 'h':
  2029. (void) lame_set_quality(gfp, 2);
  2030. break;
  2031. case 's':
  2032. argUsed = getDoubleValue("s", arg, &double_value);
  2033. if (argUsed) {
  2034. double_value = (int) (double_value * (double_value <= 192 ? 1.e3 : 1.e0) + 0.5);
  2035. global_reader.input_samplerate = (int)double_value;
  2036. (void) lame_set_in_samplerate(gfp, (int)double_value);
  2037. }
  2038. break;
  2039. case 'b':
  2040. argUsed = getIntValue("b", arg, &int_value);
  2041. if (argUsed) {
  2042. lame_set_brate(gfp, int_value);
  2043. lame_set_VBR_min_bitrate_kbps(gfp, lame_get_brate(gfp));
  2044. }
  2045. break;
  2046. case 'B':
  2047. argUsed = getIntValue("B", arg, &int_value);
  2048. if (argUsed) {
  2049. lame_set_VBR_max_bitrate_kbps(gfp, int_value);
  2050. }
  2051. break;
  2052. case 'F':
  2053. lame_set_VBR_hard_min(gfp, 1);
  2054. break;
  2055. case 't': /* dont write VBR tag */
  2056. (void) lame_set_bWriteVbrTag(gfp, 0);
  2057. global_decoder.disable_wav_header = 1;
  2058. break;
  2059. case 'T': /* do write VBR tag */
  2060. (void) lame_set_bWriteVbrTag(gfp, 1);
  2061. nogap_tags = 1;
  2062. global_decoder.disable_wav_header = 0;
  2063. break;
  2064. case 'r': /* force raw pcm input file */
  2065. #if defined(LIBSNDFILE)
  2066. error_printf
  2067. ("WARNING: libsndfile may ignore -r and perform fseek's on the input.\n"
  2068. "Compile without libsndfile if this is a problem.\n");
  2069. #endif
  2070. global_reader.input_format = sf_raw;
  2071. break;
  2072. case 'x': /* force byte swapping */
  2073. global_reader.swapbytes = 1;
  2074. break;
  2075. case 'p': /* (jo) error_protection: add crc16 information to stream */
  2076. lame_set_error_protection(gfp, 1);
  2077. break;
  2078. case 'a': /* autoconvert input file from stereo to mono - for mono mp3 encoding */
  2079. autoconvert = 1;
  2080. (void) lame_set_mode(gfp, MONO);
  2081. break;
  2082. case 'd': /*(void) lame_set_allow_diff_short( gfp, 1 ); */
  2083. case 'k': /*lame_set_lowpassfreq(gfp, -1);
  2084. lame_set_highpassfreq(gfp, -1); */
  2085. error_printf("WARNING: -%c is obsolete.\n", c);
  2086. break;
  2087. case 'S':
  2088. global_ui_config.silent = 5;
  2089. break;
  2090. case 'X':
  2091. /* experimental switch -X:
  2092. the differnt types of quant compare are tough
  2093. to communicate to endusers, so they shouldn't
  2094. bother to toy around with them
  2095. */
  2096. {
  2097. int x, y;
  2098. int n = sscanf(arg, "%d,%d", &x, &y);
  2099. if (n == 1) {
  2100. y = x;
  2101. }
  2102. argUsed = 1;
  2103. if (internal_opts_enabled) {
  2104. lame_set_quant_comp(gfp, x);
  2105. lame_set_quant_comp_short(gfp, y);
  2106. }
  2107. }
  2108. break;
  2109. case 'Y':
  2110. lame_set_experimentalY(gfp, 1);
  2111. break;
  2112. case 'Z':
  2113. /* experimental switch -Z:
  2114. */
  2115. {
  2116. int n = 1;
  2117. argUsed = sscanf(arg, "%d", &n);
  2118. /*if (internal_opts_enabled)*/
  2119. {
  2120. lame_set_experimentalZ(gfp, n);
  2121. }
  2122. }
  2123. break;
  2124. case 'e':
  2125. argUsed = 1;
  2126. switch (*arg) {
  2127. case 'n':
  2128. lame_set_emphasis(gfp, 0);
  2129. break;
  2130. case '5':
  2131. lame_set_emphasis(gfp, 1);
  2132. break;
  2133. case 'c':
  2134. lame_set_emphasis(gfp, 3);
  2135. break;
  2136. default:
  2137. error_printf("%s: -e emp must be n/5/c not %s\n", ProgramName, arg);
  2138. return -1;
  2139. }
  2140. break;
  2141. case 'c':
  2142. lame_set_copyright(gfp, 1);
  2143. break;
  2144. case 'o':
  2145. lame_set_original(gfp, 0);
  2146. break;
  2147. case '?':
  2148. long_help(gfp, stdout, ProgramName, 0 /* LESSMODE=NO */ );
  2149. return -1;
  2150. default:
  2151. error_printf("%s: unrecognized option -%c\n", ProgramName, c);
  2152. return -1;
  2153. }
  2154. if (argUsed) {
  2155. if (arg == token)
  2156. token = ""; /* no more from token */
  2157. else
  2158. ++i; /* skip arg we used */
  2159. arg = "";
  2160. argUsed = 0;
  2161. }
  2162. }
  2163. }
  2164. }
  2165. else {
  2166. if (nogap) {
  2167. if ((num_nogap != NULL) && (count_nogap < *num_nogap)) {
  2168. strncpy(nogap_inPath[count_nogap++], argv[i], PATH_MAX + 1);
  2169. input_file = 1;
  2170. }
  2171. else {
  2172. /* sorry, calling program did not allocate enough space */
  2173. error_printf
  2174. ("Error: 'nogap option'. Calling program does not allow nogap option, or\n"
  2175. "you have exceeded maximum number of input files for the nogap option\n");
  2176. *num_nogap = -1;
  2177. return -1;
  2178. }
  2179. }
  2180. else {
  2181. /* normal options: inputfile [outputfile], and
  2182. either one can be a '-' for stdin/stdout */
  2183. if (inPath[0] == '\0') {
  2184. strncpy(inPath, argv[i], PATH_MAX + 1);
  2185. input_file = 1;
  2186. }
  2187. else {
  2188. if (outPath[0] == '\0')
  2189. strncpy(outPath, argv[i], PATH_MAX + 1);
  2190. else {
  2191. error_printf("%s: excess arg %s\n", ProgramName, argv[i]);
  2192. return -1;
  2193. }
  2194. }
  2195. }
  2196. }
  2197. } /* loop over args */
  2198. if (!input_file) {
  2199. usage(Console_IO.Console_fp, ProgramName);
  2200. return -1;
  2201. }
  2202. if (lame_get_decode_only(gfp) && count_nogap > 0) {
  2203. error_printf("combination of nogap and decode not supported!\n");
  2204. return -1;
  2205. }
  2206. if (inPath[0] == '-') {
  2207. if (global_ui_config.silent == 0) { /* user didn't overrule default behaviour */
  2208. global_ui_config.silent = 1;
  2209. }
  2210. }
  2211. #ifdef WIN32
  2212. else
  2213. dosToLongFileName(inPath);
  2214. #endif
  2215. if (outPath[0] == '\0') { /* no explicit output dir or file */
  2216. if (count_nogap > 0) { /* in case of nogap encode */
  2217. strncpy(outPath, outDir, PATH_MAX);
  2218. outPath[PATH_MAX] = '\0'; /* whatever someone set via --out-dir <path> argument */
  2219. }
  2220. else if (inPath[0] == '-') {
  2221. /* if input is stdin, default output is stdout */
  2222. strcpy(outPath, "-");
  2223. }
  2224. else {
  2225. char const* s_ext = lame_get_decode_only(gfp) ? ".wav" : ".mp3";
  2226. if (generateOutPath(inPath, outDir, s_ext, outPath) != 0) {
  2227. return -1;
  2228. }
  2229. }
  2230. }
  2231. /* RG is enabled by default */
  2232. if (!noreplaygain)
  2233. lame_set_findReplayGain(gfp, 1);
  2234. /* disable VBR tags with nogap unless the VBR tags are forced */
  2235. if (nogap && lame_get_bWriteVbrTag(gfp) && nogap_tags == 0) {
  2236. console_printf("Note: Disabling VBR Xing/Info tag since it interferes with --nogap\n");
  2237. lame_set_bWriteVbrTag(gfp, 0);
  2238. }
  2239. /* some file options not allowed with stdout */
  2240. if (outPath[0] == '-') {
  2241. (void) lame_set_bWriteVbrTag(gfp, 0); /* turn off VBR tag */
  2242. }
  2243. /* if user did not explicitly specify input is mp3, check file name */
  2244. if (global_reader.input_format == sf_unknown)
  2245. global_reader.input_format = filename_to_type(inPath);
  2246. #if !(defined HAVE_MPGLIB || defined AMIGA_MPEGA)
  2247. if (is_mpeg_file_format(global_reader.input_format)) {
  2248. error_printf("Error: libmp3lame not compiled with mpg123 *decoding* support \n");
  2249. return -1;
  2250. }
  2251. #endif
  2252. /* default guess for number of channels */
  2253. if (autoconvert)
  2254. (void) lame_set_num_channels(gfp, 2);
  2255. else if (MONO == lame_get_mode(gfp))
  2256. (void) lame_set_num_channels(gfp, 1);
  2257. else
  2258. (void) lame_set_num_channels(gfp, 2);
  2259. if (lame_get_free_format(gfp)) {
  2260. if (lame_get_brate(gfp) < 8 || lame_get_brate(gfp) > 640) {
  2261. error_printf("For free format, specify a bitrate between 8 and 640 kbps\n");
  2262. error_printf("with the -b <bitrate> option\n");
  2263. return -1;
  2264. }
  2265. }
  2266. if (num_nogap != NULL)
  2267. *num_nogap = count_nogap;
  2268. return 0;
  2269. }
  2270. static int
  2271. string_to_argv(char* str, char** argv, int N)
  2272. {
  2273. int argc = 0;
  2274. if (str == 0) return argc;
  2275. argv[argc++] = "lhama";
  2276. for (;;) {
  2277. int quoted = 0;
  2278. while (isspace(*str)) { /* skip blanks */
  2279. ++str;
  2280. }
  2281. if (*str == '\"') { /* is quoted argument ? */
  2282. quoted = 1;
  2283. ++str;
  2284. }
  2285. if (*str == '\0') { /* end of string reached */
  2286. break;
  2287. }
  2288. /* found beginning of some argument */
  2289. if (argc < N) {
  2290. argv[argc++] = str;
  2291. }
  2292. /* look out for end of argument, either end of string, blank or quote */
  2293. for(; *str != '\0'; ++str) {
  2294. if (quoted) {
  2295. if (*str == '\"') { /* end of quotation reached */
  2296. *str++ = '\0';
  2297. break;
  2298. }
  2299. }
  2300. else {
  2301. if (isspace(*str)) { /* parameter separator reached */
  2302. *str++ = '\0';
  2303. break;
  2304. }
  2305. }
  2306. }
  2307. }
  2308. return argc;
  2309. }
  2310. static int
  2311. merge_argv(int argc, char** argv, int str_argc, char** str_argv, int N)
  2312. {
  2313. int i;
  2314. if (argc > 0) {
  2315. str_argv[0] = argv[0];
  2316. if (str_argc < 1) str_argc = 1;
  2317. }
  2318. for (i = 1; i < argc; ++i) {
  2319. int j = str_argc + i - 1;
  2320. if (j < N) {
  2321. str_argv[j] = argv[i];
  2322. }
  2323. }
  2324. return argc + str_argc - 1;
  2325. }
  2326. #ifdef DEBUG
  2327. static void
  2328. dump_argv(int argc, char** argv)
  2329. {
  2330. int i;
  2331. for (i = 0; i < argc; ++i) {
  2332. printf("%d: \"%s\"\n",i,argv[i]);
  2333. }
  2334. }
  2335. #endif
  2336. int parse_args(lame_t gfp, int argc, char **argv, char *const inPath, char *const outPath, char **nogap_inPath, int *num_nogap)
  2337. {
  2338. char *str_argv[512], *str;
  2339. int str_argc, ret;
  2340. str = lame_getenv("LAMEOPT");
  2341. str_argc = string_to_argv(str, str_argv, dimension_of(str_argv));
  2342. str_argc = merge_argv(argc, argv, str_argc, str_argv, dimension_of(str_argv));
  2343. #ifdef DEBUG
  2344. dump_argv(str_argc, str_argv);
  2345. #endif
  2346. ret = parse_args_(gfp, str_argc, str_argv, inPath, outPath, nogap_inPath, num_nogap);
  2347. free(str);
  2348. return ret;
  2349. }
  2350. /* end of parse.c */