Xref: utzoo comp.music:130 rec.music.synth:9266
Path: utzoo!utgpu!attcan!uunet!ginosko!brutus.cs.uiuc.edu!psuvax1!rutgers!att!cbnewsh!tjt
From: tjt@cbnewsh.ATT.COM (timothy.j.thompson)
Newsgroups: comp.music,rec.music.synth
Subject: Re: Unix MIDI software
Message-ID: <4401@cbnewsh.ATT.COM>
Date: 1 Oct 89 16:49:41 GMT
References: <10430001@hp-lsd.COS.HP.COM>
Organization: AT&T Bell Laboratories
Lines: 966
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
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* 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; nbuf[(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; nin.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; nin.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 < 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
#include
#include
#include
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
#include
#include
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 '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
#include
#include
#include
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