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