ATL for Programmers

Overview

All requests to the Audio System are handled through the PushRequest method. The caller needs to create an SAudioRequest instance, fill in the desired fields and send it to the AudioSystem via the PushRequest method call. The request data is immediately copied for internal storage and processing, so it is safe to delete an SAudioRequest instance and all related objects after the PushRequest call has returned. Internally, the request queue is processed on the Audio Thread, so only the PushRequest is executed on the Main Thread. The PushRequest interface method has been designed to be extremely light weight and to not put any unnecessary additional waiting time onto the calling thread. However, the caller does have the freedom of choosing whether the call should be executed in a blocking and/or thread safe fashion via available PushRequest flags.

ATL High Level Overview

Audio System Architecture

The Audio System is split into three largely independent layers: CAudioSystem, CAudioTranslationLayer and IAudioSystemImplementation.

CAudioSystem

Represents the Audio System’s interface to the outside world. It holds methods for looking up (or reserving) ID's for various objects and the PushRequest method – the only way to request an action from the Audio System. This class contains the message queues and handles the scheduling and dispatch of the incoming requests. It also manages the Main Audio Thread.

CAudioTranslationLayer

keeps track of the Audio System’s current state (the registered AudioObjects, AudioListeners, active AudioEvents, etc.) and processes the requests submitted through the PushRequest method.

IAudioSystemImplementation

Represents an interface to an Audio Middleware. Currently we provide our implementation of the interface in the CryAudioImplWwise project that can be found inside the CryAudio/Implementations/ filter of the CryEngine solution. While processing the incoming requests, CAudioTranslationLayer calls the appropriate method of IAudioSystemImplementation and if the call succeeds, records all of the resulting changes in the AudioSystem state.

Creating an AudioSystemImplementation

Because an Audio System Implementation is provided as a separate ENGINE module, it is now possible to create your own implementation of the IAudioSystemImplementation interface and configure CRYENGINE to use it for rendering Audio. This section describes the necessary steps.

Project

  • Create a new Visual Studio project inside CryAudio/Implementations. It probably makes sense to create a physical folder inside of Code\CryEngine\CrySoundSystem\implementations and put all of the project files in there. The .vcxproj file needs to use several engine-specific .props files and needs to support the same Platforms and Configurations as the rest of the projects. It is easiest to copy an existing .vcsproj file (for e.g. Code\CryEngine\CrySoundSystem\implementations\CryAudioImplWwise\CryAudioImplWwise.vcxproj) and adjust it to include the correct files.
  • If you put your project into a folder inside CrySoundSystem\implementations\ then add the path to CryAudioCommon files ($(ProjectDir)..\..\common\ in the Additional Include Directories in the project properties.
  • In the References section of the Common Properties of the PCLauncher project replace the existing CryAudioImplWwise with your new project. For building the PCLauncher in Release Configuration you also need to add your project-specific library paths to the AdditionalLibraryDirectories property of PCLauncher project. Do the same for all of the Launcher projects and for the platforms your game supports (DurangoLauncher, OrbisLauncher, etc.)
  • Make sure the Configuration Manager settings of your new project match those of CrySoundSystem project on all platforms and for all configurations. Again, it is easiest to manually copy the configuration lines corresponding to the CrySoundSystem GUID in the .sln file and replace the GUID with the one assigned to your new project.
  • Adjust the BaseAddress.Win32.txt, BaseAddress.x64.txt, BaseAddress.Durango.txt (if needed) and possibly other platform-specific BaseAddress files to make sure that your new module gets enough memory when loaded dynamically.

CRYENGINE

In system.cfg set s_AudioImplementationName to the string with the name of the dll generated by your project (usually it is the same as the Visual Studio project name).

CryAudioCommon

CryAudioCommon is a header-only project that contains the headers shared between the CrySoundSystem and all of the Audio Implementations.

ATLEntityData.h contains the definitions of the data-types used in the IAudioSystemInterface. Only SATLAudioFileEntryInfo and SAudioImplMemoryInfo are meant to be accessed both in the CrySoundSystem and in an AudioSystemImplementation, so they have to be PODs. All other interfaces (IATLAudioObjectData, IATLEventData, etc.) are meant to be derived from/by the specific AudioSystemImplementation to store per-instance information necessary to handle the corresponding ATLEntities correctly. The objects implementing those interfaces are created and managed by the AudioSystemImplementation - the ATL only stores the pointers to them which it never accesses. This guarantees that no non-POD objects are shared between the modules.

AudioLogger.h defines a small utility logger class which adds an <Audio> tag and a timestamp to all of the logged messages.

IAudioSystemImplementation.h defines an IAudioSystemImplementation interface that describes the interactions between the ATL and an audio middleware. The full documentation for this interface can be found here.

SoundAllocator.h and STLSoundAllocator.h provide some useful memory management utilities.

Using EntityAudioProxies

Coming soon

Using AudioProxies

Coming soon

Using the AudioSystem interface directly

Coming soon