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 0
ain@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