目次

Wwise プラグイン DLL の作成方法

Wwise プラグイン DLL には以下が含まれています:

Note.gif
Note: 1つのDLLに複数のプラグインを含むことができます。詳細は エクスポート関数 および Wwiseプラグイン XML 記述ファイル をご覧ください。

サウンドエンジンエフェクトがプラグインDLLとリンクしているスタティックライブラリに実装され、ゲーム内のリンクのために再利用されるよう、プロジェクトを組織化することをお勧めします。例えば、Wwiseで提供されるサンプルプラグイン(サンプル)がどのように組織化されているかをご覧になってみてください。

Wwise プラグインオブジェクト

インターフェースのメソッドを全て実装する AK::Wwise::IAudioPlugin から派生したクラスを作成する必要があります。このクラスは、ご使用プラグインの UI および SoundBank 生成に関連するすべてを管理します。

#include <AK/Wwise/AudioPlugin.h>

class SinePlugin
    : public AK::Wwise::IAudioPlugin
{
public:
    // All AK::Wwise::IAudioPlugin interface methods ...
    (...)

    // CompanyID and PluginID as defined in the XML file
    static const short CompanyID;
    static const short PluginID;

private:
    AK::Wwise::IPluginPropertySet * m_pPSet;
};

AK::Wwise::IAudioPlugin の関数を実装すると、Wwise の様々な状況に対するプラグインの動作が定義されます。関数によって、プラグインの以下のような状況への対応を可能にします:

  • プロパティセットインスタンスがプラグインにアタッチされている。
  • プロパティが変更されている。
  • Wwise ユーザーが別のプラットフォームを選択。
  • プラグインが SoundBank にパッケージ化されている。
  • Wwise ユーザーがプラグインと連動するダイアログをオープン。
  • Wwise にユーザーフレンドリーなプロパティまたはプロパティ値の名前を表示させたい。
  • Wwiseユーザーがオンライン Help を要求。
  • プラグインインスタンスが破棄されている。

これらのトピックのうちのいくつかは、以下のセクションで説明しますが、インターフェースと関数に関する詳細な説明は AK::Wwise::IAudioPlugin リファレンスをご覧ください。

プラグインインスタンスの破棄

Wwise ユーザーがソースやエフェクトプラグインのインスタンスを作成すると、Wwise はDLL 内の AkCreatePlugin() 関数(エクスポート関数)を呼び出して新しいインスタンスを作成します。プラグインのインスタンスをユーザーが 破棄 すると、Wwise はこの特定のインスタンス上に AK::Wwise::IPluginBase::Destroy() メソッドを呼び出します。このメソッドはオブジェクトが消費する可能性のあるメモリやその他のリソースを解放し、オブジェクト自体を削除します。

インスタンスが演算子 new で作成された場合、AKWwise::IPluginBase::Destroy() の典型的な実装は以下のようなものです:

void SinePlugin::Destroy()
{
    delete this;
}

AK::Wwise::IPluginPropertySet インスタンスのプラグインへのアタッチ

AK::Wwise::IPluginPropertySet のインスタンスは、プラグインの各インスタンスに対して自動的に作成されるので、プロパティサポートをご自身で実装する必要はありません。プラグインのインスタンスが作成されると、AKWwise::IPluginPropertySet インスタンスへのポインタを用いて、AKWwise::IAudioPlugin::SetPluginPropertySet() がプラグイン上に呼び出されます。

このポインタをメンバとして保持するために、プラグインオブジェクトをコーディングし、これを必要な時にクエリできるようにしてください。例えば、AKWwise::IAudioPlugin::GetBankParameters() の実装でクエリすることも可能です。詳細は、サウンドバンクの生成 をご覧ください:

Note.gif
Note: AK::Wwise::IAudioPlugin::SetPluginPropertySet() より受け取られる AK::Wwise::IPluginPropertySet のインスタンスは、AKWwise::IPluginBase::Destroy() がプラグインに呼び出されるまで有効であることが保証されています。

複雑なプロパティの使用

