ain@j.cc.purdue.edu (Patrick White) (03/25/88)
Program Name: midi library (part 1 of 1)
Submitted By: Pete Yadlowsky <pmy@vivaldi.acc.virginia.edu>
Summary: This is a midi library
Poster Boy: Pat White (ain@j.cc.purdue.edu)
Untested.
NOTES:
Not much we could do to test this, so we didn't bother.
I reshar'ed it to separate docs, etc.
example code posted to sources as it is source.
-- Pat White (co-moderator comp.sources/binaries.amiga)
UUCP: j.cc.purdue.edu!ain BITNET: PATWHITE@PURCCVM PHONE: (317) 743-8421
U.S. Mail: 320 Brown St. apt. 406, West Lafayette, IN 47906
========================================
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# asmsupp.i
# midi.h
# midi.i
# midibase.h
# midibase.i
# This archive created: Sun Mar 20 16:49:59 1988
# By: Patrick White (PUCC Land, USA)
echo shar: extracting asmsupp.i '(452 characters)'
cat << \SHAR_EOF > asmsupp.i
*
* asmsupp.i - some handy (read essential) macros
*
ifnd _ASMSUPP_I
_ASMSUPP_I set 1
ifnd EXEC_LIBRARIES_I
include "exec/libraries.i"
endc
CLEAR macro
moveq #0,\1
endm
LINKSYS macro
LINKLIB _LVO\1,\2
endm
CALLSYS macro
CALLLIB _LVO\1
endm
XLIB macro
xref _LVO\1
endm
FUNCDEF macro
public _LVO\1
LIBDEF _LVO\1
endm
push macro
movem.l \1,-(sp)
endm
pop macro
movem.l (sp)+,\1
endm
CLEARA macro
suba.l \1,\1
endm
endc
SHAR_EOF
if test 452 -ne "`wc -c asmsupp.i`"
then
echo shar: error transmitting asmsupp.i '(should have been 452 characters)'
fi
echo shar: extracting midi.h '(4193 characters)'
cat << \SHAR_EOF > midi.h
#ifndef MIDI_MIDI_H
#define MIDI_MIDI_H
#ifndef EXEC_LISTS_H
#include <exec/lists.h>
#endif
#ifndef EXEC_PORTS_H
#include <exec/ports.h>
#endif
/* midi.library structures & defines */
#define MIDINAME "midi.library"
#define MIDIVERSION 1L
struct MSource {
struct Node Node;
struct Image *Image;
struct MinList RPList;
APTR UserData; /* user data extension */
};
/* node types for Source */
#define NT_MSOURCE 0x20
#define NT_PERMMSOURCE 0x21
struct MDest {
struct Node Node;
struct Image *Image;
struct MinList RPList;
struct MsgPort *DestPort;
APTR UserData; /* user data extension */
};
/* node types for Dest */
#define NT_MDEST 0x22
#define NT_PERMMDEST 0x23
struct RIMatch {
UBYTE count; /* 0 for match all */
UBYTE match[3];
};
struct MRouteInfo {
UWORD MsgFlags;
UWORD ChanFlags;
BYTE ChanOffset;
BYTE NoteOffset;
struct RIMatch SysExMatch;
struct RIMatch CtrlMatch;
};
/* Msg Flags for MRouteInfo structure and returned by MidiMsgType */
#define MMF_CHAN 0x00ff
#define MMF_NOTEOFF 0x0001
#define MMF_NOTEON 0x0002
#define MMF_POLYPRESS 0x0004
#define MMF_CTRL 0x0008
#define MMF_PROG 0x0010
#define MMF_CHANPRESS 0x0020
#define MMF_PITCHBEND 0x0040
#define MMF_MODE 0x0080
#define MMF_SYSCOM 0x0100
#define MMF_SYSRT 0x0200
#define MMF_SYSEX 0x0400
struct MRoutePtr {
struct MinNode node;
struct MRoute *Route;
};
struct MRoute {
struct MSource *Source;
struct MDest *Dest;
struct MRoutePtr SRoutePtr, DRoutePtr;
struct MRouteInfo RouteInfo;
};
/* MIDI message defines - based on IMA MIDI Spec 1.0 except where noted */
/* Status Bytes */
/* Channel Voice Messages (1sssnnnn) */
#define MS_NOTEOFF 0x80
#define MS_NOTEON 0x90
#define MS_POLYPRESS 0xA0
#define MS_CTRL 0xB0
#define MS_MODE 0xB0
#define MS_PROG 0xC0
#define MS_CHANPRESS 0xD0
#define MS_PITCHBEND 0xE0
/* System Common Messages */
#define MS_SYSEX 0xF0
#define MS_SONGPOS 0xF2
#define MS_SONGSELECT 0xF3
#define MS_TUNEREQ 0xF6
#define MS_EOX 0xF7
/* System Real Time Messages */
#define MS_CLOCK 0xF8
#define MS_START 0xFA
#define MS_CONTINUE 0xFB
#define MS_STOP 0xFC
#define MS_ACTVSENSE 0xFE
#define MS_RESET 0xFF
/* Standard Controllers (from MMA - 8-86)
/* proportional MSB - 0-31, LSB - 32-63 */
#define MC_MODWHEEL 1
#define MC_BREATH 2
#define MC_FOOT 4
#define MC_PORTATIME 5
#define MC_DATAENTRY 6
#define MC_VOLUME 7
#define MC_BALANCE 8
#define MC_PAN 10
/* switches/pedals - either on(7F) or off(00) */
#define MC_SUSTAIN 64
#define MC_PORTA 65
#define MC_SUSTENUTO 66
#define MC_SOFTPEDAL 67
#define MC_HOLD2 69
#define MC_DATAINCR 96
#define MC_DATADECR 97
/* Channel Modes */
#define MM_LOCAL 122
#define MM_ALLOFF 123
#define MM_OMNIOFF 124
#define MM_OMNION 125
#define MM_MONO 126
#define MM_POLY 127
/* Sys/Ex ID numbers (from MMA as described in IMA bulletin) */
#define MID_SCI 0x01
#define MID_BIGBRIAR 0x02
#define MID_OCTAVEPLATEAU 0x03
#define MID_MOOG 0x04
#define MID_PASSPORT 0x05
#define MID_LEXICON 0x06
#define MID_OBERHEIM 0x10
#define MID_PAIA 0x11
#define MID_SIMMONS 0x12
#define MID_FAIRLIGHT 0x14
#define MID_BONTEMPI 0x20
#define MID_SIEL 0x21
#define MID_SYNTHAXE 0x23
#define MID_KAWAI 0x40
#define MID_ROLAND 0x41
#define MID_KORG 0x42
#define MID_YAMAHA 0x43
/* special Sys/Ex ID numbers: Non-Commercial, Non-Real Time, Real Time */
#define MID_NC 0x7d
#define MID_NRT 0x7e
#define MID_RT 0x7f
/* handy macros */
/* pack high/low bytes of a word into midi format */
#define MIDI_HIBYTE(word) ( (word) >> 7 & 0x7f )
#define MIDI_LOBYTE(word) ( (word) & 0x7f )
/* unpack 2 midi bytes into a word */
#define MIDI_WORD(hi,lo) ( (hi & 0x7f) << 7 | (lo & 0x7f) )
/* midi.library routine declarations */
struct MSource *CreateMSource(), *FindMSource();
struct MDest *CreateMDest(), *FindMDest();
struct MRoute *CreateMRoute(), *MRouteSource(), *MRouteDest(), *MRoutePublic();
UBYTE *GetMidiMsg();
BOOL PutMidiMsg();
ULONG MidiMsgLength(), MidiMsgType();
#endif
SHAR_EOF
if test 4193 -ne "`wc -c midi.h`"
then
echo shar: error transmitting midi.h '(should have been 4193 characters)'
fi
echo shar: extracting midi.i '(3204 characters)'
cat << \SHAR_EOF > midi.i
; midi/midi.i
ifnd MIDI_MIDI_I
MIDI_MIDI_I set 1
ifnd EXEC_LISTS_I
include "exec/lists.i"
endc
MIDINAME macro
dc.b 'midi.library',0
endm
MIDIVERSION equ 1
STRUCTURE MSource,LN_SIZE
APTR ms_Image
STRUCT ms_RPList,MLH_SIZE
APTR ms_UserData
LABEL sizeof_MSource
; Node Types for MSource nodes
NT_MSOURCE equ $20
NT_PERMMSOURCE equ $21
STRUCTURE MDest,LN_SIZE
APTR md_Image
STRUCT md_RPList,MLH_SIZE
APTR md_DestPort
APTR md_UserData
LABEL sizeof_MDest
; Node Types for MDest nodes
NT_MDEST equ $22
NT_PERMMDEST equ $23
STRUCTURE RIMatch,0
UBYTE rim_count
STRUCT rim_match,3
LABEL sizeof_RIMatch
STRUCTURE MRouteInfo,0
UWORD ri_MsgFlags
UWORD ri_ChanFlags
BYTE ri_ChanOffset
BYTE ri_NoteOffset
STRUCT ri_SysExMatch,sizeof_RIMatch
STRUCT ri_CtrlMatch,sizeof_RIMatch
LABEL sizeof_MRouteInfo
; Midi Msg Type Flags for RouteInfo and returned by MidiMsgType
MMF_CHAN equ $00ff
MMF_NOTEOFF equ $0001
MMF_NOTEON equ $0002
MMF_POLYPRESS equ $0004
MMF_CTRL equ $0008
MMF_PROG equ $0010
MMF_CHANPRESS equ $0020
MMF_PITCHBEND equ $0040
MMF_MODE equ $0080
MMF_SYSCOM equ $0100
MMF_SYSRT equ $0200
MMF_SYSEX equ $0400
STRUCTURE MRoutePtr,MLN_SIZE
APTR rp_Route
LABEL sizeof_MRoutePtr
STRUCTURE MRoute,0
APTR mr_Source
APTR mr_Dest
STRUCT mr_SRoutePtr,sizeof_MRoutePtr
STRUCT mr_DRoutePtr,sizeof_MRoutePtr
STRUCT mr_RouteInfo,sizeof_MRouteInfo
LABEL sizeof_MRoute
; MIDI message defines - based on IMA MIDI Spec 1.0 except where noted
; Status Bytes
; Channel Voice Messages (1sssnnnn)
MS_NOTEOFF equ $80
MS_NOTEON equ $90
MS_POLYPRESS equ $A0
MS_CTRL equ $B0
MS_MODE equ $B0
MS_PROG equ $C0
MS_CHANPRESS equ $D0
MS_PITCHBEND equ $E0
; System Common Messages
MS_SYSEX equ $F0
MS_SONGPOS equ $F2
MS_SONGSELECT equ $F3
MS_TUNEREQ equ $F6
MS_EOX equ $F7
; System Real Time Messages
MS_CLOCK equ $F8
MS_START equ $FA
MS_CONTINUE equ $FB
MS_STOP equ $FC
MS_ACTVSENSE equ $FE
MS_RESET equ $FF
; Standard Controllers (from MMA - 8-86)
; proportional MSB - 0-31, LSB - 32-63
MC_MODWHEEL equ 1
MC_BREATH equ 2
MC_FOOT equ 4
MC_PORTATIME equ 5
MC_DATAENTRY equ 6
MC_VOLUME equ 7
MC_BALANCE equ 8
MC_PAN equ 10
; switches/pedals - either on(7F) or off(00)
MC_SUSTAIN equ 64
MC_PORTA equ 65
MC_SUSTENUTO equ 66
MC_SOFTPEDAL equ 67
MC_HOLD2 equ 69
MC_DATAINCR equ 96
MC_DATADECR equ 97
; Channel Modes
MM_LOCAL equ 122
MM_ALLOFF equ 123
MM_OMNIOFF equ 124
MM_OMNION equ 125
MM_MONO equ 126
MM_POLY equ 127
; Sys/Ex ID numbers (from MMA as described in IMA bulletin)
MID_SCI equ $01
MID_BIGBRIAR equ $02
MID_OCTAVEPLATEAU equ $03
MID_MOOG equ $04
MID_PASSPORT equ $05
MID_LEXICON equ $06
MID_OBERHEIM equ $10
MID_PAIA equ $11
MID_SIMMONS equ $12
MID_FAIRLIGHT equ $14
MID_BONTEMPI equ $20
MID_SIEL equ $21
MID_SYNTHAXE equ $23
MID_KAWAI equ $40
MID_ROLAND equ $41
MID_KORG equ $42
MID_YAMAHA equ $43
; special Sys/Ex ID numbers: Non-Commercial, Non-Real Time, Real Time
MID_NC equ $7d
MID_NRT equ $7e
MID_RT equ $7f
endc
SHAR_EOF
if test 3204 -ne "`wc -c midi.i`"
then
echo shar: error transmitting midi.i '(should have been 3204 characters)'
fi
echo shar: extracting midibase.h '(1206 characters)'
cat << \SHAR_EOF > midibase.h
#ifndef MIDI_MIDIBASE_H
#define MIDI_MIDIBASE_H
/* midi.library MidiBase & related definitions (not for the casual midi user) */
#ifndef EXEC_LIBRARIES_H
#include <exec/libraries.h>
#endif
#ifndef EXEC_SEMAPHORES_H
#include <exec/semaphores.h>
#endif
#ifndef LIBRARIES_DOS_H
#include <libraries/dos.h>
#endif
#ifndef MIDI_MIDI_H
#include <midi/midi.h>
#endif
struct MidiBase {
struct Library libnode;
struct List SourceList,DestList;
struct SignalSemaphore ListSemaphore; /* blocks Source/Dest list management */
struct SignalSemaphore RouteSemaphore; /* blocks RPList management & msg routing */
ULONG SegList;
APTR SysBase,DosBase;
};
struct MTaskInfo {
/* set by caller */
char *Name;
WORD Pri;
void (*Entry)();
UWORD Stack;
UWORD Sources;
struct MNodeInfo *SourceList;
UWORD Dests;
struct MNodeInfo *DestList;
/* set by midi.library */
struct SignalSemaphore Semaphore; /* locks task */
UWORD UsageCount; /* task's usage count */
struct MsgPort *TaskPort; /* task's MsgPort */
BPTR Segment; /* task's Segment */
};
struct MNodeInfo {
char *Name;
struct Image *Image;
APTR Node;
};
#endif
SHAR_EOF
if test 1206 -ne "`wc -c midibase.h`"
then
echo shar: error transmitting midibase.h '(should have been 1206 characters)'
fi
echo shar: extracting midibase.i '(1500 characters)'
cat << \SHAR_EOF > midibase.i
; midi/midibase.i
ifnd MIDI_MIDIBASE_I
MIDI_MIDIBASE_I set 1
ifnd EXEC_LIBRARIES_I
include "exec/libraries.i"
endc
ifnd EXEC_SEMAPHORES_I
include "exec/semaphores.i"
endc
ifnd LIBRARIES_DOS_I
include "libraries/dos.i"
endc
ifnd MIDI_MIDI_I
include "midi/midi.i"
endc
STRUCTURE MidiBase,LIB_SIZE ; Library Base
STRUCT ml_SourceList,LH_SIZE ; Source List
STRUCT ml_DestList,LH_SIZE ; Dest List
STRUCT ml_ListSemaphore,SS_SIZE ; locks source/dest lists - blocks Src & Dst list management
; (locked when LockBase is called)
STRUCT ml_RouteSemaphore,SS_SIZE ; locks routes - blocks msg routing & RPList management in Src & Dst
ULONG ml_SegList ; Segment List for the library
ULONG ml_SysBase ; SysBase
ULONG ml_DosBase ; DosBase
LABEL sizeof_MidiBase
STRUCTURE MTaskInfo,0 ; Task info structure for PermNodes
APTR ti_Name ; Process Name
WORD ti_Pri ; Process Priority
APTR ti_Entry ; Entry point
UWORD ti_Stack ; Stack Size
UWORD ti_Sources ; source count
APTR ti_SourceList ; source list
UWORD ti_Dests ; dest count
APTR ti_DestList ; dest list
STRUCT ti_Semaphore,SS_SIZE ; signal semaphore for locking this task
UWORD ti_UsageCount
APTR ti_TaskPort ; task's MsgPort
BPTR ti_Segment ; BPTR pointer to tasks segment
LABEL sizeof_MTaskInfo
STRUCTURE MNodeInfo,0 ; PermNode info structure
APTR ni_Name ; Node Name
APTR ni_Image ; Node Image
APTR ni_Node ; Node pointer
LABEL sizeof_MNodeInfo
endc
SHAR_EOF
if test 1500 -ne "`wc -c midibase.i`"
then
echo shar: error transmitting midibase.i '(should have been 1500 characters)'
fi
# End of shell archive
exit 0ain@j.cc.purdue.edu (Patrick White) (03/25/88)
Program Name: midi library (lib source) Submitted By: Pete Yadlowsky <pmy@vivaldi.acc.virginia.edu> Summary: This is a midi library Poster Boy: Pat White (ain@j.cc.purdue.edu) Untested. NOTES: Not much we could do to test this, so we didn't bother. I reshar'ed it to separate docs, etc. -- Pat White (co-moderator comp.sources/binaries.amiga) UUCP: j.cc.purdue.edu!ain BITNET: PATWHITE@PURCCVM PHONE: (317) 743-8421 U.S. Mail: 320 Brown St. apt. 406, West Lafayette, IN 47906 ======================================== # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # Makefile # credst.asm # crerte.asm # cresrc.asm # deldst.asm # delrte.asm # delsrc.asm # finddst.asm # findsrc.asm # freemsg.asm # getmsg.asm # lockbase.asm # midilvo.asm # modrte.asm # msglen.asm # msgtype.asm # putmsg.asm # putstr.asm # rtedst.asm # rtepub.asm # rtesrc.asm # unlockba.asm # This archive created: Sun Mar 20 16:45:19 1988 # By: Patrick White (PUCC Land, USA) echo shar: extracting Makefile '(381 characters)' cat << \SHAR_EOF > Makefile # midi.lib makefile CFLAGS=-n +b AFLAGS= MIDI_LIB=\ credst.o crerte.o cresrc.o deldst.o delrte.o delsrc.o finddst.o\ findsrc.o freemsg.o getmsg.o lockbase.o modrte.o msglen.o msgtype.o\ putmsg.o putstr.o rtedst.o rtepub.o rtesrc.o unlockba.o midilvo.o all: midi.lib midi.lib: $(MIDI_LIB) lb $@ $(MIDI_LIB) #midilvo.asm: /lib/midibase.asm # makelvo /lib/midibase midilvo SHAR_EOF if test 381 -ne "`wc -c Makefile`" then echo shar: error transmitting Makefile '(should have been 381 characters)' fi echo shar: extracting credst.asm '(217 characters)' cat << \SHAR_EOF > credst.asm public _MidiBase,_LVOCreateMDest ; struct MDest *CreateMDest (name,image) ; char *name; ; struct Image *image; public _CreateMDest _CreateMDest movem.l 4(sp),a0-a1 move.l _MidiBase,a6 jmp _LVOCreateMDest(a6) SHAR_EOF if test 217 -ne "`wc -c credst.asm`" then echo shar: error transmitting credst.asm '(should have been 217 characters)' fi echo shar: extracting crerte.asm '(316 characters)' cat << \SHAR_EOF > crerte.asm public _MidiBase,_LVOCreateMRoute ; struct Route *CreateMRoute (source,dest,routeinfo) ; Struct MSource *source; ; Struct MDest *dest; ; Struct MRouteInfo *routeinfo; public _CreateMRoute _CreateMRoute movem.l a2,-(sp) movem.l 8(sp),a0-a2 move.l _MidiBase,a6 jsr _LVOCreateMRoute(a6) movem.l (sp)+,a2 rts SHAR_EOF if test 316 -ne "`wc -c crerte.asm`" then echo shar: error transmitting crerte.asm '(should have been 316 characters)' fi echo shar: extracting cresrc.asm '(229 characters)' cat << \SHAR_EOF > cresrc.asm public _MidiBase,_LVOCreateMSource ; struct MSource *CreateMSource (name,image) ; char *name; ; struct Image *image; public _CreateMSource _CreateMSource movem.l 4(sp),a0-a1 move.l _MidiBase,a6 jmp _LVOCreateMSource(a6) SHAR_EOF if test 229 -ne "`wc -c cresrc.asm`" then echo shar: error transmitting cresrc.asm '(should have been 229 characters)' fi echo shar: extracting deldst.asm '(177 characters)' cat << \SHAR_EOF > deldst.asm public _MidiBase,_LVODeleteMDest ; DeleteMDest (dest) ; struct MDest *dest; public _DeleteMDest _DeleteMDest move.l 4(sp),a0 move.l _MidiBase,a6 jmp _LVODeleteMDest(a6) SHAR_EOF if test 177 -ne "`wc -c deldst.asm`" then echo shar: error transmitting deldst.asm '(should have been 177 characters)' fi echo shar: extracting delrte.asm '(185 characters)' cat << \SHAR_EOF > delrte.asm public _MidiBase,_LVODeleteMRoute ; DeleteMRoute (route) ; struct MRoute *route; public _DeleteMRoute _DeleteMRoute move.l 4(sp),a0 move.l _MidiBase,a6 jmp _LVODeleteMRoute(a6) SHAR_EOF if test 185 -ne "`wc -c delrte.asm`" then echo shar: error transmitting delrte.asm '(should have been 185 characters)' fi echo shar: extracting delsrc.asm '(193 characters)' cat << \SHAR_EOF > delsrc.asm public _MidiBase,_LVODeleteMSource ; DeleteMSource (source) ; struct MSource *source; public _DeleteMSource _DeleteMSource move.l 4(sp),a0 move.l _MidiBase,a6 jmp _LVODeleteMSource(a6) SHAR_EOF if test 193 -ne "`wc -c delsrc.asm`" then echo shar: error transmitting delsrc.asm '(should have been 193 characters)' fi echo shar: extracting finddst.asm '(173 characters)' cat << \SHAR_EOF > finddst.asm public _MidiBase,_LVOFindMDest ; struct MDest *FindMDest (name) ; char *name; public _FindMDest _FindMDest move.l 4(sp),a0 move.l _MidiBase,a6 jmp _LVOFindMDest(a6) SHAR_EOF if test 173 -ne "`wc -c finddst.asm`" then echo shar: error transmitting finddst.asm '(should have been 173 characters)' fi echo shar: extracting findsrc.asm '(185 characters)' cat << \SHAR_EOF > findsrc.asm public _MidiBase,_LVOFindMSource ; struct MSource *FindMSource (name) ; char *name; public _FindMSource _FindMSource move.l 4(sp),a0 move.l _MidiBase,a6 jmp _LVOFindMSource(a6) SHAR_EOF if test 185 -ne "`wc -c findsrc.asm`" then echo shar: error transmitting findsrc.asm '(should have been 185 characters)' fi echo shar: extracting freemsg.asm '(169 characters)' cat << \SHAR_EOF > freemsg.asm public _MidiBase,_LVOFreeMidiMsg ; FreeMidiMsg (msg) ; UBYTE *msg; public _FreeMidiMsg _FreeMidiMsg movem.l 4(sp),a0 move.l _MidiBase,a6 jmp _LVOFreeMidiMsg(a6) SHAR_EOF if test 169 -ne "`wc -c freemsg.asm`" then echo shar: error transmitting freemsg.asm '(should have been 169 characters)' fi echo shar: extracting getmsg.asm '(179 characters)' cat << \SHAR_EOF > getmsg.asm public _MidiBase,_LVOGetMidiMsg ; UBYTE *GetMidiMsg (dest) ; struct MDest *dest public _GetMidiMsg _GetMidiMsg movem.l 4(sp),a0 move.l _MidiBase,a6 jmp _LVOGetMidiMsg(a6) SHAR_EOF if test 179 -ne "`wc -c getmsg.asm`" then echo shar: error transmitting getmsg.asm '(should have been 179 characters)' fi echo shar: extracting lockbase.asm '(138 characters)' cat << \SHAR_EOF > lockbase.asm public _MidiBase,_LVOLockMidiBase ; LockMidiBase() public _LockMidiBase _LockMidiBase move.l _MidiBase,a6 jmp _LVOLockMidiBase(a6) SHAR_EOF if test 138 -ne "`wc -c lockbase.asm`" then echo shar: error transmitting lockbase.asm '(should have been 138 characters)' fi echo shar: extracting midilvo.asm '(606 characters)' cat << \SHAR_EOF > midilvo.asm ; midilvo.asm - library routine definitions ; file created automatically by MakeLVO include "exec/types.i" include "exec/libraries.i" include "asmsupp.i" LIBINIT FUNCDEF LockMidiBase FUNCDEF UnlockMidiBase FUNCDEF CreateMSource FUNCDEF DeleteMSource FUNCDEF FindMSource FUNCDEF CreateMDest FUNCDEF DeleteMDest FUNCDEF FindMDest FUNCDEF CreateMRoute FUNCDEF ModifyMRoute FUNCDEF DeleteMRoute FUNCDEF MRouteSource FUNCDEF MRouteDest FUNCDEF MRoutePublic FUNCDEF GetMidiMsg FUNCDEF PutMidiMsg FUNCDEF FreeMidiMsg FUNCDEF MidiMsgType FUNCDEF MidiMsgLength FUNCDEF PutMidiStream end SHAR_EOF if test 606 -ne "`wc -c midilvo.asm`" then echo shar: error transmitting midilvo.asm '(should have been 606 characters)' fi echo shar: extracting modrte.asm '(237 characters)' cat << \SHAR_EOF > modrte.asm public _MidiBase,_LVOModifyMRoute ; ModifyMRoute (route,newrouteinfo) ; struct MRoute *route; ; struct MRouteInfo *newrouteinfo; public _ModifyMRoute _ModifyMRoute movem.l 4(sp),a0-a1 move.l _MidiBase,a6 jmp _LVOModifyMRoute(a6) SHAR_EOF if test 237 -ne "`wc -c modrte.asm`" then echo shar: error transmitting modrte.asm '(should have been 237 characters)' fi echo shar: extracting msglen.asm '(178 characters)' cat << \SHAR_EOF > msglen.asm public _MidiBase,_LVOMidiMsgLength ; MidiMsgLength (msg) ; UBYTE *msg; public _MidiMsgLength _MidiMsgLength move.l 4(sp),a0 move.l _MidiBase,a6 jmp _LVOMidiMsgLength(a6) SHAR_EOF if test 178 -ne "`wc -c msglen.asm`" then echo shar: error transmitting msglen.asm '(should have been 178 characters)' fi echo shar: extracting msgtype.asm '(168 characters)' cat << \SHAR_EOF > msgtype.asm public _MidiBase,_LVOMidiMsgType ; MidiMsgType (msg) ; UBYTE *msg; public _MidiMsgType _MidiMsgType move.l 4(sp),a0 move.l _MidiBase,a6 jmp _LVOMidiMsgType(a6) SHAR_EOF if test 168 -ne "`wc -c msgtype.asm`" then echo shar: error transmitting msgtype.asm '(should have been 168 characters)' fi echo shar: extracting putmsg.asm '(200 characters)' cat << \SHAR_EOF > putmsg.asm public _MidiBase,_LVOPutMidiMsg ; PutMidiMsg (source,msg) ; struct MSource *source; ; UBYTE *msg; public _PutMidiMsg _PutMidiMsg movem.l 4(sp),a0-a1 move.l _MidiBase,a6 jmp _LVOPutMidiMsg(a6) SHAR_EOF if test 200 -ne "`wc -c putmsg.asm`" then echo shar: error transmitting putmsg.asm '(should have been 200 characters)' fi echo shar: extracting putstr.asm '(360 characters)' cat << \SHAR_EOF > putstr.asm public _MidiBase,_LVOPutMidiStream ; void PutMidiStream (source,fillbuffer,buf,bufsize,cursize) ; struct MSource *source; ; ULONG (*fillbuffer)(); ; UBYTE *buf; ; ULONG bufsize,cursize; public _PutMidiStream _PutMidiStream movem.l a2,-(sp) movem.l 8(sp),a0-a2 movem.l 20(sp),d0-d1 move.l _MidiBase,a6 jsr _LVOPutMidiStream(a6) movem.l (sp)+,a2 rts SHAR_EOF if test 360 -ne "`wc -c putstr.asm`" then echo shar: error transmitting putstr.asm '(should have been 360 characters)' fi echo shar: extracting rtedst.asm '(301 characters)' cat << \SHAR_EOF > rtedst.asm public _MidiBase,_LVOMRouteDest ; struct MRoute *MRouteDest (sourcename,dest,midiinfo) ; char *sourcename; ; struct MDest *dest; ; struct MidiInfo *midiinfo; public _MRouteDest _MRouteDest movem.l a2,-(sp) movem.l 8(sp),a0-a2 move.l _MidiBase,a6 jsr _LVOMRouteDest(a6) movem.l (sp)+,a2 rts SHAR_EOF if test 301 -ne "`wc -c rtedst.asm`" then echo shar: error transmitting rtedst.asm '(should have been 301 characters)' fi echo shar: extracting rtepub.asm '(307 characters)' cat << \SHAR_EOF > rtepub.asm public _MidiBase,_LVOMRoutePublic ; struct MRoute *MRoutePublic (sourcename,destname,routeinfo) ; char *sourcename,*destname; ; struct MRouteInfo *routeinfo; public _MRoutePublic _MRoutePublic movem.l a2,-(sp) movem.l 8(sp),a0-a2 move.l _MidiBase,a6 jsr _LVOMRoutePublic(a6) movem.l (sp)+,a2 rts SHAR_EOF if test 307 -ne "`wc -c rtepub.asm`" then echo shar: error transmitting rtepub.asm '(should have been 307 characters)' fi echo shar: extracting rtesrc.asm '(317 characters)' cat << \SHAR_EOF > rtesrc.asm public _MidiBase,_LVOMRouteSource ; struct MRoute *MRouteSource (source,destname,routeinfo) ; Struct MSource *source; ; char *destname; ; Struct MRouteInfo *routeinfo; public _MRouteSource _MRouteSource movem.l a2,-(sp) movem.l 8(sp),a0-a2 move.l _MidiBase,a6 jsr _LVOMRouteSource(a6) movem.l (sp)+,a2 rts SHAR_EOF if test 317 -ne "`wc -c rtesrc.asm`" then echo shar: error transmitting rtesrc.asm '(should have been 317 characters)' fi echo shar: extracting unlockba.asm '(148 characters)' cat << \SHAR_EOF > unlockba.asm public _MidiBase,_LVOUnlockMidiBase ; UnlockMidiBase() public _UnlockMidiBase _UnlockMidiBase move.l _MidiBase,a6 jmp _LVOUnlockMidiBase(a6) SHAR_EOF if test 148 -ne "`wc -c unlockba.asm`" then echo shar: error transmitting unlockba.asm '(should have been 148 characters)' fi # End of shell archive exit 0
ain@j.cc.purdue.edu (Patrick White) (03/25/88)
Program Name: midi library (example code)
Submitted By: Pete Yadlowsky <pmy@vivaldi.acc.virginia.edu>
Summary: This is a midi library
Poster Boy: Pat White (ain@j.cc.purdue.edu)
Untested.
NOTES:
Not much we could do to test this, so we didn't bother.
I reshar'ed it to separate docs, etc.
example source
-- Pat White (co-moderator comp.sources/binaries.amiga)
UUCP: j.cc.purdue.edu!ain BITNET: PATWHITE@PURCCVM PHONE: (317) 743-8421
U.S. Mail: 320 Brown St. apt. 406, West Lafayette, IN 47906
========================================
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# hr.c
# ht.c
# makefile
# r.c
# rsx.c
# tsx.c
# This archive created: Sun Mar 20 16:42:58 1988
# By: Patrick White (PUCC Land, USA)
echo shar: extracting hr.c '(2589 characters)'
cat << \SHAR_EOF > hr.c
/* hex receive from midi.library */
/*
display incoming MIDI messages in Hex to the console.
Shows proper method of waiting for, receiving, processing, and disposing
of MIDI messages.
*/
#include <libraries/dos.h>
#include <clib/macros.h>
#include <midi/midi.h>
#include <functions.h>
#include <stdio.h>
void *MidiBase;
struct MDest *dest;
struct MRoute *route;
UBYTE *msg; /* buffer this in case we get shut down before freeing the current message */
main(argc,argv)
char **argv;
{
char *sname = "MidiIn";
static struct MRouteInfo routeinfo = { -1, -1 }; /* route spec's: receive all */
printf ("MIDI Hex Display\n");
if (argc > 1 && *argv[1] == '?') {
printf ("usage: hr [source]\n");
exit (1);
}
if (!(MidiBase = OpenLibrary (MIDINAME,MIDIVERSION))) {
printf ("can't open midi.library\n");
goto clean;
}
if (argc > 1) { /* if there's an argument, use it as an alt. source name */
sname = argv[1];
}
/* create out dest node (private) */
if (!(dest = CreateMDest (NULL,NULL))) {
printf ("can't create Dest\n");
goto clean;
}
/* create out route to MidiIn or whatever the user specified */
if (!(route = MRouteDest (sname, dest, &routeinfo))) {
printf ("can't create Route (can't find source \"%s\"?)\n",sname);
goto clean;
}
process(dest); /* process until shutdown */
clean:
cleanup();
}
_abort() /* abort routine called when CTRL-C is hit (Aztec) */
{
fflush(stdout);
cleanup();
exit (1);
}
cleanup()
{
if (msg) FreeMidiMsg (msg);
if (route) DeleteMRoute (route);
if (dest) DeleteMDest (dest);
if (MidiBase) CloseLibrary (MidiBase);
}
process (dest)
struct MDest *dest;
{
ULONG flags = SIGBREAKF_CTRL_C | (1L << dest->DestPort->mp_SigBit);
while (!(Wait(flags) & SIGBREAKF_CTRL_C)) { /* wait until we get a message or CTRL-C is hit, quit on CTRL-C */
while (msg = GetMidiMsg (dest)) { /* get a message */
dumpmsg (msg); /* print it */
FreeMidiMsg (msg); /* free it */
}
}
}
dumpmsg (msg)
UBYTE *msg;
{
long len = MidiMsgLength (msg); /* find out how long the message is */
if (*msg == MS_SYSEX) { /* if it's a System Exclusive message... */
dump (msg,MIN(len,8)); /* only print the first 8 bytes */
printf ("... (%ld bytes)\n",len);
}
else { /* otherwise */
dump (msg,MidiMsgLength(msg)); /* print the whole message */
printf ("\n");
}
}
dump (s,len) /* print len bytes in hex */
UBYTE *s;
long len;
{
while (len--) printf ("%02x ",*s++);
}
SHAR_EOF
if test 2589 -ne "`wc -c hr.c`"
then
echo shar: error transmitting hr.c '(should have been 2589 characters)'
fi
echo shar: extracting ht.c '(1784 characters)'
cat << \SHAR_EOF > ht.c
/* simplified Hex Transmit to midi */
/*
Shows usage of PutMidiStream() when buffer size is known and of managable
size.
*/
#include <midi/midi.h>
#include <functions.h>
void *MidiBase;
main (argc,argv)
char **argv;
{
struct MSource *source=0;
struct MRoute *route=0;
static struct MRouteInfo routeinfo = { -1, -1 }; /* route spec's: transmit all */
char buf[128]; /* buffer used for midi transfer */
long len;
extern int Enable_Abort;
Enable_Abort = 0; /* disable auto CTRL-C termination */
if (argc < 2) {
printf ("MIDI Hex Transmit\n");
printf ("usage: ht <hex byte>...\n");
exit (1);
}
if (!(MidiBase = OpenLibrary (MIDINAME,MIDIVERSION))) {
printf ("can't open midi.library\n");
goto clean;
}
/* create our Source node (private) */
if (!(source = CreateMSource (NULL,NULL))) {
printf ("can't create Source\n");
goto clean;
}
/* create out Route to MidiOut */
if (!(route = MRouteSource (source,"MidiOut",&routeinfo))) {
printf ("can't create Route (can't find MidiOut?)\n");
goto clean;
}
/* parse the command line for hex bytes, make into an array */
len = makestream (buf,argc-1,argv+1);
/* convert array to midi messages and send */
PutMidiStream (source,NULL,buf,len,len);
clean: /* clean up */
if (route) DeleteMRoute (route);
if (source) DeleteMSource (source);
if (MidiBase) CloseLibrary (MidiBase);
}
makestream (buf,argc,argv) /* convert args into an array of bytes, return length */
char *buf;
char **argv;
{
int len=0;
while (argc--) {
*buf++ = atox(*argv++);
len++;
}
return len;
}
atox(cp) /* like atoi() but read string as hex rather than decimal */
char *cp;
{
int x;
sscanf (cp,"%x",&x);
return x;
}
SHAR_EOF
if test 1784 -ne "`wc -c ht.c`"
then
echo shar: error transmitting ht.c '(should have been 1784 characters)'
fi
echo shar: extracting makefile '(190 characters)'
cat << \SHAR_EOF > makefile
all: ht hr rsx tsx r
ht: ht.o
ln +q ht.o -lmidi -lc
hr: hr.o
ln +q hr.o -lmidi -lc
rsx: rsx.o
ln +q rsx.o -lmidi -lc
tsx: tsx.o
ln +q tsx.o -lmidi -lc
r: r.o
ln +q r.o -lmidi -lc
SHAR_EOF
if test 190 -ne "`wc -c makefile`"
then
echo shar: error transmitting makefile '(should have been 190 characters)'
fi
echo shar: extracting r.c '(7600 characters)'
cat << \SHAR_EOF > r.c
/* simple MIDI router */
/*
This is considered an example even though it's included with the utility
set. It shows methods for scanning public node lists and managing routes
to public nodes. This might be used as the skeleton for a graphics-based
route manager.
*/
#include <exec/types.h>
#include <exec/lists.h>
#include <midi/midibase.h>
#include <functions.h>
#define DeclareMinList(list)\
struct MinList list = { (void *)&list.mlh_Tail, NULL, (void *)&list.mlh_Head }
struct MidiBase *MidiBase;
DeclareMinList(routelist); /* list or MRoutePtr's for maintaining routes that we create */
main()
{
char b[128];
extern int Enable_Abort;
Enable_Abort = 0; /* disable CTRL-C */
if (!(MidiBase = (void *)OpenLibrary (MIDINAME,MIDIVERSION))) {
printf ("can't open midi.library\n");
goto clean;
}
printf ("MIDI Router (type ? for help)\n");
/* process commands */
for (;;) {
printf ("route> ");
if (gets(b) && !parse(b)) break;
}
clean:
if (MidiBase) CloseLibrary (MidiBase);
}
parse(s)
char *s;
{
switch (tolower(*s++)) {
case 'x': /* quit */
case 'q':
zaproutelist();
return 0;
case 'l': /* list */
list();
break;
case 'a': /* add */
addroute(s);
break;
case 'm': /* modify */
modroute(s);
break;
case 'r': /* remove */
remroute(s);
break;
case 'h': /* help */
case '?':
help();
break;
}
return 1;
}
help()
{
printf ("\n");
printf ("Simple MIDI Router\n");
printf (" ? - help\n");
printf (" a <src> <dst> <MsgFlags> <ChanFlags> <ChanOffset> <NoteOffset> - add a route\n");
printf (" m <num> <MsgFlags> <ChanFlags> <ChanOffset> <NoteOffset> - modify a route\n");
printf (" r <num> - rem a route\n");
printf (" l - list\n");
printf (" q - quit\n");
printf ("\n");
}
list()
{
/* list public sources */
printf ("\nSources:\n");
listnames (&MidiBase->SourceList);
/* list public dests */
printf ("\nDests:\n");
listnames (&MidiBase->DestList);
/* list our routes */
printf ("\nRoutes:\n");
listroutes();
printf ("\n");
}
/*
Lists names in a specified list (like MidiBase->SourceList or MidiBase->DestList).
This requires locking the lists to prevent changes while scanning them.
Ideally, if a similar routine is going to take any large amount of time
or can be halted by the user in mid-stream, it should take a snapshot
of all the data it wishes to handle rather than locking the lists for
the whole process. Locking the lists prevents anyone else from Creating
or Deleting a node or Finding a node.
*/
listnames(list)
struct List *list;
{
struct Node *node;
LockMidiBase();
for (node = list->lh_Head; node->ln_Succ; node=node->ln_Succ) {
printf (" %s\n",node->ln_Name);
}
UnlockMidiBase();
}
/* Displays our route list. */
listroutes()
{
struct MinNode *node;
int i;
for (i=0,node = routelist.mlh_Head; node->mln_Succ; i++,node=node->mln_Succ) {
prtroute (i,node);
}
}
/*
Displays info about one of our routes. In order to display the node
names, we need to lock the lists to ensure validity of the nodes. This
one is done correctly: it locks the lists, copies the names of the nodes
if present, unlocks the lists, and THEN prints.
*/
prtroute (i,rp)
struct MRoutePtr *rp;
{
struct MRoute *route = rp->Route;
struct MRouteInfo *ri = &route->RouteInfo;
struct MSource *source;
struct MDest *dest;
char sname[64], dname[64];
LockMidiBase(); /* lock node lists */
if (source = route->Source) { /* if the source still exists */
if (source->Node.ln_Name) /* and it has a name (public, for this program this should always be true) */
sprintf (sname,"\"%s\"",source->Node.ln_Name); /* copy the name */
else
strcpy (sname,"(private)");
}
else {
strcpy (sname,"(removed)");
}
if (dest = route->Dest) { /* do the same for the dest */
if (dest->Node.ln_Name)
sprintf (dname,"\"%s\"",dest->Node.ln_Name);
else
strcpy (dname,"(private)");
}
else {
strcpy (dname,"(removed)");
}
UnlockMidiBase(); /* unlock the lists */
/* print */
printf (" %2d: %08lxH %s->%s %04x %04x %d %d\n", i, route, sname, dname, ri->MsgFlags, ri->ChanFlags, ri->ChanOffset, ri->NoteOffset);
}
/* delete all routes in our route list, used on exit */
zaproutelist()
{
struct MRoutePtr *rp;
while (rp = (struct MRoutePtr *)RemHead(&routelist)) {
DeleteMRoute(rp->Route);
free (rp);
}
}
/* adds a new route based on the command line in s */
addroute(s)
char *s;
{
char sname[64],dname[64];
struct MRouteInfo ri;
struct MRoutePtr *rp=NULL;
struct MRoute *route=NULL;
int chanoffset,noteoffset;
void *calloc();
setmem (&ri,sizeof ri,0);
if (sscanf (s,"%s%s%x%x%d%d",sname,dname,&ri.MsgFlags,&ri.ChanFlags,&chanoffset,¬eoffset) != 6) {
printf ("syntax error\n");
goto clean;
}
ri.ChanOffset = chanoffset;
ri.NoteOffset = noteoffset;
/* allocate a RoutePtr to hold ptr to our route */
if (!(rp = calloc(1,sizeof *rp))) {
printf ("out of memory\n");
goto clean;
}
/* try to create the route */
if (!(route = MRoutePublic(sname,dname,&ri))) {
printf ("error creating route\n");
goto clean;
}
rp->Route = route; /* set route pointer in our list */
AddTail (&routelist,rp); /* add to our list */
printf (" Route %d added.\n",findpos (&routelist,rp));
return 0;
clean:
if (route) DeleteMRoute (route);
if (rp) free (rp);
return -1;
}
/* modifies a existing route based on the command line in s */
modroute(s)
char *s;
{
int num;
struct MRouteInfo ri;
struct MRoutePtr *rp;
struct Node *findnode();
int chanoffset,noteoffset;
setmem (&ri,sizeof ri,0);
if (sscanf (s,"%d%x%x%d%d",&num,&ri.MsgFlags,&ri.ChanFlags,&chanoffset,¬eoffset) != 5) {
printf ("syntax error\n");
goto clean;
}
ri.ChanOffset = chanoffset;
ri.NoteOffset = noteoffset;
/* find our routeptr by position */
if (!(rp = (struct MRoutePtr *)findnode(&routelist,num))) {
printf ("can't find route\n");
goto clean;
}
/* modify the route */
ModifyMRoute (rp->Route,&ri);
printf (" Route %d modified.\n",num);
return 0;
clean:
return -1;
}
/* removes the route specifed in the command line s */
remroute(s)
char *s;
{
int num;
struct MRoutePtr *rp;
struct Node *findnode();
if (sscanf (s,"%d",&num) != 1) {
printf ("syntax error\n");
goto clean;
}
/* find our route ptr by number */
if (!(rp = (struct MRoutePtr *)findnode(&routelist,num))) {
printf ("can't find route\n");
goto clean;
}
/* remove from our list */
Remove (rp);
DeleteMRoute (rp->Route); /* delete the route */
free (rp); /* free our route ptr */
printf (" Route %d removed.\n",num);
return 0;
clean:
return -1;
}
/* finds a node by number */
struct Node *findnode (list,num)
struct List *list;
{
struct Node *node;
for (node = list->lh_Head; node->ln_Succ; node=node->ln_Succ) {
if (!num--) return node;
}
return 0;
}
/* returns the ordinal position of a node within a list */
findpos (list,match)
struct List *list;
struct Node *match;
{
struct Node *node;
int num;
for (num=0,node = list->lh_Head; node->ln_Succ; num++,node=node->ln_Succ) {
if (node==match) return num;
}
return -1;
}
SHAR_EOF
if test 7600 -ne "`wc -c r.c`"
then
echo shar: error transmitting r.c '(should have been 7600 characters)'
fi
echo shar: extracting rsx.c '(2377 characters)'
cat << \SHAR_EOF > rsx.c
/* simplified receive system exclusive */
/* receives next sys/ex message and save it to a named file */
/*
shows usage of GetMidiMsg(), MidiMsgLength(), FreeMidiMsg() and msg
filtering with routes.
*/
#include <libraries/dos.h>
#include <midi/midi.h>
#include <functions.h>
#include <fcntl.h>
void *MidiBase;
main(argc,argv)
char **argv;
{
extern int Enable_Abort;
int fo; /* output file descriptor */
UBYTE *msg=0, *getmsg();
struct MDest *dest=0;
struct MRoute *route=0;
static struct MRouteInfo routeinfo = { MMF_SYSEX }; /* receive only sys/ex msg's */
char *fname;
printf ("Receive Sys/Ex\n");
Enable_Abort = 0; /* disable auto CTRL-C handling */
if (argc < 2) {
printf ("usage: rsx <file>\n");
exit (1);
}
fname = argv[1]; /* get file name */
if (!(MidiBase = OpenLibrary (MIDINAME,MIDIVERSION))) {
printf ("can't open midi.library\n");
goto clean;
}
/* create our dest node (private) */
if (!(dest = CreateMDest (NULL,NULL))) {
printf ("can't create Dest\n");
goto clean;
}
/* create our route to MidiIn */
if (!(route = MRouteDest ("MidiIn", dest, &routeinfo))) {
printf ("can't create Route (can't find MidiIn?)\n");
goto clean;
}
/* create our output file */
if ( (fo=creat(fname,0666)) == -1) {
printf ("can't open %s\n",fname);
goto clean;
}
/* wait for the next message, save it or skip if terminated */
if (msg = getmsg(dest)) {
long len = MidiMsgLength(msg); /* get message length */
if (write (fo,msg,(int)len) != len || /* won't work for msg's bigger than 64K */
close(fo) == -1) {
printf ("error writing file.\n");
}
printf ("sys/ex file \"%s\" saved. (%ld bytes)\n",fname,len);
}
else {
printf ("save aborted.\n");
close(fo);
unlink(fname);
}
clean:
if (msg) FreeMidiMsg (msg);
if (route) DeleteMRoute (route);
if (dest) DeleteMDest (dest);
if (MidiBase) CloseLibrary (MidiBase);
}
/*
waits for next msg (will be sys/ex because that's all that our route lets
through). Returns pointer to message. If CTRL-C is hit before a message
arrives, returns NULL
*/
UBYTE *getmsg (dest)
struct MDest *dest;
{
ULONG flags = SIGBREAKF_CTRL_C | (1L << dest->DestPort->mp_SigBit);
if (Wait(flags) & SIGBREAKF_CTRL_C) return 0;
return GetMidiMsg (dest);
}
SHAR_EOF
if test 2377 -ne "`wc -c rsx.c`"
then
echo shar: error transmitting rsx.c '(should have been 2377 characters)'
fi
echo shar: extracting tsx.c '(1879 characters)'
cat << \SHAR_EOF > tsx.c
/* simplified transmit sys/ex file */
/* actually transmits entire contents of file, not just sys/ex */
/*
describes usage of PutMidiStream() limited buffer size and unknown
stream length.
*/
#include <midi/midi.h>
#include <functions.h>
#include <fcntl.h>
void *MidiBase;
static int fi; /* input file descriptor */
UBYTE buf[512]; /* buffer used for transfer */
main(argc,argv)
char **argv;
{
struct MSource *source=0;
struct MRoute *route=0;
static struct MRouteInfo routeinfo = { -1, -1 }; /* support all msg's */
extern short Enable_Abort;
char *fname;
long fillbuffer();
printf ("Transmit Sys/Ex\n");
Enable_Abort = 0; /* disable auto CTRL-C handling */
if (argc < 2) {
printf ("usage: tsx <file>\n");
exit (1);
}
fname = argv[1]; /* get file name */
if (!(MidiBase = OpenLibrary (MIDINAME,MIDIVERSION))) {
printf ("can't open midi.library\n");
goto clean;
}
/* create our source node (private) */
if (!(source = CreateMSource (NULL,NULL))) {
printf ("can't create Source\n");
goto clean;
}
/* create our route to MidiOut */
if (!(route = MRouteSource (source,"MidiOut",&routeinfo))) {
printf ("can't create Route (can't find MidiOut?)\n");
goto clean;
}
/* open input file */
if ( (fi=open(fname,O_RDONLY)) == -1) {
printf ("can't open %s\n",fname);
goto clean;
}
/* convert file to midi messages */
PutMidiStream (source,fillbuffer,buf,(long)sizeof buf,0L);
clean:
if (route) DeleteMRoute (route);
if (source) DeleteMSource (source);
if (MidiBase) CloseLibrary (MidiBase);
}
/* fill our buffer with data from the file, called by PutMidiStream() */
static
long fillbuffer()
{
register long len;
geta4(); /* Aztec small data model */
return (len = read(fi,buf,sizeof buf)) == -1 ? 0 : len;
}
SHAR_EOF
if test 1879 -ne "`wc -c tsx.c`"
then
echo shar: error transmitting tsx.c '(should have been 1879 characters)'
fi
# End of shell archive
exit 0