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 >
Wrap
C/C++ Source or Header
|
1992-10-15
|
20KB
|
655 lines
/************************************************************************
* SBSIM Demonstration *** MSC/TC ***
*
* Copyright (c) Creative Labs, Inc. 1992, 1993. All rights reserved
*
* Title: SBSIMDMO.C
*
* Description: This program demonstrates using the Sound Blaster
* Simplified Interface Module (SBSIM) to play a CMF music file, a
* MID music file, a VOC file from memory, and a VOC file from disk.
* An option is also provided to change the volumes of each source.
*
* This program requires the following Creative Labs drivers:
* SBFMDRV.COM, SBMIDI.EXE, CT-VOICE.DRV, CTVDSK.DRV, and AUXDRV.DRV
*
************************************************************************/
#include <dos.h>
#include <stdio.h>
#include <fcntl.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include "sbsimdmo.h"
unsigned SIMint; // SBSIM's interrupt
unsigned char memVocBuf[BUFSIZE]; // storage for memory VOC
void main(void)
{
unsigned Dvrs,
SIMver,
size,
szRd,
dataLoc,
volume,
type = -1;
SOURCE source;
int fhdl,
status[] = {STOPPED, STOPPED, STOPPED, STOPPED, STOPPED};
void far *entryAddr,
far *bufferAddr;
char *fileType[] = {"CMF", "DskVOC", "MemVOC", NULL, "MIDI"},
*statTxt[] = {"stopped ", "playing ", "paused "};
char choice = 0;
SIMERR error;
printf("\n\n\n");
printf("SBSIM Demonstration Program\n");
printf("---------------------------\n");
if((SIMint = FindSIM()) != 0)
{
printf("Using interrupt %xh\n", SIMint);
if((SIMver = QueryVersion()) >= VERSION)
{
printf("Version %d.%02d\n\n", HIBYTE(SIMver), LOBYTE(SIMver));
Dvrs = QueryDrivers();
if((Dvrs != 0) & (Dvrs != 8)) // Check for drivers or Aux only
{
printf("SBFMDRV.COM-------%s", (Dvrs & 1)? "loaded" : "missing");
if(Dvrs & 1)
{
if(!(error = GetAddress(FM, &entryAddr)))
printf(" Entry-%Fp", entryAddr);
else
{
printf("Error #%d, GetAddress, %s\n", error, fileType[FM]);
exit(EXIT_FAILURE);
}
if(!(error = GetBufferInfo(FM, &bufferAddr, &size)))
printf(" Buffer-%Fp Size-%u Kbytes\n", bufferAddr, size);
else
{
printf("Error #%d, GetBufferInfo, %s\n", error, fileType[FM]);
exit(EXIT_FAILURE);
}
}
else
printf("\n");
printf("CTVDSK.DRV--------%s", (Dvrs & 2)? "loaded" : "missing");
if(Dvrs & 2)
{
if(!(error = GetAddress(DskVoice, &entryAddr)))
printf(" Entry-%Fp", entryAddr);
else
{
printf("Error #%d, GetAddress, %s\n", error, fileType[DskVoice]);
exit(EXIT_FAILURE);
}
if(!(error = GetBufferInfo(DskVoice, &bufferAddr, &size)))
printf(" Buffer-%Fp Size-%u Kbytes\n", bufferAddr, size);
else
{
printf("Error #%d, GetBufferInfo, %s\n", error, fileType[DskVoice]);
exit(EXIT_FAILURE);
}
}
else
printf("\n");
printf("CT-VOICE.DRV------%s", (Dvrs & 4 )? "loaded" : "missing");
if(Dvrs & 4)
if(!(error = GetAddress(MemVoice, &entryAddr)))
printf(" Entry-%Fp\n", entryAddr);
else
{
printf("Error #%d, GetAddress, %s\n", error, fileType[MemVoice]);
exit(EXIT_FAILURE);
}
else
printf("\n");
printf("AUXDRV.DRV--------%s", (Dvrs & 8 )? "loaded" : "missing");
if(Dvrs & 8)
if(!(error = GetAddress(AuxDrv, &entryAddr)))
printf(" Entry-%Fp\n", entryAddr);
else
{
printf("Error #%d, GetAddress, %s\n", error, fileType[AuxDrv]);
exit(EXIT_FAILURE);
}
else
printf("\n");
printf("SBMIDI.EXE--------%s", (Dvrs & 16)? "loaded" : "missing");
if(Dvrs & 16)
{
if(!(error = GetAddress(Midi, &entryAddr)))
printf(" Entry-%Fp", entryAddr);
else
{
printf("Error #%d, GetAddress, %s\n", error, fileType[Midi]);
exit(EXIT_FAILURE);
}
if(!(error = GetBufferInfo(Midi, &bufferAddr, &size)))
printf(" Buffer-%Fp Size-%u Kbytes\n\n", bufferAddr, size);
else
{
printf("Error #%d, GetBufferInfo, %s\n", error, fileType[Midi]);
exit(EXIT_FAILURE);
}
}
else
printf("\n");
printf("1. PLAY SOUND\n");
printf("2. STOP SOUND\n");
printf("3. PAUSE SOUND\n");
printf("4. RESUME SOUND\n");
printf("5. SET VOLUME\n");
printf("6. QUIT\n\n");
if(Dvrs & 1)
{
printf("<C>MF File ");
if(StartSnd(FM, "TEST.CMF"))
{
printf("Error - \007unable to initialize CMF player");
exit(EXIT_FAILURE);
}
}
if(Dvrs & 2)
{
printf("<D>isk VOC file ");
if(StartSnd(DskVoice, "TEST1.VOC"))
{
printf("\nError - \007unable to initialize DskVOC player");
exit(EXIT_FAILURE);
}
}
if(Dvrs & 4)
{
printf("<M>emory VOC file ");
if(!_dos_open("TEST2.VOC", O_BINARY|O_RDONLY, &fhdl))
{
if(_dos_read(fhdl, memVocBuf, 20, &szRd)) // seek to data offset
{
printf("\nError reading TEST2.VOC");
exit(EXIT_FAILURE);
}
if(_dos_read(fhdl, &dataLoc, 2, &szRd)) // read data offset
{
printf("\nError reading TEST2.VOC");
exit(EXIT_FAILURE);
}
if(_dos_read(fhdl, memVocBuf, dataLoc - 22, &szRd)) // seek to data
{
printf("\nError reading TEST2.VOC");
exit(EXIT_FAILURE);
}
if(_dos_read(fhdl, memVocBuf, BUFSIZE, &szRd)) // load data
{
printf("\nError reading TEST2.VOC");
exit(EXIT_FAILURE);
}
_dos_close(fhdl); // close file
}
else
{
printf("\nERROR - \007unable to open TEST2.VOC\n");
exit(EXIT_FAILURE);
}
if(StartSnd(MemVoice, memVocBuf))
{
printf("\nError - \007unable to initialize MemVOC player");
exit(EXIT_FAILURE);
}
}
if(Dvrs & 16)
{
printf("M<I>DI file");
if(StartSnd(Midi, "TEST.MID"))
{
printf("\nError - \007unable to initialize MIDI player");
exit(EXIT_FAILURE);
}
}
printf("\n\n");
// determine first sound driver loaded
for(type = 0; !((Dvrs & 0x0f7) & (1 << type)); type++);
printf("\r[%s] %s", fileType[type], statTxt[status[type]]);
while(choice != '6')
{
while(!kbhit()) // detect a keystroke
// detect the ending of a file
if((GetSndStat(type) == STOPPED) && (status[type] == PLAYING))
{
status[type] = STOPPED;
printf("\r[%s] %s", fileType[type], statTxt[status[type]]);
}
choice = getch(); // get keystroke
switch(choice)
{
case '1': // Play sound
if(status[type] == PAUSED)
{
ResumeSnd(type);
status[type] = PLAYING;
}
else
if(status[type] == STOPPED)
{
if((error = PlaySnd(type)))
{
printf("\rError #%d, PlaySnd, %s\n", error, fileType[type]);
exit(EXIT_FAILURE);
}
status[type] = PLAYING;
}
break;
case '2': // stop sound
if(status[type] == PAUSED)
ResumeSnd(type);
StopSnd(type);
status[type] = STOPPED;
break;
case '3': // pause sound
if(status[type] != STOPPED)
{
PauseSnd(type);
status[type] = PAUSED;
}
break;
case '4': // continue sound
if(status[type] == PAUSED)
{
ResumeSnd(type);
status[type] = PLAYING;
}
break;
case '5': // set volume
source = ((type == FM) || (type == Midi))? SYNTH : VOICE;
if(!(error = GetVolume(source, &volume)))
{
printf("\r[%s] (%d, %d) ", fileType[type], volume >> 8,
volume & 0xff);
GetInputVol(&volume);
printf("\r ");
if((error = SetVolume(source, volume)) != 0)
{
printf("\rError #%d, SetVolume, %s\n", error, fileType[type]);
exit(EXIT_FAILURE);
}
}
else
{
printf("\rError #%d, GetVolume, %s\n", error, fileType[type]);
exit(EXIT_FAILURE);
}
break;
case 'c': // select CMF
case 'C':
if(Dvrs & 1)
type = FM;
break;
case 'd': // select DskVoice
case 'D':
if(Dvrs & 2)
type = DskVoice;
break;
case 'm': // select MemVoice
case 'M':
if(Dvrs & 4)
type = MemVoice;
break;
case 'i': // select MIDI
case 'I':
if(Dvrs & 16)
type = Midi;
break;
default:
break;
}
printf("\r[%s] %s", fileType[type], statTxt[status[type]]);
}
}
else
printf("Error\007 - No sound drivers are loaded\n");
}
else
printf("Error\007 - SBSIM must be version 2.00 or later\n");
}
else
printf("Error\007 - Unable to locate SBSIM interrupt\n");
}
/*************************************************************************
* FUNCTION: FINDSIM - Searches for SBSIM's interrupt.
*
* Inputs: none
*
* Output: interrupt number or 0 if not found.
*************************************************************************/
unsigned FindSIM(void)
{
unsigned SIMint,
intFound = FALSE;
char far *far *SIMvec;
for(SIMint = 0x80; (SIMint < 0x0C0) && (intFound == FALSE); ++ SIMint)
{
SIMvec = MK_FP(0, SIMint * 4);
if(!_fstrncmp((char far *)MK_FP(FP_SEG(*SIMvec), 0x103), "SBSIM", 5))
intFound = TRUE;
}
if(intFound == TRUE)
return(--SIMint);
else
return(0);
}
/*************************************************************************
* FUNCTION: QUERYVERSION - Get the current version of SBSIM.
*
* Inputs: none
*
* Output: version = high byte, sub-version = low byte.
*************************************************************************/
unsigned QueryVersion(void)
{
union REGS inregs, outregs;
inregs.h.bh = 0; // control function
inregs.h.bl = 0; // query version sub-fn
int86(SIMint, &inregs, &outregs);
return(outregs.x.ax); // return version number
}
/*************************************************************************
* FUNCTION: QUERYDRIVERS - Determines which drivers are loaded.
*
* Inputs: none
*
* Output: bit field indicating which drivers are loaded.
*
* bit 0 - FM driver
* bit 1 - Double disk buffered voice driver
* bit 2 - Memory voice driver
* bit 3 - Auxiliary driver (mixer)
* bit 4 - MIDI driver
*************************************************************************/
unsigned QueryDrivers(void)
{
union REGS inregs, outregs;
inregs.h.bh = 0; // control function
inregs.h.bl = 1; // query drivers sub-fn
int86(SIMint, &inregs, &outregs);
return(outregs.x.ax); // return driver bit field
}
/*************************************************************************
* FUNCTION: GETADDRESS - Returns selected driver's entry address.
*
* Inputs: driver 0 - FM driver
* 1 - Double disk buffered voice driver
* 2 - Memory voice driver
* 3 - Auxiliary driver (mixer)
* 4 - MIDI driver
* **address - storage for entry address pointer
*
* Output: 0 if no error.
*************************************************************************/
SIMERR GetAddress(DRIVER driver, void far **address)
{
union REGS inregs, outregs;
inregs.h.bh = 0; // control function
inregs.h.bl = 2; // driver entry address sub-fn
inregs.x.ax = driver;
int86(SIMint, &inregs, &outregs);
*address = MK_FP(outregs.x.dx, outregs.x.ax); // return address
if(!outregs.x.cflag) // test for errors
return(0); // return result
else
return(outregs.x.ax); // error occured
}
/*************************************************************************
* FUNCTION: GETBUFFERINFO - Returns selected driver's buffer address.
*
* Inputs: driver 0 - FM driver
* 1 - Double disk buffered voice driver
* 4 - MIDI driver
* **address - storage for buffer address pointer
* *size - size of buffer in Kbytes
*
* Output: 0 if no error
*************************************************************************/
SIMERR GetBufferInfo(DRIVER driver, void far **address, unsigned *size)
{
union REGS inregs, outregs;
inregs.h.bh = 0; // control function
inregs.h.bl = 5; // driver entry address sub-fn
inregs.x.ax = driver;
int86(SIMint, &inregs, &outregs);
*address = MK_FP(outregs.x.dx, outregs.x.ax); // return address
*size = outregs.x.cx; // return buffer size
if(!outregs.x.cflag) // test for errors
return(0); // return result
else
return(outregs.x.ax); // error occured
}
/*************************************************************************
* FUNCTION: STARTSND - Initializes the driver for output.
*
* Inputs: driver 0 - FM driver
* 1 - Double disk buffered voice driver
* 2 - Memory voice driver
* 4 - MIDI driver
*
* Output: Initialization result
*************************************************************************/
SIMERR StartSnd(DRIVER driver, void far *ptr)
{
union REGS inregs, outregs;
inregs.h.bh = driver + 1;
inregs.h.bl = 0; // start sound source function
inregs.x.ax = FP_OFF(ptr); // pointer to name or buffer
inregs.x.dx = FP_SEG(ptr);
int86(SIMint, &inregs, &outregs);
return(outregs.x.ax); // return initialization result
}
/*************************************************************************
* FUNCTION: GETSNDSTAT - Get the driver's status.
*
* Inputs: driver 0 - FM driver
* 1 - Double disk buffered voice driver
* 2 - Memory voice driver
* 4 - MIDI driver
*
* Output: Current status
*************************************************************************/
unsigned GetSndStat(DRIVER driver)
{
union REGS inregs, outregs;
inregs.h.bh = driver + 1;
inregs.h.bl = 5; // get sound status function
int86(SIMint, &inregs, &outregs);
return(outregs.x.ax); // return status
}
/*************************************************************************
* FUNCTION: PLAYSND - Plays music/voice on the selected driver.
*
* Inputs: driver 0 - FM driver
* 1 - Double disk buffered voice driver
* 2 - Memory voice driver
* 4 - MIDI driver
*
* Output: Result
*************************************************************************/
SIMERR PlaySnd(DRIVER driver)
{
union REGS inregs, outregs;
inregs.h.bh = driver + 1;
inregs.h.bl = 1; // play sound function
int86(SIMint, &inregs, &outregs);
return(outregs.x.ax); // return result
}
/*************************************************************************
* FUNCTION: STOPSND - Stops music/voice on the selected driver.
*
* Inputs: driver 0 - FM driver
* 1 - Double disk buffered voice driver
* 2 - Memory voice driver
* 4 - MIDI driver
*
* Output: none
*************************************************************************/
void StopSnd(DRIVER driver)
{
union REGS inregs, outregs;
inregs.h.bh = driver + 1;
inregs.h.bl = 2; // stop sound function
int86(SIMint, &inregs, &outregs);
}
/*************************************************************************
* FUNCTION: PAUSESND - Pauses music/voice on the selected driver.
*
* Inputs: driver 0 - FM driver
* 1 - Double disk buffered voice driver
* 2 - Memory voice driver
* 4 - MIDI driver
*
* Output: None
*************************************************************************/
void PauseSnd(DRIVER driver)
{
union REGS inregs, outregs;
inregs.h.bh = driver + 1;
inregs.h.bl = 3; // pause sound function
int86(SIMint, &inregs, &outregs);
}
/*************************************************************************
* FUNCTION: RESUMESND - Continues paused music/voice.
*
* Inputs: driver 0 - FM driver
* 1 - Double disk buffered voice driver
* 2 - Memory voice driver
* 4 - MIDI driver
*
* Output: none
*************************************************************************/
void ResumeSnd(DRIVER driver)
{
union REGS inregs, outregs;
inregs.h.bh = driver + 1;
inregs.h.bl = 4; // resume sound function
int86(SIMint, &inregs, &outregs);
}
/*************************************************************************
* FUNCTION: GETVOLUME - Get the source's volume.
*
* Inputs: source 0 - Master volume
* 1 - Voice volume
* 2 - FM volume
* 3 - CD volume
* 4 - Line-in volume
* 5 - Microphone volume
* *volume - storage for source's volume
*
* Output: 0 if no error
*************************************************************************/
SIMERR GetVolume(SOURCE source, unsigned *volume)
{
union REGS inregs, outregs;
inregs.x.ax = source;
inregs.h.bh = 4; // auxilary function
inregs.h.bl = 0; // get source volume sub-function
int86(SIMint, &inregs, &outregs);
*volume = outregs.x.ax; // return volume
if(outregs.x.cflag)
return(outregs.x.ax); // return error code
else
return(0);
}
/*************************************************************************
* FUNCTION: SETVOLUME - Set the source's volume.
*
* Inputs: source 0 - Master volume
* 1 - Voice volume
* 2 - FM volume
* 3 - CD volume
* 4 - Line-in volume
* 5 - Microphone volume
* volume - source's new volume
*
* Output: 0 if no error
*************************************************************************/
SIMERR SetVolume(SOURCE source, unsigned volume)
{
union REGS inregs, outregs;
inregs.h.bh = 4; // auxilary function
inregs.h.bl = 1; // set source volume sub-function
inregs.x.ax = source;
inregs.x.dx = volume;
int86(SIMint, &inregs, &outregs);
return(outregs.x.ax); // return result
}
void GetInputVol(unsigned *value)
{
char buffer[80],
*ptr,
choice;
unsigned result,
i = 0;
while((choice = getch()) != 13) // get input string and echo (no CR)
{
buffer[i++] = choice;
putch(choice);
}
buffer[i] = 0; // terminate string
ptr = strtok(buffer, " ,\t");
if(ptr != NULL)
*((char *)value + 1) = atoi(ptr); // get left channel setting
ptr = strtok(NULL, " ,\t");
if(ptr != NULL)
*(char *)value = atoi(ptr); // get right channel setting
}