ご使用のプラグインが、シンプルプロパティの代わりに曲線やグラフなどの洗練されたデータを使用している場合、プロパティセットはこれを保持することができません。従って、これをプラグインクラスに保持し、AKWwise::IPluginPropertySet::NotifyInternalDataChanged() を使用して Wwise に特定のデータが変更されたことを通知する必要があります。これにより、Wwise はデータが保存またはサウンドエンジンに転送されなければならないことを認識します。このタイプのデータに関しては、プラグインの XMLでは何も定義しないでください。NotifyInternalDataChanged を呼び出す時、ParamID を指定してデータのサブセットに通知を制限することができます。すべてのデータが変更されたことを指定するには、AKIAkPluginParam::ALL_PLUGIN_DATA_ID を使用してください。

Note.gif
Note: XMLで宣言されているシンプルプロパティに対して、NotifyInternalDataChanged を使用しないでください。AKWwise::IPluginPropertySet::SetValue が使用されると通知が自動的に行われます。

ユーザーが複雑なプロパティを変更して、NotifyInternalDataChanged を呼び出すと、Wwise は AK::Wwise::IAudioPlugin::GetPluginData を介して、ご使用のプラグインのサウンドエンジン部分へ転送されるデータブロックを取得するためにコールバックします。サウンドエンジンプラグインは AK::IAkPluginParam::SetParam を介して、NotifyInternalDataChanged で指定されている ParamID で、ブロックを受け取ります。

Note.gif
Note: 複雑なプロパティを使用する場合、AKIAkPluginParam::SetParam と AK::Wwise::IAudioPlugin::GetPluginData 内の AK::IAkPluginParam::ALL_PLUGIN_DATA_ID を処理する必要があります。これは、プラグインが最初に再生される時に、少なくとも一度だけ使用されます。

プラグインのパラメータのロードと保存は、プラグインが XML でそのプロパティを宣言する時に自動的に行われます。しかしながら、複雑なデータに対しては、独自の永続性コードを提供する必要があります。これを行うには、AKWwise::IAudioPlugin::Save と AK::Wwise::IAudioPlugin::Load をオーバーライドします。更なる詳細は、AKIXmlTextReader と AK::IXmlTextWriter をご覧ください。プロジェクトがソース管理下にある場合、ファイルのマージを容易にするためにデータを XMLで保存することをお勧めします。また、プラグインコードは、データのバージョン管理を処理します。プラグインが、ロード可能または不可能なデータのバージョンを認識していることを確認し、クラッシュやデータ破損の発生を避けるようにしてください。

Wwise ユーザーによるプロパティ値の変更

Wwise ユーザーは、直接ダイアログ内のコントロールを介して、または、undo/redo(元に戻す/やり直し)コマンドを使用して、プロパティ値を変更することができます。ユーザーがプロパティ値を変更すると、 AKWwise::IAudioPlugin::NotifyPropertyChanged() がプラグイン上に呼び出されます。ダイアログがその時点で表示されている場合は、コントロールを有効または無効にすると言うような実行するアクションをダイアログで指定することができます。

Wwise ユーザーによる現行プラットフォームの変更

Wwise ユーザーが、ドロップダウンリストまたはキーボードショートカットを使用して現行プラットフォームを変更すると、AKWwise::IAudioPlugin::NotifyCurrentPlatformChanged() メソッドへの呼び出しにより、ご使用プラグインのインスタンスに通知されます。従って、もしもこの時ダイアログが表示されている場合には、これを新しい現行プラットフォームに適応させることが可能です。

サウンドバンクの生成

要求があるとプラグインをコーディングして、現行の設定をバンクに保存する必要があります。これは、AKWwise::IAudioPlugin::GetBankParameters() メソッドを実装することにより実行可能です。

パラメータは、データブロックとしてサウンドバンクに書き込まれます。続いて、ブロックはサウンドバンクから直接サウンドエンジンプラグインのパラメータ構造体にロードされます。従って、サウンドエンジンプラグインのパラメータ構造体で宣言されているのと同じ順序でパラメータを記述する必要があります。 詳細は、パラメータ ノード インターフェイスの実装 をご覧ください。

例えば、次のパラメータ構造体を見てみましょう:

// Parameter structure for this effect.
struct AkFXSrcSineParams
{
    AkReal32     fFrequency;     // Frequency (in Hertz).
    AkReal32     fGain;          // Gain (in dBFS).
    AkReal32     fDuration;      // Sustain duration (only valid if finite).
};

