1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: snd_SequenceTrack.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: 23660 $
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17
18 #include <nw/snd/snd_SequenceTrack.h>
19
20 #include <nw/snd/snd_SequenceSoundPlayer.h>
21 #include <nw/snd/snd_HardwareManager.h>
22
23 namespace nw {
24 namespace snd {
25 namespace internal {
26 namespace driver {
27
28 /* ========================================================================
29 memnber function
30 ======================================================================== */
31
SetPlayerTrackNo(int playerTrackNo)32 void SequenceTrack::SetPlayerTrackNo( int playerTrackNo )
33 {
34 NW_MINMAX_ASSERT( playerTrackNo, 0, SequenceSoundPlayer::TRACK_NUM_PER_PLAYER );
35 m_PlayerTrackNo = static_cast<u8>( playerTrackNo );
36 }
37
SequenceTrack()38 SequenceTrack::SequenceTrack()
39 : m_OpenFlag( false ),
40 m_pSequenceSoundPlayer( NULL ),
41 m_pChannelList( NULL )
42
43 {
44 InitParam();
45 }
46
~SequenceTrack()47 SequenceTrack::~SequenceTrack()
48 {
49 Close();
50 }
51
52 /*---------------------------------------------------------------------------*
53 Name: InitParam
54
55 Description: トラック構造体を初期化します
56
57 Arguments: track - トラックポインタ
58
59 Returns: None.
60 *---------------------------------------------------------------------------*/
InitParam()61 void SequenceTrack::InitParam()
62 {
63 m_ExtVolume = 1.0f;
64 m_ExtPitch = 1.0f;
65 m_ExtPan = 0.0f;
66 m_ExtSurroundPan = 0.0f;
67 m_PanRange = 1.0f;
68
69 // Parser Param
70 m_ParserTrackParam.baseAddr = NULL;
71 m_ParserTrackParam.currentAddr = NULL;
72
73 m_ParserTrackParam.cmpFlag = true;
74 m_ParserTrackParam.noteWaitFlag = true;
75 m_ParserTrackParam.tieFlag = false;
76 m_ParserTrackParam.monophonicFlag = false;
77
78 m_ParserTrackParam.callStackDepth = 0;
79
80 m_ParserTrackParam.wait = 0;
81
82 m_ParserTrackParam.muteFlag = false;
83 m_ParserTrackParam.silenceFlag = false;
84 m_ParserTrackParam.noteFinishWait = false;
85 m_ParserTrackParam.portaFlag = false;
86 m_ParserTrackParam.damperFlag = false;
87
88 m_ParserTrackParam.bankIndex = 0;
89 m_ParserTrackParam.prgNo = 0;
90
91 m_ParserTrackParam.lfoParam.Initialize();
92 m_ParserTrackParam.lfoTarget = Channel::LFO_TARGET_PITCH;
93 m_ParserTrackParam.sweepPitch = 0.0f;
94
95 m_ParserTrackParam.volume.InitValue( 127 );
96 m_ParserTrackParam.pan.InitValue( 0 );
97 m_ParserTrackParam.surroundPan.InitValue( 0 );
98 m_ParserTrackParam.volume2 = 127;
99 m_ParserTrackParam.velocityRange = 127;
100 m_ParserTrackParam.pitchBend.InitValue( 0 );
101 m_ParserTrackParam.bendRange = DEFAULT_BENDRANGE;
102 m_ParserTrackParam.initPan = 0;
103 m_ParserTrackParam.transpose = 0;
104 m_ParserTrackParam.priority = DEFAULT_PRIORITY;
105 m_ParserTrackParam.portaKey = DEFAULT_PORTA_KEY;
106 m_ParserTrackParam.portaTime = 0;
107
108 m_ParserTrackParam.attack = INVALID_ENVELOPE;
109 m_ParserTrackParam.decay = INVALID_ENVELOPE;
110 m_ParserTrackParam.sustain = INVALID_ENVELOPE;
111 m_ParserTrackParam.release = INVALID_ENVELOPE;
112 m_ParserTrackParam.envHold = INVALID_ENVELOPE;
113
114 m_ParserTrackParam.mainSend = 127;
115 for ( int i=0; i<AUX_BUS_NUM; i++ )
116 {
117 m_ParserTrackParam.fxSend[i] = 0;
118 }
119
120 m_ParserTrackParam.lpfFreq = 0.0f;
121 m_ParserTrackParam.biquadType = 0;
122 m_ParserTrackParam.biquadValue = 0;
123
124 for( int varNo = 0; varNo < TRACK_VARIABLE_NUM ; varNo++ )
125 {
126 m_TrackVariable[ varNo ] = SequenceSoundPlayer::VARIABLE_DEFAULT_VALUE;
127 }
128 }
129
130 /*---------------------------------------------------------------------------*
131 Name: SetSeqData
132
133 Description: シーケンスデータをセットします
134
135 Arguments: seqBase - シーケンスデータベースアドレス
136 seqOffset - シーケンスデータオフセット
137
138 Returns: None.
139 *---------------------------------------------------------------------------*/
SetSeqData(const void * seqBase,s32 seqOffset)140 void SequenceTrack::SetSeqData( const void* seqBase, s32 seqOffset )
141 {
142 m_ParserTrackParam.baseAddr = static_cast<const u8*>( seqBase );
143 m_ParserTrackParam.currentAddr = m_ParserTrackParam.baseAddr + seqOffset;
144 }
145
Open()146 void SequenceTrack::Open()
147 {
148 m_ParserTrackParam.noteFinishWait = false;
149 m_ParserTrackParam.callStackDepth = 0;
150 m_ParserTrackParam.wait = 0;
151
152 m_OpenFlag = true;
153 }
154
155 /*---------------------------------------------------------------------------*
156 Name: Close
157
158 Description: トラックを閉じます
159
160 Arguments: player - プレイヤーポインタ
161
162 Returns: None.
163 *---------------------------------------------------------------------------*/
Close()164 void SequenceTrack::Close()
165 {
166 ReleaseAllChannel( -1 );
167 FreeAllChannel();
168
169 m_OpenFlag = false;
170 }
171
172 /*---------------------------------------------------------------------------*
173 Name: UpdateChannelLength
174
175 Description: チャンネル長を更新します
176
177 Arguments: None.
178
179 Returns: None.
180 *---------------------------------------------------------------------------*/
UpdateChannelLength()181 void SequenceTrack::UpdateChannelLength()
182 {
183 if ( ! m_OpenFlag ) return;
184
185 Channel* channel = m_pChannelList;
186 while( channel != NULL )
187 {
188 if ( channel->GetLength() > 0 )
189 {
190 channel->SetLength( channel->GetLength() - 1 );
191 }
192
193 UpdateChannelRelease( channel );
194
195 if ( ! channel->IsAutoUpdateSweep() )
196 {
197 channel->UpdateSweep( 1 );
198 }
199
200 channel = channel->GetNextTrackChannel();
201 }
202 }
203
204 /*---------------------------------------------------------------------------*
205 Name: UpdateChannelRelease
206
207 Description: チャンネルをリリース状態を更新する
208
209 Arguments: channel - チャンネル
210
211 Returns: なし
212 *---------------------------------------------------------------------------*/
UpdateChannelRelease(Channel * channel)213 void SequenceTrack::UpdateChannelRelease( Channel* channel )
214 {
215 if ( ( channel->GetLength() == 0 ) && ( ! channel->IsRelease() ) )
216 {
217 if ( ! m_ParserTrackParam.damperFlag )
218 {
219 channel->NoteOff();
220 }
221 }
222 }
223
224 /*---------------------------------------------------------------------------*
225 Name: ParseNextTick
226
227 Description: トラックのシーケンス処理を進めます
228
229 Arguments: doNoteOn - ノートオンするかどうか
230
231 Returns: シーケンス継続時には正を、終了時には負を、未Open時には0を返します
232 *---------------------------------------------------------------------------*/
ParseNextTick(bool doNoteOn)233 int SequenceTrack::ParseNextTick( bool doNoteOn )
234 {
235 if ( ! m_OpenFlag ) {
236 return 0;
237 }
238
239 // MoveValueの更新
240 m_ParserTrackParam.volume.Update();
241 m_ParserTrackParam.pan.Update();
242 m_ParserTrackParam.surroundPan.Update();
243 m_ParserTrackParam.pitchBend.Update();
244
245 // ウェイトチェック
246 if ( m_ParserTrackParam.noteFinishWait ) {
247 if ( m_pChannelList != NULL ) {
248 return 1;
249 }
250 m_ParserTrackParam.noteFinishWait = false;
251 }
252 if ( m_ParserTrackParam.wait > 0 ) {
253 m_ParserTrackParam.wait--;
254 if ( m_ParserTrackParam.wait > 0 ) {
255 return 1;
256 }
257 }
258
259 // シーケンス処理
260 if ( m_ParserTrackParam.currentAddr != NULL )
261 {
262 while( m_ParserTrackParam.wait == 0 && ! m_ParserTrackParam.noteFinishWait )
263 {
264 ParseResult result = Parse( doNoteOn );
265 if ( result == PARSE_RESULT_FINISH ) {
266 return -1;
267 }
268 }
269 }
270
271 return 1;
272 }
273
274 /*---------------------------------------------------------------------------*
275 Name: StopAllChannel
276
277 Description: トラックのチャンネルを全て停止します
278
279 Arguments: None.
280
281 Returns: None.
282 *---------------------------------------------------------------------------*/
StopAllChannel()283 void SequenceTrack::StopAllChannel()
284 {
285 Channel* channel = m_pChannelList;
286
287 while( channel != NULL )
288 {
289 Channel::FreeChannel( channel );
290 channel->Stop();
291 channel = channel->GetNextTrackChannel();
292 }
293
294 m_pChannelList = NULL;
295 }
296
297 /*---------------------------------------------------------------------------*
298 Name: ReleaseAllChannel
299
300 Description: トラックのチャンネルを全てリリースします
301
302 Arguments: release - リリース値(負値の場合は、既に設定されているリリース値を使用する)
303
304 Returns: None.
305 *---------------------------------------------------------------------------*/
ReleaseAllChannel(int release)306 void SequenceTrack::ReleaseAllChannel( int release )
307 {
308 UpdateChannelParam();
309
310 Channel* channel = m_pChannelList;
311 while( channel != NULL )
312 {
313 if ( channel->IsActive() )
314 {
315 if ( release >= 0 )
316 {
317 NW_MINMAX_ASSERT( release, 0, 127 );
318 channel->SetRelease( static_cast<u8>( release ) );
319 }
320 channel->Release();
321 }
322 channel = channel->GetNextTrackChannel();
323 }
324 }
325
326 /*---------------------------------------------------------------------------*
327 Name: PauseAllChannel
328
329 Description: トラックのチャンネルを全てポーズします
330
331 Arguments: track - トラックポインタ
332 player - プレイヤーポインタ
333 release - リリース値(負値の場合は、既に設定されているリリース値を使用する)
334
335 Returns: None.
336 *---------------------------------------------------------------------------*/
PauseAllChannel(bool flag)337 void SequenceTrack::PauseAllChannel( bool flag )
338 {
339 Channel* channel = m_pChannelList;
340
341 while( channel != NULL )
342 {
343 if ( channel->IsActive() && ( channel->IsPause() != flag ) )
344 {
345 channel->Pause( flag );
346 }
347 channel = channel->GetNextTrackChannel();
348 }
349 }
350
351 /*---------------------------------------------------------------------------*
352 Name: AddChannel
353
354 Description: トラックへチャンネルを追加します
355
356 Arguments: channel - チャンネルポインタ
357
358 Returns: None.
359 *---------------------------------------------------------------------------*/
AddChannel(Channel * channel)360 void SequenceTrack::AddChannel( Channel* channel )
361 {
362 channel->SetNextTrackChannel( m_pChannelList );
363 m_pChannelList = channel;
364 }
365
366 /*---------------------------------------------------------------------------*
367 Name: UpdateChannelParam
368
369 Description: トラックが保持しているチャンネルのパラメータを更新します
370
371 Arguments: None.
372
373 Returns: None.
374 *---------------------------------------------------------------------------*/
UpdateChannelParam()375 void SequenceTrack::UpdateChannelParam()
376 {
377 if ( ! m_OpenFlag ) return;
378
379 if ( m_pChannelList == NULL ) {
380 // 更新不要
381 return;
382 }
383
384 // volume
385 register float volume
386 = m_ParserTrackParam.volume.GetValue()
387 * m_ParserTrackParam.volume2
388 * m_pSequenceSoundPlayer->GetParserPlayerParam().volume
389 / (127.0f * 127.0f * 127.0f);
390 volume = volume * volume * m_ExtVolume * m_pSequenceSoundPlayer->GetVolume();
391
392 f32 pitch = ( m_ParserTrackParam.pitchBend.GetValue() / 128.0f ) * m_ParserTrackParam.bendRange;
393
394 float pitchRatio = m_pSequenceSoundPlayer->GetPitch() * m_ExtPitch;
395
396 // pan
397 register float pan
398 = ut::Clamp( static_cast<float>( m_ParserTrackParam.pan.GetValue() ) / 63.0f, -1.0f, 1.0f )
399 * m_PanRange
400 * m_pSequenceSoundPlayer->GetPanRange()
401 + m_ExtPan
402 + m_pSequenceSoundPlayer->GetPan();
403
404 // surround pan
405 float surroundPan
406 = ut::Clamp( static_cast<float>( m_ParserTrackParam.surroundPan.GetValue() ) / 63.0f, 0.0f, 2.0f )
407 + m_ExtSurroundPan
408 + m_pSequenceSoundPlayer->GetSurroundPan();
409
410 // lpf freq
411 float lpfFreq
412 = m_ParserTrackParam.lpfFreq
413 + m_pSequenceSoundPlayer->GetLpfFreq();
414
415 // biquad filter
416 int biquadType = m_ParserTrackParam.biquadType;
417 float biquadValue = m_ParserTrackParam.biquadValue;
418 if ( m_pSequenceSoundPlayer->GetBiquadFilterType() != BIQUAD_FILTER_TYPE_NONE )
419 {
420 biquadType = m_pSequenceSoundPlayer->GetBiquadFilterType();
421 biquadValue = m_pSequenceSoundPlayer->GetBiquadFilterValue();
422 }
423
424 // main send
425 float mainSend
426 = static_cast<float>( m_ParserTrackParam.mainSend ) / 127.0f - 1.0f // -1.0 ~ 0.0 に
427 + m_pSequenceSoundPlayer->GetMainSend();
428
429 float fxSend[ AUX_BUS_NUM ];
430 for ( int i=0; i<AUX_BUS_NUM; i++ )
431 {
432 AuxBus bus = static_cast<AuxBus>( i );
433 fxSend[ i ] = static_cast<float>( m_ParserTrackParam.fxSend[i] ) / 127.0f
434 + m_pSequenceSoundPlayer->GetFxSend( bus );
435 }
436
437 // set channel params of track
438 register Channel* channel = m_pChannelList;
439 while( channel != NULL )
440 {
441 channel->SetUserVolume( volume );
442 channel->SetUserPitch( pitch );
443 channel->SetUserPitchRatio( pitchRatio );
444 channel->SetUserPan( pan );
445 channel->SetUserSurroundPan( surroundPan );
446 channel->SetUserLpfFreq( lpfFreq );
447 channel->SetBiquadFilter( biquadType, biquadValue );
448 channel->SetMainSend( mainSend );
449 for ( int i=0; i<AUX_BUS_NUM; i++ )
450 {
451 AuxBus bus = static_cast<AuxBus>( i );
452 channel->SetFxSend( bus, fxSend[ i ] );
453 }
454
455 channel->SetLfoParam( m_ParserTrackParam.lfoParam );
456 channel->SetLfoTarget( static_cast<Channel::LfoTarget>( m_ParserTrackParam.lfoTarget ) );
457
458 channel = channel->GetNextTrackChannel();
459 }
460 }
461
462 /*---------------------------------------------------------------------------*
463 Name: FreeAllChannel
464
465 Description: トラックのチャンネルを全て解放します
466
467 Arguments: track - トラックポインタ
468
469 Returns: None.
470 *---------------------------------------------------------------------------*/
FreeAllChannel(void)471 void SequenceTrack::FreeAllChannel( void )
472 {
473 Channel* channel = m_pChannelList;
474
475 while( channel != NULL ) {
476 Channel::FreeChannel( channel );
477 channel = channel->GetNextTrackChannel();
478 }
479 m_pChannelList = NULL;
480 }
481
482
483 /*---------------------------------------------------------------------------*
484 Name: GetChannelCount
485
486 Description: トラックが保持しているチャンネル数を取得する
487
488 Arguments: なし
489
490 Returns: チャンネル数
491 *---------------------------------------------------------------------------*/
GetChannelCount() const492 int SequenceTrack::GetChannelCount() const
493 {
494 Channel* channel = m_pChannelList;
495 int count = 0;
496 while( channel != NULL ) {
497 ++count;
498 channel = channel->GetNextTrackChannel();
499 }
500
501 return count;
502 }
503
504 /*---------------------------------------------------------------------------*
505 Name: ChannelCallbackFunc
506
507 Description: チャンネルから呼びだされるコールバック関数
508
509 Arguments: dropChannel - チャンネルポインタ
510 status - チャンネルコールバックステータス
511 userData - トラックポインタを格納したコールバックユーザーデータ
512
513 Returns: None.
514 *---------------------------------------------------------------------------*/
ChannelCallbackFunc(Channel * dropChannel,Channel::ChannelCallbackStatus status,u32 userData)515 void SequenceTrack::ChannelCallbackFunc(
516 Channel* dropChannel,
517 Channel::ChannelCallbackStatus status,
518 u32 userData
519 )
520 {
521 SequenceTrack* track = reinterpret_cast<SequenceTrack*>( userData );
522
523 NW_NULL_ASSERT( dropChannel );
524 NW_NULL_ASSERT( track );
525
526 switch ( status )
527 {
528 case Channel::CALLBACK_STATUS_STOPPED:
529 case Channel::CALLBACK_STATUS_FINISH:
530 Channel::FreeChannel( dropChannel );
531 break;
532 }
533
534 if ( track->m_pSequenceSoundPlayer != NULL ) {
535 track->m_pSequenceSoundPlayer->ChannelCallback( dropChannel );
536 }
537
538 // チャンネル参照の切断
539 if ( track->m_pChannelList == dropChannel ) {
540 track->m_pChannelList = dropChannel->GetNextTrackChannel();
541 return;
542 }
543
544 Channel* channel = track->m_pChannelList;
545 NW_NULL_ASSERT( channel );
546 while( channel->GetNextTrackChannel() != NULL ) {
547 if ( channel->GetNextTrackChannel() == dropChannel ) {
548 channel->SetNextTrackChannel( dropChannel->GetNextTrackChannel() );
549 return;
550 }
551 channel = channel->GetNextTrackChannel();
552 }
553
554 NW_ASSERT( false );
555 }
556
SetMute(SeqMute mute)557 void SequenceTrack::SetMute( SeqMute mute )
558 {
559 switch ( mute )
560 {
561 case SEQ_MUTE_OFF:
562 m_ParserTrackParam.muteFlag = false;
563 break;
564 case SEQ_MUTE_STOP:
565 StopAllChannel();
566 m_ParserTrackParam.muteFlag = true;
567 break;
568 case SEQ_MUTE_RELEASE:
569 ReleaseAllChannel( -1 );
570 FreeAllChannel();
571 m_ParserTrackParam.muteFlag = true;
572 break;
573 case SEQ_MUTE_NO_STOP:
574 m_ParserTrackParam.muteFlag = true;
575 break;
576 }
577 }
578
SetSilence(bool silenceFlag,int fadeTimes)579 void SequenceTrack::SetSilence( bool silenceFlag, int fadeTimes )
580 {
581 m_ParserTrackParam.silenceFlag = silenceFlag;
582
583 Channel* channel = m_pChannelList;
584 while( channel != NULL )
585 {
586 channel->SetSilence(
587 silenceFlag,
588 ( fadeTimes + HardwareManager::SOUND_FRAME_INTERVAL_MSEC - 1 ) /
589 HardwareManager::SOUND_FRAME_INTERVAL_MSEC );
590 channel = channel->GetNextTrackChannel();
591 }
592 }
593
SetBiquadFilter(int type,float value)594 void SequenceTrack::SetBiquadFilter( int type, float value )
595 {
596 m_ParserTrackParam.biquadType = static_cast<u8>( type );
597 m_ParserTrackParam.biquadValue = value;
598 }
599
SetBankIndex(int bankIndex)600 void SequenceTrack::SetBankIndex( int bankIndex )
601 {
602 // SequenceSoundHandle::SetTrackBankIndex でも範囲チェックしているが、念のため。
603 NW_MINMAXLT_ASSERT( bankIndex, 0, SoundArchive::SEQ_BANK_MAX );
604 m_ParserTrackParam.bankIndex = static_cast<u8>( bankIndex );
605 }
606
607 /*---------------------------------------------------------------------------*
608 Name: GetTrackVariable
609
610 Description: シーケンストラック変数を取得します。
611
612 Arguments: varNo - 変数番号
613
614 Returns: 変数の値
615 *---------------------------------------------------------------------------*/
GetTrackVariable(int varNo) const616 s16 SequenceTrack::GetTrackVariable( int varNo ) const
617 {
618 NW_MINMAXLT_ASSERT( varNo, 0, TRACK_VARIABLE_NUM );
619
620 return m_TrackVariable[ varNo ];
621 }
622
623 /*---------------------------------------------------------------------------*
624 Name: SetTrackVariable
625
626 Description: シーケンスローカル変数を設定します。
627
628 Arguments: player - プレイヤー
629 varNo - 変数番号
630 var - 変数値
631
632 Returns: 変数の値
633 *---------------------------------------------------------------------------*/
SetTrackVariable(int varNo,s16 var)634 void SequenceTrack::SetTrackVariable( int varNo, s16 var )
635 {
636 NW_MINMAXLT_ASSERT( varNo, 0, TRACK_VARIABLE_NUM );
637
638 m_TrackVariable[ varNo ] = var;
639 }
640
641 /*---------------------------------------------------------------------------*
642 Name: GetVariablePtr
643
644 Description: 変数のポインタを取得します
645
646 Arguments: player - プレイヤーポインタ
647 varNo - 変数番号
648
649 Returns: 変数のポインタ
650 *---------------------------------------------------------------------------*/
GetVariablePtr(int varNo)651 vs16* SequenceTrack::GetVariablePtr( int varNo )
652 {
653 NW_MINMAX_ASSERT( varNo, 0, TRACK_VARIABLE_NUM );
654
655 if ( varNo < TRACK_VARIABLE_NUM )
656 {
657 return & m_TrackVariable[ varNo ];
658 }
659 else
660 {
661 return NULL;
662 }
663 }
664
665 /*---------------------------------------------------------------------------*
666 Name: NoteOn
667
668 Description: ノートオン
669
670 Arguments: key - キー番号
671 velocity - ベロシティ
672 length - ノート長 ( -1 なら無限長 )
673 tieFlag - タイフラグ
674
675 Returns: 発音したチャンネルのポインタ
676 *---------------------------------------------------------------------------*/
NoteOn(int key,int velocity,s32 length,bool tieFlag)677 Channel* SequenceTrack::NoteOn(
678 int key,
679 int velocity,
680 s32 length,
681 bool tieFlag
682 )
683 {
684 NW_MINMAX_ASSERT( key, 0, 127 );
685 NW_MINMAX_ASSERT( velocity, 0, 127 );
686
687 const SequenceSoundPlayer::ParserPlayerParam& playerParam = m_pSequenceSoundPlayer->GetParserPlayerParam();
688
689 Channel* channel = NULL;
690
691 // ベロシティレンジ適用
692 velocity = velocity * m_ParserTrackParam.velocityRange / 127;
693
694 if ( tieFlag )
695 {
696 // タイ
697 channel = GetLastChannel();
698 if ( channel != NULL )
699 {
700 channel->SetKey( static_cast<u8>( key ) );
701 float initVolume = static_cast<float>( velocity ) / 127.0f;
702 channel->SetInitVolume( initVolume * initVolume );
703 // TODO: パンも更新するか?
704 }
705 }
706
707 if ( GetParserTrackParam().monophonicFlag )
708 {
709 // モノフォニック
710 channel = GetLastChannel();
711 if ( channel != NULL )
712 {
713 if ( channel->IsRelease() )
714 {
715 channel->Stop();
716 channel = NULL;
717 }
718 else
719 {
720 channel->SetKey( static_cast<u8>( key ) );
721 float initVolume = static_cast<float>( velocity ) / 127.0f;
722 channel->SetInitVolume( initVolume * initVolume );
723 channel->SetLength( length );
724 }
725 }
726 }
727
728 if ( channel == NULL )
729 {
730 NoteOnInfo noteOnInfo = {
731 m_ParserTrackParam.prgNo,
732 key,
733 velocity,
734 tieFlag ? -1 : length,
735 m_ParserTrackParam.initPan,
736 playerParam.priority + m_ParserTrackParam.priority,
737 SequenceTrack::ChannelCallbackFunc,
738 reinterpret_cast<u32>( this )
739 };
740 channel = m_pSequenceSoundPlayer->NoteOn(
741 m_ParserTrackParam.bankIndex,
742 noteOnInfo
743 );
744 if ( channel == NULL ) return NULL;
745
746 // オルタネートアサイン処理
747 if ( channel->GetKeyGroupId() > 0 )
748 {
749 Channel* itr = m_pChannelList;
750 while( itr != NULL )
751 {
752 if ( itr->GetKeyGroupId() == channel->GetKeyGroupId() )
753 {
754 itr->Release();
755 }
756 itr = itr->GetNextTrackChannel();
757 }
758 }
759
760 // チャンネルリストへの結合
761 AddChannel( channel );
762 }
763
764 // 初期パラメータ設定
765
766 // エンベロープ更新
767 if ( m_ParserTrackParam.attack <= SequenceTrack::MAX_ENVELOPE_VALUE )
768 {
769 channel->SetAttack( m_ParserTrackParam.attack );
770 }
771
772 if ( m_ParserTrackParam.decay <= SequenceTrack::MAX_ENVELOPE_VALUE )
773 {
774 channel->SetDecay( m_ParserTrackParam.decay );
775 }
776
777 if ( m_ParserTrackParam.sustain <= SequenceTrack::MAX_ENVELOPE_VALUE )
778 {
779 channel->SetSustain( m_ParserTrackParam.sustain );
780 }
781
782 if ( m_ParserTrackParam.release <= SequenceTrack::MAX_ENVELOPE_VALUE )
783 {
784 channel->SetRelease( m_ParserTrackParam.release );
785 }
786 if ( m_ParserTrackParam.envHold <= SequenceTrack::MAX_ENVELOPE_VALUE )
787 {
788 channel->SetHold( m_ParserTrackParam.envHold );
789 }
790
791 // スイープ&ポルタメント更新
792 f32 sweepPitch = m_ParserTrackParam.sweepPitch;
793
794 if ( m_ParserTrackParam.portaFlag )
795 {
796 sweepPitch += m_ParserTrackParam.portaKey - key;
797 }
798
799 if ( m_ParserTrackParam.portaTime == 0 )
800 {
801 NW_WARNING( length != 0, "portatime zero is invalid." );
802 channel->SetSweepParam( sweepPitch, length, false );
803 }
804 else
805 {
806 int sweepTime = m_ParserTrackParam.portaTime;
807 sweepTime *= sweepTime;
808 sweepTime = static_cast<int>( sweepTime * ( sweepPitch >= 0 ? sweepPitch : -sweepPitch ) );
809 sweepTime >>= 5;
810 sweepTime *= 5; // 単位はmsec
811
812 channel->SetSweepParam( sweepPitch, sweepTime, true );
813 }
814
815 // ポルタメント開始キーを更新
816 m_ParserTrackParam.portaKey = static_cast<u8>( key );
817
818 // その他
819 channel->SetSilence( m_ParserTrackParam.silenceFlag != 0, 0 );
820 channel->SetReleasePriorityFix( m_pSequenceSoundPlayer->IsReleasePriorityFix() );
821 channel->SetPanMode( m_pSequenceSoundPlayer->GetPanMode() );
822 channel->SetPanCurve( m_pSequenceSoundPlayer->GetPanCurve() );
823 channel->SetFrontBypass( m_ParserTrackParam.frontBypassFlag );
824
825 return channel;
826 }
827
828 } // namespace nw::snd::internal::driver
829 } // namespace nw::snd::internal
830 } // namespace nw::snd
831 } // namespace nw
832
833