Optimizing Memory Pools

Wwise has two memory pools:

  • Default: A general-usage pool for high-level sound structures. When loading banks, this is where the non-WAV data ends up. Game objects and their related positioning and RTPC data structures are also stored here. It also contains the command queue where posted events are stored before being processed by the audio thread. Finally, it contains a small amount of high-level per-voice playback data.
  • Lower engine: The main audio processing pipeline pool, essentially empty when nothing is playing. Here are allocated all the intermediate processing buffers for things such as decompression, format-conversion, pitch-shifting, effect processing, and mixing.

Determining an Appropriate Size for Your Memory Pools

The default size of the internal memory pools of the sound engine are very large only to ensure that anyone who tries the sound engine for the first time has enough resources to run their worst-case scenario. The default size for each pool is:

Note: If you use the sample code to integrate the streaming manager, 8 MB are also allocated for the streaming buffers (Stream I/O).

The size of the default memory pool will ultimately depend on the type of game you are creating. For example, if your game has gigabytes of audio assets but rarely plays more than four or five sounds at a time, with no or few effects, then the memory requirements of the default memory pool may be larger, but the requirements of the lower engine memory pool may be smaller. If, on the other hand, your game has few sounds but plays them all simultaneously with lots of reverb, echo, and other environmental effects, like in a first-person shooter, then the memory requirements of the default memory pool may be smaller, but the requirements of the lower engine memory pool may be larger. The size of the lower engine memory pool will ultimately depend on what you plan to do with the sound engine. If your game will play a lot of voices simultaneously (including virtual voices) and will be processing a large number of effects, then you will need more memory in this pool.

Setting the Size of Your Memory Pools

On PC, with no banks loaded or sounds playing, the amount of memory used should be around 150 KB. You can see the exact amount in Wwise by switching to the Profiler layout and looking at the Total Used Memory value in the Performance Monitor. This value will go up with the number of assets loaded, voices playing, game object positions, and so on.

The required size of your memory pools will depend on a number of different factors, including the quality of your audio, the number of sounds loaded, the number of voices playing simultaneously, the complexity of your sound structures, the encoding method chosen, the type and number of effects that require processing, the number of 3D positioned sounds, switches, and so on.

The only reliable way to know how much memory is required is to do the following:

  1. Assign an arbitrary amount of memory to the pools. If you can, start by using the default memory sizes.
  2. Connect Wwise to your game.
  3. Run a busy game scenario with the Profile version of the sound engine.
  4. Look at the Memory tab of the Advanced Profiler. The Peak Used column should give you a good indication of what the pool sizes should be.

Typically, the optimal size for each pool is 15-20% above the peak memory usage value.

Debug-only allocations are made in the Communications, Monitor, and Monitor Queue memory pools, which are not created in the Release version. Subtracting the size of these pools should give you a good idea of the release-version memory usage.

Note: You can also explore sound engine memory usage in the Memory tab by capturing profile information from Wwise itself without connecting to a game.

What Size Should I Use to Get Started?

In most cases, it is best to start off using the default memory pool sizes (16 MB per pool). By having such large pool sizes, you can easily find out what your real memory usage is and then you can trim down the pools accordingly. If you are more restricted in the amount of memory you can assign to these pools (16 MB is too much), you can start by using the following values:

  • Default memory pool: 2 MB
  • Lower engine memory pool: 2 MB
  • Streaming management: 2 MB

2 MB per pool should be enough to cover most, if not all, of your scenarios. The streaming buffer size will depend on if you plan to stream a lot of sounds, the quality of the sounds, and the safety timeline of the streaming sounds. The default value of 8 MB would generally be seen as a waste of memory for most games, but again it is best to start out large and trim down as your memory usage becomes clearer. For more information on streaming buffer memory, refer to Audiokinetic Stream Manager Initialization Settings.

Memory Pool Sizes and Platforms

When setting the pool size for each platform, it is important to understand that the size of a memory pool depends much more on audio content and usage than it does on the platform. This means that you can use the same pool sizes to start with and then tailor them to the particular platform using the memory readings in the Advanced Profiler.