以下の AK::Wwise::IAudioPlugin::GetBankParameters() の実装では、各プロパティの現在の値を取得し、適切なメソッドを使用して、パラメータとして受け取った AK::Wwise::IWriteData オブジェクトで値を記述します。これらのアクションは、メンバがパラメータ構造体で定義された順序と同じ順序で実行されます。

bool SinePlugin::GetBankParameters( const GUID & in_guidPlatform, AK::Wwise::IWriteData* in_pDataWriter ) const
{
    CComVariant varProp;
    m_pPSet->GetValue( in_guidPlatform, szSineFreq, varProp );
    in_pDataWriter->WriteReal32( varProp.fltVal );
    
    m_pPSet->GetValue( in_guidPlatform, szSineGain, varProp );
    in_pDataWriter->WriteReal32( varProp.fltVal );

    m_pPSet->GetValue( in_guidPlatform, szSineDuration, varProp );
    in_pDataWriter->WriteReal32( varProp.fltVal );
    return true;
}
Note.gif
Note: プロパティの現在の値を取得するには、AKWwise::IAudioPlugin::SetPluginPropertySet()) を介してプラグインにアサインされた AK::Wwise::IPluginPropertySet のインスタンス上に AK::Wwise::IPluginPropertySet::GetValue() を呼び出します。

異なるタイプのデータ記述に利用可能なメソッドに関する詳細については、AK::Wwise::IWriteData を参照してください。

ダイアログ関連コード

DLLには、プラグインのプロパティ編集のために Wwise ユーザーがアクセスするダイアログを定義するためのリソースを含んでいる必要があります(詳細は、プラグインダイアログリソース を参照)。AKWwise::IAudioPlugin オブジェクトにこれらのダイアログに関連するメソッドを実装する必要があります。

AK::Wwise::IAudioPlugin::GetResourceHandle() メソッドはダイアログリソースを探す場所を Wwise に知らせます。以下は、MFC を使用する標準実装です:

// Get access to UI resource handle.
HINSTANCE SinePlugin::GetResourceHandle() const
{
    return AfxGetStaticModuleState()->m_hCurrentResourceHandle;
}

プラグインオブジェクトには、Wwise がダイアログに関する情報を取得できるよう、AKWwise::IAudioPlugin::GetDialog() も実装されている必要があります。この情報には、ダイアログリソースIDとオプショナルな AK::Wwise::PopulateTableItem が含まれています。

Note.gif
Note: エフェクトプラグインは1つだけダイアログを持ち、これは Effect EditorのEffect Settings タブに表示されます。ただし、ソースプラグインは2箇所で編集可能です:Contents Editor と Source Plug-in Property Editor。適切な情報を返すには、AKWwise::IAudioPlugin::eDialog パラメータを使用してください。

以下は、ソースプラグインのための、AKWwise::IAudioPlugin::GetDialog() の典型的な実装です:

// Bind non static text UI controls to properties for property view
AK_BEGIN_POPULATE_TABLE(ToneGenProp)
    AK_POP_ITEM(IDC_CHECK_SWEEPFREQ, szSweepFreq, L"")
    AK_POP_ITEM(IDC_RADIO_FREQSWEEPLIN, szSweepFreqType, L"")
    AK_POP_ITEM(IDC_RADIO_FIXLENGTH, szDurMode, L"")
AK_END_POPULATE_TABLE()

// Determine what dialog has been called and set the property names to a UI control binding populated table.
bool ToneGenPlugin::GetDialog( eDialog in_eDialog, UINT & out_uiDialogID, PopulateTableItem *& out_pTable ) const
{
    CComVariant varProp;

    switch ( in_eDialog )
    {
    case SettingsDialog:
        out_uiDialogID = IDD_TONEGENPLUGIN_BIG;
        out_pTable = ToneGenProp;

        return true;

    case ContentsEditorDialog:
        out_uiDialogID = IDD_TONEGENPLUGIN_SMALL;
        out_pTable = NULL;

        return true;
    }

    return false;
}

こちらは、エフェクトプラグインのために実装された AK::Wwise::IAudioPlugin::GetDialog() です:

