I am having some trouble understanding the lifetime of a channel because I’ve seen two ways of playing a sound and holding onto it’s playback attributes. (My suspicion is that method #2 is correct, but it would be great to get validation or an even better channel management method)
Method #1 – Holding onto a channel indefinitely:
With this method the moment you load a fmod sound you would immediately play it paused in order to get a channel. From there you apply whatever settings you want and then “play”(unpause) the channel. Once the channel is completed playback (in the end
FMOD_CHANNEL_CALLBACKTYPE_END callback) you play the sound again in a paused state to reuse
FMOD_CHANNEL_REUSE the channel. Saving all the playback properties that were set earlier.
Method #2 – Hold the playback settings yourself, then fire and forget the channel:
Instead of the channel holding onto your playback properties for any length of time; you make your own datastructure and only set the properties on the channel once you are about to actually play the sound. (ie copy the properties from your class/struct and call fmod with all the changes). In this case you don’t need to care at all about whether the channel is stolen or not, if it is not valid simply ignore it.
- You must login to post comments
Version 2 sounds better but I still don’t know why you need to store everything yourself.
The fmod channel is the datastructure that holds the info you’re talking about. There’s no point in holding ‘volume’ for example when Channel::getVolume gives you the currently set volume.
FMOD_CHANNEL_REUSE was removed in FMOD Studio, it serves a very specific purpose, to avoid a new channel being spawned while the old channel winds down, or to force stop the old channel. It never needs to be used in a game situation.
You should just be spawning a new channel every time (FMOD_CHANNEL_FREE) and initialize with enough of them so they never get stolen (ie 1000 is a fairly normal voice init limit). The are all ‘virtual voices’ remember. The real, audible, mixed voices, are a subset of these and managed automatically by fmod (they are prioritized and swapped based on audibility and priority).
A channel handle just goes stale when the sound stops either by the API user, or by itself (a one shot).
If this happens, the channel starts returning FMOD_ERR_INVALID_HANDLE .. this is when your game object knows the channel is dead. Channel::isPlaying will return false and this error as well.
The engine wants to “create” a sound and set playback properties but not necessarily play those properties immediately. For example a scripted sound might get loaded but not be played until 30minutes later. (Engine architecture reasons outside of my control). So that runs the risk of a channel getting stolen. I’m under the impression that properties on channels are gone when the channel gets stolen. Is that indeed the case?
Channels dont get stolen unless you dont have a large initial channel count (ie 1000), but ones that go stale (ie they end) do get re-used, so the handle you hold will return FMOD_ERR_INVALID_HANDLE.
I guess you’re saying it could happen if you played all your sounds paused, and set the attributes on them, then waited 30 minutes. Can’t really answer that without profiling the game (ie would a 1000 paused sounds build up over time? I don’t know), but It would probably make sense to store attributes in your own struct which also stores the channel handle pointer, ready for when playsound has to happen. This is just your #2 case above that means.
- You must login to post comments
Please login first to submit.