I'm playing with Direct Sound and I'd like to know what is the Primary Buffer doing behind the scenes in the stack.
Here's a piece of sample code I'm using:
private Device soundDevice; secondaryBuffer.Play(0, BufferPlayFlags.Default); |
As you can see, I'm playing the secondaryBuffer 3 times.
Does the Primary Buffer get passed a reference to the secondary buffer or is a copy made. Have I lost access to the first sound played or can I still access it (If change the volume or whatever of the secondayBuffer, only the last sound is changed).
And in terms of design, should I create a secondary buffer for each object I want control or can I use just one and save some memory
For example, I have 2 monsters which makes a noise when they are shot by the player.
If I use just one secondary buffer, I just start playing when I shoot the first monster and play again when I shoot the second

What happens in the Primary Buffer
francisk
Thanks for the reply; I suppose theres no correct answer to my question. Does this mean that the sound model is outdated for DX9 While youre right and I wouldnt use the same secondary buffer to manage multiple monsters, because of the glitches it is very possible to create a buffer and play it, mess with the settings and play it again.< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
Is this being looked at for future versions of DX
BigSquare
Let me try to clarify some things about primary buffers today.
The primary buffer concept dates back to Windows 95, when accelerated dsound drivers were VxDs and indeed all secondary buffers were mixed to a primary buffer. Since this was replaced with the WDM audio driver model (mostly in Win2000 and beyond), the primary buffer no longer means much. All S/W buffers are mixed by the kmixer.sys component and all H/W buffers are mixed by the driver, and there is no way to get access to the internal mix buffer that they use. If you use the WRITEPRIMARY to actually write to a "primary" buffer, it is just treated as any other secondary buffer - there's no improvement in performance or latency. The main use of primary buffers today is to set the global device volume and pan which you can do via SetVolume and SetPan calls to a primary buffer created without the WRITEPRIMARY flag.
Regarding your monster-shooting scenario, the code you have won't do what you want. Your last two play calls are redundant as they your single buffer is already playing. The correct way to do this is to use the DuplicateSoundBuffer API. This lets you create several dsound buffers that share the same memory area, so any lock, write and unlock operation you perform on any of the duplicate buffers will affect them all. This is good for identical one-shot sounds. It won't work as well if you're actually updating the buffer data while the buffers are playing, as each dsound buffer's read cursor will be at a different position in the memory buffer and your partial buffer updates are likely to cause a glitch.
I hope that helped. Let me know if anything is unclear...
Dugan Porter - DirectX Audio Team - Microsoft
This posting is provided "as is" with no warranties, and confers no rights
Amardon
Thanks, I realise I don't NEED to worry about the Primary Buffer, but that would nullify my entire question. I do want to "worry" about it because I'd like to understand what it's doing since there's obiviously leveraging opportunities here.
Just to add to the confusion of whether the "sound-to-be-played" is copied in memory or not, if I were to change the last piece of the code and change the PanningControl of the SecondaryBuffer to only play in the right ear and play. Then change the panning to the left ear and play; and lastly change the FrequencyControl and play. All 3 sounds would be properly mixed and presented.
So here I'm changing the SecondaryBuffer each time before I play it; and after reading the SDK, it says I can play as many sounds as there's available processing time. I'm not quite sure how this can be calculated (presuming your sounds are part of a game with graphics and input devices) but there doesn't seem to be any memory limitations.
<Rant>My apologise, but I feel I have to state that I'm disappointed with the DirectX MVPs if thier knowledge is limited to Direct 3D. I think an MVP should be well versed in all the aspects of DirectX (3D, Input and Sound) for both managed and unmanaged code.</Rant>
Anyways, moving swiftly along, I've uploaded a picture I created, showing the relationship between a SecondaryBuffer, PrimaryBuffer and the output sound, for a talk I gave on DirectSound here (http://dotnet.org.za/photos/mailowl/images/48546/original.aspx); you are all welcome to use it.
vandershnozz
You don't really have to concern yourself with the primary buffer as that get managed by DirectSound mostly. What you do need to concern yourself about is the Secondary buffers. A Secondary buffer is basically created to store your sound. Your application must create at least one Secondary buffer.
When you have a scenario where you have multiple objects and they have different sounds you could opt to go with a simple approach. You could have a secondary buffer for each enemy or object that has a sound or load the sounds at runtime if they aren't too big. You could test this and see if it works but generally I just create a secondary buffer for each object and play them when needed.
So to come back to your first question. You don't need to worry about the Primary buffer. DirectSound will manage it for you. You can think of the Primary buffer as your middleware between your application and your hardware.
You could read this for some more information or this.
I hope this helps.
Take care.