// Set the property names to a UI control binding populated table.
bool DelayPlugin::GetDialog( eDialog in_eDialog, UINT & out_uiDialogID, PopulateTableItem *& out_pTable ) const
{
    assert( in_eDialog == SettingsDialog );

    out_uiDialogID = IDD_DELAY;
    out_pTable = NULL;

    return true;
}

フォーマット、コントロールなどを含めた実際のダイアログリソースに関する詳細は プラグインダイアログリソース をご覧ください。

AK::Wwise::PopulateTableItem をいつどのように使用するかに関する情報およびプラグインダイアログ関連マクロに関する情報は 標準コントロールをプロパティにバインドする方法 をご覧ください。

UI 変更により、コントロールを有効または無効にするのような特定のアクションが要求された場合、AKWwise::IAudioPlugin::WindowProc() 関数内で受け取ったウィンドウメッセージを解釈することにより実行可能です:

// Standard window function allowing the user to intercept whatever message is of interest when implementing UI behavior.
bool ToneGenPlugin::WindowProc( eDialog in_eDialog, HWND in_hWnd, UINT in_message, WPARAM in_wParam, LPARAM in_lParam, LRESULT & out_lResult )
{

    if ( in_message == WM_INITDIALOG )
    {   
        // Perform anything you need to do on dialog window initialization ...
    }

    // For example, catch window command actions (only for the main dialog) to enable/disable controls
    else if ( in_eDialog == SettingsDialog && in_message == WM_COMMAND )
    {
        // Notification code
        switch ( HIWORD( in_wParam ) )
        {
        case BN_CLICKED:
            // Check which button was clicked
            switch ( LOWORD( in_wParam ) )
            {
            case IDC_CHECK_SWEEPFREQ:
                // Verify if checkbox was checked or unchecked
                if ( IsDlgButtonChecked( in_hWnd, IDC_CHECK_SWEEPFREQ ) == BST_CHECKED )
                {
                    // Enable some controls ...
                }
                else if ( IsDlgButtonChecked( in_hWnd, IDC_CHECK_SWEEPFREQ ) == BST_UNCHECKED )
                {
                    // Disable some controls ...
                }
                break;
            }           
        } // End switch hi word (notification code)

    } // End command window event

    // Return False to let the parent window deal with the message. Return True
    // for messages you don't want the parent window to handle.

    return false;
}

プロパティ名とプロパティ値のユーザーフレンドリーなテキスト

AK::Wwise::IAudioPlugin::DisplayNameForProp() 関数の実装により、インターフェースの複数の場所に表示できる、そのプロパティ用の‘ユーザーフレンドリーな’名前を取得することが可能です。 これらの場所には、プロパティ変更後の undo/redo コマンド用などに、RTPC Manager が編集メニューに含まれています。

in_szPropertyName パラメータは、プラグインの XML 定義ファイルで特定されているプロパティ名に対応します(Wwiseプラグイン XML 記述ファイル)。以下はこのメソッドのサンプル実装です:

bool SinePlugin::DisplayNameForProp( LPCWSTR in_szPropertyName, LPWSTR out_szDisplayName, UINT in_unCharCount ) const
{
    // Get resource handle
    HINSTANCE hInst = AfxGetStaticModuleState()->m_hCurrentResourceHandle;
    if ( !wcscmp( in_szPropertyName, szSineFreq ) )
    {
        ::LoadString( hInst, IDS_SINEFREQ, out_szDisplayName, in_unCharCount );
        return true;    
    }
    else if ( !wcscmp( in_szPropertyName, szSineGain ) )
    {
        ::LoadString( hInst, IDS_SINEGAIN, out_szDisplayName, in_unCharCount );
        return true;    
    }
    // ...
    return false;
}

特定のプロパティが、On/Off または Yes/No を意味するブール型 (Boolean) プロパティまたはカーブ型に対する列挙のような、数値以外の値を持つ場合、あるいは 一部 の値が特別な意味を持っている場合、AKWwise::IAudioPlugin::DisplayNamesForPropValues() メソッドの実装で一部またはすべての可能なプロパティ値に対して表示するカスタムテキストを指定することができます。カスタムテキストは、Y軸上の値の RTPC グラフビューに使用されます。

Note.gif

