1 /*
2 mpg321 - a fully free clone of mpg123.
3 Copyright (C) 2001 Joe Drew
4
5 Originally based heavily upon:
6 plaympeg - Sample MPEG player using the SMPEG library
7 Copyright (C) 1999 Loki Entertainment Software
8
9 Also uses some code from
10 mad - MPEG audio decoder
11 Copyright (C) 2000-2001 Robert Leslie
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <math.h>
32 #include <libgen.h>
33 #include <signal.h>
34 #include <limits.h>
35 #include <sys/time.h>
36 #include <assert.h>
37
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 #include <unistd.h>
42 #include <sys/mman.h>
43
44 #include "getopt.h" /* GNU getopt is needed, so I included it */
45 #include "mpg321.h"
46
47 #include <id3tag.h>
48
49 int shuffle_play;
50 int stop_playing_file = 0;
51 int quit_now = 0;
52 char *playlist_file;
53 ao_device *playdevice=NULL;
54 mad_timer_t current_time;
55 mpg321_options options = { 0, NULL, NULL, 0 , 0, 0};
56 int status = MPG321_STOPPED;
57 int file_change = 0;
58
59 char *id3_get_tag (struct id3_tag const *tag, char const *what, unsigned int maxlen);
60
mpg123_boilerplate()61 void mpg123_boilerplate()
62 {
63 fprintf(stderr,"High Performance MPEG 1.0/2.0/2.5 Audio Player for Layer 1, 2, and 3.\n"
64 "Version " FAKEVERSION " (" VERSIONDATE "). Written and copyrights by Joe Drew.\n"
65 "Uses code from various people. See 'README' for more!\n"
66 "THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR OWN RISK!\n");
67 }
68
69 /* print the error in errno */
mpg321_error(char * file)70 void mpg321_error(char *file)
71 {
72 char *error = strerror(errno);
73 fprintf(stderr, "%s: %s\n",file, error);
74 }
75
usage(char * argv0)76 void usage(char *argv0)
77 {
78 mpg123_boilerplate();
79 fprintf(stderr,
80 "\nUsage: %s [options] file(s) | URL(s) | -\n\n"
81 "Options supported:\n"
82 " --verbose or -v Increase verbosity\n"
83 " --quiet or -q Quiet mode (no title or boilerplate)\n"
84 " --gain N or -g N Set gain (audio volume) to N (0-100)\n"
85 " --skip N or -k N Skip N frames into the file\n"
86 " --verbose or -v Be more verbose in playing files\n"
87 " -o dt Set output devicetype to dt\n"
88 " [esd,alsa(09),arts,sun,oss]\n"
89 " --audiodevice N or -a N Use N for audio-out\n"
90 " --stdout or -s Use stdout for audio-out\n"
91 " --au N Use au file N for output\n"
92 " --cdr N Use wave file N for output\n"
93 " --wav N or -w N Use wave file N for output\n"
94 " --test or -t Test only; do no audio output\n"
95 " --list N or -@ N Use playlist N as list of MP3 files\n"
96 " --random or -Z Play files randomly until interrupted\n"
97 " --shuffle or -z Shuffle list of files before playing\n"
98 " -R Use remote control interface\n"
99 " --aggressive Try to get higher priority\n"
100 " --help or --longhelp Print this help screen\n"
101 " --version or -V Print version information\n"
102 "\n"
103 "This version of mpg321 has been configured with " AUDIO_DEFAULT " as its default\n"
104 "libao output device.\n" , argv0);
105 }
106
107 /* retsigtype is defined by configure;
108 pass handle_signals -1 to initialize it */
handle_signals(int sig)109 RETSIGTYPE handle_signals(int sig)
110 {
111 static struct timeval last_signal = { 0, 0 };
112 struct timeval curr_tv;
113
114 gettimeofday(&curr_tv, NULL);
115
116 if (sig == SIGINT)
117 {
118 if (((curr_tv.tv_sec - last_signal.tv_sec) * 1000000 +
119 (curr_tv.tv_usec - last_signal.tv_usec)) < 1000000) /* Allow a short delay to
120 kill mpg321 */
121 {
122 quit_now = 1;
123 }
124
125 last_signal.tv_sec = curr_tv.tv_sec;
126 last_signal.tv_usec = curr_tv.tv_usec;
127
128 stop_playing_file = 1;
129 }
130 else if (sig == -1) /* initialize */
131 {
132 last_signal.tv_sec = curr_tv.tv_sec;
133 last_signal.tv_usec = curr_tv.tv_usec;
134 }
135 }
136
137 /*
138 Only shows ID3 tags if at least one of
139 TITLE, ARTIST, ALBUM, YEAR, COMMENT, GENRE
140 is present.
141 */
show_id3(struct id3_tag const * tag)142 static int show_id3(struct id3_tag const *tag)
143 {
144 unsigned int i;
145 int print = 0;
146 char emptystring[31];
147 char *names[6];
148 struct {
149 int index;
150 char const *id;
151 char const *name;
152 } const info[] = {
153 { 0, ID3_FRAME_TITLE, "Title : " },
154 { 1, ID3_FRAME_ARTIST, " Artist: " },
155 { 2, ID3_FRAME_ALBUM, "Album : " },
156 { 3, ID3_FRAME_YEAR, " Year : " },
157 { 4, ID3_FRAME_COMMENT,"Comment: " },
158 { 5, ID3_FRAME_GENRE, " Genre : " }
159 };
160
161 memset (emptystring, ' ', 30);
162 emptystring[30] = '\0';
163 /* Get ID3 tag if available, 30 chars except 4 for year */
164 for (i=0; i<=5; i++) {
165 names[i] = NULL;
166 names[i] = id3_get_tag(tag, info[i].id, (i==3) ? 4 : 30);
167 }
168 for (i=0; i<=5; i++) {
169 if (names[i]) {
170 print = 1;
171 break;
172 }
173 }
174 if (!print) {
175 return 0;
176 }
177
178 if (options.opt & MPG321_REMOTE_PLAY)
179 {
180 printf("@I ID3:");
181
182 for (i=0; i<=5; i++)
183 {
184 if(!names[i])
185 {
186 printf(emptystring);
187 }
188
189 else
190 {
191 printf("%s", names[i]);
192 free(names[i]);
193 }
194 }
195 printf("\n");
196 }
197
198 else
199 {
200 /* Emulate mpg123 original behaviour */
201 for (i=0; i<=5; i++) {
202 fprintf (stderr, "%s", info[i].name);
203 if (!names[i]) {
204 fprintf (stderr, emptystring);
205 } else {
206 fprintf (stderr, "%s", names[i]);
207 free (names[i]);
208 }
209 if (i%2) fprintf (stderr, "\n");
210 }
211 }
212
213 return 1;
214 }
215
main(int argc,char * argv[])216 int main(int argc, char *argv[])
217 {
218 int fd = 0;
219 char *currentfile, old_dir[PATH_MAX];
220 playlist *pl = NULL;
221 struct id3_file *id3struct = NULL;
222 struct id3_tag *id3tag = NULL;
223
224 buffer playbuf;
225
226 struct mad_decoder decoder;
227
228 old_dir[0] = '\0';
229
230 playbuf.pl = pl = new_playlist();
231
232 if (!pl)
233 {
234 fprintf(stderr, "malloc failed at startup!\n");
235 exit(1);
236 }
237
238 options.volume = MAD_F_ONE;
239
240 status = MPG321_PLAYING;
241
242 /* Get the command line options */
243 parse_options(argc, argv, pl);
244
245 /* If there were no files and no playlist specified just print the usage */
246 if (!playlist_file && optind == argc)
247 {
248 usage(argv[0]);
249 exit(0);
250 }
251
252 if (playlist_file)
253 load_playlist(pl, playlist_file);
254
255 add_cmdline_files(pl, argv);
256
257 if (shuffle_play)
258 shuffle_files(pl);
259
260 ao_initialize();
261
262 check_default_play_device();
263
264 if (!(options.opt & MPG321_REMOTE_PLAY))
265 {
266 handle_signals(-1); /* initialize signal handler */
267
268 remote_input_buf[0] = '\0';
269 }
270
271 if (!(options.opt & MPG321_QUIET_PLAY))
272 mpg123_boilerplate();
273
274 if (options.opt & MPG321_REMOTE_PLAY)
275 {
276 printf ("@R MPG123\n");
277 }
278
279 /* Play the mpeg files or zip it! */
280 while((currentfile = get_next_file(pl, &playbuf)))
281 {
282 if (quit_now)
283 break;
284
285 signal(SIGINT, SIG_DFL);
286
287 playbuf.buf = NULL;
288 playbuf.frames = NULL;
289 playbuf.times = NULL;
290 playbuf.fd = -1;
291 playbuf.length = 0;
292 playbuf.done = 0;
293 playbuf.num_frames = 0;
294 playbuf.max_frames = -1;
295 strncpy(playbuf.filename,currentfile, PATH_MAX);
296 playbuf.filename[PATH_MAX-1] = '\0';
297
298 if (status == MPG321_PLAYING)
299 file_change = 1;
300
301 mad_timer_reset(&playbuf.duration);
302
303 mad_timer_reset(¤t_time);
304
305 if (!(options.opt & MPG321_QUIET_PLAY) && file_change)
306 {
307 id3struct = id3_file_open (currentfile, ID3_FILE_MODE_READONLY);
308
309 if (id3struct)
310 {
311 id3tag = id3_file_tag (id3struct);
312
313 if (id3tag)
314 {
315 show_id3 (id3tag);
316 }
317
318 id3_file_close (id3struct);
319 }
320 }
321
322 if (options.opt & MPG321_REMOTE_PLAY && file_change)
323 {
324 id3struct = id3_file_open (currentfile, ID3_FILE_MODE_READONLY);
325
326 if (id3struct)
327 {
328 id3tag = id3_file_tag (id3struct);
329
330 if (id3tag)
331 {
332 if (!show_id3(id3tag))
333 {
334 /* This shouldn't be necessary, but it appears that
335 libid3tag doesn't necessarily know if there are no
336 id3 tags on a given mp3 */
337 char * basec = strdup(currentfile);
338 char * basen = basename(basec);
339
340 char * dot = strrchr(basen, '.');
341
342 if (dot)
343 *dot = '\0';
344
345 printf("@I %s\n", basen);
346
347 free(basec);
348 }
349 }
350
351 else
352 {
353 fprintf(stderr, "Allocation error");
354 exit(1);
355 }
356
357 id3_file_close (id3struct);
358 }
359
360 else
361 {
362 char * basec = strdup(currentfile);
363 char * basen = basename(basec);
364
365 char * dot = strrchr(basen, '.');
366
367 if (dot)
368 *dot = '\0';
369
370 printf("@I %s\n", basen);
371
372 free(basec);
373 }
374 }
375
376 /* Create the MPEG stream */
377 /* Check if source is on the network */
378 if((fd = raw_open(currentfile)) != 0 || (fd = http_open(currentfile)) != 0
379 || (fd = ftp_open(currentfile)) != 0)
380 {
381 playbuf.fd = fd;
382 playbuf.buf = malloc(BUF_SIZE);
383 playbuf.length = BUF_SIZE;
384
385 mad_decoder_init(&decoder, &playbuf, read_from_fd, read_header, /*filter*/0,
386 output, /*error*/0, /* message */ 0);
387 }
388
389 /* Check if we are to use stdin for input */
390 else if(strcmp(currentfile, "-") == 0)
391 {
392 playbuf.fd = fileno(stdin);
393 playbuf.buf = malloc(BUF_SIZE);
394 playbuf.length = BUF_SIZE;
395
396 mad_decoder_init(&decoder, &playbuf, read_from_fd, read_header, /*filter*/0,
397 output, /*error*/0, /* message */ 0);
398 }
399
400 /* currentfile is a local file (presumably.) mmap() it */
401 else
402 {
403 struct stat stat;
404
405 if((fd = open(currentfile, O_RDONLY)) == -1)
406 {
407 mpg321_error(currentfile);
408
409 /* mpg123 stops immediately if it can't open a file */
410 break;
411 }
412
413 if(fstat(fd, &stat) == -1)
414 {
415 close(fd);
416 mpg321_error(currentfile);
417 continue;
418 }
419
420 if (!S_ISREG(stat.st_mode))
421 {
422 close(fd);
423 continue;
424 }
425
426 calc_length(currentfile, &playbuf);
427
428 if ((options.maxframes != -1) && (options.maxframes <= playbuf.num_frames))
429 {
430 playbuf.max_frames = options.maxframes;
431 }
432
433 playbuf.frames = malloc((playbuf.num_frames + 1) * sizeof(void*));
434 playbuf.times = malloc((playbuf.num_frames + 1) * sizeof(mad_timer_t));
435
436 if((playbuf.buf = mmap(0, playbuf.length, PROT_READ, MAP_SHARED, fd, 0))
437 == MAP_FAILED)
438 {
439 close(fd);
440 mpg321_error(currentfile);
441 continue;
442 }
443
444 playbuf.frames[0] = playbuf.buf;
445
446 mad_decoder_init(&decoder, &playbuf, read_from_mmap, read_header, /*filter*/0,
447 output, /*error*/0, /* message */ 0);
448 }
449
450 if(!(options.opt & MPG321_QUIET_PLAY))/*zip it!!!*/
451 {
452 /* Because dirname might modify the argument */
453 char * dirc = strdup(currentfile);
454 char * basec = strdup(currentfile);
455
456 char * basen = basename(basec);
457 char * dirn = dirname(dirc);
458
459 /* make sure that the file has a pathname; otherwise don't print out
460 a Directory: listing */
461 if(strchr(currentfile, '/') && strncmp(old_dir, dirn, PATH_MAX) != 0)
462 {
463 /* Print information about the file */
464 fprintf(stderr, "\n");
465 fprintf(stderr,"Directory: %s/\n", dirn);
466
467 strncpy(old_dir, dirn, PATH_MAX);
468 old_dir[PATH_MAX-1] = '\0';
469 }
470
471 /* print a newline between different songs only, not after
472 Directory: listing */
473 else
474 {
475 fprintf(stderr, "\n");
476 }
477
478 fprintf(stderr,"Playing MPEG stream from %s ...\n", basen);
479
480 free(dirc);
481 free(basec);
482 }
483
484 signal(SIGINT, handle_signals);
485
486 /* Every time the user gets us to rewind, we exit decoding,
487 reinitialize it, and re-start it */
488 while (1)
489 {
490 mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);
491
492 /* if we're rewinding on an mmap()ed stream */
493 if(status == MPG321_REWINDING && playbuf.fd == -1)
494 {
495 mad_decoder_init(&decoder, &playbuf, read_from_mmap, read_header, /*filter*/0,
496 output, /*error*/0, /* message */ 0);
497 }
498 else
499 break;
500 }
501
502 if (!(options.opt & MPG321_QUIET_PLAY))
503 {
504 char time_formatted[11];
505 mad_timer_string(current_time, time_formatted, "%.1u:%.2u", MAD_UNITS_MINUTES,
506 MAD_UNITS_SECONDS, 0);
507 fprintf(stderr, "\n[%s] Decoding of %s finished.\n",time_formatted, basename(currentfile));
508 }
509
510 if (options.opt & MPG321_REMOTE_PLAY && status == MPG321_STOPPED)
511 {
512 clear_remote_file(pl);
513 }
514
515 mad_decoder_finish(&decoder);
516
517 if (playbuf.frames)
518 free(playbuf.frames);
519
520 if (playbuf.times)
521 free(playbuf.times);
522
523 if (playbuf.fd == -1)
524 {
525 munmap(playbuf.buf, playbuf.length);
526 close(fd);
527 }
528
529 else
530 {
531 free(playbuf.buf);
532 if (playbuf.fd != fileno(stdin))
533 close(playbuf.fd);
534 }
535 }
536
537 if(playdevice)
538 ao_close(playdevice);
539
540 ao_shutdown();
541
542 return(0);
543 }
544
545
546 /* Convenience for retrieving already formatted id3 data
547 * what parameter is one of
548 * ID3_FRAME_TITLE
549 * ID3_FRAME_ARTIST
550 * ID3_FRAME_ALBUM
551 * ID3_FRAME_YEAR
552 * ID3_FRAME_COMMENT
553 * ID3_FRAME_GENRE
554 * It allocates a new string. Free it later.
555 * NULL if no tag or error.
556 */
id3_get_tag(struct id3_tag const * tag,char const * what,unsigned int maxlen)557 char *id3_get_tag (struct id3_tag const *tag, char const *what, unsigned int maxlen)
558 {
559 struct id3_frame const *frame = NULL;
560 union id3_field const *field = NULL;
561 int nstrings;
562 int avail;
563 int j;
564 int tocopy;
565 int len;
566 char printable [1024];
567 char *retval = NULL;
568 id3_ucs4_t const *ucs4 = NULL;
569 id3_latin1_t *latin1 = NULL;
570
571 memset (printable, '\0', 1024);
572 avail = 1024;
573 if (strcmp (what, ID3_FRAME_COMMENT) == 0)
574 {
575 /*There may be sth wrong. I did not fully understand how to use
576 libid3tag for retrieving comments */
577 j=0;
578 frame = id3_tag_findframe(tag, ID3_FRAME_COMMENT, j++);
579 if (!frame) return (NULL);
580 ucs4 = id3_field_getfullstring (&frame->fields[3]);
581 if (!ucs4) return (NULL);
582 latin1 = id3_ucs4_latin1duplicate (ucs4);
583 if (!latin1 || strlen(latin1) == 0) return (NULL);
584 len = strlen(latin1);
585 if (avail > len)
586 tocopy = len;
587 else
588 tocopy = 0;
589 if (!tocopy) return (NULL);
590 avail-=tocopy;
591 strncat (printable, latin1, tocopy);
592 free (latin1);
593 }
594
595 else
596 {
597 frame = id3_tag_findframe (tag, what, 0);
598 if (!frame) return (NULL);
599 field = &frame->fields[1];
600 nstrings = id3_field_getnstrings(field);
601 for (j=0; j<nstrings; ++j)
602 {
603 ucs4 = id3_field_getstrings(field, j);
604 if (!ucs4) return (NULL);
605 if (strcmp (what, ID3_FRAME_GENRE) == 0)
606 ucs4 = id3_genre_name(ucs4);
607 latin1 = id3_ucs4_latin1duplicate(ucs4);
608 if (!latin1) break;
609 len = strlen(latin1);
610 if (avail > len)
611 tocopy = len;
612 else
613 tocopy = 0;
614 if (!tocopy) break;
615 avail-=tocopy;
616 strncat (printable, latin1, tocopy);
617 free (latin1);
618 }
619 }
620 retval = malloc (maxlen + 1);
621 if (!retval) return (NULL);
622
623 strncpy (retval, printable, maxlen);
624 retval[maxlen] = '\0';
625
626 len = strlen(printable);
627 if (maxlen > len)
628 {
629 memset (retval + len, ' ', maxlen - len);
630 }
631
632 return (retval);
633 }
634