/* * This file is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify this file without charge, but are not authorized to * license or distribute it to anyone else except as part of a product * or program developed by the user. * * THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * This file is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even * if Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* Broadcast your audio input to all the displays mentioned in the command line up to 64 machines. */ #include #include #include #include #include "audio.h" #define w_WIDTH 400 #define w_HEIGHT 200 #define BUT_HEIGHT 30 #define BUT_WIDTH 80 #define MARGIN 20 #define NUM_LEVELS 22 #define RIGHT_EDGE (w_WIDTH - MARGIN - BUT_WIDTH) #define V_SIZE ((w_WIDTH - MARGIN - MARGIN)/NUM_LEVELS) #define TRUE 1 #define MAXHOSTS 64 typedef struct { Display *xdisplay; char *name; int rec_vol; int play_vol; } Windata; Windata local, machine[MAXHOSTS]; static char *audio_hosts[MAXHOSTS]; static int num_machines=0; static char *hosts[MAXHOSTS]; static int num_hosts=0; char **all_hosts(i) int *i; { *i = num_machines ; return( audio_hosts ); } parse_for_names() { FILE *fd, *fopen(); int end =0,a,b,c,d,e; char name [100]; fd = fopen("/etc/hosts", "r"); while (!end) { e = getc(fd); if (e == #') to_eol(fd); else { ungetc( e, fd ); end = (fscanf( fd, "%d.%d.%d.%d %s",&a,&b,&c,&d, name)== EOF ); to_eol(fd); if (!end && (( a == 192 )&&(strlen(name)))) { hosts[num_hosts] = (char *)malloc(strlen(name) + 3); sprintf( (char *)hosts[num_hosts] ,"%s:0", name ); num_hosts++; } } end = (e == EOF ); } fclose(fd); } to_eol(fd) FILE *fd; { int c; while(c = getc(fd)) if ((c == \n')||(c == EOF)) break; } connect_to_machines(local_display, argc, argv) Display *local_display; int argc; char **argv; { char *name; char **mhost = hosts; int i; if ( !argc ) { hosts[num_hosts] = (char *)getenv("DISPLAY");/*takes localhosts*/ num_hosts = 1; } else { if ((*argv[0]== -')&&(argv[0][1] == f'))/*takes /etc/hosts*/ parse_for_names(); else while (*argv) /* command line argc as hosts */ hosts[num_hosts++]= *argv++; } hosts[num_hosts] = NULL; while( name = *mhost ++ ) { if (!(machine[num_machines].xdisplay = XOpenDisplay( name ))) { (void)printf("Open Display Error:"); (void)printf("Cannot open host <%s>\n",name); continue; } machine[num_machines].name = name; if (!start_audio(machine[num_machines])) continue ; machine[num_machines].play_vol = 27 + MIN_VOLUME; machine[num_machines].rec_vol = 20 + MIN_VOLUME; audio_hosts[num_machines] = name; num_machines++ ; } if (! num_machines) { fprintf(stderr,"cannot open any hosts\n"); exit(0); } else { fprintf( stderr, "hosts accessed ="); for (i = 0; i < num_machines; i++) fprintf(stderr,"\t%s,", machine[i].name ); fprintf( stderr, ".\n"); } local.name = (char *)getenv("DISPLAY"); local.xdisplay = local_display; local.play_vol = 27 + MIN_VOLUME; local.rec_vol = 20 + MIN_VOLUME; if (!start_audio(local)) /* sets up audio*/ fprintf(stderr,"cannot open local audio\n" ); } quit_proc() { int i; XAudioPlayOff(local.xdisplay,1); clean_up(local.xdisplay); /* let xview do the rest */ for (i = 0; i < num_machines; i++ ) { XAudioPlayOff(machine[i].xdisplay,1); clean_up(machine[i].xdisplay); quit_x(machine[i]); } } start_audio(xwin) Windata xwin; { /* remote host */ if (XAudioOpen(xwin.xdisplay) < 1) { (void)fprintf(stderr,"cannot open host audio %s.\n", xwin.name); return(0); } XAudioSetVolume(xwin.xdisplay, xwin.play_vol, xwin.rec_vol); XFlush(xwin.xdisplay); return(1); } /* clean up the audio stuff that has been opened */ clean_up(xdisplay) Display *xdisplay; { int closed; while( !( closed = XAudioClose(xdisplay))) { (void)fprintf(stderr,"waiting closed = %d.\n",closed); sleep(1); } } quit_x(xwin) Windata xwin; { XFlush(xwin.xdisplay); XCloseDisplay(xwin.xdisplay); } /* Globals for the following functions */ int from_file; char play_file[200]; int dropped = 0; int fd = 0; start_file(file, fromfile, forced ) char *file; { if ( fromfile | forced) { if (file != NULL) strcpy(play_file, file); if (fd) { close(fd); fd=0; } if (play_file) { fd = open(play_file,O_RDONLY ); if (fd <= 0) { fprintf(stderr,"Cannot open file %s.\n", play_file); fd = 0; } } if (!forced) XAudioPlayOff(local.xdisplay, 1); if (from_file ) XAudioRecordOff(local.xdisplay); } else { if (fd) { close(fd); fd=0; } } from_file = fromfile; dropped = forced; } #define EACH_BUFF ONE_SECOND_DATA_SIZE +10 do_audio() { int i, dose = 0; static char buffer[WRITE_SIZE]; static int sizeofbuffer; static int delay[MAXHOSTS] ={ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,} ; if (from_file | dropped) { if (fd <= 0) return; for (i=0; i< num_machines;i++) /* clean out last buffer */ if (delay[i]) { (void)XAudioPlay(machine[i].xdisplay, buffer+sizeofbuffer-delay[i], delay[i]); dose= (dose > delay[i])? dose: delay[i]; } /* slow down a little bit to get in sync */ if (dose) { dose =(dose/8192.0 - 1.0) * 1000000.0 ; usleep(dose); } sizeofbuffer = read(fd,buffer,EACH_BUFF); for (i=0; i< num_machines;i++) delay[i]=XAudioPlay(machine[i].xdisplay,buffer,sizeofbuffer); if (sizeofbuffer != EACH_BUFF) { close(fd); fd = 0; dropped = 0; bzero(delay, sizeof(delay)); } } else { if (fd ) { close(fd); fd = 0; dropped = 0; } sizeofbuffer = XAudioRecord(local.xdisplay,buffer); for (i=0; i< num_machines;i++) (void)XAudioPlay(machine[i].xdisplay,buffer,sizeofbuffer); } } change_volume(rec,i) { int n; if (rec) { local.rec_vol = i + MIN_VOLUME ; XAudioSetVolume(local.xdisplay, local.play_vol, local.rec_vol); } else { for (n=0; n < num_machines; n++) { machine[n].play_vol = i + MIN_VOLUME; XAudioSetVolume(machine[n].xdisplay, machine[n].play_vol, machine[n].rec_vol); } } }