Note: DisplayNamesForPropValues() に構築される文字列の形式は、ダイアログ内の Combo Box コントロールで指定できる "Options" 属性の形式と同じです(詳細は Wwise プラグインのダイアログリファレンス を参照)。文字列には、カンマで区切られた値/テキストのペアが含まれ、各ペアには、コロンで区切られた数値とテキストが含まれています。例:

  • ブール型(Boolean)プロパティ:"0:Off,1:On"
  • 列挙型の数値プロパティ:"0:Low Pass,1:High Pass,2:Band Pass"
  • 特別な意味を持ついくつかの値を使用する数値プロパティ: "-100:Left,0:Center,100:Right"

bool 型プロパティに対しては、値/テキストのペアの値側で、false に対して 0、true に対して 1 を使用してください。

次のサンプルコードでは、プラグインリソースから名前が取得されています:

// Allow Wwise to retrieve a user friendly name for that property's value (for example, RTPCs).
bool DelayPlugin::DisplayNamesForPropValues( LPCWSTR in_szPropertyName, LPWSTR out_szValuesName, UINT in_unCharCount ) const
{
    bool bFound = false;

    if ( !wcscmp( in_szPropertyName, szFeedbackEnabled ) )
    {
        WCHAR szValueName[128];

        CString csValuesName( L"0:" );
        ::LoadString( AfxGetStaticModuleState()->m_hCurrentResourceHandle, 
            IDS_PROPVALUENAME_FEEDBACKENABLED_OFF, szValueName, 128 );  
        csValuesName += szValueName;

        csValuesName += L",1:";
        ::LoadString( AfxGetStaticModuleState()->m_hCurrentResourceHandle, 
            IDS_PROPVALUENAME_FEEDBACKENABLED_ON, szValueName, 128 );
        csValuesName += szValueName;

        _tcsncpy( out_szValuesName, csValuesName, in_unCharCount );
        
        bFound = true;
    }
    else if ( !wcscmp( in_szPropertyName, szWetDryMix ) )
    {
        WCHAR szValueName[128];

        CString csValuesName( L"0:" );
        ::LoadString( AfxGetStaticModuleState()->m_hCurrentResourceHandle, 
            IDS_PROPVALUENAME_WETDRYMIX_DRY, szValueName, 128 );    
        csValuesName.AppendFormat( L"(%s) 0", szValueName );

        csValuesName += L",100:";
        ::LoadString( AfxGetStaticModuleState()->m_hCurrentResourceHandle, 
            IDS_PROPVALUENAME_WETDRYMIX_WET, szValueName, 128 );
        csValuesName.AppendFormat( L"(%s) 100", szValueName );

        _tcsncpy( out_szValuesName, csValuesName, in_unCharCount );
        
        bFound = true;
    }

    return bFound;
}

プラグインのHelp表示

Wwise ユーザーが、プラグインのダイアログタイトルバーにある '?' アイコンをクリックすると、このプラグインに AK::Wwise::IAudioPlugin::Help() が呼び出されます。Helpは、HTMLHelp や WinHelp、またはサードパーティ製 Help ブラウザなどの様々なツールを使用して実装可能です。関数は、表示したいウィンドウの親として使用可能なウィンドウハンドルを受け取ります。AKWwise::IAudioPlugin::eDialog パラメータの使用により、Wwise ユーザーが現在開いているダイアログに合った特定の Help トピックを選択することができます。この関数は、Help リクエストを処理した場合には true、それ以外の場合は false を返し、Wwise は Plug-in Manager に関する Help を表示します。

Note.gif
Note: 前述のように、エフェクトプラグインはダイアログを1つのみ持ちますが、ソースプラグインは2つ持ちます。ソースプラグインが、その2つのダイアログに対して個別の Help トピックを持つ場合には、AKWwise::IAudioPlugin::eDialog パラメータが使用されなければなりません。

以下は、HTML ヘルプを使用するソースプラグイン例です:

