(*************************************************************************** :Program. MidiL.def :Author. Jürgen Zimmermann :Address. Ringstraße 6, W-6719 Altleiningen, Germany :Phone. 06356/1456 :ShortCut. [JnZ] :Support. - :Version. 1.03 :Date. 30. Oct 1991 :Copyright. PD :Language. MODULA-II :Translator. M2Amiga 4.0d :Contents. Modula-2-interface-module for Bill Barton's :Contents. "midi.library" of Fish 227, c-functions in "MidiSupport"! :Imports. "midi.library" V2.0 in the LIBS:-directory :Remark. I want to get into contact with other users of the :Remark. "midi.library" or MIDI-programmers. :Remark. (If you have a new version of the library, please send :Remark. it to me!) :Usage. described in the documents of "midi.library" ****************************************************************************) DEFINITION MODULE MidiD; (*$ Implementation:=FALSE *) (* Definitions pertaining to MIDI are derived from MIDI 1.0 Detailed Specification v4.0 (published by the Internation MIDI Association) and is current as of June, 1988. v2.0 - 23-Oct-88 *) FROM SYSTEM IMPORT ADDRESS, BPTR; FROM ExecD IMPORT List, Library, SignalSemaphore, MsgPortPtr, MinList, Node, MinNode, Message, TaskPtr; FROM IntuitionD IMPORT ImagePtr; CONST midiName = "midi.library"; midiOutName = "MidiOut"; midiInName = "MidiIn"; TYPE MidiBasePtr = POINTER TO MidiBase; MTaskInfoPtr = POINTER TO MTaskInfo; MNodeInfoPtr = POINTER TO MNodeInfo; MSourcePtr = POINTER TO MSource; MDestPtr = POINTER TO MDest; RIMatchPtr = POINTER TO RIMatch; MRouteInfoPtr = POINTER TO MRouteInfo; MRoutePtr = POINTER TO MRoute; MidiPacketPtr = POINTER TO MidiPacket; MListSignalPtr = POINTER TO MListSignal; (* Msg Flags for MRouteInfo structure and returned by MidiMsgType *) MMFFlags = (NoteOn, NoteOff, PolyPress, Ctrl, Prog, ChanPress, PitchBend, Mode, SysCom, SysRt, SysEx, mmf11, mmf12, mmf13, mmf14, mmf15); MMFFlagSet = SET OF MMFFlags; (* MidiChannel-Flags, um nur bestimmte Midi-Kanäle anzusprechen *) MidiChannels = (Ch01, Ch02, Ch03, Ch04, Ch05, Ch06, Ch07, Ch08, Ch09, Ch10, Ch11, Ch12, Ch13, Ch14, Ch15, Ch16); MidiChannelSet = SET OF MidiChannels; RIMFlags = (extBit1,extBit2,rim2,rim3,rim4,rim5,extId,reverse); RIMFlagSet = SET OF RIMFlags; CONST MMFChan = MMFFlagSet{NoteOn..Mode}; MMFAll = MMFChan + MMFFlagSet{SysCom, SysRt, SysEx}; AllChannels = MidiChannelSet{Ch01..Ch16}; RIMCountBits = RIMFlagSet{extBit1, extBit2}; (* mask for # of match values (0 for match all) *) RIMExtId = RIMFlagSet{extId}; (* indicates all 3 bytes of match[] == one 3 byte manuf. id (not valid for CtrlMatch) *) RIMExclude = RIMFlagSet{reverse}; (* reverses logic of RIMatch so that all except those specified pass *) RIMMaxCount = 3; (* node types for Source *) NTMSource = 20H; NTMResMSource = 21H; (* node types for Dest *) NTMDest = 22H; NTResMDest = 23H; (* user flags *) MLSFSource = 00000001H; (* causes signal when SourceList changes *) MLSFDest = 00000002H; (* causes signal when DestList changes *) TYPE MidiBase = RECORD libnode : Library; SourceList : List; DestList : List; ListSemaphore : SignalSemaphore; (* blocks Source/Dest list management *) RouteSemaphore: SignalSemaphore; (* blocks RPList management & msg routing *) SegList : LONGCARD; SysBase : ADDRESS; DosBase : ADDRESS; SignalList : MinList; (* list of MListSignal's *) END; MTaskInfo = RECORD (* set by caller *) name : ADDRESS; Pri : INTEGER; Entry : ADDRESS; (* Adresse des TaskCodes *) Stack : CARDINAL; Sources : CARDINAL; SourceList: MNodeInfoPtr; Dests : CARDINAL; DestList : MNodeInfoPtr; (* set by midi.library *) Semaphore : SignalSemaphore; (* locks task *) UsageCount: CARDINAL; (* task's usage count *) TaskPort : MsgPortPtr; (* task's MsgPort *) Segment : BPTR; (* task's Segment *) END; MNodeInfo = RECORD name : ADDRESS; image: ImagePtr; node : ADDRESS; END; MSource = RECORD node : Node; image : ImagePtr; RPList : MinList; userData : ADDRESS; (* user data extension *) (* new stuff for v2.0 *) RouteMsgFlags : MMFFlagSet; RouteChanFlags: MidiChannelSet; (* RouteMsgFlags: mask of all route->MsgFlags for this MSource; RouteChanFlags: mask of all route->ChanFlags for this MSource *) END; TYPE RIMatch = RECORD flags: RIMFlagSet; match: ARRAY[1..RIMMaxCount] OF SHORTCARD; END; MRouteInfo = RECORD MsgFlags : MMFFlagSet; ChanFlags : MidiChannelSet; ChanOffset: SHORTINT; NoteOffset: SHORTINT; SysExMatch: RIMatch; CtrlMatch : RIMatch; (* MsgFlags: flags enabling message types defined below (MMF_) (msg filters); ChanFlags: incoming channel enable flags (LSB = chan 1, MSB = chan 16) (channel filters); ChanOffset: signed offset applied to channels (simple channelizing); NoteOffset: signed offset applied to note numbers (transposition); SysExMatch: Sys/Ex manufacturer id filtering; CtrlMatch: Controller number filtering *) END; MDest = RECORD node : Node; image : ImagePtr; RPList : MinList; DestPort : MsgPortPtr; userData : ADDRESS;(* user data extension *) (* new stuff for v2.0 *) DefaultRouteInfo: MRouteInfo; (* used when Routing function doesn't supply a RouteInfo *) END; TYPE MRoutePointer = RECORD (* alias MRoutePtr (C-Definition!) *) node : MinNode; Route: MRoutePtr; END; MRoute = RECORD Source : MSourcePtr; Dest : MDestPtr; SRoute : MRoutePointer; DRoute : MRoutePointer; (* MRoutePtr (C-Definition!) *) RouteInfo: MRouteInfo; END; (* MIDI Packet (new for v2.0) *) MidiPacket = RECORD (* returned by GetMidiPacket() *) ExecMsg : Message; Type : MMFFlagSet; Length : CARDINAL; reserved: LONGCARD; MidiMsg : ARRAY[1..4] OF SHORTCARD; (* ExecMsg: ***; Type: MMF_ bit for this message (as returned by MidiMsgType()); Length: length of msg in bytes (as returned by MidiMsgLength()); reserved: reserved for future expansion; MidiMsg: actual MIDI message (real length of this array is Length, always at least this much memory allocated) *) END; (* Public List Change Signal *) MListSignal = RECORD node : MinNode; SigTask: TaskPtr; (* task to signal *) SigBit : SHORTCARD; (* signal bit to use *) Flags : SHORTCARD; (* user flags *) END; (* MIDI message defininition *) (* Status Bytes *) (* Channel Voice Messages (1sssnnnn) (OR with channel number) *) CONST MSNOTEOFF = 80H; MSNOTEON = 90H; MSPOLYPRESS = 0A0H; MSCTRL = 0B0H; MSMODE = 0B0H; MSPROG = 0C0H; MSCHANPRESS = 0D0H; MSPITCHBEND = 0E0H; (* System Common Messages (11110sss) *) MSSYSEX = 0F0H; MSQTRFRAME = 0F1H; MSSONGPOS = 0F2H; MSSONGSELECT = 0F3H; MSTUNEREQ = 0F6H; MSEOX = 0F7H; (* System Real Time Messages (11111sss) *) MSCLOCK = 0F8H; MSSTART = 0FAH; MSCONTINUE = 0FBH; MSSTOP = 0FCH; MSACTVSENSE = 0FEH; MSRESET = 0FFH; (* Miscellaneous *) MIDDLEC = 60H; (* middle C note value *) DEFAULTVELOCITY = 64H; (* default Note On or Off velocity *) PITCHBENDCENTER = 2000H;(* pitch bend center position as a 14 bit word *) MCLKSPERQTR = 24H; (* MIDI clocks per qtr-note *) MCLKSPERSP = 6H; (* MIDI clocks per song position index *) MCCENTER = 64H; (* center value for controllers like Pan and Balance *) (* Standard Controllers *) (* continuous 14 bit - MSB: 0-1f, LSB: 20-3f *) MCMODWHEEL = 01H; MCBREATH = 02H; MCFOOT = 04H; MCPORTATIME = 05H; MCDATAENTRY = 06H; MCVOLUME = 07H; MCBALANCE = 08H; MCPAN = 0AH; MCEXPRESSION = 0BH; MCGENERAL1 = 10H; MCGENERAL2 = 11H; MCGENERAL3 = 12H; MCGENERAL4 = 13H; (* continuous 7 bit (switches: 0-3f=off, 40-7f=on) *) MCSUSTAIN = 40H; MCPORTA = 41H; MCSUSTENUTO = 42H; MCSOFTPEDAL = 43H; MCHOLD2 = 45H; MCGENERAL5 = 50H; MCGENERAL6 = 51H; MCGENERAL7 = 52H; MCGENERAL8 = 53H; MCEXTDEPTH = 5BH; MCTREMOLODEPTH = 5CH; MCCHORUSDEPTH = 5DH; MCCELESTEDEPTH = 5EH; MCPHASERDEPTH = 5FH; MCDATAINCR = 60H; MCDATADECR = 61H; MCNRPNL = 62H; MCNRPNH = 63H; MCRPNL = 64H; MCRPNH = 65H; MCMAX = 78H; (* max controller value *) (* Channel Modes *) MMMIN = 79H; (* min mode value *) MMRESETCTRL = 79H; MMLOCAL = 7AH; MMALLOFF = 7BH; MMOMNIOFF = 7CH; MMOMNION = 7DH; MMMONO = 7EH; MMPOLY = 7FH; (* Registered Parameter Numbers *) (* These are 16 bit values that need to be separated into two bytes for use with the MC_RPNH & MC_RPNL messages using 8 bit math (hi = MRP_ >> 8, lo = MRP_ & ff) as opposed to 7 bit math. This is done so that the defines match the numbers from the MMA. See MIDI 1.0 Detailed Spec v4.0 pp 12, 23 for more info. *) MRPPBSENS = 0000H; MRPFINETUNE = 0001H; MRPCOURSETUNE = 0002H; (* MTC Quarter Frame messages *) (* Qtr Frame message is F1 0nnndddd where nnn is a message type defined below dddd is 4 bit data nibble for those message types Each pair of nibbles is combined by the receiver into a single byte. There are masks and type values defined for some of these data bytes below. *) (* message types *) MTCQFRAMEL = 00H; MTCQFRAMEH = 10H; MTCQSECL = 20H; MTCQSECH = 30H; MTCQMINL = 40H; MTCQMINH = 50H; MTCQHOURL = 60H; MTCQHOURH = 70H; (* also contains time code type *) (* message masks *) MTCQTYPEMASK = 70H; (* mask for type bits in message *) MTCQDATAMASK = 0FH; (* mask for data bits in message *) (* hour byte *) MTCHTYPEMASK = 60H; (* mask for time code type *) MTCHHOURMASK = 1FH; (* hours mask (range 0-23) *) (* time code type values for hour byte *) MTCT24FPS = 00H; MTCT25FPS = 20H; MTCT30FPSDROP = 40H; MTCT30FPSNONDROP = 60H; (* Sys/Ex ID numbers *) (* Now includes 3 byte extension for the American Group. This new format uses a $00 as the sys/ex id followed by two additional bytes that actually identify the manufacturer. These new extended id constants are 32 bit values (24 significant bits) that you will have to break apart manually. You can match or filter off one of the extended id's when using the RIMF_EXTID bit described above. *) (* American Group *) XAMERICA = 00H; SEQUENTIAL = 01H; IDP = 02H; OCTAVEPLATEAU = 03H; MOOG = 04H; PASSPORT = 05H; LEXICON = 06H; KURZWEIL = 07H; FENDER = 08H; AKG = 0AH; VOYCE = 0BH; WAVEFRAME = 0CH; ADA = 0DH; GARFIELD = 0EH; ENSONIQ = 0FH; OBERHEIM = 10H; APPLE = 11H; GREYMATTER = 12H; PALMTREE = 14H; JLCOOPER = 15H; LOWREY = 16H; ADAMSSMITH = 17H; EMU = 18H; HARMONY = 19H; ART = 1AH; BALDWIN = 1BH; EVENTIDE = 1CH; INVENTRONICS = 1DH; CLARITY = 1FH; (* American Group extened *) DIGITALMUSIC = 0000007H; IOTA = 0000008H; IVL = 000000BH; SOUTHERNMUSIC = 000000CH; LAKEBUTLER = 000000DH; DOD = 0000010H; PERFECTFRET = 0000014H; OPCODE = 0000016H; SPATIALSOUND = 0000018H; KMX = 0000019H; AXXES = 0000020H; (* European Group *) PASSAC = 20H; SIEL = 21H; SYNTHAXE = 22H; HOHNER = 24H; TWISTER = 25H; SOLTON = 26H; JELLINGHAUS = 27H; SOUTHWORTH = 28H; PPG = 29H; JEN = 2AH; SSL = 2BH; AUDIOVERITRIEB = 2CH; ELKA = 2FH; DYNACORD = 30H; (* Japanese Group *) KAWAI = 40H; ROLAND = 41H; KORG = 42H; YAMAHA = 43H; CASIO = 44H; MORIDAIRA = 45H; KAMIYA = 46H; AKAI = 47H; JAPANVICTOR = 48H; MEISOSHA = 49H; HOSHINOGAKKI = 4AH; FUJITSU = 4BH; SONY = 4CH; NISSHINONPA = 4DH; SYSTEMPRODUCT = 4FH; (* Universal ID Numbers *) NC = 7DH; NRT = 7EH; RT = 7FH; END MidiD.