Keywords: directsound 9 VB. NET DirectX sound control sound engine Author: Dong Hanjun
Reprinted please indicate from http://blog.csdn.net/a11s
Objective: to create a sound effect controller to reduce memory usage, encapsulate directsound, and reduce CPU consumption, so as to meet the actual needs of people and improve ease of use.
I was not planning to continue. I studied related issues with denghe a few days ago. we have discussed the impact of too many sound effects on machines, especially memory usage and release. we found it necessary to create a controller dedicated to sound effects management.
Different from the purpose of denghe, the implementation is quite different. all of them need to implement the gameobject interface, which is feasible for games. however, I am not only using controllers for games. it is more like providing a sound processing service. I dare not call it a sound engine. after all, few functions can be implemented.
Problem
1. When you plan to play the sound effect (WAV), you can use new buffer (filename ,....) we all know this. however, after new, the whole WAV file will be loaded into the memory. we call it static loading. when you attack the enemy, such as the bullet sound or the sword sound. many of them are repeated. at this time, you can use the new buffer to directly play.
2. if the problem is so simple, there is no need to write this article. when a sound is not completely played, and another repeated sound is then played, it is obvious that play cannot be played directly. What should you do? Stop it first and play it again from scratch? Obviously, neither. you can simply create another one. of course you can, unless you do sound mixing yourself (requires a lot of acoustic knowledge and mathematics), you can only use two buffer methods to play simultaneously at different times.
3 seems to have solved the problem. we continue to promote the problem to multiple audio effects (WAV), as well as a large number of repeated playback times. use the solution of problem 2 to generate a large number of new buffers. not only is it very complicated to manage, but it also consumes terrible memory. and your system resource overhead is considerable. it seems that this phenomenon is very easy to appear in the game. therefore, a management method is urgently needed to deal with this phenomenon.
Different from me, denghe provides a soundpool solution that relies on the script engine of the game. manage the loading and uninstallation of wav files. each valid WAV creates multiple backups when loaded in each scenario. You can create a certain number of buffer buffers for each WAV. for example, create four, and then automatically point to the next one as needed. then it loops between four. for shorter sound effects, it can fully meet the needs of human hearing. therefore, the game can fundamentally solve the infinite waste of memory, and each sound effect does not interfere with each other .. you only need a reliable script engine to load and release it. the total space required is the total volume occupied by the file + the number of buffers per file * the size of the file. In fact, many sound effects interact with users, so we cannot predict the actual frequency of some sound effects. in the worst case, the actual memory you pay = the number of WAV Files * The number of buffers. for a small number of sound effectsProgramBut some large scenarios may have to pay for the cost, but this solution is a good solution for games.
4. My solutions:
4.1 Build a layer: in my opinion, sound can be divided. for example, a fighting game. player1 can be set to layer1. the player can be set to Layer2, and the effect of combat-that is, the squeaking sounds can be set to layer3. At the beginning of the scenario, "Ready Go ", and "K. o. "All can be placed in layer4
4.2 create a layer Buffer: After the classification is completed, you will find that if the interaction between layers is inappropriate, but inside the layer, when people speak, if there are two sentences at the same time, isn't it natural ?? Or during the fight, those sounds are too common and short. When people are busy, don't you care if the video has been played ?? Putting these mutex factors in the same layer meets the actual needs.
4.3 creation steps:
In order to adapt to the needs of speed, you cannot consider loading from the hard disk when the game is in progress. therefore, all data must be loaded to the memory at the beginning. during playback, each WAV file has only one buffer, so you need to dynamically create a copy for playback. copy management can be handed over to the Controller. for example, the play method. play (soundkey, targetlayer)
4.4 Performance Analysis: Mainly memory usage. Memory required = size of each file and + number of layers * Number of buffers in each layer
These are all controllable. Of course, the larger the buffer, the better the effect, and the layer is usually determined at the beginning based on actual needs. Therefore, the memory usage can be stable in a value. Fortunately, this value is controllable and can even temporarily change the number of buffers based on the computer's memory capacity (well, no one will think so)
5. key technical issues: The above ideas seem good, but the following issues need to be considered for implementation.
5.1 how to manage all the buffers? We may seldom consider this issue when we get used to object-oriented. You can use any advanced means or even use dataset .... it is not an alternative, but I am a classic user. I use a two-dimensional array of buffer, which is enough. I used to use arrylist, but I couldn't figure out how many practical advantages it can bring to me compared with arrays.
5.2 how does one determine which buffer to play? Since buffer is an array or other form, according to layer division, it belongs to layer. For a two-dimensional array only, buffer [tarlayer] [tarbuffer] is filled with two parameters of a two-dimensional array.
5.3 since it is recycled, how should we specify a suitable buffer?
This problem is complicated. I encapsulated it in the Controller and used an enumeration method to specify a suitable buffer. The following is the procedure.
Function enumbuffer (tarlayer as integer) as integer is passed to use that layer, and a suitable bufferid is returned.
A. Check whether the current layer has idle buffer. If there is a buffer of nothing or null, there is no doubt that it will be the most suitable buffer, so directly exit the loop and return his ID
B. if it does not meet a, check whether there is disposed or stopped buffer. They are no longer playing. it is also suitable. After finding one, there is no need to continue the loop and the ID is directly returned.
C. if B is not met, traverse all the buffer of the current layer and find the buffer with the longest playback time. A long playback time means the longest playback time. we can ask him to rest and return this ID
D. If there are more than one that satisfies C, the first or last return is returned.
5.4 what should we pay attention to during playback?
To save space, you must clear the enumerated buffer and create a copy of The wavbuffer list for playing.
Because data cannot be obtained from the hard disk at this time, you can only consider using the buffer. Clone () method, or directly create a new buffer (using the stream of wavbuffer)
6. Detailed Structure
Class: xsoundlist is essentially a filestream hashtable. It provides a keyword, a filename, and creates a filestream... which plays a role in storage. It sets the original data here to facilitate the Controller to read.
Class: xbgmlist is similar to xsoundlist. However, xbgmlist is used to store large files without static loading and provides multiple formats. for background music (Do you plan to load the CD audio track or several minutes of wav to the memory? Crazy)
Class: xsoundmanex controller. Which one is played in the tube, the number of internal buffers, and the volume? This is also the encapsulation class for directsound. It can be used to manage soundbuffer using the layer idea.
Class: xsoundman standard controller. Because xsoundmanex uses too many directsound features and does not conform to the idea of OOP encapsulation, this should be used to replace xsoundmanex for common applications, unless you want to re-encapsulate the original ex.
Class: xsoundsimp simple controller. as long as there is a layer, it is enough. A super simple controller, loading in the first step, playing in the second step is gone, and the analysis structure has been rewritten, so you don't have to worry about leakage, even creating an xsoundsimp each time saves memory compared to creating multiple buffers directly, and you do not have to initialize directsound.
7 Additional Features
Adjust the sound volume, separate the background music from soundbuffer, dynamically load WAV (although not recommended), loop playback, and so on. If not, you can continue encapsulation from xsoundmanex.
8. known shortcomings and plans for the next version.
The volume between layers is not independent, which is contrary to mutual interference between layers.
BGM does not differentiate layers. It is of little significance to determine that BGM divides layers during design. therefore, BGM has only one layer. intermediate use is also competitive. although bgmbuffer can be used to establish a large bgmbuffer, this problem can be solved (it doesn't matter, dynamic loading, memory consumption is not very large ). however, users who do not understand the mechanism will feel incredible. in addition, if the maximum buffer value is exceeded, the use of background music may be affected. for example, if some sound effects are too large, the programmer adds them as BGM, which seems to save, but there are hidden dangers. unless you can ensure that the enumeration Condition B is met.
9 program demonstration andSource codeIntroduction
In the first simple application, pressing the keyboard button in the response will produce sound effects, which can be like playing the piano. (do you want to make a soft wave table ?)
The second demonstration is to use text to drive the playing of sound. You can "record ".
The third demonstration shows the impact of frequency repetition on memory and CPU (test performance), including playing background music and using layer.
The fourth is hidden by me. I used to make a game. I didn't have much time to complete it. I can continue to improve it if I am interested.
10 is not available for the moment, because I cannot find a place to store myCode, About 800 KB, And the csdn blog does not currently provide RAR upload. If necessary, add the QQ group: 589626 C # Game Development. rar downloads are included in the group sharing.
==================== end ============================