home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!crdgw1!rpi!usc!elroy.jpl.nasa.gov!nntp-server.caltech.edu!draco.macsch.com!portia.si.macsch.com!bnc
- From: bnc@portia.si.macsch.com (Brian Casey)
- Newsgroups: comp.unix.aix
- Subject: Re: CD-ROM for audio
- Keywords: CD-ROM, Audio
- Message-ID: <1993Jan27.182449.13574@draco.macsch.com>
- Date: 27 Jan 93 18:24:49 GMT
- References: <1993Jan26.163734.9839@news.unige.ch> <Jan26.174131.54628@yuma.ACNS.ColoState.EDU>
- Sender: usenet@draco.macsch.com (Usenet Poster)
- Organization: The MacNeal-Schwendler Corporation
- Lines: 657
-
- In article <Jan26.174131.54628@yuma.ACNS.ColoState.EDU> copeland@lamar.ColoState.EDU (Jeffrey Copeland) writes:
- >
- >I started to convert xcdplayer, but gave up. Since I'm also root I just use
- >play. The problem (If I can remember) was in trying to find register and/or
- >port flags/addresses for the cd-rom. If someone could get ahold of the source
- >code for IBM's play it shouldn't be too difficult, I just couldn't
- >locate the appropriate header files.
- >
- >Jeff Copeland -- Atmospheric Science
-
-
-
- Attached is the source code to a very basic version of an audio CD player
- for the IBM RISC System/6000. Although in its current state, this code
- only plays a CD from beginning to end, the source includes functions that
- could be used to add a lot of additional features.
-
- If you name this file playcd.c, you can compile and link it using the
- following command:
-
- make playcd
-
- After creating the executable, you must change the owner to root, and
- change the mode to setuid; only root has privileges to access the CD
- drive for audio functions.
-
- One favor - if you put together a full featured program, please send me
- a copy. I like to see how other people do things like this. Thanks.
-
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys/ioctl.h>
- #include <sys/cdrom.h>
- #include <signal.h>
- #include <setjmp.h>
- #include <math.h>
-
-
- #define STRAIGHT 1
- #define STRAIGHT2 2
- #define RANDOM 3
- #define PROGRAMMED 4
- #define HALT 5
-
- #define CD_POSITION 0xC0
- #define CD_PLAYAUDIO 0xC1
- #define CD_PAUSE 0xC2
- #define CD_OPEN 0xC4
- #define CD_CLOSE 0xC5
- #define CD_SENSE 0xC6
- #define CD_READINFO 0xC7
-
- #define PSEUDOHEX(i) ( ((i)/10) * 16 + ((i) % 10) )
- #define REALHEX(i) ( (((i) & 0xf0) >> 4) * 10 + ( (i) & 0x0f) )
-
- #define True 1
- #define False 0
-
- typedef int Boolean;
-
- int fd = -1;
-
- int TrackInfo[100];
- int local_time[100];
- char rsbuf[4];
- char pingbuf[10];
-
- int ping_track();
- void play_same();
- void Oops() ;
- Boolean test_unit_ready();
-
- typedef enum { Mute=0, Left_channel=1, Right_channel=2, Stereo=3 }
- Play_mode_type;
- Play_mode_type Last_play_mode = Stereo;
-
- /******************************************************************************/
-
- int ping_track()
- {
- struct sc_iocmd pt;
- int i, rc;
-
- for (i = 0; i < 10; i++)
- pingbuf[i] = 0xAA;
- pt.command_length = 0x0A;
- pt.scsi_cdb[0] = CD_SENSE;
- pt.scsi_cdb[1] = 0x09;
- for (i = 3 ; i < 9 ; i++) {
- pt.scsi_cdb[i] = 0x00;
- }
-
- pt.flags = 0x08 | B_READ;
- pt.buffer = pingbuf;
- pt.data_length = 0x0A;
- pt.timeout_value = 0x05;
- pt.status_validity = 0x00;
- pt.scsi_bus_status = 0x00;
- pt.adapter_status = 0x00;
-
- rc = ioctl(fd, CDIOCMD, &pt);
- return(pingbuf[0]);
- }
-
- /******************************************************************************/
-
- int play_straight(track)
- uchar track;
- {
- struct sc_iocmd pt;
- int i, rc;
-
- if (test_unit_ready()==False) {
- Oops(&pt);
- }
- /* issue the play command */
- pt.command_length = 0x0A;
- pt.scsi_cdb[0] = CD_POSITION;
- pt.scsi_cdb[1] = 0x00; /* Do not play right away - pause after search */
- pt.scsi_cdb[2] = PSEUDOHEX(track);
- for (i = 3 ; i < 9 ; i ++) {
- pt.scsi_cdb[i] = 0x00;
- }
- pt.scsi_cdb[9] = 0x80; /* Position to given track */
- pt.flags = SC_ASYNC;
- pt.buffer = NULL;
- pt.data_length = 0x00;
- pt.timeout_value = 0x05;
- pt.status_validity = 0x00;
- pt.scsi_bus_status = 0x00;
- pt.adapter_status = 0x00;
- rc = ioctl(fd, CDIOCMD, &pt);
- if (rc == -1) {
- Oops(&pt);
- } else {
- play_same();
- }
- }
-
- /******************************************************************************/
-
- get_times(min, max, new_max)
- int min, max;
- int *new_max;
- {
- struct sc_iocmd pt;
- int i, rc;
- int max_flag = 1;
- int track_loop;
- int time_loop;
- int minutes = 0;
- int seconds = 0;
-
- if (test_unit_ready()==False) {
- Oops(&pt);
- return(-1);
- }
-
- /* issue the read disc info command */
- pt.command_length = 0x0A;
- pt.scsi_cdb[0] = CD_READINFO;
- pt.scsi_cdb[1] = 0x02;
- for (i = 3 ; i < 9 ; i ++) {
- pt.scsi_cdb[i] = 0x00;
- }
-
- pt.scsi_cdb[9] = 0x80;
- pt.flags = 0x08 | B_READ;
- pt.buffer = rsbuf;
- pt.data_length = 0x04;
- pt.timeout_value = 0x05;
- pt.status_validity = 0x00;
- pt.scsi_bus_status = 0x00;
- pt.adapter_status = 0x00;
-
- local_time[0] = 0;
- for (track_loop = min; track_loop <= max; track_loop++) {
- pt.scsi_cdb[2] = PSEUDOHEX(track_loop);
-
- for (i = 0; i < 4; i++)
- rsbuf[i] = 0x00;
-
- rc = ioctl(fd, CDIOCMD, &pt);
-
- minutes = REALHEX(rsbuf[0]);
- seconds = REALHEX(rsbuf[1]);
-
- if (rc == -1) {
- minutes = -1;
- seconds = -1;
- scanf("%d",&i);
- if (max_flag) {
- *new_max = track_loop - 1;
- max_flag = 0;
- }
- }
-
- local_time[track_loop] = 60 * minutes + seconds;
- }
-
- /* For the last track, we must get the total disk time to determine its
- * length
- */
-
- /* issue the read disc info command */
- pt.command_length = 0x0A;
- pt.scsi_cdb[0] = CD_READINFO;
- pt.scsi_cdb[1] = 0x01;
- for (i = 3 ; i < 9 ; i ++) {
- pt.scsi_cdb[i] = 0x00;
- }
-
- pt.flags = 0x08 | B_READ;
- pt.buffer = rsbuf;
- pt.data_length = 0x04;
- pt.timeout_value = 0x05;
- pt.status_validity = 0x00;
- pt.scsi_bus_status = 0x00;
- pt.adapter_status = 0x00;
- rc = ioctl(fd, CDIOCMD, &pt);
-
- minutes = REALHEX(rsbuf[0]);
- seconds = REALHEX(rsbuf[1]);
-
- local_time[max+1] = 60 * minutes + seconds;
-
-
- for (track_loop = min; track_loop <= max; track_loop++)
- TrackInfo[track_loop] = local_time[track_loop + 1] - local_time[track_loop];
-
- }
-
- /******************************************************************************/
-
- int get_tracks(min, max)
- int *min, *max;
- {
- struct sc_iocmd pt;
- int i, rc;
-
- if (test_unit_ready()==False) {
- Oops(&pt);
- return(0);
- }
-
- /* issue the play command */
- pt.command_length = 0x0A;
- pt.scsi_cdb[0] = CD_READINFO;
- for (i = 1 ; i < 9 ; i ++) {
- pt.scsi_cdb[i] = 0x00;
- }
-
- for (i = 0; i < 4; i++)
- rsbuf[i] = 0xAA;
-
- pt.scsi_cdb[9] = 0x80;
- pt.flags = 0x08 | B_READ;
- pt.buffer = rsbuf;
- pt.data_length = 0x04;
- pt.timeout_value = 0x05;
- pt.status_validity = 0x00;
- pt.scsi_bus_status = 0x00;
- pt.adapter_status = 0x00;
-
- rc = ioctl(fd, CDIOCMD, &pt);
- if (rc == -1) {
- Oops(&pt);
- return(rc);
- }
- *min = REALHEX(rsbuf[0]);
- *max = REALHEX(rsbuf[1]);
- return(1);
- }
-
- /******************************************************************************/
-
- int open_CD(which)
- int which;
- {
- char buffer[20];
-
- if (fd == -1) {
- sprintf(buffer, "/dev/rcd%d", which);
- fd = openx(buffer, O_RDONLY, NULL, SC_DIAGNOSTIC);
- }
- return fd;
- }
-
- void close_CD()
- {
- if ( fd != -1 ) {
- close(fd);
- }
- }
-
- Boolean test_unit_ready()
- {
- struct sc_iocmd pt;
- int i, rc;
- /* Issue 2 test unit ready's */
- for (i=0 ; i<2 ; i++) {
- pt.command_length = 0x06;
- for (i = 0 ; i < 6 ; i ++) {
- pt.scsi_cdb[i] = 0x00;
- }
- pt.flags = 0x00;
- pt.buffer = NULL;
- pt.data_length = 0x00;
- pt.timeout_value = 0x05;
- pt.status_validity = 0x00;
- pt.scsi_bus_status = 0x00;
- pt.adapter_status = 0x00;
- rc = ioctl(fd, CDIOCMD, &pt);
- }
- if (rc == -1) {
- /*
- Oops(&pt);
- */
- return False;
- }
- return True;
- }
-
- void cd_info()
- {
- int first,last;
- int new_last;
-
- get_tracks(&first, &last);
- get_times(first, last, &new_last);
- ping_track();
- }
-
- int track_seconds(int Track)
- {
- return TrackInfo[Track];
- }
-
- int which_track_is_playing()
- {
- ping_track();
- return REALHEX(pingbuf[2]);
- }
-
- int time_gone()
- {
- ping_track();
- return(REALHEX(pingbuf[4]) * 60 + REALHEX(pingbuf[5]));
- }
-
- void open_tray()
- {
- struct sc_iocmd pt;
- int i, rc;
- if ( test_unit_ready() ) {
- /* issue the tray open command */
- pt.command_length = 0x0A;
- pt.scsi_cdb[0] = CD_OPEN;
- pt.scsi_cdb[1] = 0x01;
- for (i = 2 ; i < 9 ; i ++) {
- pt.scsi_cdb[i] = 0x00;
- }
- pt.scsi_cdb[9] = 0x80;
- pt.flags = SC_ASYNC;
- pt.buffer = NULL;
- pt.data_length = 0x00;
- pt.timeout_value = 0x05;
- pt.status_validity = 0x00;
- pt.scsi_bus_status = 0x00;
- pt.adapter_status = 0x00;
- rc = ioctl(fd, CDIOCMD, &pt);
- if (rc == -1) {
- Oops(&pt);
- }
- }
- }
-
- void close_tray()
- /* This does not seem to work */
- {
- struct sc_iocmd pt;
- int i, rc;
- if ( test_unit_ready() ) {
- /* issue the tray close command */
- pt.command_length = 0x0A;
- pt.scsi_cdb[0] = CD_CLOSE;
- pt.scsi_cdb[1] = 0x01;
- for (i = 2 ; i < 9 ; i ++) {
- pt.scsi_cdb[i] = 0x00;
- }
- pt.scsi_cdb[9] = 0x80;
- pt.flags = SC_ASYNC;
- pt.buffer = NULL;
- pt.data_length = 0x00;
- pt.timeout_value = 0x05;
- pt.status_validity = 0x00;
- pt.scsi_bus_status = 0x00;
- pt.adapter_status = 0x00;
- rc = ioctl(fd, CDIOCMD, &pt);
- if (rc == -1) {
- Oops(&pt);
- }
- }
- }
-
- int CD_Position(track, totime)
- int track;
- int totime;
- {
- struct sc_iocmd pt;
- int i, rc;
-
- rc = totime + local_time[track];
- if ( test_unit_ready() ) {
- /* issue the position command */
- pt.command_length = 0x0A;
- pt.scsi_cdb[0] = CD_POSITION;
- for (i = 1 ; i < 9 ; i ++) {
- pt.scsi_cdb[i] = 0x00;
- }
- pt.scsi_cdb[2] = PSEUDOHEX(rc / 60);
- pt.scsi_cdb[3] = PSEUDOHEX(rc % 60);
- pt.scsi_cdb[9] = 0x40; /* Position to given time */
- pt.flags = SC_ASYNC;
- pt.buffer = NULL;
- pt.data_length = 0x00;
- pt.timeout_value = 0x05;
- pt.status_validity = 0x00;
- pt.scsi_bus_status = 0x00;
- pt.adapter_status = 0x00;
- rc = ioctl(fd, CDIOCMD, &pt);
- if (rc == -1) {
- Oops(&pt);
- }
- }
- return rc;
- }
-
- void mute()
- {
- struct sc_iocmd pt;
- int i, rc;
- if ( test_unit_ready() ) {
- Last_play_mode = Mute;
- /* issue the play audio command with muting on */
- pt.command_length = 0x0A;
- pt.scsi_cdb[0] = CD_PLAYAUDIO;
- pt.scsi_cdb[1] = Last_play_mode; /* Muting on */
- for (i = 2 ; i < 8 ; i ++) {
- pt.scsi_cdb[i] = 0x00;
- }
- pt.scsi_cdb[9] = 0xC0; /* Type of play: playback completion ignored */
- pt.flags = SC_ASYNC;
- pt.buffer = NULL;
- pt.data_length = 0x00;
- pt.timeout_value = 0x05;
- pt.status_validity = 0x00;
- pt.scsi_bus_status = 0x00;
- pt.adapter_status = 0x00;
- rc = ioctl(fd, CDIOCMD, &pt);
- if (rc == -1) {
- Oops(&pt);
- }
- }
- }
-
- void play_left_channel()
- {
- struct sc_iocmd pt;
- int i, rc;
- if ( test_unit_ready() ) {
- Last_play_mode = Left_channel;
- /* issue the play audio command with left channel only */
- pt.command_length = 0x0A;
- pt.scsi_cdb[0] = CD_PLAYAUDIO;
- pt.scsi_cdb[1] = Left_channel; /* Left channel on */
- for (i = 2 ; i < 8 ; i ++) {
- pt.scsi_cdb[i] = 0x00;
- }
- pt.scsi_cdb[9] = 0xC0; /* Type of play: playback completion ignored */
- pt.flags = SC_ASYNC;
- pt.buffer = NULL;
- pt.data_length = 0x00;
- pt.timeout_value = 0x05;
- pt.status_validity = 0x00;
- pt.scsi_bus_status = 0x00;
- pt.adapter_status = 0x00;
- rc = ioctl(fd, CDIOCMD, &pt);
- if (rc == -1) {
- Oops(&pt);
- }
- }
- }
-
- void play_right_channel()
- {
- struct sc_iocmd pt;
- int i, rc;
- if ( test_unit_ready() ) {
- Last_play_mode = Right_channel;
- /* issue the play audio command with right channel only */
- pt.command_length = 0x0A;
- pt.scsi_cdb[0] = CD_PLAYAUDIO;
- pt.scsi_cdb[1] = Right_channel; /* Right channel on */
- for (i = 2 ; i < 8 ; i ++) {
- pt.scsi_cdb[i] = 0x00;
- }
- pt.scsi_cdb[9] = 0xC0; /* Type of play: playback completion ignored */
- pt.flags = SC_ASYNC;
- pt.buffer = NULL;
- pt.data_length = 0x00;
- pt.timeout_value = 0x05;
- pt.status_validity = 0x00;
- pt.scsi_bus_status = 0x00;
- pt.adapter_status = 0x00;
- rc = ioctl(fd, CDIOCMD, &pt);
- if (rc == -1) {
- Oops(&pt);
- }
- }
- }
-
- void play_stereo()
- {
- struct sc_iocmd pt;
- int i, rc;
-
- if ( test_unit_ready() ) {
- Last_play_mode = Stereo;
- /* issue the play audio command in stereo mode */
- pt.command_length = 0x0A;
- pt.scsi_cdb[0] = CD_PLAYAUDIO;
- pt.scsi_cdb[1] = Last_play_mode; /* Both left and right channel */
- for (i = 2 ; i < 8 ; i ++) {
- pt.scsi_cdb[i] = 0x00;
- }
- pt.scsi_cdb[9] = 0xC0; /* Type of play: playback completion ignored */
- pt.flags = SC_ASYNC;
- pt.buffer = NULL;
- pt.data_length = 0x00;
- pt.timeout_value = 0x05;
- pt.status_validity = 0x00;
- pt.scsi_bus_status = 0x00;
- pt.adapter_status = 0x00;
- rc = ioctl(fd, CDIOCMD, &pt);
- if (rc == -1) {
- Oops(&pt);
- }
- }
- }
-
- void play_same()
- {
- struct sc_iocmd pt;
- int i, rc;
- if ( test_unit_ready() ) {
- /* issue the play audio command with the left/right/stereo unchanged */
- pt.command_length = 0x0A;
- pt.scsi_cdb[0] = CD_PLAYAUDIO;
- pt.scsi_cdb[1] = Last_play_mode; /* unchanged play mode */
- for (i = 2 ; i < 8 ; i ++) {
- pt.scsi_cdb[i] = 0x00;
- }
- pt.scsi_cdb[9] = 0xC0; /* Type of play: playback completion ignored */
- pt.flags = SC_ASYNC;
- pt.buffer = NULL;
- pt.data_length = 0x00;
- pt.timeout_value = 0x05;
- pt.status_validity = 0x00;
- pt.scsi_bus_status = 0x00;
- pt.adapter_status = 0x00;
- rc = ioctl(fd, CDIOCMD, &pt);
- if (rc == -1) {
- Oops(&pt);
- }
- }
- }
-
- void pause()
- {
- struct sc_iocmd pt;
- int i, rc;
-
- if ( test_unit_ready() ) {
- /* issue the still command */
- pt.command_length = 0x0A;
- pt.scsi_cdb[0] = CD_PAUSE;
- pt.scsi_cdb[1] = Last_play_mode; /* unchanged play mode */
- for (i = 2 ; i < 9 ; i ++) {
- pt.scsi_cdb[i] = 0x00;
- }
- pt.flags = SC_ASYNC;
- pt.buffer = NULL;
- pt.data_length = 0x00;
- pt.timeout_value = 0x05;
- pt.status_validity = 0x00;
- pt.scsi_bus_status = 0x00;
- pt.adapter_status = 0x00;
- rc = ioctl(fd, CDIOCMD, &pt);
- if (rc == -1) {
- /*
- Oops(&pt);
- */
- }
- }
- }
-
- jmp_buf env ;
-
- main()
- {
- int min, max, newmax, i ;
- extern int upd() ;
-
- open_CD(0) ;
- play_straight(1) ;
- get_tracks(&min,&max) ;
- get_times(min,max,&newmax) ;
- for (i = 1 ; i <= max ; i++)
- printf("%2d. %2d:%02d\n",i,TrackInfo[i]/60,TrackInfo[i] % 60) ;
- exit(0) ;
- }
-
- void Oops()
- {
- }
-
- int upd()
- {
- int i, t1, t2, m1, m2, s1, s2 ;
-
- signal(SIGALRM,upd) ;
- alarm(1) ;
- return ;
- }
- /*
- i = which_track_is_playing() ;
- t1 = time_gone() ;
- m1 = t1 / 60 ;
- s1 = t1 % 60 ;
- t2 = track_seconds(i) ;
- m2 = t2 / 60 ;
- s2 = t2 % 60 ;
-
- fprintf(stderr,"\rTrack: %2d %2d:%02d of %2d:%02d",
- i, m1, s1, m2, s2) ;
- fflush(stderr) ;
- if (i <= 0)
- {
- close_CD() ;
- exit(0) ;
- }
- alarm(1) ;
- longjmp(env,1) ;
- return ;
- }
- */
-