home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / unix / aix / 13795 < prev    next >
Encoding:
Text File  |  1993-01-28  |  15.7 KB  |  670 lines

  1. Path: sparky!uunet!crdgw1!rpi!usc!elroy.jpl.nasa.gov!nntp-server.caltech.edu!draco.macsch.com!portia.si.macsch.com!bnc
  2. From: bnc@portia.si.macsch.com (Brian Casey)
  3. Newsgroups: comp.unix.aix
  4. Subject: Re: CD-ROM for audio
  5. Keywords: CD-ROM, Audio
  6. Message-ID: <1993Jan27.182449.13574@draco.macsch.com>
  7. Date: 27 Jan 93 18:24:49 GMT
  8. References: <1993Jan26.163734.9839@news.unige.ch> <Jan26.174131.54628@yuma.ACNS.ColoState.EDU>
  9. Sender: usenet@draco.macsch.com (Usenet Poster)
  10. Organization: The MacNeal-Schwendler Corporation
  11. Lines: 657
  12.  
  13. In article <Jan26.174131.54628@yuma.ACNS.ColoState.EDU> copeland@lamar.ColoState.EDU (Jeffrey Copeland) writes:
  14. >
  15. >I started to convert xcdplayer, but gave up.  Since I'm also root I just use
  16. >play.  The problem (If I can remember) was in trying to find register and/or
  17. >port flags/addresses for the cd-rom.  If someone could get ahold of the source
  18. >code for IBM's play it shouldn't be too difficult,  I just couldn't 
  19. >locate the appropriate header files.
  20. >
  21. >Jeff Copeland -- Atmospheric Science
  22.  
  23.  
  24.  
  25. Attached is the source code to a very basic version of an audio CD player
  26. for the IBM RISC System/6000.  Although in its current state, this code
  27. only plays a CD from beginning to end, the source includes functions that
  28. could be used to add a lot of additional features.
  29.  
  30. If you name this file playcd.c, you can compile and link it using the
  31. following command:
  32.  
  33.     make playcd
  34.  
  35. After creating the executable, you must change the owner to root, and 
  36. change the mode to setuid; only root has privileges to access the CD
  37. drive for audio functions.
  38.  
  39. One favor - if you put together a full featured program, please send me
  40. a copy.  I like to see how other people do things like this.  Thanks.
  41.  
  42. #include <stdio.h>
  43. #include <fcntl.h>
  44. #include <sys/ioctl.h>
  45. #include <sys/cdrom.h>
  46. #include <signal.h>
  47. #include <setjmp.h>
  48. #include <math.h>
  49.  
  50.  
  51. #define STRAIGHT 1
  52. #define STRAIGHT2 2
  53. #define RANDOM  3
  54. #define PROGRAMMED 4
  55. #define HALT  5
  56.  
  57. #define CD_POSITION  0xC0
  58. #define CD_PLAYAUDIO 0xC1
  59. #define CD_PAUSE     0xC2
  60. #define CD_OPEN      0xC4
  61. #define CD_CLOSE     0xC5
  62. #define CD_SENSE     0xC6
  63. #define CD_READINFO  0xC7
  64.  
  65. #define PSEUDOHEX(i) ( ((i)/10) * 16 + ((i) % 10) )
  66. #define REALHEX(i)   ( (((i) & 0xf0) >> 4) * 10 + ( (i) & 0x0f) )
  67.  
  68. #define True 1
  69. #define False 0
  70.  
  71. typedef int Boolean;
  72.  
  73. int fd = -1;
  74.  
  75. int TrackInfo[100];
  76. int local_time[100];
  77. char rsbuf[4];
  78. char pingbuf[10];
  79.  
  80. int ping_track();
  81. void play_same();
  82. void Oops() ;
  83. Boolean test_unit_ready();
  84.  
  85. typedef enum { Mute=0, Left_channel=1, Right_channel=2, Stereo=3 }
  86.         Play_mode_type;
  87. Play_mode_type Last_play_mode = Stereo;
  88.  
  89. /******************************************************************************/
  90.  
  91. int ping_track()
  92. {
  93.   struct sc_iocmd         pt;
  94.   int                     i, rc;
  95.  
  96.   for (i = 0; i < 10; i++)
  97.     pingbuf[i] = 0xAA;
  98.   pt.command_length = 0x0A;
  99.   pt.scsi_cdb[0] = CD_SENSE;
  100.   pt.scsi_cdb[1] = 0x09;
  101.   for (i = 3 ; i < 9 ; i++) {
  102.     pt.scsi_cdb[i] = 0x00;
  103.   }
  104.  
  105.   pt.flags              = 0x08 | B_READ;
  106.   pt.buffer             = pingbuf;
  107.   pt.data_length        = 0x0A;
  108.   pt.timeout_value      = 0x05;
  109.   pt.status_validity    = 0x00;
  110.   pt.scsi_bus_status    = 0x00;
  111.   pt.adapter_status     = 0x00;
  112.   
  113.   rc = ioctl(fd, CDIOCMD, &pt);
  114.   return(pingbuf[0]);
  115. }
  116.  
  117. /******************************************************************************/
  118.  
  119. int play_straight(track)
  120. uchar track;
  121. {
  122.   struct sc_iocmd         pt;
  123.   int                     i, rc;
  124.  
  125.   if (test_unit_ready()==False) {
  126.     Oops(&pt);
  127.   }
  128.   /* issue the play command */
  129.   pt.command_length = 0x0A;
  130.   pt.scsi_cdb[0] = CD_POSITION;
  131.   pt.scsi_cdb[1] = 0x00; /* Do not play right away - pause after search */
  132.   pt.scsi_cdb[2] = PSEUDOHEX(track);
  133.   for (i = 3 ; i < 9 ; i ++) {
  134.     pt.scsi_cdb[i] = 0x00;
  135.   }
  136.   pt.scsi_cdb[9] = 0x80; /* Position to given track */
  137.   pt.flags              = SC_ASYNC;
  138.   pt.buffer             = NULL;
  139.   pt.data_length        = 0x00;
  140.   pt.timeout_value      = 0x05;
  141.   pt.status_validity    = 0x00;
  142.   pt.scsi_bus_status    = 0x00;
  143.   pt.adapter_status     = 0x00;
  144.   rc = ioctl(fd, CDIOCMD, &pt);
  145.   if (rc == -1) {
  146.     Oops(&pt);
  147.   } else {
  148.     play_same();
  149.   }
  150. }
  151.  
  152. /******************************************************************************/
  153.  
  154. get_times(min, max, new_max)
  155. int min, max;
  156. int *new_max;
  157. {
  158.   struct sc_iocmd pt;
  159.   int i, rc;
  160.   int max_flag = 1;
  161.   int track_loop;
  162.   int time_loop;
  163.   int minutes = 0;
  164.   int seconds = 0;
  165.  
  166.   if (test_unit_ready()==False) {
  167.     Oops(&pt);
  168.     return(-1);
  169.   }
  170.  
  171.   /* issue the read disc info command */
  172.   pt.command_length = 0x0A;
  173.   pt.scsi_cdb[0] = CD_READINFO;
  174.   pt.scsi_cdb[1] = 0x02;
  175.   for (i = 3 ; i < 9 ; i ++) {
  176.     pt.scsi_cdb[i] = 0x00;
  177.   }
  178.  
  179.   pt.scsi_cdb[9] = 0x80;
  180.   pt.flags              = 0x08 | B_READ;
  181.   pt.buffer             = rsbuf;
  182.   pt.data_length        = 0x04;
  183.   pt.timeout_value      = 0x05;
  184.   pt.status_validity    = 0x00;
  185.   pt.scsi_bus_status    = 0x00;
  186.   pt.adapter_status     = 0x00;
  187.  
  188.   local_time[0] = 0;
  189.   for (track_loop = min; track_loop <= max; track_loop++) {
  190.     pt.scsi_cdb[2] = PSEUDOHEX(track_loop);
  191.     
  192.     for (i = 0; i < 4; i++)
  193.       rsbuf[i] = 0x00;
  194.     
  195.     rc = ioctl(fd, CDIOCMD, &pt);
  196.     
  197.     minutes = REALHEX(rsbuf[0]);
  198.     seconds = REALHEX(rsbuf[1]);
  199.  
  200.     if (rc == -1) {
  201.       minutes = -1;
  202.       seconds = -1;
  203.       scanf("%d",&i);
  204.       if (max_flag) {
  205.     *new_max = track_loop - 1;
  206.     max_flag = 0;
  207.       }
  208.     }
  209.  
  210.     local_time[track_loop] = 60 * minutes + seconds;
  211.   }
  212.  
  213.   /* For the last track, we must get the total disk time to determine its
  214.    * length
  215.    */
  216.  
  217.   /* issue the read disc info command */
  218.   pt.command_length = 0x0A;
  219.   pt.scsi_cdb[0] = CD_READINFO;
  220.   pt.scsi_cdb[1] = 0x01;
  221.   for (i = 3 ; i < 9 ; i ++) {
  222.     pt.scsi_cdb[i] = 0x00;
  223.   }
  224.  
  225.   pt.flags              = 0x08 | B_READ;
  226.   pt.buffer             = rsbuf;
  227.   pt.data_length        = 0x04;
  228.   pt.timeout_value      = 0x05;
  229.   pt.status_validity    = 0x00;
  230.   pt.scsi_bus_status    = 0x00;
  231.   pt.adapter_status     = 0x00;
  232.   rc = ioctl(fd, CDIOCMD, &pt);
  233.   
  234.   minutes = REALHEX(rsbuf[0]);
  235.   seconds = REALHEX(rsbuf[1]);
  236.   
  237.   local_time[max+1] = 60 * minutes + seconds;
  238.  
  239.  
  240.   for (track_loop = min; track_loop <= max; track_loop++)
  241.     TrackInfo[track_loop] = local_time[track_loop + 1] - local_time[track_loop];
  242.  
  243. }
  244.  
  245. /******************************************************************************/
  246.  
  247. int get_tracks(min, max)
  248. int *min, *max;
  249. {
  250.   struct sc_iocmd         pt;
  251.   int                     i, rc;
  252.  
  253.   if (test_unit_ready()==False) {
  254.     Oops(&pt);
  255.     return(0);
  256.   }
  257.  
  258.   /* issue the play command */
  259.   pt.command_length = 0x0A;
  260.   pt.scsi_cdb[0] = CD_READINFO;
  261.   for (i = 1 ; i < 9 ; i ++) {
  262.     pt.scsi_cdb[i] = 0x00;
  263.   }
  264.  
  265.   for (i = 0; i < 4; i++)
  266.     rsbuf[i] = 0xAA;
  267.  
  268.   pt.scsi_cdb[9] = 0x80;
  269.   pt.flags              = 0x08 | B_READ;
  270.   pt.buffer             = rsbuf;
  271.   pt.data_length        = 0x04;
  272.   pt.timeout_value      = 0x05;
  273.   pt.status_validity    = 0x00;
  274.   pt.scsi_bus_status    = 0x00;
  275.   pt.adapter_status     = 0x00;
  276.   
  277.   rc = ioctl(fd, CDIOCMD, &pt);
  278.   if (rc == -1) {
  279.     Oops(&pt);
  280.     return(rc);
  281.   }
  282.   *min = REALHEX(rsbuf[0]);
  283.   *max = REALHEX(rsbuf[1]);
  284.   return(1);
  285. }
  286.  
  287. /******************************************************************************/
  288.  
  289. int open_CD(which)
  290. int which;
  291. {
  292.   char buffer[20];
  293.  
  294.   if (fd == -1) {
  295.     sprintf(buffer, "/dev/rcd%d", which);
  296.     fd = openx(buffer, O_RDONLY, NULL, SC_DIAGNOSTIC);
  297.   }
  298.   return fd;
  299. }
  300.  
  301. void close_CD()
  302. {
  303.   if ( fd != -1 ) {
  304.     close(fd);
  305.   }
  306. }
  307.  
  308. Boolean test_unit_ready()
  309. {
  310.   struct sc_iocmd         pt;
  311.   int                     i, rc;
  312.   /* Issue 2 test unit ready's */
  313.   for (i=0 ; i<2 ; i++) {
  314.     pt.command_length = 0x06;
  315.     for (i = 0 ; i < 6 ; i ++) {
  316.     pt.scsi_cdb[i] = 0x00;
  317.   }
  318.     pt.flags              = 0x00;
  319.     pt.buffer             = NULL;
  320.     pt.data_length        = 0x00;
  321.     pt.timeout_value      = 0x05;
  322.     pt.status_validity    = 0x00;
  323.     pt.scsi_bus_status    = 0x00;
  324.     pt.adapter_status     = 0x00;
  325.     rc = ioctl(fd, CDIOCMD, &pt);
  326.   }
  327.   if (rc == -1) {
  328. /*
  329.     Oops(&pt);
  330. */
  331.     return False;
  332.   }
  333.   return True;
  334. }
  335.  
  336. void cd_info()
  337. {
  338.   int first,last;
  339.   int new_last;
  340.   
  341.   get_tracks(&first, &last);
  342.   get_times(first, last, &new_last);
  343.   ping_track();
  344. }
  345.  
  346. int track_seconds(int Track)
  347. {
  348.   return TrackInfo[Track];
  349. }
  350.  
  351. int which_track_is_playing()
  352. {
  353.   ping_track();
  354.   return REALHEX(pingbuf[2]);
  355. }
  356.  
  357. int time_gone()
  358. {
  359.   ping_track();
  360.   return(REALHEX(pingbuf[4]) * 60 + REALHEX(pingbuf[5]));
  361. }
  362.  
  363. void open_tray()
  364. {
  365.   struct sc_iocmd         pt;
  366.   int                     i, rc;
  367.   if ( test_unit_ready() ) {
  368.     /* issue the tray open command */
  369.     pt.command_length = 0x0A;
  370.     pt.scsi_cdb[0] = CD_OPEN;
  371.     pt.scsi_cdb[1] = 0x01;
  372.     for (i = 2 ; i < 9 ; i ++) {
  373.       pt.scsi_cdb[i] = 0x00;
  374.     }
  375.     pt.scsi_cdb[9] = 0x80;
  376.     pt.flags              = SC_ASYNC;
  377.     pt.buffer             = NULL;
  378.     pt.data_length        = 0x00;
  379.     pt.timeout_value      = 0x05;
  380.     pt.status_validity    = 0x00;
  381.     pt.scsi_bus_status    = 0x00;
  382.     pt.adapter_status     = 0x00;
  383.     rc = ioctl(fd, CDIOCMD, &pt);
  384.     if (rc == -1) {
  385.       Oops(&pt);
  386.     }
  387.   }
  388. }
  389.  
  390. void close_tray()
  391. /* This does not seem to work */
  392. {
  393.   struct sc_iocmd         pt;
  394.   int                     i, rc;
  395.   if ( test_unit_ready() ) {
  396.     /* issue the tray close command */
  397.     pt.command_length = 0x0A;
  398.     pt.scsi_cdb[0] = CD_CLOSE;
  399.     pt.scsi_cdb[1] = 0x01;
  400.     for (i = 2 ; i < 9 ; i ++) {
  401.       pt.scsi_cdb[i] = 0x00;
  402.     }
  403.     pt.scsi_cdb[9] = 0x80;
  404.     pt.flags              = SC_ASYNC;
  405.     pt.buffer             = NULL;
  406.     pt.data_length        = 0x00;
  407.     pt.timeout_value      = 0x05;
  408.     pt.status_validity    = 0x00;
  409.     pt.scsi_bus_status    = 0x00;
  410.     pt.adapter_status     = 0x00;
  411.     rc = ioctl(fd, CDIOCMD, &pt);
  412.     if (rc == -1) {
  413.       Oops(&pt);
  414.     }
  415.   }
  416. }
  417.  
  418. int CD_Position(track, totime)
  419. int track;
  420. int totime;
  421. {
  422.   struct sc_iocmd         pt;
  423.   int                     i, rc;
  424.  
  425.   rc = totime + local_time[track];
  426.   if ( test_unit_ready() ) {
  427.     /* issue the position command */
  428.     pt.command_length = 0x0A;
  429.     pt.scsi_cdb[0] = CD_POSITION;
  430.     for (i = 1 ; i < 9 ; i ++) {
  431.       pt.scsi_cdb[i] = 0x00;
  432.     }
  433.     pt.scsi_cdb[2] = PSEUDOHEX(rc / 60);
  434.     pt.scsi_cdb[3] = PSEUDOHEX(rc % 60);
  435.     pt.scsi_cdb[9] = 0x40; /* Position to given time */
  436.     pt.flags              = SC_ASYNC;
  437.     pt.buffer             = NULL;
  438.     pt.data_length        = 0x00;
  439.     pt.timeout_value      = 0x05;
  440.     pt.status_validity    = 0x00;
  441.     pt.scsi_bus_status    = 0x00;
  442.     pt.adapter_status     = 0x00;
  443.     rc = ioctl(fd, CDIOCMD, &pt);
  444.     if (rc == -1) {
  445.       Oops(&pt);
  446.     }
  447.   }
  448.   return rc;
  449. }
  450.  
  451. void mute()
  452. {
  453.   struct sc_iocmd         pt;
  454.   int                     i, rc;
  455.   if ( test_unit_ready() ) {
  456.     Last_play_mode = Mute;
  457.     /* issue the play audio command with muting on */
  458.     pt.command_length = 0x0A;
  459.     pt.scsi_cdb[0] = CD_PLAYAUDIO;
  460.     pt.scsi_cdb[1] = Last_play_mode; /* Muting on */
  461.     for (i = 2 ; i < 8 ; i ++) {
  462.       pt.scsi_cdb[i] = 0x00;
  463.     }
  464.     pt.scsi_cdb[9] = 0xC0;  /* Type of play: playback completion ignored */
  465.     pt.flags              = SC_ASYNC;
  466.     pt.buffer             = NULL;
  467.     pt.data_length        = 0x00;
  468.     pt.timeout_value      = 0x05;
  469.     pt.status_validity    = 0x00;
  470.     pt.scsi_bus_status    = 0x00;
  471.     pt.adapter_status     = 0x00;
  472.     rc = ioctl(fd, CDIOCMD, &pt);
  473.     if (rc == -1) {
  474.       Oops(&pt);
  475.     }
  476.   }
  477. }
  478.  
  479. void play_left_channel()
  480. {
  481.   struct sc_iocmd         pt;
  482.   int                     i, rc;
  483.   if ( test_unit_ready() ) {
  484.     Last_play_mode = Left_channel;
  485.     /* issue the play audio command with left channel only */
  486.     pt.command_length = 0x0A;
  487.     pt.scsi_cdb[0] = CD_PLAYAUDIO;
  488.     pt.scsi_cdb[1] = Left_channel; /* Left channel on */
  489.     for (i = 2 ; i < 8 ; i ++) {
  490.       pt.scsi_cdb[i] = 0x00;
  491.     }
  492.     pt.scsi_cdb[9] = 0xC0;  /* Type of play: playback completion ignored */
  493.     pt.flags              = SC_ASYNC;
  494.     pt.buffer             = NULL;
  495.     pt.data_length        = 0x00;
  496.     pt.timeout_value      = 0x05;
  497.     pt.status_validity    = 0x00;
  498.     pt.scsi_bus_status    = 0x00;
  499.     pt.adapter_status     = 0x00;
  500.     rc = ioctl(fd, CDIOCMD, &pt);
  501.     if (rc == -1) {
  502.       Oops(&pt);
  503.     }
  504.   }
  505. }
  506.  
  507. void play_right_channel()
  508. {
  509.   struct sc_iocmd         pt;
  510.   int                     i, rc;
  511.   if ( test_unit_ready() ) {
  512.     Last_play_mode = Right_channel;
  513.     /* issue the play audio command with right channel only */
  514.     pt.command_length = 0x0A;
  515.     pt.scsi_cdb[0] = CD_PLAYAUDIO;
  516.     pt.scsi_cdb[1] = Right_channel; /* Right channel on */
  517.     for (i = 2 ; i < 8 ; i ++) {
  518.       pt.scsi_cdb[i] = 0x00;
  519.     }
  520.     pt.scsi_cdb[9] = 0xC0;  /* Type of play: playback completion ignored */
  521.     pt.flags              = SC_ASYNC;
  522.     pt.buffer             = NULL;
  523.     pt.data_length        = 0x00;
  524.     pt.timeout_value      = 0x05;
  525.     pt.status_validity    = 0x00;
  526.     pt.scsi_bus_status    = 0x00;
  527.     pt.adapter_status     = 0x00;
  528.     rc = ioctl(fd, CDIOCMD, &pt);
  529.     if (rc == -1) {
  530.       Oops(&pt);
  531.     }
  532.   }
  533. }
  534.  
  535. void play_stereo()
  536. {
  537.   struct sc_iocmd         pt;
  538.   int                     i, rc;
  539.  
  540.   if ( test_unit_ready() ) {
  541.     Last_play_mode = Stereo;
  542.     /* issue the play audio command in stereo mode */
  543.     pt.command_length = 0x0A;
  544.     pt.scsi_cdb[0] = CD_PLAYAUDIO;
  545.     pt.scsi_cdb[1] = Last_play_mode; /* Both left and right channel */
  546.     for (i = 2 ; i < 8 ; i ++) {
  547.       pt.scsi_cdb[i] = 0x00;
  548.     }
  549.     pt.scsi_cdb[9] = 0xC0;  /* Type of play: playback completion ignored */
  550.     pt.flags              = SC_ASYNC;
  551.     pt.buffer             = NULL;
  552.     pt.data_length        = 0x00;
  553.     pt.timeout_value      = 0x05;
  554.     pt.status_validity    = 0x00;
  555.     pt.scsi_bus_status    = 0x00;
  556.     pt.adapter_status     = 0x00;
  557.     rc = ioctl(fd, CDIOCMD, &pt);
  558.     if (rc == -1) {
  559.       Oops(&pt);
  560.     }
  561.   }
  562. }
  563.  
  564. void play_same()
  565. {
  566.   struct sc_iocmd         pt;
  567.   int                     i, rc;
  568.   if ( test_unit_ready() ) {
  569.     /* issue the play audio command with the left/right/stereo unchanged */
  570.     pt.command_length = 0x0A;
  571.     pt.scsi_cdb[0] = CD_PLAYAUDIO;
  572.     pt.scsi_cdb[1] = Last_play_mode; /* unchanged play mode */
  573.     for (i = 2 ; i < 8 ; i ++) {
  574.       pt.scsi_cdb[i] = 0x00;
  575.     }
  576.     pt.scsi_cdb[9] = 0xC0;  /* Type of play: playback completion ignored */
  577.     pt.flags              = SC_ASYNC;
  578.     pt.buffer             = NULL;
  579.     pt.data_length        = 0x00;
  580.     pt.timeout_value      = 0x05;
  581.     pt.status_validity    = 0x00;
  582.     pt.scsi_bus_status    = 0x00;
  583.     pt.adapter_status     = 0x00;
  584.     rc = ioctl(fd, CDIOCMD, &pt);
  585.     if (rc == -1) {
  586.       Oops(&pt);
  587.     }
  588.   }
  589. }
  590.  
  591. void pause()
  592. {
  593.   struct sc_iocmd         pt;
  594.   int                     i, rc;
  595.  
  596.   if ( test_unit_ready() ) {
  597.     /* issue the still command */
  598.     pt.command_length = 0x0A;
  599.     pt.scsi_cdb[0] = CD_PAUSE;
  600.     pt.scsi_cdb[1] = Last_play_mode; /* unchanged play mode */
  601.     for (i = 2 ; i < 9 ; i ++) {
  602.       pt.scsi_cdb[i] = 0x00;
  603.     }
  604.     pt.flags              = SC_ASYNC;
  605.     pt.buffer             = NULL;
  606.     pt.data_length        = 0x00;
  607.     pt.timeout_value      = 0x05;
  608.     pt.status_validity    = 0x00;
  609.     pt.scsi_bus_status    = 0x00;
  610.     pt.adapter_status     = 0x00;
  611.     rc = ioctl(fd, CDIOCMD, &pt);
  612.     if (rc == -1) {
  613. /*
  614.       Oops(&pt);
  615. */
  616.     }
  617.   }
  618. }
  619.  
  620. jmp_buf env ;
  621.  
  622. main()
  623. {
  624.     int min, max, newmax, i ;
  625.     extern int upd() ;
  626.  
  627.     open_CD(0) ;
  628.     play_straight(1) ;
  629.     get_tracks(&min,&max) ;
  630.     get_times(min,max,&newmax) ;
  631.     for (i = 1 ; i <= max ; i++)
  632.         printf("%2d. %2d:%02d\n",i,TrackInfo[i]/60,TrackInfo[i] % 60) ;
  633.     exit(0) ;
  634. }    
  635.  
  636. void Oops()
  637. {
  638. }
  639.  
  640. int upd()
  641. {
  642.     int i, t1, t2, m1, m2, s1, s2 ;
  643.  
  644.     signal(SIGALRM,upd) ;
  645.     alarm(1) ;
  646.     return ;
  647. }
  648. /*
  649.     i = which_track_is_playing() ;
  650.     t1 = time_gone() ;
  651.     m1 = t1 / 60 ;
  652.     s1 = t1 % 60 ;
  653.     t2 = track_seconds(i) ;
  654.     m2 = t2 / 60 ;
  655.     s2 = t2 % 60 ;
  656.  
  657.     fprintf(stderr,"\rTrack: %2d  %2d:%02d of %2d:%02d",
  658.         i, m1, s1, m2, s2) ;
  659.     fflush(stderr) ;
  660.     if (i <= 0)
  661.     {    
  662.         close_CD() ;
  663.         exit(0) ;
  664.     }
  665.     alarm(1) ;
  666.     longjmp(env,1) ;
  667.     return ;
  668. }
  669. */
  670.