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