mike@orca.WV.TEK.COM (Mike Witt) (09/13/89)
Does anyone out there have any experience with a MIDI setup for a regular UNIX workstation? That is, a MIDI interface that connects to a standard RS232 port and sequencing or other software that runs on UNIX. Mike Witt mike@orca.wv.tek.com
dag@hp-lsd.COS.HP.COM (David Geiser) (09/26/89)
Silence? I, too, am UNIX based and would be interested in obtaining/porting/hacking MIDI SW. dag a.k.a. David Geiser (719) 590-5038 same last 7 for Yelnet* *Trademark*
paul@hpldola.HP.COM (Paul Bame) (09/28/89)
MIDI on UN*X isn't a new idea of course. This is a fun reference. Hardware presented in the article is for a Multibus SUN and an MPU-401 but the software seems pretty generic. Some of the MIDI books might be useful since much of the software is in C anyway. Anybody know of a MIDI controller (aka MPU-401) with an RS-232 port? Yeah, I know it's probably too slow but if the buffer was big enough... MIDI Music Software for UN*X Michael Hawley - The Droid Works Proceedings of the 1986 Summer USENIX Conference - Page 1
sahayman@iuvax.cs.indiana.edu (Steve Hayman) (09/29/89)
>Anybody know of a MIDI controller (aka MPU-401) with an RS-232 port? Yeah, >I know it's probably too slow but if the buffer was big enough... An Atari ST (with some simple software) would make a nice MIDI-to-RS232 converter. It's got the ports already, lots of memory, and it's cheap. You wouldn't even need the monitor, and if you could arrange to put the software on cartridge, you wouldn't even need a floppy drive. (I'm not volunteering to write the software.)
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)