home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2819 < prev    next >
Internet Message Format  |  1991-02-20  |  8KB

  1. From: mario@cs.man.ac.uk (Mario Wolczko)
  2. Newsgroups: alt.sources
  3. Subject: Add flashing lights to your SPARCstation (patch to SunOS4.1 play)
  4. Message-ID: <2165@m1.cs.man.ac.uk>
  5. Date: 20 Feb 91 21:03:58 GMT
  6.  
  7. Here's a quick patch to the sun-supplied "play" program (available on
  8. sparcstations and SLCs, SunOS4.1 or higher).  Inspired by an earlier
  9. program to set the keyboard LEDs, it uses them as a VU meter...
  10.  
  11. No man page, and not necessarily very clean, but it works (I think).
  12.  
  13. Enjoy!
  14.  
  15. Mario Wolczko
  16.  
  17.    ______      Dept. of Computer Science   Internet:      mario@cs.man.ac.uk
  18.  /~      ~\    The University              uucp:      mcsun!ukc!man.cs!mario
  19. (    __    )   Manchester M13 9PL          JANET:         mario@uk.ac.man.cs
  20.  `-':  :`-'    U.K.                        Tel: +44-61-275 6146  (FAX: 6280)
  21. ____;  ;_____________the mushroom project___________________________________
  22. *** play.c.sun    Fri Dec 21 18:30:16 1990
  23. --- play.c    Tue Feb  5 18:23:19 1991
  24. ***************
  25. *** 20,25 ****
  26. --- 20,26 ----
  27.   #include <multimedia/libaudio.h>
  28.   #include <multimedia/audio_device.h>
  29.   
  30. + #include <sundev/kbd.h>
  31.   
  32.   #define    Error        (void) fprintf
  33.   
  34. ***************
  35. *** 27,37 ****
  36.   /* Local variables */
  37.   char *prog;
  38.   char prog_desc[] = "Play an audio file";
  39. ! char prog_opts[] = "Viv:d:?";        /* getopt() flags */
  40.   
  41.   char        *Stdin = "stdin";
  42.   unsigned char    buf[1024 * 64];        /* size should depend on sample_rate */
  43.   
  44.   
  45.   #define    MAX_GAIN        (100)        /* maximum gain */
  46.   
  47. --- 28,40 ----
  48.   /* Local variables */
  49.   char *prog;
  50.   char prog_desc[] = "Play an audio file";
  51. ! char prog_opts[] = "lViv:d:?";        /* getopt() flags */
  52.   
  53.   char        *Stdin = "stdin";
  54.   unsigned char    buf[1024 * 64];        /* size should depend on sample_rate */
  55.   
  56. + int kbd;            /* fd of kbd */
  57. + unsigned char snd[2];        /* 2 buffer for writes to kbd */
  58.   
  59.   #define    MAX_GAIN        (100)        /* maximum gain */
  60.   
  61. ***************
  62. *** 41,47 ****
  63. --- 44,65 ----
  64.    */
  65.   #define    SAMPLE_RATE_THRESHOLD    (.01)
  66.   
  67. + /* These define the sample used for averaging to calculate the bar graph size */
  68. + #define LN2_SS 8
  69. + #define SAMPLE_SIZE (1 << LN2_SS)
  70.   
  71. + /* how to convert an average to a bar graph, given only 5 different bar sizes */
  72. + static unsigned char bar[] = {
  73. +     0,
  74. +     LED_CAPS_LOCK,
  75. +     LED_CAPS_LOCK|LED_COMPOSE,
  76. +     LED_CAPS_LOCK|LED_COMPOSE,
  77. +     LED_CAPS_LOCK|LED_COMPOSE|LED_SCROLL_LOCK,
  78. +     LED_CAPS_LOCK|LED_COMPOSE|LED_SCROLL_LOCK,
  79. +     LED_CAPS_LOCK|LED_COMPOSE|LED_SCROLL_LOCK|LED_NUM_LOCK,
  80. +     LED_CAPS_LOCK|LED_COMPOSE|LED_SCROLL_LOCK|LED_NUM_LOCK
  81. + };
  82.   unsigned    Volume = ~0;        /* output volume */
  83.   double        Savevol;        /* saved volume level */
  84.   int        Verbose = FALSE;    /* verbose messages */
  85. ***************
  86. *** 52,59 ****
  87.   Audio_hdr    Dev_hdr;        /* audio header for device */
  88.   char        *Ifile;            /* current filename */
  89.   Audio_hdr    File_hdr;        /* audio header for file */
  90.   
  91.   /* Global variables */
  92.   extern int getopt();
  93.   extern int optind;
  94. --- 70,77 ----
  95.   Audio_hdr    Dev_hdr;        /* audio header for device */
  96.   char        *Ifile;            /* current filename */
  97.   Audio_hdr    File_hdr;        /* audio header for file */
  98. + int         leds = TRUE;        /* use leds as vu meter */
  99.   
  100.   /* Global variables */
  101.   extern int getopt();
  102.   extern int optind;
  103. ***************
  104. *** 63,73 ****
  105.   usage()
  106.   {
  107.       Error(stderr, "%s -- usage:\n\t%s ", prog_desc, prog);
  108. !     Error(stderr, "\t[-iV] [-v #] [-d dev] [file ...]\nwhere:\n");
  109.       Error(stderr, "\t-i\tDon't hang if audio device is busy\n");
  110.       Error(stderr, "\t-V\tPrint verbose warning messages\n");
  111.       Error(stderr, "\t-v #\tSet output volume (0 - %d)\n", MAX_GAIN);
  112.       Error(stderr, "\t-d dev\tSpecify audio device (default: /dev/audio)\n");
  113.       Error(stderr, "\tfile\tList of files to play\n");
  114.       Error(stderr, "\t\tIf no files specified, read stdin\n");
  115.       exit(1);
  116. --- 81,92 ----
  117.   usage()
  118.   {
  119.       Error(stderr, "%s -- usage:\n\t%s ", prog_desc, prog);
  120. !     Error(stderr, "\t[-iV] [-v #] [-d dev] [-l] [file ...]\nwhere:\n");
  121.       Error(stderr, "\t-i\tDon't hang if audio device is busy\n");
  122.       Error(stderr, "\t-V\tPrint verbose warning messages\n");
  123.       Error(stderr, "\t-v #\tSet output volume (0 - %d)\n", MAX_GAIN);
  124.       Error(stderr, "\t-d dev\tSpecify audio device (default: /dev/audio)\n");
  125. +     Error(stderr, "\t-l\tDon't use the keyboard LEDs\n");
  126.       Error(stderr, "\tfile\tList of files to play\n");
  127.       Error(stderr, "\t\tIf no files specified, read stdin\n");
  128.       exit(1);
  129. ***************
  130. *** 83,91 ****
  131. --- 102,125 ----
  132.               (void) audio_set_play_gain(Audio_fd, &Savevol);
  133.           (void) close(Audio_fd);            /* close output */
  134.       }
  135. +     if (leds) {
  136. +         snd[1]= 0 ; write(kbd, snd, 2);
  137. +         (void) close(kbd);
  138. +     }
  139.       exit(1);
  140.   }
  141.   
  142. + void set_channel(fd)        /* choose output port on env var */
  143. + int fd;
  144. + {
  145. +     extern char *getenv();
  146. +     unsigned port= getenv("SST_EARPHONES") ? AUDIO_HEADPHONE : AUDIO_SPEAKER;
  147. +     
  148. +      (void) audio_set_play_port(fd, &port); 
  149. + }
  150.   /*
  151.    * Play a list of audio files.
  152.    */
  153. ***************
  154. *** 94,100 ****
  155.       char        **argv;
  156.   {
  157.       int        i;
  158. !     int        cnt;
  159.       int        err;
  160.       int        ifd;
  161.       int        stdinseen;
  162. --- 128,134 ----
  163.       char        **argv;
  164.   {
  165.       int        i;
  166. !     int        cnt, cum_cnt;
  167.       int        err;
  168.       int        ifd;
  169.       int        stdinseen;
  170. ***************
  171. *** 101,106 ****
  172. --- 135,141 ----
  173.       double        vol;
  174.       struct stat    st;
  175.       struct sigvec    vec;
  176. +     register unsigned char *bufp;
  177.   
  178.       prog = argv[0];        /* save program initiation name */
  179.   
  180. ***************
  181. *** 123,128 ****
  182. --- 158,166 ----
  183.       case 'i':
  184.           Immediate = TRUE;
  185.           break;
  186. +     case 'l':
  187. +         leds = FALSE;
  188. +         break;
  189.       case '?':
  190.           usage();
  191.   /*NOTREACHED*/
  192. ***************
  193. *** 168,173 ****
  194. --- 206,213 ----
  195.           exit(1);
  196.       }
  197.   
  198. +     set_channel(Audio_fd);
  199.       /* Get the device output encoding configuration */
  200.       if (audio_get_play_config(Audio_fd, &Dev_hdr) != AUDIO_SUCCESS) {
  201.           Error(stderr, "%s: %s is not an audio device\n",
  202. ***************
  203. *** 188,193 ****
  204. --- 228,239 ----
  205.           }
  206.       }
  207.   
  208. +     if (leds) { /* open keyboard device */
  209. +         kbd= open("/dev/kbd", O_WRONLY);
  210. +         snd[0]= 016;        /* code to set leds */
  211. +         if (kbd < 0) leds = FALSE;
  212. +     }
  213.       /* Set up SIGINT handler to flush output */
  214.       vec.sv_handler = sigint;
  215.       vec.sv_mask = 0;
  216. ***************
  217. *** 254,271 ****
  218.   
  219.           /*
  220.            * At this point, we're all ready to copy the data.
  221.            */
  222. !         while ((cnt = read(ifd, (char *)buf, sizeof (buf))) >= 0) {
  223. !             /* If input EOF, write an eof marker */
  224. !             err = write(Audio_fd, (char *)buf, cnt);
  225.   
  226. !             if (err != cnt) {
  227. !                 Error(stderr, "%s: output error: ", prog);
  228. !                 perror("");
  229. !                 break;
  230.               }
  231. !             if (cnt == 0)
  232. !                 break;
  233.           }
  234.           if (cnt < 0) {
  235.               Error(stderr, "%s: error reading ", prog);
  236. --- 300,358 ----
  237.   
  238.           /*
  239.            * At this point, we're all ready to copy the data.
  240. +          * The outer loop grabs a chunk of data.
  241.            */
  242. !         for (cum_cnt=0; cnt = read(ifd, (char *)buf, sizeof (buf)), cnt > 0;) {
  243. !                 /* the inner loop breaks the chunk into
  244. !                  SAMPLE_SIZEd samples, and averages them */
  245. !             for (bufp= buf; cnt >= SAMPLE_SIZE ;
  246. !                  bufp += SAMPLE_SIZE, cnt -= SAMPLE_SIZE) {
  247. !                 register unsigned int total= 0, n;
  248.   
  249. !                 /* write to the audio channel */
  250. !                 err = write(Audio_fd, (char *)bufp, SAMPLE_SIZE);
  251. !                 if (err != SAMPLE_SIZE) {
  252. !                     Error(stderr, "%s: output error: ", prog);
  253. !                     perror("");
  254. !                     break;
  255. !                 }
  256. !                 if (leds) {
  257. !                     cum_cnt += SAMPLE_SIZE;
  258. !                     /* this is the averaging calculation */
  259. !                     for (n= 0; n < SAMPLE_SIZE; ++n) {
  260. !                         unsigned char b=bufp[n];
  261. !                         /* full wave rectification */
  262. !                         total += b&0x80 ? b^0xFF : b^0x7F;
  263. !                     }
  264. !                     
  265. !                     /* now convert to bargraph pattern */
  266. !                     /* seven bits of data -- strip 4 */
  267. !                     snd[1]= bar[total >> (LN2_SS + 4)];
  268. !                     /* and output to leds */
  269. !                     write(kbd, snd, 2);
  270. !                     /* this keeps the leds and audio in sync */
  271. !                     cum_cnt += SAMPLE_SIZE;
  272. !                     if (cum_cnt > 8000) { /* approx 1s */
  273. !                         audio_drain(Audio_fd,FALSE);
  274. !                         cum_cnt= 0;
  275. !                     }
  276. !                 }
  277.               }
  278. !             /* remaining chunk: don't average */
  279. !             if (leds) { /* this keeps the leds and audio in sync */
  280. !                 cum_cnt += SAMPLE_SIZE;
  281. !                 if (cum_cnt > 8000) { /* approx 1s */
  282. !                     audio_drain(Audio_fd,FALSE);
  283. !                     cum_cnt= 0;
  284. !                 }
  285. !                 snd[1]= 0 ; write(kbd, snd, 2);
  286. !             }
  287. !             write(Audio_fd, (char *)buf, cnt);
  288. !             /* If input EOF, write an eof marker */
  289. !             if (cnt > 0) write(Audio_fd, (char *)buf, 0);
  290.           }
  291.           if (cnt < 0) {
  292.               Error(stderr, "%s: error reading ", prog);
  293.