Return to BSD News archive
Path: sserve!newshost.anu.edu.au!munnari.oz.au!bruce.cs.monash.edu.au!harbinger.cc.monash.edu.au!msunews!uwm.edu!vixen.cso.uiuc.edu!howland.reston.ans.net!Germany.EU.net!news.dfn.de!zeus.rbi.informatik.uni-frankfurt.de!terra.wiwi.uni-frankfurt.de!news.th-darmstadt.de!zib-berlin.de!math.fu-berlin.de!fub!kwcom1.in-berlin.de!kwcom.in-berlin.de!matthaei From: matthaei@kwcom.in-berlin.de (Olaf Matthaei) Newsgroups: comp.os.386bsd.questions Subject: Re: S: utree and cdplayer Date: 28 Dec 1994 18:01:22 +0100 Organization: Public access FreeBSD system, 15711 Koenigs Wusterhausen, DE Lines: 501 Message-ID: <3ds5l2$23v@kwcom.in-berlin.de> References: <3dkg8l$j6h@kwcom.in-berlin.de> NNTP-Posting-Host: kwcom.in-berlin.de X-Newsreader: TIN [version 1.2 PL2] Olaf Matthaei (matthaei@kwcom.in-berlin.de) wrote: : Hi ! : Does anyone know, where I can find utree and cdplayer (not xcdplayer) : packages for FreeBSD 2.0 ? OK here is the source for the textbased cdplayer: ---------------------------------------------------------- /* * (#)@ cdplayer.c * * Stand Alone Non X CD Player module * * */ #include <stdio.h> #include <sys/file.h> #include <sys/cdio.h> #include <sys/ioctl.h> #define MITSUMI #ifndef DEVICE #ifdef MITSUMI #define DEVICE "/dev/rmcd0a" #else #define DEVICE "/dev/rcd0a" #endif #endif #define command(s) strncmp(cmd,s,strlen(s))==0 /* * CD Player Shared Data (define the pointers here... Use malloc() to * create the actual data areas. */ #define TOC_ENTRIES 64 static struct cd_toc_entry toc_buffer[TOC_ENTRIES]; static struct cd_sub_channel_info *s; int cd_fd = -1; int been_here = 0; int standalone; char cmd[132]; int pause (); int resume (); int stop (); int eject (); int setvol (int, int, int, int); int read_toc_header (); int read_toc_entry (int); int play_msf (int, int, int, int, int, int); int play_track (int, int, struct ioc_toc_header *); int get_vol (int *, int *); u_char status (); int input (); void open_cd (); void usage(); void disp_status(int); void disp_subchan(); u_char trk, hrs, min, sec, frame; u_char t_trk, t_hrs, t_min, t_sec, t_frame; int start, end; char toggle[20]; int debug_flag; int m1, m2, s1, s2, f1, f2; int l, r, lo, ro; main (int argc, char **argv) { int rc, i; int min, sec; char volc[12]; struct ioc_toc_header h; s =(struct cd_sub_channel_info *)malloc(sizeof(struct cd_sub_channel_info)); standalone = isatty(0); while (been_here == 0 && input (argc, argv)) { open_cd (); for (i=0; i < strlen(cmd); cmd[i]=tolower(cmd[i]),i++); if (command ("play")) { sscanf (cmd+4, "%d %d", &start, &end); read_toc_header (&h); play_track (start, end, &h); } else if (command ("msfplay")) { sscanf(cmd+7, "%d %d %d %d %d %d", &m1, &s1, &f1, &m2, &s2, &f2); play_msf (m1, s1, f1, m2, s2, f2); } else if (command ("status")) { disp_status(argc); } else if (command ("debug")) { sscanf (cmd+5, "%3s", &toggle); if (strcmp("on",toggle) == 0) { debug_flag = 1; (void)ioctl(cd_fd,CDIOCSETDEBUG); } if (strcmp("off",toggle) == 0) { debug_flag = 0; (void)ioctl(cd_fd,CDIOCCLRDEBUG); } } else if (command ("pause")) pause (); else if (command ("resume")) resume (); else if (command ("stop")) { stop (); } else if (command ("eject")) { eject (); } else if (command ("vol")) { sscanf (cmd+3, "%s", volc); if (strcmp("mono",volc) == 0) { (void)ioctl(cd_fd,CDIOCSETMONO); } else if (strcmp("stereo",volc) == 0) { (void)ioctl(cd_fd,CDIOCSETSTERIO); } else if (strcmp("mute",volc) == 0) { (void)ioctl(cd_fd,CDIOCSETMUTE); } else if (strcmp("left",volc) == 0) { (void)ioctl(cd_fd,CDIOCSETLEFT); } else if (strcmp("right",volc) == 0) { (void)ioctl(cd_fd,CDIOCSETRIGHT); } else { (void)ioctl(cd_fd,CDIOCSETSTERIO); } } else if (command ("setvol")) { sscanf (cmd+6, "%d %d %d %d", &l, &r, &lo, &ro); setvol (l, r, lo, ro); } else if (command ("getvol")) { struct ioc_vol volume; for (i = 0; i < 4; i++) volume.vol[i] = 0; getvol(&volume); printf ("%d %d %d %d\n", volume.vol[0], volume.vol[2], volume.vol[1], volume.vol[3]); } else if (command ("subchan")) { disp_subchan(); } else if (command ("status")) { disp_status(argc); } else if (command ("tochdr")) { read_toc_header (&h); printf ("%d %d %d\n", h.len, h.starting_track, h.ending_track); } else if (command ("tocentry")) { int i,n; read_toc_header (&h); n = h.ending_track - h.starting_track + 1; read_toc_entry(n); printf("Track\tStart Time\tDuration\n"); for (i = 0; toc_buffer[i].track < 110 && i < h.ending_track; i++) { /*printf ("%3d\t%5d:%02d", toc_buffer[i].track, toc_buffer[i].addr[1], toc_buffer[i].addr[2]); min = toc_buffer[i+1].addr[1] - toc_buffer[i].addr[1]; sec = toc_buffer[i+1].addr[2] - toc_buffer[i].addr[2]; if (sec < 0)*/ { sec += 60; min --; } if (min < 0) { sec = 0; min = 0; } printf ("\t%5d:%02d",min,sec); if (debug_flag) printf ("\t%d %d",toc_buffer[i].control, toc_buffer[i].addr_type); putchar('\n'); status(); } } else if (command("reset")) { do_reset(); } else if (command("help")) { usage(); } else if (command("quit")) { break; } else if (command("exit")) break; fflush (stdout); close (cd_fd); cd_fd = -1; } exit (0); } /* Display a help message */ void usage() { printf("Text based CD Player\n"); printf(" play b e : Play a CD.\n"); printf(" where b is the starting track \n"); printf(" and e is the ending track.\n"); printf(" msfplay bm bs bf em es ef \n"); printf(" : Play a CD.\n"); printf(" debug [on|off]\n"); printf(" : Turn kernel debug output on or off.\n"); printf(" pause : Pause the current playing CD.\n"); printf(" resume : Resume playing a CD.\n"); printf(" stop : Stop the current CD.\n"); printf(" tochdr : Get CD Time and track numbers.\n"); printf(" tocentry : Get Table of Contents for CD.\n"); printf(" getvol : Get the Volume Information.\n"); printf(" setvol : Set the Volume Information.\n"); printf(" vol {mono, stereo, mute, left, right}\n"); printf(" : Set Volume Control Functions.\n"); printf(" eject : Eject the current CD (if supported).\n"); printf(" status : Display the current CD status.\n"); printf(" quit : Get out of here (does not stop CD).\n"); } /* Display the Volume Information */ void disp_subchan() { struct ioc_read_subchannel subchan; struct cd_sub_channel_info subdata; int i; subchan.data_format = CD_MEDIA_CATALOG; subchan.address_format = CD_MSF_FORMAT; subchan.data_len = sizeof(struct cd_sub_channel_info); subchan.data = &subdata; ioctl (cd_fd, CDIOCREADSUBCHANNEL, &subchan); printf("Valid Catalog: %s\n", (subdata.what.media_catalog.mc_valid) ? "Yes" : "No"); printf("Data Format: %d\n", subdata.what.media_catalog.data_format); printf("Track Numbers: %d\n", bcd2bin(subdata.what.media_catalog.mc_number[0])); for (i = 1; i < 15; i++) printf(" %d\n", bcd2bin(subdata.what.media_catalog.mc_number[i])); printf("Audio Status: %d\n", subdata.header.audio_status); } /* Display a reasonable status output */ void disp_status(argc) { u_char rc; char stat_str[40]; if (cd_fd <= 0) rc = -1; else rc = status (); switch (rc) { case CD_AS_AUDIO_INVALID : strcpy(stat_str,"Audio invalid"); break; case CD_AS_PLAY_IN_PROGRESS : strcpy(stat_str,"Playing."); break; case CD_AS_PLAY_PAUSED : strcpy(stat_str,"Paused."); break; case CD_AS_PLAY_COMPLETED : strcpy(stat_str,"Play complete."); break; case CD_AS_PLAY_ERROR : strcpy(stat_str,"Play error."); break; case CD_AS_NO_STATUS : strcpy(stat_str,"No status available."); break; default : printf("rc = %d\n",rc); strcpy(stat_str,"rc error."); break; } printf ("%-40s\n", stat_str); printf ("Track: %02d%50s\n", trk," "); printf ("Current Time: %02d:%02d%40s\n", min, sec, " "); /* This hack is because the 'total time' is the time at the point of the CD we are at, including the dead time at the beginning. This is usually off by about 2 seconds, so we will just assume that this is true until I change it later. */ if (t_sec < 2) { t_sec += 58; t_min--; } else { t_sec -= 2; } printf ("Total Time: %02d:%02d%40s\n", t_min, t_sec, " "); } /* * play CD tracks <start> through <end> */ int play_track (int start, int end, struct ioc_toc_header *h) { struct ioc_play_track t; if (start < 1) { t.start_track = h->starting_track; } else { t.start_track = (u_char)start; } if (end < t.start_track) { t.end_track = h->ending_track; } else { t.end_track = (u_char)end; } t.start_index = (u_char)1; t.end_index = (u_char)1; return ioctl (cd_fd, CDIOCPLAYTRACKS, &t); } int pause () { return ioctl (cd_fd, CDIOCPAUSE); } int resume () { return ioctl (cd_fd, CDIOCRESUME); } int stop () { return ioctl (cd_fd, CDIOCSTOP); } int eject () { return ioctl (cd_fd, CDIOCEJECT); } int do_reset () { return ioctl (cd_fd, CDIOCRESET); } int setvol (int l, int r, int lo, int ro) { struct ioc_vol v; v.vol[0] = l; v.vol[1] = r; v.vol[2] = lo; v.vol[3] = ro; return ioctl (cd_fd, CDIOCSETVOL, &v); } int getvol (struct ioc_vol *v) { return ioctl (cd_fd, CDIOCGETVOL, v); } int read_toc_header (struct ioc_toc_header *h) { struct ioc_toc_header toc_head; int ioctl_ret; ioctl_ret = ioctl (cd_fd, CDIOREADTOCHEADER, &toc_head); h->len = toc_head.len; h->starting_track = toc_head.starting_track; h->ending_track = toc_head.ending_track; return ioctl_ret; } int read_toc_entry (int n) { struct ioc_read_toc_entry toc; if (n > TOC_ENTRIES) n = TOC_ENTRIES; toc.address_format = CD_MSF_FORMAT; toc.starting_track = 1; toc.data_len = sizeof(struct cd_toc_entry)*n; toc.data = toc_buffer; return ioctl (cd_fd, CDIOREADTOCENTRYS, &toc); } int play_msf (int start_m, int start_s, int start_f, int end_m, int end_s, int end_f) { struct ioc_play_msf a; a.start_m = start_m; a.start_s = start_s; a.start_f = start_f; a.end_m = end_m; a.end_s = end_s; a.end_f = end_f; return ioctl (cd_fd, CDIOCPLAYMSF, &a); } u_char status () { /* Set up ioc_read_subchannel structure */ struct ioc_read_subchannel pos; struct cd_sub_channel_info subchan; pos.address_format = CD_MSF_FORMAT; pos.data_format = CD_CURRENT_POSITION; pos.track = 0; pos.data_len = sizeof(struct cd_sub_channel_info); pos.data = &subchan; if (ioctl (cd_fd, CDIOCREADSUBCHANNEL, &pos) < 0) return -1; *s = subchan; trk = pos.data->what.position.track_number; /*hrs = pos.data->what.position.reladdr[0]; min = pos.data->what.position.reladdr[1]; sec = pos.data->what.position.reladdr[2]; t_hrs = pos.data->what.position.absaddr[0]; t_min = pos.data->what.position.absaddr[1]; t_sec = pos.data->what.position.absaddr[2]; t_frame = pos.data->what.position.absaddr[3]; */ return pos.data->header.audio_status; } int input (int argc, char **argv) { size_t len; int i; cmd[0] = '\0'; if (argc > 1 && been_here == 0) { for (i = 1; i < argc; i++) { strcat(cmd, argv[i]); strcat(cmd," "); } been_here = -1; } else { if (standalone) { fprintf(stderr, "CD>"); } strncpy(cmd,fgetln(stdin, &len),131); } return cmd[0] != '\0'; } void open_cd () { if (cd_fd > -1) return; cd_fd = open (DEVICE, O_RDONLY); if (cd_fd < 0) { perror("open"); exit (1); } } int bcd2bin(u_char x) { return ((x & 0xf0 >> 4) * 10 + ( x & 0x0f)); } ------------------------------------------------------------ : -- : Mfg : +----------------------------+-------------------------+--------------------+ : | Olaf Matthaei | root@kwcom.in-berlin.de | FreeBSD 2.0 | : | Luckenwalderstrasse 38 +-------------------------+--------------------+ : | 15711 KOENIGSWUSTERHAUSEN | Line 1: +49 3375 291894 ELSA 28800 V.34 | : | KW-COMMUNICATION, Germany | Line 2: +49 3375 292702 YORIKO 28.8 V.FC | : +----------------------------+----------------------------------------------+ -- Mfg +----------------------------+-------------------------+--------------------+ | Olaf Matthaei | root@kwcom.in-berlin.de | FreeBSD 2.0 | | Luckenwalderstrasse 38 +-------------------------+--------------------+ | 15711 KOENIGSWUSTERHAUSEN | Line 1: +49 3375 291894 ELSA 28800 V.34 | | KW-COMMUNICATION, Germany | Line 2: +49 3375 292702 YORIKO 28.8 V.FC | +----------------------------+----------------------------------------------+