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