How to program your SoundBlaster board
(see at the end of document for Copyrights and Warranties)
Chapter 2 - Advanced DSP Programming
Here's! It's time to have in our hands the full power of the SB' DSP. In this chapter I'll show you how to program the DSP to use a DMA, so you'll play your samples in background while your CPU can do other tasks (such as BitBlt operations, if you plan to make a game!). You must be aware of the fact that there are two different types of DMA tranfers: the first is called 'Single Cycle' and the second, more powerful, is called 'Auto-Initialize'.
In the Single Cycle mode you'll program the DSP and the DMA controller to play a sample buffer (a location in memory where your sample is stored), and when the buffer has been completly reproducted, the DSP will signal the performed operation via its IRQ line. Easy, uh? Well, it has the disadvantage the buffer can't be longer than 64Kbytes in 8 bit/sample mode or 128Kbytes in 16 bit/sample mode.
In Auto-Initialize mode you program the DSP and the DMA controller to play a sample buffer and, when the buffer is finished, it restarts from the beggining. An IRQ is signalled when the reproduction is finishing and is restarting and an IRQ is signalled also when the reproduction is in the half of the buffer. What does it means? It means that you can, after the first half of the buffer has been played (and its IRQ has been signalled), change the contents of the first half of the buffer while your SB is playing the second half. When the next IRQ will come, the "third haf" of the buffer will be reproducted. This scheme, known as 'double buffering', means that you can have a large buffer (a long sample) stored somewhere in memory (in XMS, for example) and you copy subsequently parts of that onto the DMA buffer space which could be, in fact, very tiny.
As you can remember I've never told you how detecting the correct IRQ and the DMA channels of your SB. This task is not so easy, unless you have an SB 16 or later. If it's your case (if your program is running on a SB 16 equipped computer), it'll be easy to discover this settings; I'll teach you how to do this in the next chapter (I'm sorry ... this task involves the Mixer chip). If your SB isn't a SB 16 or later ... well ... you can only try all the values until you find the correct ones.
To find the correct IRQ you will do something like that: First, install a short IRQ handler for the IRQ you're testing. Second, give the DSP the command IRQ Request (F2h). Third: if you receive the IRQ in a couple of microseconds, you've find the right IRQ, otherwise, try another line. Remember that the SB has generated the IRQ, so it wait for an acknowledge. To acknowledge its IRQ read the IRQ ack port (0Eh). Don't forget to perform the EOI (end of interrupt) of the interested PIC, otherwise your PC won't be very happy!
To find the correct 8 bit DMA channel (if you need the 16 bit DMA channel it's because you've got a SB 16, so you don't need to do that) setting of your SB, the only thing you can do is to try to play a short sample (say 1 byte) using one of the possible DMA channels in Single Cycle mode and wait for the related IRQ. If it will be signalled, you've choosen the right DMA channel.
Ok, say we want to play, in background, a short sample (4000 bytes) with Single Cycle DMA mode. So, basically, we will follow this steps:
First: Allocate a buffer 4000 bytes long somewhere in memory. This could also be not so easy. I haven't told you before that DMA operations cannot cross 64K page boundary. It means that you can't have your buffer starting at 6000h:FF00h (memory location expressed as a segment:offset pair) and ending at 7000h:02FFh (1024 bytes long). So you must allocate your buffer entirely in a memory page (say from 6000h:F000h to 6000h:F3FFh, that's also 1Kb). This can be not so easy with large buffers (60 Kb, for example). Have you done that? If so, you're ready for the second step.
Second: Program the DMA controller to communicate with your SB. I will not explain now how can you do that ... may be in another chapter. Just remember that, when you are playing, the DMA operation will be a read operation (because you read bytes from the memory).
Third: Tell the DSP how fast must it play the sample via the DSP command Set Time Constant (40h). This command must be followed by a byte-value that will indicate the sample rate. This value can be calculated with the formula TIMECONSTANT = 256 - (1,000,000 / SAMPLERATE), so if you want to play your 4000-bytes sample at 8000 samples/sec (Hz), you will set this value to 131.
Fourth: Tell the DSP to play your buffer via the DSP command 8-bit Single Cycle DMA DAC (14h). This command must be followed by a 16 bit value indicating how many samples we would like to play. Pass the DSP the LoByte first (the LSB), so the HiByte (the MSB). Remember also that a zero value will play a buffer 1 byte long. For playing a 4000 bytes samplebuffer we will say the DSP a length equal to 3999 (you cannot play a zero-length samplebuffer ... who wants to do that?).
When you have done that the DSP will play your sample without using any CPU resources. Remember to enable the speakers before starting!
At the end of the samplebuffer, the DSP will signal the end of the operation via its IRQ. Be sure to be notified when this occours: install an IRQ handler before starting playing, remember also to acknowledge the IRQ! When all that has been done, the DSP will be ready for a new operation.
Say now we want to play a samplebuffer using 'Auto-Inizialize' mode. First we must be sure the SB model is a version 2.0 or later. SB 1.0 and 1.5 won't support this DMA transfer mode. If our SB has this capability we will follow this steps:
First we'll program the DMA controller to communicate with our SB. So we will say the DSP the sample rate we want to play the sample (as we have done in the Single-Cycle mode example above).
Then we will say the DSP the length of the samplebuffer we will play continuously. We can do that via the DSP command Set DMA Block Size (48h). We must follow the command with a pair of byte meaning the half of the buffer length; the LSB first and then the MSB. So we can play only buffers with even length. The value we will put into will be calculated as (BUFFERLEN / 2) - 1. For a 4000 bytes long samplebuffer the value will be 1999. This formula will ever be used when playing in Auto-Inizialize mode.
Last, give the DSP the 8-bit Auto-inizialize DMA DAC command (1Ch). When done that, the reproduction will start. At the middle and at the end of the buffer an IRQ will be signalled. Do what do you know. When you want the reproduction to be stopped, give the DSP the Halt 8-bit DMA operation (D0h); this will only pause the reproduction. To continue playing give the DSP the Continue 8-bit DMA operation (D4h); to terminate the reproduction give the DSP the command Exit Auto-Inizialize 8-bit DMA Operation command (DAh). Enjoy!
In the next chapter I will explain the use of the Mixer chip. So you will learn how can you play stereo samples, how can you do volume fade operations, panning operation, and also detecting (and changing!) SB 16 IRQ and DMA settings.
Here's a table with all the DSP commands explained in that chapter
DSP Command | What it does | Note |
____________ | ___________________________________ | ___________________________ |
14h | 8-bit Single Cycle DMA DAC | Length follows, LSB first, so MSB |
1Ch | 8-bit Auto-inizialize DMA DAC | |
40h | Set Time Constant | 1 byte follows |
48h | Set DMA Block Size | Length/2 follows, LSB first, so MSB |
D0h | 8-bit Halt DMA operation | |
D4h | 8-bit Continue DMA operation | |
DAh | 8-bit Exit Auto-Inizialize 8-bit DMA operation | |
F2h | 8-bit IRQ Request | |
____________ | ___________________________________ | ___________________________ |
Stay tuned!
Sverx, 28 / 05 / 98
__________________________________________________________________
Warranty and Copyright Policy
This document is provided on an "as-is" basis, and its author makes no warranty or representation, express or implied, with respect to its quality performance or fitness for a particular purpose. In no event will the author of this document be liable for direct, indirect, special, incidental, or consequential damages arising out of the use or inability to use the information contained within. Use of this document is at your own risk.
This file may be used and copied freely so long as the applicable copyright notices are retained, and no modifications are made to the text of the document. No money shall be charged for its distribution beyond reasonable shipping, handling and duplication costs, nor shall proprietary changes be made to this document so that it cannot be distributed freely. This document may not be included in published material or commercial packages without the written consent of its author.
ALL COPYRIGHTS AND TRADEMARKS BELONG TO THEIR RESPECTIVE OWNERS.
__________________________________________________________________
[ Back to Main Programming Page - Back to Chapter 1 - Go to Chapter 3 - Back to Home Page ]