Version
menu_open
Wwise SDK 2021.1.14
Offline Rendering with Wwise

Offline Rendering

The Wwise Sound Engine offers offline rendering that allows for non-real-time, compute-intensive audio generation and the synchronization of audio processing with compute-intensive video generation.

Caution: Care must be taken when enabling offline rendering in applications that use the synchronous AK::SoundEngine::LoadBank and AK::SoundEngine::UnloadBank APIs. See Audio Rendering Thread for details.

An audio capture callback can be registered using AK::SoundEngine::RegisterCaptureCallback, which provides a mechanism for accessing the rendered audio buffers.

The following is an example that illustrates one possible implementation of offline rendering:

/// Video capture services accessible in the game code
namespace VideoCaptureServices
{
/// Possibly allocates buffers for video capture
void Initialize();
/// Possibly outputs captured video and audio as a movie file
void Finalize();
/// Possibly captures a single video frame buffer to a file.
void CaptureSingleFrame();
}
/// Audio capture services accessible in the game code
namespace AudioCaptureServices
{
/// Allocates buffers or opens files for the eventual capture of audio samples.
void Initialize(unsigned in_uSampleRate, unsigned in_uChannels);
/// Releases buffers or file handles once audio sample capture is completed.
void Finalize();
/// Adds audio samples to the allocated buffers
void CaptureInterleavedSamples(float* in_pfSamples, unsigned in_uSampleCount);
}
class GameInterface
{
// ...
public:
/// Function called once per game frame
virtual void UpdateCallback(float deltaTime //< the elapsed time - wall clock time in real-time, approximately calculated in offline
) = 0;
};
class Game : public GameInterface
{
// ...
private:
/// True when offline rendering is enabled.
bool m_bIsOfflineRendering{ false };
/// Output device ID for registration/unregistration of capture callback.
AkOutputDeviceID m_defaultOutputDeviceId{ AK_INVALID_OUTPUT_DEVICE_ID };
/// Wwise audio capture callback.
static void CaptureCallback(AkAudioBuffer& in_CaptureBuffer, AkOutputDeviceID /*in_idOutput*/, void* /*in_pCookie*/)
{
const unsigned uSampleCount = static_cast<unsigned>(in_CaptureBuffer.uValidFrames) * in_CaptureBuffer.NumChannels();
if (!uSampleCount)
return;
AudioCaptureServices::CaptureInterleavedSamples(in_CaptureBuffer.GetInterleavedData(), uSampleCount);
}
public:
/// Function called to enable/disable offline rendering
void SetOfflineRendering(bool bIsOfflineRendering //< true for offline rendering, and false for real-time rendering
)
{
const bool bWasOfflineRendering{ m_bIsOfflineRendering };
m_bIsOfflineRendering = bIsOfflineRendering;
// Posts a message on the message queue to enable/disable offline rendering
AK::SoundEngine::SetOfflineRendering(m_bIsOfflineRendering);
if (m_bIsOfflineRendering == bWasOfflineRendering)
return;
// Posts a message on the message queue to set the offline rendering frame time to zero ensuring that the subsequent call to RenderAudio() will not generate more audio samples.
// Call RenderAudio() to flush the message queue. After this call, offline rendering will be enabled/disabled.
if (m_bIsOfflineRendering)
{
VideoCaptureServices::Initialize();
// Cache the output device ID for unregistration.
m_defaultOutputDeviceId = AK::SoundEngine::GetOutputID(AK_INVALID_UNIQUE_ID, 0);
AkChannelConfig channelConfig{};
Ak3DAudioSinkCapabilities audioSinkCapabilities{};
// Obtain the number of channels.
AK::SoundEngine::GetOutputDeviceConfiguration(m_defaultOutputDeviceId, channelConfig, audioSinkCapabilities);
const AkUInt32 uSampleRate{ AK::SoundEngine::GetSampleRate() };
// Provide the sample rate and number of channels to allocate the appropriate buffers.
AudioCaptureServices::Initialize(uSampleRate, channelConfig.uNumChannels);
AK::SoundEngine::RegisterCaptureCallback(&CaptureCallback, m_defaultOutputDeviceId, this);
}
else
{
AK::SoundEngine::UnregisterCaptureCallback(&CaptureCallback, m_defaultOutputDeviceId, this);
AudioCaptureServices::Finalize();
VideoCaptureServices::Finalize();
}
}
void UpdateCallback(float deltaTime) override
{
if (m_bIsOfflineRendering)
if (m_bIsOfflineRendering)
VideoCaptureServices::CaptureSingleFrame();
}
};
AKSOUNDENGINE_API AkUInt32 GetSampleRate()
AkForceInline AkUInt32 NumChannels() const
Get the number of channels.
Definition: AkCommonDefs.h:465
AKSOUNDENGINE_API AKRESULT SetOfflineRenderingFrameTime(AkReal32 in_fFrameTimeInSeconds)
AkUInt16 uValidFrames
Number of valid sample frames in the audio buffer.
Definition: AkCommonDefs.h:630
AKSOUNDENGINE_API AkOutputDeviceID GetOutputID(AkUniqueID in_idShareset, AkUInt32 in_idDevice)
AKSOUNDENGINE_API AKRESULT GetOutputDeviceConfiguration(AkOutputDeviceID in_idOutput, AkChannelConfig &io_channelConfig, Ak3DAudioSinkCapabilities &io_capabilities)
AKSOUNDENGINE_API AKRESULT RegisterCaptureCallback(AkCaptureCallbackFunc in_pfnCallback, AkOutputDeviceID in_idOutput=AK_INVALID_OUTPUT_DEVICE_ID, void *in_pCookie=NULL)
AKSOUNDENGINE_API AKRESULT RenderAudio(bool in_bAllowSyncRender=true)
AKSOUNDENGINE_API AKRESULT UnregisterCaptureCallback(AkCaptureCallbackFunc in_pfnCallback, AkOutputDeviceID in_idOutput=AK_INVALID_OUTPUT_DEVICE_ID, void *in_pCookie=NULL)
static const AkUInt32 AK_INVALID_OUTPUT_DEVICE_ID
Invalid Device ID.
Definition: AkTypes.h:114
static const AkUniqueID AK_INVALID_UNIQUE_ID
Invalid unique 32-bit ID.
Definition: AkTypes.h:102
AKSOUNDENGINE_API AKRESULT SetOfflineRendering(bool in_bEnableOfflineRendering)
uint32_t AkUInt32
Unsigned 32-bit integer.
Definition: AkTypes.h:59
AkUInt64 AkOutputDeviceID
Audio Output device ID.
Definition: AkTypes.h:94
AkForceInline void * GetInterleavedData()
Definition: AkCommonDefs.h:487

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