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