1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_Channel.h
4 
5   Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain proprietary
8   information of Nintendo and/or its licensed developers and are protected by
9   national and international copyright laws. They may not be disclosed to third
10   parties or copied or duplicated in any form, in whole or in part, without the
11   prior written consent of Nintendo.
12 
13   The content herein is highly confidential and should be handled accordingly.
14 
15   $Revision: 31311 $
16  *---------------------------------------------------------------------------*/
17 
18 #ifndef NW_SND_CHANNEL_H_
19 #define NW_SND_CHANNEL_H_
20 
21 #include <nn/snd.h>
22 #include <nw/snd/snd_Global.h>  // WaveInfo
23 #include <nw/snd/snd_Voice.h>   // Voice::PRIORITY_RELEASE
24 #include <nw/snd/snd_MoveValue.h>
25 #include <nw/snd/snd_CurveAdshr.h>
26 #include <nw/snd/snd_CurveLfo.h>
27 #include <nw/snd/snd_DisposeCallback.h>
28 
29 #ifdef NW_PLATFORM_CTR
30 #include <nw/snd/snd_HardwareManager.h>     // HardwareManager::AUDIO_CHANNEL_COUNT
31 #endif
32 
33 namespace nw {
34 namespace snd {
35 namespace internal {
36 namespace driver {
37 
38 /* ========================================================================
39         class definition
40    ======================================================================== */
41 
42 class Channel
43 {
44     /* ------------------------------------------------------------------------
45             typename definition
46        ------------------------------------------------------------------------ */
47 public:
48     enum LfoTarget
49     {
50         LFO_TARGET_PITCH,
51         LFO_TARGET_VOLUME,
52         LFO_TARGET_PAN
53     };
54 
55     enum ChannelCallbackStatus
56     {
57         CALLBACK_STATUS_STOPPED,
58         CALLBACK_STATUS_DROP,
59         CALLBACK_STATUS_FINISH,
60         CALLBACK_STATUS_CANCEL
61     };
62 
63     typedef void (*ChannelCallback) (
64         Channel *channel,
65         ChannelCallbackStatus status,
66         u32 userData );
67 
68     /* ------------------------------------------------------------------------
69             constant declaration
70        ------------------------------------------------------------------------ */
71 public:
72     static const int CHANNEL_NUM            = HardwareManager::SOUND_VOICE_COUNT + 1; // チャンネル数
73     static const int CHANNEL_MIN            = 0;
74     static const int CHANNEL_MAX            = CHANNEL_MIN + CHANNEL_NUM - 1;
75 
76     static const int PRIORITY_RELEASE       = Voice::PRIORITY_RELEASE;
77 
78 private:
79     static const int KEY_INIT               = 60;
80     static const int ORIGINAL_KEY_INIT      = 60;
81     static const u8  SILENCE_VOLUME_MAX     = 255;
82     static const u8  SILENCE_VOLUME_MIN     = 0;
83 
84     /* ------------------------------------------------------------------------
85             static members
86        ------------------------------------------------------------------------ */
87 public:
88     static Channel* AllocChannel(
89         int voiceChannelCount,
90         int priority,
91         ChannelCallback callback,
92         u32 callbackData
93     );
94     static void FreeChannel( Channel* channel );
95 
96 private:
97     static void VoiceCallbackFunc(
98         Voice* voice,
99         Voice::VoiceCallbackStatus status,
100         void* arg
101     );
102 
103 #ifdef NW_PLATFORM_CTR
104     void AppendWaveBuffer( const WaveInfo& waveInfo );
105 
106     static const int WAVE_BUFFER_MAX = 2;
107 
108     nn::snd::WaveBuffer m_WaveBuffer[Voice::CHANNEL_MAX][WAVE_BUFFER_MAX];
109     nn::snd::AdpcmContext m_AdpcmContext[Voice::CHANNEL_MAX];
110     nn::snd::AdpcmContext m_AdpcmLoopContext[Voice::CHANNEL_MAX];
111     u32 m_LoopStartFrame;
112     bool m_LoopFlag;
113 #endif
114 
115     /* ------------------------------------------------------------------------
116             class members
117        ------------------------------------------------------------------------ */
118 public:
119     Channel();
120     ~Channel();
121 
122     void Update( bool doPeriodicProc );
123 
124     void Start( const WaveInfo& waveParam, int length, u32 startOffset );
125     void NoteOff();
126     void Release();
127     void Stop();
Pause(bool flag)128     void Pause( bool flag ) { m_PauseFlag = flag; m_pVoice->Pause( flag ); }
IsActive()129     bool IsActive() const { return m_ActiveFlag != 0; }
IsPause()130     bool IsPause() const { return m_PauseFlag != 0; }
131 
132     //------------------------------------------------------------------
133     // 初期パラメータ
SetKey(u8 key)134     void SetKey( u8 key ) { m_Key = key; }
SetKey(u8 key,u8 originalKey)135     void SetKey( u8 key, u8 originalKey ) { m_Key = key; m_OriginalKey = originalKey; }
SetInitVolume(f32 volume)136     void SetInitVolume( f32 volume ) { m_InitVolume = volume; }
SetInitPan(f32 pan)137     void SetInitPan( f32 pan ) { m_InitPan = pan; }
SetInitSurroundPan(f32 surroundPan)138     void SetInitSurroundPan( f32 surroundPan ) { m_InitSurroundPan = surroundPan; }
SetTune(f32 tune)139     void SetTune( f32 tune ) { m_Tune = tune; }
140 
SetAttack(int attack)141     void SetAttack( int attack ) { m_CurveAdshr.SetAttack( attack ); }
SetHold(int hold)142     void SetHold( int hold ) { m_CurveAdshr.SetHold( hold ); }
SetDecay(int decay)143     void SetDecay( int decay ) { m_CurveAdshr.SetDecay( decay ); }
SetSustain(int sustain)144     void SetSustain( int sustain ) { m_CurveAdshr.SetSustain( sustain ); }
SetRelease(int release)145     void SetRelease( int release ) { m_CurveAdshr.SetRelease( release ); }
146 
SetSilence(bool silenceFlag,int fadeTimes)147     void SetSilence( bool silenceFlag, int fadeTimes )
148     {
149         NW_MINMAX_ASSERT( fadeTimes, 0, USHRT_MAX );
150         m_SilenceVolume.SetTarget(
151             silenceFlag? SILENCE_VOLUME_MIN: SILENCE_VOLUME_MAX,
152             static_cast<u16>( fadeTimes )
153         );
154     }
155 
GetLength()156     s32 GetLength() const { return m_Length; }
SetLength(s32 length)157     void SetLength( s32 length ) { m_Length = length; }
IsRelease()158     bool IsRelease() const { return m_CurveAdshr.GetStatus() == CurveAdshr::STATUS_RELEASE; }
159 
160     //------------------------------------------------------------------
161     // ユーザーパラメータ
SetUserVolume(f32 volume)162     void SetUserVolume( f32 volume ) { m_UserVolume = volume; }
SetUserPitch(f32 pitch)163     void SetUserPitch( f32 pitch ) { m_UserPitch = pitch; }
SetUserPitchRatio(f32 pitchRatio)164     void SetUserPitchRatio( f32 pitchRatio ) { m_UserPitchRatio = pitchRatio; }
SetUserPan(f32 pan)165     void SetUserPan( f32 pan ) { m_UserPan = pan; }
SetUserSurroundPan(f32 surroundPan)166     void SetUserSurroundPan( f32 surroundPan ) { m_UserSurroundPan = surroundPan; }
SetUserLpfFreq(f32 lpfFreq)167     void SetUserLpfFreq( f32 lpfFreq ) { m_UserLpfFreq = lpfFreq; }
168     void SetBiquadFilter( int type, f32 value );
SetLfoParam(const CurveLfoParam & param)169     void SetLfoParam( const CurveLfoParam& param ) { m_Lfo.SetParam( param ); }
SetLfoTarget(LfoTarget type)170     void SetLfoTarget( LfoTarget type ) { m_LfoTarget = type; }
SetPriority(int priority)171     void SetPriority( int priority ) { m_pVoice->SetPriority( priority ); }
SetReleasePriorityFix(bool fix)172     void SetReleasePriorityFix( bool fix ) { m_ReleasePriorityFixFlag = fix; }
SetIsIgnoreNoteOff(bool flag)173     void SetIsIgnoreNoteOff( bool flag ) { m_IsIgnoreNoteOff = flag; }
SetFrontBypass(bool flag)174     void SetFrontBypass( bool flag ) { m_pVoice->SetFrontBypass( flag ); }
175 
176     void SetSweepParam( f32 sweepPitch, int sweepTime, bool autoUpdate );
IsAutoUpdateSweep()177     bool IsAutoUpdateSweep() const { return m_AutoSweep != 0 ; }
178     void UpdateSweep( int count );
179 
SetPanMode(PanMode panMode)180     void SetPanMode( PanMode panMode ) { m_PanMode = panMode; }
SetPanCurve(PanCurve panCurve)181     void SetPanCurve( PanCurve panCurve ) { m_PanCurve = panCurve; }
182 
183     //------------------------------------------------------------------
184     // 出力パラメータ
SetMainSend(f32 send)185     void SetMainSend( f32 send ) { m_MainSend = send; }
SetFxSend(AuxBus bus,f32 send)186     void SetFxSend( AuxBus bus, f32 send ) { m_FxSend[ bus ] = send; }
187 
188     //------------------------------------------------------------------
GetNextTrackChannel()189     Channel* GetNextTrackChannel() const { return m_pNextLink; }
SetNextTrackChannel(Channel * channel)190     void SetNextTrackChannel( Channel* channel ) { m_pNextLink = channel; }
191 
192     u32 GetCurrentPlayingSample() const;
193 
SetKeyGroupId(u8 id)194     void SetKeyGroupId( u8 id ) { m_KeyGroupId = id; }
GetKeyGroupId()195     u8 GetKeyGroupId() const { return m_KeyGroupId; }
196 
SetInterpolationType(u8 type)197     void SetInterpolationType( u8 type ) { m_InterpolationType = type; }
GetInterpolationType()198     u8 GetInterpolationType() const { return m_InterpolationType; }
199 
200 private:
201     class Disposer : public DisposeCallback
202     {
203       public:
Disposer(Channel * channel)204         Disposer(Channel* channel) : m_pChannel(channel) {}
~Disposer()205         virtual ~Disposer() {}
206         virtual void InvalidateData( const void* start, const void* end );
207       private:
208         Channel* m_pChannel;
209     };
210     friend class Disposer;
211 
212     f32 GetSweepValue() const;
213     void InitParam( ChannelCallback callback, u32 callbackData );
214 
215     Disposer m_Disposer;
216     CurveAdshr m_CurveAdshr;
217     CurveLfo m_Lfo;
218     u8 m_LfoTarget; // enum LfoTarget
219 
220     u8 m_PauseFlag;
221     u8 m_ActiveFlag;
222     u8 m_AllocFlag;
223     u8 m_AutoSweep;
224     u8 m_ReleasePriorityFixFlag;
225     u8 m_IsIgnoreNoteOff;
226     u8 m_BiquadType;
227 
228     f32 m_UserVolume;
229     f32 m_UserPitchRatio;
230     f32 m_UserPan;
231     f32 m_UserSurroundPan;
232     f32 m_UserLpfFreq;
233     f32 m_BiquadValue;
234     f32 m_MainSend;
235     f32 m_FxSend[ AUX_BUS_NUM ];
236 
237     f32 m_UserPitch;
238     f32 m_SweepPitch;
239     s32 m_SweepCounter;
240     s32 m_SweepLength;
241 
242     f32 m_InitVolume;
243     f32 m_InitPan;
244     f32 m_InitSurroundPan;
245     f32 m_Tune;
246     MoveValue<u8, u16> m_SilenceVolume;
247 
248     f32 m_Cent;
249     f32 m_CentPitch;
250 
251     s32 m_Length;
252 
253     PanMode m_PanMode;
254     PanCurve m_PanCurve;
255 
256     u8 m_Key;
257     u8 m_OriginalKey;
258     u8 m_KeyGroupId;
259     u8 m_InterpolationType;
260 
261     ChannelCallback m_Callback;
262     u32 m_CallbackData;
263 
264     Voice* m_pVoice;
265 
266     Channel* m_pNextLink;
267 
268 public:
269     ut::LinkListNode m_Link;
270 
271   #ifdef NW_PLATFORM_CTR
272     static nn::os::Tick GetTick();
273   #endif
274 };
275 
276 } // namespace nw::snd::internal::driver
277 } // namespace nw::snd::internal
278 } // namespace nw::snd
279 } // namespace nw
280 
281 
282 #endif /* NW_SND_CHANNEL_H_ */
283 
284