What is the optimal size to set for each memory pool? This depends on many things, including:

  • File format used
  • Maximum number of sounds that can be played at one time
  • Number of sounds pre-loaded using banks
  • Effects used
  • Rate of Events/RTPC/position updates per second
  • Speaker setup selected (especially on PC )
  • And other related considerations

Choosing Worst Case Scenarios for Testing

Each memory pool may have a different worst case scenario. For example, playing sixty-four sounds at once greatly increases usage of the lower engine pool while only slightly increasing usage of the upper one. On the other hand, loading twenty banks all at once increases upper engine memory usage without affecting lower memory pool usage. Therefore, we recommend that you don’t use just one worst case scenario for all your tests, because other situations may use memory differently.

One particular situation to test occurs when SoundBanks are loaded and unloaded between levels, because this causes a peak in the upper memory pool. For example, if the banks from Level 1 and Level 2 of a game can both be loaded at the same time for a brief interval, this peaking may occur.

Warning: When performing tests to check peak memory usage for PC, you must ensure that the speaker setup configuration of the PC running the game is set to 5.1 or better. This is necessary because the sound engine performs some optimizations when the speaker setup is stereo, and therefore may use less memory than in 5.1.

Running out of Memory

The sound engine reacts differently to "out of memory" conditions depending on when the condition occurs. For example, here is what happens when memory is missing in the following scenarios:

  • Sound engine initialization: The initialization fails.
  • Loading a bank: The bank load fails.
  • Starting a transition for a parameter, such as volume: The transition is skipped and the parameter jumps directly to the target value without transition.
  • Playing a sound: Either the play fails or another playback with lower priority is stopped to free memory for the new one.

Detecting Memory Problems

When you use the Wwise Profiler, a warning notification is sent to the capture log for every allocation failure that occurs in the game. You can check this list of notifications to find out which memory pools were lacking in memory at each point during gameplay.

Causes of High Memory Usage

The following items can cause high memory usage:

  • Loading banks increases Default memory pool usage. Note that each bank uses a different amount of memory. Memory used by a bank in the Default memory pool does not depend on the physical size of the bank but on the number of sounds and events that it contains.
  • Some effects, including reverb and delay, consume a certain amount of memory when playing.
  • Playing multiple sounds at once drastically increases the amount of memory used in the Lower Engine Default pool.
  • Sending multiple actions in a short amount of time increases the memory usage of the Default pool.
  • Registering game objects, setting "per object" parameters, and setting object positions all use a small amount of memory in the Default pool. However, be aware that unused game objects must be unregistered to free up this memory. Otherwise, the amount of memory being used constantly increases.

More details are available in the following sections:

Defining a Memory Threshold

When initializing the sound engine, you have the option to define a memory threshold for one or more of the sound engine's memory pools.

You can define a threshold for a memory pool by modifying the values in the initialization parameters of the sound engine: AkInitSettings::fDefaultPoolRatioThreshold and AkPlatformInitSettings::fLEngineDefaultPoolRatioThreshold

By default, the memory threshold is disabled, by using a default value of 1 (or 100%). You can enable it by setting a value ranging anywhere between 0 and 1.

When the memory threshold is disabled, the memory allocator will work normally. When enabled, the engine periodically checks that the percentage of memory being used is below the specified threshold. If it goes over the threshold, the system will start dropping sounds with the lowest priority.

In situations where the memory threshold is not used, the engine will honor priorities of sounds, but in low-memory conditions, the engine may not have enough memory to play a sound with a high priority, which means that it would get dropped. When the memory threshold is used, sounds with lower priorities will be dropped to free up space for the higher priority sound.

In general, you will define a threshold for the AkPlatformInitSettings::fLEngineDefaultPoolRatioThreshold parameter. Setting a threshold on the AkInitSettings::fDefaultPoolRatioThreshold parameter could result in unexpected behaviors because it is also used to load banks.

See also: