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