home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 066.lha / MidiDev / library.doc < prev    next >
Text File  |  1986-11-20  |  31KB  |  766 lines

  1.                                 MIDI LIBRARY
  2.                                 ==== =======
  3.  
  4. WHAT IS THE MIDI LIBRARY?
  5.  
  6.      The MIDI library is a standard Amiga disk-based library that 
  7. provides multitasking access to MIDI resources such as the serial port.  
  8. The library is based around a "copying" message system so that a single 
  9. message sent in can cause several messages to be sent back out.  Included 
  10. as part of the library are tasks that convert serial I/O to MIDI messages 
  11. which can be sent to any task that cares to listen.  This provides for 
  12. unlimited sharing of the serial port by MIDI applications.
  13.  
  14.      The need for such a service seems obvious in a multitasking 
  15. environment.  Without this sort of interface, two tasks trying to receive 
  16. MIDI data from the serial port at the same time will exclude each other 
  17. from working correctly.  Neither of them will get all the data they 
  18. seek.  By using the MIDI library this problem is eliminated because there 
  19. is only one task actually receiving data from the serial port.  Data is 
  20. then distributed to all who are waiting for it.
  21.  
  22.      A similar problem occurs with transmitting.  MIDI is based around a 
  23. message system.  Each message contains a certain number of bytes and must 
  24. be received intact to make sense to the receiver.  If two tasks try to 
  25. transmit data to the serial port at the same time it is likely that the 
  26. partial messages from each stream will merge producing disastrous 
  27. results.  The MIDI library handles this by keeping messages intact, and 
  28. again only one task is actually sending data to the serial port.
  29.  
  30.      The MIDI library is intended for developers writing MIDI 
  31. applications to use with their products.  The library takes care of all 
  32. the grunginess of transferring MIDI data between your applications and 
  33. the serial port.  Instead of getting an unformatted stream of bytes your 
  34. programs receive complete messages as asynchronous events.
  35.  
  36.      The MIDI library is not SoundScape!  It does NOT contain a sequencer 
  37. or sound sampler.  It is merely a message distributor.
  38.  
  39.  
  40.      Features:
  41.  
  42.      *  Unlimited MIDI message merging.
  43.  
  44.      *  Provides an interface for multiple MIDI applications to access 
  45.         the serial port without conflict.
  46.  
  47.      *  Versatile MIDI filtering including message, channel, controller, 
  48.         and SysEx ID number filtering.
  49.  
  50.      *  Exists as a standard disk-based Amiga library less than 10K in 
  51.         size.
  52.  
  53.      *  Supports the full MIDI message specification including system 
  54.         exclusive.
  55.  
  56.      *  Transfers MIDI packets using the Amiga Executive message system.
  57.  
  58.      *  Almost entirely written in Assembly.
  59.  
  60. OVERVIEW
  61.  
  62.      Tasks wishing to perform MIDI I/O create source and destination 
  63. nodes.  These points where messages are sent out and received from.  
  64. Sources and destinations are then routed together.  Any number of routes 
  65. can be connected to a source or destination.  In addition to piping 
  66. information along, a route processes MIDI data.  The following operations 
  67. can be performed by a route in any combination:
  68.  
  69.      Message filtering
  70.      Channel filtering
  71.      Channel offset
  72.      Note offset
  73.      Controller number filtering
  74.      Sys/Ex id number filtering
  75.  
  76.      In addition to nodes that the applications create there are 
  77. "resident" nodes that launch built-in tasks.  Currently the only built-in 
  78. tasks are for transmitting and receiving MIDI messages to and from the 
  79. serial port.
  80.  
  81.  
  82. LIBRARY
  83.  
  84.      Before using the MIDI library it must be opened like any other Amiga 
  85. library.  The global symbol for the library base is "MidiBase".
  86.  
  87.           MidiBase = OpenLibrary ("midi.library",1L);
  88.  
  89.      The current version number is 1.  This will eventually be set to the 
  90. standard value for KickStart 1.2, which is 33, to avoid version number 
  91. confusion.
  92.  
  93.      When done using the library you should close it:
  94.  
  95.           CloseLibrary (MidiBase);
  96.  
  97. SOURCES AND DESTINATIONS
  98.  
  99.      The MIDI source and destination nodes are the terminals for MIDI 
  100. communication.  Messages are placed at a source to be distributed to 
  101. destinations through whatever routes are in place.
  102.  
  103.      Nodes can be either public or private.  Private nodes can only be 
  104. accessed by the task that creates them.  Public nodes are available to 
  105. everyone.  This way an application can perform it's own private 
  106. communications or can be made available for routing in a patch bay.
  107.  
  108.      The MIDI source is defined in "midi/midi.h" is follows:
  109.  
  110.           struct MSource {
  111.                struct Node Node;
  112.                struct Image *Image;
  113.                struct MinList RPList;
  114.                APTR UserData;
  115.           };
  116.  
  117.      where
  118.  
  119.           Node
  120.                is an instance of an Exec Node used for linking public 
  121.                nodes into the library's source list.  The ln_Name field 
  122.                is set for public nodes to the name supplied by the 
  123.                caller.  ln_Type is set to NT_MSOURCE for user MSource's 
  124.                or NT_PERMMSOURCE for resident MSource's.
  125.  
  126.           Image
  127.                is a pointer to an Intuition Image structure.  The image 
  128.                may be used by graphics-based patch bay applications.  It 
  129.                is only used for public nodes.  A NULL here indicates that 
  130.                the creator of this node does not have an Image for it; 
  131.                patch bay programs may deal with that as they see fit.
  132.  
  133.           RPList
  134.                is a linked list of MRoutePtr structures.  Each member of 
  135.                the list is attached to an MRoute structure.  Scanning 
  136.                this list allows you to determine what other nodes are 
  137.                connected to this one.
  138.  
  139.           UserData
  140.                a generic pointer to any user extension data.  For 
  141.                resident nodes this points to an instance of an MTaskInfo 
  142.                structure.
  143.  
  144.      There are three functions dealing with MSource's:
  145.  
  146.           CreateMSource (name,image)
  147.                allocates, initializes, and returns a pointer to a new 
  148.                MSource structure.  If name is non-NULL the MSource will 
  149.                be considered public and will be linked into the library's 
  150.                source list.  Otherwise it will be considered private.
  151.  
  152.           DeleteMSource (source)
  153.                removes and frees a source created by CreateMSource().
  154.  
  155.           FindMSource (name)
  156.                looks for a public MSource with the specified name.  If it 
  157.                is found a pointer to it is returned.
  158.  
  159.  
  160.      The MIDI destination is defined in "midi/midi.h" is follows:
  161.  
  162.           struct MDest {
  163.                struct Node Node;
  164.                struct Image *Image;
  165.                struct MinList RPList;
  166.                struct MsgPort *DestPort;
  167.                APTR UserData;
  168.           };
  169.  
  170.      where the fields differ from an MSource
  171.  
  172.           Node
  173.                is the same as in an MSource except ln_Type is set to 
  174.                NT_MDEST for user MDest's or NT_PERMMDEST for resident 
  175.                MDest's.
  176.  
  177.           DestPort
  178.                is a pointer to an Exec MsgPort that is automatically 
  179.                created.  This is where MIDI messages will arrive.  The 
  180.                port flags are set to PA_SIGNAL so you can Wait() for 
  181.                something to arrive.  You don't GetMsg() from this port, 
  182.                however.  See the messages section for the proper way to 
  183.                read messages.
  184.  
  185.      As with MSource there are three functions dealing with MDest's:
  186.  
  187.           CreateMDest (name,image)
  188.                allocates, initializes, and returns a pointer to a new 
  189.                MDest structure.  If name is non-NULL the MDest will be 
  190.                considered public and will be linked into the library's 
  191.                destination list.  Otherwise it will be considered private.
  192.  
  193.           DeleteMDest (source)
  194.                removes and frees a source created by CreateMDest().  Also 
  195.                any unread messages will be freed.
  196.  
  197.           FindMDest (name)
  198.                looks for a public MDest with the specified name.  If it 
  199.                is found a pointer to it is returned.
  200.  
  201.      Most of the fields within the node structures can be ignored by 
  202. casual users since they are managed by the library.  You are responsible 
  203. for deleting any nodes you create.
  204.  
  205. ROUTES
  206.  
  207.      Routes are the cables that connect sources to destinations.  Nodes 
  208. can have any number of routes connected to them and routes may be 
  209. connected in parallel.  Additionally routes process MIDI messages as they 
  210. are transferred along them.
  211.  
  212.      The route structure and related structures are defined in 
  213. "midi/midi.h" is follows:
  214.  
  215.      The MRoute structure is the actual route structure managed by the 
  216. library.  You probably need not be concerned with it's contents.
  217.  
  218.           struct MRoute {
  219.                struct MSource *Source;
  220.                struct MDest *Dest;
  221.                struct MRoutePtr SRoutePtr, DRoutePtr;
  222.                struct MRouteInfo RouteInfo;
  223.           };
  224.  
  225.      where
  226.  
  227.           Source
  228.                points to the source end or input to this route.  If is 
  229.                NULL, then the source no longer exists.
  230.  
  231.           Dest
  232.                points to the destination end or output of this route.  If 
  233.                is NULL, then the destination no longer exists.
  234.  
  235.           SRoutePtr
  236.                is an instance of an MRoutePtr structure.  This is the 
  237.                node that is linked into the source's RPList.
  238.  
  239.           DRoutePtr
  240.                is an instance of an MRoutePtr structure.  This is the 
  241.                node that is linked into the destination's RPList.
  242.  
  243.           RouteInfo
  244.                is an instance of an MRouteInfo structure.  This is a copy 
  245.                of data supplied by the user.
  246.  
  247.  
  248.      The MRoutePtr structure is used to link routes to nodes.  It is 
  249. primarily an internal structure.
  250.  
  251.           struct MRoutePtr {
  252.                struct MinNode node;
  253.                struct MRoute *Route;
  254.           };
  255.  
  256.      where
  257.  
  258.           node
  259.                is an instance of an Exec MinNode structure.
  260.  
  261.           Route
  262.                points to the MRoute structure containing this MRoutePtr 
  263.                structure.
  264.  
  265.  
  266.      You initialize an MRouteInfo structure before creating a route to 
  267. indicate what sort of processing the route is to perform.
  268.  
  269.           struct MRouteInfo {
  270.                UWORD MsgFlags;
  271.                UWORD ChanFlags;
  272.                BYTE  ChanOffset;
  273.                BYTE  NoteOffset;
  274.                struct RIMatch SysExMatch;
  275.                struct RIMatch CtrlMatch;
  276.           };
  277.  
  278.      where
  279.  
  280.           MsgFlags
  281.                are flag bits indicating which messages are to be 
  282.                supported by this route.  "midi/midi.h" contains MMF_ 
  283.                constants which may be ored together.  A value of -1 
  284.                indicates all message types.
  285.  
  286.           ChanFlags
  287.                are flag bits indicating which channels for channel 
  288.                messages are to be supported by this route.  The least 
  289.                significant bit corresponds to MIDI channel 1, the most 
  290.                significant bit corresponds to MIDI channel 16.  A value 
  291.                of -1 indicates all channels.
  292.  
  293.           ChanOffset
  294.                is a signed offset to be applied to all channel messages 
  295.                passed through this route.  If the resulting channel is 
  296.                invalid the message is not sent.
  297.  
  298.           NoteOffset
  299.                is a signed offset to be applied to note on and off 
  300.                messages.  It is half steps.  If the resulting note number 
  301.                is invalid the message is not sent.
  302.  
  303.           SysExMatch
  304.                is an instance of an RIMatch structure.  It allows you to 
  305.                specify up to three System Exclusive ID numbers to pass 
  306.                through this route.  If left unset, all will be passed.  
  307.                To use this the MMF_SYSEX bit must be set in MsgFlags.
  308.  
  309.           CtrlMatch
  310.                is an instance of an RIMatch structure.  It allows you to 
  311.                specify up to three controller numbers to pass through 
  312.                this route.  If left unset, all will be passed.  To use 
  313.                this the MMF_CTRL bit must be set in MsgFlags.
  314.  
  315.  
  316.      The RIMatch structure is used to specify up to three values to match.
  317.  
  318.           struct RIMatch {
  319.                UBYTE count;
  320.                UBYTE match[3];
  321.           };
  322.  
  323.      where
  324.  
  325.           count
  326.                indicates the number of values in the match list.  If it 
  327.                is 0, all values will be passed.
  328.  
  329.           match
  330.                contains count values to match.
  331.  
  332.  
  333.      In order to create a route you need to have a source pointer, a 
  334. destination pointer, and a properly filled out MRouteInfo structure.  The 
  335. contents of your MRouteInfo is copied to the created route so you do not 
  336. need to preserve it after creation.
  337.  
  338.      There are several routines dealing with route management.  First a 
  339. note about public nodes.  Since public nodes are available to other tasks 
  340. besides the creator there needs to be a way to insure the validity of a 
  341. given node between the time that someone finds it and the time that 
  342. someone attempts to route to it.  There is a pair of routines to lock the 
  343. node lists to prevent a node from being removed while you are dealing 
  344. with it.  Additionally there are some special routing functions for 
  345. dealing with public nodes that lock the lists for you.  Thus, there is 
  346. route creation function for every permutation of public and private nodes.
  347.  
  348.      source    dest      function
  349.  
  350.      private   private   CreateMRoute
  351.      private   public    MRouteSource
  352.      public    private   MRouteDest
  353.      public    public    MRoutePublic
  354.  
  355.           CreateMRoute (source,dest,routeinfo)
  356.                allocates and links a route into the specified source and 
  357.                destination nodes.  The data pointed to by routeinfo is 
  358.                copied to the new route structure.  This is primarily used 
  359.                when both source and destination are private.
  360.  
  361.           MRouteSource (source,destname,routeinfo)
  362.                routes a source to a named public destination.
  363.  
  364.           MRouteDest (sourcename,dest,routeinfo)
  365.                routes a named public source to a destination.
  366.  
  367.           MRoutePublic (sourcename,destname,routeinfo)
  368.                routes a named public source to a named public destination.
  369.  
  370.  
  371.      The remaining routines deal with modifying and deleting routes
  372.  
  373.           ModifyMRoute (route,newrouteinfo)
  374.                copies the contents of the new MRouteInfo structure to the 
  375.                specified route.
  376.  
  377.           DeleteMRoute (route)
  378.                unlinks and frees a route.
  379.  
  380.  
  381.      You are responsible for deleting any routes you create even if the 
  382. nodes it connected have been deleted.  You should not delete or modify 
  383. anyone else's routes.
  384.  
  385. MESSAGES
  386.  
  387.      The messages passed between nodes are UBYTE arrays in the form of 
  388. standard MIDI messages.  There is no restriction on alignment since they 
  389. are bytes.  Each message contains a status byte as its first byte and any 
  390. data bytes associated with that message.  With the exception of system 
  391. exclusive, all messages are from 1 to 3 bytes in length.  A given status 
  392. byte always has the same number of data bytes.
  393.  
  394.      System exclusive messages can be any length.  Also, the last byte in 
  395. a system exclusive message is the EOX status byte used as a terminator 
  396. (like '\0' in a C string).
  397.  
  398.      When a message arrives at your destination's MsgPort, it is not in a 
  399. form that you can read directly.  Picture the MDest as a mailbox.  The 
  400. message that arrives is in an envelope or packet that can be discarded.  
  401. When you discover that MDest->DestPort has become non-empty you must call 
  402. GetMidiMsg() rather than GetMsg() since this will take care of opening 
  403. the envelope and throwing it away for you and give you a readable 
  404. message.  Likewise, PutMidiMsg() places a message in an envelope and 
  405. posts it.
  406.  
  407.      These functions deal with receiving messages:
  408.  
  409.           GetMidiMsg (dest)
  410.                gets the first MIDI message available at a destination and 
  411.                returns a pointer to it.  If none are available NULL is 
  412.                returned.  Any message that you receive from GetMidiMsg() 
  413.                should be freed with FreeMidiMsg().  See below for an 
  414.                example message reader.
  415.  
  416.           FreeMidiMsg (msg)
  417.                frees a message received from GetMidiMsg().
  418.  
  419.  
  420.      These functions deal with sending messages:
  421.  
  422.           PutMidiMsg (source,msg)
  423.                places a message at a source for distribution.  Upon 
  424.                return you may recycle you msg buffer since its contents 
  425.                has been copied to anyone who's listening.  This routine 
  426.                assumes that you have constructed a valid MIDI message as 
  427.                described above.  Invalid or undefined messages are 
  428.                ignored, however an unterminated system exclusive message 
  429.                cannot be detected and runs the risk of crashing the 
  430.                machine.
  431.  
  432.           PutMidiStream (source,fillbuffer,buf,bufsize,cursize)
  433.                converts an unformatted data stream into MIDI messages 
  434.                which are then sent by calling PutMidiMsg().  See the 
  435.                function documentation for proper usage.
  436.  
  437.  
  438.      These functions give you information about specific messages:
  439.  
  440.           MidiMsgType (msg)
  441.                returns an MMF_ flag indicating the type message.  It 
  442.                returns 0 for invalid or undefined messages.
  443.  
  444.           MidiMsgLength (msg)
  445.                returns the number of bytes in a message.  For 
  446.                non-exclusive messages this is the status byte + data 
  447.                bytes.  For system exclusive messages it is status byte + 
  448.                data bytes + EOX.  0 is returned for invalid or undefined 
  449.                messages.
  450.  
  451.  
  452. Some additional notes about messages:
  453.  
  454.      EOX is not considered a valid message and is only used to terminate 
  455.      system exclusive messages.  It will be ignored if sent with 
  456.      PutMidiMsg()
  457.  
  458.      Trivial messages are ignored.  Trivial messages are those that 
  459.      contain no useful data.  An example is a system exclusive message 
  460.      that contains no data.
  461.  
  462.      Note on messages with velocity == 0 are considered note off 
  463.      messages.  MidiMsgType() will return MMF_NOTEOFF rather than 
  464.      MMF_NOTEON for these.
  465.  
  466.      Controller numbers 122-127 are reserved for MIDI mode changes and 
  467.      are treated as such.  MidiMsgType() will return MMF_MODE rather than 
  468.      MMF_CTRL for these.
  469.  
  470.      As of this writing MIDI Time Code is not supported due to lack of 
  471.      documentation.  As soon as I get proper specs, I'll add it.
  472.  
  473.  
  474.      Here is a code fragment showing the recommended MIDI message receive 
  475. technique:
  476.  
  477.      domidi(dest)
  478.      struct Dest *dest;
  479.      {
  480.           UBYTE *msg;
  481.  
  482.           for (;;) {
  483.                Wait (1L << dest->DestPort->mp_SigBit);
  484.                while (msg = GetMidiMsg (dest)) {
  485.                     /* process the message */
  486.                     .
  487.                     .
  488.                     .
  489.                     /* then free it */
  490.                     FreeMidiMsg (msg);
  491.                }
  492.           }
  493.      }
  494.  
  495.      DO NOT WAIT FOR ACTIVITY LIKE THIS:
  496.  
  497.           while (!(msg = GetMidiMsg(dest))) ;
  498.  
  499.      unless you really want your Amiga to lock up.
  500.  
  501.  
  502. INNER WORKINGS
  503.  
  504.      This section is for the more adventurous MIDI programmer.  The 
  505. information here is necessary for authors of patch bay or other route 
  506. managing applications.
  507.  
  508. MidiBase
  509.  
  510.      The structure of the library base is defined in "midi/midibase.h".
  511.  
  512.           struct MidiBase {
  513.                struct Library libnode;
  514.                struct List SourceList, DestList;
  515.                struct SignalSemaphore ListSemaphore;
  516.                struct SignalSemaphore RouteSemaphore;
  517.                BPTR SegList;
  518.                APTR SysBase, DosBase;
  519.           };
  520.  
  521.      where
  522.  
  523.           libnode
  524.                is the standard Amiga library node
  525.  
  526.           SourceList
  527.                is an Exec linked list containing all public MSource nodes.
  528.  
  529.           DestList
  530.                is an Exec linked list containing all public MDest nodes.
  531.  
  532.           ListSemaphore
  533.                is a SignalSemaphore for locking the source and 
  534.                destination lists.  This is the semaphore used when you 
  535.                call LockMidiBase() or UnlockMidiBase().  Exclusive access 
  536.                to lists is required when managing or scanning either the 
  537.                source or destination list.  It is not required for 
  538.                message propagation.  It is required for route management 
  539.                only when a public node is involved.
  540.  
  541.           RouteSemaphore
  542.                is a SignalSemaphore for locking the route system.  The 
  543.                routines LockMRoutes() and UnlockMRoutes() will use this 
  544.                semaphore when implemented.  Exclusive access to the 
  545.                routing system is required for message propagation and 
  546.                route management.  It is not needed for managing or 
  547.                scanning the node lists.  If necessary you may call 
  548.                ObtainSemaphore() (and of course ReleaseSemaphore()) with 
  549.                a pointer to this structure to examine the routes.  Use 
  550.                this with care since it blocks message propagation.
  551.  
  552.           SegList
  553.                is a BPTR to the segment list for the library.
  554.  
  555.           SysBase & DosBase
  556.                are the the library's pointers to Exec and Dos.
  557.  
  558.  
  559.      These routines are useful for examining the base:
  560.  
  561.           LockMidiBase()
  562.                Gains exclusive access to the source and destination 
  563.                lists.  Use of this will block anyone else from managing 
  564.                nodes or scanning the lists.  Messages propagation is not 
  565.                blocked, however.  Calls may be nested but each call must 
  566.                be matched with a call to UnlockMidiBase().
  567.  
  568.           UnlockMidiBase()
  569.                Relinquishes exclusive access to the source and 
  570.                destination lists.
  571.  
  572.  
  573.      There currently are no routines for locking the route system.  You 
  574. may however Forbid() or ObtainSemaphore(&MidiBase->RouteSemaphore) to 
  575. lock the routes.  You shouldn't be very likely to need to do this, 
  576. however, and if you do it should only be to read the route lists not to 
  577. modify anything.  A patch bay application should not use this approach to 
  578. keep track of its routes.  Instead it must maintain its own list or 
  579. routes.  As long as everyone observes the rule of modifying only their 
  580. own structures there shouldn't be any trouble.
  581.  
  582.  
  583. Resident Nodes
  584.  
  585.      As noted before there are some nodes that are always present.  They 
  586. are created by the library when it is first loaded.  These nodes are 
  587. attached to built-in tasks (actually processes) that are launched when 
  588. the nodes are routed to.  There are currently only two resident nodes:  
  589. one for receiving from the serial port and one for transmitting to the 
  590. serial port.
  591.  
  592.      MidiIn   source  Launches a task called MidiIn running at +10 
  593.                       priority when it is first routed to.  It receives 
  594.                       data from the serial port and converts it to MIDI 
  595.                       messages which are posted to its MSource node.  
  596.                       Anyone with destinations routed to this node will 
  597.                       receive MIDI messages from it.
  598.  
  599.      MidiOut  dest    Launches a task called MidiOut which also runs at 
  600.                       +10 priority.  It is responsible for receiving 
  601.                       messages from it's MDest node and sending them to 
  602.                       the serial port.  Any number of MSource's can be 
  603.                       routed to it without fear of mangled data; messages 
  604.                       are merged properly.  Each message sent to it will 
  605.                       be transmitted to the serial port in the order 
  606.                       received.
  607.  
  608.      NOTE: The "serial.device" has a hard time receiving MIDI data at 
  609. full speed, even with the SERF_RAD_BOOGIE flag set.  It apparently loses 
  610. a byte or two on larger transfers (>4K).  Perhaps someone knowledgeable 
  611. in these matters might write a streamlined MIDI serial device capable of 
  612. handling full speed MIDI data.  For now, it is strongly recommended that 
  613. you make sure that you get what you expect when reading system exclusive 
  614. messages from MidiIn.  Use whatever error detection methods are 
  615. appropriate for the data being transferred (like dump sizes or checksums).
  616.  
  617.      Resident nodes can be identified by a node type value (in ln_Type) 
  618. of NT_PERMMSOURCE or NT_PERMMDEST.  Resident nodes have an additional 
  619. MTaskInfo structure attached to them that is pointed to by the UserData 
  620. field in the MSource or MDest structure.  The MTaskInfo structure is 
  621. defined in "midi/midibase.h".
  622.  
  623.           struct MTaskInfo {
  624.                char *Name;
  625.                WORD Pri;
  626.                void (*Entry)();
  627.                UWORD Stack;
  628.                UWORD Sources;
  629.                struct MNodeInfo *SourceList;
  630.                struct Dests;
  631.                struct MNodeInfo *DestList;
  632.                struct SignalSemaphore Semaphore;
  633.                UWORD UsageCount;
  634.                struct MsgPort *TaskPort;
  635.                BPTR Segment;
  636.           };
  637.  
  638.      where these fields are defined by the task's code:
  639.  
  640.           Name
  641.                points to the name of the task.
  642.  
  643.           Pri
  644.                is the task's priority.
  645.  
  646.           Entry
  647.                is the start of the task's code.
  648.  
  649.           Stack
  650.                is the size of stack to allocate for the task.
  651.  
  652.           Sources
  653.                is the the number of MSource nodes defined for this task.
  654.  
  655.           SourceList
  656.                points to an array of MNodeInfo structures containing the 
  657.                definition of this task's MSource nodes.
  658.  
  659.           Dests
  660.                is the the number of MDest nodes defined for this task.
  661.  
  662.           DestList
  663.                points to an array of MNodeInfo structures containing the 
  664.                definition of this task's MDest nodes.
  665.  
  666.      and these fields are managed by the library (don't mess with them)
  667.  
  668.           Semaphore
  669.                is a signal semaphore for locking this MTaskInfo 
  670.                structure.  This is only used when launching or shutting 
  671.                down this task.
  672.  
  673.           UsageCount
  674.                is the number of accessors to this task.  If it is 
  675.                non-zero the task is running otherwise it is dormant.
  676.  
  677.           TaskPort
  678.                points to the message port used to communicate with the 
  679.                task.
  680.  
  681.           Segment
  682.                is a BPTR to a fake segment list necessary for 
  683.                CreateProc().  The segment contains a jump instruction to 
  684.                the startup code for the task.  The task's code is 
  685.                actually part of the library's segment list.  This might 
  686.                be considered making use of undocumented features, but as 
  687.                long as no one tries to UnloadSeg() this segment (and no 
  688.                one should) there shouldn't be any trouble.
  689.  
  690.  
  691.      The MNodeInfo structure referred to above is used to define the 
  692. resident source or destination nodes attached to this task.  Tasks are 
  693. not restricted to just one resident node, but that is the current usage.  
  694. This structure is also defined in "midi/midibase.h".
  695.  
  696.           struct MNodeInfo {
  697.                char *Name;
  698.                struct Image *Image;
  699.                APTR Node;
  700.           };
  701.  
  702.      where
  703.  
  704.           Name
  705.                points to the name of the node.  This shouldn't ever be 
  706.                NULL.
  707.  
  708.           Image
  709.                points to an Intuition Image structure for this node.  
  710.                This may be NULL.
  711.  
  712.           Node
  713.                points to the node allocated for this MNodeInfo structure 
  714.                so that the task can find it easily.
  715.  
  716. CONCLUSION
  717.  
  718.      Hopefully this document has provided you with an understanding of 
  719. the MIDI library and will enable you to make use of its features in your 
  720. own MIDI applications.  Our own MIDI applications have now been 
  721. retrofitted to make use of the library.  I was amazed at how simple a 
  722. task this was and how much code I was able to dispose of.
  723.  
  724.      At this point, I don't consider the library to be a finished 
  725. product.  It is functional though, and I present it now with the hopes 
  726. that it will be used by other MIDI developers with whose help I would 
  727. like to see this library mature into a standard for the Amiga.  This is 
  728. the sort of thing that can make the Amiga a powerful tool for the 
  729. musician.
  730.  
  731.      In addition to library revisions, the MIDI tools need to be enhanced.
  732.  
  733.      First, there needs to a graphics-based Patch Bay application for 
  734. creating and managing routes to public nodes.  Unlike SoundScape I 
  735. decided this should be outside the library so that it need not be present 
  736. all the time.  My vision in this area seems to be limited, however.  What 
  737. I picture is a window with the Images provided by public nodes appearing 
  738. on each side of the window.  The user can drag lines from source to 
  739. destination to create routes and edit a requester to modify them.  
  740. Perhaps patch files could be saved, too.  This really needs some 
  741. creativity.  There is also a risk of having it resemble SoundScape too 
  742. much.
  743.  
  744.      Next, there should probably be a program to bridge this library to 
  745. SoundScape so that no one complains about incompatibility problems 
  746. between this library and what already exists.  I have a number of gripes 
  747. about SoundScape (part of what prompted me to write the MIDI library in 
  748. the first place) but this is not the place to go into them.  I only 
  749. mention this now because SoundScape does some similar functions and might 
  750. be considered by some to be the standard already.  Also SoundScape does 
  751. have a fairly good sequencer and I'd hate to exclude anyone from using 
  752. the library just because they like SoundScape.
  753.  
  754.      If you have any comments on any of this (and hopefully you will) 
  755. here is how I can be reached.
  756.  
  757.  
  758.      Bill Barton
  759.      1111 El Sur Way
  760.      Sacramento, CA  95864
  761.      (916) 487-9472
  762.  
  763.      BIX: peabody
  764.      Delphi: BBARTON
  765.  
  766.