Advertisement
Guest User

Untitled

a guest
Jun 3rd, 2016
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.70 KB | None | 0 0
  1. Programming World
  2. Go Back
  3. Archive
  4. Delete
  5. Favorite
  6. Share
  7. Display Options
  8. Pocket
  9. My List
  10. Favorites
  11. Archive
  12. Articles
  13. Videos
  14. Images
  15. Tags ›
  16. Careers at Pocket
  17. Become a Sponsor
  18. More
  19. Programming World
  20. www.ragestorm.netView Original
  21. SOUND BLASTER TUTORIAL
  22. --------------------------------------
  23. (c) 2005 by Jvs
  24. --------------------------------------
  25. *Last update on 18.08.2005
  26. [-] BEFORE WE START [-]
  27. -----------------------------------------------------------------------------------------------
  28. - My english is not perfect - as you could notice, so don't be angry when
  29. I make a mistake.
  30. -----------------------------------------------------------------------------------------------
  31.  
  32. [-] SPECIAL THANKS [-]
  33. ------------------------------
  34. - GIL DABAH (a.k.a Arkon) for giving me this webspace and giving me right
  35. place for sb source :).
  36. - STEVEN H. DON
  37. - ANDRE BERESEL
  38. - CRAIG JACKSON
  39. - ETHAN BRODSKY (huge thanks)
  40. - DAVID WELCH (huge thanks)
  41. - DRAEDEN OF VLA
  42. - ROB CRAIG
  43. - JACQUES DESCHENES
  44. - JUSTIN DELTENER
  45.  
  46. and huge thanks to djs - MARKO NASTIC and TIESTO - for making me cheerful when I was writing this tutorial.
  47.  
  48.  
  49. TABLE OF CONTENTS
  50.  
  51. 1. INTRODUCTION
  52. 1.0 Author
  53. 2. AUDIO PROGRAMMING
  54. 2.0 Introduction to audio programming
  55. 2.1 Basics
  56. 3. SOUND BLASTER
  57. 3.0 Introduction to SB
  58. 3.1 Interrupts
  59. 3.2 DSP Ports
  60. 3.3 Direct mode
  61. 4. DIRECT MEMORY ACCESS
  62. 4.0 About DMA
  63. 4.1 DMA Ports
  64. 4.2 Starting DMA Transfer
  65. 5. CLOSING
  66. 5.0 What I didn't mention?
  67.  
  68. 1. INTRODUCTION
  69. -----------------------------------------------------------------------------------------------
  70.  
  71. :[ 1.0 Author ]:
  72.  
  73. This tutorial is written by 4-years experienced programmer, thus there's no guarantee that information in this document is 100% perfect. For any damage caused by using information from this tutorial author does not take any responsibility. ["TRAFFIC" is currently playing in background]
  74.  
  75. I wrote this document only because I found that informations about sb programming are really badly united. I'm sick and tired of many different suggestions and propositions, stupid source codes that make you sick of them, stupid guides and documentations... so I used keyboard, I opened notepad, and wrote few words about what you really need to know if you're
  76. going to write programs using sb sound.
  77.  
  78. You can contact me via my e-mail (jvs_prog@hotmail.com) used especially for you guyz out there who want to know more about sound blaster programming and other stuff. (emulation much prefered)
  79.  
  80. 2. AUDIO PROGRAMMING
  81. -----------------------------------------------------------------------------------------------
  82.  
  83. :[ 2.0 Introduction to audio programming ]:
  84.  
  85. Sound Blaster cards work with digital sound - waveform audio. You should know that sound in nature is represented as a waveform (when is called analog audio). When need to be stored in computer memory, computer first convert analog signals to digital signals by using ADC (Analog-to-digital converter). This process is better known as RECORDING. When it needs to play it back, computer converts digital signals into analog using DAC (Digital-to-analog converter) and guess what - you hear the sound.
  86.  
  87. The chip that contains ADC and DAC ICs (Integrated Circuits) is called DSP (Digital Signal Processor) that beside this ICs contains many other for working with sound I/O. DSP chips are used in many elecotronic devices such as video and audio recorders, sound cards and many others. There's a chip on Sound Blaster card that contains ADC and DAC ICs that's called DSP chip despite that it doesn't have all functions like real DSP chips.
  88.  
  89. :[ 2.1 Basics ]:
  90.  
  91. Well, you probably ask yourself how the sound is written in memory. How the analog sound is converted into digital sound. Well here it is - explanation.
  92.  
  93. I already said that you can think about analog sound like you think about an unvisible wave. Digital sound is an analog sound represented by digits - numbers or on computer level - bytes. When converting to digital sound you should know that you lose the quality - that's right.
  94.  
  95. Well, enough shitting. Let's back to basics. Digital sound is an array of digital samples ( simply called "samples" ) that determines the height of waveform at specified time. Sample is a number that can range from 0-255 (8-bit), 0-65536 (16-bit) and so on. Sample frequency determines the number of samples that are sent to DAC/ADC for one second - that is - the number of samples played in one second. So 22050Hz sample frequency tell us that 22050 samples make a sound of 1 second. Sample frequency is also known as sample rate.
  96.  
  97. Mono and stereo? When working with mono sound, there's only one sound channel. When you're working with stereo there are two sound channels. Channels need to be the same size - need to have same number of samples. When DAC is sending multichannel sound to output it takes all samples at specified position from all channels and make a SAMPLE FRAME.
  98.  
  99. Let's take a look at some sound buffer...
  100.  
  101. [068][164][200][000][128][128][003][241][093][128]
  102.  
  103. If this sound is 8-bit than samples are only one byte. If this sound is stereo every deuce of bytes make a sample frame. If the smaple rate of this sound is 22050Hz than every block of 22050 sample frames (which are 2 bytes in our example so it makes 22050*2=44100 bytes) make a sound of one second.
  104.  
  105. When you want to mix two sounds you only need to add corresponding samples and you've got the mixture. Detailed info about this is out of scope of this tut. There're a lot of sites that explains basic audio arithmetics.
  106.  
  107. One more thing to add before I switch to more important things - silence is at 128 in 8-bit sound. The silence line is called baseline.
  108.  
  109. 3. SOUND BLASTER
  110. -----------------------------------------------------------------------------------------------
  111.  
  112. :[ 3.0 Introduction to SB ]:
  113.  
  114. Sound Blaster is pretty old sound card used in mid 90s. All changes to SB
  115. are actually made to its poor DSP chip.
  116.  
  117. SB's DSP chip works through I/O ports. Before I dive into details I'll explain the basic work of SB's DSP.
  118.  
  119. First, DSP can play/record sound in two modes - either using DMA (Direct Memory Access) or using CPU (obsolete). When you work with DMA, you should only program specified DMA channel that'll be used by DSP and then program DSP. Then , when you say to DSP "start" it polls one of DMA channels ( it should be one you programmed ) and it sends/recieves bytes from a memory location pointed by DMA channel that is polled. When DSP has sent/received specified number of bytes it interrupts CPU - that is - it tells CPU through IRQs (Interrupt Request Lines) to stop it's current execution and execute corresponding ISR (Interrupt Service Routine) that is determined by selected IRQ. In second mode (called direct mode) you need to send samples by hand and calculate time you should wait before you send next sample to DSP. This mode is a little bit (not just a little bit) obsolete and it uses CPU. It doesn't give any chance to CPU to execute any other code. So, some smart guyz developed DMA (which stands for "Direct Memory Access") chip that will transfer memory without any intervention of CPU ( we don't count programming DMA ). Well I don't think it is just like they say - DSP borrows the bus on some time to access RAM, so CPU can't execute some instructions that need memory access!
  120.  
  121. Well, really hard? Yep.. It is if you do not know what are interrupts, interrupt service routines, interrupt request lines... OK! Here it is - explanation.
  122.  
  123. :[ 3.1 Interrupts ]:
  124.  
  125. Interrupt stands for... interrupt. Interrupts interrupt CPU and make it execute some other code. There are two types of interrupts - software and hardware.
  126.  
  127. Software interrupts are generated by --- software/programs. They are accessible to programmer and they provide much more than one function to programmer. Well, they are number 0x10-0xFF (0x means HEX). You do not need to know about them now...
  128.  
  129. Hardware interrupts are generated by devices (such as Sound Blaster's DSP). They use physical inputs of CPU (through its microchip pins) that are called Interrupt Request Lines (IRQs). When a signal is sent on specific IRQ of CPU, CPU stops everything and executes specified ISR (Interrupt Service Routine). The memory location of ISR that CPU executes depends on IRQ line.
  130.  
  131. Hardware interrupts are numbered 0x00-0x0F. So it means that there are 16 differenct IRQ lines. IRQ lines cannot be shared!!! I'm not going to tell you which are free for use, but you should only know that IRQ5 and IRQ7 are most used IRQ lines by SB's DSP chip.
  132.  
  133. :[ 3.2 DSP Ports ]:
  134.  
  135. Beside memory address space there's I/O address space in 80x86 Intel CPUs. This address space is used to communicate with devices. Everything sent by some device should be sent at specified I/O address place called port. Well, to program the DSP and DMA you should access specified ports.
  136.  
  137. To read from a specified port we use IN instruction (assembly) or INPORTB(to read a byte from port in C). To write to a specified port we use OUT instruction (assembly) or OUTPORTB (to write a byte to specified port).
  138.  
  139. (my winamp is currently playing Marko Nastic's soundtracks - so don't be angry if I give you bad info)
  140.  
  141. So you should ask me - where are ports used by DSP? They start at specified base port that can be one of 0x220, 0x230, 0x240, 0x250, 0x260 or 0x280.
  142.  
  143. So how to find which base port my DSP uses? To find out which base port DSP uses you should try to reset DSP for each port until you get positive answer.. If no positive answer is returned - there's no Sound Blaster card or somebody took off DSP chip from your card. How to reset DSP will be covered after I give PORT MAP of DSP chip.
  144.  
  145. I will not cover all ports used by DSP (there're many dox you can find out there about ports used by SB's DSP). I'll only cover few of them.
  146.  
  147. [0x06] DSP Reset (W)
  148. [0x0A] DSP - Read Data (R)
  149. [0x0C] DSP - Write Data Or Command (W)
  150. [0x0C] DSP - Write Buffer Status - bit 7 (R)
  151. [0x0E] DSP - Data Available Status - bit 7 (R)
  152.  
  153. Port address relative to base address is placed between brackets. (W) means write-only, (R) means read-only.
  154.  
  155. First port called DSP reset port (port at address 0x06 relative to base address) is used to reset DSP. Resetting DSP can be used to autodetect which baseport is used by DSP on specified computer (more prefered than using BLASTER environment variable).
  156.  
  157. To reset DSP you should do the following:
  158.  
  159. - write 0x01 to port DSP_RESET (BASEPORT+0x06)
  160. - wait for 3 microseconds (that's the time it takes DSP to reinitialize itself)
  161. - write 0x00 to port DSP_RESET (BASEPORT+0x06)
  162. - wait for 3 microsecond for results
  163. - read byte (I'll refer to it as DATA) from DSP_DATAAVAIL (BASEPORT+0x0E) and read byte (I'll refer to it as READ) from DSP_READ (BASEPORT+0x0A). If bit 7 is set in DATA and READ is 0xAA then DSP is detected at BASEPORT. If condition failed no DSP is detect at base port BASEPORT.
  164.  
  165. Well, I don't really know why we should write 0x00 to DSP_RESET after writing 0x01 but that's it. Some other codes say something different - like you don't need to check if bit 7 in DATA is set. So, I'll give you next function for resetting DSP chip on SB:
  166.  
  167. #define DSP_RESET 0x06
  168. #define DSP_DATAAVAIL 0x0E
  169. #define DSP_READ 0x0A
  170. int ResetDSP( unsinged int BasePort )
  171. {
  172. outportb(BasePort + DSP_RESET, 0x01); // write 0x01 to DSP_RESET
  173. delay(10); // reinitialization
  174. outportb(BasePort + DSP_RESET, 0x00); // write 0x00 to DSP_RESET
  175. delay(10); // waiting for results
  176. if ((inportb(BasePort + DSP_DATAAVAIL) & 0x80)=0x80) &&
  177. (inportb(BasePort + DSP_READ) == 0xAA))
  178. {
  179. // DSP was found
  180. return(1);
  181. };
  182. return(0); // No DSP found
  183. }
  184.  
  185. Second port called DSP read port (port at address 0x0A relative to base port) is used for reading. To read from a read port you should do next:
  186.  
  187. - wait until bit 7 is set in data available status (0x0E relative to base port).
  188. - then read from read port (0x0A)
  189.  
  190. Third port called DSP Write Data or Command (port address 0x0C relative to base port) is used for writing commands to DSP. To write command to this port you should do following:
  191.  
  192. - wait until bit 7 is set in write buffer status port (0x0C relative to base port)
  193. - write command to this port (0x0C)
  194.  
  195. Next are some of DSP commands (I'm not going to cover all of them):
  196.  
  197. [0x10] Start DAC. 8-bit sound. Direct mode. // playback
  198. [0x14] Start DAC. 8-bit sound. DMA mode. // playback
  199. [0x20] Start ADC. 8-bit sound. Direct mode. // recording
  200. [0x24] Start ADC. 8-bit sound. DMA mode. // recording
  201. [0x40] Set time constant.
  202. [0x48] Set block size.
  203. [0xD1] Turn on speaker.
  204. [0xD3] Turn off speaker.
  205. [0xD0] Halt DMA in progress.
  206. [0xD4] Continue DMA.
  207. [0xE1] Get DSP Version.
  208.  
  209. With command 0x10 we tell DSP that we're going to start to transfer the
  210. samples from our buffer to DSP in direct mode (playback).
  211.  
  212. Command 0x14 will tell DSP to poll DMA - it starts reading samples (playback).
  213.  
  214. Command 0x20 wil tell DSP that we're going to read samples from it in direct mode (recording).
  215.  
  216. Command 0x24 will tell DSP to poll DMA - it starts sending samples (recording).
  217.  
  218. Command 0x40 will set time constant. This is used to set something like sample frequency - the number of samples that are going to output in one second. To calculate time constant you should use next equation:
  219.  
  220. 256 - ( 1 000 000 - sample frequency )
  221.  
  222. Command 0x48 simply sets the number of bytes it will read/write from/to DMA, after what it generates interrupt. There's also DMA port that sets the block size but those values do not need to be same. Instead it is used for smooth playback of larger sound files. I'll talk about this a little later.
  223.  
  224. Command 0xD1 will turn speaker on. This is used for compatibility with older SB versions. After you tell DSP to start to play/record sound you should turn on speaker.
  225.  
  226. Command 0xD3 turns off speaker.
  227.  
  228. Command 0xD0 will stop DMA transfer to/from DSP for a moment, until you write 0xD4 command.
  229.  
  230. Command 0xD4 continues DMA transfer which was previously halted.
  231.  
  232. Command 0xE1 tells DSP that you want to read DSP version. So once you tell DSP that you want to read version, you should read twice from DSP read port (first read returns major second returns minor).
  233.  
  234. :[ 3.3 Direct mode ]:
  235.  
  236. Well, I already said - direct mode is obsolete. It uses CPU and while you play sound, you can't do anything else. So if you don't want to know how this works just skip it. You won't learn anything from this that can help you later with DMA mode. So make your decision.
  237.  
  238. DSP is preparing for direct mode when you write command 0x10 (for 8-bit playback) or 0x20 (for 8-bit recording). To play using direct mode do following:
  239.  
  240. -1- turn on speaker
  241. -2- write command 0x10 or 0x20 to DSP depending on what do you want to do - record or playback
  242. -3- read ror next sample from read port (0x0A) if you're recording, or write next sample to write port (0x0C) if you're playbacking
  243. -4- wait for the correct timing (must do it by yourself)
  244. -5- if not the end of sound buffer goto step 2
  245. -6- turn off speaker
  246.  
  247. 4. DIRECT MEMORY ACCESS
  248. -----------------------------------------------------------------------------------------------
  249.  
  250. :[ 4.0 About DMA ]:
  251.  
  252. DMA stands for "Direct Memory Access" and it's another chip on your motherboard beside well-known CPU. It is invented to solve the problem of impossible background transfering. It can transfer data RAM-to-device and vice-versa. It starts its background transfering when some device polls it. And, one more thing - it is not capable of generating interrupts.
  253.  
  254. What we really need to know is that DMA transfers block of memory without intervetion of CPU (a LIE!). That's what makes SB sound a reality
  255.  
  256. DMA has two DMACs (DMA Controllers). First DMAC (a.k.a DMAC1) has 4 DMA channels dedicated to 8-bit transfering while second one DMAC2 is dedicated to 16-bit transfering. We're not going to talk about DMAC2 because, actually, we are working with 8-bit mono sound.
  257.  
  258. :[ 4.1 DMA Ports ]:
  259.  
  260. Just like you program DSP, you program DMA via I/O ports.
  261.  
  262. Here are some of the ports we are going to explore:
  263.  
  264. * NOTE: All port addresses are absolute - that is - all are relative to port address zero.
  265.  
  266. [0x00] DMAC1 CH0 Address port
  267. [0x01] DMAC1 CH0 Count port
  268. [0x02] DMAC1 CH1 Address port
  269. [0x03] DMAC1 CH1 Count port
  270. [0x04] DMAC1 CH2 Address port
  271. [0x05] DMAC1 CH2 Count port
  272. [0x06] DMAC1 CH3 Address port
  273. [0x07] DMAC1 CH3 Count port
  274.  
  275. DMAC1 - DMA Controller 1
  276. CH# - Channel number #
  277.  
  278. As you can see from above every channel has its address and count port. Address port is used for setting memory location of buffer used in transfert. Count port determines the size of the buffer.
  279.  
  280. Because DMA was first invented for 16-bit systems, the address ports can take only absolute 16-bit addresses. Later when it was upgraded, to keep compatibility with older programs written for older DMA, developers only added new ports to new DMA called PAGE REGISTERS.
  281.  
  282. With this expansion, new DMA can access 32-bit memory address space, but cannot transfer memory buffers that cross page boundary. So you should care about that your buffer doesn't cross page boundary.
  283.  
  284. Here are page register ports:
  285.  
  286. [0x87] DMAC1 CH0 Page Register
  287. [0x83] DMAC1 CH1 Page Register
  288. [0x81] DMAC1 CH2 Page Register
  289. [0x82] DMAC1 CH3 Page Register
  290.  
  291. That means you should convert your SEGMENT:OFFSET pointer into PAGE:OFFSET pointer.
  292.  
  293. This is how we do (not the stupid song..) . First, we have a pointer to our buffer. So you should convert SEG:OFF to PAGE:OFF pointer. Segment represent an ordinal number of 16Byte block in absolute memory. Offset is the memory address relative to segment's absolute memory location. So what do you do... Multiply segment with 16 and add offset to it. With this we got an absolute memory location. The upper 2 bytes of result are page... Really easy? Easy, only if you knew anything about stupid memory segmentation before. I forgot to mention - lower two bytes determine offset in page.
  294.  
  295. How to check if my buffer crossed page boundary? Well when you calculate your linear (absolute) address of buffer you should only add the size of your buffer to it. If page changed then your buffer crossed page boundary. All you need to do is to allocate it again and everything will be ok , unless you use buffer larger than 64K.
  296.  
  297. To write a word to those ports first write lower byte then upper.
  298.  
  299. :[ 4.2 Starting DMA Transfer ]:
  300.  
  301. - First - we should enable speaker for compatibility with older DSP versions.
  302. - Then we set time constant via command 0x40. Already explained.
  303. - Then calculate absolute linear address of buffer that will participate in transfer (reading from it (playback) or writing to it (record)). Get page
  304. offset and offset in the page.
  305. - Disable DMA channel we are going to program. To disable it we are using
  306. single mask register port I didn't explained. It's port address is 0x0A and you should send to it a byte that is structured on the next way:
  307.  
  308. +----+-----+-----+-----+-----+-----+-----+-----+
  309. | 0 | 0 | 0 | 0 | 0 | M | CHANNEL |
  310. +----+-----+-----+-----+-----+-----+-----+-----+
  311.  
  312. CHANNEL - The lower two bits of this single mask control byte set channel we want to disable/enable. CH0 = 00 CH1 = 01 CH2 = 10 CH3 = 11
  313. M - If this bit is set DSP will disable channel, otherwise it will enable it.
  314. Rest of bits are unused.
  315. This is used to avoid problems when some other device/s is/are trying to use this channel.
  316. - Clear byte pointer flip-flop. Hey what's this? I never mention this. Ok there's one more DMA port that is used to tell DMA that we are going to re-program one of its channels. This port is called byte pointer flip flop and it's port address is 0x0C. To clear byte pointer flip-flop just write anything to it.
  317. - After this we should set DMA mode. I didn't mention this ,too. The port used for setting DMA mode is at address 0x0B. You have to write a control byte for DMA mode to it. A control byte is structured like this:
  318.  
  319. +----+-----+-----+-----+-----+-----+-----+-----+
  320. | MODE | ID | A | TYPE | CHANNEL |
  321. +----+-----+-----+-----+-----+-----+-----+-----+
  322.  
  323. CHANNEL - The lower two bits select channel which mode we're going to change
  324. TYPE - This is a transfer type and it can be one of the following:
  325. 00 - Verify
  326. 01 - Write (playback) // sends memory to device which polled DMA
  327. 10 - Read (record) // receives memory from device which polled DMA
  328.  
  329. A - Auto-Initilialization Enable
  330.  
  331. I didn't mention auto-initialize mode but only difference between manual initialization and auto is that in auto mode DMA never stops transfert - it loops. I'll spit few words about this mode at the and of this tut.
  332.  
  333. ID - Increment/Decrement
  334.  
  335. 0 - Increment
  336. 1 - Decrement
  337.  
  338. Determines whether the address port of selected channel increment or decrements. That is - is written address to address port of selected channel end of buffer or start of the buffer. Hope you understand ... if not, you should know that everybody use INCREMENT.
  339.  
  340. MODE - This is a bit more on hardware level than it is on software level. I'm not sure I'm going to cover all modes, nor any mode. I'll just tell you use demand mode.
  341.  
  342. 00 - Demand mode
  343. 01 - Single mode
  344. 10 - Block mode
  345. 11 - Cascade mode
  346.  
  347. To explain the differences between those modes I need to access hardware level... Well I don't like it and beside that I don't know how Cascade mode really works, but beside all your head might pop if I start to explain some of those modes. Maybe in future release of this tut (at www.admiral.bizland.com).
  348.  
  349. - Remember when you calculated your page offset and offset in your page. Write that "offset in your page" to address port (first lower byte then upper)
  350. - Write the page to page register ( it's only one byte )
  351. - Write size of your buffer to count port (first lower byte then upper)
  352. - Enable DMA channel
  353. - Write number of bytes after DSP will generate interrupt. Command 0x48. Already explained. First lower byte then upper.
  354. - Then DMA DAC 8-bit command or auto-init playback command which I didn't mention (0x1C).
  355. - Listen to sample.
  356.  
  357. 5. CLOSING
  358. -----------------------------------------------------------------------------------------------
  359.  
  360. GO VISIT: WWW.SHDON.CJB.NET
  361.  
  362. I don't have so much time to write detailed tut I promised I'll write for my site.
  363. But I will one day.
  364.  
  365. I didn't talk about auto-initialized mode, how to play sounds larger than 64KB and detecting IRQs, but I can only tell you to look at www.shdon.cjb.net. I explained something what you can't find in other tuts and dox, so I hope you can now easily explore Steven H. Don's source codes about programming sound blaster.
  366.  
  367. Auto-initialized mode is not present in earlier DSP version (SB 1.x , 2.x...). It is introduced in SB Pro ( correct me if I'm wrong - i'm not sure ). It is more efficient than manual initialization because it doesn't generate stupid noise at the end of DMA buffer.
  368.  
  369. I hope you know how to rewrite ISRs (Interrupt Service Routines) because I tought you can learn this with Shdon's source codes.
  370.  
  371. Good luck, my hands are...
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement