1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_SequenceSoundPlayer.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  * :include nw/snd/snd_SequenceSoundPlayer.h
19  *
20  * @file snd_SequenceSoundPlayer.h
21  */
22 
23 #ifndef NW_SND_SEQUENCE_SOUND_PLAYER_H_
24 #define NW_SND_SEQUENCE_SOUND_PLAYER_H_
25 
26 #include <nw/snd/snd_BasicSoundPlayer.h>
27 #include <nw/snd/snd_DisposeCallback.h>
28 #include <nw/snd/snd_SoundThread.h>
29 #include <nw/snd/snd_NoteOnCallback.h>      // NoteOnCallback, NoteOnInfo
30 #include <nw/snd/snd_SoundArchive.h>
31 
32 namespace nw {
33 namespace snd {
34 
35 // シーケンスコマンド'userproc'用コールバック
36 //---------------------------------------------------------------------------
37 //! @brief    'userproc' コマンドで呼び出されるコールバックで使用される構造体です。
38 //!
39 //!           'userproc' コマンドの詳細については、
40 //!           シーケンスデータマニュアルを参照してください。
41 //---------------------------------------------------------------------------
42 struct SequenceUserprocCallbackParam
43 {
44     //---------------------------------------------------------------------------
45     //! @brief    ローカル変数の配列です。
46     //!           localVariable[0] から localVariable[15] まで指定できます。
47     //!           変数の値を参照、あるいは変更することができます。
48     //---------------------------------------------------------------------------
49     vs16* localVariable;
50 
51     //---------------------------------------------------------------------------
52     //! @brief    グローバル変数の配列です。
53     //!           globalVariable[0] から globalVariable[15] まで指定できます。
54     //!           変数の値を参照、あるいは変更することができます。
55     //---------------------------------------------------------------------------
56     vs16* globalVariable;
57 
58     //---------------------------------------------------------------------------
59     //! @brief    トラック変数の配列です。
60     //!           trackVariable[0] から trackVariable[15] まで指定できます。
61     //!           変数の値を参照、あるいは変更することができます。
62     //---------------------------------------------------------------------------
63     vs16* trackVariable;
64 
65     //---------------------------------------------------------------------------
66     //! @brief    比較コマンドで設定される真偽のフラグです。
67     //!           フラグの状態を参照、あるいは変更することができます。
68     //---------------------------------------------------------------------------
69     bool cmpFlag;
70 };
71 
72 //---------------------------------------------------------------------------
73 //! @brief    シーケンスサウンドで使用可能なユーザープロシージャのコールバックです。
74 //!
75 //!           このコールバックはシーケンスデータ内の 'userproc'
76 //!           コマンドによって呼び出されます。
77 //!           'userproc' コマンドが処理されたフレームで、
78 //!           サウンドスレッドから呼び出されます。
79 //!
80 //!           procId は、シーケンスデータで 'userproc'
81 //!           コマンドのパラメータとして指定された値が渡されます。
82 //!
83 //!           param は、コールバック内で利用できるパラメータです。
84 //!           データで設定されてる値を参照することができます。
85 //!           また、この値を書き換えることでサウンドデータに反映することが出来ます。
86 //!
87 //!           'userproc' コマンドの詳細については、
88 //!           シーケンスデータマニュアルを参照してください。
89 //!
90 //! @param[in] procId     シーケンスデータで指定されたプロシージャ ID です。
91 //! @param[in] param      コールバック内で利用できるパラメータです。
92 //! @param[in] arg        ユーザー引数です。
93 //!
94 //! @see      @ref SoundArchivePlayer::SetSequenceUserprocCallback,
95 //!           @ref SequenceUserprocCallbackParam
96 //---------------------------------------------------------------------------
97 typedef void (*SequenceUserprocCallback)(
98     u16 procId,
99     SequenceUserprocCallbackParam* param,
100     void* arg
101 );
102 
103 namespace internal {
104 namespace driver {
105 
106 /* ========================================================================
107         typename declaration
108    ======================================================================== */
109 
110 class SequenceTrack;
111 class SequenceTrackAllocator;
112 
113 /* ========================================================================
114         class definition
115    ======================================================================== */
116 
117 class SequenceSoundPlayer : public BasicSoundPlayer, public DisposeCallback, public SoundThread::PlayerCallback
118 {
119     /* ------------------------------------------------------------------------
120             constant variable
121        ------------------------------------------------------------------------ */
122 public:
123     static const int PLAYER_VARIABLE_NUM    = 16;
124     static const int GLOBAL_VARIABLE_NUM    = 16;
125     static const int TRACK_NUM_PER_PLAYER   = 16;
126     static const int VARIABLE_DEFAULT_VALUE = -1;
127 
128     static const int DEFAULT_TIMEBASE       = 48; /* 四分音符分解能 */
129     static const int DEFAULT_TEMPO          = 120;
130 
131     static const int MAX_SKIP_TICK_PER_FRAME = 48*4*4;
132 
133     /* ------------------------------------------------------------------------
134             type definition
135        ------------------------------------------------------------------------ */
136 public:
137     struct ParserPlayerParam
138     {
139         u8 volume;
140         u8 priority;
141         u8 timebase;
142         u16 tempo;
143 
144         NoteOnCallback* callback;
145     };
146 
147 #if 0
148     enum SetupResult
149     {
150         SETUP_SUCCESS = 0,
151         SETUP_ERR_CANNOT_ALLOCATE_TRACK,
152         SETUP_ERR_UNKNOWN
153     };
154 #endif
155 
156     enum OffsetType
157     {
158         OFFSET_TYPE_TICK,
159         OFFSET_TYPE_MILLISEC
160     };
161 
162     /* ------------------------------------------------------------------------
163             class member
164        ------------------------------------------------------------------------ */
165 public:
166     static void InitSequenceSoundPlayer();
167 
168     SequenceSoundPlayer();
169     virtual ~SequenceSoundPlayer();
170 
171     virtual void Initialize();
172     virtual void Finalize();
173 
174     void Setup(
175         SequenceTrackAllocator* trackAllocator,
176         u32 allocTracks,
177         NoteOnCallback* callback
178     );
179 
180     void SetSeqData( const void* seqBase, s32 seqOffset );
181     void SetBankData( const void* bankFiles[], u32 bankFileCount );
182 
183     virtual void Start();
184     virtual void Stop();
185     virtual void Pause( bool flag );
186     void Skip( OffsetType offsetType, int offset );
187 
188     Channel* NoteOn(
189         u8 bankIndex,
190         const NoteOnInfo& noteOnInfo
191     );
192 
193     void SetSequenceUserprocCallback( SequenceUserprocCallback callback, void* arg );
194     void CallSequenceUserprocCallback( u16 procId, SequenceTrack* track );
195 
196     //------------------------------------------------------------------
197     // プレイヤーパラメータ
198     void SetTempoRatio( float tempoRatio );
199     void SetPanRange( float panRange );
200     void SetChannelPriority( int priority );
201     void SetReleasePriorityFix( bool fix );
202 
GetTempoRatio()203     float GetTempoRatio() const { return m_TempoRatio; }
GetPanRange()204     float GetPanRange() const { return m_PanRange; }
GetChannelPriority()205     int GetChannelPriority() const { return m_ParserParam.priority; }
206 
IsReleasePriorityFix()207     bool IsReleasePriorityFix() const { return m_ReleasePriorityFixFlag; }
208 
209     //------------------------------------------------------------------
210     // トラックパラメータ
211     void SetTrackMute( u32 trackBitFlag, SeqMute mute );
212     void SetTrackSilence( unsigned long trackBitFlag, bool silenceFlag, int fadeTimes );
213     void SetTrackVolume( u32 trackBitFlag, float volume );
214     void SetTrackPitch( u32 trackBitFlag, float pitch );
215     void SetTrackPan( u32 trackBitFlag, float pan );
216     void SetTrackSurroundPan( u32 trackBitFlag, float surroundPan );
217     void SetTrackPanRange( u32 trackBitFlag, float panRange );
218     void SetTrackLpfFreq( u32 trackBitFlag, float lpfFreq );
219     void SetTrackBiquadFilter( u32 trackBitFlag, int type, float value );
220     void SetTrackModDepth( u32 trackBitFlag, float depth );
221     void SetTrackModSpeed( u32 trackBitFlag, float speed );
222     bool SetTrackBankIndex( u32 trackBitFlag, int bankIndex );
223 
SetBankFile(u8 bankIndex,const void * pBankFile)224     void SetBankFile( u8 bankIndex, const void* pBankFile )
225     {
226         m_pBankFiles[ bankIndex ] = pBankFile;
227     }
GetBankFile(u8 bankIndex)228     const void* GetBankFile( u8 bankIndex ) const { return m_pBankFiles[ bankIndex ]; }
229 
230     //------------------------------------------------------------------
231     // シーケンス変数
232     s16 GetLocalVariable( int varNo ) const;
233     static s16 GetGlobalVariable( int varNo );
234     void SetLocalVariable( int varNo, s16 var );
235     static void SetGlobalVariable( int varNo, s16 var );
236 
237     vs16* GetVariablePtr( int varNo );
238 
239     //------------------------------------------------------------------
240     // invalidate
241     virtual void InvalidateData( const void* start, const void* end );
242 
243     //------------------------------------------------------------------
244     // info
GetParserPlayerParam()245     const ParserPlayerParam& GetParserPlayerParam() const { return m_ParserParam; }
GetParserPlayerParam()246     ParserPlayerParam& GetParserPlayerParam() { return m_ParserParam; }
GetTickCounter()247     u32 GetTickCounter() const { return m_TickCounter; }
248 
249     //------------------------------------------------------------------
250     SequenceTrack* GetPlayerTrack( int trackNo );
251     const SequenceTrack* GetPlayerTrack( int trackNo ) const;
252     void SetPlayerTrack( int trackNo, SequenceTrack* track );
253 
GetTrackAllocator()254     const SequenceTrackAllocator* GetTrackAllocator() { return m_pSequenceTrackAllocator; }
255 
256     void Update();
257 
ChannelCallback(Channel * channel)258     virtual void ChannelCallback( Channel* channel ) { (void)channel; }
259 
260 protected:
OnUpdateFrameSoundThread()261     virtual void OnUpdateFrameSoundThread() { Update(); }
OnShutdownSoundThread()262     virtual void OnShutdownSoundThread() { Stop(); }
263 
264 private:
265     template< typename T >
266     void SetTrackParam( u32 trackBitFlag, void (SequenceTrack::*func)( T ), T param );
267     template< typename T, typename U >
268     void SetTrackParam( u32 trackBitFlag, void (SequenceTrack::*func)( T, U ), T param1, U param2 );
269 
270     int  ParseNextTick( bool doNoteOn );
271 
272     void UpdateChannelParam();
273     void UpdateTick();
274     void SkipTick();
275 
276     void CloseTrack( int trackNo );
277     void FinishPlayer();
278 
CalcTickPerMinute()279     f32 CalcTickPerMinute() const { return m_ParserParam.timebase * m_ParserParam.tempo * m_TempoRatio; }
CalcTickPerMsec()280     f32 CalcTickPerMsec() const { return CalcTickPerMinute() / ( 60 * 1000.0f ); }
281 
282     static vs16 m_GlobalVariable[ GLOBAL_VARIABLE_NUM ];
283 
284     bool m_ReleasePriorityFixFlag;
285 
286     f32 m_PanRange;
287     f32 m_TempoRatio;
288     f32 m_TickFraction;
289     u32 m_SkipTickCounter;
290     f32 m_SkipTimeCounter;
291 
292     ParserPlayerParam m_ParserParam;
293     SequenceTrackAllocator* m_pSequenceTrackAllocator;
294 
295     SequenceUserprocCallback m_SequenceUserprocCallback;
296     void* m_pSequenceUserprocCallbackArg;
297 
298     SequenceTrack* m_pTracks[ TRACK_NUM_PER_PLAYER ];
299 
300     vs16 m_LocalVariable[ PLAYER_VARIABLE_NUM ];
301     vu32 m_TickCounter;
302 
303     const void* m_pBankFiles[ SoundArchive::SEQ_BANK_MAX ];
304 };
305 
306 template< typename T >
SetTrackParam(u32 trackBitFlag,void (SequenceTrack::* func)(T),T param)307 void SequenceSoundPlayer::SetTrackParam( u32 trackBitFlag, void (SequenceTrack::*func)( T ), T param )
308 {
309     for( int trackNo = 0;
310          trackNo < TRACK_NUM_PER_PLAYER && trackBitFlag != 0 ;
311          trackNo++, trackBitFlag >>= 1
312     )
313     {
314         if ( ( trackBitFlag & 0x01 ) == 0 ) continue;
315         SequenceTrack* track = GetPlayerTrack( trackNo );
316         if ( track != NULL ) (track->*func)( param );
317     }
318 }
319 
320 template< typename T, typename U >
SetTrackParam(u32 trackBitFlag,void (SequenceTrack::* func)(T,U),T param1,U param2)321 void SequenceSoundPlayer::SetTrackParam( u32 trackBitFlag, void (SequenceTrack::*func)( T, U ), T param1, U param2 )
322 {
323     for( int trackNo = 0;
324          trackNo < TRACK_NUM_PER_PLAYER && trackBitFlag != 0 ;
325          trackNo++, trackBitFlag >>= 1
326     )
327     {
328         if ( ( trackBitFlag & 0x01 ) == 0 ) continue;
329         SequenceTrack* track = GetPlayerTrack( trackNo );
330         if ( track != NULL ) (track->*func)( param1, param2 );
331     }
332 }
333 
334 } // namespace nw::snd::internal::driver
335 } // namespace nw::snd::internal
336 } // namespace nw::snd
337 } // namespace nw
338 
339 
340 #endif /* NW_SND_SEQUENCE_SOUND_PLAYER_H_ */
341 
342