// Implement online help when the user clicks on the "?" icon
bool ToneGenPlugin::Help( HWND in_hWnd, eDialog in_eDialog ) const
{
    AFX_MANAGE_STATE( ::AfxGetStaticModuleState() ) ;

    DWORD dwTopic = ONLINEHELP::Tone_Generator_Settings;
    if ( in_eDialog == AK::Wwise::IAudioPlugin::ContentsEditorDialog )
        dwTopic = ONLINEHELP::Tone_Generator_ContentsEditor;

    // Note: Do NOT call AfxGetApp()->HtmlHelp() as it will launch the Help
    // window from the wrong parent window which will make floating views
    // behave unexpectedly.
    ::HtmlHelp( NULL, AfxGetApp()->m_pszHelpFilePath, HH_HELP_CONTEXT, dwTopic );

    return true;
}
Caution.gif
Caution: Help() メソッドは、AfxGetApp()->HtmlHelp() を呼び出すべきではありません。とうのも、これにより間違った親ウィンドウから Help ウィンドウを起動してフローティングビューが予期しない動作を起こす可能性があるからです。 代わりに、上の例で示されているように、HtmlHelp() を NULL ウィンドウハンドルで使用するようにしてください。

プラグインダイアログリソース

DLLには、プラグインの(1つまたは複数)ダイアログのリソースが含まれている必要があります。各ダイアログのリソースIDは、AKWwise::IAudioPlugin::GetDialog() に返されるIDと同じです。詳細は ダイアログ関連コード をご覧ください。

ダイアログで使用可能なコントロール、これらをプロパティへバインドする方法などの完全な解説は Wwise プラグインのダイアログリファレンス を参照してください。

エクスポート関数

各プラグインDLLは、2つの関数をエクスポートする必要があります:

  • AkCreatePlugin():AKWwise::IPluginBase オブジェクトのインスタンスを作成します。
  • AkGetSoundEngineCallbacks:サウンドエンジンプラグインとそのパラメータを作成する関数へのポインタを Wwise に取得させます。これらは、プラグインを AK::SoundEngine::RegisterPlugin() で登録する際にゲームが指定するのと同じ関数です。 これらの関数に関する詳細は オーディオプラグイン サウンドエンジン部分の記述 をご覧ください。

どちらの関数も、パラメータとして Company ID と Plug-in ID を取得します。これらのIDは、プラグインXML定義ファイルで定義されているIDと一致します(詳細は Wwiseプラグイン XML 記述ファイル を参照)。使用 DLL と XML が複数のプラグインを含んでいる場合、これらのパラメータにより、どのプラグインが要求されているかを知ることができます。

以下は、プラグインを1つ含むプラグインDLLのエクスポート関数の例です:

#include <AK/Wwise/Utilities.h>
#include <AK/SoundEngine/Common/IAkPlugin.h>
#include <assert.h>

// Wwise UI plug-in factory
AK::Wwise::IPluginBase* __stdcall AkCreatePlugin( unsigned short in_usCompanyID, unsigned short in_usPluginID )
{
    if ( in_usCompanyID == SinePlugin::CompanyID && in_usPluginID == SinePlugin::PluginID )
        return new MyPlugin; // return AK::Wwise::IAudioPlugin-derived object in the case of a source plug-in.

    // If this function is called with the wrong company/plug-in ID, it is because
    // the IDs in the plug-in XML definition file and those in the code don't match.
    assert( false );

    return NULL;
}

// Sound Engine callback provider
bool __stdcall AkGetSoundEngineCallbacks( unsigned short in_usCompanyID, unsigned short in_usPluginID, AkCreatePluginCallback & out_funcEffect, AkCreateParamCallback & out_funcParam )
{
    if ( in_usCompanyID == SinePlugin::CompanyID && in_usPluginID == SinePlugin::PluginID )
    {
        out_funcEffect = CreateMyEffect;
        out_funcParam = CreateMyEffectParam;
        return true;
    }

    // If this function is called with the wrong company/plug-in ID, it is because
    // the IDs in the plug-in XML definition file and those in the code don't match.
    assert( false );

    return false;
}

ライブラリ記述ファイル (.def) で、エクスポートされるべき2つの関数を明示的に言及する必要があります:

LIBRARY      "MyPlugin"

EXPORTS
    AkCreatePlugin
    AkGetSoundEngineCallbacks

リーガルテキスト(オプション)

Wwise オーサリングツールは、プラグインがプロジェクトに初めて追加された時にユーザーに法的義務を知らせるメッセージボックスを表示することができます。このテキストは、プラグイン内に埋め込むことができますが、これは必須ではありません。この機能を使用したくない場合は、このセクションを読み飛ばしてください。

