home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 17 / CD_ASCQ_17_101194.iso / dos / prg / sphinx / examples / sblaster / sb_dma.c__ < prev    next >
Encoding:
Text File  |  1994-03-30  |  6.2 KB  |  295 lines

  1. /*
  2.    NAME:  SB_DMA.C--
  3.    Copyright (C) 1994  Michael B. Martin
  4.  
  5.    Output a raw sample to SB DAC using DMA mode.
  6.  
  7.    Uses SB_GET_PARAMS() and SB_INIT().
  8.  
  9.    30 Mar 1994:  Small modifications by SPHINX.
  10. */
  11.  
  12. ?parsecommandline TRUE
  13. ?resize FALSE             // we'll do it ourselves
  14. ?assumeDSSS TRUE
  15.  
  16. ?include "WRITE.H--"
  17. ?include "DOS.H--"
  18. ?include "STRING.H--"
  19. ?include "KEYCODES.H--"
  20. ?include "SYSTEM.H--"
  21.  
  22. ?include "SB.H--"
  23. ?include "SBDMA.H--"
  24.  
  25. ?define DEFAULT_VOL 9
  26. ?define BUFFER_SIZE 32000
  27.  
  28. word sl=0, sr=11000;
  29. byte stereo=FALSE;
  30. byte signed=FALSE;
  31. byte vol=-1;
  32. byte oldvol=0;
  33. byte done=FALSE;
  34. byte fast=FALSE;
  35. byte params=0;
  36. word i=0;
  37. word Buffer_Seg=0;
  38. word fhandle=0;
  39.  
  40. byte mem_str = "Can't allocate enough memory.\n"
  41.                "This program requires 192k free RAM.\n";
  42.  
  43. byte usage_str = "Usage: dacdma [-a] [-r rate] [-s] [-v volume] sample\n\n"
  44.                  "Switches:\n"
  45.                  "  -a  enables playback of signed (Amiga) samples\n"
  46.                  "  -r  sample rate in Hz (samples per second)\n"
  47.                  "  -s  enables stereo mode (SB Pro only)\n"
  48.                  "  -v  volume value can be 0 to 15 (SB Pro only)\n";
  49.  
  50. byte no_pro1 = "SB Pro not found: ignoring request for ";
  51.  
  52. void main()
  53. {
  54.  
  55.    /* first grab some memory for a buffer */
  56.    AX = CS;
  57.    $ SHR AX,12
  58.    $ ADD AL,2    // start at beginnning of next free (64k) page
  59.    $ SHL AX,12
  60.    Buffer_Seg = AX;
  61.    BX = CS;
  62.    AX -= BX;     // space before buffer seg
  63.    AX += 0x1000; // plus segment for data buffers
  64.    BX = AX;      // total (contiguous) space required
  65.  
  66.    IF (RESIZEMEM(CS,BX) != 0)
  67.    {
  68.       WRITESTR(#mem_str);
  69.       return();
  70.    }
  71.  
  72.    params = PARAMCOUNT();
  73.    IF (params == 0)
  74.    {
  75.       WRITESTR(#usage_str);
  76.       return();
  77.    }
  78.  
  79.    params--;     // assume last argument is file name (ignore for now)
  80.    if (params > 0)  // do we have switches?
  81.    {
  82.       do {
  83.          IF (STRCMP(PARAMSTR(i),"-s") == 0)
  84.          {
  85.             stereo = TRUE;
  86.             i++;
  87.          }
  88.          else IF (STRCMP(PARAMSTR(i),"-a") == 0)
  89.          {
  90.             signed = TRUE;
  91.             i++;
  92.          }
  93.          ELSE IF (STRCMP(PARAMSTR(i),"-r") == 0)
  94.          {
  95.             PARAMSTR(i+1);
  96.             SI = AX;
  97.             ES = CS;
  98.             sr = DIGITSTOWORD();
  99.             i+=2;
  100.          }
  101.          ELSE IF (STRCMP(PARAMSTR(i),"-v") == 0)
  102.          {
  103.             PARAMSTR(i+1);
  104.             SI = AX;
  105.             ES = CS;
  106.             AX = DIGITSTOWORD();
  107.             vol = AL;
  108.             i+=2;
  109.          }
  110.          ELSE
  111.          {
  112.             WRITESTR("Invalid parameter: \"");
  113.             WRITESTR(PARAMSTR(i));
  114.             WRITESTR("\"\n");
  115.         return();
  116.          }
  117.       } while (i < params);
  118.    }
  119.  
  120.    AX = PARAMSTR(i);
  121.    DX = AX;
  122.    FOPEN(0,,,DX);
  123.    IF (AX == 0)
  124.    {
  125.       WRITESTR("Couldn't open file.\n");
  126.       return();
  127.    }
  128.    fhandle = AX;
  129.  
  130.    IF (SB_GET_PARAMS() != 0)
  131.    {
  132.       WRITESTR("BLASTER environment variable not set.\n");
  133.       return();
  134.    }
  135.  
  136.    IF (SB_INIT() != 0)
  137.    {
  138.       WRITESTR("Could not find Sound Blaster!\n");
  139.       return();
  140.    }
  141.  
  142.    WRITESTR("Found Sound Blaster ");
  143.    IF (SbType == SBPro)
  144.       WRITESTR("Pro ");
  145.    WRITESTR("at address ");
  146.    WRITEHEX(SbIOaddr);
  147.    WRITESTR("h, IRQ ");
  148.    WRITEWORD(SbIRQ);
  149.    WRITESTR(", DMA channel ");
  150.    WRITEWORD(SbDMAchan);
  151.    WRITESTR(".\n");
  152.  
  153.    IF (SbType != SBPro)
  154.    {
  155.       IF (vol != -1)
  156.       {
  157.          WRITESTR(#no_pro1);
  158.          WRITESTR("volume control\n");
  159.       }
  160.    }
  161.    ELSE
  162.    {
  163.       IF (vol == -1)
  164.          vol = DEFAULT_VOL;   // set to default if user does not specify
  165.       IF (vol > 15)
  166.       {
  167.          WRITESTR("Maximum volume exceeded: setting to 15\n");
  168.          vol = 15;
  169.       }
  170.       AL = vol;
  171.       $ PUSH AX
  172.       AL <<= 4;
  173.       vol += AL;   // set both channels to same value
  174.  
  175.       oldvol = READMIXER(VOC_VOL);   // save previous value (to be nice)
  176.       WRITEMIXER(VOC_VOL,vol);
  177.  
  178.       WRITESTR("Volume is ");
  179.       $ POP AX
  180.       $ XOR AH,AH
  181.       WRITEWORD(AX);
  182.       WRITESTR(" (max: 15)\n");
  183.    }
  184.  
  185.    WRITESTR("Sample rate = ");
  186.    WRITEWORD(sr);
  187.    WRITESTR(" Hz\n");
  188.    IF (stereo == TRUE)
  189.    {
  190.       IF (SbType == SBPro)
  191.          WRITESTR("Output is stereo.\n");
  192.       ELSE
  193.       {
  194.          WRITESTR(#no_pro1);
  195.          WRITESTR("stereo\n");
  196.       }
  197.    }
  198.  
  199.    SB_SAMPLE_RATE(,sr);
  200.  
  201.    IF (sr > 23000)
  202.    {
  203.       fast = TRUE;
  204.       WRITESTR("Running in high-speed mode.\n");
  205.    }
  206.  
  207.    Sb_Init_Voice_DMA(0,0);   /* Use default interrupt handler */
  208.  
  209.    SB_VOICE(1);
  210.  
  211.    DMA_complete = TRUE;
  212.  
  213.   do {
  214.    $ PUSH DS
  215.    BX = fhandle;
  216.    DS = Buffer_Seg;
  217.    FREAD(,BX,BUFFER_SIZE,0);
  218.    $ POP DS
  219.    IF (AX == 0)
  220.    {
  221.       WRITESTR("Couldn't read in data\n");
  222.       return();
  223.    }
  224.    sl = AX;
  225.  
  226.    IF (signed == TRUE)
  227.    {
  228.       ES = Buffer_Seg;
  229.       SI = 0;
  230.       CX = sl;
  231.       loop(CX)
  232.       {
  233.          ESBYTE[SI] += 0x80;
  234.          SI++;
  235.       }
  236.    }
  237.  
  238.    do {
  239.       IF (BIOSKEYCHECK())
  240.       {
  241.          done = TRUE;
  242.      $ JMP END_LOOP
  243.       }
  244.    } while (SB_DMA_COMPLETE() == FALSE);
  245.  
  246.    IF (Sb_Out_Voice_DMA(Buffer_Seg,0,sl,stereo,fast) != 0)
  247.    {
  248.       WRITESTR("DMA Error: ");
  249.       BX = dma_errno;
  250.       $ SHL BX,1      // convert to word pointer
  251.       WRITESTR(dma_errlist[BX]);
  252.       $ JMP DMA_ERROR
  253.    }
  254.  
  255.    IF (sl < BUFFER_SIZE)      // last buffer
  256.    {
  257.       do {
  258.          IF (BIOSKEYCHECK())
  259.             done = TRUE;
  260.          IF (SB_DMA_COMPLETE())
  261.             done = TRUE;
  262.       } while (done == FALSE);
  263.    }
  264.    ELSE
  265.       $ XOR Buffer_Seg,BUFFER_SIZE/16   // swap buffers
  266. END_LOOP:
  267.   } while (done == FALSE);
  268.  
  269.    IF (SB_DMA_COMPLETE() == FALSE)
  270.    {
  271.       BIOSREADKEY();  // process the key the user pressed
  272.       WRITESTR("Halting DMA transfer...\n");
  273.       IF (fast == TRUE)
  274.          SB_INIT();     // only way to stop high-speed DMA transfers?
  275.       ELSE
  276.          SB_HALT_DMA();
  277.    }
  278.  
  279.    WRITESTR("Done.\n");
  280.  
  281. DMA_ERROR:
  282.    IF (SbType == SBPro)
  283.    {
  284.       WRITEMIXER(VOC_VOL,oldvol);   // reset to previous value
  285.    }
  286.  
  287.    SB_VOICE(0);
  288.    Sb_DeInit_Voice_DMA();
  289.  
  290.    FCLOSE(,fhandle);
  291.  
  292. NO_FILE:
  293. }
  294.  
  295. /* end of SB_DMA.C-- */