/* cda.c * * Minimalistic command line CD player using libcda. Written for Linux * systems, but should work on others with a little help. * * Peter Wang */ #include #include #include #include #include #include #define VERSION "cda -- Copyright 2000, 2002 Peter Wang (tjaden@users.sourceforge.net)" static void fatal (const char *fmt, ...) { va_list ap; va_start (ap, fmt); vfprintf (stderr, fmt, ap); va_end (ap); exit (EXIT_FAILURE); } static void cd_fatal (const char *s) { fatal ("%s: %s\n", s, cd_error); } static int t0, t1; static void get_track_info () { if (cd_get_tracks (&t0, &t1)) cd_fatal ("cd_get_tracks"); } static void show_usage () { printf (VERSION "\n" "Interface pinched from dcd by dave@technopagan.org\n" "Usage: cda [command | tracks]\n" "\t d dir lists the CD directory\n" "\t e eject opens the CD tray\n" "\t c close closes the CD tray\n" "\t h help displays this message\n" "\t i info minimal info on the current CD\n" "\t p pause pause/resume the CD\n" "\t s stop stops the CD player\n" "\t v version displays the software revision/patchlevel\n" "\t f forward play the next track on CD\n" "\t b back play the previous track on CD\n" "\t r random play random track from the CD\n" "\t B background run in background and play random tracks\n"); } static void show_version () { printf (VERSION "\n"); } static void show_toc () { int i; get_track_info (); printf ("Track Type (%d tracks)\n", t1 - t0 + 1); for (i = t0; i <= t1; i++) printf (" %2d %s\n", i, cd_is_audio (i) ? "Audio" : "Data"); } static void show_info () { int i; get_track_info (); i = cd_current_track (); if (i > 0) printf ("Playing track %d (%d tracks)\n", i, t1 - t0 + 1); else printf ("Not playing (%d tracks)\n", t1 - t0 + 1); } static void pause_resume () { if (cd_is_paused ()) cd_resume (); else if (cd_current_track ()) cd_pause (); } static void forward_track () { int i, j; get_track_info (); j = cd_current_track (); if (!j) i = j = t0; else { i = j + 1; if (i > t1) i = t0; } while (1) { if (cd_is_audio (i)) { cd_play_from (i); break; } if (++i > t1) i = t0; if (i == j) fatal ("No audio tracks on CD.\n"); } } static void back_track () { int i, j; get_track_info (); j = i = cd_current_track (); if (!j) j = i = t0; while (1) { if (--i < t0) i = t1; if (i == j) break; if (cd_is_audio (i)) { cd_play_from (i); break; } } if (i == j) fatal ("No audio tracks on CD.\n"); } static void random_track (int one_only) { int i; get_track_info (); for (i = t0; i <= t1; i++) if (cd_is_audio (i)) break; if (i == t1 + 1) fatal ("No audio tracks on CD.\n"); srand (time (NULL)); while (1) if (cd_is_audio ((i = (rand () % (t1 + 1 - t0)) + t0))) { if (one_only) cd_play (i); else cd_play_from (i); break; } } static void background_mode () { while (1) { if (!cd_current_track () && !cd_is_paused ()) random_track (1); sleep (5); } } static int option (const char *arg, const char *o1, const char *o2) { return (o1 && !strcmp (arg, o1)) || (o2 && !strcmp (arg, o2)); } int main (int argc, char *argv[]) { int i; char *arg; if (cd_init ()) cd_fatal ("cd_init"); /* Command line options. */ for (i = 1; i < argc; i++) { arg = argv[i]; while (*arg && *arg == '-') arg++; if (option (arg, "d", "dir")) show_toc (); else if (option (arg, "e", "eject")) cd_eject (); else if (option (arg, "c", "close")) cd_close (); else if (option (arg, "h", "help")) show_usage (); else if (option (arg, "i", "info")) show_info (); else if (option (arg, "p", "pause")) pause_resume (); else if (option (arg, "s", "stop")) cd_stop (); else if (option (arg, "v", "version")) show_version (); else if (option (arg, "f", "forward")) forward_track (); else if (option (arg, "b", "back")) back_track (); else if (option (arg, "r", "random")) random_track (0); else if (option (arg, "B", "background")) background_mode (); else { int i = atoi (arg); if (i) { if (cd_is_audio (i) > 0) cd_play_from (i); else fatal ("Track %d is not audio or out of range\n", i); } else fatal ("Unrecognised option `%s'\n", arg); } } /* No command line options: play first audio track. */ if (argc < 2) { cd_stop (); forward_track (); } cd_exit (); return EXIT_SUCCESS; } /* * end of cda.c * * 9 June 2000 - First version * 14 June 2000 - Fixed problem trying to play no-audio CDs * 4 Nov 2000 - "Forward" skipped first track if not already playing * 29 Aug 2002 - Added "background" mode * 1 Sep 2002 - Fixed an oops in background mode */