home *** CD-ROM | disk | FTP | other *** search
/ Audio 4.94 - Over 11,000 Files / audio-11000.iso / msdos / sndbords / sndblstr / sb_book / sbdisk.exe / SBDISK / SBSIM / SBSIMDMO.C < prev    next >
C/C++ Source or Header  |  1992-10-15  |  20KB  |  655 lines

  1. /************************************************************************
  2.  * SBSIM Demonstration                      *** MSC/TC ***
  3.  *
  4.  * Copyright (c) Creative Labs, Inc. 1992, 1993. All rights reserved
  5.  *
  6.  * Title: SBSIMDMO.C
  7.  *
  8.  * Description: This program demonstrates using the Sound Blaster
  9.  *     Simplified Interface Module (SBSIM) to play a CMF music file, a
  10.  *     MID music file, a VOC file from memory, and a VOC file from disk.
  11.  *     An option is also provided to change the volumes of each source.
  12.  *
  13.  *     This program requires the following Creative Labs drivers:
  14.  *     SBFMDRV.COM, SBMIDI.EXE, CT-VOICE.DRV, CTVDSK.DRV, and AUXDRV.DRV
  15.  *
  16.  ************************************************************************/
  17.  
  18. #include <dos.h>
  19. #include <stdio.h>
  20. #include <fcntl.h>
  21. #include <conio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include "sbsimdmo.h"
  25.  
  26. unsigned SIMint;                        // SBSIM's interrupt
  27. unsigned char memVocBuf[BUFSIZE];             // storage for memory VOC
  28. void main(void)
  29. {
  30.   unsigned Dvrs,
  31.            SIMver,
  32.            size,
  33.                      szRd,
  34.                      dataLoc,
  35.                      volume,
  36.                      type = -1;
  37.  
  38.     SOURCE source;
  39.  
  40.     int fhdl,
  41.             status[] = {STOPPED, STOPPED, STOPPED, STOPPED, STOPPED};
  42.     void far *entryAddr,
  43.              far *bufferAddr;
  44.     char *fileType[] = {"CMF", "DskVOC", "MemVOC", NULL, "MIDI"},
  45.              *statTxt[] = {"stopped   ", "playing   ", "paused   "};
  46.   char choice = 0;
  47.     SIMERR error;
  48.  
  49.     printf("\n\n\n");
  50.   printf("SBSIM Demonstration Program\n");
  51.   printf("---------------------------\n");
  52.   if((SIMint = FindSIM()) != 0)
  53.   {
  54.         printf("Using interrupt %xh\n", SIMint);
  55.         if((SIMver = QueryVersion()) >= VERSION)
  56.         {
  57.             printf("Version %d.%02d\n\n", HIBYTE(SIMver), LOBYTE(SIMver));
  58.  
  59.             Dvrs = QueryDrivers();
  60.             if((Dvrs != 0) & (Dvrs != 8))         // Check for drivers or Aux only
  61.             {
  62.                 printf("SBFMDRV.COM-------%s", (Dvrs & 1)? "loaded" : "missing");
  63.                 if(Dvrs & 1)
  64.                 {
  65.                     if(!(error = GetAddress(FM, &entryAddr)))
  66.                         printf("   Entry-%Fp", entryAddr);
  67.                     else
  68.                     {
  69.                         printf("Error #%d, GetAddress, %s\n", error, fileType[FM]);
  70.                         exit(EXIT_FAILURE);
  71.                     }
  72.                     if(!(error = GetBufferInfo(FM, &bufferAddr, &size)))
  73.                         printf("   Buffer-%Fp   Size-%u Kbytes\n", bufferAddr, size);
  74.                     else
  75.                     {
  76.                         printf("Error #%d, GetBufferInfo, %s\n", error, fileType[FM]);
  77.                         exit(EXIT_FAILURE);
  78.                     }
  79.                 }
  80.                 else
  81.                     printf("\n");
  82.  
  83.                 printf("CTVDSK.DRV--------%s", (Dvrs & 2)? "loaded" : "missing");
  84.  
  85.                 if(Dvrs & 2)
  86.                 {
  87.                     if(!(error = GetAddress(DskVoice, &entryAddr)))
  88.                         printf("   Entry-%Fp", entryAddr);
  89.                     else
  90.                     {
  91.                         printf("Error #%d, GetAddress, %s\n", error, fileType[DskVoice]);
  92.                         exit(EXIT_FAILURE);
  93.                     }
  94.                     if(!(error = GetBufferInfo(DskVoice, &bufferAddr, &size)))
  95.                         printf("   Buffer-%Fp   Size-%u Kbytes\n", bufferAddr, size);
  96.                     else
  97.                     {
  98.                         printf("Error #%d, GetBufferInfo, %s\n", error, fileType[DskVoice]);
  99.                         exit(EXIT_FAILURE);
  100.                     }
  101.                 }
  102.                 else
  103.                     printf("\n");
  104.  
  105.                 printf("CT-VOICE.DRV------%s", (Dvrs & 4 )? "loaded" : "missing");
  106.                 if(Dvrs & 4)
  107.                     if(!(error = GetAddress(MemVoice, &entryAddr)))
  108.                         printf("   Entry-%Fp\n", entryAddr);
  109.                     else
  110.                     {
  111.                         printf("Error #%d, GetAddress, %s\n", error, fileType[MemVoice]);
  112.                         exit(EXIT_FAILURE);
  113.                     }
  114.                 else
  115.                     printf("\n");
  116.  
  117.                 printf("AUXDRV.DRV--------%s", (Dvrs & 8 )? "loaded" : "missing");
  118.                 if(Dvrs & 8)
  119.                     if(!(error = GetAddress(AuxDrv, &entryAddr)))
  120.                         printf("   Entry-%Fp\n", entryAddr);
  121.                     else
  122.                     {
  123.                         printf("Error #%d, GetAddress, %s\n", error, fileType[AuxDrv]);
  124.                         exit(EXIT_FAILURE);
  125.                     }
  126.                 else
  127.                     printf("\n");
  128.  
  129.                 printf("SBMIDI.EXE--------%s", (Dvrs & 16)? "loaded" : "missing");
  130.                 if(Dvrs & 16)
  131.                 {
  132.                     if(!(error = GetAddress(Midi, &entryAddr)))
  133.                         printf("   Entry-%Fp", entryAddr);
  134.                     else
  135.                     {
  136.                         printf("Error #%d, GetAddress, %s\n", error, fileType[Midi]);
  137.                         exit(EXIT_FAILURE);
  138.                     }
  139.                     if(!(error = GetBufferInfo(Midi, &bufferAddr, &size)))
  140.                         printf("   Buffer-%Fp   Size-%u Kbytes\n\n", bufferAddr, size);
  141.                     else
  142.                     {
  143.                         printf("Error #%d, GetBufferInfo, %s\n", error, fileType[Midi]);
  144.                         exit(EXIT_FAILURE);
  145.                     }
  146.                 }
  147.                 else
  148.                     printf("\n");
  149.  
  150.                 printf("1. PLAY SOUND\n");
  151.                 printf("2. STOP SOUND\n");
  152.                 printf("3. PAUSE SOUND\n");
  153.                 printf("4. RESUME SOUND\n");
  154.                 printf("5. SET VOLUME\n");
  155.                 printf("6. QUIT\n\n");
  156.  
  157.                 if(Dvrs & 1)
  158.                 {
  159.                     printf("<C>MF File  ");
  160.                     if(StartSnd(FM, "TEST.CMF"))
  161.                     {
  162.                         printf("Error - \007unable to initialize CMF player");
  163.                         exit(EXIT_FAILURE);
  164.                     }
  165.                 }
  166.                 if(Dvrs & 2)
  167.                 {
  168.                     printf("<D>isk VOC file  ");
  169.                     if(StartSnd(DskVoice, "TEST1.VOC"))
  170.                     {
  171.                         printf("\nError - \007unable to initialize DskVOC player");
  172.                         exit(EXIT_FAILURE);
  173.                     }
  174.                 }
  175.                 if(Dvrs & 4)
  176.                 {
  177.                     printf("<M>emory VOC file  ");
  178.                     if(!_dos_open("TEST2.VOC",  O_BINARY|O_RDONLY, &fhdl))
  179.                     {
  180.                         if(_dos_read(fhdl, memVocBuf, 20, &szRd))      // seek to data offset
  181.                         {
  182.                             printf("\nError reading TEST2.VOC");
  183.                             exit(EXIT_FAILURE);
  184.                         }
  185.                         if(_dos_read(fhdl, &dataLoc, 2, &szRd))              // read data offset
  186.                         {
  187.                             printf("\nError reading TEST2.VOC");
  188.                             exit(EXIT_FAILURE);
  189.                         }
  190.                         if(_dos_read(fhdl, memVocBuf, dataLoc - 22, &szRd)) // seek to data
  191.                         {
  192.                             printf("\nError reading TEST2.VOC");
  193.                             exit(EXIT_FAILURE);
  194.                         }
  195.                         if(_dos_read(fhdl, memVocBuf, BUFSIZE, &szRd)) // load data
  196.                         {
  197.                             printf("\nError reading TEST2.VOC");
  198.                             exit(EXIT_FAILURE);
  199.                         }
  200.                         _dos_close(fhdl);                                                     // close file
  201.                     }
  202.                     else
  203.                     {
  204.                         printf("\nERROR - \007unable to open TEST2.VOC\n");
  205.                         exit(EXIT_FAILURE);
  206.                     }
  207.                     if(StartSnd(MemVoice, memVocBuf))
  208.                     {
  209.                         printf("\nError - \007unable to initialize MemVOC player");
  210.                         exit(EXIT_FAILURE);
  211.                     }
  212.                 }
  213.                 if(Dvrs & 16)
  214.                 {
  215.                     printf("M<I>DI file");
  216.                     if(StartSnd(Midi, "TEST.MID"))
  217.                     {
  218.                         printf("\nError - \007unable to initialize MIDI player");
  219.                         exit(EXIT_FAILURE);
  220.                     }
  221.                 }
  222.                 printf("\n\n");
  223.  
  224.                 // determine first sound driver loaded
  225.                 for(type = 0; !((Dvrs & 0x0f7) & (1 << type)); type++);
  226.  
  227.                 printf("\r[%s] %s", fileType[type], statTxt[status[type]]);
  228.  
  229.                 while(choice != '6')
  230.                     {
  231.                         while(!kbhit())                             // detect a keystroke
  232.                             // detect the ending of a file
  233.                             if((GetSndStat(type) == STOPPED) && (status[type] == PLAYING))
  234.                             {
  235.                                 status[type] = STOPPED;
  236.                                 printf("\r[%s] %s", fileType[type], statTxt[status[type]]);
  237.                             }
  238.                         choice = getch();                         // get keystroke
  239.                         switch(choice)
  240.                         {
  241.                             case '1':                   // Play sound
  242.                                 if(status[type] == PAUSED)
  243.                                 {
  244.                                     ResumeSnd(type);
  245.                                     status[type] = PLAYING;
  246.                                 }
  247.                                 else
  248.                                     if(status[type] == STOPPED)
  249.                                     {
  250.                                         if((error = PlaySnd(type)))
  251.                                         {
  252.                                             printf("\rError #%d, PlaySnd, %s\n", error, fileType[type]);
  253.                                             exit(EXIT_FAILURE);
  254.                                         }
  255.                                         status[type] = PLAYING;
  256.                                     }
  257.                                 break;
  258.                             case '2':                   // stop sound
  259.                                 if(status[type] == PAUSED)
  260.                                     ResumeSnd(type);
  261.                                 StopSnd(type);
  262.                                 status[type] = STOPPED;
  263.                                 break;
  264.                             case '3':                   // pause sound
  265.                                 if(status[type] != STOPPED)
  266.                                 {
  267.                                     PauseSnd(type);
  268.                                     status[type] = PAUSED;
  269.                                 }
  270.                                 break;
  271.                             case '4':                   // continue sound
  272.                                 if(status[type] == PAUSED)
  273.                                 {
  274.                                     ResumeSnd(type);
  275.                                     status[type] = PLAYING;
  276.                                 }
  277.                                 break;
  278.                             case '5':                   // set volume
  279.                                 source = ((type == FM) || (type == Midi))? SYNTH : VOICE;
  280.                                 if(!(error = GetVolume(source, &volume)))
  281.                                 {
  282.                                     printf("\r[%s] (%d, %d) ", fileType[type], volume >> 8,
  283.                                         volume & 0xff);
  284.                                     GetInputVol(&volume);
  285.                                     printf("\r                                  ");
  286.                                     if((error = SetVolume(source, volume)) != 0)
  287.                                         {
  288.                                             printf("\rError #%d, SetVolume, %s\n", error, fileType[type]);
  289.                                             exit(EXIT_FAILURE);
  290.                                         }
  291.                                 }
  292.                                 else
  293.                                 {
  294.                                     printf("\rError #%d, GetVolume, %s\n", error, fileType[type]);
  295.                                     exit(EXIT_FAILURE);
  296.                                 }
  297.                                 break;
  298.  
  299.                             case 'c':                   // select CMF
  300.                             case 'C':
  301.                                 if(Dvrs & 1)
  302.                                     type = FM;
  303.                                 break;
  304.                             case 'd':                   // select DskVoice
  305.                             case 'D':
  306.                                 if(Dvrs & 2)
  307.                                     type = DskVoice;
  308.                                 break;
  309.                             case 'm':                   // select MemVoice
  310.                             case 'M':
  311.                                 if(Dvrs & 4)
  312.                                     type = MemVoice;
  313.                                 break;
  314.                             case 'i':                   // select MIDI
  315.                             case 'I':
  316.                                 if(Dvrs & 16)
  317.                                     type = Midi;
  318.                                 break;
  319.                             default:
  320.                                 break;
  321.                         }
  322.                         printf("\r[%s] %s", fileType[type], statTxt[status[type]]);
  323.                     }
  324.             }
  325.             else
  326.                 printf("Error\007 - No sound drivers are loaded\n");
  327.         }
  328.         else
  329.             printf("Error\007 - SBSIM must be version 2.00 or later\n");
  330.     }
  331.     else
  332.         printf("Error\007 - Unable to locate SBSIM interrupt\n");
  333. }
  334.  
  335. /*************************************************************************
  336.  * FUNCTION: FINDSIM - Searches for SBSIM's interrupt.
  337.  *
  338.  * Inputs: none
  339.  *
  340.  * Output: interrupt number or 0 if not found.
  341.  *************************************************************************/
  342.  
  343. unsigned FindSIM(void)
  344. {
  345.     unsigned SIMint,
  346.              intFound = FALSE;
  347.  
  348.     char far *far *SIMvec;
  349.  
  350.     for(SIMint = 0x80; (SIMint < 0x0C0) && (intFound == FALSE); ++ SIMint)
  351.     {
  352.                 SIMvec = MK_FP(0, SIMint * 4);
  353.         if(!_fstrncmp((char far *)MK_FP(FP_SEG(*SIMvec), 0x103), "SBSIM", 5))
  354.             intFound = TRUE;
  355.     }
  356.  
  357.     if(intFound == TRUE)
  358.         return(--SIMint);
  359.     else
  360.         return(0);
  361. }
  362.  
  363. /*************************************************************************
  364.  * FUNCTION: QUERYVERSION - Get the current version of SBSIM.
  365.  *
  366.  * Inputs: none
  367.  *
  368.  * Output: version = high byte, sub-version = low byte.
  369.  *************************************************************************/
  370.  
  371. unsigned QueryVersion(void)
  372. {
  373.     union REGS inregs, outregs;
  374.  
  375.     inregs.h.bh = 0;                    // control function
  376.     inregs.h.bl = 0;                    // query version sub-fn
  377.     int86(SIMint, &inregs, &outregs);
  378.     return(outregs.x.ax);               // return version number
  379. }
  380.  
  381. /*************************************************************************
  382.  * FUNCTION: QUERYDRIVERS - Determines which drivers are loaded.
  383.  *
  384.  * Inputs: none
  385.  *
  386.  * Output: bit field indicating which drivers are loaded.
  387.  *
  388.  *         bit 0 - FM driver
  389.  *         bit 1 - Double disk buffered voice driver
  390.  *         bit 2 - Memory voice driver
  391.  *         bit 3 - Auxiliary driver (mixer)
  392.  *         bit 4 - MIDI driver
  393.  *************************************************************************/
  394.  
  395. unsigned QueryDrivers(void)
  396.  {
  397.     union REGS inregs, outregs;
  398.  
  399.     inregs.h.bh = 0;                    // control function
  400.     inregs.h.bl = 1;                    // query drivers sub-fn
  401.     int86(SIMint, &inregs, &outregs);
  402.     return(outregs.x.ax);               // return driver bit field
  403. }
  404.  
  405. /*************************************************************************
  406.  * FUNCTION: GETADDRESS - Returns selected driver's entry address.
  407.  *
  408.  * Inputs: driver   0 - FM driver
  409.  *                  1 - Double disk buffered voice driver
  410.  *                  2 - Memory voice driver
  411.  *                  3 - Auxiliary driver (mixer)
  412.  *                  4 - MIDI driver
  413.  *                 **address - storage for entry address pointer
  414.  *
  415.  * Output: 0 if no error.
  416.  *************************************************************************/
  417.  
  418. SIMERR GetAddress(DRIVER driver, void far **address)
  419. {
  420.     union REGS inregs, outregs;
  421.  
  422.     inregs.h.bh = 0;                    // control function
  423.     inregs.h.bl = 2;                    // driver entry address sub-fn
  424.         inregs.x.ax = driver;
  425.     int86(SIMint, &inregs, &outregs);
  426.         *address = MK_FP(outregs.x.dx, outregs.x.ax); // return address
  427.         if(!outregs.x.cflag)                                // test for errors
  428.             return(0);                                                // return result
  429.         else
  430.             return(outregs.x.ax);                         // error occured
  431. }
  432.  
  433. /*************************************************************************
  434.  * FUNCTION: GETBUFFERINFO - Returns selected driver's buffer address.
  435.  *
  436.  * Inputs: driver   0 - FM driver
  437.  *                  1 - Double disk buffered voice driver
  438.  *                  4 - MIDI driver
  439.  *                 **address - storage for buffer address pointer
  440.  *         *size - size of buffer in Kbytes
  441.  *
  442.  * Output: 0 if no error
  443.  *************************************************************************/
  444.  
  445. SIMERR GetBufferInfo(DRIVER driver, void far **address, unsigned *size)
  446. {
  447.     union REGS inregs, outregs;
  448.  
  449.     inregs.h.bh = 0;                    // control function
  450.     inregs.h.bl = 5;                    // driver entry address sub-fn
  451.         inregs.x.ax = driver;
  452.     int86(SIMint, &inregs, &outregs);
  453.         *address = MK_FP(outregs.x.dx, outregs.x.ax); // return address
  454.     *size = outregs.x.cx;               // return buffer size
  455.         if(!outregs.x.cflag)                                // test for errors
  456.             return(0);                                                // return result
  457.         else
  458.             return(outregs.x.ax);                         // error occured
  459. }
  460.  
  461. /*************************************************************************
  462.  * FUNCTION: STARTSND - Initializes the driver for output.
  463.  *
  464.  * Inputs: driver   0 - FM driver
  465.  *                  1 - Double disk buffered voice driver
  466.  *                                    2 - Memory voice driver
  467.  *                  4 - MIDI driver
  468.  *
  469.  * Output: Initialization result
  470.  *************************************************************************/
  471. SIMERR StartSnd(DRIVER driver, void far *ptr)
  472. {
  473.         union REGS inregs, outregs;
  474.  
  475.         inregs.h.bh = driver + 1;
  476.         inregs.h.bl = 0;                                        // start sound source function
  477.         inregs.x.ax = FP_OFF(ptr);                    // pointer to name or buffer
  478.         inregs.x.dx = FP_SEG(ptr);
  479.         int86(SIMint, &inregs, &outregs);
  480.         return(outregs.x.ax);                             // return initialization result
  481. }
  482.  
  483. /*************************************************************************
  484.  * FUNCTION: GETSNDSTAT - Get the driver's status.
  485.  *
  486.  * Inputs: driver   0 - FM driver
  487.  *                  1 - Double disk buffered voice driver
  488.  *                                    2 - Memory voice driver
  489.  *                  4 - MIDI driver
  490.  *
  491.  * Output: Current status
  492.  *************************************************************************/
  493. unsigned GetSndStat(DRIVER driver)
  494. {
  495.         union REGS inregs, outregs;
  496.  
  497.         inregs.h.bh = driver + 1;
  498.         inregs.h.bl = 5;                                        // get sound status function
  499.         int86(SIMint, &inregs, &outregs);
  500.         return(outregs.x.ax);                             // return status
  501. }
  502.  
  503. /*************************************************************************
  504.  * FUNCTION: PLAYSND - Plays music/voice on the selected driver.
  505.  *
  506.  * Inputs: driver   0 - FM driver
  507.  *                  1 - Double disk buffered voice driver
  508.  *                                    2 - Memory voice driver
  509.  *                  4 - MIDI driver
  510.  *
  511.  * Output: Result
  512.  *************************************************************************/
  513. SIMERR PlaySnd(DRIVER driver)
  514. {
  515.         union REGS inregs, outregs;
  516.  
  517.         inregs.h.bh = driver + 1;
  518.         inregs.h.bl = 1;                                        // play sound function
  519.         int86(SIMint, &inregs, &outregs);
  520.         return(outregs.x.ax);                             // return result
  521. }
  522.  
  523. /*************************************************************************
  524.  * FUNCTION: STOPSND - Stops music/voice on the selected driver.
  525.  *
  526.  * Inputs: driver   0 - FM driver
  527.  *                  1 - Double disk buffered voice driver
  528.  *                                    2 - Memory voice driver
  529.  *                  4 - MIDI driver
  530.  *
  531.  * Output: none
  532.  *************************************************************************/
  533. void StopSnd(DRIVER driver)
  534. {
  535.         union REGS inregs, outregs;
  536.  
  537.         inregs.h.bh = driver + 1;
  538.         inregs.h.bl = 2;                                        // stop sound function
  539.         int86(SIMint, &inregs, &outregs);
  540. }
  541.  
  542. /*************************************************************************
  543.  * FUNCTION: PAUSESND - Pauses music/voice on the selected driver.
  544.  *
  545.  * Inputs: driver   0 - FM driver
  546.  *                  1 - Double disk buffered voice driver
  547.  *                                    2 - Memory voice driver
  548.  *                  4 - MIDI driver
  549.  *
  550.  * Output: None
  551.  *************************************************************************/
  552. void PauseSnd(DRIVER driver)
  553. {
  554.         union REGS inregs, outregs;
  555.  
  556.         inregs.h.bh = driver + 1;
  557.         inregs.h.bl = 3;                                        // pause sound function
  558.         int86(SIMint, &inregs, &outregs);
  559. }
  560.  
  561. /*************************************************************************
  562.  * FUNCTION: RESUMESND - Continues paused music/voice.
  563.  *
  564.  * Inputs: driver   0 - FM driver
  565.  *                  1 - Double disk buffered voice driver
  566.  *                                    2 - Memory voice driver
  567.  *                  4 - MIDI driver
  568.  *
  569.  * Output: none
  570.  *************************************************************************/
  571. void ResumeSnd(DRIVER driver)
  572. {
  573.         union REGS inregs, outregs;
  574.  
  575.         inregs.h.bh = driver + 1;
  576.         inregs.h.bl = 4;                                        // resume sound function
  577.         int86(SIMint, &inregs, &outregs);
  578. }
  579.  
  580. /*************************************************************************
  581.  * FUNCTION: GETVOLUME - Get the source's volume.
  582.  *
  583.  * Inputs: source     0 - Master volume
  584.  *                                    1 - Voice volume
  585.  *                                    2 - FM volume
  586.  *                                    3 - CD volume
  587.  *                                    4 - Line-in volume
  588.  *                                    5 - Microphone volume
  589.  *                 *volume - storage for source's volume
  590.  *
  591.  * Output: 0 if no error
  592.  *************************************************************************/
  593. SIMERR GetVolume(SOURCE source, unsigned *volume)
  594. {
  595.         union REGS inregs, outregs;
  596.  
  597.         inregs.x.ax = source;
  598.         inregs.h.bh = 4;                                        // auxilary function
  599.         inregs.h.bl = 0;                                        // get source volume sub-function
  600.         int86(SIMint, &inregs, &outregs);
  601.         *volume = outregs.x.ax;                         // return volume
  602.         if(outregs.x.cflag)
  603.             return(outregs.x.ax);                         // return error code
  604.         else
  605.             return(0);
  606. }
  607.  
  608. /*************************************************************************
  609.  * FUNCTION: SETVOLUME - Set the source's volume.
  610.  *
  611.  * Inputs: source     0 - Master volume
  612.  *                                    1 - Voice volume
  613.  *                                    2 - FM volume
  614.  *                                    3 - CD volume
  615.  *                                    4 - Line-in volume
  616.  *                                    5 - Microphone volume
  617.  *                 volume - source's new volume
  618.  *
  619.  * Output: 0 if no error
  620.  *************************************************************************/
  621. SIMERR SetVolume(SOURCE source, unsigned volume)
  622. {
  623.         union REGS inregs, outregs;
  624.  
  625.         inregs.h.bh = 4;                                        // auxilary function
  626.         inregs.h.bl = 1;                                        // set source volume sub-function
  627.         inregs.x.ax = source;
  628.         inregs.x.dx = volume;
  629.         int86(SIMint, &inregs, &outregs);
  630.         return(outregs.x.ax);                             // return result
  631. }
  632.  
  633. void GetInputVol(unsigned *value)
  634. {
  635.     char buffer[80],
  636.              *ptr,
  637.              choice;
  638.     unsigned result,
  639.                      i = 0;
  640.  
  641.     while((choice = getch()) != 13)             // get input string and echo (no CR)
  642.     {
  643.         buffer[i++] = choice;
  644.         putch(choice);
  645.     }
  646.     buffer[i] = 0;                                                // terminate string
  647.     ptr = strtok(buffer, " ,\t");
  648.     if(ptr != NULL)
  649.         *((char *)value + 1) = atoi(ptr);     // get left channel setting
  650.     ptr = strtok(NULL, " ,\t");
  651.     if(ptr != NULL)
  652.         *(char *)value = atoi(ptr);                 // get right channel setting
  653. }
  654.  
  655.