SoundManager

Ok, seems good.



I have two suggestions:


  1. Maybe it should follow the singleton pattern so that it’s accessable from everywhere.


  2. Maybe it should extend SoundNode instead of having a public one.



    What do you think?



    /Per

Looks pretty good to me.


1) Maybe it should follow the singleton pattern so that it's accessable from everywhere.


Agree, there shouldn't ever be more than a single manager per application, right?

2) Maybe it should extend SoundNode instead of having a public one.


Can you elaborate a little more?
1) Maybe it should follow the singleton pattern so that it's accessable from everywhere.


I do like that idea. Honestly, I wrote this as part of a larger project I am doing for school. I haven't had time to flesh out a great design for it because I am having to work quickly through numerous problems, nor have I had time to get acquainted with the overall design philosophy of JME. If the 'Singleton' approach works with the overall design, more power to you guys.

:)

When changing game states or loading new levels, a method to clear all loaded sounds would be good.



/Per

any update on this? (including the clearing of loaded sounds)

Well, at least I dropped the idea of having it extending SoundNode, and added these two methods instead:

/

 * Draws the <code>SoundNode</code> of this manager. Should be called from

 * render in game loop.

 */

public void draw() {

   SoundAPIController.getRenderer().draw(node);

}



/


 * Updates the <code>SoundNode</code> of this manager. Should be called from

 * update in game loop.

 

 
@param tpf The time since last frame.

 */

public void update(float tpf) {

   node.updateGeometricState(tpf, true);

}





I don’t really have enough knowledge of the inner workings of the sound system to take this any further.



/Per



PS: I’ve also made a MusicManager, which I don’t know if I should post here or in another thread?

Sorry, no updates recently. I’ll get back to this in a few more weeks unless you like it as is.



If anyone else has any ideas of what they would like to see in this, please list them out.



Right now I want to add these items:

  1. Clearing of loaded sounds (as requested by others)
  2. Possibly a priority map so that "important" sounds are not preempted
SoundAPIController.getSoundSystem(properties.getRenderer());
SoundAPIController.getRenderer().setCamera(cam);


Just thought I'd include that you need these lines before calling SoundManager's constructor (for the other newbies who'll want to use this class) or you'll be kicked back to desktop with a null pointer error or another exception.

edit: I just noticed in testing that while it works great for playing the same sound multiple times, if I try to play two seperate sounds at the same time, I get only the most recently played sound. I'll have to try and figure out how to fix that after some sleep, I don't understand the sound stuff very well but my first random guess is to blame it on soundNode.onEvent only being able to handle one event per cycle or something like that... I'll try and look into it after some sleep.

Just noticed another bit of quirkiness here, when you try to play a sound outside of the audiable area you hear nothing (which is good of course) but then when you start playing sounds in the area where noise should be heard, suddenly the sounds double up or sometimes don’t play. I think that when a sound isn’t played because it’s too far away, it might somehow be filling a channel to begin with… I’ll try to figure this out but I am not very familiar with sound stuff (lwjgl, java, or any of it really).

I’m suggesting the following change to the two methods in SoundManager. In the previous versoin if you had 8 channels and a sound with the id 1 and a sound with the id 9, whichever sound was bound second would overwrite some of the previous sounds binding locations…



private void bindEvent(int soundEventID, int globalEventID) {
for (int i = 0; i < numberOfChannels; i++) {
channel.bindEvent(i + (numberOfChannels * globalEventID),
soundEventID);
}
}

public void playSound(int globalEventID, Vector3f position) {
int channel = getOpenChannel();
if (channel >= 0) {
this.channel[channel].setPosition(position);
soundNode.onEvent(channel + (numberOfChannels * globalEventID));
}
}


The other problem I had where only the last sound I attempt to play is pretty simple... onEvent can only hold a single event at a time, I assume that to have more than one sound start would require multiple SoundNode objects, I'm going to alter it locally to store an ArrayList of events and if it tests good I'll post it (possibly a new thread).

edit: My changes to SoundNode caused sounds to only play sometimes and has scared me away from attempting to edit it again. Am I the only one who is limitted by only being able to start a single sound at a time? (More than one sound can play, but they have to be started on different updates). Should I be using multiple sound nodes instead of just multiple programmable sounds?

Yet another edit: I added soundNode.updateWorldData(0f); just after soundNode.onEvent in playSound(...) and multiple sounds work... nothing else seems to go wrong, but I'm pretty sure this is a naughty workaround.