home *** CD-ROM | disk | FTP | other *** search
/ Point Programming 1 / PPROG1.ISO / c / rukc10 / ruckdac.doc < prev    next >
Encoding:
Text File  |  1993-03-05  |  91.5 KB  |  3,961 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.      RUCKUS-DAC Copyright (C)1993 Cornel Huth
  9.      Documentation Copyright (C)1993 Cornel Huth
  10.      All Rights Reserved.
  11.  
  12.      Version 1.00.
  13.      06-Mar-93/C.
  14.  
  15.      For ordering information, license agreement, and product support
  16.      information, see Appendix Z.
  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-DAC is one part of the RUCKUS sound toolkit for DOS programmers. Its
  78.      forte is its ability to play digital data in three different formats and
  79.      record in two: VOC, WAVE, and MOD. The other part of the RUCKUS sound
  80.      toolkit is RUCKUS-MIDI. Its forte is its ability to play standard MIDI data
  81.      files. See RUCKUS-MIDI for more.
  82.  
  83.      RUCKUS-DAC currently supports six sound devices: the PC speaker, a DAC on
  84.      an LPT port, Disney Sound Source, AdLib MSC, Sound Blaster, and the Sound
  85.      Blaster Pro (stereo). Since most sound devices emulate one of the above,
  86.      RUCKUS-DAC should handle most devices likely to be found in a PC. RUCKUS-
  87.      DAC is implemented to be device-independent. As new sound hardware (with
  88.      supporting documentation) becomes available to this programmer, it will be
  89.      added. The code you write to play any of the digital formats using RUCKUS
  90.      will play on any new device added later without any code changes to your
  91.      program. You just supply the new device ID (see InitDac for more). 
  92.  
  93.      The RUCKUS toolkit supports most DOS compilers as is. This documentation
  94.      describes using RUCKUS with C DOS compilers. Also available is a BASIC-
  95.      specific version (BASIC7/QB45/VBDOS/etc.) of this documentation. Other
  96.      implementations should be able to get the necessary details using this
  97.      documentation. Note that these toolkits will not work with the current or
  98.      past Turbo Pascal compilers. This is due to Turbo Pascal's proprietary
  99.      linkage methods.
  100.  
  101.      To provide compiler-independence, RUCKUS (and all of my latest toolkits)
  102.      implements a simple calling scheme: a single far pointer (segmented) is
  103.      passed to RUCKUS. The data structure that is pointed to varies depending on
  104.      RUCKUS function. There are 13 structure types ("packs") currently. The
  105.      first two data members of each pack are identical in all packs. These are
  106.      Func and Stat. The remaining members, if any, vary depending on
  107.      requirements. For instance, the LoadDac routine uses, in addition to Func
  108.      and Stat, six additional members: FilenamePtr, StartPos, LoadSize, XMMflag,
  109.      XMMhandle and LoadPtr. The steps needed to load a digital (LoadDac is for
  110.      VOC/WAVE files, LoadMod is for MOD files) data file to memory would be as
  111.      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.           struct LoadPack LP;
  118.  
  119.           2. Assign member values:
  120.       
  121.           gets(filename);
  122.           LP.Func = LoadDac;
  123.           LP.FilenamePtr = filename;
  124.           LP.StartPos = 0L;                    
  125.           LP.LoadSize = 0L;
  126.           LP.XMMflag = 0;  
  127.  
  128.           3. Call RUCKUS:
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.           rez = RUCKDAC(&LP);
  144.  
  145.           4. On return from the call:
  146.  
  147.           if (rez == 0)
  148.              // LP.LoadPtr -> address of digital data in memory
  149.              // or, if XMMflag then LP.XMMhandle is XMS handle of storage 
  150.  
  151.      After the load you can immediately call the PlayDac routine using the
  152.      LP.LoadPtr returned from the LoadDac call. You don't need to use the RUCKUS
  153.      LoadDac routine; you can perform your own digital data file loads to memory
  154.      (VOC and WAV only, MODs must be loaded by RUCKUS-DAC). However, RUCKUS can
  155.      load up to 32 separate digital files at one time (and 96 more to XMS) and
  156.      performs all the necessary memory allocations and deallocations
  157.      automatically. See LoadDac/LoadMod for more.
  158.  
  159.      As you can see, using RUCKUS is easy. If you'd rather use a traditional 
  160.      calling convention, wrap the RUCKUS routines in a C function and call it as
  161.      you normally would, e.g., rez = LoadDacFile(filename,LP) where LoadDacFile
  162.      contains the actual code (as shown above).
  163.  
  164.      Now that I have your interest, let me tell you why I've provided this
  165.      toolkit for you. Shareware. That's right. Shareware. What I've done is
  166.      provide you with a means to evaluate this product completely, with no
  167.      upfront obligations. If you can't make use of this product, no problem.
  168.      Think of this as the ultimate return policy. You can actually take the
  169.      goods home, try it out, break it in. Then, if after a period of no more
  170.      than 21 days, you feel that this product is well worth the price I'm
  171.      asking, by all means, you should go ahead and fill out the order form and
  172.      send it in. If you do not register, then of course, it means the product is
  173.      not something you can use. If you can't use it, I don't want your money.
  174.      But if it's something you will use, it's only fair that you register. The
  175.      PROFESSIONAL registered versions does not have any built-in advertising
  176.      screens. The PERSONAL DEVELOPER registered version does display a sign-on
  177.      banner once. See Appendix Z. for ordering options and other related
  178.      information specific to this product.
  179.  
  180.      The documentation that follows describes each of the function routines as
  181.      to use, pack type used, and sample code in C. Also available is a BASIC
  182.      version of this toolkit, differing only in example programs and
  183.      documentation. For additional source examples see the included X files on
  184.      disk.
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209.      RUCKUS-DAC Functions.
  210.  
  211.       0. SysInfoDac  ...........................................  5
  212.       1. InitDac  ..............................................  6
  213.       2. ExitDac  ..............................................  7
  214.       3. AtExitDac  ............................................  8
  215.       4. LoadDac  ..............................................  9
  216.       5. PlayDac  .............................................. 10
  217.       6. RecordDac  ............................................ 11
  218.       7. StoreDac  ............................................. 13
  219.       8. EndDac  ............................................... 14
  220.       9. PauseDac  ............................................. 15
  221.      10. DeallocDac  ........................................... 16
  222.          11 to 19 are not used 
  223.      20. SetAllDac  ............................................ 17 
  224.      21. SetVolumeDac  ......................................... 19
  225.      22. SetIntRateDac  ........................................ 20
  226.      23. SetPriorityDac  ....................................... 21
  227.          24 to 27 are not used
  228.      28. GetBufferDataDac  ..................................... 22
  229.      29. GetBytePosDac  ........................................ 23
  230.      30. SetAllSBP  ............................................ 24
  231.      31. SetVolMainSBP ......................................... 26
  232.      32. SetVolVocSBP  ......................................... 27
  233.      33. SetLevelMicSBP  ....................................... 28
  234.      34. SetLevelCDSBP   ....................................... 29
  235.      35. SetLevelLineSBP  ...................................... 30
  236.      36. SetFilterOutSBP  ...................................... 31
  237.      37. SetFilterInSBP  ....................................... 32
  238.      38. SetSourceSBP  ......................................... 33
  239.      39. SetStereoSBP  ......................................... 34
  240.      40. SetSpeakerSB  ......................................... 35
  241.          41 to 47 are not used
  242.      48. GetMixerRegSBP  ....................................... 36
  243.      49. GetDacSB .............................................. 37
  244.      50. ExitMod  .............................................. 38
  245.      51. AtExitMod  ............................................ 39
  246.      52. LoadMod  .............................................. 40
  247.      53. PlayMod  .............................................. 41
  248.      54. EndMod  ............................................... 42
  249.      55. PauseMod  ............................................. 43
  250.      56. SetIntRateMod ......................................... 44
  251.      57. SetSpeedMod ........................................... 45
  252.      58. SetVolumeMod  ......................................... 46
  253.      59. SetPositionMod ........................................ 47
  254.      60. SetStereoMod .......................................... 48
  255.      61. SetFastMod ............................................ 49
  256.          Appendix A. Tips and Tricks ........................... 50
  257.          Appendix B. Pack Structure ............................ 51
  258.          Appendix C. Compiler, Linker and Call Use ............. 55
  259.          Appendix D. RUCKUS-DAC Data Area ...................... 56
  260.          Appendix Z. Ordering Information, License Agreement
  261.                      and Product Support........................ 58
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.      SysInfoDac          Func: 0        Pack: SysInfoPack
  277.  
  278.      Before doing any other RUCKUS function, you should call SysInfoDac to
  279.      determine what sound devices are available. RUCKUS-DAC currently supports
  280.      the following devices:
  281.  
  282.           0. PC speaker
  283.           1. LPT-DAC device on a printer port, commonly home-built
  284.           2. Disney Sound Source, a printer port DAC device
  285.           3. AdLib Music Synthesizer Card
  286.           4. Sound Blaster (DSP version 1.03 and up)
  287.           5. Sound Blaster Pro
  288.           6. UltraSound*
  289.  
  290.      *The UltraSound (GUS) will be supported in an upcoming release. PAS16
  291.      native support soon after.
  292.  
  293.      Since many current sound cards are Sound Blaster compatible, RUCKUS-DAC
  294.      supports somewhere around 95% of all sound devices in active use on PC-
  295.      compatible computers.
  296.  
  297.      SysInfoDac scans for and detects all devices. In the case of the DAC on the
  298.      printer port (LPT-DAC), it can only detect if a printer port is available.
  299.      All other sound cards are detected by their manufacturer's documented
  300.      methods, and should be 100% reliable. Information returned includes the
  301.      device's base port address, IRQ line, DMA channel, and capabilities.
  302.  
  303.      Since the SB Pro is SB-compatible, and since the SB is AdLib-compatible,
  304.      these lower devices are also detected in these cards.
  305.  
  306.  
  307.      Sample Use:
  308.  
  309.      struct SysInfoPack SIP;
  310.  
  311.      SIP.Func = SysInfoDac;   //SysInfoDac is a CONST in RUCKDAC.BI
  312.      rez = RUCKDAC(&SIP);     //call to RUCKUS library code
  313.      if (rezt == 0) {
  314.         printf("CPU type is %u/%u\n", SIP.CPU, SIP.MHz);
  315.         if (SIP.SD[5].Device != 0)
  316.             printf("SB PRO at port %x\n", SIP.SD[5].Port);
  317.         if (SIP.SD[4].Device != 0)
  318.             printf("SB 1.5 at port %x\n", SIP.SD[4].Port);
  319.         :
  320.         printf("PC speaker always available\n");
  321.      }
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.                                                                                5
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343.      InitDac             Func: 1        Pack: InitPack
  344.  
  345.      Before you can use a sound device, you must inform RUCKUS about it. The
  346.      InitDac routine sets up default sets of data that RUCKUS uses, or that you
  347.      can later change. You cannot operate a device until you have called this
  348.      routine. You should not InitDac more than one sound device at a time. If
  349.      you want to use a different device, first ExitDac then InitDac again.
  350.  
  351.      The information that InitDac requires is available from the SysInfoDac
  352.      routine. InitDac returns with information on its data section address and
  353.      size, and the address of the ExitDac routine (in case AtExitDac doesn't
  354.      work for your esoteric compiler or run-time library).
  355.  
  356.      InitDac is used for both RUCKUS-DAC and the RUCKUS-DAC mod extension code.
  357.  
  358.      There is a special feature available for the PC speaker and the AdLib
  359.      devices: 2x upsampling. To use 2x upsampling, use the I/O port as returned
  360.      by SysInfoDac for IP.IOport. To use standard (in some cases downsampling)
  361.      play for the PC speaker and AdLib (recommended for play of samples with
  362.      rates above 8kHz) use an IP.IOport=0. For an example of 2x upsampling see
  363.      the MODAC1 documentation. Upsampling is available only for VOC and WAVE
  364.      playback.
  365.  
  366.  
  367.      Sample Use:
  368.  
  369.      struct InitPack IP;  
  370.  
  371.      IP.Func = InitDac;       // CONST in RUCKDAC.BI
  372.      IP.DeviceID = device;    // see SysInfoDac for device numbers
  373.      IP.IOport = port;        // and other info needed by InitDac
  374.      IP.IRQline = IRQ;
  375.      IP.DMAch = DMA;
  376.      rez = RUCKDAC(&IP);
  377.      if (rez == 0)
  378.         // device initialized okay
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.                                                                                6
  399.  
  400.  
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  
  409.  
  410.      ExitDac             Func: 2        Pack: XitPack
  411.  
  412.      When using RUCKUS, certain aspects of the computer are controlled by the
  413.      RUCKUS code. To have RUCKUS return full control back to the computer and
  414.      operating system, ExitDac must be called. To ensure that this happens, even
  415.      after an abnormal termination (such as an untrapped divide by zero), RUCKUS
  416.      provides a routine that ensures that ExitDac is always called before your
  417.      application ends. See AtExitDac for more.
  418.  
  419.      Once a sound device has been initialized with InitDac, you must call
  420.      ExitDac before you can switch to another device with InitDac. Calling
  421.      ExitDac releases any memory allocations made while the previous sound
  422.      device was active (allocations made by LoadDac, LoadMod, or RecordDac).
  423.      Memory allocations that your program has made on its own are not affected.
  424.  
  425.      Tip: If you call InitDac with one device, load a file, then call InitDac
  426.      again with another device, the memory allocated by the load is not
  427.      released. This allows you to play data from previous load operation(s) on
  428.      all the RUCKUS-supported devices. To force the release of a previous memory
  429.      allocation, see DeallocDac. 
  430.  
  431.  
  432.      Sample Use:
  433.  
  434.      struct XitPack XP;
  435.  
  436.      XP.Func = ExitDac;
  437.      rez = RUCKDAC(&XP);
  438.      if (rez != 0)
  439.         // error
  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.      AtExitDac           Func: 3        Pack: XitPack
  478.  
  479.      To ensure that all machine control is returned to the operating system and
  480.      that all RUCKUS-made memory allocations are released before your
  481.      application program ends, AtExitDac should be used. This routine takes
  482.      advantage of most compiler's _atexit enregistration routine. This _atexit
  483.      compiler run-time library routine allows for up to 32 different calls to be
  484.      made just prior to it (the compiler's run-time code) returning to the
  485.      operating system (program termination). Most of the time, you can make all
  486.      the necessary shutdowns that your program requires in your app's code.
  487.      However, abnormal terminations -- terminations that can cause a bypass of
  488.      your own shutdown code -- may mean that when the operating systems regains
  489.      control, certain machine operations are not in a stable state. The
  490.      AtExitDac routine ensures that ExitDac is called no matter what (in most
  491.      all cases, except where the program locks up, in which case the session
  492.      needs to be reset anyway). 
  493.  
  494.      Note: AtExitDac should be called only once in your program's execution. 
  495.  
  496.      Graphically, your program executes like this:
  497.  
  498.         DOS C>program.exe
  499.           |
  500.         Compiler startup code (performs basic setup)
  501.           |
  502.           +----->+
  503.                  | Your program starts, ends
  504.           +<-----+
  505.           |   
  506.          rest of startup code, _atexit registered routines
  507.           |
  508.          DOS C>_
  509.  
  510.      Caution: In order for the _atexit registered routines to be called by your
  511.      compilers run-time, you must not allow you program to exit via non-standard
  512.      ways. Calling INT21/4C is on example (you should never do this from
  513.      compiled code, anyway). Note that some compilers' run-time code bypasses
  514.      _atexit when Ctrl-C or Ctrl-Break is used. If this is the case, you must
  515.      trap these and perform an ExitDac before returning to DOS.
  516.  
  517.      The startup code is basically a program that sets up your program to run,
  518.      calls your program, regains control when your program ends, then performs
  519.      the necessary shutdown actions required, including calling all routines
  520.      registered with _atexit.
  521.  
  522.      Sample Use:
  523.  
  524.      struct XitPack XP;
  525.  
  526.      XP.Func = AtExitDac;
  527.      rez = RUCKDAC(&XP);
  528.      if (rez !=0)
  529.         // error (more than 32 calls made to _atexit)
  530.  
  531.  
  532.                                                                                8
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544.      LoadDac             Func: 4        Pack: LoadPack
  545.  
  546.      Though not required, you can have RUCKUS load a digital file into memory
  547.      for you. It makes the necessary memory allocations and loads the data into
  548.      conventional or XMS memory. You can load up to 32 separate digital data
  549.      files to conventional memory at one time, and up to 96 more into XMS.
  550.      RUCKUS takes care of the memory allocation details.
  551.  
  552.      LoadDac can also be instructed to start loading at any particular byte in a
  553.      file for as many bytes as you specify. This would be useful, for example,
  554.      if you have a single file made up of several VOC or WAVE files appended to
  555.      form one large data file.
  556.  
  557.      Sample Use:
  558.  
  559.      struct LoadPack LP;
  560.  
  561.      LP.Func = LoadDac;
  562.      LP.FilenamePtr = filename;
  563.      LP.StartPos = 0L;         // start load at first byte of file
  564.      LP.LoadSize = 0L;         // have RUCKUS load all of it
  565.      LP.XMMflag = 0;           // -1 if loading into XMS
  566.      rez = RUCKDAC(&LP);
  567.      if (rez == 0) 
  568.         // okay load
  569.  
  570.      Note that even though loading into XMS memory, RUCKUS-DAC still needs some
  571.      conventional memory to use as a buffer. After the load to XMS, the low
  572.      memory is no longer required.
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.                                                                                9
  600.  
  601.  
  602.  
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609.  
  610.  
  611.      PlayDac             Func: 5        Pack: PlaybackPack
  612.  
  613.      Once the digital data is in either conventional or XMS memory, you can play
  614.      it to any of the RUCKUS-supported devices. XMS memory, however, requires
  615.      DMA playback mode; this mode is supported in the Sound Blasters only. Also,
  616.      for STEREO playback, DMA mode is required (SB Pro only).
  617.  
  618.      In addition to DMA-mode playback, you can instruct RUCKUS to play in the
  619.      background or foreground. Playing in the background allows your computer
  620.      program to regain control immediately after play has begun. If you choose
  621.      foreground play, control does not return to your program until the end of
  622.      the data has been played, or, until CTRL-ALT is pressed.
  623.  
  624.      All RUCKUS-supported devices can be played in the background. Only the
  625.      Sound Blasters can be played using DMA. DMA playback is similar to
  626.      background play in that control is returned to your program immediately,
  627.      but it is also much more efficient since DMA playback uses no CPU time.
  628.      Background play, on the other hand, can require anywhere from 1 to 100% of
  629.      available CPU time, depending on what playback rate has been selected (see
  630.      SetIntRateDac). 
  631.  
  632.      Since it's possible to load several data files into memory at one time, to
  633.      play a particular data file requires that you specify its start address or,
  634.      if loaded to XMS memory, its XMS handle. Given the code sequence example in
  635.      LoadDac, the following PlayDac code takes up from there:
  636.  
  637.      struct PlaybackPack PBP;
  638.  
  639.      PBP.Func = PlayDac;
  640.      PBP.Mode = 2;       // mode 0=foreground, 1=background, 2=DMA
  641.      PBP.XMMhandle = 0;  // 0=conv memory data follow, 1+=XMS data follows
  642.  
  643.      'If conventional memory used, then the following pointer is the 
  644.      'segment:offset start address of the VOC/WAVE data to play.
  645.      '
  646.      'If XMS memory used, the following pointer is the 32-bit offset within the
  647.      'XMS handle (PBP.XMMhandle) that the data starts. If you just load one data
  648.      'file to one XMM handle, then these will always=0. However, if you're short
  649.      'on available XMM handles, you could load several data files into a single,
  650.      'huge, XMM allocation. In order to do this, you must do your own data
  651.      'loads since LoadDac loads one file per XMM handle.
  652.      '
  653.      PBP.LoadPtr = LP.LoadPtr;
  654.  
  655.      'Note: the PBP.BufferSize is used by PlayMod only. Also, you may want/need
  656.      'to perform pre-Play tasks. See SetAllDac/SetAllSBP.
  657.  
  658.      rez = RUCKDAC(&PBP);
  659.      if (rez == 0)
  660.         // if DMA or background mode then the digital data is playing now, 
  661.         // but if foreground mode, the play has ended by the time we get here
  662.  
  663.  
  664.  
  665.  
  666.                                                                               10
  667.  
  668.  
  669.  
  670.  
  671.  
  672.  
  673.  
  674.  
  675.  
  676.  
  677.  
  678.      RecordDac           Func: 6        Pack: RecordPack
  679.  
  680.      The Sound Blasters can record as well as play digital data. As with play,
  681.      you can record directly into conventional or XMS memory. You can let RUCKUS
  682.      make the memory allocations, or you can allocate your own memory and record
  683.      into that. With the SB Pro, you can also record in stereo.
  684.  
  685.      With the Sound Blaster Pro you can select among three input sources: mic,
  686.      line, and CD. The earlier Sound Blaster has one input, the mic. A quality
  687.      microphone can make a big difference. For other-than-mic input on the SB,
  688.      you can pipe the headphone output of a CD player into the mic input. Your
  689.      results may vary, but this is better than mic'ing a loudspeaker. For
  690.      anything other than mic input, the SB Pro is recommended. Its recording
  691.      quality is very good since it allows sampling rates up to 45.5kHz in mono,
  692.      and 22.75kHz in stereo. The SB allows recording sampling rates up to 12kHz
  693.      (rated to 13kHz record and 23kHz playback). The sampling size is 8 bits.
  694.  
  695.      NOTE: TO RECORD IN STEREO AT A GIVEN SAMPLE RATE, YOU MUST SPECIFY TWICE
  696.            THE RATE DESIRED. FOR EXAMPLE, TO RECORD OFF A CD DECK CONNECTED TO
  697.            THE LINE INPUT OF THE PRO, AT A SAMPLE RATE OF 22.5kHz, YOU MUST
  698.            SET THE SP.SetIntRate=44100.
  699.  
  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.  
  746.      Sample Use:
  747.  
  748.      struct RecordPack RP;
  749.      struct XitPack XP;   
  750.      EP.Func = EndDac;         // preload EP.Func here for space reasons
  751.  
  752.      RP.Func = RecordDac;
  753.      RP.SampleRate = 23000;
  754.  
  755.      /* To record into XMM and have RUCKUS make the allocation, set RP.XMMhandle
  756.      to -1. If you made your own XMS allocation, set this to your handle.
  757.      To load into conventional memory and have RUCKUS make the allocation,
  758.      set RP.RecordPtr to NULL. If you made your own allocation, set this
  759.      to your far segmented pointer. */
  760.  
  761.      RP.XMMhandle = 0;         // use conventional memory if this is 0
  762.      RP.RecordPtrOff = 0;      // have RUCKUS make the memory allocation
  763.      RP.RecordPtrSeg = 0;      // if this is 0 (and if RP.XMMhandle=0)
  764.  
  765.      /* By using the DACDATA.MemDOS or .MemXMM, we can record as many bytes
  766.      as we have available. Below we reserve 5K (more for XMS) for misc use, as
  767.      you should, too. This is the max bytes to record; we can also stop
  768.      at any point before this. */
  769.  
  770.      RP.RecordBytes = (DACDATA.MemDOS - 5) * 1024;  
  771.      RP.StereoFlag = 0;
  772.      rez = RUCKDAC(&RP);
  773.      if (rez == 0)  {
  774.         // we are recording right now, using DMA, so, while we could do just
  775.         // about anything we wanted, in this example, we just wait until the
  776.         // record is over
  777.  
  778.         do 
  779.            ;
  780.         while (DACDATA.End == 0);
  781.         rez2 = RUCKDAC(&XP);   // stop recording (XP defined/assigned above)
  782.      }
  783.  
  784.      /* The above loop won't be exited until all the bytes requested have been
  785.      recorded. The number of bytes recorded (not counting any file headers added
  786.      by StoreDac) is in DACDATA.RecordLen.
  787.  
  788.      Now you can save the data by using StoreDac, or play it using PlayDac. On
  789.      return from the RECORD, RP.RecordPtr is set to the segment:offset of the
  790.      first byte recorded in conventional memory, or if using XMS memory,
  791.      RP.XMMhandle is set to the XMS handle. */
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.  
  800.                                                                               12
  801.  
  802.  
  803.  
  804.  
  805.  
  806.  
  807.  
  808.  
  809.  
  810.  
  811.  
  812.      StoreDac            Func: 7        Pack: SaveDataPack
  813.  
  814.      Once digital data has been loaded or recorded in memory, you can store it
  815.      do disk in either VOC or WAVE format. If you want, you can load a file in
  816.      one format and save it in the other with just a few lines of code (shown
  817.      below).
  818.  
  819.      Sample Use:
  820.  
  821.      struct SaveDataPack SDP;
  822.  
  823.      SDP.Func = StoreDac;
  824.      SDP.FilenamePtr= filename;
  825.  
  826.      // the LP pointer below is from (say) a just-loaded VOC file (using
  827.      // LoadDac), and we want to convert and store it to WAVE format
  828.  
  829.      SDP.DataPtr = LP.LoadPtr // segment:offset of conventional memory
  830.                               // or 0 if storing from an XMS handle
  831.      SDP.FileType = 2;        // 1=VOC, 2=WAVE
  832.      SDP.XMMhandle = 0;       // 0 if DOS data, else XMS handle 
  833.      rez = RUCKDAC(&SDP);
  834.      if (rez == 0)
  835.         // data stored to filename$
  836.      else
  837.         //file save error in stat
  838.  
  839.      /* Caution: Be sure to account for the additional memory required once data
  840.      has been stored to a file. StoreDac builds the appropriate VOC or WAV
  841.      header and this adds to the total memory required to reload. I suggest that
  842.      you do not record so much data as to not be able to load it back in once
  843.      saved to VOC or WAVE format. */
  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.      EndDac              Func: 8        Pack: XitPack
  880.  
  881.      EndDac is used to end (stop) play or record on command. Once PlayDac has
  882.      started, it continues to play in the background until either the end of the
  883.      digital data has been reached, or you call this routine. In the case of a
  884.      record, play continues until the number of bytes requested has been
  885.      recorded, or this routine is called.
  886.  
  887.      Sample Use:
  888.  
  889.      struct XitPack XP;
  890.  
  891.      // LoadDac and PlayDac, or RecordDac, have already been called
  892.      // see those routines for more information
  893.  
  894.      XP.Func = EndDac;     // if play or record is active this call
  895.      rez = RUCKDAC(&XP);   // ends it
  896.  
  897.      // See RecordDac on getting the number of bytes actually recorded
  898.  
  899.  
  900.  
  901.  
  902.  
  903.  
  904.  
  905.  
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.  
  929.  
  930.  
  931.  
  932.  
  933.  
  934.                                                                               14
  935.  
  936.  
  937.  
  938.  
  939.  
  940.  
  941.  
  942.  
  943.  
  944.  
  945.  
  946.      PauseDac            Func: 9        Pack: PausePack
  947.  
  948.      PauseDac allows you to temporarily pause and then restart a playback.
  949.  
  950.  
  951.      Sample Use:
  952.  
  953.      struct PausePack PP;
  954.  
  955.      PP.Func = PauseDac;
  956.      PP.Pause = 1;        // non-zero pauses, zero restarts
  957.      rez = RUCKDAC(&PP);
  958.  
  959.  
  960.  
  961.  
  962.  
  963.  
  964.  
  965.  
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979.  
  980.  
  981.  
  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.      DeallocDac          Func: 10       Pack: DeallocPack
  1014.  
  1015.      If you have RUCKUS load digital data files, which is most likely the case,
  1016.      it makes memory allocations from the operating system memory pool. RUCKUS
  1017.      tracks up to 32 consecutive DOS loads, and up to 96 loads to XMS (provided
  1018.      enough memory and XMS handles). These should be higher than you'll ever
  1019.      likely use at one time. DeallocDac "unloads" files that RUCKUS has loaded,
  1020.      thus releasing the memory that they used. 
  1021.  
  1022.      As an example, let's say that you want to start up your program with 5
  1023.      digital data files in XMS memory. You have 5MB of XMS available. Each data
  1024.      file is 1M in size. To load a new data file after these 5, you will need to
  1025.      unload one of the 5 already loaded. DeallocDac does that for you. The
  1026.      following example loads a single data file to XMS then immediately unloads
  1027.      it.
  1028.  
  1029.      DeallocDac is not used for releasing LoadMod allocations. 
  1030.  
  1031.      Sample Use:
  1032.  
  1033.      struct LoadPack LP;
  1034.      struct DeallocPack DP;
  1035.  
  1036.      LP.Func = LoadDac;
  1037.      LP.FilenamePtr = filename;
  1038.      LP.StartPos = 0L;
  1039.      LP.LoadSize = 0L;   
  1040.      LP.XMMflag = 1;        // non-zero means use XMS for load
  1041.      rez = RUCKDAC(&LP);
  1042.  
  1043.      if (rez == 0) {
  1044.         DP.Func = DeallocDac;
  1045.         DP.HandSeg = LP.XMMhandle; // XMM handle returned by RUCKDAC(LP)
  1046.         DP.TypeFlag = LP.XMMflag;  // 0=DOS allocation, 1=XMS
  1047.         rez = RUCKDAC(&DP);     // if this were a DOS allocation, DP.HandSeg
  1048.                                 // would be set to LP.LoadPtrSeg only since
  1049.                                 // _FP_OFF(LP.LoadPtr)==0 as returned by LoadDac
  1050.      }
  1051.      if (rez != 0)
  1052.         // file load error or deallocate error in rez
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.  
  1064.  
  1065.  
  1066.  
  1067.  
  1068.                                                                               16
  1069.  
  1070.  
  1071.  
  1072.  
  1073.  
  1074.  
  1075.  
  1076.  
  1077.  
  1078.  
  1079.  
  1080.      SetAllDac           Func: 20       Pack: SetPack
  1081.  
  1082.      This routine sets the overall playback volume, interrupt rate, and RUCKUS
  1083.      priority in one call.
  1084.  
  1085.      The playback volume affects VOC or WAVE output for non-DMA mode, only. In
  1086.      other words, it's for controlling the volume on the PC speaker, LPT-DAC,
  1087.      Disney Sound Source, and AdLib only. To control the playback volume of the
  1088.      Sound Blaster, you must operate it under non-DMA mode. To control the
  1089.      playback of the Sound Blaster Pro, a separate set of RUCKUS routines are
  1090.      used. See the SetAllSBP routine for more.
  1091.  
  1092.      The default volume is set to 16. Minimum is 0, maximum is 127. For a linear
  1093.      approximation of this volume control, 16 is about half-volume, 8 about 1/4,
  1094.      64 about 3/4, and 127 full volume. A volume other than 16 may
  1095.      cause a slowdown in performance so 16 should be used as much as possible.
  1096.  
  1097.      Note: SETTING THE VOLUME TO 0 TURNS OFF THE SOUND BLASTER AND PRO'S
  1098.            SPEAKER (REQUIRED BEFORE RECORDING). ANY OTHER SETTING TURNS
  1099.            THE SPEAKER CONNECTION ON.
  1100.  
  1101.      The interrupt rate sets the playback rate of background play for non-DMA
  1102.      mode. For example, let's say you load a file that was recorded with a
  1103.      sample rate of 8000Hz (this information is stored with the VOC or WAVE).
  1104.      That is the value to which you set the interrupt rate. Easy enough. But
  1105.      let's say that it was recorded at 44,100Hz and in stereo. Normally, this
  1106.      data file couldn't be played except with high-end sound cards. What you can
  1107.      do is set the interrupt rate to 8000Hz and have RUCKUS-DAC perform on-the-
  1108.      fly downsampling so that you can play this file on any of the supported
  1109.      devices (in non-DMA mode).
  1110.  
  1111.      In addition to downsampling, RUCKUS-DAC can upsample with the PC Speaker
  1112.      and AdLib cards (the two that need it the most). Let's take that 8000Hz
  1113.      sample rate file again. Upsampling performs on-the-fly adjustments to the
  1114.      data so that it sounds as if the file sample rate were twice the original.
  1115.      This results in a much cleaner sound. There is a drawback: much more CPU
  1116.      time is needed at this high rate, and it should only be used on powerful
  1117.      CPUs. To use the upsampling capabilities of RUCKUS-DAC, set the interrupt
  1118.      rate to the original sample rate. There is also a special method used in
  1119.      the initialization of the device. See InitDac for more. You can experiment
  1120.      with the down- and upsampling of RUCKUS-DAC by using the MODAC.EXE program.
  1121.  
  1122.      When using non-DMA mode, you can select from three priority levels. The
  1123.      default priority=1. This level allows the system to run as normal, even
  1124.      though the computer's ticker has been sped up some thousand times. Priority
  1125.      level 2 hogs all background time for the RUCKUS-DAC playback. The
  1126.      computer's clock is not updated. Priority level 0 gives top priority to
  1127.      other computer events. This level may result in a warbly sound. Priority
  1128.      only affects non-DMA VOC/WAVE output. Use the default level (1).
  1129.  
  1130.  
  1131.  
  1132.  
  1133.  
  1134.  
  1135.                                                                               17
  1136.  
  1137.  
  1138.  
  1139.  
  1140.  
  1141.  
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  1147.      The default interrupt rate is 10989. If you are on a slow machine, this may
  1148.      be too high for non-DMA operations. The following table shows the min, max,
  1149.      and nominal interrupt rate for the supported devices. In all cases, higher
  1150.      rates require more CPU power, except in DMA mode. Nominal values based on a
  1151.      386/25 CPU.
  1152.  
  1153.        Device   MinRate   MaxRate  Nominal  Comments
  1154.        ------   -------   -------  -------  ------------------------------------
  1155.        PCSKP0      5000     18000     8000  rates < 16000 may be noisy
  1156.        PCSPK1      5000      9000     8000  effective rate=rate*2
  1157.        LPTDAC      5000     23000    15000  not tested
  1158.        DISNEY      5000      7000     7000  max usable rate is 7000Hz
  1159.        ADLIB0      5000     12000     8000  AdLib very slow as digital device
  1160.        ADLIB1      5000      6000     5500  effective rate=rate*2
  1161.        SB          5000     23000    15000  DMA mode is 5-23000, record to 12kHz
  1162.        SB PRO      5000     23000    15000  DMA mode is 5-45500
  1163.  
  1164.      Sample Use:
  1165.  
  1166.      struct SetPack SP;
  1167.  
  1168.      SP.Func = SetAllDac;
  1169.      SP.Volume = 16;       // any other value slows down performance
  1170.      SP.IntRate = 8000;      
  1171.      SP.Priority = 1;
  1172.      rez = RUCKDAC(&SP);
  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.      SetVolumeDac        Func: 21       Pack: SetPack
  1215.  
  1216.      SetVolumeDac does two things. First, it controls the non-DMA mode output
  1217.      volume. Second, it turns the SB's speaker on and off; the SB speaker must
  1218.      be off, and remain off, while recording. Under normal use, the SB speaker
  1219.      is turned on and off by RUCKUS automatically.
  1220.  
  1221.      Because of the extra calculations required when the volume is set to
  1222.      anything other than the default (16), it's recommended that the volume be
  1223.      changed only when necessary (especially on slow machines).
  1224.  
  1225.      This routine controls the output volume on all devices in non-DMA mode. In
  1226.      DMA-mode, the SB's volume is not controllable. The SB PRO, however, has a
  1227.      large set of mixer controls that can be controlled via RUCKUS-DAC. See
  1228.      SetAllSBP for more.
  1229.  
  1230.      Sample Use:
  1231.  
  1232.      struct SetPack SP;
  1233.  
  1234.      SP.Func = SetVolumeDac;
  1235.      SP.Volume = 127;          // set to max volume
  1236.      rez = RUCKDAC(&SP);
  1237.      if (rez != 0)
  1238.         // you probably didn't set SP.Func correctly
  1239.  
  1240.  
  1241.  
  1242.  
  1243.  
  1244.  
  1245.  
  1246.  
  1247.  
  1248.  
  1249.  
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258.  
  1259.  
  1260.  
  1261.  
  1262.  
  1263.  
  1264.  
  1265.  
  1266.  
  1267.  
  1268.  
  1269.                                                                               19
  1270.  
  1271.  
  1272.  
  1273.  
  1274.  
  1275.  
  1276.  
  1277.  
  1278.  
  1279.  
  1280.  
  1281.      SetIntRateDac       Func: 22       Pack: SetPack
  1282.  
  1283.      SetIntRateDac, with respect to the -DAC section of RUCKUS, controls the
  1284.      playback rate of non-DMA output.
  1285.  
  1286.      After loading a file, that file's sample rate is available in the DAC data
  1287.      section. You may choose to have the digital data file played back at that
  1288.      rate, or, you may choose to downsample the original rate. Downsampling is
  1289.      useful since it allows slower computers to play data files originally
  1290.      sampled at rates too high to be played back -- RUCKUS can play a 44.1kHz
  1291.      stereo VOC or WAVE file back through the PC speaker, or any of the other
  1292.      supported devices. Note that the actual downsampled rate is not always
  1293.      exactly what you specify, but a best-fit approximation.
  1294.  
  1295.      As an example, let's suppose you have a VOC file originally sampled at
  1296.      22050Hz, mono format. While this can easily be played on the SBs using DMA-
  1297.      mode playback, non-DMA mode requires a very powerful CPU to handle that
  1298.      high a rate. After loading using LoadDac, the 22050 sample rate, and its
  1299.      mono format, is determined by reading the DAC data section. To play back
  1300.      this file through PCSPKR0, say, at 11kHz, you'd set SP.IntRate=11025.
  1301.  
  1302.      With the PC speaker and the AdLib, there are two different output modes.
  1303.      The first either plays at the original rate, or is downsampled to a lower
  1304.      rate (as specified by you). The second mode upsamples. By upsampling,
  1305.      RUCKUS can output a much cleaner sound than playing at the original sample
  1306.      rate. However, this is useful only for samples that were originally at a
  1307.      low sample rate. You would not want to upsample a VOC file that was sampled
  1308.      at 22kHz, since that would demand too much CPU power, plus, very little
  1309.      benefit would be achieved. The best use of upsampling is on data that was
  1310.      originally sampled at, say, 8kHz or less. In order to properly upsample,
  1311.      you need to specify a SP.IntRate equal to the original sample rate (this
  1312.      can be found in the DAC data section immediately after a LoadDac).
  1313.  
  1314.      As mentioned, upsample mode is available on the speaker and AdLib devices
  1315.      only. To specify this mode, set the IP.IOport to the physical port when
  1316.      initializing the device (InitDac). In the PC speaker's case, IP.IOport=0x42
  1317.      would activate up-sample mode. Using IP.IOport=0 would have the regular
  1318.      mode used. For the AdLib, specify IP.IOport=0x388. As with the PC speaker,
  1319.      setting IP.IOport=0 uses the regular AdLib play mode.
  1320.  
  1321.      Sample Use:
  1322.  
  1323.      struct SetPack SP;
  1324.  
  1325.      SP.Func = SetIntRateDac;
  1326.      SP.IntRate = 11025;
  1327.      rez = RUCKDAC(&SP);
  1328.  
  1329.  
  1330.  
  1331.  
  1332.  
  1333.  
  1334.  
  1335.  
  1336.                                                                               20
  1337.  
  1338.  
  1339.  
  1340.  
  1341.  
  1342.  
  1343.  
  1344.  
  1345.  
  1346.  
  1347.  
  1348.      SetPriorityDac      Func: 23       Pack: SetPack
  1349.  
  1350.      When operating in non-DMA mode playback of VOC or WAVE data, RUCKUS
  1351.      reprograms the system timer. Normally, this timer runs at the familiar 18.2
  1352.      times per second rate. When you play back at, say, a SP.IntRate=10000, this
  1353.      is the new rate that the system timer is set to operate at. So, instead of
  1354.      the timer interrupting the CPU (via IRQ0) 18.2/sec, it interrupts at
  1355.      10,000/sec. 
  1356.  
  1357.      The routine allows you to control the priority given to other events while
  1358.      the timer is operating at this accelerated pace. The default priority is 1.
  1359.      At the priority, the playback code is called at the desired rate, and,
  1360.      given a 10kHz rate, every 550th time the playback code is executed, the
  1361.      original timer-dependant code is executed. This allows the system clock,
  1362.      and any other system in the computer dependant on the clock, to be properly
  1363.      maintained. On each 550th call, RUCKUS first performs all tasks that needs
  1364.      to be done, then it calls the original system code. In most cases, if not
  1365.      all, this priority works best.
  1366.  
  1367.      Priority 0 is exactly like priority 1 except that control is released as
  1368.      soon as the RUCKUS code starts. The permits other tasks to interrupt
  1369.      RUCKUS. This may cause a warbly-type sound, but permits, say, high-speed
  1370.      communications code to operate in the background with missing a beat.
  1371.  
  1372.      Priority 2 causes RUCKUS to use (hog) all background processing time for
  1373.      itself. The system clock is not maintained. Use this priority only if the
  1374.      other two are causing problems (doubtful) or if you want to get the maximum
  1375.      sound performance out of RUCKUS and don't care if the system clock is
  1376.      maintained.
  1377.  
  1378.  
  1379.      Sample Use:
  1380.  
  1381.      struct SetPack SP;
  1382.  
  1383.      SP.Func = SetPriorityDac;
  1384.      SP.Priority = 1;   // 1 is the default so no need to call unless changed
  1385.      rez = RUCKDAC(&SP);
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391.  
  1392.  
  1393.  
  1394.  
  1395.  
  1396.  
  1397.  
  1398.  
  1399.  
  1400.  
  1401.  
  1402.  
  1403.                                                                               21
  1404.  
  1405.  
  1406.  
  1407.  
  1408.  
  1409.  
  1410.  
  1411.  
  1412.  
  1413.  
  1414.  
  1415.      GetBufferDataDac    Func: 28       Pack: GetDataPack
  1416.  
  1417.      Used to get a specified number of bytes from the current digital data path.
  1418.  
  1419.      This routine is currently under development and should not be used.
  1420.  
  1421.  
  1422.  
  1423.  
  1424.  
  1425.  
  1426.  
  1427.  
  1428.  
  1429.  
  1430.  
  1431.  
  1432.  
  1433.  
  1434.  
  1435.  
  1436.  
  1437.  
  1438.  
  1439.  
  1440.  
  1441.  
  1442.  
  1443.  
  1444.  
  1445.  
  1446.  
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452.  
  1453.  
  1454.  
  1455.  
  1456.  
  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.      GetBytePosDac       Func: 29       Pack: GetDataPack
  1483.  
  1484.      Used to determine where in the current digital data path processing is
  1485.      occurring.
  1486.  
  1487.      Sample Use:
  1488.  
  1489.      struct GetDataPack GDP;
  1490.  
  1491.      GDP.Func = GetBytePosDac;
  1492.      rez = RUCKDAC(&GDP);
  1493.      if (rez == 0)
  1494.         printf("Curr pos relative start of data is %ul", GDP.BytePos);
  1495.  
  1496.  
  1497.  
  1498.  
  1499.  
  1500.  
  1501.  
  1502.  
  1503.  
  1504.  
  1505.  
  1506.  
  1507.  
  1508.  
  1509.  
  1510.  
  1511.  
  1512.  
  1513.  
  1514.  
  1515.  
  1516.  
  1517.  
  1518.  
  1519.  
  1520.  
  1521.  
  1522.  
  1523.  
  1524.  
  1525.  
  1526.  
  1527.  
  1528.  
  1529.  
  1530.  
  1531.  
  1532.  
  1533.  
  1534.  
  1535.  
  1536.  
  1537.                                                                               23
  1538.  
  1539.  
  1540.  
  1541.  
  1542.  
  1543.  
  1544.  
  1545.  
  1546.  
  1547.  
  1548.  
  1549.      SetAllSBP           Func: 30       Pack: SetProPack
  1550.  
  1551.      This routine allows you to control the mixer facility of the Sound Blaster
  1552.      Pro including main volume, VOC volume, mic level, CD level, line level,
  1553.      output filter, input source selection, record filters, input source, and
  1554.      stereo/mono record mode.
  1555.  
  1556.      During initialization of the Sound Blaster Pro (InitDac), the main and VOC
  1557.      volumes are set to maximum (15) for both left and right channels, the three
  1558.      input levels are set to their minimums (1), all filters are set to off,
  1559.      mode is set to mono record, and input selection is set to mic.
  1560.  
  1561.      NOTE: PLAYBACK OF VOC AND WAVE STEREO DATA FILES IS AUTOMATIC. THE STEREO
  1562.            MODE SETTING IS FOR RECORDING ONLY. TO PLAY STEREO FILES IN MONO
  1563.            ON THE SB PRO, USE THE SOUND BLASTER (DEVICE 4) INSTEAD.
  1564.  
  1565.      The main volume (left and right, as are all mixer controls except mic)
  1566.      adjusts both the digital and synthesizer outputs of the PRO (the
  1567.      synthesizer, or FM section, is not used by RUCKUS-DAC, but is in RUCKUS-
  1568.      MIDI). In normal use the main volume channels would be set to 15, the
  1569.      maximum.
  1570.  
  1571.      The VOC volume adjusts the volume of the digital output channels. Anything
  1572.      played through the SB PRO's digital channels can be adjusted with this. As
  1573.      with the main volume, the VOC volume is normally set to 15, the maximum.
  1574.  
  1575.      The SB PRO provides for three inputs. Mic, CD, and Line. Each of these have
  1576.      separate level adjustments. The mic input level is the odd one out. Unlike
  1577.      the other two, the mic level does not adjust the mic input level, but
  1578.      rather the mic output level. Whenever you record via the mic input line at
  1579.      the back of the card, the input level is controlled by an AGC, automatic
  1580.      gain control. The AGC acts as a real-time level adjuster -- high signal
  1581.      levels (loud sounds) have the AGC automatically decrease the mic input
  1582.      sensitivity -- low signal levels (quiet sounds) have it automatically
  1583.      increase the mic input sensitivity. The actions of an AGC has its drawbacks
  1584.      in reduced dynamic range and perhaps a noticeable "breathing" of the sound
  1585.      on playback. Breathing is where the background noise increases as the level
  1586.      of the sound decreases. However, often the reduced dynamic range makes for
  1587.      a better final results, especially when using a mic/SB combination.
  1588.  
  1589.      The CD input level adjusts the level of the CD-ROM device. No testing has
  1590.      been done with this. It controls the input level from the proprietary CD-
  1591.      ROM drive that CLabs distributes for the SB PRO, or one which is compatible
  1592.      (and is hooked up to the SB PRO's CD connector). Any CD should be able to
  1593.      plug into the CD audio connector of the SB PRO (see the SB PRO docs) and so
  1594.      have its level controllable via RUCKUS-DAC.
  1595.  
  1596.      The Line input level adjusts the input sensitivity. Normally, when
  1597.      recording from this input, the Line level should be set to 15, the maximum.
  1598.      For preamps that have an unusually high line out level, reducing the PRO's
  1599.      line input level may produce a better recording.
  1600.  
  1601.      The output filter can be used to reduce the noise at the mid and high end
  1602.      of the digital data being played. Normally, this filter is not needed.
  1603.  
  1604.                                                                               24
  1605.  
  1606.  
  1607.  
  1608.  
  1609.  
  1610.  
  1611.  
  1612.  
  1613.  
  1614.  
  1615.  
  1616.  
  1617.      The recording filters are very useful and should be used whenever the
  1618.      recording sample rate is below 18kHz and the source being record has
  1619.      frequencies above 9kHz. There are two filters to choose from: one has a
  1620.      3.2kHz cutoff, the other 8.8kHz.
  1621.  
  1622.      Whenever you are recording from a source that will include frequencies
  1623.      higher than 3.2kHz, and you have the PRO recording at a sample rate under
  1624.      6.4kHz, you should select the 3.2kHz filter. This will attenuate
  1625.      frequencies higher than 3.2kHz and should help produce a cleaner recording.
  1626.      Along the same lines, if you are recording frequencies higher than 8.8kHz,
  1627.      and are recording using a sample rate less than 17.6kHz, you should use the
  1628.      8.8kHz filter. Note that filter use as described above is not a rule, just
  1629.      a guideline. You may find that using no filters is best.
  1630.  
  1631.      With the SB PRO you have 3 input sources to record from: the mic, a CD-ROM
  1632.      drive attached to the SB PRO (requires special cable), or a line-level
  1633.      input. The mic allows mono recording only. The CD-ROM facility controls
  1634.      only a CD-ROM drive hooked up to the SB PRO. The line input can be
  1635.      connected directly to a preamplifier's line out jacks.
  1636.  
  1637.      The SB PRO allows you to record in STEREO from the CD and LINE input
  1638.      sources; mic is always mono. When recording in stereo, the sample rate you
  1639.      record at must be set to twice the desired rate. For example, if you want
  1640.      to record from the LINE input at 22.05kHz, in stereo, set the recording
  1641.      rate to twice 22,050, or 44,100. The SB PRO can sample up to a 45,500Hz
  1642.      rate (which, if a stereo recording, is an effective rate of 22,750Hz). See
  1643.      RecordDac for more.
  1644.  
  1645.      Sample Use:
  1646.  
  1647.      struct SetProPack SPP;  // be careful not to type SBP
  1648.  
  1649.      SPP.Func = SetAllSBP;
  1650.      SPP.Volume = 0x0F0F;    // max out volumes
  1651.      SPP.VolVoc = 0x0F0F;
  1652.  
  1653.      SPP.VolMic = 0;         // minimized mic input level
  1654.      SPP.CD = 0;             // actual min for SB Pro is 1
  1655.      SPP.LI = 0;
  1656.  
  1657.      SPP.FilterOut = 0;      // 0=off filter, 1=on (output filter)
  1658.      SPP.FilterIn = 0;       // 0=off filter, 1=3.2kHz, 2=8.8kHz (record filter)
  1659.      SPP.SourceIn = 0;       // 0=mic, 1=CD, 2=line
  1660.      SPP.StereoIn = 0;       // record mode: 0=mono, 1=stereo
  1661.      rez = RUCKDAC(&SPP);
  1662.  
  1663.  
  1664.  
  1665.  
  1666.  
  1667.  
  1668.  
  1669.  
  1670.  
  1671.                                                                               25
  1672.  
  1673.  
  1674.  
  1675.  
  1676.  
  1677.  
  1678.  
  1679.  
  1680.  
  1681.  
  1682.  
  1683.      SetVolMainSBP       Func: 31       Pack: SetProPack
  1684.  
  1685.      The main volume (left and right) adjusts both the digital and synthesizer
  1686.      outputs of the PRO; it is the overall volume setting. Each of these outputs
  1687.      also has its own volume control. In normal use, the main volume channels
  1688.      would be set to 15, the maximum.
  1689.  
  1690.      The range of volume is 1 to 15, in steps of 2 (1,3,5,7,9,11,13,15). To set
  1691.      the left channel main volume, multiply the volume desired by 256. To set
  1692.      the right channel, just add its value. For example, to set the main volume
  1693.      to maximum (15, or 0F hex), multiply 15*256 and add 15. In hex, this value
  1694.      is 0F0F (decimal 3855, but decimal is much too awkward). If you know
  1695.      beforehand that you want the main volume at maximum, you can forego the
  1696.      multiplication and simply use 0F0F, as in the example below.
  1697.  
  1698.      NOTE: Since you are the programmer and you have the documentation, do not
  1699.            depend on RUCKUS correcting out-of-value parameters. If you use 
  1700.            parameters that are not within specifications, the results are
  1701.            undefined.
  1702.  
  1703.      Sample Use:
  1704.  
  1705.      struct SetProPack SPP;
  1706.  
  1707.      SPP.Func = SetVolMainSBP;
  1708.      SPP.Volume = 0x0F0F;
  1709.      rez = RUCKDAC(&SPP);
  1710.  
  1711.  
  1712.  
  1713.  
  1714.  
  1715.  
  1716.  
  1717.  
  1718.  
  1719.  
  1720.  
  1721.  
  1722.  
  1723.  
  1724.  
  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.      SetVolVocSBP        Func: 32       Pack: SetProPack
  1751.  
  1752.      The VOC volume (left and right) adjusts the digital output volume of the
  1753.      PRO. The range of volume is 1 to 15, in steps of 2 (1,3,5,7,9,11,13,15). To
  1754.      set the left channel VOC volume, multiply the volume desired by 256. To set
  1755.      the right channel, just add its value. For example, to set the VOC volume
  1756.      to maximum (15, or 0F hex), multiply 15*256 and add 15. In hex, this value
  1757.      is 0F0F (decimal 3855, but decimal is much too awkward). If you know
  1758.      beforehand that you want the VOC volume at maximum, you can forego the
  1759.      multiplication and simply use 0F0F, as in the example below.
  1760.  
  1761.      Sample Use:
  1762.  
  1763.      struct SetProPack SPP;
  1764.  
  1765.      SPP.Func = SetVolMainSBP;
  1766.      SPP.VolVoc = 0x0F0F;
  1767.      rez = RUCKDAC(&SPP);
  1768.  
  1769.  
  1770.  
  1771.  
  1772.  
  1773.  
  1774.  
  1775.  
  1776.  
  1777.  
  1778.  
  1779.  
  1780.  
  1781.  
  1782.  
  1783.  
  1784.  
  1785.  
  1786.  
  1787.  
  1788.  
  1789.  
  1790.  
  1791.  
  1792.  
  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.      SetLevelMicSBP      Func: 33       Pack: SetProPack
  1818.  
  1819.      This routine does not actually adjust the mic input level, but rather the
  1820.      mic output level. Whenever you record via the mic input line at the back of
  1821.      the card, the input level is controlled by an AGC, automatic gain control.
  1822.      The AGC acts as a real-time level adjuster -- high signal levels (loud
  1823.      sounds) have the AGC automatically decrease the mic input sensitivity --
  1824.      low signal levels (quiet sounds) have it automatically increase the mic
  1825.      input sensitivity. The actions of an AGC has its drawbacks in reduced
  1826.      dynamic range and perhaps a noticeable "breathing" of the sound on
  1827.      playback. Breathing is where the background noise increases as the level of
  1828.      the sound decreases. However, often the reduced dynamic range makes for a
  1829.      better final results, especially when using a mic/SB combination.
  1830.  
  1831.      By setting the mic input level, you can use the computer as a public
  1832.      address system. To do this, select mic as the input source, set the mic
  1833.      input level to maximum, and turn on the SB speaker. To avoid feedback, keep
  1834.      the mic away from the loudspeakers.
  1835.  
  1836.      The input level range is 1 to 7, in steps of 2 (1,3,5,7). This setting has
  1837.      no effect on recording level (see above).
  1838.  
  1839.      Sample Use:
  1840.  
  1841.      struct SetProPack SPP;
  1842.  
  1843.      SPP.Func = SetVolMicSBP;
  1844.      SPP.VolVoc = 0x07;
  1845.      rez = RUCKDAC(&SPP);
  1846.  
  1847.  
  1848.  
  1849.  
  1850.  
  1851.  
  1852.  
  1853.  
  1854.  
  1855.  
  1856.  
  1857.  
  1858.  
  1859.  
  1860.  
  1861.  
  1862.  
  1863.  
  1864.  
  1865.  
  1866.  
  1867.  
  1868.  
  1869.  
  1870.  
  1871.  
  1872.                                                                               28
  1873.  
  1874.  
  1875.  
  1876.  
  1877.  
  1878.  
  1879.  
  1880.  
  1881.  
  1882.  
  1883.  
  1884.      SetLevelCDSBP       Func: 34       Pack: SetProPack
  1885.  
  1886.      The CD input level (left and right) adjusts the input level of the attached
  1887.      CD-ROM drive. This has not been tested. For its use, see SetLevelLineSBP.
  1888.  
  1889.  
  1890.  
  1891.  
  1892.  
  1893.  
  1894.  
  1895.  
  1896.  
  1897.  
  1898.  
  1899.  
  1900.  
  1901.  
  1902.  
  1903.  
  1904.  
  1905.  
  1906.  
  1907.  
  1908.  
  1909.  
  1910.  
  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.      SetLevelLineSBP     Func: 35       Pack: SetProPack
  1952.  
  1953.      The line level (left and right) adjusts the analog input level of the PRO.
  1954.      The range of volume is 1 to 15, in steps of 2 (1,3,5,7,9,11,13,15). To set
  1955.      the left channel line level, multiply the volume desired by 256. To set the
  1956.      right channel, just add its value. For example, to set the line level to
  1957.      maximum sensitivity (15, or 0F hex), multiply 15*256 and add 15. In hex,
  1958.      this value is 0F0F (decimal 3855, but decimal is much too awkward). If you
  1959.      know beforehand that you want the line level at maximum, you can forego the
  1960.      multiplication and simply use 0F0F, as in the example below.
  1961.  
  1962.      Sample Use:
  1963.  
  1964.      struct SetProPack SPP;
  1965.  
  1966.      SPP.Func = SetVolMainSBP;
  1967.      SPP.VolLI = 0x0F0F;
  1968.      stat = RUCKDAC(&SPP);
  1969.  
  1970.  
  1971.  
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.  
  1978.  
  1979.  
  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.      SetFilterOutSBP     Func: 36       Pack: SetProPack
  2019.  
  2020.      The output filter of the PRO can be used to reduce the noise at the mid and
  2021.      high end of the digital data being played. Normally, this filter is not
  2022.      needed. Recordings made at a very low sample rate, say, under 6kHz, may
  2023.      sound better with this output filter on.
  2024.  
  2025.      The digital output filter, and also the analog recording filter, is set off
  2026.      by default. 
  2027.  
  2028.      Sample Use:
  2029.  
  2030.      struct SetProPack SPP;
  2031.  
  2032.      SPP.Func = SetFilterOutSBP;
  2033.      SPP.FilterOut = 1;          // enable output filter
  2034.      rez = RUCKDAC(&SPP);
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.  
  2042.  
  2043.  
  2044.  
  2045.  
  2046.  
  2047.  
  2048.  
  2049.  
  2050.  
  2051.  
  2052.  
  2053.  
  2054.  
  2055.  
  2056.  
  2057.  
  2058.  
  2059.  
  2060.  
  2061.  
  2062.  
  2063.  
  2064.  
  2065.  
  2066.  
  2067.  
  2068.  
  2069.  
  2070.  
  2071.  
  2072.  
  2073.                                                                               31
  2074.  
  2075.  
  2076.  
  2077.  
  2078.  
  2079.  
  2080.  
  2081.  
  2082.  
  2083.  
  2084.  
  2085.      SetFilterInSBP      Func: 37       Pack: SetProPack
  2086.  
  2087.      The recording filters are very useful and should be used whenever the
  2088.      recording sample rate is below 18kHz and the source being record has
  2089.      frequencies above 9kHz. There are two filters to choose from: one has a
  2090.      3.2kHz cutoff, the other 8.8kHz.
  2091.  
  2092.      Whenever you are recording from a source that will include frequencies
  2093.      higher than 3.2kHz, and you have the PRO recording at a sample rate under
  2094.      6.4kHz, you should select the 3.2kHz filter. This will attenuate
  2095.      frequencies higher than 3.2kHz and should help produce a cleaner recording.
  2096.      Along the same lines, if you are recording frequencies higher than 8.8kHz,
  2097.      and are recording using a sample rate less than 17.6kHz, you should use the
  2098.      8.8kHz filter. Note that filter use as described above is not a rule, just
  2099.      a guideline. You may find that using no filters is best.
  2100.  
  2101.      The input filter is off by default.
  2102.  
  2103.      Sample Use:
  2104.  
  2105.      struct SetProPack SPP;
  2106.  
  2107.      SPP.Func = SetFilterInSBP;
  2108.      SPP.FilterIn = 1;       // 0=no filter, 1=3.2kHz cutoff, 2=8.8kHz cutoff
  2109.      rez = RUCKDAC(&SPP);
  2110.  
  2111.  
  2112.  
  2113.  
  2114.  
  2115.  
  2116.  
  2117.  
  2118.  
  2119.  
  2120.  
  2121.  
  2122.  
  2123.  
  2124.  
  2125.  
  2126.  
  2127.  
  2128.  
  2129.  
  2130.  
  2131.  
  2132.  
  2133.  
  2134.  
  2135.  
  2136.  
  2137.  
  2138.  
  2139.  
  2140.                                                                               32
  2141.  
  2142.  
  2143.  
  2144.  
  2145.  
  2146.  
  2147.  
  2148.  
  2149.  
  2150.  
  2151.  
  2152.      SetSourceSBP        Func: 38       Pack: SetProPack
  2153.  
  2154.      With the SB PRO you have three input sources to record from: the mic, a CD-
  2155.      ROM drive attached to the SB PRO (requires special cable), or a line-level
  2156.      input. The mic allows mono recording only. The CD-ROM facility controls
  2157.      only a CD-ROM drive hooked up to the SB PRO. The line input can be
  2158.      connected directly to a preamplifier's line out jacks.
  2159.  
  2160.      Recording with the mic requires only that it be selected. The mic input
  2161.      level does not control the recording level, but rather the PA output. See
  2162.      SetAllSBP for more.
  2163.  
  2164.      Recording from the connected CD-ROM drive has not been tested. If you can
  2165.      control the CD, you can record from it using RUCKUS.
  2166.  
  2167.      Recording from the line-level input is simple. Just hook your tape-out
  2168.      jacks from your preamplifier to the cable supplied with the SB PRO. This
  2169.      cable, a 1/8-inch mini stereo to 2 RCA phono jacks is the same one that
  2170.      comes with the original Sound Blaster. You'll probably need more cable
  2171.      unless you have your preamp nearby. 
  2172.  
  2173.      When recording from either the CD or line, you must set the source's input
  2174.      level. Normally, setting it to maximum (15) is best. If you have
  2175.      particularly high line output levels, you may need to set this lower. As
  2176.      with all mixer settings, settings are 1 to 15 in steps of 2. The mic is 1
  2177.      to 7, by 2.
  2178.  
  2179.      Sample Use:
  2180.  
  2181.      struct SetProPack SPP;
  2182.  
  2183.      SPP.Func = SetSourceSBP;
  2184.      SPP.SourceIn = 2;         // set input source to line input
  2185.      rez = RUCKDAC(&SPP);
  2186.  
  2187.  
  2188.  
  2189.  
  2190.  
  2191.  
  2192.  
  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.      SetStereoSBP        Func: 39       Pack: SetProPack
  2220.  
  2221.      The SB PRO allows you to record in STEREO from the CD and LINE input
  2222.      sources; mic is always mono. When recording in stereo, the sample rate you
  2223.      record at must be set to twice the desired rate. For example, if you want
  2224.      to record from the LINE input at 22.05kHz, in stereo, set the recording
  2225.      rate to twice 22,050, or 44,100. The SB PRO can sample up to a 45,500Hz
  2226.      rate (which, if a stereo recording, is an effective rate of 22,750Hz). See
  2227.      RecordDac for more.
  2228.  
  2229.      You must set the mode to stereo or mono before starting the actual record.
  2230.  
  2231.      Sample Use:
  2232.  
  2233.      struct SetProPack SPP;
  2234.  
  2235.      SPP.Func = SetStereoSBP;
  2236.      SPP.StereoIn = 1;         // set to stereo record
  2237.      rez = RUCKDAC(&SPP);
  2238.  
  2239.  
  2240.  
  2241.  
  2242.  
  2243.  
  2244.  
  2245.  
  2246.  
  2247.  
  2248.  
  2249.  
  2250.  
  2251.  
  2252.  
  2253.  
  2254.  
  2255.  
  2256.  
  2257.  
  2258.  
  2259.  
  2260.  
  2261.  
  2262.  
  2263.  
  2264.  
  2265.  
  2266.  
  2267.  
  2268.  
  2269.  
  2270.  
  2271.  
  2272.  
  2273.  
  2274.                                                                               34
  2275.  
  2276.  
  2277.  
  2278.  
  2279.  
  2280.  
  2281.  
  2282.  
  2283.  
  2284.  
  2285.  
  2286.      SetSpeakerSB        Func: 40       Pack: SetPack
  2287.  
  2288.      The routine activates or deactivates the Sound Blasters' output. When
  2289.      recording it must be off. When playing back, it must be on. When starting a
  2290.      recording, RUCKUS automatically turns the speaker off; when playing back it
  2291.      turns the speaker on. For those occasions when you want to control the
  2292.      speaker connection, use this routine.
  2293.  
  2294.      Note that the generic SetVolumeDac also controls the SB's speaker
  2295.      connection. If the speaker is currently on and you set the volume to 0, the
  2296.      SB speaker is turned off. And, of the speaker is currently off, and you set
  2297.      the volume to a non-zero value, the speaker is turned on. This routine lets
  2298.      you control the connection without changing the generic volume setting.
  2299.  
  2300.      Sample Use:
  2301.  
  2302.      struct SetPack SP;
  2303.  
  2304.      SP.Func = SetSpeakerSB;
  2305.      SP.Volume = 0;           // use the volume member of SP to control speaker
  2306.      rez = RUCKDAC(&SP);      // to turn the speaker on, set SP.Volume = 1
  2307.                               // THIS DOES NOT ALTER THE VOLUME
  2308.  
  2309.  
  2310.  
  2311.  
  2312.  
  2313.  
  2314.  
  2315.  
  2316.  
  2317.  
  2318.  
  2319.  
  2320.  
  2321.  
  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.      GetMixerRegSBP      Func: 48       Pack: GetDataPack
  2354.  
  2355.      Get a SB PRO mixer port-value.
  2356.  
  2357.      This routine is under development and should not be used.
  2358.  
  2359.  
  2360.  
  2361.  
  2362.  
  2363.  
  2364.  
  2365.  
  2366.  
  2367.  
  2368.  
  2369.  
  2370.  
  2371.  
  2372.  
  2373.  
  2374.  
  2375.  
  2376.  
  2377.  
  2378.  
  2379.  
  2380.  
  2381.  
  2382.  
  2383.  
  2384.  
  2385.  
  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.      GetDacSB            Func: 49       Pack: GetDataPack
  2421.  
  2422.      This routine gets a byte from the Sound Blasters data channel. This routine
  2423.      should not be called while the Sound Blaster is playing or record. It can
  2424.      be used for level tests.
  2425.  
  2426.      Before using this routine on the PRO, first select the input device (mic,
  2427.      CD, or line) and then perform a 64-byte record from that device. This
  2428.      because the input device is not selected until you actually record from it.
  2429.  
  2430.      Unlike the other RUCKDAC routines, the return value is not the error code,
  2431.      but rather the data byte itself. To check for an error, use GDP.stat (as
  2432.      you can in all RUCKUS functions).
  2433.  
  2434.      Sample Use:
  2435.  
  2436.      struct GetDataPack GDP;
  2437.  
  2438.      GDP.Func = GetDacSB;
  2439.      data = RUCKDAC(&GDP);
  2440.      if (GDP.stat != 0) 
  2441.        // error 
  2442.  
  2443.  
  2444.  
  2445.  
  2446.  
  2447.  
  2448.  
  2449.  
  2450.  
  2451.  
  2452.  
  2453.  
  2454.  
  2455.  
  2456.  
  2457.  
  2458.  
  2459.  
  2460.  
  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.      ExitMod             Func: 50       Pack: XitPack
  2488.  
  2489.      When using RUCKUS, certain aspects of the computer are controlled by the
  2490.      RUCKUS code. To have RUCKUS return full control back to the computer and
  2491.      operating system, ExitMod must be called. To ensure that this happens, even
  2492.      after an abnormal termination (such as an untrapped divide by zero), RUCKUS
  2493.      also provides a routine that ensures that ExitMod is always called before
  2494.      your application ends and returns to the operating system. See AtExitMod
  2495.      for more.
  2496.  
  2497.      Once you have loaded a mod file via LoadMod, or performed any mod function,
  2498.      you must call ExitMod before you end you program and return to DOS. Calling
  2499.      ExitMod releases any memory allocations made, and also performs other
  2500.      system cleanup.
  2501.  
  2502.      Sample Use:
  2503.  
  2504.      struct XitPack XP;
  2505.  
  2506.      XP.Func = ExitMod;
  2507.      rez = RUCKDAC(&XP);
  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.      AtExitMod           Func: 51       Pack: XitPack
  2555.  
  2556.      To ensure that all machine control is returned to the operating system and
  2557.      that all RUCKUS-made memory allocations are released, before your
  2558.      application program ends, AtExitMod should be used (if you have used the
  2559.      mod extensions to RUCKUS-DAC). This routine takes advantage of most
  2560.      compiler's _atexit enregistration routine. This _atexit compiler run-time
  2561.      library routine allows for up to 32 different calls to be made just prior
  2562.      to it (the compiler's run-time code) returning to the operating system
  2563.      (program termination). Most of the time, you can make all the necessary
  2564.      shutdowns that your program requires in your app's code. However, abnormal
  2565.      terminations--terminations that can cause a bypass of your own shutdown
  2566.      code, may mean that when the operating systems regains control, certain
  2567.      machine operations are not in a stable state. The AtExitMod routine ensures
  2568.      that ExitMod is called no matter what (in most all cases, except where the
  2569.      program locks up, in which case the session needs to be reset anyway). 
  2570.  
  2571.      Graphically, your program executes like this:
  2572.  
  2573.         DOS C>program.exe
  2574.           |
  2575.         Compiler startup code (performs basic setup)
  2576.           |
  2577.           +----->+
  2578.                  | Your program starts, ends
  2579.           +<-----+
  2580.           |   
  2581.          rest of startup code, _atexit registered routines
  2582.           |
  2583.          DOS C>_
  2584.  
  2585.      Caution: In order for the _atexit registered routines to be called by your
  2586.      compilers run-time, you must not allow you program to exit via non-standard
  2587.      ways. Calling INT21/4C is on example (you should never do this from
  2588.      compiled code, anyway).
  2589.  
  2590.      The startup code is basically a program that sets up your program to run,
  2591.      calls your program, regains control when your program ends, then performs
  2592.      the necessary shutdown actions required, including calling all routines
  2593.      registered with _atexit. See AtExitDac for an important addition.
  2594.  
  2595.      Sample Use:
  2596.  
  2597.      struct XitPack XP;
  2598.  
  2599.      XP.Func = AtExitMod;
  2600.      rez = RUCKDAC(&XP);
  2601.      if (rez != 0)
  2602.         puts("_atexit is full (more than 32 calls made to _atexit)");
  2603.  
  2604.  
  2605.  
  2606.  
  2607.  
  2608.  
  2609.                                                                               39
  2610.  
  2611.  
  2612.  
  2613.  
  2614.  
  2615.  
  2616.  
  2617.  
  2618.  
  2619.  
  2620.  
  2621.      LoadMod             Func: 52       Pack: LoadPack
  2622.  
  2623.      It is required that RUCKUS load mod files into memory. RUCKUS makes the
  2624.      necessary memory allocations and loads the data into conventional memory,
  2625.      with UMB blocks used if available and controlled by DOS (via DOS=,UMB in
  2626.      CONFIG.SYS). Only one mod file may be in memory at any one time. To unload
  2627.      the mod file you must execute an ExitMod call.
  2628.  
  2629.      LoadMod can be instructed to start loading at any particular byte in a
  2630.      file. This would be useful, for example, if you have a single file made up
  2631.      of several mod files, appended to form one large data file.
  2632.  
  2633.      Sample Use:
  2634.  
  2635.      struct LoadPack LP;
  2636.  
  2637.      LP.Func = LoadMod;
  2638.      LP.FilenamePtr = filename;
  2639.      LP.StartPos = 0L;  // start load at first byte of file
  2640.      LP.LoadSize = 0L;  // have RUCKUS load all of it
  2641.      LP.XMMflag = 0;    // this must be set to zero
  2642.      rez = RUCKDAC(&LP);
  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.  
  2682.  
  2683.  
  2684.  
  2685.  
  2686.  
  2687.  
  2688.      PlayMod             Func: 53       Pack: PlayBackPack
  2689.  
  2690.      Once the mod file has been loaded, you can play it to any of the RUCKUS-
  2691.      supported devices. There are 4 modes that can be used for playback; non-DMA
  2692.      foreground, non-DMA background, DMA foreground, and DMA background. The DMA
  2693.      modes require the Sound Blasters. Also, for STEREO mod playback, DMA mode
  2694.      is required (SB Pro only).
  2695.  
  2696.      Playing in the background allows your computer program to regain control
  2697.      immediately after play has begun. If you choose foreground play, control
  2698.      does not return to your program until the end of the data has been played,
  2699.      or, until CTRL-ALT is pressed. In all cases, mod file playback is best done
  2700.      on a fast computer, though excellent results can be gotten from 286-class
  2701.      machines. For slow machines, DMA foreground allows for best sound, since
  2702.      you can set the mod process rate higher than you can if you choose a
  2703.      background mode.  
  2704.  
  2705.      Before play, you should set up other parameters by calling the other Set
  2706.      mod routines (SetIntRateMod, SetStereoMod, and SetFastMod).
  2707.  
  2708.      NOTE: SOME MACHINES ARE NOT ABLE TO HANDLE BACKGROUND DMA MODE AT HIGH 
  2709.            RATES, EVEN ON 486-CLASS MACHINES. HOWEVER, BOTH MY 486/33 AND
  2710.            MY 286/16 WORK WELL IN THIS MODE. THE 486/33 CAN PROCESS MOD DATA
  2711.            AT RATES UP TO THE PRO'S MAX, 45,500Hz. THE 286/16 CAN PROCESS UP 
  2712.            TO 16kHz IN THIS MODE AND 22kHz IN DMA FOREGROUND. A 286/6 HAS 
  2713.            BEEN TESTED TO 8kHz (DMA FOREGROUND) AND PERFORMS WELL. A 12MHz
  2714.            DID 16kHz. ON SLOWER MACHINES, USING A LARGER DMA BUFFER SIZE
  2715.            AND A HIGHER DMAX: VALUE ALLOWS FOR HIGHER RATES TO BE ACHIEVED.
  2716.            IT IS POSSIBLE TO LOCK UP A MACHINE IF TOO HIGH A RATE IS ATTEMPTED.
  2717.  
  2718.      struct PlaybackPack PBP;
  2719.  
  2720.      PBP.Func = PlayMod;
  2721.      PBP.Mode = 3;      // mode 0=foreground, 1=background, 2=DMA FG, 3=DMA BG
  2722.      PBP.XMMhandle = 0; // this must be set to 0
  2723.  
  2724.      // PBP.LoadPtr is not used by PlayMod
  2725.  
  2726.      PBP.BufferSize = 4096;// buffer size is bytes per buffer (2 buffers used)
  2727.                            // minimum size is 2048, maximum is 65520
  2728.                            // buffers allocated only if DMA play (mode=2 or 3)
  2729.      rez = RUCKDAC(&PBP);
  2730.      if (rez == 0)
  2731.         // if background mode then the mod data is playing now, but
  2732.         // if foreground mode, the play has ended by the time we get here
  2733.      else
  2734.         // play error (could be not enough memory for PBP.BufferSize)
  2735.  
  2736.  
  2737.  
  2738.  
  2739.  
  2740.  
  2741.  
  2742.  
  2743.                                                                               41
  2744.  
  2745.  
  2746.  
  2747.  
  2748.  
  2749.  
  2750.  
  2751.  
  2752.  
  2753.  
  2754.  
  2755.      EndMod              Func: 54       Pack: XitPack
  2756.  
  2757.      EndMod is used to end (stop) play on command. Once PlayMod has started, it
  2758.      continues to play in the background until either the end of the mod data
  2759.      has been reached, or you call this routine.
  2760.  
  2761.      Sample Use:
  2762.  
  2763.      struct XitPack XP;
  2764.  
  2765.      // LoadMod and PlayMod have already been called
  2766.      // see those routines for more information
  2767.  
  2768.      XP.Func = EndMod;     // if play is active this call
  2769.      rez = RUCKDAC(&XP);   // ends it
  2770.  
  2771.  
  2772.  
  2773.  
  2774.  
  2775.  
  2776.  
  2777.  
  2778.  
  2779.  
  2780.  
  2781.  
  2782.  
  2783.  
  2784.  
  2785.  
  2786.  
  2787.  
  2788.  
  2789.  
  2790.  
  2791.  
  2792.  
  2793.  
  2794.  
  2795.  
  2796.  
  2797.  
  2798.  
  2799.  
  2800.  
  2801.  
  2802.  
  2803.  
  2804.  
  2805.  
  2806.  
  2807.  
  2808.  
  2809.  
  2810.                                                                               42
  2811.  
  2812.  
  2813.  
  2814.  
  2815.  
  2816.  
  2817.  
  2818.  
  2819.  
  2820.  
  2821.  
  2822.      PauseMod            Func: 55       Pack: PausePack
  2823.  
  2824.      PauseMod allows you to temporarily pause and then restart a playback.
  2825.  
  2826.      Sample Use:
  2827.  
  2828.      struct PausePack PP;
  2829.  
  2830.      PP.Func = PauseMod;
  2831.      PP.Pause = 1;        // non-zero pauses, zero restarts
  2832.      rez = RUCKDAC(&PP);
  2833.  
  2834.  
  2835.  
  2836.  
  2837.  
  2838.  
  2839.  
  2840.  
  2841.  
  2842.  
  2843.  
  2844.  
  2845.  
  2846.  
  2847.  
  2848.  
  2849.  
  2850.  
  2851.  
  2852.  
  2853.  
  2854.  
  2855.  
  2856.  
  2857.  
  2858.  
  2859.  
  2860.  
  2861.  
  2862.  
  2863.  
  2864.  
  2865.  
  2866.  
  2867.  
  2868.  
  2869.  
  2870.  
  2871.  
  2872.  
  2873.  
  2874.  
  2875.  
  2876.  
  2877.                                                                               43
  2878.  
  2879.  
  2880.  
  2881.  
  2882.  
  2883.  
  2884.  
  2885.  
  2886.  
  2887.  
  2888.  
  2889.      SetIntRateMod       Func: 56       Pack: SetModPack
  2890.  
  2891.      SetIntRateMod, with respect to the mod extensions of RUCKUS, controls the
  2892.      mod data processing rate, which in turn, is the playback rate (the opposite
  2893.      of sample rate).
  2894.  
  2895.      A process rate of 22kHz should be considered a practical maximum. Higher
  2896.      process rates are possible (up to 45.5kHz with the PRO) but the improvement
  2897.      in sound quality over 22kHz is negligible (to me). If the machine is
  2898.      capable, a rate of at least 16kHz should be used. At this rate, sound is
  2899.      reasonably good sounding. Rates below 16kHz will most likely incur a high-
  2900.      pitched whistling noise that can be very annoying. Using the output filter
  2901.      of the SB PRO helps. The whistle is totally absent from the output of the
  2902.      Disney Sound Source (which internally plays at 7kHz regardless of the input
  2903.      stream rate). For PC speaker output, rates above 18kHz are not recommended.
  2904.      Best performance for the PC speaker is at 16kHz. The AdLib, being a very
  2905.      slow device when made to play digital data, has an effective top-end of
  2906.      about 13kHz. 
  2907.  
  2908.      When using the SB PRO in stereo mode, the mod process rate must not exceed
  2909.      45.5kHz/2, or 22.75kHz. This is a limitation of the Sound Blaster. In mono,
  2910.      you can run up to 45.5kHz if you have the muscle to do so (typically
  2911.      requires a 486, and a DMAX: setting of at least 4). Buffer sizes above 4K
  2912.      matter most on slower machines.
  2913.  
  2914.      Adjusting the mod processing while playing is permitted, though it's
  2915.      recommended to do so only when not.
  2916.  
  2917.      Sample Use:
  2918.  
  2919.      struct SetModPack SMP;
  2920.  
  2921.      SMP.Func = SetIntRateMod;
  2922.      SMP.IntRate = 22000;     
  2923.      rez = RUCKDAC(&SMP);
  2924.  
  2925.  
  2926.  
  2927.  
  2928.  
  2929.  
  2930.  
  2931.  
  2932.  
  2933.  
  2934.  
  2935.  
  2936.  
  2937.  
  2938.  
  2939.  
  2940.  
  2941.  
  2942.  
  2943.  
  2944.                                                                               44
  2945.  
  2946.  
  2947.  
  2948.  
  2949.  
  2950.  
  2951.  
  2952.  
  2953.  
  2954.  
  2955.  
  2956.      SetSpeedMod         Func: 57       Pack: SetModPack
  2957.  
  2958.      Temporarily increases or decreases the playback speed of the mod file
  2959.      playing. The basic speed of a mod, with regard to this routine, is 6.
  2960.      However, at any particular point in the mod file this can change.
  2961.  
  2962.      The speed range is 1 to 15, with 1 resulting in fast play, and 15 resulting
  2963.      in a very slow play.
  2964.  
  2965.      Sample Use:
  2966.  
  2967.      struct SetModPack SMP;
  2968.  
  2969.      SMP.Func = SetSpeedMod;
  2970.      SMP.Speed = 4;          // increase play by 33% over norm
  2971.      rez = RUCKDAC(&SMP);
  2972.  
  2973.  
  2974.  
  2975.  
  2976.  
  2977.  
  2978.  
  2979.  
  2980.  
  2981.  
  2982.  
  2983.  
  2984.  
  2985.  
  2986.  
  2987.  
  2988.  
  2989.  
  2990.  
  2991.  
  2992.  
  2993.  
  2994.  
  2995.  
  2996.  
  2997.  
  2998.  
  2999.  
  3000.  
  3001.  
  3002.  
  3003.  
  3004.  
  3005.  
  3006.  
  3007.  
  3008.  
  3009.  
  3010.  
  3011.                                                                               45
  3012.  
  3013.  
  3014.  
  3015.  
  3016.  
  3017.  
  3018.  
  3019.  
  3020.  
  3021.  
  3022.  
  3023.      SetVolumeMod        Func: 58       Pack: SetModPack
  3024.  
  3025.      SetVolumeMod controls each of the four mod digital output channels.
  3026.      Normally they would all be set to maximum (255). In order to adjust channel
  3027.      volume, FastMod mode must be off.
  3028.  
  3029.      Sample Use:
  3030.  
  3031.      struct SetModPack SMP;
  3032.  
  3033.      SMP.Func = SetVolumeMod;
  3034.      SMP.VolCh1 = 255;
  3035.      SMP.VolCh2 = 255;
  3036.      SMP.VolCh3 = 255;
  3037.      SMP.VolCh4 = 255;
  3038.      rez = RUCKDAC(&SMP);
  3039.  
  3040.  
  3041.  
  3042.  
  3043.  
  3044.  
  3045.  
  3046.  
  3047.  
  3048.  
  3049.  
  3050.  
  3051.  
  3052.  
  3053.  
  3054.  
  3055.  
  3056.  
  3057.  
  3058.  
  3059.  
  3060.  
  3061.  
  3062.  
  3063.  
  3064.  
  3065.  
  3066.  
  3067.  
  3068.  
  3069.  
  3070.  
  3071.  
  3072.  
  3073.  
  3074.  
  3075.  
  3076.  
  3077.  
  3078.                                                                               46
  3079.  
  3080.  
  3081.  
  3082.  
  3083.  
  3084.  
  3085.  
  3086.  
  3087.  
  3088.  
  3089.  
  3090.      SetPositionMod      Func: 59       Pack: SetModPack
  3091.  
  3092.      Each mod file is composed of several tracks, known as patterns. Each
  3093.      pattern contains 64*4 notes (64 notes per channel). A mod file can contain
  3094.      up to 63 separate patterns, and can play up to 128 patterns in total
  3095.      (though any pattern can be made to repeat). SetPositionMod lets you move to
  3096.      the start of any pattern to be played (up to the number of patterns to
  3097.      play). The first pattern is pattern number 0. The last possible patter
  3098.      number is 127.
  3099.  
  3100.      Sample Use:
  3101.  
  3102.      struct SetModPack SMP;
  3103.  
  3104.      SMP.Func = SetPositionMod;
  3105.      SMP.Position = 0;          // restart play from the beginning
  3106.      rez = RUCKDAC(&SMP);
  3107.  
  3108.  
  3109.  
  3110.  
  3111.  
  3112.  
  3113.  
  3114.  
  3115.  
  3116.  
  3117.  
  3118.  
  3119.  
  3120.  
  3121.  
  3122.  
  3123.  
  3124.  
  3125.  
  3126.  
  3127.  
  3128.  
  3129.  
  3130.  
  3131.  
  3132.  
  3133.  
  3134.  
  3135.  
  3136.  
  3137.  
  3138.  
  3139.  
  3140.  
  3141.  
  3142.  
  3143.  
  3144.  
  3145.                                                                               47
  3146.  
  3147.  
  3148.  
  3149.  
  3150.  
  3151.  
  3152.  
  3153.  
  3154.  
  3155.  
  3156.  
  3157.      SetStereoMod        Func: 60       Pack: SetModPack
  3158.  
  3159.      Mod data files contain four channels of information. In mono playback mode,
  3160.      all four of these are combined to form a single digital output stream. In
  3161.      stereo mode (SB PRO only), you can select from three different combine
  3162.      modes. You can increase this to nine stereo combinations by setting the
  3163.      high bit of SMP.Stereo. If set, the left/right channels are reversed.
  3164.  
  3165.      Sample Use:
  3166.  
  3167.      struct SetModPack SMP;
  3168.  
  3169.      SMP.Func = SetPositionMod;
  3170.      SMP.Stereo = 1;          // 0=mono
  3171.      rez = RUCKDAC(&SMP);     // 1=LEFT:ch1+ch3  RIGHT:ch2+ch4
  3172.                               // 2=LEFT:ch1+ch4  RIGHT:ch2+ch3
  3173.                               // 3=LEFT:ch1+ch2  RIGHT:ch3+ch4
  3174.                               // &H8000 + mode then LEFT <-> RIGHT, e.g.,
  3175.                               // &H8001=LEFT:ch2+ch4  RIGHT:ch1+ch3
  3176.  
  3177.  
  3178.  
  3179.  
  3180.  
  3181.  
  3182.  
  3183.  
  3184.  
  3185.  
  3186.  
  3187.  
  3188.  
  3189.  
  3190.  
  3191.  
  3192.  
  3193.  
  3194.  
  3195.  
  3196.  
  3197.  
  3198.  
  3199.  
  3200.  
  3201.  
  3202.  
  3203.  
  3204.  
  3205.  
  3206.  
  3207.  
  3208.  
  3209.  
  3210.  
  3211.  
  3212.                                                                               48
  3213.  
  3214.  
  3215.  
  3216.  
  3217.  
  3218.  
  3219.  
  3220.  
  3221.  
  3222.  
  3223.  
  3224.      SetFastMod          Func: 61       Pack: SetModPack
  3225.  
  3226.      Mod files require lost of CPU power and lots of CPU attention. The most
  3227.      often executed code performs 4 BPTR IMUL instructions every tick of a
  3228.      process clock (10,000 times/sec if that is the process rate selected).
  3229.      Multiply on the 8088 is a very time consuming operation. If an 8088-based
  3230.      computer is to play mod files, these multiplies must be sped up. SetFastMod
  3231.      performs this task by implementing an alternate method. Note that with
  3232.      FastMod mode enable, some mod files may sound odd.
  3233.  
  3234.      The SliceAdj instructs the DMA buffer fill code to perform more than one
  3235.      mix per interrupt. By increasing this number you reduce the interrupt-
  3236.      latency time wasted (since more mod data is processed per interrupt) but
  3237.      you also decrease the amount of time given to other tasks (tasks other than
  3238.      mod playback). Fast CPUs have no problem keeping the DMA buffers full, so
  3239.      even a large SliceAdj will have little of any impact on these machines.
  3240.      However, on slow machines where the DMA buffers are constantly needing to
  3241.      be filled (where neither DMA buffer is ever filled) a SliceAdj above 1 may
  3242.      be desirable. Typically, though, the default of 1 works fine.
  3243.  
  3244.      Sample Use:
  3245.  
  3246.      struct SetModPack SMP;
  3247.  
  3248.      SMP.Func = SetFastMod;
  3249.      SMP.FastMode = -1;      // 0=normal, 1=fast mode enabled, -1 to skip
  3250.      SMP.SliceAdj = 32;      // DMA buffer fill count (1-4096, default=1)
  3251.      rez = RUCKDAC(&SMP);
  3252.  
  3253.  
  3254.  
  3255.  
  3256.  
  3257.  
  3258.  
  3259.  
  3260.  
  3261.  
  3262.  
  3263.  
  3264.  
  3265.  
  3266.  
  3267.  
  3268.  
  3269.  
  3270.  
  3271.  
  3272.  
  3273.  
  3274.  
  3275.  
  3276.  
  3277.  
  3278.  
  3279.                                                                               49
  3280.  
  3281.  
  3282.  
  3283.  
  3284.  
  3285.  
  3286.  
  3287.  
  3288.  
  3289.  
  3290.  
  3291.      Appendix A. Tips and Tricks.
  3292.  
  3293.      See the RUCKUS-MIDI documenation.
  3294.  
  3295.  
  3296.  
  3297.  
  3298.  
  3299.  
  3300.  
  3301.  
  3302.  
  3303.  
  3304.  
  3305.  
  3306.  
  3307.  
  3308.  
  3309.  
  3310.  
  3311.  
  3312.  
  3313.  
  3314.  
  3315.  
  3316.  
  3317.  
  3318.  
  3319.  
  3320.  
  3321.  
  3322.  
  3323.  
  3324.  
  3325.  
  3326.  
  3327.  
  3328.  
  3329.  
  3330.  
  3331.  
  3332.  
  3333.  
  3334.  
  3335.  
  3336.  
  3337.  
  3338.  
  3339.  
  3340.  
  3341.  
  3342.  
  3343.  
  3344.  
  3345.  
  3346.                                                                               50
  3347.  
  3348.  
  3349.  
  3350.  
  3351.  
  3352.  
  3353.  
  3354.  
  3355.  
  3356.  
  3357.  
  3358.      Appendix B. Pack Structure.
  3359.  
  3360.      #pragma pack(1)
  3361.  
  3362.      int __far __pascal RUCKDAC(void __far *datapack);
  3363.  
  3364.      #define SysInfoDac      0
  3365.      #define InitDac         1
  3366.      #define ExitDac         2
  3367.      #define AtExitDac       3
  3368.      #define LoadDac         4
  3369.      #define PlayDac         5
  3370.      #define RecordDac       6
  3371.      #define StoreDac        7
  3372.      #define EndDac          8
  3373.      #define PauseDac        9
  3374.      #define DeallocDac      10
  3375.  
  3376.      #define SetAllDac       20
  3377.      #define SetVolumeDac    21
  3378.      #define SetIntRateDac   22
  3379.      #define SetPriorityDac  23
  3380.      #define GetBufferDataDac 28
  3381.      #define GetBytePosDac   29
  3382.  
  3383.      #define SetAllSBP       30
  3384.      #define SetVolMainSBP   31
  3385.      #define SetVolVocSBP    32
  3386.      #define SetLevelMicSBP  33
  3387.      #define SetLevelCDSBP   34
  3388.      #define SetLevelLineSBP 35
  3389.      #define SetFilterOutSBP 36
  3390.      #define SetFilterInSBP  37
  3391.      #define SetSourceSBP    38
  3392.      #define SetStereoSBP    39
  3393.  
  3394.      #define SetSpeakerSB    40
  3395.      #define GetMixerRegSBP  48
  3396.      #define GetDacSB        49
  3397.  
  3398.      #define ExitMod         50
  3399.      #define AtExitMod       51
  3400.      #define LoadMod         52
  3401.      #define PlayMod         53
  3402.      #define EndMod          54
  3403.      #define PauseMod        55
  3404.      #define SetIntRateMod   56
  3405.      #define SetSpeedMod     57
  3406.      #define SetVolumeMod    58
  3407.      #define SetPositionMod  59
  3408.      #define SetStereoMod    60
  3409.      #define SetFastMod      61
  3410.      /* current highest function is 61 */
  3411.  
  3412.  
  3413.                                                                               51
  3414.  
  3415.  
  3416.  
  3417.  
  3418.  
  3419.  
  3420.  
  3421.  
  3422.  
  3423.  
  3424.  
  3425.  
  3426.      struct DeallocPack {    /* DP */
  3427.       unsigned Func;
  3428.       int Stat;
  3429.       unsigned HandSeg;      /* RUCKUS allocates either XMM handle/DOS para */
  3430.       unsigned TypeFlag;     /* 0=DOS para, 1=XMS handle */
  3431.      }; /* 8 */
  3432.  
  3433.      struct GetDataPack {    /* GDP */
  3434.       unsigned Func;
  3435.       int Stat;
  3436.       unsigned long BytePos; /* current byte relative base ptr */
  3437.       char __far *BufferPtr; /* far pointer to buffer to fill with data */
  3438.       long StartPos;         /* start get at this offset relative BufferPtr */
  3439.       unsigned BufferCnt;    /* bytes to fill (2-65520) */
  3440.       unsigned MixerReg;     /* SBPro mixer register to get */
  3441.      }; /* 20 */
  3442.  
  3443.      struct InitPack {       /* IP */
  3444.       unsigned Func;
  3445.       int Stat;
  3446.       unsigned DeviceID;     /* 0=SPKR,1=LPTDAC,2=DSS,4=SB,5=SBPro */
  3447.       unsigned IOport;
  3448.       unsigned IRQline;
  3449.       unsigned DMAch;
  3450.       unsigned Flags;        /* see Appendix D. */
  3451.       void __far *InfoPtr;     /* ret:far ptr to dac info */
  3452.       void __far *DacExitPtr;  /* ret:far ptr to dac's ExitDac routine */
  3453.       void __far *ModExitPtr;  /* ret:far ptr to mod's ExitMod routine */
  3454.      }; /* 26 */
  3455.  
  3456.      struct LoadPack {       /* LP */
  3457.       unsigned Func;
  3458.       int Stat;
  3459.       void __far *FilenamePtr;/* far ptr to filenameZ to load */
  3460.       unsigned long StartPos; /* offset into file to start load at */
  3461.       unsigned long LoadSize; /* number of bytes to load (or 0 for autosize) */
  3462.       int XMMflag;            /* if <> 0 use XMS for load */
  3463.       int XMMhandle;          /* ret:XMS handle, or */
  3464.       void __far *LoadPtr;    /* ret:DOS seg:offset (offset always 0) */
  3465.      }; /* 24 */
  3466.  
  3467.      struct PlaybackPack {   /* PBP */
  3468.       unsigned Func;
  3469.       int Stat;
  3470.       unsigned Mode;         /* mode (0=int FG,1=BG,2=DMA,3=DMA+BG for mod) */
  3471.       unsigned XMMhandle;    /* if <> 0 this XMM handle used regardless */
  3472.       void __far *LoadPtr;   /* seg:off to start of data to play */
  3473.       unsigned BufferSize;   /* size of DMA buffer for mod playback */
  3474.      }; /* 14 */
  3475.  
  3476.  
  3477.  
  3478.  
  3479.  
  3480.                                                                               52
  3481.  
  3482.  
  3483.  
  3484.  
  3485.  
  3486.  
  3487.  
  3488.  
  3489.  
  3490.  
  3491.  
  3492.  
  3493.      struct PausePack {      /* PP */
  3494.       unsigned Func;
  3495.       int Stat;
  3496.       unsigned Pause;        /* 0=unpause else pause */
  3497.      }; /* 6 */
  3498.  
  3499.      struct RecordPack {     /* RP */
  3500.       unsigned Func;
  3501.       int Stat;
  3502.       unsigned SampleRate;
  3503.       int XMMhandle;         /* -1 auto XMS (ret here) else use this handle */
  3504.       void __far *RecordPtr; /* seg:off of buffer to store (0 for auto-store) */
  3505.       unsigned long RecordBytes; /* bytes to record */
  3506.       unsigned StereoFlag;   /* stereo flag */
  3507.      }; /* 18 */
  3508.  
  3509.      struct SaveDataPack {   /* SDP */
  3510.       unsigned Func;
  3511.       int Stat;
  3512.       void __far *FilenamePtr; /* far ptr to filenameZ to save */
  3513.       void __far *DataPtr;   /* pointer to start of data to save */
  3514.       unsigned FileType;     /* 1=VOC,2=WAV */
  3515.       unsigned XMMhandle;    /* XMS handle of data to save (0 if DOS data) */
  3516.      }; /* 16 */
  3517.  
  3518.      struct SetPack {        /* SP */
  3519.       unsigned Func;
  3520.       int Stat;              /* (if volume=0 SB speaker off'ed else on'ed) */
  3521.       unsigned Volume;       /* volume (left ch=MSB,right=LSB) (0-127,0-127) */
  3522.       unsigned IntRate;      /* playback interrupt rate (5000-23000) */
  3523.       unsigned Priority;     /* priority level (0-2, default=1) */
  3524.      }; /* 10 */
  3525.  
  3526.      struct SetModPack {     /* SMP */
  3527.       unsigned Func;
  3528.       int Stat;
  3529.       unsigned VolCh1;       /* channel volume (0-255) */
  3530.       unsigned VolCh2;       /* channel volumes adjustments made only */
  3531.       unsigned VolCh3;       /*  if FastMode=0 */
  3532.       unsigned VolCh4;
  3533.       unsigned Stereo;       /* playback mode (0=mono,stereo 1,2,3) */
  3534.       int FastMode;          /* fast playback (0=normal,1 fast,-1 skip) */
  3535.       unsigned IntRate;      /* playback interrupt rate (5000-45500) */
  3536.       unsigned Position;     /* pattern list position (0-patterns to play) */
  3537.       unsigned Speed;        /* temp playback speed (1-15,default=6,15=slow) */
  3538.       unsigned SliceAdj;     /* slice adj (1-4096,default=1) set via FastMod */
  3539.      }; /* 24 */
  3540.  
  3541.  
  3542.  
  3543.  
  3544.  
  3545.  
  3546.  
  3547.                                                                               53
  3548.  
  3549.  
  3550.  
  3551.  
  3552.  
  3553.  
  3554.  
  3555.  
  3556.  
  3557.  
  3558.  
  3559.  
  3560.      struct SetProPack {     /* SPP */
  3561.       unsigned Func;
  3562.       int Stat;
  3563.       unsigned Volume;       /* volume (low=right;0-15, high byte=left;0-15) */
  3564.       unsigned VolVoc;
  3565.       unsigned VolMic;       /* (mono only, 0-7) input level */
  3566.       unsigned VolCD;        /* input level (0-15,0-15) */
  3567.       unsigned VolLI;        /* input level (0-15,0-15) */
  3568.       unsigned FilterOut;    /* 0=filter off, 1=filter on */
  3569.       unsigned FilterIn;     /* 0=filter off, 1=3.2kHz, 2=8.8kHz */
  3570.       unsigned SourceIn;     /* 0=mic,1=CD,2=line */
  3571.       unsigned StereoIn;     /* 0=mono,1=stereo record */
  3572.      }; /* 22 */
  3573.  
  3574.      struct XitPack {        /* XP */
  3575.       unsigned Func;
  3576.       int Stat;
  3577.      }; /* 4 */
  3578.  
  3579.      struct SysDev {         /* SD (used by SysInfoPack below) */
  3580.       int Device;            /* =1 device available */
  3581.       unsigned Port;
  3582.       unsigned IRQ;
  3583.       unsigned DMA;
  3584.       unsigned Flags;        /* bit4=MIDI/3=XMS/2=DMA/1=REC/0=PLAY */
  3585.      }; /* 10 */
  3586.  
  3587.      struct SysInfoPack {    /* SIP */
  3588.       unsigned Func;
  3589.       int Stat;
  3590.       unsigned CPU;          /* CPU class (88,286,386,486) */
  3591.       unsigned CPUmode;      /* 0=real mode,1=PM,2=PM w/paging */
  3592.       unsigned MHz;          /* approx speed (5,20,33) */
  3593.       struct SysDev SD[6];
  3594.      }; /* 70 */
  3595.  
  3596.  
  3597.  
  3598.  
  3599.  
  3600.  
  3601.  
  3602.  
  3603.  
  3604.  
  3605.  
  3606.  
  3607.  
  3608.  
  3609.  
  3610.  
  3611.  
  3612.  
  3613.  
  3614.                                                                               54
  3615.  
  3616.  
  3617.  
  3618.  
  3619.  
  3620.  
  3621.  
  3622.  
  3623.  
  3624.  
  3625.  
  3626.      Appendix C. Compiler, Linker, and Call Use.
  3627.  
  3628.      Consult your development system's documentation on the use of external
  3629.      library files. For call use, see the example X*.c files.
  3630.  
  3631.  
  3632.  
  3633.  
  3634.  
  3635.  
  3636.  
  3637.  
  3638.  
  3639.  
  3640.  
  3641.  
  3642.  
  3643.  
  3644.  
  3645.  
  3646.  
  3647.  
  3648.  
  3649.  
  3650.  
  3651.  
  3652.  
  3653.  
  3654.  
  3655.  
  3656.  
  3657.  
  3658.  
  3659.  
  3660.  
  3661.  
  3662.  
  3663.  
  3664.  
  3665.  
  3666.  
  3667.  
  3668.  
  3669.  
  3670.  
  3671.  
  3672.  
  3673.  
  3674.  
  3675.  
  3676.  
  3677.  
  3678.  
  3679.  
  3680.  
  3681.                                                                               55
  3682.  
  3683.  
  3684.  
  3685.  
  3686.  
  3687.  
  3688.  
  3689.  
  3690.  
  3691.  
  3692.  
  3693.      Appendix D. RUCKUS-DAC Data Area.
  3694.  
  3695.      To access the DAC data area in your code:
  3696.  
  3697.           extern struct DacDataArea __pascal DACDATA;
  3698.           :
  3699.           printf("DACDATA DeviceID is %u", DACDATA.DeviceID);
  3700.  
  3701.      /* dac data area structure */
  3702.  
  3703.      #pragma pack(1)
  3704.  
  3705.      struct DacDataArea {
  3706.       unsigned DeviceID;     /* 0   ;device ID */
  3707.       unsigned IOport;       /* 2   ;port of device */
  3708.       unsigned IRQ;          /* 4   ;IRQ of device */
  3709.       unsigned DMA;          /* 6   ;DMA of device */
  3710.       unsigned Flags;        /* 8   ;bit0=1 use DOS UMB memory */
  3711.                              /*     ;bit1-3 reserved */
  3712.                              /*     ;bit4=1 force SBPro if SB15 (DSPtype=3) */
  3713.                              /*     ;       (but DSPversion remains same) */
  3714.                              /*     ;bit5=1 force XMS2 to be used */
  3715.                              /*     ;bit6=1 force dev speaker on until exit */
  3716.                              /*     ;bit7=1 force passed parms to be used */
  3717.                              /*     ;       Following values are ret bits */
  3718.                              /*     ;bit8=1 paging in force, no UMBs */
  3719.                              /*     ;bit9-15 reserved */
  3720.       unsigned End;          /* 10  ;=1 end of play (dac, not mod) */
  3721.       unsigned Pause;        /* 12  ;=1 pause play */
  3722.       unsigned EndOfMod;     /* 14  ;=1 end of mod play */
  3723.                              /*     (when dac@end AND dac@endmod   */
  3724.                              /*     ;both are 1 then play is done) */
  3725.       unsigned MemDOS;       /* 16  ;DOS memory available (in K) */
  3726.       unsigned MemXMM;       /* 18  ;XMS memory available (in K) */
  3727.       unsigned Type;         /* 20  ;digital file type (1=VOC,2=WAV,3=MOD) */
  3728.       unsigned MemUsed;      /* 22  ;memory used for last file load (in K) */
  3729.       unsigned SampleRate;   /* 24  ;sample rate currently playing */
  3730.       unsigned Stereo;       /* 26  ;stereo playback (data is stereo) */
  3731.       unsigned long VocLen;  /* 28  ;length of voc block (only current block) */
  3732.       void __far *VocPtrPtr; /* 32  ;pointer to pointer->current data */
  3733.       unsigned long RecordLen;/*36  ;length of recorded data */
  3734.      }; /* 40 */
  3735.  
  3736.      #pragma pack()
  3737.  
  3738.  
  3739.  
  3740.  
  3741.  
  3742.  
  3743.  
  3744.  
  3745.  
  3746.  
  3747.  
  3748.                                                                               56
  3749.  
  3750.  
  3751.  
  3752.  
  3753.  
  3754.  
  3755.  
  3756.  
  3757.  
  3758.  
  3759.  
  3760.      /*
  3761.      To access the MOD data area in your code:
  3762.  
  3763.           extern struct ModDataArea __pascal MODDATA;
  3764.           :
  3765.           printf("MODDATA Type is %u", MODDATA.Type);
  3766.      */
  3767.  
  3768.      struct ModDataArea {
  3769.  
  3770.       void __near *chInfoPtr;/* -2  ;near ptr to channel info (not listed) */
  3771.  
  3772.       unsigned Type;         /*  0  ;mod type (15 or 31 samples) */
  3773.       unsigned Samples;      /*  2  ;number of instrument samples in mod */
  3774.       unsigned HeaderSeg;    /*  4  ;header segment (aka sample info) */
  3775.       unsigned PatternSeg;   /*  6  ;pats' segment (1 to pats2play 1K pats) */
  3776.       unsigned SampleSeg[31];/*  8 (+62) ;list of sample segments */
  3777.  
  3778.       unsigned Stereo;       /* 70  ;=1 then play stereo (only SBPro can set) */
  3779.       unsigned FastMode;     /* 72  ;=1 then channel volume adjusts disabled */
  3780.  
  3781.       unsigned PatListPos;   /* 74  ;byte pos within mod@patterList (0-127) */
  3782.       unsigned NotePatPos;   /* 76  ;note pos within pattern 1K area (0-1008) */
  3783.                              /*     ;pattern#=patternList(patListPos) */
  3784.                              /*     ;note is at offset (pat#*1024)+notePatPos */
  3785.                              /*     ;-- in segment mod@patternSeg */
  3786.       unsigned HiPattern;    /* 78  ;highest pattern # to play/+1!/ (0-63) */
  3787.       unsigned Pats2play;    /* 80  ;pats to play (direct DOS file load here) */
  3788.       char PatternList[128]; /* 82  (+128) ;pattern positions (to here) */
  3789.       char MKoverflow[6];    /*210 (+6)   ;overflow for 31-instr patpos read */
  3790.  
  3791.       unsigned MemUsed;      /*216 ;DOS mem needed by mod file loaded (paras) */
  3792.       unsigned long VS;      /*218 ;times VS handler entered (50Hz rate) */
  3793.      }; /* 222 */
  3794.  
  3795.      #pragma pack()
  3796.  
  3797.  
  3798.  
  3799.  
  3800.  
  3801.  
  3802.  
  3803.  
  3804.  
  3805.  
  3806.  
  3807.  
  3808.  
  3809.  
  3810.  
  3811.  
  3812.  
  3813.  
  3814.  
  3815.                                                                               57
  3816.  
  3817.  
  3818.  
  3819.  
  3820.  
  3821.  
  3822.  
  3823.  
  3824.  
  3825.  
  3826.  
  3827.      Appendix Z. Ordering Information, License Agreement and Product Support.
  3828.  
  3829.      To order you must you the order form included with the distribution files.
  3830.      Its filename is !ORDER.FRM. Orders made without this form may be delayed.
  3831.  
  3832.      There are two RUCKUS packages available. The PERSONAL DEVELOPER version is
  3833.      for the hobby-programmer while the PROFESSIONAL version is for the
  3834.      professional programmer.
  3835.  
  3836.      The PERSONAL DEVELOPER version is for persons that are not creating
  3837.      programs for distribution to others. With the PERSONAL DEVELOPER license
  3838.      you may not distribute any programs you create with RUCKUS. In addition, a
  3839.      sign-on banner is issued once, displaying the RUCKUS copyright and license
  3840.      restriction.
  3841.  
  3842.      The PROFESSIONAL version has no distribution restrictions on end-user
  3843.      programs you create with RUCKUS. The PROFESSIONAL license provides you with
  3844.      the right to create all the end-user programs royalty-free. You also have
  3845.      direct access to the latest version of RUCKUS free-of-charge by way of my
  3846.      support BBS and the RUCKUS Developer's Conference there. No sign-on banner
  3847.      is issued.
  3848.  
  3849.  
  3850.  
  3851.  
  3852.  
  3853.  
  3854.  
  3855.  
  3856.  
  3857.  
  3858.  
  3859.  
  3860.  
  3861.  
  3862.  
  3863.  
  3864.  
  3865.  
  3866.  
  3867.  
  3868.  
  3869.  
  3870.  
  3871.  
  3872.  
  3873.  
  3874.  
  3875.  
  3876.  
  3877.  
  3878.  
  3879.  
  3880.  
  3881.  
  3882.                                                                               58
  3883.  
  3884.  
  3885.  
  3886.  
  3887.  
  3888.  
  3889.  
  3890.  
  3891.  
  3892.  
  3893.  
  3894.      License Agreement
  3895.  
  3896.      Before using this software you must agree to the following:
  3897.  
  3898.      1. You are not allowed to operate more than one (1) copy of this software
  3899.      package at one time per license. This means that if you have 10 programmers 
  3900.      that COULD possibly use the RUCKUS library at the same time, you must also  
  3901.      have ten (10) RUCKUS licenses. 
  3902.  
  3903.      2. You are not allowed to distribute non-executable code containing RUCKUS 
  3904.      code. This means that you are not allowed to redistribute RUCKUS code as    
  3905.      another .LIB, for example. Also, if RUCKUS code is to be contained in a    
  3906.      Dynamic Link Library (DLL) then it must be part of a stand-alone product. 
  3907.      This means that you cannot provide a .DLL containing RUCKUS code if that    
  3908.      .DLL is to be used as a programming library for other programmers. If you   
  3909.      wish to distribute non-executable code containing RUCKUS code you must    
  3910.      obtain written permission from the author.
  3911.  
  3912.      3. This license grants you the right to use the RUCKUS library code on a   
  3913.      royalty-free basis, except when the license is the PERSONAL DEVELOPER, in
  3914.      which case you may not distribute any program in which RUCKUS has been
  3915.      used.
  3916.  
  3917.      4. RUCKUS is owned by the author, Cornel Huth, and is protected by United  
  3918.      States copyright laws and international treaty provisions. You are not    
  3919.      allowed to make copies of this software except for archival purposes.
  3920.  
  3921.      5. You may not rent or lease RUCKUS. You may not transfer this license
  3922.      without the written permission of the author. If this software is an update
  3923.      or upgrade, you may not sell or give away previous versions.
  3924.  
  3925.      6. You may not reverse engineer, decompile, or disassemble this software.
  3926.  
  3927.      7. There are no expressed or implied warranties with this software.
  3928.  
  3929.      8. All liabilities in the use of this software rest with the user.
  3930.  
  3931.      9. U.S. Government Restricted Rights. This software is provided with    
  3932.      restricted rights. Use, duplication, or disclosure by the Government is    
  3933.      subject to restrictions as set forth in subparagraph (c)(1)(ii) of the    
  3934.      Rights in Technical Data and Computer Software clause at 52.227-7013.    
  3935.      Manufacturer is Cornel Huth/6402 Ingram Rd/San Antonio, TX 78238.
  3936.  
  3937.      This agreement is governed by the laws of the state of Texas.
  3938.  
  3939.  
  3940.  
  3941.  
  3942.  
  3943.  
  3944.  
  3945.  
  3946.  
  3947.  
  3948.  
  3949.                                                                               59
  3950.  
  3951.  
  3952.  
  3953.  
  3954.  
  3955.  
  3956.  
  3957.  
  3958.  
  3959.  
  3960.  
  3961.      Product Support
  3962.  
  3963.      Support is available 7 days/week from 17:00 to 09:00 Central Time at my
  3964.      BBS: The Fortieth Floor at 1(210)684-8065.
  3965.  
  3966.      Internet and Fidonet addresses:
  3967.  
  3968.      Internet: chuth@lonestar.utsa.edu
  3969.             or cornel.huth@p8.f800.n387.z1.fidonet.org
  3970.       Fidonet: 1:387/800.8
  3971.  
  3972.      PROFESSIONAL version licensees have free access to all future RUCKUS
  3973.      updates and upgrades via the RUCKUS Developer's Conference on The Fortieth
  3974.      Floor BBS (1(210)684-8065). PERSONAL DEVELOPER licensees have restricted
  3975.      access to in-version maintenance updates at no charge.
  3976.  
  3977.      End of the RUCKUS-DAC DOCUMENT. See also the RUCKUS-MIDI DOCUMENT.
  3978.  
  3979.  
  3980.  
  3981.  
  3982.  
  3983.  
  3984.  
  3985.  
  3986.  
  3987.  
  3988.  
  3989.  
  3990.  
  3991.  
  3992.  
  3993.  
  3994.  
  3995.  
  3996.  
  3997.  
  3998.  
  3999.  
  4000.  
  4001.  
  4002.  
  4003.  
  4004.  
  4005.  
  4006.  
  4007.  
  4008.  
  4009.  
  4010.  
  4011.  
  4012.  
  4013.  
  4014.  
  4015.  
  4016.                                                                               60
  4017.  
  4018.  
  4019.  
  4020.  
  4021.