SBDRV.C - SB DRIVER FUNCTIONS V1.2 ================================== NOTE: There is some important information in the COMPILER REQUIREMENTS section. The SBDRV.C file includes a set of simple routines for generating audio output through a basic SB card, which should include all SB compatible cards. The routines are designed to use the low-speed DMA output feature of the SB card. The routines will automatically create the necessary buffers. The audio processing/mixing function will automatically be called from the ISR to provide a continuous stream of output. These functions have been designed to work with multiple compilers. They have already been tested with Borland C++ V3.1, MSVC V1.52, WATCOM V10.6 and DJGPP. The Borland and MSVC compilers used were 16-bit, while the WATCOM and DJGPP were 32-bit. A header file 'SBDRV.H' has been included for use in other modules, and provides the necessary function prototypes. The routines are easy to use. Detailed descriptions on the function calls are listed below. FEATURES -------- 1) Full support for IRQs 0-15. 2) Ability to adjust the Master, FM and VOC/WAV volumes (note: not supported by all cards). 2) Once started, the the sound IRQ automatically calls the audio processing function. No additional calls are required. 3) The audio processing/mixing function is passed in as a initialization parameter. This should allow the routines to be used in most applications without modification. 4) The routines support AUTO-INITIALIZE and STANDARD DMA modes of operation. This will allow good sound reproduction on the newer cards but still support the old cards. LIMITATIONS ----------- The SB Driver routines have several limitations. 1) The routines can support any DMA channel from 0 to 3. If any other DMA channel is needed, changes are required. This may need to be changed to support all SB cards. This should not be much of a concern, though, since DMA channels 4-7 are only used for 16-bit DMA operation. 2) The routines only support the low-speed DMA output function of the SB card, which limits the maximum playback to approximately 22KHz. 3) The routines only support 8-bit mono audio output. 4) The routines require that the 'BLASTER' environment variable be configured. This can be accomplished by using "SET BLASTER = A220 I7 D1" from the command line. The 'A' value is the base address of the card, the 'I' value is the configured interrupt line, and the 'D' value is the configured DMA channel. GENERAL OVERVIEW ---------------- On start-up of the system, a single call should be made to OpenSB. This routine will reset the SB, setup the interrupts and prepare the structures for sound output. This routine should not be called again until after the CloseSB function is called. On system shut-down, a single call should be made to CloseSB. This routine will reset the SB, disable the interrupts and free the structures that were created. Once the SB has been initialized, calling the Start_audio_output function will start the DMA operation. Once started, the sound output will be continuous; no other calls are required. The sound output will continue until either the Stop_audio_output or CloseSB functions are called. The Stop_audio_output function can be used to pause the output temporarily. COMPILER REQUIREMENTS --------------------- *** Probably the most important compiler option is the selection of the data segment/stack segment relationship. Because the IRQ will be calling the fillBuffer function from within the IRQ, the data segment and stack segment may not be equal. The compiler should be set to DS != SS. Without this option, a stack overflow, system lockup or other unusual problem will occur. Borland C++ 3.1 Notes --------------------- The memory model must be set to LARGE and the COMP16 logical must be defined. The DS/SS relationship can be left to 'default for memory model' since the LARGE model automatically sets DS != SS, or this option can be set to never. MSVC++ 1.5x ----------- The memory model must be set to LARGE and the segment setup must be set to 'DS != SS, DS loaded on function entry'. Extern and unitialized data should be assumed to be 'far'. Also, the COMP16 preprocessor symbol must be defined. WATCOM 10.6 ------------ The segment relationship must be set to DS != SS and stack probes must be removed. This is accomplished by using the /zu and /s compiler options. DJGPP ----- Actually, I'm not sure what's required. I just compiled it as GCC -o SBDRVTST.EXE SBDRVTST.C SBDRV.C and it worked. If you have problems you may want to contact Bradford Mott as he added DJGPP support. DETAILED FUNCTION DESCRIPTIONS ------------------------------ OpenSB (uint16 playback_freq, uint16 buffer_size) ------------------------------------------------- This function resets and initializes the SB, initializes and enables the interrupts, and creates and initializes all local global structures. This function takes two parameters: the playback frequency and the size of each playback buffer. The playback frequency can be any unsigned integer from 1-65535, though the maximum limit is currently set by the SB low-speed DMA audio routines (approx. 22KHz). The system will automatically allocate two playback buffers. The size of each buffer can be any value from 1 to 65535. The actual size needed will depend on the playback frequency and the DMA mode. If Auto-Initialize DMA mode will be used, the size of the buffer can be set as low as 35 or 40 with good output, though I don't recommend values lower than 100. If Standard DMA mode will be used, the minimum size that will produce clear output varies based on the sample frequency. At maximum freq (22kHz), the buffer size must be between 500-600 to produce clear output. At lower sample frequencies, the size of the buffer can be much smaller. If the call to OpenSB was unsuccessful, the function will return a value of 0. Otherwise, the return value will be non-zero. CloseSB (void) -------------- This function disables all interrupts, frees all buffers and stops all SB audio output. This function should be called before the program exits. This function has no input or output parameters. Set_FM_volume (uint8 left, uint8 right) Set_line_volume (uint8 left, uint8 right) Set_master_volume (uint8 left, uint8 right) ------------------------------------------- These functions set the left and right volume levels for the FM, line and master volume controls. These functions have no output parameters (void). Start_audio_output (uint8 dma_mode, void (*fillBuffer)(uint8 *buf, uint16 n)) ----------------------------------------------------------------------------- This function starts the audio output. It takes two parameters, the dma mode to be used and the name of the function that generates the audio. The possible selections for the dma_mode are AUTO_DMA and STANDARD_DMA. Normally, the AUTO_DMA option should always be used as the routines will attempt to auto-detect whether the AUTO_DMA option is supported. If AUTO_DMA is not supported, the routine will automatically switch to STANDARD_DMA mode. It is possible (though unlikely) that the AUTO_DMA attempt will cause problems. Because of this possibility, the system can be forced to use the STANDARD_DMA mode by passing STANDARD_DMA to Start_audio_output. I recommend providing the user the option to force STANDARD_DMA operation. Note that the buffer size may need to be increased to support STANDARD_DMA (see OpenSB). The fillBuffer function passed should be a function that takes two parameters, a pointer to an unsigned 8-bit buffer and an unsigned 16-bit integer. The fillBuffer routine should process the next 'n' bytes (specified by the 16-bit integer) and place them in the buffer pointed to starting with byte 0. Any function that meets these requirements can be used, which makes the SBDRV routines generic. License Information and Copyright Notice ======================================== SBDRV is Copyright(c) 1997-1998 by Ron Fries, Neil Bradley and Bradford Mott This library is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU Library General Public License as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. To obtain a copy of the GNU Library General Public License, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Any permitted reproduction of these routines, in whole or in part, must bear this legend.