main.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852
  1. /*
  2. * Squeezelite - lightweight headless squeezebox emulator
  3. *
  4. * (c) Adrian Smith 2012-2015, triode1@btinternet.com
  5. * Ralph Irving 2015-2017, ralph_irving@hotmail.com
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program 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
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. * Additions (c) Paul Hermann, 2015-2017 under the same license terms
  21. * -Control of Raspberry pi GPIO for amplifier power
  22. * -Launch script on power status change from LMS
  23. */
  24. #include "squeezelite.h"
  25. #include <signal.h>
  26. #define TITLE "Squeezelite " VERSION ", Copyright 2012-2015 Adrian Smith, 2015-2019 Ralph Irving."
  27. #define CODECS_BASE "flac,pcm,mp3,ogg"
  28. #if NO_FAAD
  29. #define CODECS_AAC ""
  30. #else
  31. #define CODECS_AAC ",aac"
  32. #endif
  33. #if FFMPEG
  34. #define CODECS_FF ",wma,alac"
  35. #else
  36. #define CODECS_FF ""
  37. #endif
  38. #if DSD
  39. #define CODECS_DSD ",dsd"
  40. #else
  41. #define CODECS_DSD ""
  42. #endif
  43. #define CODECS_MP3 " (mad,mpg for specific mp3 codec)"
  44. #define CODECS CODECS_BASE CODECS_AAC CODECS_FF CODECS_DSD CODECS_MP3
  45. static void usage(const char *argv0) {
  46. printf(TITLE " See -t for license terms\n"
  47. "Usage: %s [options]\n"
  48. " -s <server>[:<port>]\tConnect to specified server, otherwise uses autodiscovery to find server\n"
  49. " -o <output device>\tSpecify output device, default \"default\", - = output to stdout\n"
  50. " -l \t\t\tList output devices\n"
  51. #if ALSA
  52. " -a <b>:<p>:<f>:<m>\tSpecify ALSA params to open output device, b = buffer time in ms or size in bytes, p = period count or size in bytes, f sample format (16|24|24_3|32), m = use mmap (0|1)\n"
  53. #endif
  54. #if PORTAUDIO
  55. #if PA18API
  56. " -a <frames>:<buffers>\tSpecify output target 4 byte frames per buffer, number of buffers\n"
  57. #elif OSX && !defined(OSXPPC)
  58. " -a <l>:<r>\t\tSpecify Portaudio params to open output device, l = target latency in ms, r = allow OSX to resample (0|1)\n"
  59. #elif WIN
  60. " -a <l>:<e>\t\tSpecify Portaudio params to open output device, l = target latency in ms, e = use exclusive mode for WASAPI (0|1)\n"
  61. #else
  62. " -a <l>\t\tSpecify Portaudio params to open output device, l = target latency in ms\n"
  63. #endif
  64. #endif
  65. " -a <f>\t\tSpecify sample format (16|24|32) of output file when using -o - to output samples to stdout (interleaved little endian only)\n"
  66. " -b <stream>:<output>\tSpecify internal Stream and Output buffer sizes in Kbytes\n"
  67. " -c <codec1>,<codec2>\tRestrict codecs to those specified, otherwise load all available codecs; known codecs: " CODECS "\n"
  68. " \t\t\tCodecs reported to LMS in order listed, allowing codec priority refinement.\n"
  69. " -C <timeout>\t\tClose output device when idle after timeout seconds, default is to keep it open while player is 'on'\n"
  70. #if !IR
  71. " -d <log>=<level>\tSet logging level, logs: all|slimproto|stream|decode|output, level: info|debug|sdebug\n"
  72. #else
  73. " -d <log>=<level>\tSet logging level, logs: all|slimproto|stream|decode|output|ir, level: info|debug|sdebug\n"
  74. #endif
  75. #if defined(GPIO) && defined(RPI)
  76. " -G <Rpi GPIO#>:<H/L>\tSpecify the BCM GPIO# to use for Amp Power Relay and if the output should be Active High or Low\n"
  77. #endif
  78. " -e <codec1>,<codec2>\tExplicitly exclude native support of one or more codecs; known codecs: " CODECS "\n"
  79. " -f <logfile>\t\tWrite debug to logfile\n"
  80. #if IR
  81. " -i [<filename>]\tEnable lirc remote control support (lirc config file ~/.lircrc used if filename not specified)\n"
  82. #endif
  83. " -m <mac addr>\t\tSet mac address, format: ab:cd:ef:12:34:56\n"
  84. " -M <modelname>\tSet the squeezelite player model name sent to the server (default: " MODEL_NAME_STRING ")\n"
  85. " -n <name>\t\tSet the player name\n"
  86. " -N <filename>\t\tStore player name in filename to allow server defined name changes to be shared between servers (not supported with -n)\n"
  87. " -W\t\t\tRead wave and aiff format from header, ignore server parameters\n"
  88. #if ALSA
  89. " -p <priority>\t\tSet real time priority of output thread (1-99)\n"
  90. #endif
  91. #if LINUX || FREEBSD || SUN
  92. " -P <filename>\t\tStore the process id (PID) in filename\n"
  93. #endif
  94. " -r <rates>[:<delay>]\tSample rates supported, allows output to be off when squeezelite is started; rates = <maxrate>|<minrate>-<maxrate>|<rate1>,<rate2>,<rate3>; delay = optional delay switching rates in ms\n"
  95. #if GPIO
  96. " -S <Power Script>\tAbsolute path to script to launch on power commands from LMS\n"
  97. #endif
  98. #if RESAMPLE
  99. " -R -u [params]\tResample, params = <recipe>:<flags>:<attenuation>:<precision>:<passband_end>:<stopband_start>:<phase_response>,\n"
  100. " \t\t\t recipe = (v|h|m|l|q)(L|I|M)(s) [E|X], E = exception - resample only if native rate not supported, X = async - resample to max rate for device, otherwise to max sync rate\n"
  101. " \t\t\t flags = num in hex,\n"
  102. " \t\t\t attenuation = attenuation in dB to apply (default is -1db if not explicitly set),\n"
  103. " \t\t\t precision = number of bits precision (NB. HQ = 20. VHQ = 28),\n"
  104. " \t\t\t passband_end = number in percent (0dB pt. bandwidth to preserve. nyquist = 100%%),\n"
  105. " \t\t\t stopband_start = number in percent (Aliasing/imaging control. > passband_end),\n"
  106. " \t\t\t phase_response = 0-100 (0 = minimum / 50 = linear / 100 = maximum)\n"
  107. #endif
  108. #if RESAMPLE16
  109. " -R -u [params]\tResample, params = (i|m)[:i],\n"
  110. " \t\t\t i = linear interpolation, m = 13 taps filter, i = interpolate filter coefficients\n"
  111. #endif
  112. #if DSD
  113. #if ALSA
  114. " -D [delay][:format]\tOutput device supports DSD, delay = optional delay switching between PCM and DSD in ms\n"
  115. " \t\t\t format = dop (default if not specified), u8, u16le, u16be, u32le or u32be.\n"
  116. #else
  117. " -D [delay]\t\tOutput device supports DSD over PCM (DoP), delay = optional delay switching between PCM and DoP in ms\n"
  118. #endif
  119. #endif
  120. #if VISEXPORT
  121. " -v \t\t\tVisualiser support\n"
  122. #endif
  123. # if ALSA
  124. " -O <mixer device>\tSpecify mixer device, defaults to 'output device'\n"
  125. " -L \t\t\tList volume controls for output device\n"
  126. " -U <control>\t\tUnmute ALSA control and set to full volume (not supported with -V)\n"
  127. " -V <control>\t\tUse ALSA control for volume adjustment, otherwise use software volume adjustment\n"
  128. " -X \t\t\tUse linear volume adjustments instead of in terms of dB (only for hardware volume control)\n"
  129. #endif
  130. #if LINUX || FREEBSD || SUN
  131. " -z \t\t\tDaemonize\n"
  132. #endif
  133. #if RESAMPLE || RESAMPLE16
  134. " -Z <rate>\t\tReport rate to server in helo as the maximum sample rate we can support\n"
  135. #endif
  136. " -t \t\t\tLicense terms\n"
  137. " -? \t\t\tDisplay this help text\n"
  138. "\n"
  139. "Build options:"
  140. #if SUN
  141. " SOLARIS"
  142. #elif LINUX
  143. " LINUX"
  144. #endif
  145. #if WIN
  146. " WIN"
  147. #endif
  148. #if OSX
  149. " OSX"
  150. #endif
  151. #if OSXPPC
  152. "PPC"
  153. #endif
  154. #if FREEBSD
  155. " FREEBSD"
  156. #endif
  157. #if ALSA
  158. " ALSA"
  159. #endif
  160. #if PORTAUDIO
  161. " PORTAUDIO"
  162. #if PA18API
  163. "18"
  164. #endif
  165. #endif
  166. #if EVENTFD
  167. " EVENTFD"
  168. #endif
  169. #if SELFPIPE
  170. " SELFPIPE"
  171. #endif
  172. #if LOOPBACK
  173. " LOOPBACK"
  174. #endif
  175. #if WINEVENT
  176. " WINEVENT"
  177. #endif
  178. #if RESAMPLE_MP
  179. " RESAMPLE_MP"
  180. #else
  181. #if RESAMPLE
  182. " RESAMPLE"
  183. #endif
  184. #if RESAMPLE16
  185. " RESAMPLE16"
  186. #endif
  187. #endif
  188. #if FFMPEG
  189. " FFMPEG"
  190. #endif
  191. #if NO_FAAD
  192. " NO_FAAD"
  193. #endif
  194. #if VISEXPORT
  195. " VISEXPORT"
  196. #endif
  197. #if IR
  198. " IR"
  199. #endif
  200. #if GPIO
  201. " GPIO"
  202. #endif
  203. #if RPI
  204. " RPI"
  205. #endif
  206. #if DSD
  207. " DSD"
  208. #endif
  209. #if USE_SSL
  210. " SSL"
  211. #endif
  212. #if LINKALL
  213. " LINKALL"
  214. #endif
  215. #if STATUSHACK
  216. " STATUSHACK"
  217. #endif
  218. "\n\n",
  219. argv0);
  220. }
  221. static void license(void) {
  222. printf(TITLE "\n\n"
  223. "This program is free software: you can redistribute it and/or modify\n"
  224. "it under the terms of the GNU General Public License as published by\n"
  225. "the Free Software Foundation, either version 3 of the License, or\n"
  226. "(at your option) any later version.\n\n"
  227. "This program is distributed in the hope that it will be useful,\n"
  228. "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
  229. "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
  230. "GNU General Public License for more details.\n\n"
  231. "You should have received a copy of the GNU General Public License\n"
  232. "along with this program. If not, see <http://www.gnu.org/licenses/>.\n"
  233. #if DSD
  234. "\nContains dsd2pcm library Copyright 2009, 2011 Sebastian Gesemann which\n"
  235. "is subject to its own license.\n"
  236. "\nContains the Daphile Project full dsd patch Copyright 2013-2017 Daphile,\n"
  237. "which is subject to its own license.\n"
  238. #endif
  239. "\nOption to allow server side upsampling for PCM streams (-W) from\n"
  240. "squeezelite-R2 (c) Marco Curti 2015, marcoc1712@gmail.com.\n"
  241. #if GPIO
  242. "\nAdditions (c) Paul Hermann, 2015, 2017 under the same license terms\n"
  243. "- Launch a script on power status change\n"
  244. "- Control of Raspberry pi GPIO for amplifier power\n"
  245. #endif
  246. #if RPI
  247. "\nContains wiringpi GPIO Interface library Copyright (c) 2012-2017\n"
  248. "Gordon Henderson, which is subject to its own license.\n"
  249. #endif
  250. #if FFMPEG
  251. "\nThis software uses libraries from the FFmpeg project under\n"
  252. "the LGPLv2.1 and its source can be downloaded from\n"
  253. "<https://sourceforge.net/projects/lmsclients/files/source/>\n"
  254. #endif
  255. "\n"
  256. );
  257. }
  258. static void sighandler(int signum) {
  259. slimproto_stop();
  260. // remove ourselves in case above does not work, second SIGINT will cause non gracefull shutdown
  261. signal(signum, SIG_DFL);
  262. }
  263. int main(int argc, char **argv) {
  264. char *server = NULL;
  265. char *output_device = "default";
  266. char *include_codecs = NULL;
  267. char *exclude_codecs = "";
  268. char *name = NULL;
  269. char *namefile = NULL;
  270. char *modelname = NULL;
  271. extern bool pcm_check_header;
  272. extern bool user_rates;
  273. char *logfile = NULL;
  274. u8_t mac[6];
  275. unsigned stream_buf_size = STREAMBUF_SIZE;
  276. unsigned output_buf_size = 0; // set later
  277. unsigned rates[MAX_SUPPORTED_SAMPLERATES] = { 0 };
  278. unsigned rate_delay = 0;
  279. char *resample = NULL;
  280. char *output_params = NULL;
  281. unsigned idle = 0;
  282. #if LINUX || FREEBSD || SUN
  283. bool daemonize = false;
  284. char *pidfile = NULL;
  285. FILE *pidfp = NULL;
  286. #endif
  287. #if ALSA
  288. unsigned rt_priority = OUTPUT_RT_PRIORITY;
  289. char *mixer_device = output_device;
  290. char *output_mixer = NULL;
  291. bool output_mixer_unmute = false;
  292. bool linear_volume = false;
  293. #endif
  294. #if DSD
  295. unsigned dsd_delay = 0;
  296. dsd_format dsd_outfmt = PCM;
  297. #endif
  298. #if VISEXPORT
  299. bool visexport = false;
  300. #endif
  301. #if IR
  302. char *lircrc = NULL;
  303. #endif
  304. log_level log_output = lWARN;
  305. log_level log_stream = lWARN;
  306. log_level log_decode = lWARN;
  307. log_level log_slimproto = lWARN;
  308. #if IR
  309. log_level log_ir = lWARN;
  310. #endif
  311. int maxSampleRate = 0;
  312. char *optarg = NULL;
  313. int optind = 1;
  314. int i;
  315. #define MAXCMDLINE 512
  316. char cmdline[MAXCMDLINE] = "";
  317. get_mac(mac);
  318. for (i = 0; i < argc && (strlen(argv[i]) + strlen(cmdline) + 2 < MAXCMDLINE); i++) {
  319. strcat(cmdline, argv[i]);
  320. strcat(cmdline, " ");
  321. }
  322. while (optind < argc && strlen(argv[optind]) >= 2 && argv[optind][0] == '-') {
  323. char *opt = argv[optind] + 1;
  324. if (strstr("oabcCdefmMnNpPrs"
  325. #if ALSA
  326. "UVO"
  327. #endif
  328. /*
  329. * only allow '-Z <rate>' override of maxSampleRate
  330. * reported by client if built with the capability to resample!
  331. */
  332. #if RESAMPLE || RESAMPLE16
  333. "Z"
  334. #endif
  335. , opt) && optind < argc - 1) {
  336. optarg = argv[optind + 1];
  337. optind += 2;
  338. } else if (strstr("ltz?W"
  339. #if ALSA
  340. "LX"
  341. #endif
  342. #if RESAMPLE || RESAMPLE16
  343. "uR"
  344. #endif
  345. #if DSD
  346. "D"
  347. #endif
  348. #if VISEXPORT
  349. "v"
  350. #endif
  351. #if IR
  352. "i"
  353. #endif
  354. #if defined(GPIO) && defined(RPI)
  355. "G"
  356. #endif
  357. #if GPIO
  358. "S"
  359. #endif
  360. , opt)) {
  361. optarg = NULL;
  362. optind += 1;
  363. } else {
  364. fprintf(stderr, "\nOption error: -%s\n\n", opt);
  365. usage(argv[0]);
  366. local_exit(1);
  367. }
  368. switch (opt[0]) {
  369. case 'o':
  370. output_device = optarg;
  371. #if ALSA
  372. mixer_device = optarg;
  373. #endif
  374. break;
  375. case 'a':
  376. output_params = optarg;
  377. break;
  378. case 'b':
  379. {
  380. char *s = next_param(optarg, ':');
  381. char *o = next_param(NULL, ':');
  382. if (s) stream_buf_size = atoi(s) * 1024;
  383. if (o) output_buf_size = atoi(o) * 1024;
  384. }
  385. break;
  386. case 'c':
  387. include_codecs = optarg;
  388. break;
  389. case 'C':
  390. if (atoi(optarg) > 0) {
  391. idle = atoi(optarg) * 1000;
  392. }
  393. break;
  394. case 'e':
  395. exclude_codecs = optarg;
  396. break;
  397. case 'd':
  398. {
  399. char *l = strtok(optarg, "=");
  400. char *v = strtok(NULL, "=");
  401. log_level new = lWARN;
  402. if (l && v) {
  403. if (!strcmp(v, "info")) new = lINFO;
  404. if (!strcmp(v, "debug")) new = lDEBUG;
  405. if (!strcmp(v, "sdebug")) new = lSDEBUG;
  406. if (!strcmp(l, "all") || !strcmp(l, "slimproto")) log_slimproto = new;
  407. if (!strcmp(l, "all") || !strcmp(l, "stream")) log_stream = new;
  408. if (!strcmp(l, "all") || !strcmp(l, "decode")) log_decode = new;
  409. if (!strcmp(l, "all") || !strcmp(l, "output")) log_output = new;
  410. #if IR
  411. if (!strcmp(l, "all") || !strcmp(l, "ir")) log_ir = new;
  412. #endif
  413. } else {
  414. fprintf(stderr, "\nDebug settings error: -d %s\n\n", optarg);
  415. usage(argv[0]);
  416. local_exit(1);
  417. }
  418. }
  419. break;
  420. case 'f':
  421. logfile = optarg;
  422. break;
  423. case 'm':
  424. {
  425. int byte = 0;
  426. char *tmp;
  427. if (!strncmp(optarg, "00:04:20", 8)) {
  428. LOG_ERROR("ignoring mac address from hardware player range 00:04:20:**:**:**");
  429. } else {
  430. char *t = strtok(optarg, ":");
  431. while (t && byte < 6) {
  432. mac[byte++] = (u8_t)strtoul(t, &tmp, 16);
  433. t = strtok(NULL, ":");
  434. }
  435. }
  436. }
  437. break;
  438. case 'M':
  439. modelname = optarg;
  440. break;
  441. case 'r':
  442. {
  443. char *rstr = next_param(optarg, ':');
  444. char *dstr = next_param(NULL, ':');
  445. if (rstr && strstr(rstr, ",")) {
  446. // parse sample rates and sort them
  447. char *r = next_param(rstr, ',');
  448. unsigned tmp[MAX_SUPPORTED_SAMPLERATES] = { 0 };
  449. int i, j;
  450. int last = 999999;
  451. for (i = 0; r && i < MAX_SUPPORTED_SAMPLERATES; ++i) {
  452. tmp[i] = atoi(r);
  453. r = next_param(NULL, ',');
  454. }
  455. for (i = 0; i < MAX_SUPPORTED_SAMPLERATES; ++i) {
  456. int largest = 0;
  457. for (j = 0; j < MAX_SUPPORTED_SAMPLERATES; ++j) {
  458. if (tmp[j] > largest && tmp[j] < last) {
  459. largest = tmp[j];
  460. }
  461. }
  462. rates[i] = last = largest;
  463. }
  464. } else if (rstr) {
  465. // optstr is <min>-<max> or <max>, extract rates from test rates within this range
  466. unsigned ref[] TEST_RATES;
  467. char *str1 = next_param(rstr, '-');
  468. char *str2 = next_param(NULL, '-');
  469. unsigned max = str2 ? atoi(str2) : (str1 ? atoi(str1) : ref[0]);
  470. unsigned min = str1 && str2 ? atoi(str1) : 0;
  471. unsigned tmp;
  472. int i, j;
  473. if (max < min) { tmp = max; max = min; min = tmp; }
  474. rates[0] = max;
  475. for (i = 0, j = 1; i < MAX_SUPPORTED_SAMPLERATES; ++i) {
  476. if (ref[i] < rates[j-1] && ref[i] >= min) {
  477. rates[j++] = ref[i];
  478. }
  479. }
  480. }
  481. if (dstr) {
  482. rate_delay = atoi(dstr);
  483. }
  484. if (rates[0]) {
  485. user_rates = true;
  486. }
  487. }
  488. break;
  489. case 's':
  490. server = optarg;
  491. break;
  492. case 'n':
  493. name = optarg;
  494. break;
  495. case 'N':
  496. namefile = optarg;
  497. break;
  498. case 'W':
  499. pcm_check_header = true;
  500. break;
  501. #if ALSA
  502. case 'p':
  503. rt_priority = atoi(optarg);
  504. if (rt_priority > 99 || rt_priority < 1) {
  505. fprintf(stderr, "\nError: invalid priority: %s\n\n", optarg);
  506. usage(argv[0]);
  507. exit(1);
  508. }
  509. break;
  510. #endif
  511. #if LINUX || FREEBSD || SUN
  512. case 'P':
  513. pidfile = optarg;
  514. break;
  515. #endif
  516. #if !CONFIG_DACAUDIO && !CONFIG_BTAUDIO
  517. case 'l':
  518. list_devices();
  519. exit(0);
  520. break;
  521. #endif
  522. #if RESAMPLE || RESAMPLE16
  523. case 'u':
  524. case 'R':
  525. if (optind < argc && argv[optind] && argv[optind][0] != '-') {
  526. resample = argv[optind++];
  527. } else {
  528. resample = "";
  529. }
  530. break;
  531. case 'Z':
  532. maxSampleRate = atoi(optarg);
  533. break;
  534. #endif
  535. #if DSD
  536. case 'D':
  537. dsd_outfmt = DOP;
  538. if (optind < argc && argv[optind] && argv[optind][0] != '-') {
  539. char *dstr = next_param(argv[optind++], ':');
  540. char *fstr = next_param(NULL, ':');
  541. dsd_delay = dstr ? atoi(dstr) : 0;
  542. if (fstr) {
  543. if (!strcmp(fstr, "dop")) dsd_outfmt = DOP;
  544. if (!strcmp(fstr, "u8")) dsd_outfmt = DSD_U8;
  545. if (!strcmp(fstr, "u16le")) dsd_outfmt = DSD_U16_LE;
  546. if (!strcmp(fstr, "u32le")) dsd_outfmt = DSD_U32_LE;
  547. if (!strcmp(fstr, "u16be")) dsd_outfmt = DSD_U16_BE;
  548. if (!strcmp(fstr, "u32be")) dsd_outfmt = DSD_U32_BE;
  549. if (!strcmp(fstr, "dop24")) dsd_outfmt = DOP_S24_LE;
  550. if (!strcmp(fstr, "dop24_3")) dsd_outfmt = DOP_S24_3LE;
  551. }
  552. }
  553. break;
  554. #endif
  555. #if VISEXPORT
  556. case 'v':
  557. visexport = true;
  558. break;
  559. #endif
  560. #if ALSA
  561. case 'O':
  562. mixer_device = optarg;
  563. break;
  564. case 'L':
  565. list_mixers(mixer_device);
  566. exit(0);
  567. break;
  568. case 'X':
  569. linear_volume = true;
  570. break;
  571. case 'U':
  572. output_mixer_unmute = true;
  573. case 'V':
  574. if (output_mixer) {
  575. fprintf(stderr, "-U and -V option should not be used at same time\n");
  576. exit(1);
  577. }
  578. output_mixer = optarg;
  579. break;
  580. #endif
  581. #if IR
  582. case 'i':
  583. if (optind < argc && argv[optind] && argv[optind][0] != '-') {
  584. lircrc = argv[optind++];
  585. } else {
  586. lircrc = "~/.lircrc"; // liblirc_client will expand ~/
  587. }
  588. break;
  589. #endif
  590. #if defined(GPIO) && defined(RPI)
  591. case 'G':
  592. if (power_script != NULL){
  593. fprintf(stderr, "-G and -S options cannot be used together \n\n" );
  594. usage(argv[0]);
  595. exit(1);
  596. }
  597. if (optind < argc && argv[optind] && argv[optind][0] != '-') {
  598. char *gp = next_param(argv[optind++], ':');
  599. char *go = next_param (NULL, ':');
  600. gpio_pin = atoi(gp);
  601. if (go != NULL){
  602. if ((strcmp(go, "H")==0)|(strcmp(go, "h")==0)){
  603. gpio_active_low=false;
  604. }else if((strcmp(go, "L")==0)|(strcmp(go, "l")==0)){
  605. gpio_active_low=true;
  606. }else{
  607. fprintf(stderr,"Must set output to be active High or Low i.e. -G18:H or -G18:L\n");
  608. usage(argv[0]);
  609. exit(1);
  610. }
  611. }else{
  612. fprintf(stderr,"-G Option Error\n");
  613. usage(argv[0]);
  614. exit(1);
  615. }
  616. gpio_active = true;
  617. relay(0);
  618. } else {
  619. fprintf(stderr, "Error in GPIO Pin assignment.\n");
  620. usage(argv[0]);
  621. exit(1);
  622. }
  623. break;
  624. #endif
  625. #if GPIO
  626. case 'S':
  627. if (gpio_active){
  628. fprintf(stderr, "-G and -S options cannot be used together \n\n" );
  629. usage(argv[0]);
  630. exit(1);
  631. }
  632. if (optind < argc && argv[optind] && argv[optind][0] != '-') {
  633. power_script = argv[optind++];
  634. if( access( power_script, R_OK|X_OK ) == -1 ) {
  635. // file doesn't exist
  636. fprintf(stderr, "Script %s, not found\n\n", argv[optind-1]);
  637. usage(argv[0]);
  638. exit(1);
  639. }
  640. } else {
  641. fprintf(stderr, "No Script Name Given.\n\n");
  642. usage(argv[0]);
  643. exit(1);
  644. }
  645. relay_script(0);
  646. break;
  647. #endif
  648. #if LINUX || FREEBSD || SUN
  649. case 'z':
  650. daemonize = true;
  651. #if SUN
  652. init_daemonize();
  653. #endif /* SUN */
  654. break;
  655. #endif
  656. case 't':
  657. license();
  658. local_exit(0);
  659. break; // mute compiler warning
  660. case '?':
  661. usage(argv[0]);
  662. local_exit(0);
  663. break; // mute compiler warning
  664. default:
  665. fprintf(stderr, "Arg error: %s\n", argv[optind]);
  666. break;
  667. }
  668. }
  669. // warn if command line includes something which isn't parsed
  670. if (optind < argc) {
  671. fprintf(stderr, "\nError: command line argument error\n\n");
  672. usage(argv[0]);
  673. local_exit(1);
  674. }
  675. signal(SIGINT, sighandler);
  676. signal(SIGTERM, sighandler);
  677. #if defined(SIGQUIT)
  678. signal(SIGQUIT, sighandler);
  679. #endif
  680. #if defined(SIGHUP)
  681. signal(SIGHUP, sighandler);
  682. #endif
  683. #if USE_SSL && !LINKALL
  684. ssl_loaded = load_ssl_symbols();
  685. #endif
  686. // set the output buffer size if not specified on the command line, take account of resampling
  687. if (!output_buf_size) {
  688. output_buf_size = OUTPUTBUF_SIZE;
  689. if (resample) {
  690. unsigned scale = 8;
  691. if (rates[0]) {
  692. scale = rates[0] / 44100;
  693. if (scale > 8) scale = 8;
  694. if (scale < 1) scale = 1;
  695. }
  696. output_buf_size *= scale;
  697. }
  698. }
  699. if (logfile) {
  700. if (!freopen(logfile, "a", stderr)) {
  701. fprintf(stderr, "error opening logfile %s: %s\n", logfile, strerror(errno));
  702. } else {
  703. if (log_output >= lINFO || log_stream >= lINFO || log_decode >= lINFO || log_slimproto >= lINFO) {
  704. fprintf(stderr, "\n%s\n", cmdline);
  705. }
  706. }
  707. }
  708. #if LINUX || FREEBSD || SUN
  709. if (pidfile) {
  710. if (!(pidfp = fopen(pidfile, "w")) ) {
  711. fprintf(stderr, "Error opening pidfile %s: %s\n", pidfile, strerror(errno));
  712. exit(1);
  713. }
  714. pidfile = realpath(pidfile, NULL); // daemonize will change cwd
  715. }
  716. if (daemonize) {
  717. if (daemon(0, logfile ? 1 : 0)) {
  718. fprintf(stderr, "error daemonizing: %s\n", strerror(errno));
  719. }
  720. }
  721. if (pidfp) {
  722. fprintf(pidfp, "%d\n", (int) getpid());
  723. fclose(pidfp);
  724. }
  725. #endif
  726. #if WIN
  727. winsock_init();
  728. #endif
  729. stream_init(log_stream, stream_buf_size);
  730. #ifdef EMBEDDED
  731. if(strstr(output_device,"BT")!=NULL || strstr(output_device,"bt")!=NULL) {
  732. output_init_bt(log_output, output_device, output_buf_size, output_params, rates, rate_delay, idle);
  733. }
  734. else if(strstr(output_device,"DAC")!=NULL || strstr(output_device,"dac")!=NULL){
  735. output_init_dac(log_output, output_device, output_buf_size, output_params, rates, rate_delay, idle);
  736. }
  737. #else
  738. if (!strcmp(output_device, "-")) {
  739. output_init_stdout(log_output, output_buf_size, output_params, rates, rate_delay);
  740. } else {
  741. #if ALSA
  742. output_init_alsa(log_output, output_device, output_buf_size, output_params, rates, rate_delay, rt_priority, idle, mixer_device, output_mixer,
  743. output_mixer_unmute, linear_volume);
  744. #endif
  745. #if PORTAUDIO
  746. output_init_pa(log_output, output_device, output_buf_size, output_params, rates, rate_delay, idle);
  747. #endif
  748. }
  749. #endif
  750. #if DSD
  751. dsd_init(dsd_outfmt, dsd_delay);
  752. #endif
  753. #if VISEXPORT
  754. if (visexport) {
  755. output_vis_init(log_output, mac);
  756. }
  757. #endif
  758. decode_init(log_decode, include_codecs, exclude_codecs);
  759. #if RESAMPLE || RESAMPLE16
  760. if (resample) {
  761. process_init(resample);
  762. }
  763. #endif
  764. #if IR
  765. if (lircrc) {
  766. ir_init(log_ir, lircrc);
  767. }
  768. #endif
  769. if (name && namefile) {
  770. fprintf(stderr, "-n and -N option should not be used at same time\n");
  771. local_exit(1);
  772. }
  773. slimproto(log_slimproto, server, mac, name, namefile, modelname, maxSampleRate);
  774. decode_close();
  775. stream_close();
  776. #if CONFIG_DACAUDIO
  777. output_close_dac();
  778. #elif CONFIG_BTAUDIO
  779. output_close_bt();
  780. #else
  781. if (!strcmp(output_device, "-")) {
  782. output_close_stdout();
  783. } else {
  784. #if ALSA
  785. output_close_alsa();
  786. #endif
  787. #if PORTAUDIO
  788. output_close_pa();
  789. #endif
  790. }
  791. #endif
  792. #if IR
  793. ir_close();
  794. #endif
  795. #if WIN
  796. winsock_close();
  797. #endif
  798. #if LINUX || FREEBSD || SUN
  799. if (pidfile) {
  800. unlink(pidfile);
  801. free(pidfile);
  802. }
  803. #endif
  804. #if USE_SSL && !LINKALL
  805. free_ssl_symbols();
  806. #endif
  807. local_exit(0);
  808. }