Events still messing with virtual voice system after being stopped


we’re working on a racing sim and we’ve had a ton of problems with FMOD virtual voice system. We create a lot of events, and thus lots of Software channels, each with accurately tuned and tested min and max distances, volumes, positions in the 3D world, etc. We thought the library could work out with relative ease which Soft channels elect to be Real channels with these informations, as the documentation says; however, it never worked well, for example we kept having the engine of the player’s car (that has higher priority and is just in front of the camera) going silent for some fractions of a second, because an opponent’s engine was being picked up as a Real voice even though the opponent was at the other side of the track. We’re pretty sure this was reason, because we carefully looked at the FMOD Profiler and the performance stats; the player’s car engine is a specific event that is the only one with “High” priority, and still it was turned off (i.e. it was grey in the profiler graph).

In the end, we pretty much fixed the problem by calling stop() on the events whenever their distance from the listener was greater than their max distance (common sense would suggest the library would do that - why even consider a Soft channel to be Real if it belongs to an event that is outside max range?)

However, we still have another problem now. The car that the player is driving (or, better, the camera is focused on) has a richer sound than the others, i.e. we create more events for it, for example trasmission noise. If the player switches camera from a car to another, we stop() those “extra” events on the old car and start() them on the other. The problem happens when you’re on the starting grid: if you switch from car to car and then return to your own to start the race, the number of virtual channels (as shown in FMOD Profiler) is very high, much higher than before switching the cameras around, and I hear those “click” sounds of old due to having too many channels (and the library not being able to pick the important ones). I can see those events that were started and then stopped still lingering in the profiler graph view.

I would expect calling stop() on a event to pretty much kill it good, if not in terms of memory usage at least in terms of scheduling and occupancy of slots in the virtual voice system. Can you shed some light?

Best regards

Regarding the virtual voice system, there are some initialization settings we should make sure are set up optimally. The first is the number of software channels (aka real voices), which is set into the low level as setSoftwareChannels. A reasonable number for a large scale PC and current gen consoles would be somewhere in the range of 64-128, with it being a trade-off against worst case mixer performance.

You should also set the same number of codecs into the FMOD_ADVANCEDSETTING struct. So if you picked 70 software channels to use, then on PC normally you would set maxVorbisCodecs to 70 as well. For consoles it would be maxAT9Codecs or maxXMACodecs. For lower end mobile title you’d typically use ADPCM and have a smaller number of voices reflecting the weaker CPU on those systems.

Another startup factor is the total channel count, for large scale games this can be 256 or more. That is the number passed into sytem->initialize(). You generally want to avoid running out of virtual channels.

Another important initialization setting to enable is FMOD_INIT_VOL0_BECOMES_VIRTUAL, with a corresponding advanced setting vol0virtualvol (say 0.001). Without this, a channel will never go virtual even if it is silent or paused. That can be particularly bad in combination with priority setting because the higher priority (but silent) channel will still stay allocated.

In terms of what goes into the audibility calculation - it should be the entire mix hiearchy, including volumes, sends/returns, DSP pan attenuation and even custom DSP effects. The peak volume of the sound is also factored into the calculation. So it is not an expected situation that close, loud, high priority sounds would ever be stolen for quieter lower priority sounds.

In terms of stopping events, it is normal and unavoidable that there might be some brief overlap before the old event’s virtual channels become free. Stop with fadeout also has some extra delay if there are ADHSR that are fading out. If you have something that is staying “alive” a significant beyond that then it definitely isn’t normal.

If you have set everything up to what you expect is a proper set up and still can’t achieve a good result, then the next step would be to contact and we can follow up some some profile captures (and possibly API captures + banks) to dig into what is happening in your particular case.

1 Like
  1. For a while, we tried to set the number of software channels to 128 (instead of the original 64) but we had compatibility problems. That is, it was happening that users played the game without issues for a while, and then the audio went completely silent in a sudden. After a bit of investigation we thought that it was because of sound cards/drivers that don’t support that amount of channels; going back to 64 real voices “fixed” the problem.

  2. We use ADPCM (or PCM, can’t remember) so we don’t set any codecs option. At the moment we don’t have memory problems, and on the other hand we need all the available CPU time and audio quality we can get (some of our users run the game at 120-180 fps), so using a compressed format would be quite pointless for us.

  3. Our virtual channel count is set to 1024. Very often we have races with 500+ virtual channels, so we set it pretty much double that to avoid running out of channels.

  4. We used FMOD_INIT_VOL0_BECOMES_VIRTUAL for a while, and that was very good for the channel stealing problem, but that flag carried its own set of issues with it, so we disabled it. We couldn’t find a value for vol0virtualvol that was working right (we tried a bunch of values between 0.001 and 0.00001): it was either too small, thus having a negligible effect at all, or too big, causing sound “holes”, i.e. engine audio events going silent for fractions of seconds because their volume was going under the threshold (evident with car engine events, whose volume varies with rpms/throttle). But hold on, doesn’t “without this, a channel will never go virtual even if it is silent or paused” mean the virtual voice system is pretty much ineffective with the flag (i.e. channels are never “elected” to be real or virtual based on context)? If that’s the case, I think it should be made clearer.

  5. Yes, we definitely do have channels that stay “alive” (or at least present in the DSP graph) even after we’ve stopped them. When we have time we’ll do a more thoroughly investigation and report back.

Best regards