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(&current_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