/*---------------------------------------------------------------------------* Project: NintendoWare File: snd_Channel.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: 25221 $ *---------------------------------------------------------------------------*/ #ifndef NW_SND_CHANNEL_H_ #define NW_SND_CHANNEL_H_ #include #include // WaveInfo #include // Voice::PRIORITY_RELEASE #include #include #include #include #ifdef NW_PLATFORM_CTR #include // HardwareManager::AUDIO_CHANNEL_COUNT #endif namespace nw { namespace snd { namespace internal { namespace driver { /* ======================================================================== class definition ======================================================================== */ class Channel { /* ------------------------------------------------------------------------ typename definition ------------------------------------------------------------------------ */ public: enum LfoTarget { LFO_TARGET_PITCH, LFO_TARGET_VOLUME, LFO_TARGET_PAN }; enum ChannelCallbackStatus { CALLBACK_STATUS_STOPPED, CALLBACK_STATUS_DROP, CALLBACK_STATUS_FINISH, CALLBACK_STATUS_CANCEL }; typedef void (*ChannelCallback) ( Channel *channel, ChannelCallbackStatus status, u32 userData ); /* ------------------------------------------------------------------------ constant declaration ------------------------------------------------------------------------ */ public: static const int CHANNEL_NUM = HardwareManager::SOUND_VOICE_COUNT + 1; // チャンネル数 static const int CHANNEL_MIN = 0; static const int CHANNEL_MAX = CHANNEL_MIN + CHANNEL_NUM - 1; static const int PRIORITY_RELEASE = Voice::PRIORITY_RELEASE; private: static const int KEY_INIT = 60; static const int ORIGINAL_KEY_INIT = 60; static const u8 SILENCE_VOLUME_MAX = 255; static const u8 SILENCE_VOLUME_MIN = 0; /* ------------------------------------------------------------------------ static members ------------------------------------------------------------------------ */ public: static Channel* AllocChannel( int voiceChannelCount, int priority, ChannelCallback callback, u32 callbackData ); static void FreeChannel( Channel* channel ); private: static void VoiceCallbackFunc( Voice* voice, Voice::VoiceCallbackStatus status, void* arg ); #ifdef NW_PLATFORM_CTR void AppendWaveBuffer( const WaveInfo& waveInfo ); static const int WAVE_BUFFER_MAX = 2; nn::snd::WaveBuffer m_WaveBuffer[Voice::CHANNEL_MAX][WAVE_BUFFER_MAX]; nn::snd::AdpcmContext m_AdpcmContext[Voice::CHANNEL_MAX]; nn::snd::AdpcmContext m_AdpcmLoopContext[Voice::CHANNEL_MAX]; u32 m_LoopStartFrame; bool m_LoopFlag; #endif /* ------------------------------------------------------------------------ class members ------------------------------------------------------------------------ */ public: Channel(); ~Channel(); void Update( bool doPeriodicProc ); void Start( const WaveInfo& waveParam, int length, u32 startOffset ); void NoteOff(); void Release(); void Stop(); void Pause( bool flag ) { m_PauseFlag = flag; m_pVoice->Pause( flag ); } bool IsActive() const { return m_ActiveFlag != 0; } bool IsPause() const { return m_PauseFlag != 0; } //------------------------------------------------------------------ // 初期パラメータ void SetKey( u8 key ) { m_Key = key; } void SetKey( u8 key, u8 originalKey ) { m_Key = key; m_OriginalKey = originalKey; } void SetInitVolume( f32 volume ) { m_InitVolume = volume; } void SetInitPan( f32 pan ) { m_InitPan = pan; } void SetInitSurroundPan( f32 surroundPan ) { m_InitSurroundPan = surroundPan; } void SetTune( f32 tune ) { m_Tune = tune; } void SetAttack( int attack ) { m_CurveAdshr.SetAttack( attack ); } void SetHold( int hold ) { m_CurveAdshr.SetHold( hold ); } void SetDecay( int decay ) { m_CurveAdshr.SetDecay( decay ); } void SetSustain( int sustain ) { m_CurveAdshr.SetSustain( sustain ); } void SetRelease( int release ) { m_CurveAdshr.SetRelease( release ); } void SetSilence( bool silenceFlag, int fadeTimes ) { NW_MINMAX_ASSERT( fadeTimes, 0, USHRT_MAX ); m_SilenceVolume.SetTarget( silenceFlag? SILENCE_VOLUME_MIN: SILENCE_VOLUME_MAX, static_cast( fadeTimes ) ); } s32 GetLength() const { return m_Length; } void SetLength( s32 length ) { m_Length = length; } bool IsRelease() const { return m_CurveAdshr.GetStatus() == CurveAdshr::STATUS_RELEASE; } //------------------------------------------------------------------ // ユーザーパラメータ void SetUserVolume( f32 volume ) { m_UserVolume = volume; } void SetUserPitch( f32 pitch ) { m_UserPitch = pitch; } void SetUserPitchRatio( f32 pitchRatio ) { m_UserPitchRatio = pitchRatio; } void SetUserPan( f32 pan ) { m_UserPan = pan; } void SetUserSurroundPan( f32 surroundPan ) { m_UserSurroundPan = surroundPan; } void SetUserLpfFreq( f32 lpfFreq ) { m_UserLpfFreq = lpfFreq; } void SetBiquadFilter( int type, f32 value ); void SetLfoParam( const CurveLfoParam& param ) { m_Lfo.SetParam( param ); } void SetLfoTarget( LfoTarget type ) { m_LfoTarget = type; } void SetPriority( int priority ) { m_pVoice->SetPriority( priority ); } void SetReleasePriorityFix( bool fix ) { m_ReleasePriorityFixFlag = fix; } void SetIsIgnoreNoteOff( bool flag ) { m_IsIgnoreNoteOff = flag; } void SetFrontBypass( bool flag ) { m_pVoice->SetFrontBypass( flag ); } void SetSweepParam( f32 sweepPitch, int sweepTime, bool autoUpdate ); bool IsAutoUpdateSweep() const { return m_AutoSweep != 0 ; } void UpdateSweep( int count ); void SetPanMode( PanMode panMode ) { m_PanMode = panMode; } void SetPanCurve( PanCurve panCurve ) { m_PanCurve = panCurve; } //------------------------------------------------------------------ // 出力パラメータ void SetMainSend( f32 send ) { m_MainSend = send; } void SetFxSend( AuxBus bus, f32 send ) { m_FxSend[ bus ] = send; } //------------------------------------------------------------------ Channel* GetNextTrackChannel() const { return m_pNextLink; } void SetNextTrackChannel( Channel* channel ) { m_pNextLink = channel; } u32 GetCurrentPlayingSample() const; void SetKeyGroupId( u8 id ) { m_KeyGroupId = id; } u8 GetKeyGroupId() const { return m_KeyGroupId; } void SetInterpolationType( u8 type ) { m_InterpolationType = type; } u8 GetInterpolationType() const { return m_InterpolationType; } private: class Disposer : public DisposeCallback { public: Disposer(Channel* channel) : m_pChannel(channel) {} virtual ~Disposer() {} virtual void InvalidateData( const void* start, const void* end ); private: Channel* m_pChannel; }; friend class Disposer; f32 GetSweepValue() const; void InitParam( ChannelCallback callback, u32 callbackData ); Disposer m_Disposer; CurveAdshr m_CurveAdshr; CurveLfo m_Lfo; u8 m_LfoTarget; // enum LfoTarget u8 m_PauseFlag; u8 m_ActiveFlag; u8 m_AllocFlag; u8 m_AutoSweep; u8 m_ReleasePriorityFixFlag; u8 m_IsIgnoreNoteOff; u8 m_BiquadType; f32 m_UserVolume; f32 m_UserPitchRatio; f32 m_UserPan; f32 m_UserSurroundPan; f32 m_UserLpfFreq; f32 m_BiquadValue; f32 m_MainSend; f32 m_FxSend[ AUX_BUS_NUM ]; f32 m_UserPitch; f32 m_SweepPitch; s32 m_SweepCounter; s32 m_SweepLength; f32 m_InitVolume; f32 m_InitPan; f32 m_InitSurroundPan; f32 m_Tune; MoveValue m_SilenceVolume; f32 m_Cent; f32 m_CentPitch; s32 m_Length; PanMode m_PanMode; PanCurve m_PanCurve; u8 m_Key; u8 m_OriginalKey; u8 m_KeyGroupId; u8 m_InterpolationType; ChannelCallback m_Callback; u32 m_CallbackData; Voice* m_pVoice; Channel* m_pNextLink; public: ut::LinkListNode m_Link; #ifdef NW_PLATFORM_CTR static nn::os::Tick GetTick(); #endif }; } // namespace nw::snd::internal::driver } // namespace nw::snd::internal } // namespace nw::snd } // namespace nw #endif /* NW_SND_CHANNEL_H_ */