tjt@cbnewsh.ATT.COM (timothy.j.thompson) (10/01/89)
From article <10430001@hp-lsd.COS.HP.COM>, by dag@hp-lsd.COS.HP.COM (David Geiser): > Silence? Perhaps this will stimulate things. Enclosed is a minimal device driver that provides a /dev/midi that talks to an MPU-compatible MIDI hardware interface. It *only* allows use of the UART mode of the MPU hardware, and the timing resolution of the clock it provides is (I think) 10 milliseconds. It was written for AT&T System V Release 3.2 on a 6386, but may be portable to most SVR3-based operating systems, perhaps even SVR2. See the README and midi.7 files for more info. The right way to do something like this is to use streams. This is a quick and dirty (but also quite usable) hack. Tim Thompson = tjt@twitch.att.com | att!twitch!tjt #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # devmidi # This archive created: Sun Oct 1 12:37:02 1989 export PATH; PATH=/bin:$PATH if test ! -d 'devmidi' then echo shar: creating directory "'devmidi'" mkdir 'devmidi' fi echo shar: entering directory "'devmidi'" cd 'devmidi' echo shar: extracting "'Driver.c'" '(5377 characters)' if test -f 'Driver.c' then echo shar: will not over-write existing file "'Driver.c'" else cat << \SHAR_EOF > 'Driver.c' #include <sys/types.h> #include <sys/signal.h> #include <sys/errno.h> #include <sys/param.h> #include <sys/dir.h> #include <sys/user.h> #include <sys/buf.h> #include <sys/sysmacros.h> #include <sys/systm.h> #include <sys/midi.h> /* BUFSIZ is the size of the buffers obtained from geteblk(). Is there */ /* a #define elsewhere that gives this value? (besides stdio.h) */ #define BUFSIZ 1024 #define CIRCLESIZE (BUFSIZ*MIDI_BUFS) #define controller(dev) (minor(dev)) #define DATA_PORT 0x330 #define STATUS_PORT 0x331 #define DATA_READY 0x40 #define DATA_AVAILABLE 0x80 #define RESET 0xff #define UART 0x3f /* note that active sensing and ACK from controller are the same */ #define ACK 0xfe #define ACTIVE 0xfe #define midi_putdata(ctlr,c) (outb(ctlr_to_data_port[ctlr],(c))) #define midi_putcmd(ctlr,c) (outb(ctlr_to_status_port[ctlr],(c))) #define midi_getdata(ctlr) (inb(ctlr_to_data_port[ctlr])) #define midi_getstatus(ctlr) (inb(ctlr_to_status_port[ctlr])) #define data_is_available(ctlr) (!(midi_getstatus(ctlr)&DATA_AVAILABLE)) #define ready_for_data(ctlr) (!(midi_getstatus(ctlr)&DATA_READY)) void midiinit() { register int n; /* create an irq_to_ctlr array so that midiintr() can */ /* get the ctlr number quickly. */ for ( n=0; n<NUMIRQ; n++ ) irq_to_ctlr[n] = 0; for ( n=0; n<midi_nctlr; n++ ) irq_to_ctlr[ ctlr_to_irq[n] ] = n; } unsigned char * midiqchr(q,off) struct midi_queue *q; off_t off; { struct buf *b; unsigned char *a; b = q->buf[(int)((off/BUFSIZ)%MIDI_BUFS)]; if ( ! b ) return NULL; a = (unsigned char *)(b->b_un.b_addr); if ( ! a ) return NULL; return (a + (int)(off%BUFSIZ)); } void midiqput(q,c) register struct midi_queue *q; int c; { register unsigned char *p = midiqchr(q,q->high); if ( p ) { *p = c; q->high++; /* if we wrap around in the circular buffer, */ /* make sure the low offset keeps up (ie. this */ /* throws away the oldest unread data) */ if ( (q->high - q->low) >= CIRCLESIZE ) q->low = q->high - CIRCLESIZE + 1; } } midiqget(q) struct midi_queue *q; { register unsigned char *p; register int c; if ( q->low == q->high ) return -1; p = midiqchr(q,q->low); if ( ! p ) return -1; c = *p; q->low++; return c; } void midireset(ctlr,uart) { register struct midi_ctlr *m = &midi_ctlr[ ctlr ]; register time_t etime; int n; while ( data_is_available(ctlr) ) (void) midi_getdata(ctlr); /* try reset twice if ACK not received */ for ( n=0; n<2; n++ ) { midi_putcmd(ctlr,RESET); /* probably shouldn't busy loop */ etime = lbolt + HZ / 40; /* for 25 milliseconds */ while ( lbolt >= etime ) { if ( midiqget(&(m->in)) == ACK ) break; } if ( lbolt < etime ) break; } if ( n >= 2 ) printf("midireset didn't get ACK?\n"); if ( uart ) midi_putcmd(ctlr,UART); /* doesn't send an ACK back */ } void midiopen(dev) { register struct midi_ctlr *m; register int ctlr = controller(dev); register int n; if ( ctlr >= midi_nctlr ) { u.u_error = ENXIO; return; } m = &midi_ctlr[ctlr]; if ( ((m->flags)&ISOPEN) == 0 ) { /* opened for the first time */ for ( n=0; n<MIDI_BUFS; n++ ) { m->in.buf[n] = geteblk(); m->in.low = m->in.high = 0; } m->flags |= ISOPEN; m->flags &= (~ACTSENSE);/* default is to ignore active sensing */ m->clockoffset = lbolt; /* TIME starts out at 0 */ midireset(ctlr,1); /* default is UART mode */ } } void midiioctl(dev, cmd, arg, mode) { register int ctlr = controller(dev); register struct midi_ctlr *m; time_t *t; off_t n; m = &midi_ctlr[ ctlr ]; switch(cmd) { case MIDIACTIVE: if ( arg ) m->flags |= ACTSENSE; else m->flags &= (~ACTSENSE); break; case MIDIRESET: midireset(ctlr,1); /* default is UART mode */ break; case MIDITHRU: midireset(ctlr,0); break; case MIDITIMERESET: m->clockoffset = lbolt; break; case MIDITIME: t = (time_t *)arg; #define MILLIPERHZ (1000/HZ) if ( t ) suword(t,(long)(MILLIPERHZ*(lbolt - m->clockoffset))); break; default: u.u_error = EINVAL; break; } } midi_wait_for_ready(ctlr) { int tmout; for ( tmout=50000; tmout>0; tmout-- ) { if ( ready_for_data(ctlr) ) break; } if ( tmout <= 0 ) { printf("/dev/midi timed out waiting for data ready\n"); return 0; } return 1; } void midiclose(dev) { register struct midi_ctlr *m; register int n; register int ctlr = controller(dev); m = &midi_ctlr[ ctlr ]; if ( ((m->flags)&ISOPEN) != 0 ) { /* paranoia */ m->flags &= (~ISOPEN); for ( n=0; n<MIDI_BUFS; n++ ) brelse(m->in.buf[n]); } midireset(ctlr,0); } void midiread(dev) { register struct midi_ctlr *m; register int ctlr = controller(dev); register int c; m = &midi_ctlr[ ctlr ]; while ( u.u_count ) { c = midiqget(&(m->in)); if ( c < 0 ) break; /* active sensing may be ignored */ if ( c == ACTIVE && ((m->flags&ACTSENSE)==0) ) break; subyte(u.u_base,c); u.u_base++; u.u_count--; } } void midiwrite(dev) { register int ctlr = controller(dev); while ( u.u_count ) { if ( midi_wait_for_ready(ctlr) ) { midi_putdata(ctlr,fubyte(u.u_base)); u.u_base++; u.u_count--; } } } void midiintr(irq) { register struct midi_ctlr *m; register int ctlr; register int c; ctlr = irq_to_ctlr[irq]; if ( data_is_available(ctlr) ) { c = midi_getdata(ctlr); m = &midi_ctlr[ ctlr ]; if ( (m->flags & ISOPEN) != 0 ) midiqput(&(m->in),c); } } SHAR_EOF if test 5377 -ne "`wc -c < 'Driver.c'`" then echo shar: error transmitting "'Driver.c'" '(should have been 5377 characters)' fi fi # end of overwriting check echo shar: extracting "'Files'" '(24 characters)' if test -f 'Files' then echo shar: will not over-write existing file "'Files'" else cat << \SHAR_EOF > 'Files' /usr/include/sys/midi.h SHAR_EOF if test 24 -ne "`wc -c < 'Files'`" then echo shar: error transmitting "'Files'" '(should have been 24 characters)' fi fi # end of overwriting check echo shar: extracting "'Install'" '(3491 characters)' if test -f 'Install' then echo shar: will not over-write existing file "'Install'" else cat << \SHAR_EOF > 'Install' # # Install script for Midi device driver package # if [ "$1" = -f ] then force=true else force=false fi TMP=/tmp/midi.err rm -f $TMP ERROR1=" Errors have been written to the file $TMP." ERROR2=" The Midi Driver software was not installed, and the System has not been modified." if [ "`id | grep root`" = "" ] then message "You have to be 'root' in order to install the driver! $ERROR2" exit 1 fi echo "Installing Midi Device Driver Package..." # BEGIN DYNAMIC CREATION OF Space.c, System, and Node # based on controller info entered interactively cat <<EOF > Space.c /* THIS FILE WAS CREATED BY THE Install SCRIPT. */ #include "config.h" #include "sys/types.h" #include "sys/midi.h" struct midi_ctlr midi_ctlr[MIDI_UNITS]; int midi_nctlr = MIDI_UNITS; int irq_to_ctlr[NUMIRQ]; /* to be filled in by midi_init */ EOF echo "\nHow many Midi controllers do you have? [1] --> \c" read nctlr if [ "$nctlr" = "" ] then nctlr=1 fi n=0 while [ "$n" -lt $nctlr ] do cn=`expr $n + 1` echo "\nWhat is the IRQ # for controller number $cn ? [2] --> \c" read vect if [ "$vect" = "" ] then vect=2 fi # On the 6386, vector 2 gets linked to 9 if [ "$vect" = 2 ] then vect=9 fi eval vect$n=$vect echo "Starting address (in hex) for controller number $cn ? [330] --> \c" read addr if [ "$addr" = "" ] then addr=330 fi eval saddr$n=$addr echo "Ending address (in hex) for controller number $cn ? [331] --> \c" read addr if [ "$addr" = "" ] then addr=331 fi eval eaddr$n=$addr n=`expr $n + 1` done n=0 > System while [ "$n" -lt $nctlr ] do eval echo "midi:Y:1:7:1:\$vect$n:\$saddr$n:\$eaddr$n:0:0" | sed "s/:/ /g" >> System n=`expr $n + 1` done echo "int ctlr_to_irq[] = {" >> Space.c echo MIDI_0_VECT >> Space.c n=1 while [ "$n" -lt $nctlr ] do echo ",MIDI_${n}_VECT" >> Space.c n=`expr $n + 1` done echo "};" >> Space.c echo "int ctlr_to_data_port[] = {" >> Space.c echo MIDI_0_SIOA >> Space.c n=1 while [ "$n" -lt $nctlr ] do echo ",MIDI_${n}_SIOA" >> Space.c n=`expr $n + 1` done echo "};" >> Space.c echo "int ctlr_to_status_port[] = {" >> Space.c echo "MIDI_0_SIOA + 1" >> Space.c n=1 while [ "$n" -lt $nctlr ] do echo ", MIDI_${n}_SIOA + 1" >> Space.c n=`expr $n + 1` done echo "};" >> Space.c echo "midi midi c 0" > Node n=1 while [ "$n" -lt $nctlr ] do echo "midi midi`expr $n + 1` c $n" >> Node n=`expr $n + 1` done echo "" # END OF DYNAMIC CREATION OF Space.c, System, and Node /etc/conf/bin/idcheck -p midi 2>> $TMP if [ $? != 0 ] then if [ $force = true ] then /etc/conf/bin/idinstall -d midi else message -cu "The Midi Device Driver is already installed (or partially installed). Do you wish to overwrite the existing device driver software?" if [ $? = 0 ] then /etc/conf/bin/idinstall -d midi else exit 1 fi fi fi inc=/usr/include/sys/midi.h cp midi.h $inc chown bin $inc chgrp bin $inc chmod 444 $inc if [ -f Driver.c ] then echo "Compiling Driver.c ..." cc -c Driver.c 2>> $TMP if [ $? != 0 ] then message "There was an error while compiling Driver.c. $ERROR1 $ERROR2" exit 1 fi fi /etc/conf/bin/idinstall -a -k midi 2>> $TMP if [ $? != 0 ] then message "There was an error during package installation. $ERROR1 $ERROR2" exit 1 fi /etc/conf/bin/idbuild 2>> $TMP if [ $? != 0 ] then # if an error occurs here, remove the driver components /etc/conf/bin/idinstall -d midi rm -f $inc message "There was an error during Kernel reconfiguration. $ERROR1 $ERROR2" exit 1 fi rm -f $TMP exit 0 SHAR_EOF if test 3491 -ne "`wc -c < 'Install'`" then echo shar: error transmitting "'Install'" '(should have been 3491 characters)' fi chmod +x 'Install' fi # end of overwriting check echo shar: extracting "'Makefile'" '(217 characters)' if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else cat << \SHAR_EOF > 'Makefile' all : testread testwrite resetmidi clean : rm -f testread testwrite resetmidi *.o lint : lintlib.ln lint -nux lintlib.ln Driver.c | grep -v "struct/union.*never defined" lintlib.ln : lintlib.c lint -c lintlib.c SHAR_EOF if test 217 -ne "`wc -c < 'Makefile'`" then echo shar: error transmitting "'Makefile'" '(should have been 217 characters)' fi fi # end of overwriting check echo shar: extracting "'Master'" '(32 characters)' if test -f 'Master' then echo shar: will not over-write existing file "'Master'" else cat << \SHAR_EOF > 'Master' midi ocrwiI icH midi 0 0 1 1 -1 SHAR_EOF if test 32 -ne "`wc -c < 'Master'`" then echo shar: error transmitting "'Master'" '(should have been 32 characters)' fi fi # end of overwriting check echo shar: extracting "'Name'" '(35 characters)' if test -f 'Name' then echo shar: will not over-write existing file "'Name'" else cat << \SHAR_EOF > 'Name' 386unix Midi Device Driver Package SHAR_EOF if test 35 -ne "`wc -c < 'Name'`" then echo shar: error transmitting "'Name'" '(should have been 35 characters)' fi fi # end of overwriting check echo shar: extracting "'Node'" '(29 characters)' if test -f 'Node' then echo shar: will not over-write existing file "'Node'" else cat << \SHAR_EOF > 'Node' midi midi c 0 midi midi2 c 1 SHAR_EOF if test 29 -ne "`wc -c < 'Node'`" then echo shar: error transmitting "'Node'" '(should have been 29 characters)' fi fi # end of overwriting check echo shar: extracting "'README'" '(673 characters)' if test -f 'README' then echo shar: will not over-write existing file "'README'" else cat << \SHAR_EOF > 'README' This is a minimal device driver that provides a /dev/midi that talks to an MPU-compatible MIDI hardware interface. It ONLY allows use of the UART mode of the MPU hardware. It was written for AT&T System V Release 3.2 on a 6386, but may be portable to most System V Release 3-based operating systems. To install, invoke (as root): Install This assumes the installable device driver structure of System V 3.2. The hardware interrupt # and address will be requested interactively. Included are testread.c and testwrite.c programs that can be used to exercise the device. See midi.7 for more info. Tim Thompson = tjt@twitch.att.com SHAR_EOF if test 673 -ne "`wc -c < 'README'`" then echo shar: error transmitting "'README'" '(should have been 673 characters)' fi fi # end of overwriting check echo shar: extracting "'Reboot'" '(23 characters)' if test -f 'Reboot' then echo shar: will not over-write existing file "'Reboot'" else cat << \SHAR_EOF > 'Reboot' /etc/conf/bin/idreboot SHAR_EOF if test 23 -ne "`wc -c < 'Reboot'`" then echo shar: error transmitting "'Reboot'" '(should have been 23 characters)' fi chmod +x 'Reboot' fi # end of overwriting check echo shar: extracting "'Remove'" '(419 characters)' if test -f 'Remove' then echo shar: will not over-write existing file "'Remove'" else cat << \SHAR_EOF > 'Remove' # # Remove script for Midi device driver # TMP=/tmp/midi.err RERR="An error was encountered while removing the Midi Driver Package. The file $TMP contains errors reported by the system." echo "Removing Midi Device Driver Package..." /etc/conf/bin/idinstall -d midi 2> $TMP if [ $? != 0 ] then message $RERR exit 1 fi /etc/conf/bin/idbuild 2>> $TMP if [ $? != 0 ] then message $RERR exit 1 fi rm -f $TMP exit 0 SHAR_EOF if test 419 -ne "`wc -c < 'Remove'`" then echo shar: error transmitting "'Remove'" '(should have been 419 characters)' fi fi # end of overwriting check echo shar: extracting "'Size'" '(18 characters)' if test -f 'Size' then echo shar: will not over-write existing file "'Size'" else cat << \SHAR_EOF > 'Size' ROOT=1500 USR=500 SHAR_EOF if test 18 -ne "`wc -c < 'Size'`" then echo shar: error transmitting "'Size'" '(should have been 18 characters)' fi fi # end of overwriting check echo shar: extracting "'Space.c'" '(420 characters)' if test -f 'Space.c' then echo shar: will not over-write existing file "'Space.c'" else cat << \SHAR_EOF > 'Space.c' /* THIS FILE WAS CREATED BY THE Install SCRIPT. */ #include "config.h" #include "sys/types.h" #include "sys/midi.h" struct midi_ctlr midi_ctlr[MIDI_UNITS]; int midi_nctlr = MIDI_UNITS; int irq_to_ctlr[NUMIRQ]; /* to be filled in by midi_init */ int ctlr_to_irq[] = { MIDI_0_VECT ,MIDI_1_VECT }; int ctlr_to_data_port[] = { MIDI_0_SIOA ,MIDI_1_SIOA }; int ctlr_to_status_port[] = { MIDI_0_SIOA + 1 , MIDI_1_SIOA + 1 }; SHAR_EOF if test 420 -ne "`wc -c < 'Space.c'`" then echo shar: error transmitting "'Space.c'" '(should have been 420 characters)' fi fi # end of overwriting check echo shar: extracting "'System'" '(54 characters)' if test -f 'System' then echo shar: will not over-write existing file "'System'" else cat << \SHAR_EOF > 'System' midi Y 1 7 1 9 330 331 0 0 midi Y 1 7 1 7 300 301 0 0 SHAR_EOF if test 54 -ne "`wc -c < 'System'`" then echo shar: error transmitting "'System'" '(should have been 54 characters)' fi fi # end of overwriting check echo shar: extracting "'midi.7'" '(1025 characters)' if test -f 'midi.7' then echo shar: will not over-write existing file "'midi.7'" else cat << \SHAR_EOF > 'midi.7' .TH MIDI 7 .SH SYNOPSIS /dev/midi .SH DESCRIPTION /dev/midi controls a MIDI interface. Data read from and written to /dev/midi is pure MIDI data. Reading is always non-blocking, returning immediately if no input is available. A static number of system buffers is allocated for MIDI input when /dev/midi is first opened, forming a large circular buffer in which new MIDI input overwrites the oldest MIDI input (which may still be unread). Ioctl commands are: .P ioctl(fd,MIDIRESET) .IP Reset the interface, flushing all pending MIDI input and output. The MIDI clock time is reset to 0. .P ioctl(fd,MIDITHRU) .IP Turn ``thru'' mode on. This is a mode in which MIDI input is routed directly to MIDI output, and no MIDI input can be read from /dev/midi until a MIDIRESET is done. .P ioctl(fd,MIDITIMERESET) .IP Reset the MIDI clock time to 0. .P ioctl(fd,MIDITIME,arg) .IP Get the MIDI clock time (relative to the last time a MIDITIMERESET was done) in milliseconds. arg is a pointer to a long, into which the value is written. SHAR_EOF if test 1025 -ne "`wc -c < 'midi.7'`" then echo shar: error transmitting "'midi.7'" '(should have been 1025 characters)' fi fi # end of overwriting check echo shar: extracting "'midi.h'" '(873 characters)' if test -f 'midi.h' then echo shar: will not over-write existing file "'midi.h'" else cat << \SHAR_EOF > 'midi.h' /* MIDI_BUFS is the number of buffers to allocate for MIDI I/O queues. */ /* All of the buffers get allocated when /dev/midi is first */ /* opened, and get freed when /dev/midi is finally closed. */ #define MIDI_BUFS 5 #define NUMIRQ 16 #define MIDIC ('M'<<8) #define MIDIRESET (MIDIC|01) #define MIDITIME (MIDIC|02) #define MIDITIMERESET (MIDIC|03) #define MIDIACTIVE (MIDIC|04) #define MIDITHRU (MIDIC|05) /* bits for midi_ctlr.flags */ #define ISOPEN 01 /* active sensing is passed on to the reader */ #define ACTSENSE 02 struct midi_queue { struct buf * buf[MIDI_BUFS]; off_t low; off_t high; }; struct midi_ctlr { int flags; time_t clockoffset; struct midi_queue in; }; extern struct midi_ctlr midi_ctlr[]; extern int midi_nctlr; extern int irq_to_ctlr[]; extern int ctlr_to_irq[]; extern int ctlr_to_data_port[]; extern int ctlr_to_status_port[]; SHAR_EOF if test 873 -ne "`wc -c < 'midi.h'`" then echo shar: error transmitting "'midi.h'" '(should have been 873 characters)' fi fi # end of overwriting check echo shar: extracting "'resetmidi.c'" '(273 characters)' if test -f 'resetmidi.c' then echo shar: will not over-write existing file "'resetmidi.c'" else cat << \SHAR_EOF > 'resetmidi.c' #include <sys/types.h> #include <sys/fcntl.h> #include <sys/midi.h> #include <sys/signal.h> main(argc,argv) int argc; char **argv; { int fd; if ( argc > 1 ) fd = open(argv[1],O_RDONLY ); else fd = open("/dev/midi",O_RDONLY ); ioctl(fd,MIDIRESET,0); close(fd); } SHAR_EOF if test 273 -ne "`wc -c < 'resetmidi.c'`" then echo shar: error transmitting "'resetmidi.c'" '(should have been 273 characters)' fi fi # end of overwriting check echo shar: extracting "'testread.c'" '(618 characters)' if test -f 'testread.c' then echo shar: will not over-write existing file "'testread.c'" else cat << \SHAR_EOF > 'testread.c' /* * A test program for reading from /dev/midi. * Invoke it, and play something on the MIDI input keyboard. * Interrupt to terminate. */ #include <sys/types.h> #include <sys/fcntl.h> #include <sys/midi.h> main(argc,argv) int argc; char **argv; { int n, k; unsigned char buff[100]; long t; int fd; if ( argc > 1 ) fd = open(argv[1],O_RDONLY ); else fd = open("/dev/midi",O_RDONLY ); ioctl(fd,MIDIRESET,0); while ( 1 ) { if ( (n=read(fd,buff,sizeof(buff))) > 0 ) { ioctl(fd,MIDITIME,&t); printf("Time=%ld ",t); for ( k=0; k<n; k++ ) printf(" 0x%x",buff[k]); printf("\n"); } } } SHAR_EOF if test 618 -ne "`wc -c < 'testread.c'`" then echo shar: error transmitting "'testread.c'" '(should have been 618 characters)' fi fi # end of overwriting check echo shar: extracting "'testwrite.c'" '(873 characters)' if test -f 'testwrite.c' then echo shar: will not over-write existing file "'testwrite.c'" else cat << \SHAR_EOF > 'testwrite.c' /* * A test program for writing to /dev/midi. * * Usage: testwrite {file} * * The contents of the file will be used to control the pitches of * notes written to /dev/midi. */ #include <stdio.h> #include <sys/types.h> #include <sys/fcntl.h> #include <sys/midi.h> main(argc,argv) int argc; char **argv; { int n, k, c; unsigned char buff[100]; long t; int fd; FILE *fin; long tm, nexttm; if ( argc > 2 ) { fd = open(argv[1],O_WRONLY ); argc--; argv++; } else fd = open("/dev/midi",O_WRONLY ); if ( argc > 1 ) fin = fopen(argv[1],"r"); else fin = stdin; ioctl(fd,MIDIRESET,0); ioctl(fd,MIDITIME,&tm); while ( (c=getc(fin)) != EOF ) { buff[0] = 0x90; buff[1] = c % 128; buff[2] = 0x40; write(fd,buff,3); nexttm = tm + 100; while ( tm < nexttm ) ioctl(fd,MIDITIME,&tm); buff[2] = 0x00; write(fd,buff,3); } close(fd); } SHAR_EOF if test 873 -ne "`wc -c < 'testwrite.c'`" then echo shar: error transmitting "'testwrite.c'" '(should have been 873 characters)' fi fi # end of overwriting check echo shar: done with directory "'devmidi'" cd .. # End of shell archive exit 0
bender@oobleck.Central.Sun.COM (Michael Bender) (10/04/89)
Does anyone know of any UNIX-based MIDI software (specifically for a Sun)? Preferably PD? I'm looking for a sequencer/patch editor-librarian/sample editor, whatever's out there. thanks, mike bender ------------------------------------------------------------------------ michael bender - bender@sun (can't think of a witty thing 415 336-6353 (w) 415 941-3864 (h) to put here yet) ------------------------------------------------------------------------
rlw@ttardis.UUCP (Ron Wilson) (10/04/89)
In article <4401@cbnewsh.ATT.COM>, tjt@cbnewsh.ATT.COM (timothy.j.thompson) writes: >Enclosed is a minimal device driver that provides a /dev/midi that >talks to an MPU-compatible MIDI hardware interface. It *only* allows >use of the UART mode of the MPU hardware, and the timing resolution of >the clock it provides is (I think) 10 milliseconds. It was written >for AT&T System V Release 3.2 on a 6386, but may be portable to most >SVR3-based operating systems, perhaps even SVR2. See the README >and midi.7 files for more info. The right way to do something like >this is to use streams. This is a quick and dirty (but also quite >usable) hack. > Tim Thompson = tjt@twitch.att.com | att!twitch!tjt [shell archive deleted] Any chance of a psuedo driver that would use the standard tty driver in external baud rate mode? (Please cross post to rec.music - thanks)