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