1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: snd_SequenceSoundPlayer.cpp
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 "precompiled.h"
19
20 #include <nw/snd/snd_SequenceSoundPlayer.h>
21
22 #include <nw/snd/snd_SequenceTrack.h>
23 #include <nw/snd/snd_SequenceTrackAllocator.h>
24 #include <nw/snd/snd_DisposeCallbackManager.h>
25 #include <nw/snd/snd_HardwareManager.h>
26 #include <nw/snd/snd_NoteOnCallback.h>
27 #include <nw/snd/snd_SoundThread.h>
28
29 namespace
30 {
31 // DSP プロセスの割り込み間隔の分母・分子。
32 // NUMERATOR / DENOMINATOR [msec] (約 4.888 ...) が実際の割り込み間隔。
33 const u32 INTERVAL_MSEC_NUMERATOR = NN_SND_SAMPLES_PER_FRAME * 1000 * (32 * 256);
34 const u32 INTERVAL_MSEC_DENOMINATOR = NN_SND_HW_SYSTEM_CLOCK;
35 }
36
37 namespace nw {
38 namespace snd {
39 namespace internal {
40 namespace driver {
41
42 /* ========================================================================
43 static variable
44 ======================================================================== */
45
46 vs16 SequenceSoundPlayer::m_GlobalVariable[ GLOBAL_VARIABLE_NUM ];
47
48 /* ========================================================================
49 public function
50 ======================================================================== */
51
InitSequenceSoundPlayer()52 void SequenceSoundPlayer::InitSequenceSoundPlayer()
53 {
54 for( int variableNo = 0 ; variableNo < GLOBAL_VARIABLE_NUM ; variableNo++ )
55 {
56 m_GlobalVariable[ variableNo ] = VARIABLE_DEFAULT_VALUE;
57 }
58 }
59
60 /*---------------------------------------------------------------------------*
61 Name: SequenceSoundPlayer
62
63 Description: コンストラクタ
64
65 Arguments: None.
66
67 Returns: None.
68 *---------------------------------------------------------------------------*/
SequenceSoundPlayer()69 SequenceSoundPlayer::SequenceSoundPlayer()
70 {
71 for ( int trackNo = 0; trackNo < TRACK_NUM_PER_PLAYER ; trackNo++ )
72 {
73 m_pTracks[trackNo] = NULL;
74 }
75 }
76
77 /*---------------------------------------------------------------------------*
78 Name: ~SequenceSoundPlayer
79
80 Description: デストラクタ
81
82 Arguments: None.
83
84 Returns: None.
85 *---------------------------------------------------------------------------*/
~SequenceSoundPlayer()86 SequenceSoundPlayer::~SequenceSoundPlayer()
87 {
88 Finalize();
89 }
90
91 /*---------------------------------------------------------------------------*
92 Name: Initialize
93
94 Description: パラメータを初期化します
95
96 Arguments: None.
97
98 Returns: None.
99 *---------------------------------------------------------------------------*/
Initialize()100 void SequenceSoundPlayer::Initialize()
101 {
102 BasicSoundPlayer::Initialize();
103
104 m_StartedFlag = false;
105 m_PauseFlag = false;
106 m_ReleasePriorityFixFlag = false;
107
108 m_TempoRatio = 1.0f;
109 m_TickFraction = 0.0f;
110 m_SkipTickCounter = 0;
111 m_SkipTimeCounter = 0.0f;
112 m_PanRange = 1.0f;
113 m_TickCounter = 0;
114 m_TickFraction = 0.0f;
115
116 m_SequenceUserprocCallback = NULL;
117 m_pSequenceUserprocCallbackArg = NULL;
118
119 m_ParserParam.tempo = DEFAULT_TEMPO;
120 m_ParserParam.timebase = DEFAULT_TIMEBASE;
121 m_ParserParam.volume = 127;
122 m_ParserParam.priority = 64;
123 m_ParserParam.callback = NULL;
124
125 for ( int varNo = 0; varNo < PLAYER_VARIABLE_NUM ; varNo++ )
126 {
127 m_LocalVariable[ varNo ] = VARIABLE_DEFAULT_VALUE;
128 }
129
130 for ( int trackNo = 0; trackNo < TRACK_NUM_PER_PLAYER ; trackNo++ )
131 {
132 m_pTracks[trackNo] = NULL;
133 }
134
135 for ( int bankIdx = 0; bankIdx < SoundArchive::SEQ_BANK_MAX; bankIdx++ )
136 {
137 m_pBankFiles[ bankIdx ] = NULL;
138 }
139 }
140
141 /*---------------------------------------------------------------------------*
142 Name: Finalize
143
144 Description: シーケンスプレイヤーのシャットダウン
145
146 Arguments: None.
147
148 Returns: None.
149 *---------------------------------------------------------------------------*/
Finalize()150 void SequenceSoundPlayer::Finalize()
151 {
152 m_FinishFlag = true;
153
154 FinishPlayer();
155
156 // 無効化リストから削除
157 if ( m_ActiveFlag )
158 {
159 DisposeCallbackManager::GetInstance().UnregisterDisposeCallback( this );
160 m_ActiveFlag = false;
161 }
162
163 // NN_LOG( "track rest %d\n",m_pSequenceTrackAllocator->GetAllocatableTrackCount());
164 BasicSoundPlayer::Finalize();
165 }
166
167 /*---------------------------------------------------------------------------*
168 Name: Setup
169
170 Description: シーケンスの初期化を行います
171
172 Arguments:
173
174 Returns: None.
175 *---------------------------------------------------------------------------*/
Setup(SequenceTrackAllocator * trackAllocator,u32 allocTracks,NoteOnCallback * callback)176 void SequenceSoundPlayer::Setup(
177 SequenceTrackAllocator* trackAllocator,
178 u32 allocTracks,
179 NoteOnCallback* callback
180 )
181 {
182 //-----------------------------------------------------------------------------
183 // プレイヤー初期化
184 m_ParserParam.callback = callback;
185
186 {
187 //-----------------------------------------------------------------------------
188 // 全トラックを確保することができるかどうか
189 {
190 int trackCount = 0;
191 for( u32 trackBitMask = allocTracks; trackBitMask != 0; trackBitMask >>= 1 )
192 {
193 if ( trackBitMask & 0x01 ) trackCount++;
194 }
195 if ( trackCount > trackAllocator->GetAllocatableTrackCount() )
196 {
197 #if 0
198 return SETUP_ERR_CANNOT_ALLOCATE_TRACK;
199 #else
200 NW_WARNING(false, "Failed to start sequence sound for not enough sequence track instance." );
201 Finalize();
202 return;
203 #endif
204 }
205 }
206
207 //-----------------------------------------------------------------------------
208 // トラック確保
209 {
210 u32 trackBitMask = allocTracks;
211 for( int trackNo = 0; trackBitMask != 0; trackNo++, trackBitMask >>= 1 )
212 {
213 if ( ( trackBitMask & 0x01 ) == 0 ) continue;
214
215 SequenceTrack* track = trackAllocator->AllocTrack( this );
216 NW_NULL_ASSERT( track );
217 SetPlayerTrack( trackNo, track );
218 // NN_LOG("AllocTrack %08x\n",track);
219 }
220 }
221 }
222
223 // NN_LOG( "track rest %d\n",trackAllocator->GetAllocatableTrackCount());
224
225 // 無効化リストに追加
226 DisposeCallbackManager::GetInstance().RegisterDisposeCallback( this );
227
228 m_pSequenceTrackAllocator = trackAllocator;
229 m_ActiveFlag = true;
230
231 #ifdef NW_PLATFORM_CTR
232 #if 0 // TODO: perf
233 for ( int i = 0; i < PERF_NUM; i++ )
234 {
235 s_PerfParam[ i ].Reset();
236 s_PerfParam[ i ].isCalcTick = true;
237 }
238 #endif
239 #endif
240 // SoundThread::GetInstance().SetSoundPlay( true );
241
242 // return SETUP_SUCCESS;
243 }
244
245 /*---------------------------------------------------------------------------*
246 Name: SetSeqData
247
248 Description: シーケンスの再生準備を行います
249
250 Arguments: seqBase - シーケンスデータベースアドレス
251 seqOffset - シーケンスデータオフセット
252
253 Returns: None.
254 *---------------------------------------------------------------------------*/
SetSeqData(const void * seqBase,s32 seqOffset)255 void SequenceSoundPlayer::SetSeqData( const void* seqBase, s32 seqOffset )
256 {
257 SequenceTrack* seqTrack = GetPlayerTrack( 0 );
258 if ( seqTrack == NULL )
259 {
260 return;
261 }
262
263 if ( seqBase != NULL )
264 {
265 seqTrack->SetSeqData( seqBase, seqOffset );
266 seqTrack->Open();
267 }
268 }
269
SetBankData(const void * bankFiles[],u32 bankFileCount)270 void SequenceSoundPlayer::SetBankData( const void* bankFiles[], u32 bankFileCount )
271 {
272 NW_ASSERT( bankFileCount <= SoundArchive::SEQ_BANK_MAX );
273
274 if ( bankFiles != NULL )
275 {
276 for ( u32 i = 0; i < bankFileCount; i++ )
277 {
278 m_pBankFiles[ i ] = bankFiles[ i ];
279 }
280 }
281 }
282
283 /*---------------------------------------------------------------------------*
284 Name: Start
285
286 Description: 準備完了したシーケンスの再生を開始します
287
288 Arguments: playerNo - プレイヤー番号
289
290 Returns: None.
291 *---------------------------------------------------------------------------*/
Start()292 void SequenceSoundPlayer::Start()
293 {
294 // プレイヤーリストに追加
295 SoundThread::GetInstance().RegisterPlayerCallback( this );
296 m_StartedFlag = true;
297 }
298
299 /*---------------------------------------------------------------------------*
300 Name: Stop
301
302 Description: シーケンスを止めます
303
304 Arguments: playerNo - プレイヤー番号
305
306 Returns: None.
307 *---------------------------------------------------------------------------*/
Stop()308 void SequenceSoundPlayer::Stop()
309 {
310 FinishPlayer();
311 }
312
313 /*---------------------------------------------------------------------------*
314 Name: Pause
315
316 Description: シーケンスを一時停止または再開します
317
318 Arguments: playerNo - プレイヤー番号
319 flag - trueで一時停止、falseで再開します
320
321 Returns: None.
322 *---------------------------------------------------------------------------*/
Pause(bool flag)323 void SequenceSoundPlayer::Pause( bool flag )
324 {
325 m_PauseFlag = flag;
326
327 // 全トラックのチャンネルを停止
328 SequenceTrack* track;
329 for( int trackNo = 0; trackNo < TRACK_NUM_PER_PLAYER ; trackNo++ )
330 {
331 track = GetPlayerTrack( trackNo );
332 if ( track == NULL ) continue;
333
334 track->PauseAllChannel( flag );
335 }
336 }
337
338 /*---------------------------------------------------------------------------*
339 Name: Skip
340
341 Description: シーケンスをスキップします
342 注意:サウンドフレームを生成するタイマーを一時的に止めています
343
344 Arguments: playerNo - プレイヤー番号
345 tick - スキップ量をティックで指定します
346
347 Returns: None.
348 *---------------------------------------------------------------------------*/
Skip(OffsetType offsetType,int offset)349 void SequenceSoundPlayer::Skip( OffsetType offsetType, int offset )
350 {
351 if ( !m_ActiveFlag )
352 {
353 return;
354 }
355
356 switch ( offsetType )
357 {
358 case OFFSET_TYPE_TICK:
359 m_SkipTickCounter += offset;
360 break;
361 case OFFSET_TYPE_MILLISEC:
362 m_SkipTimeCounter += static_cast<f32>( offset );
363 break;
364 }
365 }
366
SetTempoRatio(float tempoRatio)367 void SequenceSoundPlayer::SetTempoRatio( float tempoRatio )
368 {
369 NW_ASSERT( tempoRatio >= 0.0f );
370 m_TempoRatio = tempoRatio;
371 }
372
SetPanRange(float panRange)373 void SequenceSoundPlayer::SetPanRange( float panRange )
374 {
375 m_PanRange = panRange;
376 }
377
SetChannelPriority(int priority)378 void SequenceSoundPlayer::SetChannelPriority( int priority )
379 {
380 NW_MINMAX_ASSERT( priority, 0, 127 );
381 m_ParserParam.priority = static_cast<u8>( priority );
382 }
383
SetReleasePriorityFix(bool fix)384 void SequenceSoundPlayer::SetReleasePriorityFix( bool fix )
385 {
386 m_ReleasePriorityFixFlag = fix;
387 }
388
SetSequenceUserprocCallback(SequenceUserprocCallback callback,void * arg)389 void SequenceSoundPlayer::SetSequenceUserprocCallback( SequenceUserprocCallback callback, void* arg )
390 {
391 m_SequenceUserprocCallback = callback;
392 m_pSequenceUserprocCallbackArg = arg;
393 }
394
CallSequenceUserprocCallback(u16 procId,SequenceTrack * track)395 void SequenceSoundPlayer::CallSequenceUserprocCallback( u16 procId, SequenceTrack* track )
396 {
397 if ( m_SequenceUserprocCallback == NULL )
398 {
399 return;
400 }
401
402 NW_NULL_ASSERT( track );
403
404 SequenceTrack::ParserTrackParam& trackParam = track->GetParserTrackParam();
405
406 SequenceUserprocCallbackParam param;
407 param.localVariable = GetVariablePtr( 0 );
408 param.globalVariable = GetVariablePtr( 16 );
409 param.trackVariable = track->GetVariablePtr( 0 );
410 param.cmpFlag = trackParam.cmpFlag;
411
412 m_SequenceUserprocCallback(
413 procId,
414 ¶m,
415 m_pSequenceUserprocCallbackArg
416 );
417
418 trackParam.cmpFlag = param.cmpFlag;
419 }
420
421
422 /*---------------------------------------------------------------------------*
423 Name: GetLocalVariable
424
425 Description: シーケンスローカル変数を取得します。
426
427 Arguments: player - プレイヤー
428 varNo - 変数番号
429
430 Returns: 変数の値
431 *---------------------------------------------------------------------------*/
GetLocalVariable(int varNo) const432 s16 SequenceSoundPlayer::GetLocalVariable( int varNo ) const
433 {
434 NW_MINMAXLT_ASSERT( varNo, 0, PLAYER_VARIABLE_NUM );
435
436 return m_LocalVariable[ varNo ];
437 }
438
439 /*---------------------------------------------------------------------------*
440 Name: GetGlobalVariable
441
442 Description: シーケンスグローバル変数を取得します。
443
444 Arguments: varNo - 変数番号
445
446 Returns: 変数の値
447 *---------------------------------------------------------------------------*/
GetGlobalVariable(int varNo)448 s16 SequenceSoundPlayer::GetGlobalVariable( int varNo )
449 {
450 NW_MINMAXLT_ASSERT( varNo, 0, GLOBAL_VARIABLE_NUM );
451
452 return m_GlobalVariable[ varNo ];
453 }
454
455 /*---------------------------------------------------------------------------*
456 Name: SetLocalVariable
457
458 Description: シーケンスローカル変数を設定します。
459
460 Arguments: player - プレイヤー
461 varNo - 変数番号
462 var - 変数値
463
464 Returns: 変数の値
465 *---------------------------------------------------------------------------*/
SetLocalVariable(int varNo,s16 var)466 void SequenceSoundPlayer::SetLocalVariable( int varNo, s16 var )
467 {
468 NW_MINMAXLT_ASSERT( varNo, 0, PLAYER_VARIABLE_NUM );
469
470 m_LocalVariable[ varNo ] = var;
471 }
472
473 /*---------------------------------------------------------------------------*
474 Name: SetGlobalVariable
475
476 Description: シーケンスグローバル変数を設定します。
477
478 Arguments: varNo - 変数番号
479 var - 変数値
480
481 Returns: 変数の値
482 *---------------------------------------------------------------------------*/
SetGlobalVariable(int varNo,s16 var)483 void SequenceSoundPlayer::SetGlobalVariable( int varNo, s16 var )
484 {
485 NW_MINMAXLT_ASSERT( varNo, 0, GLOBAL_VARIABLE_NUM );
486
487 m_GlobalVariable[ varNo ] = var;
488 }
489
490 /*---------------------------------------------------------------------------*
491 Name: SetTrackMute
492
493 Description: トラックをミュートまたはミュート解除します
494
495 Arguments: trackBitFlag - ミュート設定するトラックのビットマスク
496 flag - trueでミュート、falseでミュート解除します
497
498 Returns: None.
499 *---------------------------------------------------------------------------*/
SetTrackMute(u32 trackBitFlag,SeqMute mute)500 void SequenceSoundPlayer::SetTrackMute( u32 trackBitFlag, SeqMute mute )
501 {
502 SetTrackParam( trackBitFlag, &SequenceTrack::SetMute, mute );
503 }
504
SetTrackSilence(unsigned long trackBitFlag,bool silenceFlag,int fadeTimes)505 void SequenceSoundPlayer::SetTrackSilence( unsigned long trackBitFlag, bool silenceFlag, int fadeTimes )
506 {
507 SetTrackParam( trackBitFlag, &SequenceTrack::SetSilence, silenceFlag, fadeTimes );
508 }
509
SetTrackVolume(u32 trackBitFlag,float volume)510 void SequenceSoundPlayer::SetTrackVolume( u32 trackBitFlag, float volume )
511 {
512 NW_ASSERT( volume >= 0.0f );
513 SetTrackParam( trackBitFlag, &SequenceTrack::SetVolume, volume );
514 }
515
SetTrackPitch(u32 trackBitFlag,float pitch)516 void SequenceSoundPlayer::SetTrackPitch( u32 trackBitFlag, float pitch )
517 {
518 NW_ASSERT( pitch >= 0.0f );
519 SetTrackParam( trackBitFlag, &SequenceTrack::SetPitch, pitch );
520 }
521
SetTrackPan(u32 trackBitFlag,float pan)522 void SequenceSoundPlayer::SetTrackPan( u32 trackBitFlag, float pan )
523 {
524 SetTrackParam( trackBitFlag, &SequenceTrack::SetPan, pan );
525 }
526
SetTrackSurroundPan(u32 trackBitFlag,float surroundPan)527 void SequenceSoundPlayer::SetTrackSurroundPan( u32 trackBitFlag, float surroundPan )
528 {
529 SetTrackParam( trackBitFlag, &SequenceTrack::SetSurroundPan, surroundPan );
530 }
531
SetTrackLpfFreq(u32 trackBitFlag,float lpfFreq)532 void SequenceSoundPlayer::SetTrackLpfFreq( u32 trackBitFlag, float lpfFreq )
533 {
534 SetTrackParam( trackBitFlag, &SequenceTrack::SetLpfFreq, lpfFreq );
535 }
536
SetTrackBiquadFilter(u32 trackBitFlag,int type,float value)537 void SequenceSoundPlayer::SetTrackBiquadFilter( u32 trackBitFlag, int type, float value )
538 {
539 SetTrackParam( trackBitFlag, &SequenceTrack::SetBiquadFilter, type, value );
540 }
541
SetTrackPanRange(u32 trackBitFlag,float panRange)542 void SequenceSoundPlayer::SetTrackPanRange( u32 trackBitFlag, float panRange )
543 {
544 SetTrackParam( trackBitFlag, &SequenceTrack::SetPanRange, panRange );
545 }
546
SetTrackModDepth(u32 trackBitFlag,float depth)547 void SequenceSoundPlayer::SetTrackModDepth( u32 trackBitFlag, float depth )
548 {
549 SetTrackParam( trackBitFlag, &SequenceTrack::SetModDepth, depth );
550 }
551
SetTrackModSpeed(u32 trackBitFlag,float speed)552 void SequenceSoundPlayer::SetTrackModSpeed( u32 trackBitFlag, float speed )
553 {
554 SetTrackParam( trackBitFlag, &SequenceTrack::SetModSpeed, speed );
555 }
556
SetTrackBankIndex(u32 trackBitFlag,int bankIndex)557 bool SequenceSoundPlayer::SetTrackBankIndex( u32 trackBitFlag, int bankIndex )
558 {
559 // SequenceSoundHandle::SetTrackBankIndex でも範囲チェックしているが、念のため。
560 NW_MINMAXLT_ASSERT( bankIndex, 0, SoundArchive::SEQ_BANK_MAX );
561 if ( m_pBankFiles[ bankIndex ] == NULL )
562 {
563 return false;
564 }
565
566 SetTrackParam( trackBitFlag, &SequenceTrack::SetBankIndex, bankIndex );
567 return true;
568 }
569
570 /*---------------------------------------------------------------------------*
571 Name: InvalidateData
572
573 Description: 指定シーケンスデータを使用しているシーケンスを無効化します
574
575 Arguments: start - シーケンスデータ開始アドレス
576 end - シーケンスデータ終了アドレス
577
578 Returns: None.
579 *---------------------------------------------------------------------------*/
InvalidateData(const void * start,const void * end)580 void SequenceSoundPlayer::InvalidateData( const void* start, const void* end )
581 {
582 if ( m_ActiveFlag )
583 {
584 for( int trackNo = 0; trackNo < TRACK_NUM_PER_PLAYER ; trackNo++ )
585 {
586 SequenceTrack* track = GetPlayerTrack( trackNo );
587 if ( track == NULL ) continue;
588
589 const u8* cur = track->GetParserTrackParam().baseAddr;
590 if ( start <= cur && cur <= end )
591 {
592 Finalize();
593 break;
594 }
595 }
596 for ( int i = 0; i < SoundArchive::SEQ_BANK_MAX; i++ )
597 {
598 const void* cur = m_pBankFiles[ i ];
599 if ( start <= cur && cur <= end )
600 {
601 m_pBankFiles[ i ] = NULL;
602 }
603 }
604 }
605 }
606
607 /*---------------------------------------------------------------------------*
608 Name: GetPlayerTrack
609
610 Description: プレイヤーが保持しているトラックを取得します
611
612 Arguments: trackNo - トラック番号
613
614 Returns: トラックポインタ
615 *---------------------------------------------------------------------------*/
GetPlayerTrack(int trackNo)616 SequenceTrack* SequenceSoundPlayer::GetPlayerTrack( int trackNo )
617 {
618 if ( trackNo > TRACK_NUM_PER_PLAYER - 1 )
619 {
620 return NULL;
621 }
622
623 return m_pTracks[ trackNo ];
624 }
625
626 /*---------------------------------------------------------------------------*
627 Name: GetPlayerTrack
628
629 Description: プレイヤーが保持しているトラックを取得します
630
631 Arguments: trackNo - トラック番号
632
633 Returns: トラックポインタ
634 *---------------------------------------------------------------------------*/
GetPlayerTrack(int trackNo) const635 const SequenceTrack* SequenceSoundPlayer::GetPlayerTrack( int trackNo ) const
636 {
637 if ( trackNo > TRACK_NUM_PER_PLAYER - 1 )
638 {
639 return NULL;
640 }
641
642 return m_pTracks[ trackNo ];
643 }
644
645 /*---------------------------------------------------------------------------*
646 Name: CloseTrack
647
648 Description: プレイヤーのトラックを閉じます。
649 トラックシーケンス完了時、シーケンス2重オープン時、
650 プレイヤーの完了時に呼びだされます。
651
652 Arguments: player : プレイヤー
653
654 Returns: None
655 *---------------------------------------------------------------------------*/
CloseTrack(int trackNo)656 void SequenceSoundPlayer::CloseTrack( int trackNo )
657 {
658 NW_MINMAXLT_ASSERT( trackNo, 0, TRACK_NUM_PER_PLAYER );
659
660 SequenceTrack* track = GetPlayerTrack( trackNo );
661 if ( track == NULL )
662 {
663 return;
664 }
665
666 track->Close();
667
668 m_pSequenceTrackAllocator->FreeTrack( m_pTracks[ trackNo ] );
669 // NN_LOG("FreeTrack %08x\n",m_pTracks[trackNo]);
670
671 m_pTracks[ trackNo ] = NULL;
672 }
673
674 /*---------------------------------------------------------------------------*
675 Name: SetPlayerTrack
676
677 Description: プレイヤーが管理するトラックを追加します
678
679 Arguments: trackNo - トラック番号
680 trackID - トラックID
681
682 Returns: なし
683 *---------------------------------------------------------------------------*/
SetPlayerTrack(int trackNo,SequenceTrack * track)684 void SequenceSoundPlayer::SetPlayerTrack( int trackNo, SequenceTrack* track )
685 {
686 if ( trackNo > TRACK_NUM_PER_PLAYER - 1 )
687 {
688 return;
689 }
690 m_pTracks[ trackNo ] = track;
691 track->SetPlayerTrackNo( trackNo );
692
693 // トラックパラメータのフロントバイパスフラグに「サウンド」のフロントバイパスフラグを反映
694 // (その後、frontbypass_on/_off コマンドで上書きされ得ます)
695 track->GetParserTrackParam().frontBypassFlag = IsFrontBypass();
696 }
697
698
699 /*---------------------------------------------------------------------------*
700 Name: FinishPlayer
701
702 Description: プレイヤーの完了処理を行います。
703
704 Arguments: player : プレイヤーポインタ
705
706 Returns: None
707 *---------------------------------------------------------------------------*/
FinishPlayer()708 void SequenceSoundPlayer::FinishPlayer()
709 {
710 // プレイヤーリストから削除
711 if ( m_StartedFlag )
712 {
713 SoundThread::GetInstance().UnregisterPlayerCallback( this );
714 m_StartedFlag = false;
715 }
716
717 // 全トラック解放
718 for( int trackNo = 0; trackNo < TRACK_NUM_PER_PLAYER ; trackNo++ )
719 {
720 CloseTrack( trackNo );
721 }
722 }
723
724 /*---------------------------------------------------------------------------*
725 Name: UpdateChannelParam
726
727 Description: プレイヤーの全トラックのチャンネルパラメータを更新します
728
729 Arguments: player - プレイヤーポインタ
730
731 Returns: None.
732 *---------------------------------------------------------------------------*/
UpdateChannelParam()733 void SequenceSoundPlayer::UpdateChannelParam()
734 {
735 SequenceTrack* track;
736 for( int trackNo = 0; trackNo < TRACK_NUM_PER_PLAYER ; trackNo++ )
737 {
738 track = GetPlayerTrack( trackNo );
739 if ( track == NULL ) continue;
740 track->UpdateChannelParam();
741 }
742 }
743
744 /*---------------------------------------------------------------------------*
745 Name: ParseNextTick
746
747 Description: プレイヤーのシーケンス処理を行います
748
749 Arguments: player - プレイヤーポインタ
750 doNoteOn - ノートオンするかどうか
751
752 Returns: 継続時には0を、完了時には1を返します
753 *---------------------------------------------------------------------------*/
ParseNextTick(bool doNoteOn)754 int SequenceSoundPlayer::ParseNextTick( bool doNoteOn )
755 {
756 bool activeFlag = false;
757
758 for( int trackNo = 0; trackNo < TRACK_NUM_PER_PLAYER ; trackNo++ )
759 {
760 SequenceTrack* track = GetPlayerTrack( trackNo );
761 if ( track == NULL )
762 {
763 continue;
764 }
765
766 track->UpdateChannelLength();
767
768 if ( track->ParseNextTick( doNoteOn ) < 0 )
769 {
770 // トラックのシーケンス終了
771 CloseTrack( trackNo );
772 }
773
774 if ( track->IsOpened() )
775 {
776 activeFlag = true;
777 }
778 }
779
780 if ( ! activeFlag )
781 {
782 return 1;
783 }
784
785 return 0;
786 }
787
788 /*---------------------------------------------------------------------------*
789 Name: GetVariablePtr
790
791 Description: 変数のポインタを取得します
792
793 Arguments: player - プレイヤーポインタ
794 varNo - 変数番号
795
796 Returns: 変数のポインタ
797 *---------------------------------------------------------------------------*/
GetVariablePtr(int varNo)798 vs16* SequenceSoundPlayer::GetVariablePtr( int varNo )
799 {
800 NW_MINMAX_ASSERT( varNo, 0, PLAYER_VARIABLE_NUM + GLOBAL_VARIABLE_NUM );
801
802 if ( varNo < PLAYER_VARIABLE_NUM )
803 {
804 return & m_LocalVariable[ varNo ] ;
805 }
806 else if ( varNo < PLAYER_VARIABLE_NUM + GLOBAL_VARIABLE_NUM )
807 {
808 return & m_GlobalVariable[ varNo - PLAYER_VARIABLE_NUM ];
809 }
810 else
811 {
812 return NULL;
813 }
814 }
815
816 /*---------------------------------------------------------------------------*
817 Name: Update
818
819 Description: プレイヤーのフレーム処理を行います
820
821 Arguments: None.
822
823 Returns: None.
824 *---------------------------------------------------------------------------*/
Update()825 void SequenceSoundPlayer::Update()
826 {
827 if ( ! m_ActiveFlag )
828 {
829 return;
830 }
831 if ( ! m_StartedFlag )
832 {
833 return;
834 }
835
836 if ( ( m_SkipTickCounter > 0 ) || ( m_SkipTimeCounter > 0.0f ) )
837 {
838 SkipTick();
839 }
840 else if ( ! m_PauseFlag )
841 {
842 UpdateTick();
843 }
844
845 UpdateChannelParam();
846 }
847
848 /*---------------------------------------------------------------------------*
849 Name: UpdateTick
850
851 Description: プレイヤーのティック処理を行います
852
853 Returns: None.
854 *---------------------------------------------------------------------------*/
UpdateTick()855 void SequenceSoundPlayer::UpdateTick()
856 {
857 f32 tickPerMsec = CalcTickPerMsec();
858 if ( tickPerMsec == 0.0f )
859 {
860 return;
861 }
862
863 u64 restMsec = INTERVAL_MSEC_NUMERATOR;
864 u64 nextMsec = static_cast<u64>(INTERVAL_MSEC_DENOMINATOR * m_TickFraction / tickPerMsec);
865
866 while ( nextMsec < restMsec )
867 {
868 restMsec -= nextMsec;
869
870 bool result = ( ParseNextTick( true ) != 0 );
871
872 if ( result )
873 {
874 FinishPlayer();
875 m_FinishFlag = true;
876 return;
877 }
878 ++m_TickCounter;
879
880 tickPerMsec = CalcTickPerMsec();
881 if ( tickPerMsec == 0.0f )
882 {
883 return;
884 }
885 nextMsec = static_cast<u64>(INTERVAL_MSEC_DENOMINATOR / tickPerMsec);
886 }
887 nextMsec -= restMsec;
888 m_TickFraction = nextMsec * tickPerMsec / INTERVAL_MSEC_DENOMINATOR;
889 }
890
891 /*---------------------------------------------------------------------------*
892 Name: SkipTick
893
894 Description: ティックのスキップ処理を行います
895
896 Arguments: None.
897
898 Returns: None.
899 *---------------------------------------------------------------------------*/
SkipTick()900 void SequenceSoundPlayer::SkipTick()
901 {
902 // 全トラックの全チャンネルをリリース
903 for( int trackNo = 0; trackNo < TRACK_NUM_PER_PLAYER ; trackNo++ )
904 {
905 SequenceTrack* track = GetPlayerTrack( trackNo );
906 if ( track == NULL ) continue;
907
908 track->ReleaseAllChannel( SequenceTrack::PAUSE_RELEASE_VALUE );
909 track->FreeAllChannel();
910 }
911
912 // スキップ処理
913 int skipCount = 0;
914 while ( m_SkipTickCounter > 0 || m_SkipTimeCounter * CalcTickPerMsec() >= 1.0f )
915 {
916 if ( skipCount >= MAX_SKIP_TICK_PER_FRAME )
917 {
918 return;
919 }
920
921 if ( m_SkipTickCounter > 0 )
922 {
923 --m_SkipTickCounter;
924 }
925 else
926 {
927 f32 tickPerMsec = CalcTickPerMsec();
928 NW_ASSERT( tickPerMsec > 0.0f ); // 0.0fの時、スキップは行われない
929 f32 msecPerTick = 1.0f / tickPerMsec;
930 m_SkipTimeCounter -= msecPerTick;
931 }
932
933 if ( ParseNextTick( false ) != 0 )
934 {
935 FinishPlayer();
936 m_FinishFlag = true;
937 return;
938 }
939 ++skipCount;
940 ++m_TickCounter;
941 }
942
943 m_SkipTimeCounter = 0.0f;
944 }
945
NoteOn(u8 bankIndex,const NoteOnInfo & noteOnInfo)946 Channel* SequenceSoundPlayer::NoteOn(
947 u8 bankIndex,
948 const NoteOnInfo& noteOnInfo
949 )
950 {
951 Channel* channel = m_ParserParam.callback->NoteOn(
952 this,
953 bankIndex,
954 noteOnInfo
955 );
956
957 return channel;
958 }
959
960 } // namespace nw::snd::internal::driver
961 } // namespace nw::snd::internal
962 } // namespace nw::snd
963 } // namespace nw
964
965