プラグインコードで、AkGetFirstTimeCreationMessage() 関数をエクスポートします。他のエクスポート関数と同様に、この関数はパラメータとして Company ID と Plug-in ID を受信します(上記 エクスポート関数 を参照)。この関数は、2つの出力引数、表示のためのメッセージ文字列、および、プラグインが既に前に作成されているかどうかを知るために使用されるレジストリキーの文字列も持っています。

この関数の実装の例を以下に示します:

// Message to display when creating the plugin for the first time
bool __stdcall AkGetFirstTimeCreationMessage(
    unsigned short in_usCompanyID,
    unsigned short in_usPluginID,
    BSTR& out_message,
    BSTR& out_key
    )
{
    assert( in_usCompanyID == SinePlugin::CompanyID && in_usPluginID == SinePlugin::PluginID );

    AFX_MANAGE_STATE( AfxGetStaticModuleState() );

    CString csText;
    csText.LoadString( IDS_SINEPLUGIN_LICENSEREMINDER );
    out_message = csText.AllocSysString();

    csText = _T("SinePlugin");
    out_key = csText.AllocSysString();

    return true;
}

この例では、ライセンスリマインダーテキストが、IDS_SINEPLUGIN_LICENSEREMINDER 下のプラグイン文字列テーブルに格納されていました。

out_key を介して返されるテキスト "SinePlugin" は、この関数が最初に呼び出された時に Wwise が作成するレジストリキーの名前です:HKEY_CURRENT_USER/Software/Audiokinetic Inc./Wwise/PluginUserAcknowledge/Projects/{current project}/SinePlugin。当然、あなたのプラグインと会社に固有の名前をつけることになるでしょう。Wwise がこの関数を再び呼び出し、このキーをレジストリに見つけると、法的義務に関するメッセージは表示されません。

ライブラリ記述ファイル(.def)で、エクスポートする必要のある関数リストに、この関数を追加してください:

LIBRARY      "MyPlugin"

EXPORTS
    AkCreatePlugin
    AkGetSoundEngineCallbacks
    AkGetFirstTimeCreationMessage

モニタリングデータの処理

Master-Mixer 階層内の(バスに適用されている)エフェクトプラグインは、サウンドエンジン内の関連ランタイムコンポーネントからモニタリング(監視)情報を受信することができます。プラグインのサウンドエンジン側からモニタリングデータをポストする方法に関する詳細は Wwise プラグイン モニタリングデータのポスト を参照してください。

プラグインインスタンスによりモニタリングデータブロックが受信されると(Wwise でモニタリングが有効になっている必要があります)、プラグインはデータを適切に解析し、統計のコンパイルやUIイベント(例えば VUメーターなど)のようなアクションをトリガします。 以下のコードは、データをポストしたプラットフォームが、Wwise プラグインのものと異なるエンディアンを持つ場合には、バイトスワップを必要に応じて処理するやり方で、IAudioPluginNotifyMonitorData() の実装内のモニタリングデータに対応する方法の簡単な例を示しています。

void MyPlugin::NotifyMonitorData( void * in_pData, unsigned int in_uDataSize, bool in_bNeedsByteSwap )
{
    // Parse the data block that was sent from your sound engine plug-in and 
    // byte swap if plaform's endianness is reported to be different than PC.
    unsigned int * pData = (unsigned int *) in_pData;
    unsigned int uNumChannels = in_bNeedsByteSwap ?_byteswap_ulong( *pData++ ) : *pData++;
    float fChannelPeaks[MAX_NUM_CHANNELS];
    
    if ( in_bNeedsByteSwap )
    {
        for ( unsigned int i = 0; i < uNumChannels; ++i )
        {
            fChannelPeaks[i] = (float) _byteswap_ulong( *pData++ );
        }
    }
    else
    {
        memcpy( fChannelPeaks, pData, uNumChannels*sizeof(float) );
    }   
    // Create some UI response to the incoming data...
}

サンプルコード

詳細は、利用可能なサンプルプラグインプロジェクトのリスト サンプル をご覧ください。

トラブルシューティング

問題が発生した場合は、Wwise ソースプラグインおよびエフェクトプラグインのトラブルシューティングガイド の Help をご利用ください。