CriWare Unreal Engine
Plug-ins for CriWare solutions.
Loading...
Searching...
No Matches
ADX Resource Management.

Until now, the resources allocation settings was a meticoulus thing to setup correctly. CRI ADX plugin for Unreal 5 is using a different asset loading design depending how the sound is imported or played in editor, played in standalone mode or finally packaged then played on target platform with various file access design. Thus resources settings got more and more complex and difficult to handle.

To simplify and optimize resource allocations, some automatic management for ADX resources have been added:
UE5 CriWare plugin v2.3.0 introduces "Dynamic ADX voice pools management" to offer a better dynamic design depending the situation of the game engine, and game script actions.
UE5 CriWare plugin v2.4.0 introduces "Dynamic CRI FileSystem management" and a "Unique global voice pool" to offer a greatly simplified management of the loading and streaming resources used for sound playbacks.


Dynamic Voice Pools

Voice pools are a cluster of multiple source voices used to playback sound. In ADX they need to be fully defined before playing anything. A source voice may have a decoder to read input encoded sound data, a re-sampler, and a source effect chain. It is used by playback and outputs to buses.

A source voice can reads encoded data stored on-memory or from a file. The StreamingType determines the read access of all voices of a voice pool.
It exists 3 types of streaming:

  • Memory: Voice reads encoded sound data from memory.
  • Stream: Voice reads encoded sound from a file (througth Unreal IODispatcher or FileAsync).
  • Mixed: Voice can read encoded sound data from both memory and file.

Before 2.4: Design voice pools by worse case scenario.

  • 2 global voice pools: 1 for memory only, 1 for mixed (stream & memory).
  • Need to setup the voice pools depending the maximum number of channels, of sample rate and of concurrent sounds wanted to play.
  • Need to setup a maxium number of FileSystem binders big enough (with quite esoteric rules) to ensure data is loaded and streamed correctly at worst case senarios.

Problems

Finding the "worse case" is difficult or even impossible.

  • This model is not really compatible with the number of sounds and the streamed nature of a level in a game or 3D applications. This means that at A point in time the need for voice pool resources is different than at another B point in time, "worse case" is to find the point in time where some maximum ressource numbers are used.

"Worse case" settings are hard to calculate and the fixed nature of the pools contributes to a substantial lost of resources when they are, most of the time, not fully involved.

Editor, Standalone Play and Packaged Game use diffrent memory models in Engine.

  • Editor when loading asset is forced to load and play sound from memory. Indeed, the asset and its payload (ACB or AWB data) are not yet saved to disk. Then it may be streamed by editor (Plugin makes temporary memory copies in editor to ensure realiable data to work with.)
  • Project files are saved in archives (.uasset). Each one have a payload of data that is separatly loaded by editor, one after one.
    But once project is cooked and packaged, Unreal uses a global file that is read by chunk and caches of data for multi-streaming (IODIspatcher).
    Moreover, depending the target platform and thanks to SSD optimization speeds, it can even read data seamlessly-like from the file stream without the request of visible copies.

An "On Memory" Cue sound designed from Atom Craft have chanche to fight against the memory model of the target architecture by creating more copies.

To resume, Atom Craft Settings, Unreal Editor, Stanalone Play and Packaged Games for various target platforms and the game logic itself, makes the resource loading process different by context.
This asked for a more general but flexible model for resources used by Atom.

Introduction to dynamic voice pools

Dynamic voice pools are created and destructed on demand by the plugin.
A voice pool is linked to a unique sound source. The pool is created at playtime and freed when sound stops or at playend. Also the voice pool uses settings accordingly to the linked sound source.

Sounds that always use dynamically created voice pools.

Due to their "standalone" nature, all sound sources that are not a AtomSoundCue from an AtomCueSheet will generate a dynamic voice pool for playtime.

In detail, sound sources that use dynamically created voice pools are:

  • Waves from a WaveBank (AtomSoundWave).
  • Proceduraly generated sounds (AudioLink...) that do not read data from a file.
  • Externally controlled sounds creates their own voice pools. (Sofdec movies...)

Settings for a dynamically created voice pool (channels, sampling-rate x max pitch factor, memory type...) are set accordingly with sound source to play.

Atom Sound Cues - Global or Dynamic voice pool

Because Cues are designed externally by Atom Craft and use multiple waves and various playback design, we let the possibility to choose whether to use the global voice pool or let play AtomSoundCue from its own separated dynamic voice pool.

To setup this, each SoundCue have a setting in Voices section:

  • Check "use dynamic voices"
  • Set a voice limit (default is 1). If your Cue uses more that one voice concurrently, you can use this value as a limiter.

This will generate the voice pool for the sound source at next play of the cue. Setting of the pool is adjusted accordingly to the 1st waveform settings of the cue. Actually, one pool is created for each playback in Unreal.

Global voice pool

This is a unique global voice pool that can decode and play any SoundCue (streamed or on memory) and used for playback by default.

