1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
|
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.
|