Version

menu_open

Tips to Reduce Memory Usage

It can be challenging to trim down memory pool sizes to fit your required limits. Here are a few tips to help reduce memory usage:

Default Pool Memory

The default pool memory is directly impacted by the number of sounds and events loaded in-memory (not the media, only structure) and the amount of game objects. It contains all the properties of the objects in your project necessary to implement the behaviors of the sound design. It also contains all the game objects and their related information (game syncs values, position, orientation, and so on). The more banks are loaded, the larger this pool needs to be. The size needed depends only on the number of sounds that can possibly be played in one scenario, level, map, game area, or the like. There are practices that can help reduce this memory:

  • Split big banks with lots of sound structures and events in smaller banks. Load and unload dynamically as needed. Regarding dialog banks, for example, avoid making banks that contain all lines for one character. Instead, group the dialog according to context.
  • Use the AK::SoundEngine::ExecuteActionOnEvent API to reduce the number of events. Play/Stop pairs can be replaced by a single Play event and a call to ExecuteActionOnEvent for the Stop and the Pause/Resume (it could be the same Play event).
  • Tightly manage your game objects. Unregister them as soon as their role is finished. Avoid keeping a pool of unused game objects alive; there is absolutely no gain in doing this, but it can cost in memory. For example, imagine an NPC dies. Unregister its game object; do not reuse it for something else. Register a brand new one when needed. As a general rule, if you have thousands of game objects alive, it is too many.
  • Do not use Actor-Mixers only to organize sounds. Folders and Work Units do not take memory, Actor-Mixers do. Unless they DO share similar properties that are not the default, then you save memory because the property is there once only. Of course, this also depends if the Actor-Mixer is referenced by events (such as SetVolume or SetPitch).
  • Try to reduce the size and complexity of large hierarchies. A common example of a large hierarchy would be an Impact hierarchy or a Footstep hierarchy. With lots of variables, it can grow large and take lots of memory for structure. Here are a few ways to reduce such a hierarchy:
    • Use RTPCs if the only thing changing in the switch is a simple property (same samples but different volume/pitch/randomizer etc.).
    • Split your Switch container hierarchy in multiple banks. In the bank manager, when you include a Switch container, all its sub branches are also included. However, you can exclude some of the branches manually in the SoundBank Editor view, on theGame Sync tab or in the Edit tab. For example, in a Footstep hierarchy, the first Switch variable could be the Surface Type. You could then split the Switch across different banks and load them depending on the context. You could have a main Footstep bank containing the surfaces that are encountered throughout the game, such as concrete and metal stairs in a city environment, and other contextual banks with specific surfaces, such as mud being used only in one scene/section of the game.
    • Replace some or all levels of the switch hierarchy with a Dialogue Event having equivalent Arguments. This is useful for variables that change often. For example, in an impact hierarchy, there is no predetermined surface that will be hit, you only know when the event occurs. Instead of using a Switch container (which needs to store the switch value), you could use a Dialogue Event with an Argument with the same possible values. The advantage is that the Dialogue Event can easily reuse the same sounds or substructures. Also, the Dialogue Event uses no memory per game object. Remember that you can link an argument path to a Switch container too, adding another level of variables. An example of that would be for footsteps. The Dialogue Event would have maybe one or two arguments, such as Surface Type and Step Type(Walk/Run), and each path could link to a Switch on "Footwear type" with values like "Boots", "Civilian shoes", and "Barefoot". The logic being that being the "Footwear" does not change often in the life of the game object, but the other 2 variables do. Replace impact-type variation WAV files with a SoundSeed Impact equivalent.
    • Replacing 10 different "clang" sounds with one is not only economical, it will give you more than 10 possible variations. Do not neglect this difference-making possibility.
  • Use "external sources" (Wwise v2010.1 and above) to reduce the overhead of sounds that do not need as much control as offered by the Wwise Actor-Mixer hierarchy. This is usually appropriate for voice-overs.

Lower Engine Pool Memory

The memory in the Lower Engine Pool is used to play sounds. It contains buffers to decompress, apply effects, and mix the audio sources. It is directly influenced by the number of sounds playing at the same time. It is also influenced by the number and type of effects that are used at the same time. To trim this down, you need to ask yourself how many sounds you want to hear at the same time. Some games will rarely have a scenario where more than 10 sounds are heard, others will have hundreds. You need to consider your worst case.

