/*---------------------------------------------------------------------------* Project: NintendoWare File: snd_Voice.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: 26775 $ *---------------------------------------------------------------------------*/ #ifndef NW_SND_VOICE_H_ #define NW_SND_VOICE_H_ #include #include #include // for ut::LinkListNode #ifdef NW_PLATFORM_CTRWIN #include #endif // NW_PLATFORM_CTRWIN namespace nw { namespace snd { namespace internal { namespace driver { #ifdef NW_PLATFORM_CTR typedef nn::snd::Voice HardwareChannel; #endif class Voice { friend class VoiceManager; public: // ------------------------------------------------------------------------ // 更新フラグ static const int UPDATE_START = 0x0001 << 0; static const int UPDATE_PAUSE = 0x0001 << 1; static const int UPDATE_SRC = 0x0001 << 2; static const int UPDATE_MIX = 0x0001 << 3; static const int UPDATE_LPF = 0x0001 << 4; static const int UPDATE_BIQUAD = 0x0001 << 5; static const int UPDATE_VE = 0x0001 << 6; // ------------------------------------------------------------------------ // コールバック関数 enum VoiceCallbackStatus { CALLBACK_STATUS_FINISH_WAVE, CALLBACK_STATUS_CANCEL, CALLBACK_STATUS_DROP_VOICE, CALLBACK_STATUS_DROP_DSP }; typedef void (*VoiceCallback)( Voice* voice, VoiceCallbackStatus status, void* callbackData ); static const int CHANNEL_MAX = nw::snd::internal::WAVE_CHANNEL_MAX; // ------------------------------------------------------------------------ // パラメータ境界 static const f32 VOLUME_MIN; static const f32 VOLUME_DEFAULT; static const f32 VOLUME_MAX; static const f32 PAN_LEFT; static const f32 PAN_CENTER; static const f32 PAN_RIGHT; static const f32 SPAN_FRONT; static const f32 SPAN_CENTER; static const f32 SPAN_REAR; static const f32 CUTOFF_FREQ_MIN; static const f32 CUTOFF_FREQ_MAX; static const f32 BIQUAD_VALUE_MIN; static const f32 BIQUAD_VALUE_MAX; static const f32 SEND_MIN; static const f32 SEND_MAX; private: // Voiceの仮想プライオリティ #ifdef NW_PLATFORM_CTRWIN static const int PRIORITY_MAX = 255; #else static const int PRIORITY_MAX = nn::snd::VOICE_PRIORITY_NODROP; #endif static const int PRIORITY_MIN = 0; // TODO: SDK での優先度との摺合せをする必要アリ // AXのボイスで使用される実際のプライオリティ #ifdef NW_PLATFORM_CTRWIN static const u32 VOICE_PRIORITY_MAX = AX_PRIORITY_STACKS - 1; static const int VOICE_PRIORITY_FREE = 0; static const u32 VOICE_PRIORITY_USE = 16; // Voiceクラスが使用するプライオリティ static const u32 VOICE_PRIORITY_ALLOC = VOICE_PRIORITY_USE + 1; static const u32 VOICE_PRIORITY_NODROP = VOICE_PRIORITY_MAX; static const u32 VOICE_PRIORITY_RELEASE = VOICE_PRIORITY_USE - 1; #else // static const u32 VOICE_PRIORITY_MAX = PRIORITY_MAX; static const u32 VOICE_PRIORITY_RELEASE = 1; #endif public: static const int PRIORITY_NODROP = PRIORITY_MAX; static const int PRIORITY_RELEASE = 1; public: Voice(); ~Voice(); // ------------------------------------------------------------------------ // 確保と開放 bool Alloc( // NW4R では Voice::Acquire int channelCount, int priority, Voice::VoiceCallback callback, void* callbackData ); void Free(); void Initialize( const WaveInfo& waveInfo, u32 startOffset ); // ------------------------------------------------------------------------ // 動作 void Start(); void Stop(); void StopFinished(); void Pause( bool flag ); void Calc(); void Update(); // ------------------------------------------------------------------------ // 動作状態 bool IsActive() const { return m_pHardwareChannel[0] != NULL; } bool IsRun() const; bool IsPause() const { return m_IsPause == true; } bool IsPlayFinished() const; // ------------------------------------------------------------------------ // パラメータ f32 GetVolume() const { return m_Volume; } void SetVolume( f32 volume ); f32 GetPitch() const { return m_Pitch; } void SetPitch( f32 pitch ); void SetPanMode( PanMode panMode ); void SetPanCurve( PanCurve panCurve ); f32 GetPan() const { return m_Pan; } void SetPan( f32 pan ); f32 GetSurroundPan() const { return m_SurroundPan; } void SetSurroundPan( f32 span ); f32 GetLpfFreq() const { return m_LpfFreq; } void SetLpfFreq( f32 lpfFreq ); int GetBiquadType() const { return m_BiquadType; } f32 GetBiquadValue() const { return m_BiquadValue; } void SetBiquadFilter( int type, f32 value ); int GetPriority() const { return m_Priority; } void SetPriority( int priority ); void SetFrontBypass( bool isFrontBypass ); void SetInterpolationType( u8 interpolationType ); // ------------------------------------------------------------------------ // ボイスパラメータ int GetPhysicalVoiceCount() const { return m_ChannelCount; } int GetChannelCount() const { return m_ChannelCount; } const HardwareChannel* GetHardwareChannel( int channelIndex ) const; void UpdateVoicesPriority(); // ------------------------------------------------------------------------ // 出力パラメータ f32 GetMainSend() const { return m_MainSend; } void SetMainSend( f32 send ); f32 GetFxSend( AuxBus bus ) const { return m_FxSend[ bus ]; } void SetFxSend( AuxBus bus, f32 send ); // ------------------------------------------------------------------------ // サンプルの調整 u32 GetCurrentPlayingSample() const; #ifdef NW_PLATFORM_CTRWIN void StopAtPoint( int channelIndex, const void* baseAddress, u32 samples ); void SetLoopFlag( bool flag ); void SetLoopStart( s32 channelIndex, const void* baseAddress, u32 samples = 0 ); void SetLoopEnd( s32 channelIndex, const void* baseAddress, u32 samples ); void SetDspAdpcmLoop( s32 channelIndex, const DspAdpcmLoopParam* param ); #endif // NW_PLATFORM_CTRWIN nw::snd::SampleFormat GetFormat() const; private: #ifdef NW_PLATFORM_CTRWIN // Voice のアロケート時に渡すコールバック関数。ボイスドロップ時に呼ばれる。 static void HardwareChannelCallbackFunc( HardwareChannel* hardwareChannel, HardwareChannel::HardwareChannelCallbackStatus status, void* callbackData ); #else static void SdkVoiceDropCallbackFunc( nn::snd::Voice* pDropVoice, uptr userArg ); static void SdkVoiceDropCallbackFuncMulti( nn::snd::Voice* pDropVoice, uptr userArg ); #endif void InitParam( int channelCount, Voice::VoiceCallback callback, void* callbackData ); // Update関数 #ifdef NW_PLATFORM_CTRWIN void SyncHardwareChannel(); #endif void CalcSrc( bool initialUpdate ); void CalcVe(); void CalcMix(); void CalcLpf(); void CalcBiquadFilter(); void CalcMixParam( int channelIndex, nw::snd::internal::MixParam* mix ); void RunAllHardwareChannel(); void StopAllHardwareChannel(); void PauseAllHardwareChannel(); private: HardwareChannel* m_pHardwareChannel[ CHANNEL_MAX ]; int m_ChannelCount; VoiceCallback m_Callback; void* m_pCallbackData; bool m_IsActive; bool m_IsStart; bool m_IsStarted; bool m_IsPause; bool m_IsPausing; bool m_IsInitialized; bool m_IsAllocating; bool m_AllocateErrorFlag; nn::snd::WaveBuffer* m_pLastWaveBuffer; u16 m_SyncFlag; u8 m_BiquadType; f32 m_Volume; f32 m_Pitch; PanMode m_PanMode; PanCurve m_PanCurve; f32 m_Pan; f32 m_SurroundPan; f32 m_LpfFreq; f32 m_BiquadValue; int m_Priority; f32 m_MainSend; f32 m_FxSend[ AUX_BUS_NUM ]; nw::snd::SampleFormat m_Format; #ifdef NW_PLATFORM_CTR public: static u32 FrameToByte( u32 sample, nw::snd::SampleFormat format ); void AppendWaveBuffer( int channelIndex, nn::snd::WaveBuffer* pBuffer, bool lastFlag ); void SetAdpcmParam( int channelIndex, const nn::snd::AdpcmParam& param ); private: uptr m_VoiceUser; // Channel or StreamTrack #endif // NW_PLATFORM_CTR public: ut::LinkListNode m_LinkNode; #ifdef NW_DEBUG // デバッグ用 public: // 直近にサラウンドパン計算したボイスのサラウンドパン値を取得する // (事実上、1 ボイス再生時にしか用途がない) static void GetDebugMixParam( f32& pan, f32& span, nw::snd::internal::MixParam& mix ); #endif }; } // namespace nw::snd::internal::driver } // namespace nw::snd::internal } // namespace nw::snd } // namespace nw #endif /* NW_SND_VOICE_H_ */