Table of Contents

Adding Media to an Audio Plug-in

The plug-in media system allows a plug-in (effect, source, sink, or mixer) to store binary data files in the project by leveraging the Wwise architecture.

There are many benefits to using plug-in media as opposed to using custom data in the plug-in:

  • Built-in persistence of data
  • Source Control integration (using work-group features)
  • Per platform specific conversion of data allowed
  • End-user selection of SoundBanks to hold the data allowed

Wwise Authoring Plug-in

Managing Plug-in Media

Override the function AK::Wwise::IAudioPlugin::SetPluginObjectMedia and store the pointer for later use. This function will be called at the initialization of the Wwise plug-in (authoring side). By implementing this function, you will receive an interface to an IPluginObjectMedia*, which allows to you to manage media files.

class MyPlugin : public AK::Wwise::IAudioPlugin
{
    ...
    virtual void SetPluginObjectMedia( IPluginObjectMedia * in_pObjectMedia )
    {
        m_pObjMedia = in_pObjectMedia;
    }

    AK::Wwise::IPluginObjectMedia * m_pObjMedia;
}

You can import media files by calling AK::Wwise::IPluginObjectMedia::SetMediaSource. When importing media, they will be copied to the plug-in's Original directory and will be managed completely by Wwise. To add a plug-in media file at index 0:

m_pObjMedia->SetMediaSource( tszFilename, 0, bReplace );

Later, you can call AK::Wwise::IPluginObjectMedia::InvalidateMediaSource to request a conversion of the media files. Override the function to be notified when the plug-in data changes.

virtual void NotifyPluginMediaChanged()
{
    // React to changes
    // ...
    
    // Notify Wwise the data needs to be reconverted
    m_pPSet->NotifyInternalDataChanged( AK::IAkPluginParam::ALL_PLUGIN_DATA_ID );
}

Refer to documentation of functions of AK::Wwise::IPluginObjectMedia for more information.

Converting the Media for Runtime

You may want to convert your media for runtime. To implement conversion functions, you need to inherit from AK::Wwise::IPluginMediaConverter and implement the required functions (including ConvertFile and GetCurrentConversionSettingsHash) that will allow you to convert your imported original WAV to an appropriate format for the real-time component.

class MyPlugin : public AK::Wwise::IAudioPlugin , public AK::Wwise::IPluginMediaConverter

Once you implement all functions in AK::Wwise::IPluginMediaConverter, you can override the function GetPluginMediaConverterInterface() to tell Wwise you want to convert your media.

virtual AK::Wwise::IPluginMediaConverter* GetPluginMediaConverterInterface()
{
    return this;
}

Here is an example implementation of the AK::Wwise::IPluginMediaConverter functions:

#include "AK\Tools\Common\AkFNVHash.h"
 
AK::Wwise::ConversionResult YourPlugin::ConvertFile( 
    const GUID & in_guidPlatform,
    const BasePlatformID & in_basePlatform,
    LPCWSTR in_szSourceFile,
    LPCWSTR in_szDestFile,
    AkUInt32 in_uSampleRate, 
    AkUInt32 in_uBlockLength, 
    AK::Wwise::IProgress* in_pProgress, 
    AK::Wwise::IWriteString* io_pError ) 
{
    // Convert the original source to a converted file.
    // At minimum, copy the original file to converted
    ::CopyFile(in_szSourceFile,in_szDestFile, FALSE);
    return AK::Wwise::ConversionSuccess;
}
 
ULONG YourPlugin::GetCurrentConversionSettingsHash( const GUID & in_guidPlatform, AkUInt32 in_uSampleRate ,  AkUInt32 in_uBlockLength ) 
{
    AK::FNVHash32 hashFunc;

    // Generate a Hash from parameters that have an influence on the conversion.
    // Take the source file name.
    CString szInputFileName;
    m_pObjMedia->GetMediaSourceFileName( szInputFileName.GetBuffer( _MAX_PATH ), _MAX_PATH );
    szInputFileName.ReleaseBuffer();
    szInputFileName.MakeLower();
    return hashFunc.Compute( (unsigned char *)(LPCTSTR)szInputFileName, szInputFileName.GetLength()*sizeof(TCHAR) ); 
}

Plug-in Definition

In the plug-in definition file, ensure you have the CanReferenceDataFile element set to true.

<PluginModule>
    <EffectMixerSourceOrSinkPlugin Name="YOUR_PLUGIN" CompanyID="???" PluginID="???">
        <PluginInfo MenuPath="???">
            <PlatformSupport>
                <Platform Name="Windows">
...
                    <CanReferenceDataFile>true</CanReferenceDataFile>
                </Platform>
                <Platform Name="XboxOne">
...
                    <CanReferenceDataFile>true</CanReferenceDataFile>
                </Platform>

Runtime Plug-In

Using Plug-in Media at Runtime

In the real-time component of your plug-in, when implementing AK::IAkEffectPlugin, you will receive an AK::IAkEffectPluginContext pointer in the Init(...) function. From the AK::IAkEffectPluginContext, you can call AK::IAkPluginContextBase::GetPluginMedia to obtain the converted media that was packaged in Wwise SoundBanks.

AKRESULT RunTimeEffect::Init(
    AK::IAkPluginMemAlloc* in_pAllocator,       // Memory allocator interface.
    AK::IAkEffectPluginContext* in_pFXCtx,      // FX Context.
    const AkAudioFormat& in_rFormat             // Audio input format. )
{
    AkUInt8 * pPluginData = NULL;
    AkUInt32 uPluginDataSize;
    in_pFXCtx->GetPluginMedia( 0, pPluginData, uPluginDataSize );
    if ( pPluginData == NULL )
        return AK_Fail; // No point in instantiating plug-in without impulse response.
    ...
}
Note.gif
Note: This example shows how to use effect plug-in media at runtime. However, it could just as easily be illustrating how to use another plug-in type, such as a source plug-in. In that case, you'd be implementing AK::IAkSourcePlugin and receiving an AK::IAkSourcePluginContext pointer.

Usage in Wwise

Using Plug-in Media in Effects Inside Bus

In Wwise, all bus Effects are stored in the Init.bnk. To avoid having the Init.bnk be too large, the plug-in media is not automatically added to Init.bnk. You will need to manually add the Effect ShareSet or the bus to a separate SoundBank.