Add flashing lights to your SPARCstation (patch to SunOS4.1 play)
Mario Wolczko
mario at cs.man.ac.uk
Thu Feb 21 08:03:58 AEST 1991
Here's a quick patch to the sun-supplied "play" program (available on
sparcstations and SLCs, SunOS4.1 or higher). Inspired by an earlier
program to set the keyboard LEDs, it uses them as a VU meter...
No man page, and not necessarily very clean, but it works (I think).
Enjoy!
Mario Wolczko
______ Dept. of Computer Science Internet: mario at cs.man.ac.uk
/~ ~\ The University uucp: mcsun!ukc!man.cs!mario
( __ ) Manchester M13 9PL JANET: mario at uk.ac.man.cs
`-': :`-' U.K. Tel: +44-61-275 6146 (FAX: 6280)
____; ;_____________the mushroom project___________________________________
*** play.c.sun Fri Dec 21 18:30:16 1990
--- play.c Tue Feb 5 18:23:19 1991
***************
*** 20,25 ****
--- 20,26 ----
#include <multimedia/libaudio.h>
#include <multimedia/audio_device.h>
+ #include <sundev/kbd.h>
#define Error (void) fprintf
***************
*** 27,37 ****
/* Local variables */
char *prog;
char prog_desc[] = "Play an audio file";
! char prog_opts[] = "Viv:d:?"; /* getopt() flags */
char *Stdin = "stdin";
unsigned char buf[1024 * 64]; /* size should depend on sample_rate */
#define MAX_GAIN (100) /* maximum gain */
--- 28,40 ----
/* Local variables */
char *prog;
char prog_desc[] = "Play an audio file";
! char prog_opts[] = "lViv:d:?"; /* getopt() flags */
char *Stdin = "stdin";
unsigned char buf[1024 * 64]; /* size should depend on sample_rate */
+ int kbd; /* fd of kbd */
+ unsigned char snd[2]; /* 2 buffer for writes to kbd */
#define MAX_GAIN (100) /* maximum gain */
***************
*** 41,47 ****
--- 44,65 ----
*/
#define SAMPLE_RATE_THRESHOLD (.01)
+ /* These define the sample used for averaging to calculate the bar graph size */
+ #define LN2_SS 8
+ #define SAMPLE_SIZE (1 << LN2_SS)
+ /* how to convert an average to a bar graph, given only 5 different bar sizes */
+ static unsigned char bar[] = {
+ 0,
+ LED_CAPS_LOCK,
+ LED_CAPS_LOCK|LED_COMPOSE,
+ LED_CAPS_LOCK|LED_COMPOSE,
+ LED_CAPS_LOCK|LED_COMPOSE|LED_SCROLL_LOCK,
+ LED_CAPS_LOCK|LED_COMPOSE|LED_SCROLL_LOCK,
+ LED_CAPS_LOCK|LED_COMPOSE|LED_SCROLL_LOCK|LED_NUM_LOCK,
+ LED_CAPS_LOCK|LED_COMPOSE|LED_SCROLL_LOCK|LED_NUM_LOCK
+ };
+
unsigned Volume = ~0; /* output volume */
double Savevol; /* saved volume level */
int Verbose = FALSE; /* verbose messages */
***************
*** 52,59 ****
Audio_hdr Dev_hdr; /* audio header for device */
char *Ifile; /* current filename */
Audio_hdr File_hdr; /* audio header for file */
-
/* Global variables */
extern int getopt();
extern int optind;
--- 70,77 ----
Audio_hdr Dev_hdr; /* audio header for device */
char *Ifile; /* current filename */
Audio_hdr File_hdr; /* audio header for file */
+ int leds = TRUE; /* use leds as vu meter */
/* Global variables */
extern int getopt();
extern int optind;
***************
*** 63,73 ****
usage()
{
Error(stderr, "%s -- usage:\n\t%s ", prog_desc, prog);
! Error(stderr, "\t[-iV] [-v #] [-d dev] [file ...]\nwhere:\n");
Error(stderr, "\t-i\tDon't hang if audio device is busy\n");
Error(stderr, "\t-V\tPrint verbose warning messages\n");
Error(stderr, "\t-v #\tSet output volume (0 - %d)\n", MAX_GAIN);
Error(stderr, "\t-d dev\tSpecify audio device (default: /dev/audio)\n");
Error(stderr, "\tfile\tList of files to play\n");
Error(stderr, "\t\tIf no files specified, read stdin\n");
exit(1);
--- 81,92 ----
usage()
{
Error(stderr, "%s -- usage:\n\t%s ", prog_desc, prog);
! Error(stderr, "\t[-iV] [-v #] [-d dev] [-l] [file ...]\nwhere:\n");
Error(stderr, "\t-i\tDon't hang if audio device is busy\n");
Error(stderr, "\t-V\tPrint verbose warning messages\n");
Error(stderr, "\t-v #\tSet output volume (0 - %d)\n", MAX_GAIN);
Error(stderr, "\t-d dev\tSpecify audio device (default: /dev/audio)\n");
+ Error(stderr, "\t-l\tDon't use the keyboard LEDs\n");
Error(stderr, "\tfile\tList of files to play\n");
Error(stderr, "\t\tIf no files specified, read stdin\n");
exit(1);
***************
*** 83,91 ****
--- 102,125 ----
(void) audio_set_play_gain(Audio_fd, &Savevol);
(void) close(Audio_fd); /* close output */
}
+ if (leds) {
+ snd[1]= 0 ; write(kbd, snd, 2);
+ (void) close(kbd);
+ }
exit(1);
}
+ void set_channel(fd) /* choose output port on env var */
+ int fd;
+ {
+ extern char *getenv();
+ unsigned port= getenv("SST_EARPHONES") ? AUDIO_HEADPHONE : AUDIO_SPEAKER;
+
+ (void) audio_set_play_port(fd, &port);
+ }
+
+
+
/*
* Play a list of audio files.
*/
***************
*** 94,100 ****
char **argv;
{
int i;
! int cnt;
int err;
int ifd;
int stdinseen;
--- 128,134 ----
char **argv;
{
int i;
! int cnt, cum_cnt;
int err;
int ifd;
int stdinseen;
***************
*** 101,106 ****
--- 135,141 ----
double vol;
struct stat st;
struct sigvec vec;
+ register unsigned char *bufp;
prog = argv[0]; /* save program initiation name */
***************
*** 123,128 ****
--- 158,166 ----
case 'i':
Immediate = TRUE;
break;
+ case 'l':
+ leds = FALSE;
+ break;
case '?':
usage();
/*NOTREACHED*/
***************
*** 168,173 ****
--- 206,213 ----
exit(1);
}
+ set_channel(Audio_fd);
+
/* Get the device output encoding configuration */
if (audio_get_play_config(Audio_fd, &Dev_hdr) != AUDIO_SUCCESS) {
Error(stderr, "%s: %s is not an audio device\n",
***************
*** 188,193 ****
--- 228,239 ----
}
}
+ if (leds) { /* open keyboard device */
+ kbd= open("/dev/kbd", O_WRONLY);
+ snd[0]= 016; /* code to set leds */
+ if (kbd < 0) leds = FALSE;
+ }
+
/* Set up SIGINT handler to flush output */
vec.sv_handler = sigint;
vec.sv_mask = 0;
***************
*** 254,271 ****
/*
* At this point, we're all ready to copy the data.
*/
! while ((cnt = read(ifd, (char *)buf, sizeof (buf))) >= 0) {
! /* If input EOF, write an eof marker */
! err = write(Audio_fd, (char *)buf, cnt);
! if (err != cnt) {
! Error(stderr, "%s: output error: ", prog);
! perror("");
! break;
}
! if (cnt == 0)
! break;
}
if (cnt < 0) {
Error(stderr, "%s: error reading ", prog);
--- 300,358 ----
/*
* At this point, we're all ready to copy the data.
+ * The outer loop grabs a chunk of data.
*/
! for (cum_cnt=0; cnt = read(ifd, (char *)buf, sizeof (buf)), cnt > 0;) {
! /* the inner loop breaks the chunk into
! SAMPLE_SIZEd samples, and averages them */
! for (bufp= buf; cnt >= SAMPLE_SIZE ;
! bufp += SAMPLE_SIZE, cnt -= SAMPLE_SIZE) {
! register unsigned int total= 0, n;
! /* write to the audio channel */
! err = write(Audio_fd, (char *)bufp, SAMPLE_SIZE);
! if (err != SAMPLE_SIZE) {
! Error(stderr, "%s: output error: ", prog);
! perror("");
! break;
! }
!
! if (leds) {
! cum_cnt += SAMPLE_SIZE;
! /* this is the averaging calculation */
! for (n= 0; n < SAMPLE_SIZE; ++n) {
! unsigned char b=bufp[n];
! /* full wave rectification */
! total += b&0x80 ? b^0xFF : b^0x7F;
! }
!
! /* now convert to bargraph pattern */
! /* seven bits of data -- strip 4 */
! snd[1]= bar[total >> (LN2_SS + 4)];
! /* and output to leds */
! write(kbd, snd, 2);
!
! /* this keeps the leds and audio in sync */
! cum_cnt += SAMPLE_SIZE;
! if (cum_cnt > 8000) { /* approx 1s */
! audio_drain(Audio_fd,FALSE);
! cum_cnt= 0;
! }
! }
}
! /* remaining chunk: don't average */
! if (leds) { /* this keeps the leds and audio in sync */
! cum_cnt += SAMPLE_SIZE;
! if (cum_cnt > 8000) { /* approx 1s */
! audio_drain(Audio_fd,FALSE);
! cum_cnt= 0;
! }
! snd[1]= 0 ; write(kbd, snd, 2);
! }
! write(Audio_fd, (char *)buf, cnt);
!
! /* If input EOF, write an eof marker */
! if (cnt > 0) write(Audio_fd, (char *)buf, 0);
}
if (cnt < 0) {
Error(stderr, "%s: error reading ", prog);
More information about the Alt.sources
mailing list