home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff227.lzh / MidiLib / docs / library.doc < prev    next >
Text File  |  1989-06-25  |  39KB  |  975 lines

  1.                                 MIDI LIBRARY
  2.                                 ==== =======
  3.  
  4. WHAT IS THE MIDI LIBRARY?
  5. ---- -- --- ---- --------
  6.  
  7. The MIDI library is a standard Amiga disk-based library that provides 
  8. multitasking access to MIDI resources such as the serial port.  The 
  9. library is based around a "copying" message system so that a single 
  10. message sent in can cause several messages to be sent back out.  Included 
  11. as part of the library are tasks that convert serial I/O to MIDI messages 
  12. which can be sent to any task that cares to listen.  This provides for 
  13. unlimited sharing of the serial port by MIDI applications.
  14.  
  15. The need for such a service seems obvious in a multitasking environment.  
  16. Without this sort of interface, two tasks trying to receive MIDI data 
  17. from the serial port at the same time will exclude each other from 
  18. working correctly.  Neither of them will get all the data they seek.  By 
  19. using the MIDI library this problem is eliminated because there is only 
  20. one task actually receiving data from the serial port.  Data is then 
  21. distributed to all who are waiting for it.
  22.  
  23. A similar problem occurs with transmitting.  MIDI is based around a 
  24. message system.  Each message contains a certain number of bytes and must 
  25. be received intact to make sense to the receiver.  If two tasks try to 
  26. transmit data to the serial port at the same time it is likely that the 
  27. partial messages from each stream will merge producing disastrous 
  28. results.  The MIDI library handles this by keeping messages intact, and 
  29. again only one task is actually sending data to the serial port.
  30.  
  31. The MIDI library is intended for developers writing MIDI applications to 
  32. use with their products.  The library takes care of all the grunginess of 
  33. transferring MIDI data between your applications and the serial port.  
  34. Instead of getting an unformatted stream of bytes your programs receive 
  35. complete messages as asynchronous events.
  36.  
  37.  
  38. Features
  39. --------
  40.  
  41.      *  Unlimited MIDI message merging.
  42.  
  43.      *  Provides an interface for multiple MIDI applications to access 
  44.         the serial port without conflict.
  45.  
  46.      *  Versatile MIDI filtering including message, channel, controller, 
  47.         and SysEx ID number filtering.
  48.  
  49.      *  Exists as a standard disk-based Amiga library less than 10K in 
  50.         size.
  51.  
  52.      *  Supports the full MIDI message specification including system 
  53.         exclusive, 3 byte SysEx ID's, and MTC.
  54.  
  55.      *  Transfers MIDI packets using the Amiga Executive message system.
  56.  
  57.      *  Entirely written in Assembly.
  58.  
  59.  
  60. OVERVIEW
  61. --------
  62.  
  63. Tasks wishing to perform MIDI I/O create "source" and "destination" 
  64. nodes.  These nodes are where messages are sent to and received from.  
  65. Sources and destinations are then "routed" together.  Once connected in 
  66. this manner, MIDI messages that are placed at the source node are 
  67. distributed to destination nodes connected to that source.  Any number of 
  68. source and destination nodes may exist at one time and any number of 
  69. routes can be connected to a source or destination.
  70.  
  71. In addition to piping information along, a route processes MIDI data.  
  72. The following operations can be performed by a route in any combination:
  73.  
  74.      Message filtering
  75.      Channel filtering
  76.      Channel offset
  77.      Note offset
  78.      Controller number filtering
  79.      Sys/Ex id number filtering
  80.  
  81. In addition to nodes that the applications create there are "resident" 
  82. nodes that launch built-in tasks.  Currently the only built-in tasks are 
  83. for transmitting and receiving MIDI messages to and from the Amiga's 
  84. serial port.
  85.  
  86. Covered in this remainder of this document are in depth descriptions of 
  87. each of the major sections and concepts within the MIDI Library.  In 
  88. general, there are a few rules you should keep in mind when using the 
  89. MIDI Library (and all other Amiga resources):
  90.  
  91.      1. You must free any resource that you allocate (such as an MSource, 
  92.         MDest, MRoute, MidiPacket, etc) when you are done with it.
  93.  
  94.      2. Only those fields within a structure that are explicitly 
  95.         documented as writable should be treated as such.
  96.  
  97.      3. Any shared lists must be locked prior to examination (there are 
  98.         various list locking functions described in the Inner Workings 
  99.         section).
  100.  
  101. More detailed information about each MIDI Library function can be found 
  102. in midi.doc.  Examine midi/midi.h (or midi/midi.i) for more information 
  103. on the structures used within the MIDI Library and some handy constants 
  104. not described in this document.
  105.  
  106. This document assumes that you have access to and are familiar with MIDI 
  107. 1.0 Spec v4.0 from the IMA.  Also, familiarity with C and the Amiga Rom 
  108. Kernel are assumed.
  109.  
  110.  
  111. LIBRARY
  112. -------
  113.  
  114. Before using the MIDI library it must be opened like any other Amiga 
  115. library.  The global symbol for the library base is "MidiBase".
  116.  
  117.           MidiBase = OpenLibrary (MIDINAME,MIDIVERSION);
  118.  
  119. The constants MIDINAME and MIDIVERSION are defined in the include file 
  120. midi/midi.h.  MIDINAME is "midi.library" and as of this writing 
  121. MIDIVERSION is 7.
  122.  
  123. When done using the library you should close it:
  124.  
  125.           CloseLibrary (MidiBase);
  126.  
  127.  
  128. SOURCE AND DESTINATION NODES
  129. ------ --- ----------- -----
  130.  
  131. The MIDI source and destination nodes are the terminals for MIDI 
  132. communication.  Messages are placed at a source to be distributed to 
  133. destinations through whatever routes are connected to the source.
  134.  
  135. Nodes can be either public or private.  Private nodes can only be 
  136. accessed by the task that created them.  Public nodes are available to 
  137. everyone.  This way an application can perform it's own private 
  138. communications or can be made available for routing in a patch bay.
  139.  
  140. The MIDI source is defined in "midi/midi.h" is follows:
  141.  
  142.           struct MSource {
  143.                struct Node Node;
  144.                struct Image *Image;
  145.                struct MinList RPList;
  146.                APTR UserData;
  147.                UWORD RouteMsgFlags;
  148.                UWORD RouteChanFlags;
  149.           };
  150.  
  151.      Node
  152.           An instance of an Exec Node used for linking public nodes into 
  153.           the library's source list.  The ln_Name field is set for public 
  154.           nodes to the name supplied by the caller.  ln_Type is set to 
  155.           NT_MSOURCE for user MSource's or NT_RESMSOURCE for resident 
  156.           MSource's.
  157.  
  158.      Image
  159.           Points to an Intuition Image structure.  The image may be used 
  160.           by graphics-based patch bay applications.  It is only used for 
  161.           public nodes.  A NULL here indicates that the creator of this 
  162.           node does not have an Image for it; patch bay programs may deal 
  163.           with that as they see fit.
  164.  
  165.      RPList
  166.           A linked list of MRoutePtr structures.  Each member of the list 
  167.           is attached to an MRoute structure.  Scanning this list allows 
  168.           you to determine what other nodes are connected to this one.
  169.  
  170.      UserData
  171.           A generic pointer to any user extension data.  For resident 
  172.           nodes this points to an instance of an MTaskInfo structure.
  173.  
  174.      RouteMsgFlags
  175.      RouteChanFlags
  176.           The sum of MsgFlags and ChanFlags, respectively, in all routes 
  177.           attached to the MSource.  This is used internally by the 
  178.           message distributor as a pre-check for which message classes 
  179.           actually need to be transmitted.
  180.  
  181. In general you will only be concerned with a pointer to an MSource, not 
  182. its contents.  It is not safe to touch anything in the MSource structure 
  183. except UserData and then only if you created the MSource.  You are free 
  184. to examine anything in the MSource structure such as RPList to determine 
  185. the sort of route connections to the MSource.  If you plan to do this, be 
  186. sure to read the section on the Inner Workings so that you will 
  187. understand all the necessary precautions.
  188.  
  189. There are three functions dealing with MSource's:
  190.  
  191.      CreateMSource (name,image)
  192.           Allocates, initializes, and returns a pointer to a new MSource 
  193.           structure.  If name is non-NULL the MSource will be considered 
  194.           public and will be linked into the library's source list.  
  195.           Otherwise it will be considered private and won't be linked 
  196.           into the library's source list.
  197.  
  198.      DeleteMSource (source)
  199.           Removes and frees a source created by CreateMSource().
  200.  
  201.      FindMSource (name)
  202.           Looks for a public MSource with the specified name.  If it is 
  203.           found a pointer to it is returned.
  204.  
  205. See "midi.doc" for more thorough information on these and other MIDI 
  206. Library functions.
  207.  
  208. The MIDI destination is defined in "midi/midi.h" is follows:
  209.  
  210.           struct MDest {
  211.                struct Node Node;
  212.                struct Image *Image;
  213.                struct MinList RPList;
  214.                struct MsgPort *DestPort;
  215.                APTR UserData;
  216.                struct MRouteInfo DefaultRouteInfo;
  217.           };
  218.  
  219. These fields differ from an MSource
  220.  
  221.      Node
  222.           The same as in an MSource except ln_Type is set to NT_MDEST for 
  223.           user MDest's or NT_RESMDEST for resident MDest's.
  224.  
  225.      DestPort
  226.           Points to an Exec MsgPort that is automatically created.  This 
  227.           is where MIDI messages will arrive.  The port flags are set to 
  228.           PA_SIGNAL so you can Wait() for something to arrive.  You don't 
  229.           GetMsg() from this port, however.  See the messages section for 
  230.           the proper way to read messages.
  231.  
  232.      DefaultRouteInfo
  233.           Used as storage for the default connection options for this 
  234.           MDest.  There is more on this subject in the Routing section.
  235.  
  236. The only field in this structure that you are likely to ever need to 
  237. access is the DestPort since you will need to Wait() for messages to 
  238. arrive there.  Otherwise, the same guidelines that apply to MSource's 
  239. apply to MDest's:  don't tamper with anything other than UserData and 
  240. only if you created the MDest.
  241.  
  242. As with MSource there are three functions dealing with MDest's that have 
  243. essentially the same functions as those for MSource's:
  244.  
  245.      CreateMDest (name,image)
  246.           Allocates, initializes, and returns a pointer to a new MDest 
  247.           structure.  If name is non-NULL the MDest will be considered 
  248.           public and will be linked into the library's destination list.  
  249.           Otherwise it will be considered private.
  250.  
  251.      DeleteMDest (source)
  252.           Removes and frees a source created by CreateMDest().  Also any 
  253.           unread messages will be freed.
  254.  
  255.      FindMDest (name)
  256.           Looks for a public MDest with the specified name.  If it is 
  257.           found a pointer to it is returned.
  258.  
  259.      FlushMDest (dest)
  260.           Disposes of any MidiPackets pending at the specified MDest.
  261.  
  262. At this point it is worth discussing the Resident Nodes currently 
  263. available.  Resident nodes are public nodes that are always present in 
  264. the public node lists and are physically part of the MIDI Library.  They 
  265. can be routed to just like any other public node as will be described in 
  266. the next section.  There are currently two resident nodes.
  267.  
  268.      name     type    description
  269.      ----     ----    -----------
  270.      MidiIn   source  Converts incoming data from the Amiga's serial port 
  271.                       to MIDI Messages.  Any MDest's that you route to 
  272.                       MidiIn will be able to receive messages from any 
  273.                       MIDI devices connected to the serial port.
  274.  
  275.      MidiOut  dest    Converts MidiPackets to data sent out the Amiga's 
  276.                       serial port.  Any MSource's that you route to 
  277.                       MidiOut will then be able to transmit MIDI messages 
  278.                       to devices connected to the serial port.  Any 
  279.                       number of MSource's can be routed to it without 
  280.                       fear of mangled data; messages are merged 
  281.                       properly.  Each message sent to it will be 
  282.                       transmitted to the serial port in the order 
  283.                       received.
  284.  
  285.  
  286. ROUTES
  287. ------
  288.  
  289. Routes are the "cables" that connect sources to destinations.  Nodes can 
  290. have any number of routes connected to them and routes may be connected 
  291. in parallel.  Additionally routes process MIDI messages as they are 
  292. transferred along them.
  293.  
  294. The route structure and related structures are defined in "midi/midi.h" 
  295. is follows:
  296.  
  297. The MRoute structure is the actual route structure managed by the 
  298. library.  You probably need not be concerned with it's contents.
  299.  
  300.               struct MRoute {
  301.                       struct MSource *Source;
  302.                       struct MDest *Dest;
  303.                       struct MRoutePtr SRoutePtr, DRoutePtr;
  304.                       struct MRouteInfo RouteInfo;
  305.               };
  306.  
  307.      Source
  308.               Points to the source end or input to this route.  If is 
  309.               NULL, then the source no longer exists.
  310.  
  311.      Dest
  312.               Points to the destination end or output of this route.  If 
  313.               is NULL, then the destination no longer exists.
  314.  
  315.      SRoutePtr
  316.      DRoutePtr
  317.               Instances of the MRoutePtr structure.  These are linked 
  318.               into the source and destination RPLists respectively.  See 
  319.               midi/midi.h for the actual MRoutePtr structure definition.
  320.  
  321.      RouteInfo
  322.               An instance of an MRouteInfo structure.  This is a copy of 
  323.               data supplied by the user.
  324.  
  325. When creating a route you have the option of using the default MRouteInfo 
  326. structure within the target MDest or supplying your own.  This structure 
  327. is what determines the behavior of a route:  filtering, event processing, 
  328. etc.  There is a great deal of flexibility offered by this system.
  329.  
  330.           struct MRouteInfo {
  331.                UWORD MsgFlags;
  332.                UWORD ChanFlags;
  333.                BYTE  ChanOffset;
  334.                BYTE  NoteOffset;
  335.                struct RIMatch SysExMatch;
  336.                struct RIMatch CtrlMatch;
  337.           };
  338.  
  339.      MsgFlags
  340.           Flag bits indicating which messages are to be supported by this 
  341.           route.  "midi/midi.h" contains MMF_ constants which may be ORed 
  342.           together.  A value of MMF_ALL indicates all message types.
  343.  
  344.      ChanFlags
  345.           Flag bits indicating which channels for channel messages are to 
  346.           be supported by this route.  The least significant bit 
  347.           corresponds to MIDI channel 1, the most significant bit 
  348.           corresponds to MIDI channel 16.  A value of 0xffff indicates 
  349.           all channels.
  350.  
  351.      ChanOffset
  352.           A signed offset to be applied to all channel messages passed 
  353.           through this route.  If the resulting channel is out of range 
  354.           the message is not sent.
  355.  
  356.      NoteOffset
  357.           A signed transposition offset to be applied to note on and off 
  358.           messages in half steps.  If the resulting note number is out of 
  359.           range the message is not sent.
  360.  
  361.      SysExMatch
  362.           An instance of an RIMatch structure.  It allows you to specify 
  363.           up to three one-byte System Exclusive ID numbers or one 
  364.           three-byte ID to pass or block through this route.  If left 
  365.           unset, all will be passed.  To use this the MMF_SYSEX bit must 
  366.           be set in MsgFlags.  See below for more on this.
  367.  
  368.      CtrlMatch
  369.           An instance of an RIMatch structure.  It allows you to specify 
  370.           up to three controller numbers to pass or block through this 
  371.           route.  If left unset, all will be passed.  To use this the 
  372.           MMF_CTRL bit must be set in MsgFlags.
  373.  
  374. The RIMatch structure is used to specify up to three values to match.
  375.  
  376.           struct RIMatch {
  377.                UBYTE Flags;
  378.                UBYTE Match[RIM_MAXCOUNT];
  379.           };
  380.  
  381.      Flags
  382.           Indicates how the value(s) in Match should be treated.  A value 
  383.           of 0 causes Match to be ignored.  A value of 1 to 3 is used to 
  384.           specify how many one-byte values are contained in Match.  
  385.           Without any other flags set, this indicates that only the 
  386.           value(s) in Match will pass through this route.
  387.  
  388.           If the RIMF_EXCLUDE bit is set (OR with value of 1-3), the 
  389.           logic is reversed such that all except those values in Match 
  390.           are passed.
  391.  
  392.           SysExMatch only:  If the RIMF_EXTID bit is set, Match is 
  393.           assumed to contain exactly one three-byte System Exclusive ID.  
  394.           This may be combined with RIMF_EXCLUDE.
  395.  
  396.      Match
  397.           Value(s) to match packed left to right.
  398.  
  399. In order to create a route you need to have a source pointer, a 
  400. destination pointer, and optionally a properly filled out MRouteInfo 
  401. structure.  The contents of your MRouteInfo is copied to the created 
  402. route so you do not need to preserve it after creation.
  403.  
  404. There are several functions dealing with route management.  First a note 
  405. about public nodes.  Since public nodes are available to other tasks 
  406. besides the creator there needs to be a way to insure the validity of a 
  407. given node between the time that someone finds it and the time that 
  408. someone attempts to route to it.  There is a pair of functions to lock 
  409. the node lists to prevent a node from being removed while you are dealing 
  410. with it.  Additionally there are some special routing functions for 
  411. dealing with public nodes that lock the lists for you.  Thus, there is 
  412. route creation function for every permutation of public and private nodes.
  413.  
  414.           source    dest      function
  415.           ------    ----      --------
  416.           private   private   CreateMRoute
  417.           private   public    MRouteSource
  418.           public    private   MRouteDest
  419.           public    public    MRoutePublic
  420.  
  421.      CreateMRoute (source,dest,routeinfo)
  422.           Allocates and links a route into the specified source and 
  423.           destination nodes.  The data pointed to by routeinfo, if 
  424.           supplied, is copied to the new route structure.  This is 
  425.           primarily used when both source and destination are private.
  426.  
  427.      MRouteSource (source,destname,routeinfo)
  428.           Routes a source to a named public destination.
  429.  
  430.      MRouteDest (sourcename,dest,routeinfo)
  431.           Routes a named public source to a destination.
  432.  
  433.      MRoutePublic (sourcename,destname,routeinfo)
  434.           Routes a named public source to a named public destination.
  435.  
  436. In all cases above, you may supply your own MRouteInfo by passing a 
  437. pointer to it or use the DefaultMRouteInfo within the target MDest by 
  438. passing NULL instead.
  439.  
  440. The remaining functions deal with modifying and deleting routes:
  441.  
  442.      ModifyMRoute (route,newrouteinfo)
  443.           Copies the contents of the new MRouteInfo structure to the 
  444.           specified route.
  445.  
  446.      DeleteMRoute (route)
  447.           Unlinks and frees a route.
  448.  
  449.      SetDefaultMRouteInfo (dest,newrouteinfo)
  450.           Copies the contents of the supplied to MRouteInfo to 
  451.           DefaultMRouteInfo in the supplied MDest.  This does not affect 
  452.           any routes already connected to the MDest, only the template 
  453.           for creating new routes.  You should only call this routine on 
  454.           MDest's that you created.
  455.  
  456. You are responsible for deleting any routes you create even if the nodes 
  457. it connected have been deleted.  You should not delete or modify anyone 
  458. else's routes.
  459.  
  460.  
  461. MESSAGES AND PACKETS
  462. -------- --- -------
  463.  
  464. From the point of view of the MIDI Library, a MIDI Message is simply an 
  465. array of UBYTEs containing a status byte as its first byte and any data 
  466. bytes associated with that message.  With the exception of system 
  467. exclusive, all messages are from 1 to 3 bytes in length.  A given status 
  468. byte always has the same number of data bytes.  Messages never contain 
  469. embedded Real Time status bytes as these are sent as separate messages.  
  470. Messages never rely on running status so there will always be a status 
  471. byte at the beginning of every message and there will never be more than 
  472. one message worth of data bytes within that message.
  473.  
  474. System exclusive messages can be any length.  Also, the last byte in a 
  475. system exclusive message is the EOX status byte used as a terminator 
  476. (like '\0' in a C string).
  477.  
  478. The MidiPacket structure is built around the above MIDI Message concept.  
  479. This structure is what arrives at the DestPort within an MDest.
  480.  
  481.           struct MidiPacket {
  482.                struct Message ExecMsg;
  483.                UWORD Type;
  484.                UWORD Length;
  485.                ULONG reserved;
  486.                UBYTE MidiMsg[4];
  487.           };
  488.  
  489.      ExecMsg
  490.           The standard Exec Message node used to send to MsgPorts.
  491.  
  492.      Type
  493.           An MMF_ message type value for the message contained in this 
  494.           packet as returned by MidiMsgType().
  495.  
  496.      Length
  497.           The length of this message in bytes as returned by 
  498.           MidiMsgLength().
  499.  
  500.      MidiMsg
  501.           The actual message as described above.  There always at least 4 
  502.           bytes here, but the actual length that you should use is found 
  503.           in Length.  Specifically, system exclusive packets more often 
  504.           than not have more than 4 bytes here.
  505.  
  506. MIDI Messages (just the UBYTE array) are used for transmitting messages 
  507. to an MSource.  MidiPackets are used for receiving messages at an MDest.  
  508. MidiPackets are always created by the MIDI Library, never by you.  
  509. Consider them entirely read-only.
  510.  
  511. These functions deal with receiving MidiPackets:
  512.  
  513.      GetMidiPacket (dest)
  514.           Gets the first MidiPacket available at a destination and 
  515.           returns a pointer to it.  If none are available NULL is 
  516.           returned.  Any MidiPacket that you receive from GetMidiPacket() 
  517.           should be freed with FreeMidiPacket().  See below for an 
  518.           example packet reader.
  519.  
  520.      FreeMidiPacket (packet)
  521.           Frees a MidiPacket received from GetMidiPacket().
  522.  
  523.      These functions deal with sending MIDI Messages:
  524.  
  525.      PutMidiMsg (source,msg)
  526.           Places a single MIDI Message at a source for distribution.  
  527.           Upon return you may recycle your msg buffer since its contents 
  528.           has been copied to any MidiPackets that have been sent.  This 
  529.           function assumes that you have constructed a valid MIDI message 
  530.           as described above.  Invalid or undefined messages are ignored, 
  531.           however an unterminated system exclusive message cannot be 
  532.           detected and runs the risk of crashing the machine.
  533.  
  534.      PutMidiStream (source,fillbuffer,buf,bufsize,cursize)
  535.           Converts an unformatted data stream into MIDI messages which 
  536.           are then sent by calling PutMidiMsg().  See midi.doc for proper 
  537.           usage.
  538.  
  539. These functions give you information about specific MIDI Messages:
  540.  
  541.      MidiMsgType (msg)
  542.           Returns an MMF_ flag indicating the type message.  It returns 0 
  543.           for invalid or undefined messages.
  544.  
  545.      MidiMsgLength (msg)
  546.           Returns the number of bytes in a message.  For non-exclusive 
  547.           messages this is the status byte + data bytes.  For system 
  548.           exclusive messages it is status byte + data bytes + EOX.  0 is 
  549.           returned for invalid or undefined messages.
  550.  
  551. These functions deal with receiving MIDI Messages w/o the packets and are 
  552. primarily here for backwards compatibility.  They do little more than 
  553. apply an offset from the beginning of the MidiPacket to the MidiMsg field 
  554. and call the corresponding MidiPacket function.  It is not recommended 
  555. that these be used in new code since they are less efficient from the 
  556. point of the Library and the caller:
  557.  
  558.      GetMidiMsg (dest)
  559.           Gets the first MIDI message available at a destination and 
  560.           returns a pointer to it.  If none are available NULL is 
  561.           returned.  Any message that you receive from GetMidiMsg() 
  562.           should be freed with FreeMidiMsg().  See below for an example 
  563.           message reader.
  564.  
  565.      FreeMidiMsg (msg)
  566.           Frees a message received from GetMidiMsg().
  567.  
  568. Some additional notes about messages:
  569.  
  570.      1. Invalid or undefined status bytes are ignored.
  571.  
  572.      2. EOX is not considered a valid status byte on its own.  It is only 
  573.         used to terminate system exclusive messages and will be ignored 
  574.         if sent by itself using PutMidiMsg().
  575.  
  576.      3. Incomplete messages (such as system exclusive messages without a 
  577.         manufacturer ID) are ignored.
  578.  
  579.      4. Note On messages with velocity == 0 are considered Note Off 
  580.         messages.  MidiMsgType() will return MMF_NOTEOFF rather than 
  581.         MMF_NOTEON for these.
  582.  
  583.      5. Controller numbers 121-127 are reserved for MIDI Mode Messages 
  584.         and are treated as such.  MidiMsgType() will return MMF_MODE 
  585.         rather than MMF_CTRL for these.
  586.  
  587.  
  588. Here is a code fragment showing the recommended MidiPacket receive 
  589. technique:
  590.  
  591.      domidi(dest)
  592.      struct Dest *dest;
  593.      {
  594.           struct MidiPacket *packet;
  595.  
  596.           while (!done) {
  597.                Wait (1L << dest->DestPort->mp_SigBit);
  598.                while (packet = GetMidiPacket (dest)) {
  599.                     /* process the packet: */
  600.                     /*   perhaps examine packet->Type */
  601.                     /*   or packet->Length */
  602.                     /*   or the actual Message in packet->MidiMsg */
  603.                          .
  604.                          .
  605.                     /* then free it */
  606.                     FreeMidiPacket (packet);
  607.                }
  608.           }
  609.      }
  610.  
  611.  
  612. It's important to understand a little about how MidiPackets are 
  613. allocated.  For all message types other than System Exclusive, 
  614. MidiPackets are allocated from a pre-allocated pool of MidiPackets.  This 
  615. is considerably quicker than having to call AllocMem() each time a 
  616. MidiPacket needs to be allocated.  The pool gets initialized the first 
  617. time you create a route.  If the pool becomes full, it gets extended but 
  618. will not be pruned until someone calls FlushMDest() or DeleteMDest().  It 
  619. gets totally expunged when the last user of the library calls 
  620. CloseLibrary().
  621.  
  622. If you cache MidiPackets for any length of time, your memory may vanish 
  623. to increase the size of the packet pool.  In order to get it back you 
  624. will have to call FlushMDest().
  625.  
  626. System Exclusive packets are allocated using AllocMem() which explains 
  627. why they are marginally slower to route than non-exclusive messages.
  628.  
  629.  
  630. INNER WORKINGS
  631. ----- --------
  632.  
  633. This section is for the more adventurous MIDI programmer.  The 
  634. information here is necessary for authors of patch bay or other route 
  635. managing applications.
  636.  
  637. MidiBase
  638. --------
  639.  
  640. The structure of the library base is defined in "midi/midibase.h".  This 
  641. structure is strictly READ-ONLY.  You may examine fields with care as 
  642. noted below.
  643.  
  644.           struct MidiBase {
  645.                struct Library libnode;
  646.                struct List SourceList, DestList;
  647.                struct SignalSemaphore ListSemaphore;
  648.                struct SignalSemaphore RouteSemaphore;
  649.                BPTR SegList;
  650.                APTR SysBase, DosBase;
  651.                struct MinList SignalList;
  652.           };
  653.  
  654.      libnode
  655.           Standard Amiga library node.
  656.  
  657.      SourceList
  658.           An Exec linked list containing all public MSource nodes.
  659.  
  660.      DestList
  661.           An Exec linked list containing all public MDest nodes.
  662.  
  663.      ListSemaphore
  664.           A SignalSemaphore for locking the source and destination 
  665.           lists.  This is the semaphore used when you call LockMidiBase() 
  666.           or UnlockMidiBase().  Exclusive access to lists is required 
  667.           when managing or scanning either the source or destination 
  668.           list.  It is not required for message propagation.  It is 
  669.           required for route management only when a public node is 
  670.           involved.
  671.  
  672.      RouteSemaphore
  673.           A SignalSemaphore for locking the route system.  The routines 
  674.           LockMRoutes() and UnlockMRoutes() use this semaphore.  
  675.           Exclusive access to the routing system is required for message 
  676.           propagation and route management.  It is not needed for 
  677.           managing or scanning the node lists.  Use this with care since 
  678.           it blocks message propagation.
  679.  
  680.      SegList
  681.           A BPTR to the segment list for the library.
  682.  
  683.      SysBase & DosBase
  684.           The library's pointers to Exec and Dos.
  685.  
  686.      SignalList
  687.           The list of MListSignal nodes.
  688.  
  689. Only SourceList and DestList are likely to be of any interest to patch 
  690. bay programmers.  The rest can be ignored.
  691.  
  692. These routines are useful for examining the base:
  693.  
  694.      LockMidiBase()
  695.           Gains exclusive access to the source and destination lists.  
  696.           Use of this will block anyone else from managing nodes or 
  697.           scanning the lists.  Messages propagation is not blocked, 
  698.           however.  Calls may be nested but each call must be matched 
  699.           with a call to UnlockMidiBase().
  700.  
  701.      UnlockMidiBase()
  702.           Relinquishes exclusive access to the source and destination 
  703.           lists.
  704.  
  705. These routines are useful for examining the routes attached to a specific 
  706. source or destination:
  707.  
  708.      LockMRoutes()
  709.           Gains exclusive access to the route system.  Use of this will 
  710.           block message propagation and route management.  Calls may be 
  711.           nested but each call must be matched with a call to 
  712.           UnlockMRoutes().
  713.  
  714.      UnlockMidiBase()
  715.           Relinquishes exclusive access to the route system.
  716.  
  717. You shouldn't be very likely to need to lock the route system, however, 
  718. and if you do it should only be to read the route lists not to modify 
  719. anything.  A patch bay application should not use this approach to keep 
  720. track of its routes.  Instead it must maintain its own list of routes.  
  721. As long as everyone observes the rule of modifying only their own 
  722. structures there shouldn't be any trouble.
  723.  
  724. Signals
  725. -------
  726.  
  727. There is a system by which your task can be signaled when either of the 
  728. public node lists changes.  This permits a patch bay system to be 
  729. notified when it needs to redraw its display of available nodes.
  730.  
  731.           struct MListSignal {
  732.                struct MinNode Node;
  733.                struct Task *SigTask;
  734.                UBYTE SigBit;
  735.                UBYTE Flags;
  736.           };
  737.  
  738.      Node
  739.           Standard Exec MinNode used to link this MListSignal into 
  740.           SignalList.
  741.  
  742.      SigTask
  743.           Pointer to the task owning this MListSignal.
  744.  
  745.      SigBit
  746.           Signal bit for this MListSignal.  Used to Signal() SigTask on 
  747.           public node list change.
  748.  
  749.      Flags
  750.           Flag bits describing which lists to watch for this signal.
  751.  
  752. This entire structure should be considered READ-ONLY.  The only field you 
  753. should be concerned with examining is SigBit since you'll need to Wait() 
  754. for that in order to find out when a list changes.  The signals do not 
  755. accumulate and you don't know what changed when you receive one, just 
  756. that something you were looking for has changed since you last received a 
  757. signal.
  758.  
  759. These functions manage MListSignals:
  760.  
  761.      CreateMListSignal (flags)
  762.           Adds your task to the list of those to be signaled when the 
  763.           public node lists change.  Flags contains either MLSF_SOURCE, 
  764.           MLSF_DEST or both depending on which list(s) you want to 
  765.           monitor.  The function returns a pointer to an MListSignal 
  766.           which you must keep and pass to DeleteMListSignal() when you 
  767.           are done with it.  A signal bit is allocated for you when you 
  768.           call this and is placed in SigBit.
  769.  
  770.      DeleteMListSignal (signal)
  771.           Removes and frees an MListSignal allocated by CreateMListSignal.
  772.  
  773.  
  774. Resident Nodes
  775. -------- -----
  776.  
  777. As noted before there are some nodes that are always present.  They are 
  778. created by the library when it is first loaded.  These nodes are attached 
  779. to built-in tasks (actually AmigaDOS Processes) that are launched when 
  780. the nodes are routed to.  There are currently only two resident nodes:  
  781. one for receiving from the serial port and one for transmitting to the 
  782. serial port.
  783.  
  784.      MidiIn   source  Launches a task called MidiIn running at +30 
  785.                       priority when it is first routed to.  It receives 
  786.                       data from the serial port and converts it to MIDI 
  787.                       messages which are posted to its MSource node.  
  788.                       Anyone with destinations routed to this node will 
  789.                       receive MIDI messages from it.
  790.  
  791.      MidiOut  dest    Launches a task called MidiOut which also runs at 
  792.                       +30 priority.  It is responsible for receiving 
  793.                       messages from it's MDest node and sending them to 
  794.                       the serial port.
  795.  
  796. Resident nodes can be identified by a node type value (in ln_Type) of 
  797. NT_RESMSOURCE or NT_RESMDEST.  Resident nodes have an additional 
  798. MTaskInfo structure attached to them that is pointed to by the UserData 
  799. field in the MSource or MDest structure.
  800.  
  801. This rest of the information about resident nodes is provided merely for 
  802. the curious and is not terribly useful.  Consider ALL of this stuff to be 
  803. READ ONLY.  And be forewarned that it may change if necessary.  The 
  804. MTaskInfo structure is defined in "midi/midibase.h".
  805.  
  806.           struct MTaskInfo {
  807.                char *Name;
  808.                WORD Pri;
  809.                void (*Entry)();
  810.                UWORD Stack;
  811.                UWORD Sources;
  812.                struct MNodeInfo *SourceList;
  813.                struct Dests;
  814.                struct MNodeInfo *DestList;
  815.                struct SignalSemaphore Semaphore;
  816.                UWORD UsageCount;
  817.                struct MsgPort *TaskPort;
  818.                BPTR Segment;
  819.           };
  820.  
  821. These fields are defined within each task's module:
  822.  
  823.      Name
  824.           Points to the name of the task.
  825.  
  826.      Pri
  827.           The task's priority.
  828.  
  829.      Entry
  830.           The start of the task's code.
  831.  
  832.      Stack
  833.           The size of stack to allocate for the task.
  834.  
  835.      Sources
  836.           The the number of MSource nodes defined for this task.
  837.  
  838.      SourceList
  839.           Points to an array of MNodeInfo structures containing the 
  840.           definition of this task's MSource nodes.
  841.  
  842.      Dests
  843.           Is the the number of MDest nodes defined for this task.
  844.  
  845.      DestList
  846.           Points to an array of MNodeInfo structures containing the 
  847.           definition of this task's MDest nodes.
  848.  
  849.      These fields are managed by the library:
  850.  
  851.      Semaphore
  852.           A signal semaphore for locking this MTaskInfo structure.  This 
  853.           is only used when launching or shutting down this task.
  854.  
  855.      UsageCount
  856.           The number of accessors to this task.  If it is non-zero the 
  857.           task is running otherwise it is dormant.
  858.  
  859.      TaskPort
  860.           Points to the message port used to communicate with the task.
  861.  
  862.      Segment
  863.           A BPTR to a fake segment list necessary for CreateProc().  The 
  864.           segment contains a jump instruction to the startup code for the 
  865.           task.  The task's code is actually part of the library's 
  866.           segment list.  This might be considered making use of 
  867.           undocumented features, but as long as no one tries to 
  868.           UnloadSeg() this segment (and no one should) there shouldn't be 
  869.           any trouble.
  870.  
  871. The MNodeInfo structure referred to above is used to define the resident 
  872. source or destination nodes attached to this task.  Tasks are not 
  873. restricted to just one resident node, but that is the current usage.  
  874. This structure is also defined in "midi/midibase.h".
  875.  
  876.           struct MNodeInfo {
  877.                char *Name;
  878.                struct Image *Image;
  879.                APTR Node;
  880.           };
  881.  
  882.      Name
  883.           Points to the name of the node.  This shouldn't ever be NULL.
  884.  
  885.      Image
  886.           Points to an Intuition Image structure for this node.  This may 
  887.           be NULL (and currently is in all cases).
  888.  
  889.      Node
  890.           Points to the node allocated for this MNodeInfo structure so 
  891.           that the task can find it easily.
  892.  
  893.  
  894. SERIAL I/O CONSIDERATIONS
  895. ------ --- --------------
  896.  
  897. The resident nodes that access the serial port do so by using 
  898. serial.device - the standard device driver for the serial port.  
  899. serial.device does however have a hard time receiving MIDI data at full 
  900. speed, even with the SERF_RAD_BOOGIE flag set.  It occasionally loses a 
  901. byte or two on larger transfers such as long system exclusive messages.  
  902. I have heard that there are also similar problems when running at 19200 
  903. baud, so it seems likely that some attention will be given to improving 
  904. serial.device in future releases of the operating system (like v1.4).
  905.  
  906. In the meantime, it is strongly recommended that you make sure that you 
  907. get what you expect when reading system exclusive messages from MidiIn.  
  908. Use whatever error detection methods are appropriate for the data being 
  909. transferred (like dump sizes or checksums).
  910.  
  911. Some sequencers use interrupt driven serial I/O for speed reasons.  
  912. These, from what I've seen, do not suffer from the lost data problems 
  913. that serial.device does.  I have given the matter of using my own serial 
  914. interrupt handler some thought and these are my reasons for not doing so 
  915. at this time.
  916.  
  917.      1. serial.device is the polite way of accessing the serial hardware 
  918.         and it should be used whenever possible as it does provide a nice 
  919.         interface to the hardware and is presumably compatible with any 
  920.         future serial hardware that comes along.
  921.  
  922.      2. Serial interrupt handlers are exclusive:  only one task can own 
  923.         the serial interrupts at a time.  Right now there are a few MIDI 
  924.         applications that use serial.device directly for MIDI.  These do 
  925.         not directly conflict with the MIDI Library so long as both are 
  926.         not attempting to read or write data to the serial port at 
  927.         exactly the same time.  If MIDI Library were to use its own 
  928.         interrupt system, these types of applications will not be able to 
  929.         access MIDI at all while someone is using MIDI Library.
  930.  
  931.      3. The problem does not appear bad enough (at least in my own 
  932.         applications) to warrant it.
  933.  
  934.      4. Commodore will presumably fix the problem eventually.
  935.  
  936.      5. MIDI Library uses memory allocations occasionally during message 
  937.         routing.  Interrupt code cannot call the memory allocator.  (This 
  938.         can be worked around by implement the interrupt handler as simply 
  939.         a queue that is read by a task which in turn calls MIDI Library)
  940.  
  941.  
  942. CONCLUSION
  943. ----------
  944.  
  945. Hopefully this document has provided you with an understanding of the 
  946. MIDI library and will enable you to make use of its features in your own 
  947. MIDI applications.
  948.  
  949. Good luck.
  950.  
  951.  
  952. COPYRIGHT AND DISTRIBUTIONS
  953. --------- --- -------------
  954.  
  955. The MIDI Library is Copyright (c) 1987, 1988, Pregnant Badger Music.  All 
  956. rights reserved.  The MIDI Library may be used in and included with 
  957. commercial products with the following provisos:
  958.  
  959.      1. Pregnant Badger Music should be kept informed of your intent to 
  960.         release products that make use of the MIDI Library so that we may 
  961.         keep you informed of changes, updates, etc.
  962.  
  963.      2. The above copyright notice should be included somewhere in the 
  964.         documentation accompanying any such commercial products.
  965.  
  966. Bill Barton
  967. Pregnant Badger Music
  968. 1111 El Sur Way
  969. Sacramento, CA  95864
  970. (916) 487-9472
  971.  
  972.     Bix:  peabody
  973.   PLink:  peabody
  974.  
  975.