Sign in to follow this  

Sound manager - By the book

This topic is 2550 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Im in the making of a 2D game engine. I have plans using the XACT that goes hand in hand with XNA to use and controll sounds. But what Im wonder is, what is the usual aproach for handling sounds?

I have a component built engine where everything is an entity. Should I store the sounds and play them by the entity whenever it want to, or should I have the entity request a sound to be played by a soundmanager class?

Since Ive never worked that much with sound I like to hear some advice before I start so I wont be running into problems that could've been avoided. Feel free to post links with good tutorials or tell me about your solutions with pros/cons.

//Doggolainen

Share this post


Link to post
Share on other sites
I'm by no means an expert but I would treat sound in a similar way to your visuals. If your entities "own" a model (or sprite) then they should own a sound source (but not the sound) too. If your splitting logic from the view (as in your entities don't own their own visual) then do the same for the sound sources.

With OpenAL there are 3 main parts, a sound listener (like a camera just for sound), a sound source (where a sound is coming from) and finally the sounds themselves. The sounds should be owned by your manager perhaps. The sound sources are up to you but I'd treat them in the same way as you would a sprite/mech. Multiple entities may be playing the same "walking" sound, one sound but multiple sources.

Share this post


Link to post
Share on other sites
I'm making an XNA game using XACT and probably have a pretty similar system that you do. I just kept things simple and added a static SoundBank to the base Entity class. The SoundBank contains all of the sound effects entities would ever need to make. Then any entity (Player, Bullet, Enemy, or whatever) can play whatever sound they would need to through the PlayCue() method. This is probably the easiest method and I haven't run into any problems doing it this way.

Share this post


Link to post
Share on other sites
Quote:
Original post by Nanoha
I'm by no means an expert but I would treat sound in a similar way to your visuals. If your entities "own" a model (or sprite) then they should own a sound source (but not the sound) too. If your splitting logic from the view (as in your entities don't own their own visual) then do the same for the sound sources.

With OpenAL there are 3 main parts, a sound listener (like a camera just for sound), a sound source (where a sound is coming from) and finally the sounds themselves. The sounds should be owned by your manager perhaps. The sound sources are up to you but I'd treat them in the same way as you would a sprite/mech. Multiple entities may be playing the same "walking" sound, one sound but multiple sources.


Lets say my mainloop looks like this:
ThinkAllEntities();
Draw();

Should I let each entity do their "PlaySound" when they are with in their own "Think".


Or should I have the mainloop look like this:
ThinkAllEntities();
PlaySounds();
Draw();

Now an Entity would do a request sound within their loop and let something play them all at the end of the frame.

Share this post


Link to post
Share on other sites
What does draw do? loop through every entity and do entity.draw() or similar?

I'd be tempted to have each entity request play/stop sounds during the think part. Seems more logical than a PlaySounds thing. Going by j0mich01 suggestion that should work easily enough. I disagree in putting a sound bank as part of the base entity class but I'd use a similar approach (Its still just a question of who owns what).

Share this post


Link to post
Share on other sites
One possible solution is to include listeners in your state transitions. If you have a FiniteStateMachineComponent you could play sounds like so:


Sound attackSound;
...
FsmComponent fsm = entity.getComponent(FsmComponent.class);
fsm.addStateListener(AttackState.class, new StateListener() {

void onEnter() {
attackSound.play();
}

void onUpdate(TimeStep t) {
}

void onExit() {
attackSound.stop();
}
});

...
fsm.changeState(AttackState.class); // plays the "attackSound"



Whenever the "entity" transitions to the "AttackState" state it will play the "attackSound".

Share this post


Link to post
Share on other sites
One reason to abstract your sounds into their own class (or at least play them through an interface) is so you can have Options to disable or change volume of Sound Effects.

It's fine if each entity "owns" its own sound effect asset (rather than having a central library of sounds), however, it may be more coding work if you want to rip out / replace sound effects down the road

Share this post


Link to post
Share on other sites
I have to disagree with newera's approach regarding a function to play a sound. A better approach may be to have a global Play(int soundNum, bool stop) function, where soundNum can be an index into the sound/wave bank. You can implement that with a general header file:

// soundbank.h
enum { SND_ROCKETFIRE, SND_GUNFIRE, SND_WHATEVER, ... };
void Playsound(int soundNum, bool stop=false);

Include that header in whatever cpp files you need it and implement Playsound(...) somewhere.

Share this post


Link to post
Share on other sites
When I look at sounds I often start to think of it as graphics. And to be consistent I want to try to play all the sounds at the end of the frame.

So within an entity's Think() I do some kind of request to get the sound played.

Soundmanager.RequestPlaySound("gunshot", position, args...);
/*
*RequestPlaySound looks up a sound to be played in some kind of dictonary
*and puts it in a "soundsList" wich will all be played at the end of the frame.
*/

Then in the game-loop I do

Soundmanager.PlaySounds();
/*
* PlaySounds plays the sounds in the soundsList. Here I can do logics not to
* play to many sounds of the same type or not to play a sound requested by a
* entity who died later on during the same frame.
*/


Because now I can do all the logics for that frame in one place. I hate when undeterministic things happends due to an entitys order in the main list of entities. Playing the sound instantly within an entity, which dies the same frame but after the sound has start playing could be avoided by the above method.

So is this a total crap idea or should I go for it?

Share this post


Link to post
Share on other sites
Sounds reasonable to me, about the only minor change I'd make is to remove the string lookup in favour of an id system (or maybe use both at once).

(I say 'minor' as I'd be tempted to decouple the sound system futher by moving the 'play' request to a message posted into the message system. Maybe also a handle could be supplied back so the entity could control the sound if needs be (such as a moving sound source), but as these are non-trivial suggestions I'd not worry about them right now...)

Share this post


Link to post
Share on other sites

This topic is 2550 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this