As a guideline, we have done some profiling on some games (on Xbox 360) and had the following numbers:

  • 1 MB will let you play approximately 50 to 80 voices
  • 2 MB will give 130 to 170 voices Although it scales mostly linearily, it really depends on which codec is used, how many effects, and other such factors. For example, using the Vorbis codec will use around 50% more memory per voice depending on the quality settings. Imagine 170 sounds at the same time: it is probably unintelligible and, therefore, useless. However, it takes some experimentation to find an ideal real number of voices for your game. Use the Memory tab of the profiler, profile multiple scenarios in your game, and note how much is used in resources.

To reduce the memory used in the lower engine pool, you need to reduce the number of simultaneous voices. This can be done using:

  • Playback Limits (Advanced Settings). For example, do you really need to hear 50 bullet ricochets? If not, maybe limit those sounds to say 15.
    Note.gif
    Note: You can set limits on busses as well.
  • Priority (Advanced Settings). For example, bullets could be less important than dialog. This means that bullets would get kicked first if there are too many sounds. Use in conjunction with Playback Limits.
  • Distance-based priority offset (Advanced Settings). Objects that are far are usually less important than closer ones. For example, again with bullets, we don't need to hear bullets that are 10 meters away if there are 15 other bullets sounds closer than that.
  • Memory threshold (code). There is a feature called the memory threshold. When initializing the sound engine pools, you can specify a percentage of the size of the pool at which voices will start to get killed based on priority. This will put a hard limit on memory that will avoid almost all Out Of Memory conditions in a nice controlled way. Note that memory can never be completely used because of fragmentation. A good starting value would be 0.9 (90%).
  • Below Threshold Behavior (Advanced Settings). The least expensive option (CPU and memory) is "Kill Voice", which is useful for non-looping sounds. The second preferred option is "Send To Virtual" "Play from beginning", then "Send To Virtual" "Resume" and then "Send To Virtual" "Play from elapsed time". "Continue to play" and "Play from elapsed time" are the most costly options, and Wwise's default value is "Continue To Play".
  • Volume Threshold (Project Settings). This will help kill the sounds too faint to be heard. This goes hand in hand with the Below Threshold Behavior and also the Attenuationsettings (farther usually means fainter).
    Note.gif
    Note: You can change the volume threshold programmatically at run-time. You may use this in game locations that are more process-heavy in order to send more voices to their "under volume threshold" state.
  • A change to the used codec settings (Conversion Settings). Vorbis needs extra memory to decompress audio. Different parameters can increase or reduce the amount needed. However, think carefully about the tradeoff: using a different codec or a weaker compression ratio will relieve the memory load in the Lower Pool but at the cost of larger files in memory, if they're in loaded banks. In some cases it's better to give an extra 500 KB to this pool to save a few MBs on audio data and, therefore, on the overall audio budget.
  • Fewer or lower quality. Some effects need a lot of memory to be processed. One very common memory consumer is the Reverb effect, in any of its available flavors. Realistically, your game should have very few reverbs running concurrently. As a rule, we suggest less than 4. Also, reducing the quality or length of the reverb will help.

Media Memory (banks)

The amount of memory taken by banks is mostly dictated by the sound data in it. Controlling the amount of memory used by your media can be done through:

  • Splitting big banks with lots of sound structures and events in smaller banks. Load and unload dynamically as needed.
  • Streaming more sounds from disk (Sounds' properties). Sounds that are latency sensitive can use prefetch media, which can be pre-loaded, or be streamed into cache on-demand using the PinEventInStreamCache API.
  • Using the PrepareEvent/UnprepareEvent API.
  • Compressing the audio more (Conversion Settings, codec, and so on).
  • Using a lower sampling rate. Also look at the Automatic Sample Rate Detection feature of the Conversion Settings.
  • Replacing impact-type sounds with a SoundSeed Impact plugin equivalent. Very useful to replace a Random Container with multiple variations in it.
    Note.gif
    Note: Non-impact sounds can have acceptable results sometimes too.
  • Replacing wind-type sounds with a SoundSeed Wind/Woosh plug-in equivalent. Wind ambiance tends to be long loops, which can take a lot of media space. Blades woosh, propellers, wind rushing in a car with open windows, ventilation noises, and so on can be modelled with this plug-in. Also consider non-windy applications: any noisy sound could be modeled. Examples: Ocean waves or the sound of a highway in the distance.

Was this page helpful?

Need Support?

Questions? Problems? Need more info? Contact us, and we can help!

Visit our Support page

Tell us about your project. We're here to help.

Register your project and we'll help you get started with no strings attached!

Get started with Wwise