/*---------------------------------------------------------------------------* Project: NintendoWare File: snd_BasicSound.h Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 22340 $ *---------------------------------------------------------------------------*/ /** * :include nw/snd/snd_BasicSound.h * * @file snd_BasicSound.h */ #ifndef NW_SND_BASIC_SOUND_H_ #define NW_SND_BASIC_SOUND_H_ #include #include #include #include #include namespace nw { namespace snd { class SoundHandle; class SoundPlayer; class SoundActor; // ------------------------------------------------------------------------ // アンビエントパラメータ //! @details :private struct SoundParam { f32 volume; f32 pitch; f32 pan; f32 span; f32 fxSend; f32 lpf; f32 biquadFilterValue; int biquadFilterType; int priority; u32 userData; SoundParam() : volume(1.0f), pitch(1.0f), pan(0.0f), span(0.0f), fxSend(0.0f), lpf(0.0f), biquadFilterValue(0.0f), biquadFilterType(0), priority(0), userData(0) {} }; //--------------------------------------------------------------------------- //! @brief アンビエントパラメータ構造体です。 //! //! 3D サウンドを使用している際には、 //! 前回計算された 3D サウンド計算結果を参照するため、そして、 //! 3D サウンドエンジンクラスの計算結果を格納するために用いられます。 //! //! @see Sound3DEngine::UpdateAmbientParam //! //! @date 2010/04/08 高速化のため VoiceOutParam メンバを削除 //! @date 2010/03/12 初版 //--------------------------------------------------------------------------- struct SoundAmbientParam { //--------------------------------------------------------------------------- //! @brief サウンドの音量の倍率です。0.0 を指定すると発音されません。 //--------------------------------------------------------------------------- f32 volume; //--------------------------------------------------------------------------- //! @brief サウンドの音程の周波数比率です。 //! 1.0 を指定すると変化しません。 //! 2.0 を指定すると再生される周波数が 2 倍になり、1 オクターブ高い音程になります。 //--------------------------------------------------------------------------- f32 pitch; //--------------------------------------------------------------------------- //! @brief サウンドのパン (左右の定位) の相対変化量です。 //! 0.0 を指定すると変化しません。 //! 1.0 を指定すると中央に定位していた音が右端に定位するようになり、 //! -1.0 を指定すると中央に定位していた音が左端に定位するようになります。 //--------------------------------------------------------------------------- f32 pan; //! 現在は無効です。 f32 span; //! 現在は無効です。 f32 fxSend; //! 現在は無効です。 f32 lpf; //! 現在は無効です。 f32 biquadFilterValue; //! 現在は無効です。 int biquadFilterType; //--------------------------------------------------------------------------- //! @brief サウンドのプレイヤープライオリティの相対変化量です。 //! もともとのプレイヤープライオリティに加算されます。 //--------------------------------------------------------------------------- int priority; //--------------------------------------------------------------------------- //! @brief ユーザーが自由に利用できるパラメータです。 //! サウンド再生時に 0 にリセットされます。 //--------------------------------------------------------------------------- u32 userData; //--------------------------------------------------------------------------- //! @brief コンストラクタです。 //! //! @date 2010/03/12 初版 //--------------------------------------------------------------------------- SoundAmbientParam() : volume(1.0f), pitch(1.0f), pan(0.0f), span(0.0f), fxSend(0.0f), lpf(0.0f), biquadFilterValue(0.0f), biquadFilterType(0), priority(0), userData(0) {} }; /* biquad フィルタは複数の箇所での設定が重ね合わされず、 以下の優先度に従って設定されます。 優先度が高い箇所でパラメータの設定がされた場合、それより下位の設定は上書きされます。 1. サウンドハンドルでの設定 2. サウンドプレーヤーでの設定 3. アンビエントパラメータ構造体での設定 4. シーケンスデータでの設定 エフェクトセンド量 fxSend は「AUX バス A」へのセンド量として反映されます。 「AUX バス B」へのセンド量は、 データや nw4r::snd::SoundHandle::SetFxSend 関数などで設定する必要があります。 span サウンドのサラウンドパン(前後の定位)の相対変化量です。 0.0 を指定すると変化しません。 1.0 を指定すると最前方に定位していた音が中央に定位するようになり、 2.0 を指定すると最前方に定位していた音が最後方に定位するようになります。 前方へ定位を移動させたい場合は負の値を指定します。 fxSend サウンドのエフェクトセンドの相対変化量です。 0.0 を指定するとセンド量を変更しません。 1.0 を指定すると AUX バスに送られていなかったサウンドが 最大のセンド量で送られるようになります。 lpf サウンドのローパスフィルタのカットオフの相対変化量です。 0.0 を指定するとカットオフの値を変更しません。 -1.0 を指定すると、フィルタがかかっていない状態から、 最もフィルタがかかっている状態(カットオフ周波数が下がる方向)に変更します。 biquadFilterValue サウンドの biquad フィルタのかかり具合を表す値です。 値の意味はフィルタの種類によって変化します。 biquadFilterType サウンドの biquad フィルタの種類です。 @ref BiquadFilterType の値を使用します。 プリセットで用意されているフィルタの種類の他、 ユーザーが登録したフィルタの種類の値をとります。 biquad フィルタは LPF に比べ 3 倍強のDSP負荷がかかります。 // TODO: 3 倍強よりは少ないかも */ namespace internal { struct SoundActorParam { f32 volume; f32 pitch; f32 pan; SoundActorParam(): volume(1.0f),pitch(1.0f),pan(0.0f) {} void Reset() { volume = pitch = 1.0f; pan = 0.0f; } }; /* ======================================================================== typename declaration ======================================================================== */ namespace driver { class BasicSoundPlayer; } class PlayerHeap; class ExternalSoundPlayer; /* ======================================================================== class definition ======================================================================== */ class BasicSound { friend class SoundHandle; public: NW_UT_RUNTIME_TYPEINFO; // ダウンキャスト用の実行時型情報を埋め込みます /* ------------------------------------------------------------------------ constant declaration ------------------------------------------------------------------------ */ public: static const int PRIORITY_MIN = 0; static const int PRIORITY_MAX = 127; static const u32 INVALID_ID = 0xffffffff; /* ------------------------------------------------------------------------ type definition ------------------------------------------------------------------------ */ public: class AmbientParamUpdateCallback; class AmbientArgUpdateCallback; class AmbientArgAllocatorCallback; struct AmbientInfo { AmbientParamUpdateCallback* paramUpdateCallback; AmbientArgUpdateCallback* argUpdateCallback; AmbientArgAllocatorCallback* argAllocatorCallback; void* arg; unsigned long argSize; }; enum PlayerState { PLAYER_STATE_INIT, PLAYER_STATE_PREPARED, PLAYER_STATE_PLAY, PLAYER_STATE_STOP }; /* ------------------------------------------------------------------------ class member ------------------------------------------------------------------------ */ public: BasicSound(); virtual ~BasicSound() {} void Update(); void StartPrepared(); void Stop( int fadeFrames ); void Pause( bool flag, int fadeFrames ); void SetAutoStopCounter( int frames ); void FadeIn( int frames ); virtual void Initialize(); virtual void Finalize(); virtual bool IsPrepared() const = 0; bool IsPause() const; //------------------------------------------------------------------ // パラメータ void SetPriority( int priority, int ambientPriority ); void SetInitialVolume( f32 volume ); void SetVolume( f32 volume, int frames = 0 ); void SetPitch( f32 pitch ); void SetPan( f32 pan ); void SetLpfFreq( f32 lpfFreq ); void SetBiquadFilter( int type, f32 value ); void SetSurroundPan( f32 pan ); void SetPanMode( PanMode panMode ); void SetPanCurve( PanCurve panCurve ); void SetPlayerPriority( int priority ); void SetFrontBypass( bool isFrontBypass ); //------------------------------------------------------------------ // 出力パラメータ void SetMainSend( f32 send ); void SetFxSend( AuxBus bus, f32 send ); //------------------------------------------------------------------ // 情報取得 int GetRemainingFadeFrames() const; int GetRemainingPauseFadeFrames() const; int GetPlayerPriority() const { return m_Priority; } // for AnimSound //------------------------------------------------------------------ // その他のパラメータ void SetId( u32 id ); u32 GetId() const { return m_Id; } unsigned long GetPlayFrameCount() const { return m_UpdateCounter; } //------------------------------------------------------------------ int CalcCurrentPlayerPriority() const { return ut::Clamp( static_cast( m_Priority ) + static_cast( m_AmbientParam.priority ), PRIORITY_MIN, PRIORITY_MAX ); } // サウンドプレイヤー SoundPlayer* GetSoundPlayer() { return m_pSoundPlayer; } const SoundPlayer* GetSoundPlayer() const { return m_pSoundPlayer; } void AttachSoundPlayer( SoundPlayer* player ); void DetachSoundPlayer( SoundPlayer* player ); void AttachSoundActor( SoundActor* actor ); void DetachSoundActor( SoundActor* actor ); void AttachExternalSoundPlayer( ExternalSoundPlayer* extPlayer ); void DetachExternalSoundPlayer( ExternalSoundPlayer* extPlayer ); // プレイヤーヒープ void AttachPlayerHeap( PlayerHeap* pHeap ); void DetachPlayerHeap( PlayerHeap* pHeap ); PlayerHeap* GetPlayerHeap() { return m_pPlayerHeap; } // アンビエントパラメータ void SetAmbientInfo( const AmbientInfo& info ); void ClearAmbientArgUpdateCallback() { m_AmbientInfo.argUpdateCallback = NULL; } void ClearAmbientParamUpdateCallback() { m_AmbientInfo.paramUpdateCallback = NULL; } void ClearAmbientArgAllocatorCallback() { m_AmbientInfo.argAllocatorCallback = NULL; } const SoundParam& GetAmbientParam() const { return m_AmbientParam; } static int GetAmbientPriority( const AmbientInfo& ambientInfo, u32 soundId ); // ハンドル関数 bool IsAttachedGeneralHandle(); bool IsAttachedTempGeneralHandle(); virtual bool IsAttachedTempSpecialHandle() = 0; void DetachGeneralHandle(); void DetachTempGeneralHandle(); virtual void DetachTempSpecialHandle() = 0; protected: virtual driver::BasicSoundPlayer* GetBasicSoundPlayerHandle() = 0; virtual void OnUpdatePlayerPriority() {} virtual void UpdateMoveValue(); virtual void UpdateParam(); bool IsStarted() const { return m_StartedFlag; } // for SeqSound bool IsPlayerAvailable() const { return m_PlayerAvailableFlag; } private: //----------------------------------------------------------------------------- // PauseState状態遷移 // // state \ event | pause | unpause | fade-finish // --------------+---------+-----------+-------------- // normal | pausing | - | - // pausing | pausing | unpausing | paused // paused | - | unpausing | - // unpausing | pausing | unpausing | normal // enum PauseState { PAUSE_STATE_NORMAL, PAUSE_STATE_PAUSING, PAUSE_STATE_PAUSED, PAUSE_STATE_UNPAUSING }; PlayerHeap* m_pPlayerHeap; SoundHandle* m_pGeneralHandle; SoundHandle* m_pTempGeneralHandle; SoundPlayer* m_pSoundPlayer; SoundActor* m_pSoundActor; ExternalSoundPlayer* m_pExtSoundPlayer; AmbientInfo m_AmbientInfo; SoundParam m_AmbientParam; SoundActorParam m_ActorParam; MoveValue m_FadeVolume; MoveValue m_PauseFadeVolume; bool m_InitializeFlag; bool m_StartFlag; bool m_StartedFlag; bool m_AutoStopFlag; bool m_FadeOutFlag; bool m_PlayerAvailableFlag; PlayerState m_PlayerState; PauseState m_PauseState; bool m_UnPauseFlag; s32 m_AutoStopCounter; u32 m_UpdateCounter; u8 m_Priority; u8 m_BiquadFilterType; u32 m_Id; MoveValue m_ExtMoveVolume; f32 m_InitVolume; f32 m_ExtPan; f32 m_ExtPitch; f32 m_LpfFreq; f32 m_BiquadFilterValue; f32 m_MainSend; f32 m_FxSend[ AUX_BUS_NUM ]; f32 m_ExtSurroundPan; public: ut::LinkListNode m_PriorityLink; // for SoundInstanceManager ut::LinkListNode m_SoundPlayerPlayLink; ut::LinkListNode m_SoundPlayerPriorityLink; ut::LinkListNode m_ExtSoundPlayerPlayLink; }; class BasicSound::AmbientParamUpdateCallback { public: virtual ~AmbientParamUpdateCallback() {} virtual void detail_UpdateAmbientParam( const void* arg, u32 soundId, SoundAmbientParam* param ) = 0; virtual int detail_GetAmbientPriority( const void* arg, u32 soundId ) = 0; }; class BasicSound::AmbientArgUpdateCallback { public: virtual ~AmbientArgUpdateCallback() {} virtual void detail_UpdateAmbientArg( void* arg, const internal::BasicSound* sound ) = 0; }; class BasicSound::AmbientArgAllocatorCallback { public: virtual ~AmbientArgAllocatorCallback() {} virtual void* detail_AllocAmbientArg( size_t argSize ) = 0; virtual void detail_FreeAmbientArg( void* arg, const internal::BasicSound* sound ) = 0; }; } // namespace nw::snd::internal } // namespace nw::snd } // namespace nw #endif /* NW_SND_BASIC_SOUND_H_ */