AtomSoundCue not using Dynamic Voices (Default) will be played over the global voice pool.

Global Voice Pool Settings are available in ProjectSettings for ADX Atom.

Alternatively, the "Forces Dynamic Voice Management for Sound Cue" checkbox will remove the Global Voice pool. Any AtomSoundCue will automatically be played using a dynamic voice pool.

Dynamic FileSystem Management

By default, ADX will allocate and free FileSystem resources when requested for voice pool creations or data loadings.


Nothing is required.

Manual CRI FileSytem settings (Not recommended)

In case you want to continue to allocate manualy the resources for CRI FileSystem at engine startup, Dynamic FileSystem Management can be disabled in ADX Atom section in Project Settings:

You need to setup a good number of FS Loaders and binders in CriWare Core settings to ensure all your sounds are loadable for any situations.

  • 1 loader/binder per concurrent voice to play.
  • 1 loader/binder per concurrent ACB and AWB to use.

Best Practices

Use dynamic voice pool for the right sounds

Multi-channel bgm and standalone Cues.

  • Instead of using a global voice pool with 8 channels for all voices, setup it with only 2 ch (stereo).
  • Use a dynamic voice pool for your BGM, particulary if it needs more than 2 voices.
    Note: Sound using a different voice pool may also prevent them to be virtualised/limited by ADX.

Optimize for OnMemory sounds

  • Using a dynamic voice pool for SoundCues that always play from memory copies. This permit to reduce the number of fixed voices allocated in the global voice pool.

Use the right memory setting in Atom Craft for waveform materials.

  • "Streaming" a sound is the default behaviour for Unreal Engine because packaged game data is streamed (IODispatcher).
  • "Low-latency Streaming" is the best option for Unreal Engine for low-latency playback sounds.
  • "Memory" is for sounds intended to be played inlined from memory (most of the time but they may be streamed also). This may use more memory since copies from Unreal to Atom are needed.
  • If a sound is intended to use high pitching values, the sampling rate of the voice pool need to be incrased. Using a dynamic voice pool for those sound avoid to set an high sampling rate to all voices of the global voice pool. Indeed, sampling rate of a dynamic voice pool is the source sampling rate multiplied by the global pitch factor from ADX Atom setup in project settings.

ADX resource loading and lifetime

ADX sound engine need to load and stream sound data to a source voice to play a sound.

The settings "Loading Behavior" from the details panel of AtomCueSheet or AtomWaveBank permits to control the loading/release time into ADX sound engine.


An AtomCueSheet own ACB data as payload that contain binary logic for cues and may also contain encoded soundwave data if set by Atom Craft.
An AtomWaveBank own AWB data as payload that contain encoded soundwave data. Only first chunk of soundwave data is loaded to ADX before play a sound then data is streamed or inline into memeory depending settings.

Unherited (Default)

The sound data will be loaded to ADX using the global rule defined by console variable 'atom.streamcache.AtomSoundBankDefaultLoadingBehavior'.
(0: Default (load on demand), 1: Retain audio data on load, 2: prime audio data on load, 3: load on demand (No audio data is loaded until a UAtomSoundBank is played or primed).)

Retain on Load

The sound data will be loaded to ADX when necessary, at the playback timing by AtomComponent.
Cue Sheet resources are not destroyed until the AtomCueSheet asset is destroyed.

Prime on Load

The sound data will be loaded to ADX at the same time than the asset is loaded.
Since, playback can be performed with few latency.

Load on Demand

The sound data will be loaded to ADX when necessary, at the playback timing from AtomComponent or when primed by PrimeSound() function call in CueSheet.
Therefore, if you try to play the Cue before the Cue Sheet is loaded, it will take little time until playback starts.

Force Inline

The sound data is loaded and fully copied into memory when the asset is loaded. ADX will access to it trough a read/write memory copy.

Attention
This setting should be used for developement purpose since it use a lot of memory.

Note: About usage of SoftObject for AtomSoundCue:
  • A SoftObjectPointer is created to control the loading time of the asset to Unreal. And that's it! Since an AtomSoundCue is a sub-object of an AtomCueSheet asset, when it is accessed it forces the AtomCueSheet asset to be loaded immediately in Unreal by dependency. However, its payload (ACB data) may be not loaded at this time.
  • ADX uses CRI FileSystem through Unreal loading managements (IODispatch) to access ACB or AWB payload of an AtomCueSheet or AtomWaveBank at different times to stream the sound data for playback.
    • This is controlled by the Loading Behaviour property of AtomCueSheet.
  • As a result, using SoftObject pointer or path for cues may not have loading performance impact except for "Retain on Load" Loading Bahaviour. This behaviour loads the ACB data into ADX at the same time the AtomSoundCue asset is loaded into Unreal. In the case AtomCueSheet only uses streamed data (wavebanks or hybrid loading from Atom Craft settings), it only loads the first chunk of data needed to start playback.