home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / basic / rukq10 / ruckmidi.doc < prev    next >
Encoding:
Text File  |  1993-02-15  |  79.4 KB  |  2,641 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.      RUCKUS-MIDI Copyright (C)1993 Cornel Huth
  9.      Documentation Copyright (C)1993 Cornel Huth
  10.      All Rights Reserved.
  11.  
  12.      Version 1.00. 
  13.  
  14.      For ordering information, license agreement, and product support
  15.      information, see Appendix Z.
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.      Introduction
  76.  
  77.      RUCKUS-MIDI is one part of the RUCKUS sound toolkit for DOS programmers.
  78.      Its forte is its ability to play MIDI data in three different formats.
  79.      Standard MIDI file format, type-0 and type-1 with selectable programs of
  80.      the General MIDI Sound Set, the MT-32, or one of the programmer's choosing.
  81.      Also supported is the CMF type (Creative Music File format, similar to
  82.      Standard MIDI) and ROL-converted MIDI type (ROL is the file type used by
  83.      the AdLib MSC). The other part of the RUCKUS sound toolkit is RUCKUS-DAC.
  84.      Its forte is its ability to play and record digital data in three formats:
  85.      VOC, WAVE, and Amiga Module. See RUCKUS-DAC for more.
  86.  
  87.      RUCKUS-MIDI currently supports the AdLib MSC and compatibles. This includes
  88.      all Sound Blasters and its clones, as well. RUCKUS-MIDI is implemented to
  89.      be device-independent. As new sound hardware (with supporting
  90.      documentation) becomes available to this programmer, it will be added. The
  91.      code you write to play MIDI music using RUCKUS will play on any new device
  92.      added later without any code changes to your program. You just supply the
  93.      new device ID (see InitMidi for more). RUCKUS-DAC already supports several
  94.      sound devices in a device-independent manner.
  95.  
  96.      The RUCKUS toolkit supports most DOS compilers as is. This documentation
  97.      describes using RUCKUS with BASIC DOS compilers. Also available is a C-
  98.      specific version of this documentation. Other implementations should be
  99.      able to get the necessary details using this documentation. Note that these
  100.      toolkits will not work with the current or past Turbo Pascal compilers.
  101.      This is due to Turbo Pascal's proprietary linkage methods.
  102.  
  103.      To provide compiler-independence, RUCKUS (and all of my latest toolkits)
  104.      implements a simple calling scheme: a single far pointer is passed to
  105.      RUCKUS. The data structure that is pointed to varies depending on RUCKUS
  106.      function. There are 11 structure types ("packs") currently. The first two
  107.      data members of each pack are identical in all packs. These are Func and
  108.      Stat. The remaining members, if any, vary depending on requirements. For
  109.      instance, the LoadMidi routine uses, in addition to Func and Stat, four
  110.      additional members: FilenamePtr, StartPos, LoadSize, and LoadPtr. The steps
  111.      needed to load a MIDI data file to memory would be as follows:
  112.  
  113.  
  114.           1. Allocate pack. Packs are reusable and can be allocated any way you
  115.           want. Here we make a static allocation for simplicity.
  116.  
  117.           DIM LMP AS LoadMidiPackTYPE
  118.  
  119.           2. Assign member values:
  120.       
  121.           filenameZ$ = file$ + CHR$(0)  'must terminate string with 0
  122.           LMP.Func = LoadMidi
  123.           LMP.FilenamePtr = SADD(filenameZ$)  
  124.           LMP.FilenamePtrSeg = VARSEG(filenameZ$)
  125.           'LMP.FilenamePtrSeg = SSEG(filenameZ$)  'for BASIC7/VBDOS
  126.           LMP.StartPos = 0&                    
  127.           LMP.LoadSize = 0&
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.           3. Call RUCKUS:
  143.  
  144.           stat = RUCKMIDI(LMP)
  145.  
  146.           4. On return from the call:
  147.  
  148.           IF stat = 0 THEN 
  149.              ' LMP.LoadPtr -> address of MIDI data in memory
  150.  
  151.      After the load you can immediately call the PlayMidi routine using the
  152.      lmp.LoadPtr returned from the Load call. You don't need to use the RUCKUS
  153.      LoadMidi routine; you can perform your own MIDI data file loads to memory.
  154.      However, RUCKUS can load up to 32 separate MIDI data files at one time and
  155.      performs all the necessary memory allocations and deallocations
  156.      automatically. See LoadMidi for more.
  157.  
  158.      As you can see, using RUCKUS is easy. If you'd rather use a traditional 
  159.      calling convention, wrap the RUCKUS routines in a BASIC function and call
  160.      it as you normally would, i.e., stat = LoadMidiFile(file$,LMP) where
  161.      LoadMidi contains the actual code (as shown above).
  162.  
  163.      Now that I have your interest, let me tell you why I've provided this
  164.      toolkit for you. Shareware. That's right. Shareware. What I've done is
  165.      provide you with a means to evaluate this product completely, with no
  166.      upfront obligations. If you can't make use of this product, no problem.
  167.      Think of this as the ultimate return policy. You can actually take the
  168.      goods home, try it out, break it in. Then, if after a period of no more
  169.      than 21 days, you feel that this product is well worth the price I'm
  170.      asking, by all means, you should go ahead and fill out the order form and
  171.      send it in. If you do not register, then of course, it means the product is
  172.      not something you can use. If you can't use it, I don't want your money.
  173.      But if it's something you will use, it's only fair that you register. The
  174.      PROFESSIONAL registered versions does not have any built-in advertising
  175.      screens. The PERSONAL DEVELOPER registered version does display a sign-on
  176.      banner once. See Appendix Z. for ordering options and other related
  177.      information specific to this product.
  178.  
  179.      The documentation that follows describes each of the function routines as
  180.      to use, pack type used, and sample code in BASIC. Also available is a C
  181.      version of this toolkit, differing only in example programs and
  182.      documentation*. For additional source examples see the included X files on
  183.      disk.
  184.  
  185.      *There is a specific object module that must be used with any Borland C
  186.      compiler, but this LIB will work for other C compilers.
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209.      RUCKUS-MIDI Functions.
  210.  
  211.       0. SysInfoMidi ...........................................  5
  212.       1. InitMidi ..............................................  6
  213.       2. ExitMidi ..............................................  7
  214.       3. AtExitMidi ............................................  8
  215.       4. LoadMidi ..............................................  9
  216.       5. PlayMidi .............................................. 10
  217.          6 and 7 are not used
  218.       8. EndMidi ............................................... 11
  219.       9. PauseMidi ............................................. 12
  220.      10. DeallocMidi ........................................... 13
  221.      11. FastFwdMidi ........................................... 14
  222.      12. OutMsgMidi ............................................ 15
  223.          13 to 19 are not used 
  224.      20. SetAllMidi ............................................ 16
  225.      21. SetVolumeMidi ......................................... 17
  226.      22. SetToneMidi ........................................... 18
  227.      23. SetPatchMidi .......................................... 19
  228.      24. SetChMaskMidi ......................................... 20
  229.          25 to 29 are not used
  230.      30. SetAllFMSBP ........................................... 21
  231.  
  232.          Appendix A. Tips and Tricks ........................... 22
  233.          Appendix B. Pack Structure ............................ 23
  234.          Appendix C. Compiler, Linker, QLB, and Call Use ....... 26
  235.          Appendix D. RUCKUS-MIDI Data Area ..................... 28
  236.          Appendix E. Key#, Frequencies and Channel Messages .... 30
  237.          Appendix F. General MIDI Sound Set .................... 32
  238.          Appendix G. MT-32 Sound Set ........................... 34
  239.          Appendix H. Patch Map Format .......................... 36
  240.          Appendix Z. Ordering Information, License Agreement
  241.                      and Product Support........................ 38
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.      SysInfoMidi         Func: 0        Pack: SysInfoMidiPack
  277.  
  278.  
  279.      Determine which RUCKUS-supported devices are available on the current
  280.      machine. Information returned on detected devices includes base I/O port
  281.      and channel information (a mask indicating available channels). 
  282.  
  283.      SysInfoMidi may be called only if no RUCKUS-MIDI device is active. If you
  284.      an active device (via InitMidi), perform an ExitMidi before calling this
  285.      function.
  286.  
  287.  
  288.      RUCKUS-MIDI currently supports the following devices:
  289.  
  290.      Device ID
  291.  
  292.           0         AdLib melodic, MIDI channels 0 to 8.
  293.                     Does not support mappable drum channel.
  294.  
  295.           1         AdLib percussive, MIDI channels 0 to 5, and 9.
  296.                     The drum channel (9) is programmer-selectable and 
  297.                     it maps to the 5 additional percussive voices.
  298.  
  299.           2*        OPL-3 percussive, MIDI channels 0 to 15.
  300.                     The drum channel (9) is programmer-selectable and
  301.                     it maps to the 5 additional percussive voices.
  302.  
  303.           3*        OPL-3 percussive, MIDI channels 0 to 8, and 9.
  304.                     The drum channel (9) is programmer-selectable and
  305.                     it maps to the 5 additional percussive voices.
  306.                     4-operator timbre data for channels 0 to 5, and 
  307.                     2-operator timbre data for channels 6 to 8.
  308.  
  309.           4*        UltraSound (GUS), MIDI channels 0 to 15, and 9.
  310.                     The drum channel (9) is programmer-selectable.
  311.  
  312.                * Devices 2, 3, and 4 are currently not supported but will be
  313.                available in the future.
  314.  
  315.      Sample Use:
  316.  
  317.      DIM SIMP AS SysInfoMidiPackTYPE
  318.  
  319.      SIMP.Func = SysInfoMidi
  320.      stat = RUCKMIDI(SIMP)
  321.      IF stat = 0 THEN
  322.         'SIMP.Device0 is 1 if AdLib melodic mode available
  323.         'if above then SIMP.D0port is 388h
  324.         '              SIMP.D0mask is 1FFh
  325.         'SIMP.Device1 is 1 if AdLib percussive mode available
  326.         'if above then SIMP.D1port is 388h
  327.         '              SIMP.D1mask is 23Fh
  328.  
  329.  
  330.  
  331.                                                                                5
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343.      InitMidi            Func: 1        Pack: mInitMidiPack
  344.  
  345.  
  346.      Initialize the RUCKUS-MIDI system to the following:
  347.  
  348.      DeviceID  - any of the supported devices found by SysInfoMidi.
  349.      IOport    - the base I/O port as reported by SysInfoMidi.
  350.      PercCh    - the channel to use for percussion mapping.
  351.      ChMask    - the 16-bit mask as reported by SysInfoMidi.
  352.      Flags     - additional options.
  353.  
  354.      No RUCKUS-MIDI routines can be called prior InitMidi except SysInfoMidi and
  355.      SetAllFMSBP.
  356.  
  357.      On return from a successful initialization, two segmented far pointers are
  358.      returned: InfoPtr and MidiExitPtr. 
  359.  
  360.      InfoPtr is used to locate the RUCKUS-MIDI data area for use with compilers
  361.      that do not handle external variable references (such as QuickBASIC). Other
  362.      compilers (such as C7) can reference RUCKUS-MIDI data directly since the
  363.      references are public. See Appendix D. for more on RUCKUS-MIDI data.
  364.  
  365.      MidiExitPtr is used for those development systems that do not have direct
  366.      support for the ANSI _atexit procedure. MidiExitPtr is a function pointer
  367.      (far pointer -> MidiExit) of the routine that should be called before
  368.      termination of any program that uses RUCKUS-MIDI. Most development systems
  369.      do provide for _atexit since it provides for orderly program shutdown in
  370.      the case of abnormal termination. For those that don't, you must include
  371.      the stub object module NOATEXIT.OBJ. See Appendix C. for more information.
  372.  
  373.      Sample Use:
  374.  
  375.      DEFINT A-Z                    'NOTE: All BASIC examples assume DEFINT A-Z
  376.      DIM MIMP AS mInitMidiPackTYPE
  377.  
  378.      MIMP.Func = InitMidi  'see Appendix B. Pack Structure for more
  379.      MIMP.DeviceID = 1
  380.      MIMP.IOport = &H388
  381.      MIMP.PercCh = 9
  382.      MIMP.ChMask = &H23F   '0000 00P0 0011 1111 binary (P=perc channel)
  383.      MIMP.Flags = 0        'see Appendix D. for bitmap of flags
  384.      stat = RUCKMIDI(MIMP)
  385.      IF stat = 0 THEN
  386.         'MIMP.InfoPtrOff is offset address to start of RUCKUS-MIDI data area
  387.         'MIMP.InfoPtrSeg is segment
  388.         'MIMP.MidiExitPtrOff is offset address to ExitMidi routine
  389.         'MIMP.MidiExitPtrSeg is segment 
  390.  
  391.         'sample use of InfoPtr
  392.         'PEEKW/D() is like PEEK but reads 2/4-byte words (see Appendix A.)
  393.         DEF SEG = MIMP.InfoPtrSeg
  394.         DosMemoryAvailK = PEEKW(InfoPtrOff + 8)
  395.         DEF SEG
  396.  
  397.  
  398.                                                                                6
  399.  
  400.  
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  
  409.  
  410.      ExitMidi            Func: 2        Pack: XitMidiPack
  411.  
  412.  
  413.      After having initialized a device via InitMidi, you must call ExitMidi
  414.      before initializing a new device or before your program ends. ExitMidi
  415.      performs three tasks. It frees any memory directly allocated by RUCKUS-MIDI
  416.      (such as within LoadMidi), it shuts down the device last initialized, and
  417.      it restores any hooked interrupts.
  418.  
  419.      This function should be called before ending your program. If your
  420.      development system supports the ANSI _atexit, it will be called
  421.      automatically (see AtExitMidi below).
  422.  
  423.      Sample Use:
  424.  
  425.      DIM XMP AS XitMidiPackTYPE
  426.  
  427.      'program has run its course, before exiting to DOS perform cleanup
  428.  
  429.      XMP.Func = ExitMidi
  430.      stat = RUCKMIDI(XMP)
  431.      END 
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.                                                                                7
  466.  
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.      AtExitMidi          Func: 3        Pack: XitMidiPack
  478.  
  479.  
  480.      AtExitMidi is used to register the MidiExit routine to be called as a
  481.      normal procedure in the ending of your program. It will be called by the
  482.      compiler's startup code after your program _main() has ended. This is
  483.      important since it ensures that all resources allocated by RUCKUS-MIDI are
  484.      freed and that the sound device is properly shut down.
  485.  
  486.      AtExitMidi should be called immediately after initializing your first
  487.      device. It need not (and should not) be called again during the program. In
  488.      other words, you can InitMidi/ExitMidi as many times during a program's
  489.      execution as you want, but you should only call AtExitMidi after the first
  490.      InitMidi.
  491.  
  492.      It is possible for _atexit to fail to register ExitMidi. This would be the
  493.      result of too many registrations requests having been made to _atexit.
  494.      Since _atexit typically can handle 32 registrations, it is unlikely to fail
  495.      (fail=become full). If it does fail, it should _not_ be considered a fatal
  496.      error, however, be aware that the automatic ExitMidi call will not take
  497.      place.
  498.  
  499.      Sample Use:
  500.  
  501.      DIM MIMP AS mInitMidiPack
  502.      DIM XMP AS XitMidiPack
  503.      DIM CalledBefore AS INTEGER   'use STATIC CalledBefore... in SUB/FUNC
  504.  
  505.      MIMP.Func = InitMidi
  506.      MIMP.DeviceID = 1
  507.      MIMP.IOport = &H388
  508.      MIMP.PercCh = 9
  509.      MIMP.ChMask = &H23F
  510.      MIMP.Flags = 0          
  511.      stat = RUCKMIDI(MIMP)
  512.      IF stat = 0 THEN
  513.  
  514.         'check to make sure that this is the first AtExitMidi call
  515.  
  516.         IF CalledBefore = 0 THEN
  517.            XMP.Func = AtExitMidi
  518.            stat = RUCKMIDI(XMP)
  519.  
  520.            IF stat = 0 THEN 
  521.               CalledBefore = -1
  522.            ELSE
  523.               PRINT "_atexit unable to register ExitMidi"
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.                                                                                8
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544.      LoadMidi            Func: 4        Pack: LoadMidiPack
  545.  
  546.  
  547.      Use to load MIDI data into DOS memory. While you may use your own memory
  548.      allocation and DOS file routines to load MIDI data, LoadMidi automates this
  549.      task.
  550.  
  551.      LoadMidi makes memory allocations directly from the operating system pool*.
  552.      This means that before using LoadMidi DOS must have enough available memory
  553.      to into which to load the file. For QuickBASIC (QuickBASIC, BASIC7, and
  554.      VBDOS) you can use SETMEM(). For most other compilers, memory is not
  555.      allocated until it's needed, thus DOS will be in control of any unallocated
  556.      memory which is just the way LoadMidi likes it.
  557.  
  558.           Note: In Borland C compilers, memory allocations made via DOS INT21/48
  559.           cannot be used when any _malloc() call is made. Doing so corrupts the
  560.           _malloc() chain. This is strictly a Borland problem. To overcome this
  561.           limitation, you must use the memory module patch, MIDMEMBC.OBJ. See
  562.           the C-specific version of RUCKUS for more on this patch.
  563.  
  564.      LoadMidi manages up to 32 files in memory at one time, given sufficient
  565.      RAM. LoadMidi can also seek into a given file at any position and start
  566.      loading from that position for any number of bytes. This lets you
  567.      concatenate several MIDI data files into one and load any or all of the
  568.      internal MIDI data streams into memory. In addition, you can load the
  569.      entire file into memory and, by using pre-calculated memory offsets, start
  570.      MidiPlay at any of the MIDI data streams. 
  571.  
  572.      LoadMidi performs no format checking. Format checking is done by MidiPlay.
  573.  
  574.      Once a file has been loaded by LoadMidi, you can release the memory used by
  575.      the file by using DeallocMidi. See that routine for more.
  576.  
  577.      Sample Use:
  578.  
  579.      DIM LMP AS LoadMidiPackTYPE  'for multiple concurrent loads 
  580.                                   'use LMP(1 TO NumOfLoads) AS...
  581.  
  582.      filename$ = file2load$ + CHR$(0) 'filename must end with ASCII 0
  583.  
  584.      LMP.Func = LoadMidi
  585.      LMP.FilenamePtrOff = SADD(filename$)    'VARSEG() is QuickBASIC format
  586.      LMP.FilenamePtrSeg = VARSEG(filename$)  'BASIC7/VBDOS use SSEG(filename$)
  587.      LMP.StartPos = 0&     'start load at first byte of file
  588.      LMP.LoadSize = 0&     'when=0 entire file is loaded into memory
  589.      stat = RUCKMIDI(LMP)
  590.      IF stat = 0 THEN
  591.         'LMP.LoadPtrOff/Seg is address of load and used by MidiPlay
  592.         'LMP.LoadPtrOff is always returned=0
  593.         'LMP.LoadPtrSeg is DOS segment allocated
  594.  
  595.  
  596.  
  597.  
  598.  
  599.                                                                                9
  600.  
  601.  
  602.  
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609.  
  610.  
  611.      PlayMidi            Func: 5        Pack: PlaybackMidiPack
  612.  
  613.  
  614.      Once MIDI data is in memory, you can begin play. Play is done as a
  615.      background task allowing other operations, such as screen updating or file
  616.      loading, to continue. Once you begin play, it plays itself. You need only
  617.      check the end of play status to determine when a MIDI stream has completed
  618.      play. All other aspects of MIDI play is handled by RUCKUS-MIDI.
  619.  
  620.      A routine also available in RUCKUS-MIDI is OutMsgMidi. You can use
  621.      OutMsgMidi to issue MIDI channel messages directly. 
  622.  
  623.      File format type is checked by PlayMidi. To determine file format before
  624.      actual play see FastFwdMidi. Note that ROL-converted MIDI files (via
  625.      ROL2MIDI.EXE) and CMF files can only be played (correctly) when using the
  626.      OPL-2 or -3 chip (on AdLib-compatibles such as SB, PAS, SB Pro, etc.).
  627.  
  628.      Sample Use:
  629.  
  630.      DIM PBMP AS PlaybackMidiPackTYPE  'LMP and DMP assumed defined
  631.  
  632.      PBMP.Func = PlayMidi
  633.      PBMP.Mode = 1          'this must be 1 for background play
  634.  
  635.      PBMP.LoadPtrOff = LMP.LoadPtrOff   'LoadPtr as set by LoadMidi
  636.      PBMP.LoadPtrSeg = LMP.LoadPtrSeg
  637.      stat = RUCKMIDI(PBMP)
  638.      IF stat = 0 THEN
  639.         
  640.         'the MIDI data is being played in the background
  641.         'at this point you can do anything you want
  642.         'for this example we just wait for the end status to become true
  643.         'see Appendix D. for information on the RUCKUS-MIDI data area
  644.  
  645.         DEF SEG = MIMP.InfoPtrSeg     'as set by InitMidi
  646.         midend = MIMP.InfoPtrOff + 6  'offset to mid@end in data area
  647.  
  648.         DO
  649.            DonePlaying = PEEK(midend) '=0 until MIDI data has ended
  650.                                       'and non-zero when data has ended
  651.         LOOP UNTIL DonePlaying
  652.         DEF SEG
  653.  
  654.         XMP.Func = EndMidi            'EndMidi should be called whenever
  655.         stat = RUCKMIDI(XMP)          'a MIDI tune is has ended
  656.  
  657.         'if no further use for this MIDI data, release the memory it uses
  658.         'see DeallocMidi for more information
  659.  
  660.         DMP.Func = DeallocMidi
  661.         DMP.HandSeg = LMP.LoadPtrSeg
  662.         DMP.TypeFlag = 0
  663.         stat = RUCKMIDI(DMP)
  664.  
  665.  
  666.                                                                               10
  667.  
  668.  
  669.  
  670.  
  671.  
  672.  
  673.  
  674.  
  675.  
  676.  
  677.  
  678.      EndMidi             Func: 8        Pack: XitMidiPack
  679.  
  680.  
  681.      Use to stop play of the initialized device. EndMidi is similar in function
  682.      to ExitMidi except that it does not release any memory. It does not
  683.      completely shut down the initialized device but it does restore hooked
  684.      interrupts.
  685.  
  686.      EndMidi can be thought of as a stop button, whereas ExitMidi is more like
  687.      the on/off switch.
  688.  
  689.      Sample Use:
  690.  
  691.      DIM XMP AS XitMidiPackTYPE
  692.  
  693.      'MIDI tune has play and is over, perform EndMidi to restore hooked
  694.      'interrupts and silence device
  695.  
  696.      XMP.Func = EndMidi
  697.      stat = RUCKMIDI(XMP)
  698.  
  699.      'now continue with program such as load next tune, play, etc.
  700.  
  701.  
  702.  
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713.  
  714.  
  715.  
  716.  
  717.  
  718.  
  719.  
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.  
  733.                                                                               11
  734.  
  735.  
  736.  
  737.  
  738.  
  739.  
  740.  
  741.  
  742.  
  743.  
  744.  
  745.      PauseMidi           Func: 9        Pack: PauseMidiPack
  746.  
  747.  
  748.      Use to pause or unpause currently playing MIDI data. There is no effect if
  749.      no data is currently playing.
  750.  
  751.      Sample Use:
  752.  
  753.      DIM PMP AS PauseMidiPack
  754.  
  755.      'pause or unpause depending on state of DoPause flag
  756.  
  757.      IF DoPause THEN
  758.         PMP.Pause = 1 
  759.      ELSE
  760.         PMP.Pause = 0
  761.      ENDIF
  762.  
  763.      PMP.Func = PauseMidi
  764.      stat = RUCKMIDI(PMP)
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.  
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.  
  800.                                                                               12
  801.  
  802.  
  803.  
  804.  
  805.  
  806.  
  807.  
  808.  
  809.  
  810.  
  811.  
  812.      DeallocMidi         Func: 10       Pack: DeallocMidiPack
  813.  
  814.  
  815.      Use to release memory used by LoadMidi. Once a file has been loaded via
  816.      LoadMidi, the memory used by that load is not available for other loads
  817.      until you release it using DeallocMidi. 
  818.  
  819.      If you will only be needing one MIDI data stream in memory at a time you
  820.      can load as many files as you want using only the memory needed by the
  821.      largest file loaded (i.e., reuse the memory). For example, let's say that
  822.      you have 40 separate MIDI data files that you will be playing. A simple
  823.      method to load these is to free up 64K (single MIDI file max for RUCKUS-
  824.      MIDI), LoadMidi a MIDI file, play it through, DeallocMidi the memory it
  825.      used, LoadMidi the next MIDI file, play it through, DeallocMidi, and so on.
  826.      This technique can also be used to LoadMidi into one concatenated file.
  827.      This requires that you pre-calculate at what offset each MIDI data stream
  828.      starts and its size. 
  829.  
  830.      DeallocMidi is called automatically by ExitMidi.
  831.  
  832.      Sample Use:
  833.  
  834.      DIM DMP AS DeallocMidiPackTYPE
  835.  
  836.      DMP.Func = DeallocMidi
  837.      DMP.HandSeg = LMP.LoadPtrSeg    'as set by LoadMidi
  838.      DMP.TypeFlag = 0                'must be = 0
  839.      stat = RUCKMIDI(DMP)
  840.      IF stat = 9 THEN 
  841.         PRINT "Invalid LMP.LoadPtrSeg, Not a fatal error"
  842.         'means that LMP.LoadPtrSeg is not valid
  843.         'perhaps it's already been deallocated by ExitMidi
  844.  
  845.  
  846.  
  847.  
  848.  
  849.  
  850.  
  851.  
  852.  
  853.  
  854.  
  855.  
  856.  
  857.  
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.  
  865.  
  866.  
  867.                                                                               13
  868.  
  869.  
  870.  
  871.  
  872.  
  873.  
  874.  
  875.  
  876.  
  877.  
  878.  
  879.      FastFwdMidi         Func: 11       Pack: FastFwdMidiPack
  880.  
  881.  
  882.      A standard MIDI file is a series of MIDI messages that are sequenced by
  883.      based on timings within the file. Each MIDI message is preceded by a tick
  884.      count that informs MIDI-RUCKUS when to output each particular message.
  885.  
  886.      FastFwdMidi instructs RUCKUS-MIDI to disregard all timing information up to
  887.      the specified tick count. It also mutes the output so no sound is produced.
  888.      The actual fast forward does not take place until the PlayMidi function is
  889.      called. After using FastFwdMidi, you must call FastFwdMidi again with
  890.      FFMP.TickCount=0& to turn off fast-forward mode.
  891.  
  892.      One use of FastFwdMidi is determine the running time of a MIDI file.
  893.  
  894.      Sample Use:
  895.  
  896.      DIM FFMP AS FastFwdMidiPack
  897.  
  898.      FFMP.Func = FastFwdMidi      'Given the MIDI data is already in memory...
  899.      FFMP.TickCount = -1&         'set to fast-fwd all the way through
  900.      stat = RUCKMIDI(FFMP)
  901.      IF stat = 0 THEN
  902.         PBMP.Func = PlayMidi      'play but in fast fwd mode
  903.         PBMP.Mode = 1
  904.         PBMP.LoadPtrOff = LMP.LoadPtrOff
  905.         PBMP.LoadPtrSeg = LMP.LoadPtrSeg
  906.         stat = RUCKMIDI(PBMP)
  907.         IF stat = 0 THEN
  908.  
  909.            DEF SEG = MIMP.InfoPtrSeg
  910.            bp = MIMP.InfoPtrOff          'bp used to lessen line length
  911.            DO : LOOP UNTIL PEEK(bp + 6)  'wait to end
  912.            
  913.            'TotalTicks& is the tick count at the end the last MIDI message
  914.            '--also need Ticks/quarternote and microseconds/quarternote
  915.  
  916.            TotalTicks& = PEEKD(bp + 22)  'see Appendix A. for PEEKD(),PEEKW()
  917.            TicksQnote = PEEKW(bp + 16)   
  918.            uSecsQnote& = PEEKD(bp + 18)  'watch for overflow so div\10 below!
  919.            DEF SEG
  920.  
  921.            TimeInSecs = ((uSecsQnote&\10)*(TotalTicks&\TicksQnote))\100000
  922.  
  923.            FFMP.Func = FastFwdMidi
  924.            FFMP.TickCount = 0&          'set FastFwdMidi off
  925.            stat = RUCKMIDI(FFMP)
  926.  
  927.      To fast forward in small increments while the MIDI data is playing, first
  928.      get the current TickCount (at bp+22), add to it the number of ticks to
  929.      skip, and use that as the FFMP.TickCount. If FFMP.TickCount > TotalTicks&
  930.      then do not perform the fast forward since it would be past the end of
  931.      data. See Appendix A. for an source example of this.
  932.  
  933.  
  934.                                                                               14
  935.  
  936.  
  937.  
  938.  
  939.  
  940.  
  941.  
  942.  
  943.  
  944.  
  945.  
  946.      OutMsgMidi          Func: 12       Pack: OutMsgMidiPack
  947.  
  948.  
  949.      OutMsgMidi lets you send MIDI channel messages directly to the channel
  950.      message parser without needing to use PlayMidi. Whereas PlayMidi deals with
  951.      all aspects of playing a MIDI stream, such as interrupt setup, timing
  952.      control and other events required to process the MIDI data, OutMsgMidi
  953.      provides access to only the channel message parser of RUCKUS-MIDI.
  954.  
  955.      MIDI channel messages (composed of channel voice and mode messages) are
  956.      those that control the actual sound output. The current MIDI 1.0
  957.      specification specifies eight message groups, each identified by a status
  958.      byte and followed by one or two data bytes. See Appendix E. for more
  959.      information on MIDI channel messages, key numbers and frequencies.
  960.  
  961.      Obvious use of OutMsgMidi is for sound effects. Notes can be sounded,
  962.      volumes adjusted, programs (instruments) selected and fine-tuned, and sound
  963.      can be turned off.
  964.  
  965.      When outputting to a channel be aware that NoteOn messages will not sound
  966.      if the channel is already in a NoteOn. I.e., each NoteOn should have a
  967.      corresponding NoteOff (or NoteOn with velocity=0).
  968.  
  969.      Sample Use:
  970.  
  971.      DIM OMMP AS OutMsgMidiPackTYPE
  972.  
  973.      OMMP.Func = OutMsgMidi
  974.      OMMP.Mstatus = &H80       'channel 0, NoteOn
  975.      OMMP.Mdata = &H7F3C       'sound middle-C (3Fh=60d) at max vol (7Fh=127d)
  976.      stat = RUCKMIDI(OMMP)
  977.  
  978.      'for those unfamiliar with hex notation, you can use the following to 
  979.      'derive Mdata values:
  980.      '
  981.      'Mdata = (Volume * 256) + NoteNumber
  982.  
  983.  
  984.  
  985.  
  986.  
  987.  
  988.  
  989.  
  990.  
  991.  
  992.  
  993.  
  994.  
  995.  
  996.  
  997.  
  998.  
  999.  
  1000.  
  1001.                                                                               15
  1002.  
  1003.  
  1004.  
  1005.  
  1006.  
  1007.  
  1008.  
  1009.  
  1010.  
  1011.  
  1012.  
  1013.      SetAllMidi          Func: 20       Pack: SetMidiPack
  1014.  
  1015.  
  1016.      While MIDI editing is best done on the MIDI data file itself with a
  1017.      sequencer/editor, RUCKUS-MIDI provides relative volume and tone adjustment
  1018.      to the MIDI data stream. Also, you may select the MIDI program/patch map to
  1019.      use. The channel mask as set in InitMidi may also be adjusted. You may also
  1020.      call each of these routines separately (see following SetMidi routines).
  1021.      For information on setting the patch map, set SetPatchMidi.
  1022.  
  1023.      The relative volume and tone adjustments let you boost or cut the playback
  1024.      levels of any or all of the MIDI channels (0-15). For example, if the MIDI
  1025.      data file has a trumpet playing to low on channel 4, you can boost channel
  1026.      4's relative volume so that the trumpet plays louder. Volume adjustment
  1027.      takes effect immediately.
  1028.  
  1029.      Tone adjustment allows you to adjust the notes being sounded in any or all
  1030.      of the channels. For example, if you want to have the notes sound on
  1031.      channel 5 play an octave lower, you adjust channel 5's relative tone by -
  1032.      12. Two octaves lower adjust by -24; an octave higher, adjust by +12; so
  1033.      on. Tone adjustment takes effect on the next sounded note.
  1034.  
  1035.      For adjusting relative levels you must designate which channels to operate
  1036.      on. SMP.Channel is a bit-mapped mask used to identify which channels. Each
  1037.      MIDI channel (0-15) has a corresponding bit in SMP.Channel. Channel 0 has
  1038.      SMP.Channel bit 0 as its mask; channel 1, bit 1; so on. For example, for
  1039.      this call to affect only channel 0, set SMP.Channel = 1. For only MIDI
  1040.      channel 1, use 2. For both channels 0 and 1, use 3. For those unfamiliar
  1041.      with binary notation, the following formula can be used.
  1042.  
  1043.      'Given the array BM(0 TO 15) is non-zero for each channel to be adjusted:
  1044.      '(Note: Since accum may overflow we process bit 15 as a special case)
  1045.      accum = 0
  1046.      FOR i = 0 TO 14
  1047.         IF BM(i) THEN accum = accum + (2 ^ i)
  1048.      NEXT
  1049.      IF BM(15) THEN accum = accum OR &H8000  'use this as SMP.Channel
  1050.  
  1051.      Sample Use:
  1052.  
  1053.      DIM SMP AS SetMidiPackTYPE
  1054.  
  1055.      SMP.Func = SetAllMidi
  1056.      SMP.Channel = &H21       'adjust channels 0 and 5 only
  1057.      SMP.Channel = 13         'increase those channels' volumes by 13
  1058.      SMP.Tone = 0             'no adjustments for tone
  1059.      SMP.ChMask = MIMP.ChMask 'use same channels as at InitMidi
  1060.      SMP.PatchMapID = 1       'use internal MT-32 program map
  1061.      SMP.PatchMapPtrOff = 0   'since using internal map these should be=0
  1062.      SMP.PatchMapPtrSeg = 0   '(see SetPatchMidi for more on PatchMapID)
  1063.      stat = RUCKMIDI(SMP)     
  1064.      IF stat = 0 THEN 'okay
  1065.  
  1066.  
  1067.  
  1068.                                                                               16
  1069.  
  1070.  
  1071.  
  1072.  
  1073.  
  1074.  
  1075.  
  1076.  
  1077.  
  1078.  
  1079.  
  1080.      SetVolumeMidi       Func: 21       Pack: SetMidiPack
  1081.  
  1082.  
  1083.      The relative volume adjustment lets you boost or cut the playback volume
  1084.      level of any or all of the MIDI channels (0-15). For example, if the MIDI
  1085.      data file has a trumpet playing to low on channel 4, you can boost channel
  1086.      4's relative volume so that the trumpet plays louder. Volume adjustment
  1087.      takes effect immediately. Any relative increase in volume level will not
  1088.      exceed the maximum level allowed, i.e., if the trumpet is already playing
  1089.      at its maximum volume, any positive relative adjustment will have no
  1090.      effect.
  1091.  
  1092.      For adjusting relative volume you must designate which channels to operate
  1093.      on. SMP.Channel is a bit-mapped mask used to identify which channels. Each
  1094.      MIDI channel (0-15) has a corresponding bit in SMP.Channel. See SetAllMidi
  1095.      on how to do this.
  1096.  
  1097.      Level adjustment range is -128 to 127.
  1098.  
  1099.      Sample Use:
  1100.  
  1101.      DIM SMP AS SetMidiPackTYPE
  1102.  
  1103.      SMP.Func = SetVolumeMidi
  1104.      SMP.Channel = &H31       'adjust channels 0, 4 and 5 only
  1105.      SMP.Volume = 127         'play those channels always at max volume
  1106.      stat = RUCKMIDI(SMP)     
  1107.      IF stat = 0 THEN 'okay
  1108.  
  1109.  
  1110.  
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127.  
  1128.  
  1129.  
  1130.  
  1131.  
  1132.  
  1133.  
  1134.  
  1135.                                                                               17
  1136.  
  1137.  
  1138.  
  1139.  
  1140.  
  1141.  
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  1147.      SetToneMidi         Func: 22       Pack: SetMidiPack
  1148.  
  1149.  
  1150.      Tone adjustment allows you to adjust notes being sounded in any or all of
  1151.      the channels. For example, if you want to have the notes sound on channel 5
  1152.      play an octave lower, adjust channel 5's relative tone by -12. Two octaves
  1153.      lower adjust by -24; an octave higher, adjust by +12; so on. Tone
  1154.      adjustment takes effect on the next sounded note. For more on note numbers
  1155.      and their relationship to notes and octaves, see Appendix E. 
  1156.  
  1157.      For adjusting relative tone you must designate which channels to operate
  1158.      on. SMP.Channel is a bit-mapped mask used to identify which channels. Each
  1159.      MIDI channel (0-15) has a corresponding bit in SMP.Channel. See SetAllMidi
  1160.      on how to do this.
  1161.  
  1162.      Level adjustment range is -128 to 127.
  1163.  
  1164.      Sample Use:
  1165.  
  1166.      DIM SMP AS SetMidiPackTYPE
  1167.  
  1168.      SMP.Func = SetToneMidi
  1169.      SMP.Channel = &H1        'adjust channel 0 only
  1170.      SMP.Tone = -12           'play notes on that channel one octave lower    
  1171.      stat = RUCKMIDI(SMP)     
  1172.      IF stat = 0 THEN 'okay
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180.  
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.  
  1190.  
  1191.  
  1192.  
  1193.  
  1194.  
  1195.  
  1196.  
  1197.  
  1198.  
  1199.  
  1200.  
  1201.  
  1202.                                                                               18
  1203.  
  1204.  
  1205.  
  1206.  
  1207.  
  1208.  
  1209.  
  1210.  
  1211.  
  1212.  
  1213.  
  1214.      SetPatchMidi        Func: 23       Pack: SetMidiPack
  1215.  
  1216.  
  1217.      MIDI specifies instruments by number (0-127). These instruments are often
  1218.      called programs, or patches. The one big incompatibility among MIDI data
  1219.      files is correspondence of instrument number to instrument sound. Up to
  1220.      just a few years ago, there was no standard, so that files made by one
  1221.      sequencer often sounded totally wrong when played on another. Ideally,
  1222.      there would be only one program map that all MIDI used, but that would be
  1223.      to restrictive to musicians. Because of this lack of standard, the
  1224.      International MIDI Association (IMA) created what is know as the General
  1225.      MIDI Sound Set. This is a standardized set of programs that map instrument
  1226.      numbers to known instrument sounds. It also standardizes the percussion
  1227.      map. 
  1228.  
  1229.      The percussion map is similar to the main sound set but is used to sound a
  1230.      wide range of percussive instruments (the main sound set is nearly all
  1231.      melodic instruments). The percussion map takes note numbers that are output
  1232.      on a certain channel (channel 9 by standard (0-based)) and maps that note
  1233.      number to a particular percussive sound. For example, note 60 when played
  1234.      on any channel but the percussion channel plays a middle-C on whatever the
  1235.      current instrument program is for that channel. However, when note number
  1236.      60 is played on the percussion channel, it maps to the Hi Bongo. Note
  1237.      number 35 maps to the bass drum. See Appendix F. for the General MIDI Sound
  1238.      Set description.
  1239.  
  1240.      In addition to the General MIDI (GM) set, RUCKUS-MIDI also maps to the MT-
  1241.      32 sound set. Many MIDI files have been sequenced to the MT-32 set (see
  1242.      Appendix G. for the MT-32 sound set). In the future, you'll find more and
  1243.      more files sequenced to General MIDI. Microsoft Windows Multimedia
  1244.      specifies General MIDI as its sound set. RUCKUS-MIDI uses the GM map by
  1245.      default.
  1246.  
  1247.      For those MIDI files that do not comply with either GM or MT-32, RUCKUS-
  1248.      MIDI allows for custom patch maps to be used. See Appendix H. for custom
  1249.      patch map specifications and implementation notes. Be aware, however, that
  1250.      custom patch maps (those created by you) are device dependent. This means
  1251.      that you need a separate custom patch map for each device you intend to
  1252.      support. The internal RUCKUS-MIDI patch maps will always be device-
  1253.      independent, in that all current and future devices supported by RUCKUS-
  1254.      MIDI will have a GM and an MT-32 map available.
  1255.  
  1256.      Sample Use:
  1257.  
  1258.      DIM SMP AS SetMidiPackTYPE
  1259.  
  1260.      SMP.Func = SetPatchMidi
  1261.      SMP.PatchMapID = 1       '1=MT-32 (0=GM and -1 means use custom map)
  1262.      SMP.PatchMapPtrOff = 0
  1263.      SMP.PatchMapPtrSeg = 0   'since not using custom patch, set these=0
  1264.      stat = RUCKMIDI(SMP)
  1265.      IF stat = 0 THEN 'okay
  1266.  
  1267.  
  1268.  
  1269.                                                                               19
  1270.  
  1271.  
  1272.  
  1273.  
  1274.  
  1275.  
  1276.  
  1277.  
  1278.  
  1279.  
  1280.  
  1281.      SetChMaskMidi       Func: 24       Pack: SetMidiPack
  1282.  
  1283.  
  1284.      SetChMaskMidi adjusts the same channel mask as that specified for InitMidi.
  1285.  
  1286.      There are 16 MIDI channels, numbered 0 to 15 in RUCKUS-MIDI (sometimes seen
  1287.      numbered 1-16). Each channel can be used to play a particular program, or
  1288.      instrument (sometimes called a voice). For example, say a MIDI file playing
  1289.      "Street Fight" is sequenced for piano and guitar. Each instrument could be
  1290.      played at the same time providing that there is a channel available for
  1291.      each. Since there are only 2 instruments and 16 MIDI channels, that's no
  1292.      problem. Further, let's say that, later, you don't want to hear the piano
  1293.      voice. By using SetChMaskMidi, you can selectively turn off the piano
  1294.      channel (channel 0, or whichever channel it's on). 
  1295.  
  1296.      SetChMaskMidi also has another important use. It can be used to turn off
  1297.      channels that are not supported by the currently selected device. For
  1298.      example, the AdLib MSC in percussive mode (RUCKUS-MIDI deviceID 1) does not
  1299.      support channels 6 to 8, and 10 to 15. These channels are not supported
  1300.      because there are not sufficient voices available on that device. These
  1301.      channels (6-8, 10-15) should be masked out so that they are not processed.
  1302.  
  1303.      In addition to turning off channels that cannot be supported due to lack of
  1304.      voices, it may also be necessary to turn off MIDI channels due to the way
  1305.      the MIDI file has been sequenced. In particular, Microsoft Windows
  1306.      Multimedia Specification dictates that MIDI files be sequenced redundantly.
  1307.      Channels 0 to 9 are for so-called extended synthesizers, and channels 12 to
  1308.      15 are for so-called base-level synthesizers. In either case, the highest
  1309.      channel (9 and 15, respectively) is used for the percussive channel. The
  1310.      specification also states that the most important channels be the lower-
  1311.      numbered (respective their synthesizer level). In RUCKUS-MIDI, such
  1312.      redundant MIDI files should always be played as if an extended synthesizer
  1313.      is active (channels 0 to 9) and the base-level redundant channels (12 to
  1314.      15, as well as channels 10 and 11) should be masked out.
  1315.  
  1316.      SMP.ChMask is a bitmapped mask, 1 bit for each channel. See SetAllMidi for
  1317.      an example in how to determine the value to use for SMP.ChMask.
  1318.  
  1319.      Sample Use:
  1320.  
  1321.      DIM SMP AS SetMidiPackTYPE
  1322.  
  1323.      SMP.Func = SetChMaskMidi
  1324.      SMP.ChMask = 3            'turn off all channels except 0 and 1
  1325.      stat = RUCKMIDI(SMP)
  1326.      IF stat = 0 THEN 'okay
  1327.  
  1328.  
  1329.  
  1330.  
  1331.  
  1332.  
  1333.  
  1334.  
  1335.  
  1336.                                                                               20
  1337.  
  1338.  
  1339.  
  1340.  
  1341.  
  1342.  
  1343.  
  1344.  
  1345.  
  1346.  
  1347.  
  1348.      SetAllFMSBP         Func:30        Pack: SetFMProPack
  1349.  
  1350.  
  1351.      Though RUCKUS-MIDI is intended and is designed to be device independent,
  1352.      there will be need for access to device-dependant features. The Sound
  1353.      Blaster Pro, for example, has an on-board mixer facility that controls FM
  1354.      chip volume. By default, the SB Pro is set to half-volume, much too low for
  1355.      typical use. By using SetAllFMSBP you can set the FM volume to maximum and
  1356.      let the actual sound volume be controlled via the MIDI data itself.
  1357.  
  1358.      In addition to the basic volume settings, you can also adjust the steering.
  1359.      Steering turns off either the left, right, or both channels. On late-model
  1360.      SB Pro cards, the independent left and right FM channel volumes can be used
  1361.      for better effect (smoother panning). Early-model SB Pros may not have the
  1362.      independent left/right volume adjustments and so steering is used to shift
  1363.      (all) sound left or right. The steering can also be set to mute the FM
  1364.      output. You may find that muting the SB Pro before InitMidi and before
  1365.      EndMidi results in a smoother sound and song transition.
  1366.  
  1367.      There is no Sound Blaster Pro detection routine available in RUCKUS-MIDI
  1368.      since the only device currently supported is the basic FM chip, originally
  1369.      used by the AdLib MSC (which is what the Sound Blaster and other
  1370.      compatibles use). Any device supporting the AdLib at I/O port 388h is
  1371.      detected. When OPL-3 (a super-set of the AdLib chip used by the SB Pro and
  1372.      others) support is added, additional detection routines for it will be
  1373.      included. Using SetAllFMSBP with no SB Pro installed should not present any
  1374.      problems, however, for absolute determination of an SB Pro device, use the
  1375.      detection routines in RUCKUS-DAC.
  1376.  
  1377.      The SB Pro base address I/O port is currently selectable at either 220h
  1378.      (the SB Pro default) or at 240h. Use RUCKUS-DAC for absolute determination.
  1379.      The master volume adjusts the Pro's master volume (also adjustable in
  1380.      RUCKUS-DAC). To low byte of SFMPP.MastVol sets the left channel's volume.
  1381.      The high byte sets the right channel's. Range for each is 1 to 15, odd
  1382.      values only. To set the right channel, multiply the volume by 256, e.g.,
  1383.      SFMPP.MastVol = (256 * RtChVol) + LfChVol. To not change the master volume,
  1384.      set to -1. SFMPP.FMvol has the same range and is set the same way. It
  1385.      cannot be skipped. Steering, described above, can also be skipped by
  1386.      setting SFMPP.Steer to -1. It's practical use is to mute output during
  1387.      InitMidi and during an abrupt EndMidi (abrupt EndMidi meaning ending a
  1388.      MidiPlay before the actual end of data and notes may still be sounding).
  1389.  
  1390.      Sample Use:
  1391.  
  1392.      DIM SFMPP AS SetFMProPackTYPE
  1393.  
  1394.      SFMPP.Func = SetAllFMSBP
  1395.      SFMPP.IOport = &H220     'base port of SB Pro (220h or 240h)
  1396.      SFMPP.MasterVol = &HF0F  'low byte=left,high=right,-1=no change
  1397.      SFMPP.Steer = 0          '0=none,1=left,2=right,3=mute,-1=no change
  1398.      SFMPP.FMvol = &HF0F      'low byte=left,high=right (cannot skip)
  1399.      stat = RUCKMIDI(SFMPP)
  1400.      IF stat = 0 THEN 'okay
  1401.  
  1402.  
  1403.                                                                               21
  1404.  
  1405.  
  1406.  
  1407.  
  1408.  
  1409.  
  1410.  
  1411.  
  1412.  
  1413.  
  1414.  
  1415.      Appendix A. Tips and Tricks.
  1416.  
  1417.  
  1418.      1. PEEK() Word and Double-word Values from Memory.
  1419.      2. Noise Abatement.
  1420.  
  1421.  
  1422.      1. PEEK() Word and Double-word Values from Memory.
  1423.  
  1424.      BASIC provides for a simple, single-byte peek into memory. Since much of
  1425.      RUCKUS-MIDI data is word or double-word size, the following functions can
  1426.      be used:
  1427.  
  1428.      FUNCTION PEEKW%(Offset) STATIC
  1429.      tLow = PEEK(Offset)
  1430.      tHigh = PEEK(Offset + 1)
  1431.      t& = (256& * tHigh) + tLow
  1432.      IF t& > 32767 THEN
  1433.         PEEKW = t& - 65536
  1434.      ELSE
  1435.         PEEKW = t&
  1436.      ENDIF
  1437.      END FUNCTION
  1438.  
  1439.      FUNCTION PEEKD&(Offset) STATIC
  1440.      DIM S4 AS STRING * 4
  1441.      tB0 = PEEK(Offset)
  1442.      tB1 = PEEK(Offset + 1)
  1443.      tB2 = PEEK(Offset + 2)
  1444.      tB3 = PEEK(Offset + 3)
  1445.      S4 = CHR$(tB3) + CHR$(tB2) + CHR$(tB1) + CHR$(tB0)
  1446.      PEEKD& = CVL(S4)
  1447.      END FUNCTION
  1448.  
  1449.  
  1450.      2. Noise Abatement.
  1451.  
  1452.      If a Sound Blaster Pro is known to be available and is used as the MIDI
  1453.      device, noise can be minimized by setting the FM volume to 0, or by muting
  1454.      the FM steering. It can also be used when abruptly ending a MIDI playback
  1455.      before actual end of data. If no SB Pro is available, setting all MIDI
  1456.      relative volumes to -128 should reduce any spurious noise.
  1457.  
  1458.  
  1459.  
  1460.  
  1461.  
  1462.  
  1463.  
  1464.  
  1465.  
  1466.  
  1467.  
  1468.  
  1469.  
  1470.                                                                               22
  1471.  
  1472.  
  1473.  
  1474.  
  1475.  
  1476.  
  1477.  
  1478.  
  1479.  
  1480.  
  1481.  
  1482.      Appendix B. RUCKUS-MIDI Pack Structure.
  1483.  
  1484.  
  1485.      DECLARE FUNCTION RUCKMIDI% (SEG packinfo AS ANY)
  1486.  
  1487.      CONST SysInfoMidi = 0, InitMidi = 1, ExitMidi = 2, AtExitMidi = 3
  1488.      CONST LoadMidi = 4, PlayMidi = 5
  1489.      CONST EndMidi = 8, PauseMidi = 9
  1490.      CONST DeallocMidi = 10, FastFwdMidi = 11, OutMsgMidi = 12
  1491.  
  1492.      CONST SetAllMidi = 20, SetVolumeMidi = 21, SetToneMidi = 22
  1493.      CONST SetPatchMidi = 23, SetChMaskMidi = 24
  1494.  
  1495.      CONST SetAllFMSBP = 30
  1496.  
  1497.      TYPE DeallocMidiPackTYPE 'DMP
  1498.       Func       AS INTEGER
  1499.       stat       AS INTEGER
  1500.       HandSeg    AS INTEGER 'RUCKUS allocates DOS segment (para)
  1501.       TypeFlag   AS INTEGER '0=DOS para (must=0)
  1502.      END TYPE '8
  1503.  
  1504.      TYPE FastFwdMidiPackTYPE 'FFMP
  1505.       Func       AS INTEGER
  1506.       stat       AS INTEGER
  1507.       TickCount  AS LONG    'tick count to fast forward to
  1508.      end type '8
  1509.  
  1510.      TYPE GetMidiDataPackTYPE 'GDP
  1511.       Func       AS INTEGER
  1512.       stat       AS INTEGER
  1513.       BytePos    AS LONG    'current byte relative base ptr (27)
  1514.      END TYPE '8
  1515.  
  1516.      TYPE mInitMidiPackTYPE  'MIMP (can't use IMP with BASIC)
  1517.       Func       AS INTEGER
  1518.       stat       AS INTEGER
  1519.       DeviceID   AS INTEGER '0=AdLib melodic, 1=AdLib percussive
  1520.       IOport     AS INTEGER
  1521.       PercCh     AS INTEGER
  1522.       ChMask     AS INTEGER
  1523.       Flags      AS INTEGER '(see below)
  1524.       InfoPtrOff AS INTEGER 'ret:far ptr to Midi info
  1525.       InfoPtrSeg AS INTEGER
  1526.       MidiExitPtrOff AS INTEGER 'ret:far ptr to Midi's ExitXB routine
  1527.       MidiExitPtrSeg AS INTEGER
  1528.      END TYPE '22
  1529.  
  1530.  
  1531.  
  1532.  
  1533.  
  1534.  
  1535.  
  1536.  
  1537.                                                                               23
  1538.  
  1539.  
  1540.  
  1541.  
  1542.  
  1543.  
  1544.  
  1545.  
  1546.  
  1547.  
  1548.  
  1549.  
  1550.      TYPE LoadMidiPackTYPE   'LMP
  1551.       Func       AS INTEGER
  1552.       stat       AS INTEGER
  1553.       FilenamePtrOff AS INTEGER 'far ptr to filenameZ to load
  1554.       FilenamePtrSeg AS INTEGER
  1555.       StartPos   AS LONG     'offset into file to start load at
  1556.       LoadSize   AS LONG     'number of bytes to load (or 0 for autosize)
  1557.       LoadPtrOff AS INTEGER  'ret:DOS seg:offset (offset always 0)
  1558.       LoadPtrSeg AS INTEGER
  1559.      END TYPE '20
  1560.  
  1561.      TYPE OutMsgMidiPackTYPE 'OMMP
  1562.       Func       AS INTEGER
  1563.       stat       AS INTEGER
  1564.       Mstatus    AS INTEGER  'status byte (8n, 9n...)
  1565.       Mdata      AS INTEGER  'data (one or two bytes)
  1566.      END TYPE '8
  1567.  
  1568.      TYPE PlaybackMidiPackTYPE 'PMBP
  1569.       Func       AS INTEGER
  1570.       stat       AS INTEGER
  1571.       Mode       AS INTEGER  'playback mode (0=interrupt FG,1=BG)
  1572.       LoadPtrOff AS INTEGER  'seg:off to start of data to play
  1573.       LoadPtrSeg AS INTEGER
  1574.      END TYPE '10
  1575.  
  1576.      TYPE PauseMidiPackTYPE  'PMP
  1577.       Func       AS INTEGER
  1578.       stat       AS INTEGER
  1579.       Pause      AS INTEGER  '0=unpause else pause
  1580.      END TYPE '6
  1581.  
  1582.      TYPE SetFMProPackTYPE   'SFMPP (FM mixer control for SB PRO-compatibles)
  1583.       Func       AS INTEGER
  1584.       stat       AS INTEGER
  1585.       IOport     AS INTEGER  'base I/O port (&H220, &H240)
  1586.       MasterVol  AS INTEGER  '0F0F (low=right ch, high=left,-1 no change)
  1587.       Steer      AS INTEGER  '0=none,1=left,2=right,3=mute,-1 no change)
  1588.       FMVol      AS INTEGER  '0F0F (low=right,high=left,cannot skip)
  1589.      END TYPE '12
  1590.  
  1591.      TYPE SetMidiPackTYPE    'SMP
  1592.       Func       AS INTEGER
  1593.       stat       AS INTEGER
  1594.       Channel    AS INTEGER  'channel to set (bit mask of channels 0-15)
  1595.       Volume     AS INTEGER  'volume adjust
  1596.       Tone       AS INTEGER  'tone adjust
  1597.       ChMask     AS INTEGER  'if bit=0 then that channel is ignored
  1598.       PatchMapID AS INTEGER  'patch map ID
  1599.       PatchMapPtrOff AS INTEGER 'far ptr to alternate patch map or
  1600.       PatchMapPtrSeg AS INTEGER 'address of patch map ID selected
  1601.      END TYPE '18
  1602.  
  1603.  
  1604.                                                                               24
  1605.  
  1606.  
  1607.  
  1608.  
  1609.  
  1610.  
  1611.  
  1612.  
  1613.  
  1614.  
  1615.  
  1616.  
  1617.      TYPE SysInfoMidiPackTYPE 'SIMP
  1618.       Func       AS INTEGER  'this (or any) TYPE will be expanded as needed
  1619.       stat       AS INTEGER  'to accommodate additional MIDI devices
  1620.       Device0    AS INTEGER  '=1 AdLib melodic mode available
  1621.       D0port     AS INTEGER  '388h
  1622.       D0mask     AS INTEGER  '
  1623.       Device1    AS INTEGER  '=1 AdLib percussive mode available
  1624.       D1port     AS INTEGER  '388h
  1625.       D1mask     AS INTEGER  '(to be extended as new devices are added)
  1626.      END TYPE '16
  1627.  
  1628.      TYPE XitMidiPackTYPE    'XMP
  1629.       Func       AS INTEGER
  1630.       stat       AS INTEGER
  1631.      END TYPE '4
  1632.  
  1633.  
  1634.  
  1635.  
  1636.  
  1637.  
  1638.  
  1639.  
  1640.  
  1641.  
  1642.  
  1643.  
  1644.  
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650.  
  1651.  
  1652.  
  1653.  
  1654.  
  1655.  
  1656.  
  1657.  
  1658.  
  1659.  
  1660.  
  1661.  
  1662.  
  1663.  
  1664.  
  1665.  
  1666.  
  1667.  
  1668.  
  1669.  
  1670.  
  1671.                                                                               25
  1672.  
  1673.  
  1674.  
  1675.  
  1676.  
  1677.  
  1678.  
  1679.  
  1680.  
  1681.  
  1682.  
  1683.      Appendix C. Compiler, Linker, QLB, and Call Use.
  1684.  
  1685.      Compile and Link.
  1686.  
  1687.      To create a stand-alone EXE file, compile your BASIC source as required. No
  1688.      special compiler switches are required. When your compiler is finished and
  1689.      has reported no errors during the compile, use the LINK program supplied
  1690.      with your compiler to resolve any external references in your BASIC program
  1691.      code that are dependent on the RUCKUS library code.
  1692.  
  1693.      For example, if you have a single-module BASIC source file called
  1694.      SOUND.BAS, compile it:
  1695.  
  1696.       C>bc SOUND /o;
  1697.  
  1698.      If successful, use the LINK program to build the final EXE:
  1699.  
  1700.       C>link SOUND,SOUND.EXE,nul,RUCKDAC.LIB RUCKMIDI.LIB;
  1701.  
  1702.      If successful, link creates SOUND.EXE ready to be run at the DOS prompt.
  1703.      The BASIC runtime is also supported by RUCKUS. Just compile as you normally
  1704.      would (without the /o, of course).
  1705.  
  1706.      RUCKUS is composed of many separate assembly language modules in two
  1707.      separate LIBs, one for digital data and the other for MIDI data.
  1708.  
  1709.      If you need to use more libraries with your programs, no problem, LINK can
  1710.      handle as many as you have. When LINK prompts you for a library file, just
  1711.      enter RUCKDAC.LIB and RUCKMIDI.LIB followed by any other library you need.
  1712.      For example:
  1713.  
  1714.       C>link
  1715.  
  1716.       Microsoft (R) Segmented Executable Linker  Version 5.31.009 Jul 13 1992
  1717.       Copyright (C) Microsoft Corp 1984-1992.  All rights reserved.
  1718.  
  1719.       Object Modules [.OBJ]: SOUND+STUB
  1720.       Run File [.EXE]: SOUND.EXE
  1721.       List File [NUL.MAP]: nul
  1722.       Libraries [.LIB]: RUCKDAC RUCKMIDI MOUSE;
  1723.  
  1724.      Consult your linker programs documentation for more.
  1725.  
  1726.  
  1727.  
  1728.  
  1729.  
  1730.  
  1731.  
  1732.  
  1733.  
  1734.  
  1735.  
  1736.  
  1737.  
  1738.                                                                               26
  1739.  
  1740.  
  1741.  
  1742.  
  1743.  
  1744.  
  1745.  
  1746.  
  1747.  
  1748.  
  1749.  
  1750.      Creating a QLB.
  1751.  
  1752.      If you use the QuickBASIC environment to program in, you need to build a
  1753.      .QLB so that you can call the RUCKUS routines. While QuickBASIC can load
  1754.      only a
  1755.      single QLB ( C>qb /L quicklib.qlb ), you can combine many LIB and OBJ
  1756.      modules to create the QLB. For example, to make a QLB of the RUCKDAC.LIB,
  1757.      RUCKMIDI.LIB and MOUSE.LIB libraries:
  1758.  
  1759.       C>link /QU RUCKDAC.LIB+RUCKMIDI.LIB+MOUSE.LIB, IDE.QLB, nul, BQLB45.LIB;
  1760.  
  1761.      Note the extension .LIB on the library modules. This is REQUIRED since LINK
  1762.      assumes .OBJ by default. The quick library, BQLB45.LIB, is required for the
  1763.      Libraries: prompt. The exact name depends on the compiler version. Consult
  1764.      your compiler documentation for more.
  1765.  
  1766.      BASIC PDS note: BASIC PDS requires that all BASIC modules included into a
  1767.      QLB be compiled using the /Fs compiler switch. This instructs the compiler
  1768.      to
  1769.      generate code compatible with "far strings". Since RUCKUS is written
  1770.      entirely in assembly language, this is not an issue. However, if you start
  1771.      QBX.EXE with /L and get an INVALID FORMAT error, one of the modules in the
  1772.      .QLB file most likely was a BASIC module that was not compiled with the /Fs
  1773.      switch.
  1774.  
  1775.  
  1776.      Calling RUCKDAC() and RUCKMIDI().
  1777.  
  1778.      RUCKUS is called through a single entry point. Depending on function
  1779.      (digital or MIDI) you use either RUCKDAC() or RUCKMIDI(). The only argument
  1780.      passed to is a segmented far pointer to the control pack. The first two
  1781.      entries in this pack are the function to be performed and the function
  1782.      return status. RUCKUS is a FUNCTION call returning an INTEGER status value
  1783.      (with a few exceptions, see the documentation).
  1784.  
  1785.      Each function (or routine) uses a prescribed pack format. For example, some
  1786.      routines need only know the function to perform. For example, to end a
  1787.      digital play you could do the following:
  1788.  
  1789.       DIM XP AS XitPackTYPE          'could also DIM SHARED
  1790.  
  1791.       XP.Func = EndDac               'EndDac is defined in RUCKDAC.BI
  1792.       stat = RUCKDAC(XP)             'do the actual call to RUCKUS-DAC
  1793.  
  1794.  
  1795.  
  1796.  
  1797.  
  1798.  
  1799.  
  1800.  
  1801.  
  1802.  
  1803.  
  1804.  
  1805.                                                                               27
  1806.  
  1807.  
  1808.  
  1809.  
  1810.  
  1811.  
  1812.  
  1813.  
  1814.  
  1815.  
  1816.  
  1817.      Appendix D. RUCKUS-MIDI Data Area.
  1818.  
  1819.  
  1820.      The offset value below is relative InfoPtrOff as returned by InitMidi. For
  1821.      example, to access mid@end, the following code can be used:
  1822.  
  1823.      DEF SEG = MIMP.InfoPtrSeg
  1824.      MidiIsOver = PEEK(MIMP.InfoPtrOff + 6)
  1825.      DEF SEG
  1826.  
  1827.      For accessing word (dw) and double-word (dd) values, see Appendix A. All
  1828.      mid@ variables are PUBLIC symbols and may be accessed directly by compilers
  1829.      that allow external references to variables. QuickBASIC does not so the DEF
  1830.      SEG method needs to be used. Where possible, access all mid@ data through a
  1831.      common function so that future changes can be easily made.
  1832.  
  1833.  
  1834.      Offset  Name         Type  Comments ----------------------------------
  1835.      +000 mid@deviceID     dw   0=AdLib melodic, 1=AdLib percussive...
  1836.         2 mid@flags        dw   bit0=1 reserved
  1837.                                 bit1=1 disable program change event
  1838.                                 bit2-7 reserved (Low byte used to send...
  1839.                                 ...while high byte used to return info)
  1840.                                 bit8-13 reserved
  1841.                                 bit14=1 then CTMF file playing
  1842.                                 bit15=1 then AdLib ROL-convert playing
  1843.         4 mid@percChannel  dw   <> 0 then percussion channel mapped
  1844.         6 mid@end          dw   =1 end of MIDI (not currently playing)
  1845.         8 mid@memDOS       dw   DOS RAM available in K
  1846.        10 mid@memUsed      dw   K used by last load
  1847.  
  1848.      The following data to mid@chNotes is zeroed before each initial play
  1849.      and is not valid until play has begun.
  1850.  
  1851.        12 mid@typeMIDI     dw   MIDI type (0 or 1)
  1852.        14 mid@noTracks     dw   number of tracks (1 to 64)
  1853.        16 mid@ticksQnote   dw   ticks/quarter-note
  1854.        18 mid@uSecsQnote   dd   micro-secs/quarter-note
  1855.        22 mid@tickCount    dd   current tick count
  1856.  
  1857.        26 mid@musicPtr     dd   seg:off->current MIDI data byte
  1858.        30 mid@currTrk      dw   current MIDI track (0 to noTracks-1)
  1859.        32 mid@timeSig pt1  DB   numerator        |Consult the MIDI 1.0|
  1860.        33 mid@timeSig pt2  DB   denominator      |specification on the|
  1861.        34 mid@timeSig pt3  DB   MIDI clocks/beat |implementation of   |
  1862.        35 mid@timeSig pt4  DB   32nd notes/beat  |the time signature  |
  1863.        36 mid@chPrograms   DB16 channel programs 0-15, 16 entries
  1864.        52 mid@chVolumes    DB16 channel volume levels (0-127), 16 entries
  1865.        68 mid@chNotes      DB16 channel note values (0-127), 16 entries
  1866.  
  1867.        84 mid@chRelVolumes dw16 -128 to 127 range (0=no change), 16 entries
  1868.       116 mid@chRelNotes   dw16 -128 to 127 range (0=no change), 16 entries
  1869.  
  1870.  
  1871.  
  1872.                                                                               28
  1873.  
  1874.  
  1875.  
  1876.  
  1877.  
  1878.  
  1879.  
  1880.  
  1881.  
  1882.  
  1883.  
  1884.  
  1885.      The following are device-dependent and so are not part of the formal
  1886.      RUCKUS-MIDI data area. They are provided in case you want to change the
  1887.      operation of RUCKUS-MIDI at its lowest level. They are PUBLIC symbols and
  1888.      can be accessed only by direct reference. For the actual internal patch
  1889.      maps used by RUCKUS-MIDI, refer to Appendix F & G.
  1890.  
  1891.           ad@PatchPtr      dd   far ptr to current programs, 0-127
  1892.           ad@PercMapPtr    dd   far ptr to current percussive map
  1893.  
  1894.      The following are the timbre data of DeviceID 1 percussive voices. All but
  1895.      bass drum, voice 6, use 1 operator. BD uses 2 operators. For the actual
  1896.      mappings used by RUCKUS-MIDI, refer to Appendix F & G.
  1897.  
  1898.      The first 13 bytes are for operator 0, the next 13 for operator 1, and the
  1899.      last 2 are wave shapes for operator 0 and 1, respectively. Format is:
  1900.  
  1901.      Op0: ksl,multi,fb(Op0),ar,sl,eg,dr,rr,tl,amvib,vib,ksr,c
  1902.      Op1: ksl,multi,fb(Op0),ar,sl,eg,dr,rr,tl,amvib,vib,ksr,c (BD only)
  1903.      Op0: wsm
  1904.      Op1: wsc
  1905.  
  1906.           ad@bdOps         DB 28 DUP (?)  Bass drum timbre
  1907.           ad@sdOp0         DB 28 DUP (?)  Snare drum timbre
  1908.           ad@tomOp0        DB 28 DUP (?)  Tom-tom timbre
  1909.           ad@cymOp0        DB 28 DUP (?)  Cymbal timbre
  1910.           ad@hhOp0         DB 28 DUP (?)  Hi-hat timbre
  1911.  
  1912.  
  1913.  
  1914.  
  1915.  
  1916.  
  1917.  
  1918.  
  1919.  
  1920.  
  1921.  
  1922.  
  1923.  
  1924.  
  1925.  
  1926.  
  1927.  
  1928.  
  1929.  
  1930.  
  1931.  
  1932.  
  1933.  
  1934.  
  1935.  
  1936.  
  1937.  
  1938.  
  1939.                                                                               29
  1940.  
  1941.  
  1942.  
  1943.  
  1944.  
  1945.  
  1946.  
  1947.  
  1948.  
  1949.  
  1950.  
  1951.      Appendix E. MIDI Key Numbers, Frequencies and Channel Messages.
  1952.  
  1953.  
  1954.       Octave  1      2       3       4       5       6      7      8
  1955.       Note                    (frequency in Hertz)
  1956.        C   16.352  32.704  65.40  130.81  261.63  523.26  1046.5 2093
  1957.        C#  17.324  34.648  69.29  138.59  277.18  554.36  1108.7 2217
  1958.        D   18.354  36.708  73.41  146.83  293.66  587.32  1174.6 2349
  1959.        D#  19.445  38.890  77.78  155.56  311.12  622.24  1244.4 2489
  1960.        E   20.601  41.202  82.40  164.80  329.61  659.23  1318.4 2637
  1961.        F   21.826  43.652  87.30  174.60  349.21  698.43  1396.8 2794
  1962.        F#  23.124  46.248  92.49  184.99  369.98  739.96  1479.9 2960
  1963.        G   24.499  48.998  97.99  195.99  391.98  783.96  1567.9 3136
  1964.        G#  25.956  51.912 103.82  207.64  415.29  830.59  1661.1 3322
  1965.        A   27.500  55.000 110.00  220.00  440.00  880.00  1760.0 3520
  1966.        A#  29.135  58.270 116.54  233.08  466.16  932.32  1864.6 3729
  1967.        B   30.867  61.734 123.46  246.93  493.87  987.74  1975.4 3951
  1968.  
  1969.      Note C1 (16Hz) is MIDI key number 12, C2 (32Hz) is 24...C5 (261Hz) is 60,
  1970.      middle-C on the piano keyboard. Valid key number range is 12 to 107 (96 key
  1971.      numbers total). This is peculiar to the OPL-2 chip. MIDI key number range
  1972.      is 0 to 127. Key numbers issued > 107 are set to 107 and numbers < 12 are
  1973.      set to 12 when using the OPL-2 or -3.
  1974.  
  1975.      For accessing steps between notes, you can use the PitchBend MIDI channel
  1976.      message (OutMsgMidi status byte En, Pitch Wheel Change). Each 512-point
  1977.      adjustment to pitchbend results in a 1-step change, giving a pitchbend
  1978.      range of +/- 16 steps per half-tone (pitchbend range is 0 to 16383 with
  1979.      8192 equal to no change).
  1980.  
  1981.  
  1982.  
  1983.  
  1984.  
  1985.  
  1986.  
  1987.  
  1988.  
  1989.  
  1990.  
  1991.  
  1992.  
  1993.  
  1994.  
  1995.  
  1996.  
  1997.  
  1998.  
  1999.  
  2000.  
  2001.  
  2002.  
  2003.  
  2004.  
  2005.  
  2006.                                                                               30
  2007.  
  2008.  
  2009.  
  2010.  
  2011.  
  2012.  
  2013.  
  2014.  
  2015.  
  2016.  
  2017.  
  2018.  
  2019.      MIDI channels messages are what OutMsgMidi transmits to the MIDI parser.
  2020.      For complete specifications on MIDI channel messages, MIDI system messages,
  2021.      and the other details of the inner-workings of MIDI, contact the
  2022.      International MIDI Association (IMA) and ask for the MIDI 1.0
  2023.      Specification. Several volumes are available for sale ranging from detailed
  2024.      specs to the standard MIDI file format. The IMA's mailing address is:
  2025.  
  2026.           IMA - the International MIDI Association
  2027.           5316 W 57 ST
  2028.           LOS ANGELES CA 90056
  2029.           USA
  2030.  
  2031.      The MIDI channel messages are:
  2032.  
  2033.      Message Name           Mstat/Mdata Comment
  2034.      -----------------------------------------------------------------
  2035.      Note Off                 8n kn v   kn=key number (0-127)
  2036.                                         v =velocity (0-127) (volume)
  2037.      Note On                  9n kn v   kn=key number (0-127)
  2038.                                         v =velocity (1-127,0=note off)
  2039.      Polyphonic After-Touch   An kn v   kn=key number (0-127)
  2040.                                         v =velocity (0-127)
  2041.      Control Change           Bn cn x   cn=controller (0-121, 0-79h)
  2042.                                         x =value (0-127)
  2043.                                         (Control Change not implemented)
  2044.      Channel Mode:
  2045.         All Notes Off         Bn 7B 0   7B=channel n sound off
  2046.                                         (Other modes not implemented)
  2047.      Program Change           Cn p      p =program (0-127)
  2048.      Channel After-Touch      Dn v      v =velocity (0-127)
  2049.      Pitch Wheel Change       En lb hb  lb=low byte (0-127)*
  2050.                                         hb=high byte (0-127)
  2051.  
  2052.      *All non-status bytes must have the high-order bit of each byte unset. For
  2053.      Pitch Wheel Change (En lb hb) where there is to be no change, lb/hb is to
  2054.      be set to 00/40h (4000h=8192, center pitch). The low byte's MSB should not
  2055.      be set, meaning that, for example, 4080 to 40FF are not valid pitch bends.
  2056.      If 4080h is used RUCKUS-MIDI unsets the MSB of lb so that 4000h is used.
  2057.  
  2058.      All status bytes have the high-order bit set. The n nybble of each status
  2059.      byte (e.g., 8n) designates the channel number, 0 to F (0 to 15d). Most MIDI
  2060.      channel messages takes two data bytes, though some take only one. The order
  2061.      shown above is the order that should be used. For example, to send the
  2062.      channel message NoteOn/key# 32/max volume via OutMsgMidi for channel 3, set
  2063.      Mstatus to 93h and set Mdata to &H7F20 (low/high bytes=20/7Fh).
  2064.  
  2065.      The specification is rather complex. RUCKUS-MIDI builds upon those aspects
  2066.      of the specification that are useful in playing back MIDI data. Much of the
  2067.      MIDI specification deals with real-time performance and recording use,
  2068.      neither of which is RUCKUS-MIDI's intended purpose.
  2069.  
  2070.  
  2071.  
  2072.  
  2073.                                                                               31
  2074.  
  2075.  
  2076.  
  2077.  
  2078.  
  2079.  
  2080.  
  2081.  
  2082.  
  2083.  
  2084.  
  2085.      Appendix F. General MIDI Sound Set - Level 1.
  2086.  
  2087.      Sound Set Program Number and Name.
  2088.  
  2089.      Prog#  Instrument        Prog#  Instrument       Prog#  Instrument
  2090.      ---------------------------------------------------------------------
  2091.       0 ACOUSTIC GRAND PIANO   43 CONTRABASS           86 LEAD 7 fifths
  2092.       1 BRITE ACOUSTIC PIANO   44 TREMELO STRINGS      87 LEAD 8 bass+lead
  2093.       2 ELECTRIC GRAND PIANO   45 PIZZICATO STRINGS    88 PAD 1 new age
  2094.       3 HONKEYTONK             46 ORCHESTRAL HARP      89 PAD 2 warm
  2095.       4 ELECTRIC PIANO 1       47 TIMPANI              90 PAD 3 polysynth
  2096.       5 ELECTRIC PIANO 2       48 STRING ENSEMBLE 1    91 PAD 4 choir
  2097.       6 HARPSICHORD            49 STRING ENSEMBLE 2    92 PAD 5 bowed
  2098.       7 CLAVI                  50 SYNTHSTRINGS 1       93 PAD 6 metallic
  2099.       8 CELESTA                51 SYNTHSTRINGS 2       94 PAD 7 halo
  2100.       9 GLOCKENSPIEL           52 CHOIR AAHS           95 PAD 8 sweep
  2101.      10 MUSICBOX               53 VOICE OOHS           96 FX1 rain
  2102.      11 VIBRAPHONE             54 SYNTH VOICE          97 FX2 soundtrack
  2103.      12 MARIMBA                55 ORCHESTRA HIT        98 FX3 crystal
  2104.      13 XYLOPHONE              56 TRUMPET              99 FX4 atmosphere
  2105.      14 TUBULAR BELLS          57 TROMBONE            100 FX5 brightness
  2106.      15 DULCIMER               58 TUBA                101 FX6 goblins
  2107.      16 DRAWBAR ORGAN          59 MUTED TRUMPET       102 FX7 echoes
  2108.      17 PERCUSSIVE ORGAN       60 FRENCH HORN         103 FX8 sci-fi
  2109.      18 ROCK ORGAN             61 BRASS SECTION       104 SITAR
  2110.      19 CHURCH ORGAN           62 SYNTHBRASS 1        105 BANJO
  2111.      20 REED ORGAN             63 SYNTHBRASS 2        106 SHAMISEN
  2112.      21 ACCORDION              64 SOPRANO SAX         107 KOTO
  2113.      22 HARMONICA              65 ALTO SAX            108 KALIMBA
  2114.      23 TANGO ACCORDIAN        66 TENOR SAX           109 BAG PIPE
  2115.      24 ACOUSTIC GUITAR nyln   67 BARITONE SAX        110 FIDDLE
  2116.      25 ACOUSTIC GUITAR stl    68 OBOE                111 SHANAI
  2117.      26 ELECTRIC GUITAR jazz   69 ENGLISH HORN        112 TINKLE BELL
  2118.      27 ELECTRIC GUITAR cln    70 BASSOON             113 AGOGO
  2119.      28 ELECTRIC GUITAR mute   71 CLARINET            114 STEEL DRUMS
  2120.      29 OVERDRIVEN GUITAR      72 PICCOLO             115 WOOD BLOCK
  2121.      30 DISTORTION GUITAR      73 FLUTE               116 TAIKO DRUM
  2122.      31 GUITAR HARMONICS       74 RECORDER            117 MELODIC TOM
  2123.      32 ACOUSTIC BASS          75 PAN FLUTE           118 SYNTH DRUM
  2124.      33 ELECTRIC BASS finger   76 BLOWN BOTTLE        119 REVERSE CYMBAL
  2125.      34 ELECTRIC BASS pick     77 SHAKUHACHI          120 GUITAR FRET NOISE
  2126.      35 FRETLESS BASS          78 WHISTLE             121 BREATH NOISE
  2127.      36 SLAP BASS 1            79 OCARINA             122 LOSTINSPACE
  2128.      37 SLAP BASS 2            80 LEAD 1 square       123 BIRD TWEET
  2129.      38 SYNTH BASS 1           81 LEAD 2 sawtooth     124 TELEPHONE RING
  2130.      39 SYNTH BASS 2           82 LEAD 3 calliope     125 HELICOPTER
  2131.      40 VIOLIN                 83 LEAD 4 chiff        126 APPLAUSE
  2132.      41 VIOLA                  84 LEAD 5 charang      127 GUNSHOT
  2133.      42 CELLO                  85 LEAD 6 voice
  2134.  
  2135.  
  2136.  
  2137.  
  2138.  
  2139.  
  2140.                                                                               32
  2141.  
  2142.  
  2143.  
  2144.  
  2145.  
  2146.  
  2147.  
  2148.  
  2149.  
  2150.  
  2151.  
  2152.  
  2153.      General MIDI - Level 1 Sound Set Groupings by Program Number.
  2154.  
  2155.      Prog#   Instrument Group     Prog#  Ins Grp      Prog#  Ins Grp
  2156.      ---------------------------------------------------------------------
  2157.       0-7  Piano                  40-47 Strings       80-87  Synth Lead
  2158.       8-15 Chromatic Percussion   48-55 Ensemble      88-95  Synth Pad
  2159.      16-23 Organ                  56-63 Brass         96-103 Synth Effects
  2160.      24-31 Guitar                 64-71 Reed         104-111 Ethnic
  2161.      32-39 Bass                   72-79 Pipe         112-119 Percussive
  2162.                                                      120-127 Sound Effects
  2163.  
  2164.  
  2165.      General MIDI - Level 1 Percussion Map (Channel 9).
  2166.  
  2167.      Key#  Drum Sound       Key#  Drum Sound        Key#  Drum Sound
  2168.      --------------------------------------------------------------------
  2169.       35 Acoustic Bass Drum  51 Ride Cymbal 1        67 High Agogo
  2170.       36 Bass Drum 1         52 Chinese Cymbal       68 Low Agogo
  2171.       37 Side Stick          53 Ride Bell            69 Cabasa
  2172.       38 Acoustic Snare      54 Tambourine           70 Maracas
  2173.       39 Hand Clap           55 Splash Cymbal        71 Short Whistle
  2174.       40 Electric Snare      56 Cowbell              72 Long Whistle
  2175.       41 Low Floor Tom       57 Crash Cymbal 2       73 Short Guiro
  2176.       42 Closed Hi-Hat       58 Vibraslap            74 Long Guiro
  2177.       43 High Floor Tom      59 Ride Cymbal 2        75 Claves
  2178.       44 Pedal Hi-Hat        60 Hi Bongo             76 Hi Wood Block
  2179.       45 Low Tom             61 Low Bongo            77 Low Wood Block
  2180.       46 Open Hi-Hat         62 Mute Hi Conga        78 Mute Cuica
  2181.       47 Low-Mid Tom         63 Open Hi Conga        79 Open Cuica
  2182.       48 Hi-Mid Tom          64 Low Conga            80 Mute Triangle
  2183.       49 Crash Cymbal 1      65 High Timbal          81 Open Triangle
  2184.       50 High Tom            66 Low Timbal
  2185.  
  2186.  
  2187.      For timbre data used by RUCKUS-MIDI for programs 0-127 see the GMPATCH.*
  2188.      file. Also see that file for percussive voice mappings (for example, how
  2189.      percussive channel 9 key# 46, Open Hi-Hat, maps to AdLib percussive
  2190.      voice 10, the Hi-Hat). These files are device-dependent and there is one
  2191.      for each RUCKUS-MIDI supported device. Included only in registered versions
  2192.      of the RUCKUS toolkit.
  2193.  
  2194.  
  2195.  
  2196.  
  2197.  
  2198.  
  2199.  
  2200.  
  2201.  
  2202.  
  2203.  
  2204.  
  2205.  
  2206.  
  2207.                                                                               33
  2208.  
  2209.  
  2210.  
  2211.  
  2212.  
  2213.  
  2214.  
  2215.  
  2216.  
  2217.  
  2218.  
  2219.      Appendix G. MT-32 MIDI Sound Set.
  2220.  
  2221.  
  2222.      Sound Set Program Number and Name.
  2223.  
  2224.      Prog#  Instrument        Prog#  Instrument       Prog#  Instrument
  2225.      ------------------------------------------------------------------
  2226.        0 AcouPno1              43 EchoPan              86 Bassoon
  2227.        1 AcouPno2              44 DocSolo              87 Harmonca
  2228.        2 AcouPno3              45 SchlDaze             88 Trumpet1
  2229.        3 ElecPno1              46 BellSing             89 Trumpet2
  2230.        4 ElecPno2              47 SqWave               90 Trombon1
  2231.        5 ElecPno3              48 StrSect1             91 Trombon2
  2232.        6 ElecPno4              49 StrSect2             92 FrHorn1
  2233.        7 HonkTonk              50 StrSect3             93 FrHorn2
  2234.        8 ElecOrg1              51 Pizzicto             94 Tuba
  2235.        9 ElecOrg2              52 Violin1              95 BrsSect1
  2236.       10 ElecOrg3              53 Violin2              96 BrsSect2
  2237.       11 ElecOrg4              54 Cello1               97 Vibes1
  2238.       12 PipeOrg1              55 Cello2               98 Vibes2
  2239.       13 PipeOrg2              56 ContraBs             99 SynMallt
  2240.       14 PipeOrg3              57 Harp1               100 WindBell
  2241.       15 Accordn               58 Harp2               101 Glock
  2242.       16 Harpsi1               59 Guitar1             102 TubeBell
  2243.       17 Harpsi2               60 Guitar2             103 XyloPhon
  2244.       18 Harpsi3               61 ElecGtr1            104 Marimba
  2245.       19 Clavi1                62 ElecGtr2            105 Koto
  2246.       20 Clavi2                63 Sitar               106 Sho
  2247.       21 Clavi3                64 AcouBs1             107 Shakuhch
  2248.       22 Celesta1              65 AcouBs2             108 Whistle1
  2249.       23 Celesta2              66 ElecBs1             109 Whistle2
  2250.       24 SynBrss1              67 ElecBs2             110 BottlBlo
  2251.       25 SynBrss2              68 SlapBs1             111 BreathPp
  2252.       26 SynBrss3              69 SlapBs2             112 Timpani
  2253.       27 SynBrss4              70 Fretls1             113 MelodTom
  2254.       28 SynBass1              71 Fretls2             114 DeepSnar
  2255.       29 SynBass2              72 Flute1              115 Oberheim
  2256.       30 SynBass3              73 Flute2              116 Noise
  2257.       31 SynBass4              74 Piccolo1            117 Taiko
  2258.       32 Fantasy               75 Piccolo2            118 TaikoRim
  2259.       33 HarmoPan              76 Recorder            119 RevCymb
  2260.       34 Chorale               77 PanPipes            120 JawHarp
  2261.       35 Glasses               78 Sax1                121 Triangle
  2262.       36 SoundTrk              79 Sax2                122 OrcheHit
  2263.       37 Atmosphr              80 Sax3                123 BassDrm
  2264.       38 WarmBell              81 Sax4                124 BirdTwt
  2265.       39 FunnyVox              82 Clarint1            125 Banjo
  2266.       40 EchoBell              83 Clarint2            126 MoogSyn
  2267.       41 IceRain               84 Oboe                127 JunglTun
  2268.       42 Oboe2001              85 EngHorn
  2269.  
  2270.  
  2271.  
  2272.  
  2273.  
  2274.                                                                               34
  2275.  
  2276.  
  2277.  
  2278.  
  2279.  
  2280.  
  2281.  
  2282.  
  2283.  
  2284.  
  2285.  
  2286.  
  2287.      MT-32 Sound Set Groupings by Program Number.
  2288.  
  2289.      Prog#   Instrument Group     Prog#  Ins Grp      Prog#  Ins Grp
  2290.      ----------------------------------------------------------------------
  2291.      Not specified.
  2292.  
  2293.  
  2294.      MT-32 Percussion Map (Channel 9).
  2295.  
  2296.      Key#  Drum Sound       Key#  Drum Sound        Key#  Drum Sound
  2297.      ----------------------------------------------------------------------
  2298.       35 Acoustic Bass       51 Ride Cymbal 1        67 High Agogo
  2299.       36 Acoustic Bass       52*Chinese Cymbal       68 Low Agogo
  2300.       37 Rim Shot            53*Ride Bell            69 Cabasa
  2301.       38 Acoustic Snare      54 Tambourine           70 Maracas
  2302.       39 Hand Clap           55*Splash Cymbal        71 Short Whistle
  2303.       40 Electric Snare      56 Cowbell              72 Long Whistle
  2304.       41 Acoustic Low Tom    57*Crash Cymbal 2       73 Short Guiro
  2305.       42 Closed High Hat     58*Vibraslap            74*Long Guiro
  2306.       43 Acoustic Low Tom    59*Ride Cymbal 2        75 Claves
  2307.       44 Open High Hat 2     60 Hi Bongo             76*Hi Wood Block
  2308.       45 Acoustic Mid Tom    61 Low Bongo            77*Low Wood Block
  2309.       46 Open High Hat 1     62 Mute Hi Conga        78*Mute Cuica
  2310.       47 Acoustic Mid Tom    63 Open Hi Conga        79*Open Cuica
  2311.       48 Acoustic High Tom   64 Low Conga            80*Mute Triangle
  2312.       49 Crash Cymbal        65 High Timbal          81*Open Triangle
  2313.       50 Acoustic High Tom   66 Low Timbal
  2314.  
  2315.  
  2316.      For timbre data used by RUCKUS-MIDI for programs 0-127 see the MTPATCH.*
  2317.      file. Also see that file for percussive voice mappings (for example, how
  2318.      percussive channel 9 key# 46, Open Hi-Hat, maps to AdLib percussive
  2319.      voice 10, the Hi-Hat). These files are device-dependent and there is one
  2320.      for each RUCKUS-MIDI supported device. Included only in registered versions
  2321.      of the RUCKUS toolkit.
  2322.  
  2323.  
  2324.  
  2325.  
  2326.  
  2327.  
  2328.  
  2329.  
  2330.  
  2331.  
  2332.  
  2333.  
  2334.  
  2335.  
  2336.  
  2337.  
  2338.  
  2339.  
  2340.  
  2341.                                                                               35
  2342.  
  2343.  
  2344.  
  2345.  
  2346.  
  2347.  
  2348.  
  2349.  
  2350.  
  2351.  
  2352.  
  2353.      Appendix H. RUCKUS-MIDI Patch Map Format.
  2354.  
  2355.  
  2356.      Format of the patch maps used internally by RUCKUS-MIDI for the 2-operator
  2357.      OPL chip is composed of 2 sections. The header and the timbre data. The
  2358.      header is the first 48 bytes of the data.
  2359.  
  2360.      HEADER:
  2361.        Patch name: 20 bytes
  2362.        Patch size: 1 word, set to 48
  2363.          reserved: 14 bytes
  2364.      TIMBRE DATA for each program (0-127):
  2365.        Instrument name: 20 bytes (may be 0- or space-filled)
  2366.        Instrument data: 28 bytes
  2367.  
  2368.        Instrument data format is:
  2369.  
  2370.      Op0:ksl,multi,fb,ar,sl,eg,dr,rr,tl,amvib,vib,ksr,c
  2371.      Op1:ksl,multi,--,ar,sl,eg,dr,rr,tl,amvib,vib,ksr,-
  2372.          mws,cws (modulator wave shape, carrier wave shape)
  2373.  
  2374.      For example:
  2375.  
  2376.      PATCHES_MT  db 'PATCHES_MT32',0,0,0,0
  2377.      dw 48
  2378.      db 14 DUP(0)
  2379.  
  2380.      db 'ACOUPIANO1',0,0,0,0,0,0,0,0,0,0                   ;(0)
  2381.      db 01h,01h,03h,0Fh,05h,00h,01h,00h,0Fh,00h,00h,00h,01h
  2382.      db 00h,00h,01h,00h,0Dh,07h,00h,03h,0Ch,04h,00h,00h,00h
  2383.      db 00h,00h
  2384.      ;the other patches would follow, to the 127th
  2385.      ;total patch size would be 48+(128*48)=6192 bytes
  2386.  
  2387.  
  2388.  
  2389.  
  2390.  
  2391.  
  2392.  
  2393.  
  2394.  
  2395.  
  2396.  
  2397.  
  2398.  
  2399.  
  2400.  
  2401.  
  2402.  
  2403.  
  2404.  
  2405.  
  2406.  
  2407.  
  2408.                                                                               36
  2409.  
  2410.  
  2411.  
  2412.  
  2413.  
  2414.  
  2415.  
  2416.  
  2417.  
  2418.  
  2419.  
  2420.  
  2421.      Internally, RUCKUS-MIDI maintains separate locations for the programs and
  2422.      the percussive map. However, for custom patch maps, the following format
  2423.      must be used:
  2424.  
  2425.      Custom Patch Format:
  2426.  
  2427.      First 48-byte section is the percussive map for key numbers 35 to 82. Key
  2428.      number 82 should map to value 255. For example:
  2429.  
  2430.  
  2431.        ;0  1  2  3  4  5  6  7  8  9 (values in decimal, 48 bytes)
  2432.      db                06,06,08,07,08 ;35-39
  2433.      db 07,08,10,08,10,08,10,08,08,09 ;40-49
  2434.      db 08,09,09,09,10,09,09,09,08,09 ;50-59
  2435.      db 08,08,08,08,08,07,07,07,07,08 ;60-69
  2436.      db 10,10,10,10,10,08,08,08,08,08 ;70-79
  2437.      db 10,10,255                     ;80-81
  2438.  
  2439.      ;In the above map, key# 35 maps to OPL-2 voice 6, the bass drum. Key# 79
  2440.      ;maps to voice 8, the tom-tom.
  2441.  
  2442.      ;This is immediately followed by the program patches as above:
  2443.  
  2444.      PATCHES_MT  db 'PATCHES_MT32',0,0,0,0
  2445.      dw 48
  2446.      db 14 DUP(0)
  2447.  
  2448.      db 'ACOUPIANO1',0,0,0,0,0,0,0,0,0,0                   ;(0)
  2449.      db 01h,01h,03h,0Fh,05h,00h,01h,00h,0Fh,00h,00h,00h,01h
  2450.      db 00h,00h,01h,00h,0Dh,07h,00h,03h,0Ch,04h,00h,00h,00h
  2451.      db 00h,00h
  2452.      ;the other patches would follow, to the 127th
  2453.      ;total patch size would be 48+48+(128*48)=6240 bytes
  2454.  
  2455.      To create custom patch maps for the OPL-2 chip, the shareware package
  2456.      SBKTimbre can be used. To convert the output of this program for use with
  2457.      RUCKUS-MIDI, use the supplied IBK2OPL2.EXE program. The 48-byte percussive
  2458.      map must be constructed by hand. 
  2459.  
  2460.      Note that other devices (when supported) will have different formats. 
  2461.  
  2462.  
  2463.  
  2464.  
  2465.  
  2466.  
  2467.  
  2468.  
  2469.  
  2470.  
  2471.  
  2472.  
  2473.  
  2474.  
  2475.                                                                               37
  2476.  
  2477.  
  2478.  
  2479.  
  2480.  
  2481.  
  2482.  
  2483.  
  2484.  
  2485.  
  2486.  
  2487.      Appendix Z. Ordering Information, License Agreement and Product Support.
  2488.  
  2489.      To order you must you the order form included with the distribution files.
  2490.      Its filename is !ORDER.FRM. Orders made without this form may be delayed.
  2491.  
  2492.      There are two RUCKUS packages available. The PERSONAL DEVELOPER version is
  2493.      for the hobby-programmer while the PROFESSIONAL version is for the
  2494.      professional programmer.
  2495.  
  2496.      The PERSONAL DEVELOPER version is for persons that are not creating
  2497.      programs for distribution to others. With the PERSONAL DEVELOPER license
  2498.      you may not distribute any programs you create with RUCKUS. In addition, a
  2499.      sign-on banner is issued once, displaying the RUCKUS copyright and license
  2500.      restriction.
  2501.  
  2502.      The PROFESSIONAL version has no distribution restrictions on end-user
  2503.      programs you create with RUCKUS. The PROFESSIONAL license provides you with
  2504.      the right to create all the end-user programs royalty-free. You also have
  2505.      direct access to the latest version of RUCKUS free-of-charge by way of my
  2506.      support BBS and the RUCKUS Developer's Conference there. No sign-on banner
  2507.      is issued.
  2508.  
  2509.  
  2510.  
  2511.  
  2512.  
  2513.  
  2514.  
  2515.  
  2516.  
  2517.  
  2518.  
  2519.  
  2520.  
  2521.  
  2522.  
  2523.  
  2524.  
  2525.  
  2526.  
  2527.  
  2528.  
  2529.  
  2530.  
  2531.  
  2532.  
  2533.  
  2534.  
  2535.  
  2536.  
  2537.  
  2538.  
  2539.  
  2540.  
  2541.  
  2542.                                                                               38
  2543.  
  2544.  
  2545.  
  2546.  
  2547.  
  2548.  
  2549.  
  2550.  
  2551.  
  2552.  
  2553.  
  2554.      License Agreement
  2555.  
  2556.      Before using this software you must agree to the following:
  2557.  
  2558.      1. You are not allowed to operate more than one (1) copy of this software
  2559.      package at one time per license. This means that if you have 10 programmers 
  2560.      that COULD possibly use the RUCKUS library at the same time, you must also  
  2561.      have ten (10) RUCKUS licenses. 
  2562.  
  2563.      2. You are not allowed to distribute non-executable code containing RUCKUS 
  2564.      code. This means that you are not allowed to redistribute RUCKUS code as    
  2565.      another .LIB, for example. Also, if RUCKUS code is to be contained in a    
  2566.      Dynamic Link Library (DLL) then it must be part of a stand-alone product. 
  2567.      This means that you cannot provide a .DLL containing RUCKUS code if that    
  2568.      .DLL is to be used as a programming library for other programmers. If you   
  2569.      wish to distribute non-executable code containing RUCKUS code you must    
  2570.      obtain written permission from the author.
  2571.  
  2572.      3. This license grants you the right to use the RUCKUS library code on a   
  2573.      royalty-free basis, except when the license is the PERSONAL DEVELOPER, in
  2574.      which case you may not distribute any program in which RUCKUS has been
  2575.      used.
  2576.  
  2577.      4. RUCKUS is owned by the author, Cornel Huth, and is protected by United  
  2578.      States copyright laws and international treaty provisions. You are not    
  2579.      allowed to make copies of this software except for archival purposes.
  2580.  
  2581.      5. You may not rent or lease RUCKUS. You may not transfer this license
  2582.      without the written permission of the author. If this software is an update
  2583.      or upgrade, you may not sell or give away previous versions.
  2584.  
  2585.      6. You may not reverse engineer, decompile, or disassemble this software.
  2586.  
  2587.      7. There are no expressed or implied warranties with this software.
  2588.  
  2589.      8. All liabilities in the use of this software rest with the user.
  2590.  
  2591.      9. U.S. Government Restricted Rights. This software is provided with    
  2592.      restricted rights. Use, duplication, or disclosure by the Government is    
  2593.      subject to restrictions as set forth in subparagraph (c)(1)(ii) of the    
  2594.      Rights in Technical Data and Computer Software clause at 52.227-7013.    
  2595.      Manufacturer is Cornel Huth/6402 Ingram Rd/San Antonio, TX 78238.
  2596.  
  2597.      This agreement is governed by the laws of the state of Texas.
  2598.  
  2599.  
  2600.  
  2601.  
  2602.  
  2603.  
  2604.  
  2605.  
  2606.  
  2607.  
  2608.  
  2609.                                                                               39
  2610.  
  2611.  
  2612.  
  2613.  
  2614.  
  2615.  
  2616.  
  2617.  
  2618.  
  2619.  
  2620.  
  2621.      Product Support
  2622.  
  2623.      Support is available 7 days/week from 17:00 to 09:00 Central Time at my
  2624.      BBS, the Fortieth Floor, at 1.210.684.8065.
  2625.  
  2626.      PROFESSIONAL version licensees have free access to all future RUCKUS
  2627.      updates and upgrades via the RUCKUS Developer's Conference on the Fortieth
  2628.      Floor BBS (1.210.684.8065). PERSONAL DEVELOPER licensees have restricted
  2629.      access to in-version maintenance updates at no charge.
  2630.  
  2631.      End of the RUCKUS-MIDI DOCUMENT. See also the RUCKUS-DAC DOCUMENT.
  2632.  
  2633.  
  2634.  
  2635.  
  2636.  
  2637.  
  2638.  
  2639.  
  2640.  
  2641.  
  2642.  
  2643.  
  2644.  
  2645.  
  2646.  
  2647.  
  2648.  
  2649.  
  2650.  
  2651.  
  2652.  
  2653.  
  2654.  
  2655.  
  2656.  
  2657.  
  2658.  
  2659.  
  2660.  
  2661.  
  2662.  
  2663.  
  2664.  
  2665.  
  2666.  
  2667.  
  2668.  
  2669.  
  2670.  
  2671.  
  2672.  
  2673.  
  2674.  
  2675.  
  2676.                                                                               40
  2677.  
  2678.  
  2679.  
  2680.  
  2681.