home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 18 / CD_ASCQ_18_111294_W.iso / dos / prg / c / ruckus / xmplesrc / x02.c < prev    next >
C/C++ Source or Header  |  1994-02-26  |  11KB  |  350 lines

  1.  
  2. #include <dos.h>
  3. #include <conio.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <stdarg.h>
  7.  
  8. #include "ruckdac.h"
  9.  
  10. /*
  11. X02.c 27-Feb-94 chh
  12. Load & Play mod file
  13. removed the C7-specific _ all over the place
  14. */
  15.  
  16. /*
  17. The following structures are in ruckdac.h
  18. */
  19.  
  20. /*
  21. DACDATA is in DGROUP so could probably get away with a __near here dear
  22. */
  23.  
  24. #pragma pack(1)  /* must byte-align any Ruckus data structure */
  25.  
  26. extern struct DacDataArea pascal DACDATA;
  27.  
  28. struct SysInfoPack SIP;
  29. struct InitPack IP;
  30. struct XitPack XP;
  31. struct LoadPack LP;
  32. struct SetModPack SMP;
  33. struct SetProPack SPP;
  34. struct PlaybackPack PBP;
  35.  
  36. #pragma pack()
  37.  
  38. int rez, rez2;      /* result status codes */
  39. char nums[9] = {7}; /* number buffer for _cgets()*/
  40. char filename[81];  /* pathname to load */
  41.  
  42. /* typedef unsigned int uint; */
  43.  
  44. int pick_device(int *devID, unsigned int *HighRate)
  45. {
  46.  
  47.     /*
  48.     Just ask for device to use and return it and that device's effective
  49.     top-end rate (nothing concrete in the returned top-end...)
  50.     */
  51.  
  52.     int td=0;
  53.  
  54.     *HighRate = 0;
  55.  
  56.     SIP.Func = SysInfoDac;
  57.     rez = RUCKDAC(&SIP);
  58.     if (rez == 0) {
  59.         printf("CPU is a %u/%u\n",SIP.CPU,SIP.MHz);
  60.  
  61.         printf("\n0. End program");
  62.         printf("\n1. PC speaker at port 42h");
  63.         if (SIP.SD[1].device)
  64.             printf("\n2. LPT-DAC on LPT1, port %xh",SIP.SD[1].Port);
  65.         if (SIP.SD[2].device)
  66.             printf("\n3. Disney Sound Source port %xh",SIP.SD[2].Port);
  67.         if (SIP.SD[3].device)
  68.             printf("\n\n4. AdLib Music Synthesizer Card, port %xh",SIP.SD[3].Port);
  69.         if (SIP.SD[4].device)
  70.             printf("\n5. Sound Blaster, port %xh",SIP.SD[4].Port);
  71.         if (SIP.SD[5].device)
  72.             printf("\n6. Sound Blaster Pro, port %xh\n",SIP.SD[5].Port);
  73.  
  74.         /*
  75.         Can't play mods from XMS (well...)
  76.         BTW, if this code looks familiar, it's because it is (see X01.C)
  77.         */
  78.  
  79.         printf("\nSelection: ");
  80.     td = atoi(cgets(nums));
  81.         td--;   /* since devices are numbered 0 to 5 */
  82.  
  83.         if ((td >=0) && (td <=5)) { /* validate device selected available */
  84.             if (SIP.SD[td].device == 0)
  85.                 td = -1;
  86.         }
  87.         else
  88.             td = -1;
  89.  
  90.         switch (td) {
  91.         case 0:                     /* 0 - PC speaker     */
  92.             *HighRate = 18000;      /* 1 - LPT-DAC        */
  93.             break;                  /* 2 - Sound Source   */
  94.         case 1:                     /* 3 - AdLib          */
  95.             *HighRate = 23000;      /* 4 - Sound Blaster  */
  96.             break;                  /* 5 - Sound Blaster Pro ((STEREO)) */
  97.         case 2:
  98.             *HighRate = 7000;
  99.             break;
  100.         case 3:
  101.             *HighRate = 12000;
  102.             break;
  103.         case 4:
  104.             *HighRate = 23000;
  105.             break;
  106.         case 5:
  107.             *HighRate = 22750;  /* ((STEREO)) 2*22750=45500Hz*/
  108.             break;
  109.         default:
  110.             td=-1;
  111.         }
  112.     }
  113.  
  114.     *devID = td;
  115.     return(rez);
  116. }
  117.  
  118.  
  119. int init_device(int devID)
  120. {
  121.     /*
  122.     Initialize RUCKDAC and device and register ExitMod with _atexit.
  123.     Mod play does not have a hi-rez mode for PC speaker & AdLib as does Dac.
  124.     */
  125.  
  126.     IP.Func = InitDac;
  127.     IP.DeviceID = devID;
  128.     IP.IOport = SIP.SD[devID].Port;
  129.     IP.IRQline = SIP.SD[devID].IRQ;
  130.     IP.DMAch = SIP.SD[devID].DMA;
  131.  
  132.     rez = RUCKDAC(&IP);                 /* Initialize */
  133.     if (rez == 0) {
  134.         XP.Func = AtExitMod;            /* Try this with based pointers */
  135.         rez2 = RUCKDAC(&XP);            /* in use...could be a C7 bug   */
  136.         if (rez2 != 0) {                /* since _atexit seems to share */
  137.                                         /* (overwrite) memory used by   */
  138.                                         /* the compiler's __based data  */
  139.                                         /* Could just be me...  `       */
  140.             printf("AtExitMod failed, press Enter to continue");
  141.             getchar();
  142.         }
  143.     }
  144.     return(rez);
  145. }
  146.  
  147.  
  148. int main()
  149. {
  150.  
  151.     int devID=-1;
  152.     unsigned int HighRate=5000, SampleRate=5000;
  153.  
  154.     printf("X02.C - RUCKUS-DAC play of MOD file example. [930228]\n");
  155.  
  156.     rez = pick_device(&devID, &HighRate);
  157.     if (devID >= 0) {
  158.         printf("Initializing devID %u\n",devID);
  159.         rez = init_device(devID);
  160.  
  161.         /*
  162.         The following load and play example source is coded inline here
  163.         to simply readability -- but it's so easy to add things that I just
  164.         kept adding stuff, so take it slow if you don't follow at first
  165.         */
  166.  
  167.         if (rez == 0) {
  168.  
  169.             /* load file and setup playback parameters */
  170.  
  171.             printf("\n MOD filename: ");
  172.             gets(filename);
  173.             printf("\n                      (5000-%u)",HighRate);
  174.             printf("\rPlayback rate: ");
  175.         SampleRate = atoi(cgets(nums));
  176.             if (SampleRate < 5000)
  177.                 SampleRate = 5000;
  178.             if (SampleRate > HighRate)
  179.                 SampleRate = HighRate;
  180.  
  181.             LP.Func = LoadMod;
  182.             LP.FilenamePtr = filename;
  183.             LP.StartPos = 0L;           /* start at first byte */
  184.             LP.LoadSize = 0L;           /* autoload entire file */
  185.             LP.XMMflag = 0;             /* LP.XMMflag always=0 */
  186.             rez = RUCKDAC(&LP);
  187.             if (rez == 0) {
  188.  
  189.                /*
  190.                Increase SB Pro main and vol volumes to max (we bad now)
  191.                */
  192.  
  193.                if (devID == 5) {
  194.                   SPP.Func = SetVolMainSBP;
  195.                   SPP.Volume = 0x0F0F;
  196.                   rez2 = RUCKDAC(&SPP);
  197.                   SPP.Func = SetVolVocSBP;
  198.                   SPP.VolVoc = 0x0F0F;
  199.                   rez2 = RUCKDAC(&SPP);
  200.                }
  201.  
  202.                 /*
  203.                 set mod channel volumes to max
  204.                 */
  205.  
  206.                 SMP.VolCh1 = 255;
  207.                 SMP.VolCh2 = 255;
  208.                 SMP.VolCh3 = 255;
  209.                 SMP.VolCh4 = 255;
  210.                 SMP.Func = SetVolumeMod;
  211.                 rez2 = RUCKDAC(&SMP);  /* always error check! */
  212.  
  213.                 /*
  214.                 if SB Pro play in stereo
  215.                 */
  216.  
  217.                 if (devID < 5)
  218.                     SMP.Stereo = 0;
  219.                 else
  220.                     SMP.Stereo = 1;
  221.                 SMP.Func = SetStereoMod;
  222.                 rez2 = RUCKDAC(&SMP);
  223.  
  224.                 SMP.IntRate = SampleRate;
  225.  
  226.                 /*
  227.                 The SB Pro doubles the sample rate when doing stereo output
  228.                 so here we double the requested rate to rate needed by SBPro.
  229.                 This should be done _AFTER_ the SetStereoMod call above
  230.                 */
  231.  
  232.                 if (SMP.Stereo !=0)
  233.                     /* double rate if stereo */
  234.                     SMP.IntRate = SampleRate + SampleRate;
  235.  
  236.                 SMP.Func = SetIntRateMod;
  237.                 rez2 = RUCKDAC(&SMP);
  238.  
  239.                 /*
  240.                 SetFastMod can be used to play at higher rates than would
  241.                 otherwise be possible. The default is FastMod off and
  242.                 SliceAdj=1. On XTs, FastMod=1 may make the difference
  243.                 between being able to play mods at all. The SliceAdj is
  244.                 the number of bytes processed and stuffed into the DMA
  245.                 buffers per timer interrrupt. The default is typically
  246.                 sufficient to keep the DMA buffers full on fast machines,
  247.                 but on slower CPUs, a higher SliceAdj will make for a
  248.                 higher playback rate allowable. Actually, the code below
  249.                 doesn't change the defaults so I'll comment it out.
  250.                 Play around with the settings if you need to. (SliceAdj
  251.                 is relevant for DMA devices only, like the Sound Blasters.)
  252.                 */
  253.  
  254.                 SMP.Func = SetFastMod;
  255.                 SMP.FastMode = -1;      /* skip fastmode adjust */
  256.                 SMP.SliceAdj = 1;       /* default = 1, range 1-4096 */
  257.                 /* rez1 = RUCKDAC(&SMP) */
  258.  
  259.  
  260.                 /*
  261.                 if DMA device use DMA foreground processing, else timer-0 FG
  262.                 */
  263.  
  264.                 PBP.Func = PlayMod;
  265.                 if (devID < 4)
  266.                     PBP.Mode = 0;
  267.                 else
  268.                     PBP.Mode = 2;
  269.  
  270.                 /*
  271.                 For timer-0 background play set PBP.Mode = 1 and for
  272.                 DMA background play set PBP.Mode = 3 -- you must also poll
  273.                 DACDATA.EndOfMod and wait until it is non-zero to determine
  274.                 if mod playback has completed
  275.                 */
  276.  
  277.                 /*
  278.                 For complete compatibility mod play is done as a
  279.                 foreground task in this example.
  280.                 */
  281.  
  282.                 printf("Playing as a foreground ");
  283.                 if (devID >= 4)
  284.                     printf("DMA");
  285.                 else
  286.                     printf("TIMER-0");
  287.  
  288.                 printf(" task ");
  289.                 if (devID == 5)
  290.                     printf("in ((STEREO)) ");
  291.  
  292.                 printf("at %u Hz mix rate\n\n", SampleRate);
  293.                 printf("Press CTRL-ALT to end or wait until tune is over.\n");
  294.  
  295.                 /*
  296.                 Note that the PC speaker playback may sound better if the
  297.                 keyboard pause button is activated, try it
  298.                 */
  299.  
  300.                 PBP.XMMhandle = 0;   /* just because */
  301.  
  302.                 /*
  303.                 Note that PBP.LoadPtr is not used with mod playback since
  304.                 only one mod can be in memory at a time. The BufferSize below
  305.                 is allocated for DMA devices only (i.e., it's disreagard if
  306.                 PBP.Mode < 2) and 2 buffers are setup. For example, if
  307.                 PBP.BufferSize=4096, 2 4K buffers are allocated. 4096 works
  308.                 well in most cases (range is 2048 to 65520 bytes) and
  309.                 larger buffer size is usually needed only for slow CPUs with
  310.                 high playback rates.
  311.                 */
  312.  
  313.                 PBP.BufferSize = 4096;
  314.                 rez = RUCKDAC(&PBP);
  315.  
  316.                 /*
  317.                 Since PBP.Mode is a foreground mode, we don't get here
  318.                 until CTRL-ALT is pressed or the tune is over. Since
  319.                 that's so, we EndMod. If doing a background mode, then
  320.                 we go off and do whatever we want, but must periodically
  321.                 check DACDATA.EndOfMod for non-zero, in which case the tune
  322.                 is over.
  323.                 */
  324.  
  325.                 if (rez==0) {
  326.                     XP.Func = EndMod;
  327.                     rez2 = RUCKDAC(&XP);
  328.  
  329.                     /*
  330.                     To release memory used by LoadMod use ExitMod
  331.                     */
  332.                 }
  333.                 else
  334.                     printf("Play failed, %i\n",rez);
  335.             }
  336.             else
  337.                 printf("Load failed, %i\n",rez);
  338.         }
  339.         else
  340.             printf("Initialization of device %u failed, %i\n",devID,rez);
  341.     }
  342.     else
  343.         puts("Device pick failed");
  344.  
  345. XP.Func = ExitMod;
  346. rez = RUCKDAC(&XP);
  347. return(rez);
  348.  
  349. }
  350.