1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: snd_SoundArchivePlayer.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: 27590 $
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17
18 #include <nw/snd/snd_SoundArchivePlayer.h>
19
20 #include <nw/snd/snd_SoundSystem.h>
21 #include <nw/snd/snd_SoundDataManager.h>
22 #include <nw/snd/snd_SoundPlayer.h>
23 #include <nw/snd/snd_SoundHandle.h>
24 #include <nw/snd/snd_SoundActor.h>
25 #include <nw/snd/snd_Bank.h>
26 #include <nw/snd/snd_SequenceSoundFileReader.h>
27 #include <nw/snd/snd_WaveSoundFileReader.h>
28 #include <nw/snd/snd_WaveArchiveFileReader.h>
29 #include <nw/snd/snd_WaveFileReader.h>
30 #include <nw/snd/snd_SoundArchiveLoader.h>
31 #include <nw/snd/snd_Debug.h>
32 #include <nw/snd/snd_Util.h>
33 #include <nw/snd/snd_PlayerHeap.h>
34 #include <nw/snd/snd_DriverCommandManager.h>
35
36 namespace nw {
37 namespace snd {
38
39 /*---------------------------------------------------------------------------*
40 Name: SoundArchivePlayer
41
42 Description: コンストラクタ
43
44 Arguments: 無し
45
46 Returns: 無し
47 *---------------------------------------------------------------------------*/
SoundArchivePlayer()48 SoundArchivePlayer::SoundArchivePlayer()
49 : m_pSoundArchive( NULL ),
50 m_SequenceCallback( *this ),
51 m_WaveSoundCallback( *this ),
52 m_SequenceUserprocCallback( NULL ),
53 m_pSequenceUserprocCallbackArg( NULL ),
54 m_SoundPlayerCount( 0 ),
55 m_pSoundPlayers( NULL ),
56 m_MmlSequenceTrackAllocator( &m_MmlParser ),
57 m_pSetupBufferAddress( NULL ),
58 m_SetupBufferSize( 0 )
59 {
60 }
61
62 /*---------------------------------------------------------------------------*
63 Name: SoundArchivePlayer
64
65 Description: デストラクタ
66
67 Arguments: 無し
68
69 Returns: 無し
70 *---------------------------------------------------------------------------*/
~SoundArchivePlayer()71 SoundArchivePlayer::~SoundArchivePlayer()
72 {
73 }
74
75 /*---------------------------------------------------------------------------*
76 Name: IsAvailable
77
78 Description: サウンドアーカイブプレイヤーが利用可能かどうかを調べる
79
80 Arguments: 無し
81
82 Returns: 利用可能かどうかを返す
83 *---------------------------------------------------------------------------*/
IsAvailable() const84 bool SoundArchivePlayer::IsAvailable() const
85 {
86 if ( m_pSoundArchive == NULL ) return false;
87 if ( ! m_pSoundArchive->IsAvailable() ) return false;
88
89 return true;
90 }
91
92 /*---------------------------------------------------------------------------*
93 Name: Initialize
94
95 Description: サウンドアーカイブ中のプレイヤー情報にしたがって
96 プレイヤーをセットアップする
97
98 Arguments: arc - サウンドアーカイブ
99 buffer - セットアップに使用するメモリ
100 size - メモリサイズ
101 aramBuffer - セットアップに使用するAメモリ
102 aramSize - メモリサイズ
103
104 Returns: セットアップに成功したらtrue
105 *---------------------------------------------------------------------------*/
Initialize(const SoundArchive * arc,const SoundDataManager * manager,void * buffer,u32 size,void * strmBuffer,u32 strmBufferSize)106 bool SoundArchivePlayer::Initialize(
107 const SoundArchive* arc,
108 const SoundDataManager* manager,
109 void* buffer,
110 u32 size,
111 void* strmBuffer,
112 u32 strmBufferSize
113 )
114 {
115 // サウンドシステムの初期化が必要
116 NW_ASSERT( SoundSystem::IsInitialized() );
117 if ( ! SoundSystem::IsInitialized() )
118 {
119 return false;
120 }
121
122 NW_NULL_ASSERT( arc );
123 NW_NULL_ASSERT( manager );
124 NW_NULL_ASSERT( buffer );
125 NW_ALIGN32_ASSERT( buffer );
126
127 if ( strmBufferSize > 0 ) {
128 NW_NULL_ASSERT( strmBuffer );
129 NW_ALIGN32_ASSERT( strmBuffer );
130
131 if ( ! internal::Util::IsDeviceMemory(
132 reinterpret_cast<uptr>(strmBuffer), strmBufferSize ) )
133 {
134 NW_ASSERTMSG( false,
135 "strmBuffer, strmBuffer + strmBufferSize is not Device Memory.");
136 return false;
137 }
138 }
139 NW_ASSERT( strmBufferSize >= GetRequiredStreamBufferSize( arc ) );
140
141 if ( ! SetupMram( arc, buffer, size ) ) {
142 return false;
143 }
144
145 if ( ! SetupStreamBuffer( arc, strmBuffer, strmBufferSize ) ) {
146 return false;
147 }
148
149 m_pSequenceTrackAllocator = &m_MmlSequenceTrackAllocator;
150 m_pSoundDataManager = manager;
151 return true;
152 }
153
154 /*---------------------------------------------------------------------------*
155 Name: Finalize
156
157 Description: サウンドアーカイブプレイヤーの機能を停止させる
158
159 Arguments: 無し
160
161 Returns: 無し
162 *---------------------------------------------------------------------------*/
Finalize()163 void SoundArchivePlayer::Finalize()
164 {
165 // 参照の破棄
166 m_pSoundArchive = NULL;
167 m_pSequenceTrackAllocator = NULL;
168
169 // 全サウンドの停止
170 for ( SoundArchive::ItemId playerId = 0; playerId < m_SoundPlayerCount ; ++playerId )
171 {
172 m_pSoundPlayers[ playerId ].StopAllSound(0);
173 }
174
175 // 停止完了待ち
176 internal::DriverCommandManager& cmdmgr = internal::DriverCommandManager::GetInstance();
177 u32 tag = cmdmgr.FlushCommand( true );
178 cmdmgr.WaitCommandReply( tag );
179
180 // インスタンスの破棄
181 m_SoundPlayerCount = 0;
182 m_pSoundPlayers = NULL;
183
184 m_StreamBufferPool.Finalize();
185
186 if ( m_pSetupBufferAddress != NULL )
187 {
188 m_SequenceSoundInstanceManager.Destroy( m_pSetupBufferAddress, m_SetupBufferSize );
189 m_MmlSequenceTrackAllocator.Destroy( m_pSetupBufferAddress, m_SetupBufferSize );
190 m_WaveSoundInstanceManager.Destroy( m_pSetupBufferAddress, m_SetupBufferSize );
191 m_StreamSoundInstanceManager.Destroy( m_pSetupBufferAddress, m_SetupBufferSize );
192
193 m_pSetupBufferAddress = NULL;
194 m_SetupBufferSize = 0;
195 }
196 }
197
198
199 /*---------------------------------------------------------------------------*
200 Name: GetRequiredMemSize
201
202 Description: サウンドアーカイブプレイヤーで使用するメモリサイズを取得する
203
204 Arguments: arc - サウンドアーカイブ
205
206 Returns: 無し
207 *---------------------------------------------------------------------------*/
GetRequiredMemSize(const SoundArchive * arc)208 size_t SoundArchivePlayer::GetRequiredMemSize( const SoundArchive* arc )
209 {
210 NW_NULL_ASSERT( arc );
211
212 size_t size = 0;
213
214 // SoundPlayer
215 {
216 u32 playerCount = arc->GetPlayerCount();
217 size += ut::RoundUp( playerCount * sizeof( SoundPlayer ), 4 );
218
219 for ( u32 playerIndex = 0; playerIndex < playerCount; ++playerIndex )
220 {
221 SoundArchive::PlayerInfo playerInfo;
222 if ( ! arc->ReadPlayerInfo( internal::Util::GetMaskedItemId(
223 playerIndex, internal::ItemType_Player ), &playerInfo ) )
224 {
225 continue;
226 }
227
228 if ( playerInfo.playerHeapSize > 0 )
229 {
230 for ( int i = 0; i < playerInfo.playableSoundMax ; i++ )
231 {
232 size += ut::RoundUp( sizeof(internal::PlayerHeap), 4 );
233 size = ut::RoundUp( size, 32 );
234 size += ut::RoundUp( playerInfo.playerHeapSize, 4 );
235 }
236 }
237 }
238 }
239
240 SoundArchive::SoundArchivePlayerInfo soundArchivePlayerInfo;
241 if ( arc->ReadSoundArchivePlayerInfo( &soundArchivePlayerInfo ) )
242 {
243 // SequenceSound
244 size += ut::RoundUp(
245 m_SequenceSoundInstanceManager.GetRequiredMemSize(soundArchivePlayerInfo.sequenceSoundMax), 4 );
246
247 // WaveSound
248 size += ut::RoundUp(
249 m_WaveSoundInstanceManager.GetRequiredMemSize(soundArchivePlayerInfo.waveSoundMax), 4 );
250
251 // StreamSound
252 size += ut::RoundUp(
253 m_StreamSoundInstanceManager.GetRequiredMemSize(soundArchivePlayerInfo.streamSoundMax), 4 );
254
255 // SequenceTrack
256 size += ut::RoundUp(
257 soundArchivePlayerInfo.sequenceTrackMax *
258 sizeof( internal::driver::MmlSequenceTrack ), 4 );
259
260 }
261
262 return size;
263 }
264
265 /*---------------------------------------------------------------------------*
266 Name: GetRequiredStreamBufferSize
267
268 Description: サウンドアーカイブプレイヤーで使用するAメモリサイズを取得する
269
270 Arguments: arc - サウンドアーカイブ
271
272 Returns: 無し
273 *---------------------------------------------------------------------------*/
GetRequiredStreamBufferSize(const nw::snd::SoundArchive * arc)274 size_t SoundArchivePlayer::GetRequiredStreamBufferSize(
275 const nw::snd::SoundArchive* arc )
276 {
277 NW_NULL_ASSERT( arc );
278
279 int strmChannelCount = 0;
280
281 SoundArchive::SoundArchivePlayerInfo soundArchivePlayerInfo;
282 if ( arc->ReadSoundArchivePlayerInfo( &soundArchivePlayerInfo ) )
283 {
284 strmChannelCount = soundArchivePlayerInfo.streamChannelMax;
285 }
286
287 size_t memSize = static_cast<size_t>(
288 internal::driver::StreamSoundPlayer::DATA_BLOCK_SIZE_MAX
289 * DEFAULT_STREAM_BLOCK_COUNT
290 * strmChannelCount
291 );
292 return memSize;
293 }
294
295 /*---------------------------------------------------------------------------*
296 Name: SetupMram
297
298 Description: サウンドアーカイブ中のプレイヤー情報にしたがって
299 プレイヤーをセットアップする
300
301 Arguments: arc - サウンドアーカイブ
302 buffer - セットアップに使用するメモリ
303 size - メモリサイズ
304
305 Returns: セットアップに成功したらtrue
306 *---------------------------------------------------------------------------*/
SetupMram(const SoundArchive * arc,void * buffer,unsigned long size)307 bool SoundArchivePlayer::SetupMram( const SoundArchive* arc, void* buffer, unsigned long size )
308 {
309 NW_ASSERT( size >= GetRequiredMemSize( arc ) );
310
311 void* endp = static_cast<char*>(buffer) + size;
312
313 void* buf = buffer;
314 if ( ! SetupSoundPlayer( arc, &buf, endp ) )
315 {
316 return false;
317 }
318
319 SoundArchive::SoundArchivePlayerInfo soundArchivePlayerInfo;
320 if ( arc->ReadSoundArchivePlayerInfo( &soundArchivePlayerInfo ) )
321 {
322 if ( ! SetupSequenceSound( arc, soundArchivePlayerInfo.sequenceSoundMax, &buf, endp ) )
323 {
324 return false;
325 }
326
327 if ( ! SetupWaveSound( arc, soundArchivePlayerInfo.waveSoundMax, &buf, endp ) )
328 {
329 return false;
330 }
331
332 if ( ! SetupStreamSound( arc, soundArchivePlayerInfo.streamSoundMax, &buf, endp ) )
333 {
334 return false;
335 }
336
337 if ( ! SetupSequenceTrack( arc, soundArchivePlayerInfo.sequenceTrackMax, &buf, endp ) )
338 {
339 return false;
340 }
341 }
342
343 NW_ASSERT(
344 static_cast<char*>(buf) - static_cast<char*>(buffer) ==
345 static_cast<s32>( GetRequiredMemSize( arc ) ) );
346
347 m_pSoundArchive = arc;
348 m_pSetupBufferAddress = buffer;
349 m_SetupBufferSize = size;
350
351 return true;
352 }
353
354 /*---------------------------------------------------------------------------*
355 Name: CreatePlayerHeap
356
357 Description: プレイヤーヒープの作成
358
359 Arguments: heap - サウンドヒープ
360 size - プレイヤーヒープサイズ
361
362 Returns: 作成したプレイヤーヒープへのポインタ
363 *---------------------------------------------------------------------------*/
CreatePlayerHeap(void ** buffer,void * endp,size_t heapSize)364 internal::PlayerHeap* SoundArchivePlayer::CreatePlayerHeap(
365 void** buffer,
366 void* endp,
367 size_t heapSize
368 )
369 {
370 // プレイヤーヒープ構造体初期化
371 void* ep = ut::RoundUp( ut::AddOffsetToPtr( *buffer, sizeof(internal::PlayerHeap) ), 4 );
372 if ( ut::ComparePtr( ep, endp ) > 0 )
373 {
374 return NULL;
375 }
376 void* buf = *buffer;
377 *buffer = ep;
378
379 internal::PlayerHeap* playerHeap = new ( buf ) internal::PlayerHeap();
380
381 // プレイヤーヒープ構築
382 *buffer = ut::RoundUp( *buffer, 32 );
383 ep = ut::RoundUp( ut::AddOffsetToPtr( *buffer, heapSize ), 4 );
384 if ( ut::ComparePtr( ep, endp ) > 0 )
385 {
386 return NULL;
387 }
388 buf = *buffer;
389 *buffer = ep;
390
391 bool result = playerHeap->Create( buf, heapSize );
392
393 if ( ! result )
394 {
395 return NULL;
396 }
397
398 return playerHeap;
399 }
400
SetupSoundPlayer(const SoundArchive * arc,void ** buffer,void * endp)401 bool SoundArchivePlayer::SetupSoundPlayer(
402 const SoundArchive* arc,
403 void** buffer,
404 void* endp
405 )
406 {
407 u32 playerCount = arc->GetPlayerCount();
408 size_t requireSize = playerCount * sizeof( SoundPlayer );
409
410 void* ep = ut::RoundUp( ut::AddOffsetToPtr( *buffer, requireSize ), 4 );
411 if ( ut::ComparePtr( ep, endp ) > 0 )
412 {
413 return false;
414 }
415 void* buf = *buffer;
416 *buffer = ep;
417
418 // buf 上に SoundPlayer インスタンスを playerCount 個並べる
419 m_pSoundPlayers = reinterpret_cast<SoundPlayer*>( buf );
420 m_SoundPlayerCount = playerCount;
421
422 u8* ptr = static_cast<u8*>( buf );
423 for ( u32 playerIndex = 0; playerIndex < playerCount;
424 ++playerIndex, ptr += sizeof( SoundPlayer ) )
425 {
426 SoundPlayer* player = new ( ptr ) SoundPlayer();
427
428 SoundArchive::PlayerInfo playerInfo;
429 if ( ! arc->ReadPlayerInfo( internal::Util::GetMaskedItemId(
430 playerIndex, internal::ItemType_Player ), &playerInfo ) )
431 {
432 continue;
433 }
434
435 player->SetPlayableSoundCount( playerInfo.playableSoundMax );
436
437 // プレイヤーヒープのセットアップ
438 if ( playerInfo.playerHeapSize > 0 )
439 {
440 for ( int i = 0; i < playerInfo.playableSoundMax ; i++ )
441 {
442 internal::PlayerHeap* playerHeap = CreatePlayerHeap(
443 buffer, endp, playerInfo.playerHeapSize );
444
445 NW_WARNING( playerHeap != NULL,
446 "failed to create player heap. ( player id = %d )", playerIndex );
447 if ( playerHeap == NULL )
448 {
449 return false;
450 }
451 player->detail_AppendPlayerHeap( playerHeap );
452 }
453
454 // プレイヤーヒープを使用する場合、
455 // 用意されたプレイヤーヒープ数を超える同時再生数は指定できない
456 player->detail_SetPlayableSoundLimit( playerInfo.playableSoundMax );
457 }
458 }
459
460 return true;
461 }
462
463 /*---------------------------------------------------------------------------*
464 Name: SetupSequenceSound
465
466 Description: シーケンスサウンドのセットアップ
467
468 Arguments: numSounds - 確保するシーケンスサウンドの数
469 heap - サウンドヒープ
470
471 Returns: 成功したかどうか
472 *---------------------------------------------------------------------------*/
SetupSequenceSound(const SoundArchive *,int numSounds,void ** buffer,void * endp)473 bool SoundArchivePlayer::SetupSequenceSound(
474 const SoundArchive* /*arc*/,
475 int numSounds,
476 void** buffer,
477 void* endp
478 )
479 {
480 size_t requireSize = m_SequenceSoundInstanceManager.GetRequiredMemSize(numSounds);
481
482 void* ep = ut::RoundUp( ut::AddOffsetToPtr( *buffer, requireSize ), 4 );
483 if ( ut::ComparePtr( ep, endp ) > 0 )
484 {
485 return false;
486 }
487
488 unsigned long createNum = m_SequenceSoundInstanceManager.Create( *buffer, requireSize );
489 NW_ASSERT( createNum == numSounds );
490 *buffer = ep;
491
492 return true;
493 }
494
495 /*---------------------------------------------------------------------------*
496 Name: SetupWaveSound
497
498 Description: ウェーブサウンドのセットアップ
499
500 Arguments: numSounds - 確保するウェーブサウンドの数
501 heap - サウンドヒープ
502
503 Returns: 成功したかどうか
504 *---------------------------------------------------------------------------*/
SetupWaveSound(const SoundArchive *,int numSounds,void ** buffer,void * endp)505 bool SoundArchivePlayer::SetupWaveSound(
506 const SoundArchive* /*arc*/,
507 int numSounds,
508 void** buffer,
509 void* endp
510 )
511 {
512 size_t requireSize = m_WaveSoundInstanceManager.GetRequiredMemSize(numSounds);
513
514 void* ep = ut::RoundUp( ut::AddOffsetToPtr( *buffer, requireSize ), 4 );
515 if ( ut::ComparePtr( ep, endp ) > 0 )
516 {
517 return false;
518 }
519
520 unsigned long createNum = m_WaveSoundInstanceManager.Create( *buffer, requireSize );
521 NW_ASSERT( createNum == numSounds );
522 *buffer = ep;
523
524 return true;
525 }
526
527 /*---------------------------------------------------------------------------*
528 Name: SetupStreamSound
529
530 Description: ストリームサウンドのセットアップ
531
532 Arguments: numSounds - 確保するストリームサウンドの数
533 heap - サウンドヒープ
534
535 Returns: 成功したかどうか
536 *---------------------------------------------------------------------------*/
SetupStreamSound(const SoundArchive *,int numSounds,void ** buffer,void * endp)537 bool SoundArchivePlayer::SetupStreamSound(
538 const SoundArchive* /*arc*/,
539 int numSounds,
540 void** buffer,
541 void* endp
542 )
543 {
544 size_t requireSize = m_StreamSoundInstanceManager.GetRequiredMemSize(numSounds);
545
546 void* ep = ut::RoundUp( ut::AddOffsetToPtr( *buffer, requireSize ), 4 );
547 if ( ut::ComparePtr( ep, endp ) > 0 )
548 {
549 return false;
550 }
551
552 unsigned long createNum = m_StreamSoundInstanceManager.Create( *buffer, requireSize );
553 NW_ASSERT( createNum == numSounds );
554 *buffer = ep;
555
556 return true;
557 }
558
559 /*---------------------------------------------------------------------------*
560 Name: SetupSequenceTrack
561
562 Description: シーケンスサウンドのセットアップ
563
564 Arguments: numSounds - 確保するシーケンスサウンドの数
565 heap - サウンドヒープ
566
567 Returns: 成功したかどうか
568 *---------------------------------------------------------------------------*/
SetupSequenceTrack(const SoundArchive *,int numTracks,void ** buffer,void * endp)569 bool SoundArchivePlayer::SetupSequenceTrack(
570 const SoundArchive* /*arc*/,
571 int numTracks,
572 void** buffer,
573 void* endp
574 )
575 {
576 unsigned long requireSize = numTracks * sizeof( internal::driver::MmlSequenceTrack );
577
578 void* ep = ut::RoundUp( ut::AddOffsetToPtr( *buffer, requireSize ), 4 );
579 if ( ut::ComparePtr( ep, endp ) > 0 )
580 {
581 return false;
582 }
583
584 unsigned long createNum = m_MmlSequenceTrackAllocator.Create( *buffer, requireSize );
585 NW_ASSERT( createNum == numTracks );
586 *buffer = ep;
587
588 return true;
589 }
590
591 /*---------------------------------------------------------------------------*
592 Name: SetupStreamBuffer
593
594 Description: ストリームチャンネルのセットアップ
595
596 Arguments: heap - サウンドヒープ
597
598 Returns: 成功したかどうか
599 *---------------------------------------------------------------------------*/
SetupStreamBuffer(const SoundArchive * arc,void * buffer,unsigned long size)600 bool SoundArchivePlayer::SetupStreamBuffer(
601 const SoundArchive* arc,
602 void* buffer,
603 unsigned long size
604 )
605 {
606 if ( size < GetRequiredStreamBufferSize( arc ) ) return false;
607
608 int strmChannelCount = 0;
609
610 SoundArchive::SoundArchivePlayerInfo soundArchivePlayerInfo;
611 if ( arc->ReadSoundArchivePlayerInfo( &soundArchivePlayerInfo ) )
612 {
613 strmChannelCount = soundArchivePlayerInfo.streamChannelMax;
614 }
615
616 m_StreamBufferPool.Initialize( buffer, size, strmChannelCount );
617
618 return true;
619 }
620
621 /*---------------------------------------------------------------------------*
622 Name: Update
623
624 Description: プレイヤーのフレーム処理を更新する
625
626 Arguments: None.
627
628 Returns: None.
629 *---------------------------------------------------------------------------*/
Update()630 void SoundArchivePlayer::Update()
631 {
632 for ( u32 playerIndex = 0;
633 playerIndex < m_SoundPlayerCount; ++playerIndex )
634 {
635 GetSoundPlayer( internal::Util::GetMaskedItemId(
636 playerIndex, internal::ItemType_Player ) ).Update();
637 }
638
639 m_SequenceSoundInstanceManager.SortPriorityList();
640 m_WaveSoundInstanceManager.SortPriorityList();
641 m_StreamSoundInstanceManager.SortPriorityList();
642
643 internal::DriverCommandManager& cmdmgr = internal::DriverCommandManager::GetInstance();
644 cmdmgr.RecvCommandReply();
645 cmdmgr.FlushCommand( false );
646 }
647
GetSoundArchive() const648 const SoundArchive& SoundArchivePlayer::GetSoundArchive() const
649 {
650 NW_ASSERTMSG( m_pSoundArchive != NULL, "Setup is not completed." );
651 return *m_pSoundArchive;
652 }
653
GetSoundPlayer(SoundArchive::ItemId playerId)654 SoundPlayer& SoundArchivePlayer::GetSoundPlayer( SoundArchive::ItemId playerId )
655 {
656 u32 itemIndex = internal::Util::GetItemIndex( playerId );
657 NW_MINMAXLT_ASSERT( itemIndex, 0, m_SoundPlayerCount );
658 return m_pSoundPlayers[ itemIndex ];
659 }
660
GetSoundPlayer(const char * pStr)661 SoundPlayer& SoundArchivePlayer::GetSoundPlayer( const char* pStr )
662 {
663 NW_NULL_ASSERT( m_pSoundArchive );
664
665 SoundArchive::ItemId playerId = m_pSoundArchive->GetItemId( pStr );
666 NW_ASSERT( playerId != SoundArchive::INVALID_ID );
667 return GetSoundPlayer( playerId );
668 }
669
670
671 /*---------------------------------------------------------------------------*
672 Name: AllocSound
673
674 Description: サウンドを取得する
675
676 Arguments: manager - サウンドインスタンスマネージャ
677 soundId - サウンドID
678 priority - プレイヤープライオリティ
679 ambientPriority - アンビエントプライオリティ
680 ambientArgInfo - アンビエント情報
681
682 Returns: サウンドへのポインタ。取得できなかったらNULL
683 *---------------------------------------------------------------------------*/
684 template< typename Sound, typename Player >
AllocSound(internal::SoundInstanceManager<Sound,Player> * manager,SoundArchive::ItemId soundId,int priority,int ambientPriority,internal::BasicSound::AmbientInfo * ambientArgInfo)685 Sound* SoundArchivePlayer::AllocSound(
686 internal::SoundInstanceManager< Sound,Player >* manager,
687 SoundArchive::ItemId soundId,
688 int priority,
689 int ambientPriority,
690 internal::BasicSound::AmbientInfo* ambientArgInfo
691 )
692 {
693 NW_NULL_ASSERT( manager );
694
695 // サウンドの確保
696 Sound* sound = manager->Alloc( priority, ambientPriority );
697 if ( sound == NULL ) return NULL;
698
699 // ID設定
700 sound->SetId( soundId );
701
702 // アンビエント設定
703 if ( ambientArgInfo != NULL )
704 {
705 sound->SetAmbientInfo( *ambientArgInfo );
706 }
707
708 return sound;
709 }
710
711 const void*
detail_GetFileAddress(SoundArchive::FileId fileId) const712 SoundArchivePlayer::detail_GetFileAddress( SoundArchive::FileId fileId ) const
713 {
714 if ( m_pSoundDataManager == NULL ) return NULL;
715
716 return m_pSoundDataManager->detail_GetFileAddress( fileId );
717 }
718
detail_SetupSound(SoundHandle * handle,u32 soundId,bool holdFlag,const StartInfo * startInfo)719 SoundStartable::StartResult SoundArchivePlayer::detail_SetupSound(
720 SoundHandle* handle,
721 u32 soundId,
722 bool holdFlag,
723 const StartInfo* startInfo
724 )
725 {
726 return detail_SetupSoundImpl(
727 handle,
728 soundId,
729 NULL,
730 NULL,
731 holdFlag,
732 startInfo
733 );
734 }
735
736 /*---------------------------------------------------------------------------*
737 Name: detail_SetupSoundImpl
738
739 Description: 再生の実装関数
740
741 Arguments: handle - サウンドハンドル
742 soundId - サウンドID
743 ambientArgInfo - 外部パラメータ
744 actor - サウンドアクター
745 holdFlag - ホールドサウンドフラグ
746
747 Returns: 結果コード
748 *---------------------------------------------------------------------------*/
detail_SetupSoundImpl(SoundHandle * handle,u32 soundId,internal::BasicSound::AmbientInfo * ambientArgInfo,SoundActor * actor,bool holdFlag,const StartInfo * startInfo)749 SoundStartable::StartResult SoundArchivePlayer::detail_SetupSoundImpl(
750 SoundHandle* handle,
751 u32 soundId,
752 internal::BasicSound::AmbientInfo* ambientArgInfo,
753 SoundActor* actor,
754 bool holdFlag,
755 const StartInfo* startInfo
756 )
757 {
758 NW_NULL_ASSERT( handle );
759
760 if ( ! IsAvailable() )
761 {
762 SoundStartable::StartResult
763 result( SoundStartable::StartResult::START_ERR_NOT_AVAILABLE );
764 return result;
765 }
766
767 // サウンドハンドルを古いサウンドから切断
768 if ( handle->IsAttachedSound() ) {
769 handle->DetachSound();
770 }
771
772 // サウンドアーカイブからサウンド情報の取得
773 SoundArchive::SoundInfo soundInfo;
774 if ( ! m_pSoundArchive->ReadSoundInfo( soundId, &soundInfo ) )
775 {
776 SoundStartable::StartResult
777 result( SoundStartable::StartResult::START_ERR_INVALID_SOUNDID );
778 return result;
779 }
780
781 // StartInfoの処理
782 SoundStartable::StartInfo::StartOffsetType startOffsetType =
783 SoundStartable::StartInfo::START_OFFSET_TYPE_MILLISEC;
784 int startOffset = 0;
785 int playerPriority = soundInfo.playerPriority;
786 SoundArchive::ItemId playerId = soundInfo.playerId;
787 int actorPlayerId = soundInfo.actorPlayerId;
788 const SoundStartable::StartInfo::SeqSoundInfo* seqInfo = NULL;
789 if ( startInfo != NULL )
790 {
791 if ( startInfo->enableFlag & StartInfo::ENABLE_START_OFFSET )
792 {
793 startOffsetType = startInfo->startOffsetType;
794 startOffset = startInfo->startOffset;
795 }
796 if ( startInfo->enableFlag & StartInfo::ENABLE_PLAYER_PRIORITY )
797 {
798 playerPriority = startInfo->playerPriority;
799 }
800 if ( startInfo->enableFlag & StartInfo::ENABLE_PLAYER_ID )
801 {
802 playerId = startInfo->playerId;
803 }
804 if ( startInfo->enableFlag & StartInfo::ENABLE_ACTOR_PLAYER_ID )
805 {
806 actorPlayerId = startInfo->actorPlayerId;
807 }
808 if ( startInfo->enableFlag & StartInfo::ENABLE_SEQ_SOUND_INFO )
809 {
810 seqInfo = &startInfo->seqSoundInfo;
811 }
812 }
813
814 // プライオリティの計算
815 int priority = playerPriority;
816 if ( holdFlag ) --priority; // HoldSoundで再生するときは同プライオリティで先着優先
817
818 int ambientPriority = 0;
819 if ( ambientArgInfo != NULL )
820 {
821 ambientPriority = internal::BasicSound::GetAmbientPriority( *ambientArgInfo, soundId );
822 }
823 int allocPriority = priority + ambientPriority;
824 allocPriority = ut::Clamp( allocPriority, internal::BasicSound::PRIORITY_MIN, internal::BasicSound::PRIORITY_MAX );
825
826 // ExternalSoundPlayer
827 internal::ExternalSoundPlayer* extPlayer = NULL;
828 if ( actor != NULL ) {
829 extPlayer = actor->detail_GetActorPlayer( actorPlayerId );
830 if ( extPlayer == NULL )
831 {
832 NW_WARNING(
833 false,
834 "actorPlayerId(%d) is out of range. (0-%d)",
835 actorPlayerId,
836 SoundActor::ACTOR_PLAYER_COUNT-1
837 );
838 return StartResult::START_ERR_INVALID_PARAMETER;
839 }
840 }
841
842 // プレイヤーの空きをチェック
843 SoundPlayer& player = GetSoundPlayer( playerId );
844 if ( ! player.detail_CanPlaySound( allocPriority ) ) {
845 return StartResult::START_ERR_LOW_PRIORITY;
846 }
847 if ( ( extPlayer != NULL ) && ( ! extPlayer->detail_CanPlaySound( allocPriority ) ) ) {
848 return StartResult::START_ERR_LOW_PRIORITY;
849 }
850
851 // サウンドのアロケート
852 internal::BasicSound* sound = NULL;
853 internal::SequenceSound* seqSound = NULL;
854 internal::StreamSound* strmSound = NULL;
855 internal::WaveSound* waveSound = NULL;
856
857 switch ( m_pSoundArchive->GetSoundType( soundId ) )
858 {
859 case SoundArchive::SOUND_TYPE_SEQ:
860 seqSound = AllocSound<internal::SequenceSound>(
861 &m_SequenceSoundInstanceManager,
862 soundId,
863 priority,
864 ambientPriority,
865 ambientArgInfo
866 );
867 if ( seqSound == NULL )
868 {
869 NW_WARNING(
870 ! internal::Debug_GetWarningFlag( DEBUG_WARNING_NOT_ENOUGH_SEQSOUND ),
871 "Failed to start sound (id:%d) for not enough SequenceSound instance.",
872 soundId
873 );
874 SoundStartable::StartResult
875 result( SoundStartable::StartResult::START_ERR_NOT_ENOUGH_INSTANCE );
876 return result;
877 }
878 sound = seqSound;
879 break;
880
881 case SoundArchive::SOUND_TYPE_STRM:
882 strmSound = AllocSound<internal::StreamSound>(
883 &m_StreamSoundInstanceManager,
884 soundId,
885 priority,
886 ambientPriority,
887 ambientArgInfo
888 );
889 if ( strmSound == NULL )
890 {
891 NW_WARNING(
892 ! internal::Debug_GetWarningFlag( DEBUG_WARNING_NOT_ENOUGH_STRMSOUND ),
893 "Failed to start sound (id:%d) for not enough StreamSound instance.",
894 soundId
895 );
896 SoundStartable::StartResult
897 result( SoundStartable::StartResult::START_ERR_NOT_ENOUGH_INSTANCE );
898 return result;
899 }
900 sound = strmSound;
901 break;
902
903 case SoundArchive::SOUND_TYPE_WAVE:
904 waveSound = AllocSound<internal::WaveSound>(
905 &m_WaveSoundInstanceManager,
906 soundId,
907 priority,
908 ambientPriority,
909 ambientArgInfo
910 );
911 if ( waveSound == NULL )
912 {
913 NW_WARNING(
914 ! internal::Debug_GetWarningFlag( DEBUG_WARNING_NOT_ENOUGH_WAVESOUND ),
915 "Failed to start sound (id:%d) for not enough WaveSound instance.",
916 soundId
917 );
918 SoundStartable::StartResult
919 result( SoundStartable::StartResult::START_ERR_NOT_ENOUGH_INSTANCE );
920 return result;
921 }
922 sound = waveSound;
923 break;
924
925 default:
926 {
927 SoundStartable::StartResult
928 result( SoundStartable::StartResult::START_ERR_INVALID_SOUNDID );
929 return result;
930 }
931 }
932
933 // サウンドプレイヤーに登録
934 if ( ! player.detail_AppendSound( sound ) )
935 {
936 sound->Finalize();
937 SoundStartable::StartResult
938 result( SoundStartable::StartResult::START_ERR_UNKNOWN );
939 return result;
940 }
941
942 // フロントバイパス設定
943 sound->SetFrontBypass( soundInfo.isFrontBypass );
944
945 // サウンドのプリペア
946 switch ( m_pSoundArchive->GetSoundType( soundId ) )
947 {
948 case SoundArchive::SOUND_TYPE_SEQ:
949 {
950 NW_NULL_ASSERT( seqSound );
951
952 // プレイヤーヒープの確保
953 (void)player.detail_AllocPlayerHeap( seqSound );
954
955 // シーケンスサウンド情報の取得
956 SoundArchive::SequenceSoundInfo info;
957 if ( ! m_pSoundArchive->ReadSequenceSoundInfo( soundId, &info ) ) {
958 seqSound->Finalize();
959 SoundStartable::StartResult
960 result( SoundStartable::StartResult::START_ERR_INVALID_SOUNDID );
961 return result;
962 }
963
964 // バンクの上書き (必要であれば)
965 if ( seqInfo != NULL )
966 {
967 for ( int i = 0; i < SoundArchive::SEQ_BANK_MAX; i++ )
968 {
969 SoundArchive::ItemId bankId = seqInfo->bankIds[ i ];
970 if ( bankId != SoundArchive::INVALID_ID )
971 {
972 info.bankIds[ i ] = seqInfo->bankIds[ i ];
973 }
974 }
975 }
976
977 // シーケンスサウンドの準備
978 StartResult result = PrepareSeqImpl(
979 seqSound,
980 &soundInfo,
981 &info,
982 startOffsetType,
983 startOffset,
984 seqInfo
985 );
986 if ( ! result.IsSuccess() )
987 {
988 seqSound->Finalize();
989 return result;
990 }
991 break;
992 }
993
994 case SoundArchive::SOUND_TYPE_STRM:
995 {
996 NW_NULL_ASSERT( strmSound );
997
998 // ストリームサウンド情報の取得
999 SoundArchive::StreamSoundInfo info;
1000 if ( ! m_pSoundArchive->detail_ReadStreamSoundInfo( soundId, &info ) ) {
1001 strmSound->Finalize();
1002 SoundStartable::StartResult
1003 result( SoundStartable::StartResult::START_ERR_INVALID_SOUNDID );
1004 return result;
1005 }
1006
1007 // ストリームサウンドの準備
1008 StartResult result = PrepareStreamImpl(
1009 strmSound,
1010 &soundInfo,
1011 &info,
1012 startOffsetType,
1013 startOffset
1014 );
1015 if ( ! result.IsSuccess() )
1016 {
1017 strmSound->Finalize();
1018 return result;
1019 }
1020 break;
1021 }
1022
1023 case SoundArchive::SOUND_TYPE_WAVE:
1024 {
1025 NW_NULL_ASSERT( waveSound );
1026
1027 // ウェーブサウンド情報の取得
1028 SoundArchive::WaveSoundInfo info;
1029 if ( ! m_pSoundArchive->detail_ReadWaveSoundInfo( soundId, &info ) ) {
1030 waveSound->Finalize();
1031 SoundStartable::StartResult
1032 result( SoundStartable::StartResult::START_ERR_INVALID_SOUNDID );
1033 return result;
1034 }
1035
1036 // ウェーブサウンドの準備
1037 StartResult result = PrepareWaveSoundImpl(
1038 waveSound,
1039 &soundInfo,
1040 &info,
1041 startOffsetType,
1042 startOffset
1043 );
1044 if ( ! result.IsSuccess() )
1045 {
1046 waveSound->Finalize();
1047 return result;
1048 }
1049 break;
1050 }
1051
1052 default:
1053 NW_ASSERT( false );
1054 sound->Finalize();
1055 {
1056 return StartResult::START_ERR_INVALID_SOUNDID;
1057 }
1058 }
1059
1060 // 外部プレイヤーに登録
1061 if ( extPlayer != NULL )
1062 {
1063 if ( ! extPlayer->AppendSound( sound ) )
1064 {
1065 sound->Finalize();
1066 return StartResult::START_ERR_UNKNOWN;
1067 }
1068 }
1069
1070 // アクターに登録
1071 if ( actor != NULL )
1072 {
1073 sound->AttachSoundActor( actor );
1074 }
1075
1076 // プライオリティの再設定
1077 if ( holdFlag )
1078 {
1079 sound->SetPlayerPriority( playerPriority );
1080 }
1081
1082 // サウンドハンドルを確保したサウンドと接続
1083 handle->detail_AttachSound( sound );
1084
1085 SoundStartable::StartResult
1086 result( SoundStartable::StartResult::START_SUCCESS );
1087 return result;
1088 }
1089
1090 /*---------------------------------------------------------------------------*
1091 Name: PrepareSeqImpl
1092
1093 Description: シーケンスを再生
1094
1095 Arguments: playerId - プレイヤー番号
1096 playerPrio - プレイヤープライオリティ
1097 info - シーケンス情報構造体のポインタ
1098 seqId - シーケンス番号
1099
1100 Returns: 成功したかどうか
1101 *---------------------------------------------------------------------------*/
PrepareSeqImpl(internal::SequenceSound * sound,const SoundArchive::SoundInfo * commonInfo,const SoundArchive::SequenceSoundInfo * info,SoundStartable::StartInfo::StartOffsetType startOffsetType,int startOffset,const StartInfo::SeqSoundInfo * externalSeqInfo)1102 SoundStartable::StartResult SoundArchivePlayer::PrepareSeqImpl(
1103 internal::SequenceSound* sound,
1104 const SoundArchive::SoundInfo* commonInfo,
1105 const SoundArchive::SequenceSoundInfo* info,
1106 SoundStartable::StartInfo::StartOffsetType startOffsetType,
1107 int startOffset,
1108 const StartInfo::SeqSoundInfo* externalSeqInfo
1109 )
1110 {
1111 NW_NULL_ASSERT( info );
1112
1113 const internal::SequenceSoundFile* seqFile = NULL;
1114 io::FileStream* fileStream = NULL;
1115
1116 u32 seqOffset = 0;
1117 u32 allocTrack = info->allocateTrackFlags;
1118
1119 if ( externalSeqInfo != NULL )
1120 {
1121 if ( externalSeqInfo->seqDataAddress != NULL )
1122 {
1123 seqFile = reinterpret_cast<const internal::SequenceSoundFile*>(
1124 externalSeqInfo->seqDataAddress );
1125 seqOffset = 0;
1126
1127 internal::SequenceSoundFileReader seqFileReader( seqFile );
1128 if ( externalSeqInfo->startLocationLabel != NULL )
1129 {
1130 bool result = seqFileReader.GetOffsetByLabel(
1131 externalSeqInfo->startLocationLabel, &seqOffset );
1132 if ( ! result )
1133 {
1134 SoundStartable::StartResult startResult(
1135 SoundStartable::StartResult::START_ERR_INVALID_SEQ_START_LOCATION_LABEL);
1136 return startResult;
1137 }
1138 }
1139 seqOffset = internal::driver::MmlParser::ParseAllocTrack(
1140 seqFileReader.GetSequenceData(),
1141 seqOffset,
1142 &allocTrack
1143 );
1144 }
1145 }
1146
1147 // 外部データが指定されていなかったら
1148 // サウンドアーカイブ中のシーケンスデータを使用する
1149 if ( seqFile == NULL )
1150 {
1151 seqFile = reinterpret_cast<const internal::SequenceSoundFile*> (
1152 m_pSoundDataManager->detail_GetFileAddress( commonInfo->fileId )
1153 );
1154 seqOffset = info->startOffset;
1155
1156 if ( externalSeqInfo != NULL && externalSeqInfo->startLocationLabel != NULL )
1157 {
1158 // TODO: seqFile がロードされていなかったらどうなる? 090730
1159 internal::SequenceSoundFileReader seqFileReader( seqFile );
1160 bool result = seqFileReader.GetOffsetByLabel(
1161 externalSeqInfo->startLocationLabel, &seqOffset );
1162 if ( ! result )
1163 {
1164 SoundStartable::StartResult startResult(
1165 SoundStartable::StartResult::START_ERR_INVALID_SEQ_START_LOCATION_LABEL );
1166 return startResult;
1167 }
1168 }
1169 }
1170
1171 // データがロードされていないのでプレイヤーヒープにロードできるかを確認する
1172 if ( seqFile == NULL )
1173 {
1174 // プレイヤーヒープがあるか
1175 internal::PlayerHeap* pPlayerHeap = sound->GetPlayerHeap();
1176 if ( pPlayerHeap == NULL )
1177 {
1178 SoundStartable::StartResult result(
1179 SoundStartable::StartResult::START_ERR_NOT_SEQ_LOADED );
1180 return result;
1181 }
1182
1183 void* fileStreamBuffer = sound->GetFileStreamBuffer();
1184 NW_NULL_ASSERT( fileStreamBuffer );
1185 size_t fileStreamBufferSize = sound->GetFileStreamBufferSize();
1186
1187 fileStream = const_cast<SoundArchive*>(m_pSoundArchive)->detail_OpenFileStream(
1188 commonInfo->fileId,
1189 fileStreamBuffer,
1190 fileStreamBufferSize
1191 );
1192 if ( fileStream == NULL )
1193 {
1194 SoundStartable::StartResult result(
1195 SoundStartable::StartResult::START_ERR_CANNOT_OPEN_FILE );
1196 return result;
1197 }
1198
1199 // プレイヤーヒープにデータをロードできるかどうか
1200 if ( pPlayerHeap->GetFreeSize() < fileStream->GetSize() )
1201 {
1202 fileStream->Close();
1203 SoundStartable::StartResult result(
1204 SoundStartable::StartResult::START_ERR_NOT_ENOUGH_PLAYER_HEAP );
1205 return result;
1206 }
1207 }
1208
1209 SoundArchive::ItemId bankIds[ SoundArchive::SEQ_BANK_MAX ];
1210 const void* bankFiles[ SoundArchive::SEQ_BANK_MAX ] = { NULL };
1211 if ( externalSeqInfo != NULL )
1212 {
1213 for ( int i = 0; i < SoundArchive::SEQ_BANK_MAX; i++ )
1214 {
1215 bankIds[ i ] = externalSeqInfo->bankIds[ i ];
1216 }
1217 }
1218 else
1219 {
1220 for ( int i = 0; i < SoundArchive::SEQ_BANK_MAX; i++ )
1221 {
1222 bankIds[ i ] = info->bankIds[ i ];
1223 }
1224 }
1225 // バンクがロード済みか?
1226 for ( int i = 0; i < SoundArchive::SEQ_BANK_MAX; i++ )
1227 {
1228 if ( bankIds[ i ] != SoundArchive::INVALID_ID )
1229 {
1230 SoundArchive::BankInfo bankInfo;
1231 bool isReadBank = GetSoundArchive().ReadBankInfo( bankIds[ i ], &bankInfo );
1232 NW_ASSERTMSG( isReadBank, "invalid bank id(%d)", bankIds[ i ] );
1233 const void* bankFile =
1234 m_pSoundDataManager->detail_GetFileAddress( bankInfo.fileId );
1235 bankFiles[ i ] = bankFile;
1236 if ( bankFile == NULL )
1237 {
1238 // return START_ERR_NOT_BANK_LOADED; // TODO: 失敗とすべきか?
1239 // 失敗とできるなら、スタート時のバンク切替で
1240 // アドレスをセットできる。
1241 SoundStartable::StartResult result(
1242 SoundStartable::StartResult::START_ERR_NOT_BANK_LOADED );
1243 return result;
1244 }
1245
1246 // 波形アーカイブがロード済みか? (MEMO: 不要かも)
1247 {
1248 // TODO: bankFile を解析する
1249 }
1250 }
1251 }
1252
1253 // プレイヤーのセットアップ
1254 #if 0
1255 internal::driver::SequenceSoundPlayer::SetupResult result =
1256 sound->Initialize(
1257 m_pSequenceTrackAllocator,
1258 allocTrack,
1259 &m_SequenceCallback,
1260 bankFiles
1261 );
1262 while ( result != internal::driver::SequenceSoundPlayer::SETUP_SUCCESS )
1263 {
1264 if ( result == internal::driver::SequenceSoundPlayer::SETUP_ERR_CANNOT_ALLOCATE_TRACK )
1265 {
1266 // トラックが足りない
1267 if ( m_SequenceSoundInstanceManager.GetActiveCount() == 1 )
1268 {
1269 // ほかにサウンドを再生していないのにトラックが足りない
1270 if ( fileStream != NULL )
1271 {
1272 fileStream->Close();
1273 }
1274 NW_WARNING(
1275 ! internal::Debug_GetWarningFlag( DEBUG_WARNING_NOT_ENOUGH_SEQTRACK ),
1276 "Failed to start sound (id:%d) for not enough SequenceTrack instance.",
1277 sound->GetId()
1278 );
1279 SoundStartable::StartResult startResult(
1280 SoundStartable::StartResult::START_ERR_NOT_ENOUGH_INSTANCE );
1281 return startResult;
1282 }
1283
1284 internal::SequenceSound* lowest = m_SequenceSoundInstanceManager.GetLowestPrioritySound();
1285 if ( sound == lowest )
1286 {
1287 // 自分が一番プライオリティが低い
1288 if ( fileStream != NULL )
1289 {
1290 fileStream->Close();
1291 }
1292 NW_WARNING(
1293 ! internal::Debug_GetWarningFlag( DEBUG_WARNING_NOT_ENOUGH_SEQTRACK ),
1294 "Failed to start sound (id:%d) for not enough SequenceTrack instance.",
1295 sound->GetId()
1296 );
1297 SoundStartable::StartResult startResult(
1298 SoundStartable::StartResult::START_ERR_NOT_ENOUGH_INSTANCE );
1299 return startResult;
1300 }
1301
1302 // もう一度 Setup
1303 NW_WARNING(
1304 ! internal::Debug_GetWarningFlag( DEBUG_WARNING_NOT_ENOUGH_SEQTRACK ),
1305 "Sound (id:%d) is stopped for not enough SequenceTrack instance.",
1306 lowest->GetId()
1307 );
1308 lowest->Stop( 0 );
1309 result = sound->Initialize(
1310 m_pSequenceTrackAllocator,
1311 allocTrack,
1312 &m_SequenceCallback,
1313 bankFiles
1314 );
1315 }
1316 else
1317 {
1318 SoundStartable::StartResult startResult(
1319 SoundStartable::StartResult::START_ERR_UNKNOWN );
1320 return startResult;
1321 }
1322 }
1323 #else
1324 // トラックが足りない時のケア無し
1325
1326 sound->Setup(
1327 m_pSequenceTrackAllocator,
1328 allocTrack,
1329 &m_SequenceCallback,
1330 bankFiles,
1331 SoundArchive::SEQ_BANK_MAX
1332 );
1333 #endif
1334
1335 // パラメータ設定
1336 UpdateCommonSoundParam( sound, commonInfo );
1337 sound->SetChannelPriority( info->channelPriority );
1338 sound->SetReleasePriorityFix( info->isReleasePriorityFix );
1339 sound->SetSequenceUserprocCallback(
1340 m_SequenceUserprocCallback, m_pSequenceUserprocCallbackArg );
1341
1342 internal::driver::SequenceSoundPlayer::OffsetType seqOffsetType;
1343 switch ( startOffsetType )
1344 {
1345 case SoundStartable::StartInfo::START_OFFSET_TYPE_MILLISEC:
1346 seqOffsetType = internal::driver::SequenceSoundPlayer::OFFSET_TYPE_MILLISEC;
1347 break;
1348 case SoundStartable::StartInfo::START_OFFSET_TYPE_TICK:
1349 seqOffsetType = internal::driver::SequenceSoundPlayer::OFFSET_TYPE_TICK;
1350 break;
1351 case SoundStartable::StartInfo::START_OFFSET_TYPE_SAMPLE:
1352 seqOffsetType = internal::driver::SequenceSoundPlayer::OFFSET_TYPE_TICK;
1353 startOffset = 0;
1354 break;
1355 default:
1356 seqOffsetType = internal::driver::SequenceSoundPlayer::OFFSET_TYPE_TICK;
1357 startOffset = 0;
1358 break;
1359 }
1360
1361 if ( seqFile != NULL )
1362 {
1363 // ロード済みのシーケンスデータを使ってプリペア
1364 internal::SequenceSoundFileReader seqFileReader( seqFile );
1365 sound->Prepare(
1366 seqFileReader.GetSequenceData(),
1367 static_cast<s32>( seqOffset ),
1368 seqOffsetType,
1369 startOffset
1370 );
1371 }
1372 else
1373 {
1374 // プレイヤーヒープにデータをロードしてプリペア
1375 sound->Prepare(
1376 fileStream,
1377 static_cast<s32>( seqOffset ),
1378 seqOffsetType,
1379 startOffset
1380 );
1381 }
1382
1383 SoundStartable::StartResult startResult(
1384 SoundStartable::StartResult::START_SUCCESS );
1385 return startResult;
1386 }
1387
1388 /*---------------------------------------------------------------------------*
1389 Name: PrepareStreamImpl
1390
1391 Description: ストリームを再生
1392
1393 Arguments: playerId - プレイヤー番号
1394 playerPrio - プレイヤープライオリティ
1395 info - ストリームの情報
1396 strmId - ストリーム番号
1397
1398 Returns: 成功したかどうか
1399 *---------------------------------------------------------------------------*/
PrepareStreamImpl(internal::StreamSound * sound,const SoundArchive::SoundInfo * commonInfo,const SoundArchive::StreamSoundInfo * info,SoundStartable::StartInfo::StartOffsetType startOffsetType,int startOffset)1400 SoundStartable::StartResult SoundArchivePlayer::PrepareStreamImpl(
1401 internal::StreamSound* sound,
1402 const SoundArchive::SoundInfo* commonInfo,
1403 const SoundArchive::StreamSoundInfo* info,
1404 SoundStartable::StartInfo::StartOffsetType startOffsetType,
1405 int startOffset
1406 )
1407 {
1408 // プレイヤーのセットアップ
1409 #if 0
1410 internal::driver::StreamSoundPlayer::SetupResult setupResult = sound->Initialize(
1411 &m_StreamBufferPool,
1412 info->allocChannelCount,
1413 info->allocTrackCount
1414 );
1415
1416 while ( setupResult != internal::driver::StreamSoundPlayer::SETUP_SUCCESS )
1417 {
1418 if ( setupResult == internal::driver::StreamSoundPlayer::SETUP_ERR_CANNOT_ALLOCATE_BUFFER )
1419 {
1420 // バッファが足りない
1421 if ( m_StreamSoundInstanceManager.GetActiveCount() == 1 )
1422 {
1423 // ほかにサウンドを再生していないのにバッファが足りない
1424 NW_WARNING(
1425 ! internal::Debug_GetWarningFlag( DEBUG_WARNING_NOT_ENOUGH_SEQTRACK ),
1426 "Failed to start sound (id:%d) for not enough StrmChannel instance.",
1427 sound->GetId()
1428 );
1429 SoundStartable::StartResult result(
1430 SoundStartable::StartResult::START_ERR_NOT_ENOUGH_INSTANCE );
1431 return result;
1432 }
1433
1434 internal::StreamSound* lowest = m_StreamSoundInstanceManager.GetLowestPrioritySound();
1435 if ( sound == lowest )
1436 {
1437 // 自分が一番プライオリティが低い
1438 NW_WARNING(
1439 ! internal::Debug_GetWarningFlag( DEBUG_WARNING_NOT_ENOUGH_SEQTRACK ),
1440 "Failed to start sound (id:%d) for not enough StrmChannel instance.",
1441 sound->GetId()
1442 );
1443 SoundStartable::StartResult result(
1444 SoundStartable::StartResult::START_ERR_NOT_ENOUGH_INSTANCE );
1445 return result;
1446 }
1447
1448 // もう一度 Initialize
1449 NW_WARNING(
1450 ! internal::Debug_GetWarningFlag( DEBUG_WARNING_NOT_ENOUGH_STRMCHANNEL ),
1451 "Sound (id:%d) is stopped for not enough StrmChannel instance.",
1452 lowest->GetId()
1453 );
1454 lowest->Stop( 0 );
1455 setupResult = sound->Initialize(
1456 &m_StreamBufferPool,
1457 info->allocChannelCount,
1458 info->allocTrackCount
1459 );
1460 }
1461 else
1462 {
1463 SoundStartable::StartResult result(
1464 SoundStartable::StartResult::START_ERR_UNKNOWN );
1465 return result;
1466 }
1467 }
1468 #else
1469 // 再生失敗時のケア無し
1470
1471 sound->Setup(
1472 &m_StreamBufferPool,
1473 info->allocChannelCount,
1474 info->allocTrackCount
1475 );
1476 #endif
1477
1478 // プリペア
1479 internal::driver::StreamSoundPlayer::StartOffsetType strmStartOffsetType;
1480 switch ( startOffsetType )
1481 {
1482 case SoundStartable::StartInfo::START_OFFSET_TYPE_MILLISEC:
1483 strmStartOffsetType = internal::driver::StreamSoundPlayer::START_OFFSET_TYPE_MILLISEC;
1484 break;
1485 case SoundStartable::StartInfo::START_OFFSET_TYPE_TICK:
1486 strmStartOffsetType = internal::driver::StreamSoundPlayer::START_OFFSET_TYPE_SAMPLE;
1487 startOffset = 0;
1488 break;
1489 case SoundStartable::StartInfo::START_OFFSET_TYPE_SAMPLE:
1490 strmStartOffsetType = internal::driver::StreamSoundPlayer::START_OFFSET_TYPE_SAMPLE;
1491 break;
1492 default:
1493 strmStartOffsetType = internal::driver::StreamSoundPlayer::START_OFFSET_TYPE_SAMPLE;
1494 startOffset = 0;
1495 break;
1496 }
1497
1498 void* fileStreamBuffer = sound->GetFileStreamBuffer();
1499 NW_NULL_ASSERT( fileStreamBuffer );
1500 long fileStreamBufferSize = sound->GetFileStreamBufferSize();
1501 io::FileStream* fileStream =
1502 const_cast<SoundArchive*>(m_pSoundArchive)->detail_OpenFileStream(
1503 commonInfo->fileId,
1504 fileStreamBuffer,
1505 fileStreamBufferSize
1506 );
1507 if ( fileStream == NULL ) {
1508 SoundStartable::StartResult result(
1509 SoundStartable::StartResult::START_ERR_CANNOT_OPEN_FILE );
1510 return result;
1511 }
1512
1513 sound->Prepare(
1514 strmStartOffsetType,
1515 startOffset,
1516 fileStream
1517 );
1518
1519 // パラメータ設定
1520 UpdateCommonSoundParam( sound, commonInfo );
1521
1522 SoundStartable::StartResult startResult(
1523 SoundStartable::StartResult::START_SUCCESS );
1524 return startResult;
1525 }
1526
1527 /*---------------------------------------------------------------------------*
1528 Name: PrepareWaveSoundImpl
1529
1530 Description: ウェーブサウンドを再生
1531
1532 Arguments: playerId - プレイヤー番号
1533 bankId - バンク番号
1534 playerPrio - プレイヤープライオリティ
1535 info - シーケンス情報構造体のポインタ
1536 seqId - シーケンス番号
1537
1538 Returns: 成功したかどうか
1539 *---------------------------------------------------------------------------*/
PrepareWaveSoundImpl(internal::WaveSound * sound,const SoundArchive::SoundInfo * commonInfo,const SoundArchive::WaveSoundInfo * info,SoundStartable::StartInfo::StartOffsetType startOffsetType,int startOffset)1540 SoundStartable::StartResult SoundArchivePlayer::PrepareWaveSoundImpl(
1541 internal::WaveSound* sound,
1542 const SoundArchive::SoundInfo* commonInfo,
1543 const SoundArchive::WaveSoundInfo* info,
1544 SoundStartable::StartInfo::StartOffsetType startOffsetType,
1545 int startOffset
1546 )
1547 {
1548 NW_NULL_ASSERT( info );
1549
1550 // データの取得
1551 const void* wsdData = m_pSoundDataManager->detail_GetFileAddress( commonInfo->fileId );
1552 if ( wsdData == NULL ) {
1553 // return START_ERR_NOT_DATA_LOADED;
1554 // return START_ERR_NOT_WSD_LOADED;
1555 SoundStartable::StartResult result(
1556 SoundStartable::StartResult::START_ERR_NOT_WSD_LOADED );
1557 return result;
1558 }
1559
1560 internal::driver::WaveSoundPlayer::StartOffsetType wsdStartOffsetType;
1561 switch ( startOffsetType )
1562 {
1563 case SoundStartable::StartInfo::START_OFFSET_TYPE_MILLISEC:
1564 wsdStartOffsetType = internal::driver::WaveSoundPlayer::START_OFFSET_TYPE_MILLISEC;
1565 break;
1566 case SoundStartable::StartInfo::START_OFFSET_TYPE_TICK:
1567 wsdStartOffsetType = internal::driver::WaveSoundPlayer::START_OFFSET_TYPE_SAMPLE;
1568 startOffset = 0;
1569 break;
1570 case SoundStartable::StartInfo::START_OFFSET_TYPE_SAMPLE:
1571 wsdStartOffsetType = internal::driver::WaveSoundPlayer::START_OFFSET_TYPE_SAMPLE;
1572 break;
1573 default:
1574 wsdStartOffsetType = internal::driver::WaveSoundPlayer::START_OFFSET_TYPE_SAMPLE;
1575 startOffset = 0;
1576 break;
1577 }
1578
1579 // プリペア
1580 sound->Prepare(
1581 wsdData,
1582 info->index,
1583 wsdStartOffsetType,
1584 startOffset,
1585 &m_WaveSoundCallback,
1586 commonInfo->fileId
1587 );
1588
1589 // パラメータ設定
1590 UpdateCommonSoundParam( sound, commonInfo );
1591 sound->SetChannelPriority( info->channelPriority );
1592 sound->SetReleasePriorityFix( info->isReleasePriorityFix );
1593
1594 SoundStartable::StartResult startResult(
1595 SoundStartable::StartResult::START_SUCCESS );
1596 return startResult;
1597 }
1598
1599 /*---------------------------------------------------------------------------*
1600 Name: UpdateCommonSoundParam
1601
1602 Description: サウンド共通パラメータの更新
1603
1604 Arguments: sound - 更新対象のサウンド
1605 commonInfo - サウンド共通パラメータ
1606
1607 Returns: None.
1608 *---------------------------------------------------------------------------*/
UpdateCommonSoundParam(internal::BasicSound * sound,const SoundArchive::SoundInfo * commonInfo)1609 void SoundArchivePlayer::UpdateCommonSoundParam(
1610 internal::BasicSound* sound,
1611 const SoundArchive::SoundInfo* commonInfo
1612 )
1613 {
1614 NW_NULL_ASSERT(sound);
1615 NW_NULL_ASSERT(commonInfo);
1616
1617 sound->SetInitialVolume( static_cast<float>( commonInfo->volume ) / 127.0f );
1618 sound->SetPanMode( commonInfo->panMode );
1619 sound->SetPanCurve( commonInfo->panCurve );
1620 }
1621
1622
1623 /*---------------------------------------------------------------------------*
1624 Name: SetSequenceUserprocCallback
1625
1626 Description: シーケンスコマンド'userproc'で呼び出されるコールバックを登録する
1627
1628 Arguments: callback - コールバック
1629 arg - コールバック引数
1630
1631 Returns:
1632 *---------------------------------------------------------------------------*/
SetSequenceUserprocCallback(SequenceUserprocCallback callback,void * callbackArg)1633 void SoundArchivePlayer::SetSequenceUserprocCallback( SequenceUserprocCallback callback, void* callbackArg )
1634 {
1635 m_SequenceUserprocCallback = callback;
1636 m_pSequenceUserprocCallbackArg = callbackArg;
1637 }
1638
1639 /*---------------------------------------------------------------------------*
1640 Name: NoteOn
1641
1642 Description: シーケンスサウンドのノートオン処理
1643
1644 Arguments:
1645
1646 Returns: None.
1647 *---------------------------------------------------------------------------*/
NoteOn(internal::driver::SequenceSoundPlayer * seqPlayer,u8 bankIndex,const internal::driver::NoteOnInfo & noteOnInfo)1648 internal::driver::Channel* SoundArchivePlayer::SequenceNoteOnCallback::NoteOn(
1649 internal::driver::SequenceSoundPlayer* seqPlayer,
1650 u8 bankIndex,
1651 const internal::driver::NoteOnInfo& noteOnInfo
1652 )
1653 {
1654 if ( ! m_pSoundArchivePlayer.IsAvailable() ) return NULL;
1655
1656 const SoundArchive& sndArc = m_pSoundArchivePlayer.GetSoundArchive();
1657
1658 // 当該ノートに該当する波形アーカイブ ID・波形アーカイブ内インデックス取得
1659 const void* bankFile = seqPlayer->GetBankFile( bankIndex );
1660 internal::driver::Bank bank;
1661 internal::driver::Channel* channel = bank.NoteOn(
1662 bankFile,
1663 noteOnInfo,
1664 sndArc,
1665 m_pSoundArchivePlayer
1666 );
1667
1668 internal::driver::SoundThread::GetInstance().IncrNoteOnCount();
1669 return channel;
1670 }
1671
1672 /* ========================================================================
1673 SoundArchivePlayer::WaveSoundCallback class
1674 ======================================================================== */
1675
1676 /*---------------------------------------------------------------------------*
1677 Name: GetWaveSoundData
1678
1679 Description: ウェーブサウンドの波形取得処理
1680
1681 Arguments:
1682
1683 Returns: None.
1684 *---------------------------------------------------------------------------*/
GetWaveSoundData(internal::WaveSoundInfo * info,internal::WaveSoundNoteInfo * noteInfo,internal::WaveInfo * waveInfo,const void * waveSoundData,int index,int noteIndex,u32) const1685 bool SoundArchivePlayer::WaveSoundCallback::GetWaveSoundData(
1686 internal::WaveSoundInfo* info,
1687 internal::WaveSoundNoteInfo* noteInfo,
1688 internal::WaveInfo* waveInfo,
1689 const void* waveSoundData, // メモリに展開されたウェーブサウンドセットファイル
1690 int index, // ウェーブサウンドセットファイル内でのインデックス
1691 int noteIndex, // 現状ではつねにゼロ
1692 u32 // userData // SoundArchivePlayer::PrepareWaveSoundImpl にて fileId が入るが、
1693 // CTR では不要
1694 ) const
1695 {
1696 // const u32 fileID = userData;
1697
1698 if ( ! m_pSoundArchivePlayer.IsAvailable() ) {
1699 return false;
1700 }
1701
1702 // ウェーブサウンド情報および、ノート情報を取得
1703 {
1704 internal::WaveSoundFileReader reader( waveSoundData );
1705 if ( ! reader.ReadWaveSoundInfo( info, index ) )
1706 {
1707 return false;
1708 }
1709 if ( ! reader.ReadNoteInfo( noteInfo, index, noteIndex ) )
1710 {
1711 return false;
1712 }
1713 }
1714
1715 // 波形アーカイブ取得
1716 const SoundArchive& sndArc = m_pSoundArchivePlayer.GetSoundArchive();
1717 #if 0 // 不要? (Util::GetWaveFile で波形アーカイブのロード確認をしているので)
1718 {
1719 SoundArchive::WaveArchiveInfo warcInfo;
1720 if ( ! sndArc.ReadWaveArchiveInfo( noteInfo->waveArchiveId, &warcInfo ) )
1721 {
1722 return false;
1723 }
1724 const void* warcFile = m_pSoundArchivePlayer.detail_GetFileAddress( warcInfo.fileId );
1725 NW_WARNING( warcFile, "WSD failed - warc(%d) is not loaded", noteInfo->waveArchiveId );
1726 if ( warcFile == NULL )
1727 {
1728 return false;
1729 }
1730 }
1731 #endif
1732
1733 // 波形ファイル取得
1734 const void* waveFile = internal::Util::GetWaveFile(
1735 noteInfo->waveArchiveId, noteInfo->waveIndex,
1736 sndArc, m_pSoundArchivePlayer );
1737 if ( waveFile == NULL )
1738 {
1739 return false;
1740 }
1741
1742 // 波形ファイル情報取得
1743 {
1744 internal::WaveFileReader reader( waveFile );
1745 if ( ! reader.ReadWaveInfo( waveInfo ) )
1746 {
1747 return false;
1748 }
1749 }
1750
1751 return true;
1752 }
1753
1754 } // namespace nw::snd
1755 } // namespace nw
1756
1757