1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_SoundArchiveFile.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: 20997 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "precompiled.h"
17 #include <nw/snd/snd_SoundArchiveFile.h>
18 
19 #include <cstring>                          // std::strcmp
20 #include <nw/ut/ut_Inlines.h>               // ut::AddOffsetToPtr
21 #include <nw/snd/snd_ElementType.h>
22 #include <nw/snd/snd_ItemType.h>
23 
24 #include <nn/os.h>
25 
26 namespace nw {
27 namespace snd {
28 namespace internal {
29 
30 namespace
31 {
32 const u32       DEFAULT_STRING_ID               = SoundArchive::INVALID_ID;
33 const PanMode   DEFAULT_PAN_MODE                = PAN_MODE_DUAL;
34 const PanCurve  DEFAULT_PAN_CURVE               = PAN_CURVE_SQRT;
35 const u8        DEFAULT_PLAYER_PRIORITY         = 64;
36 const u8        DEFAULT_CHANNEL_PRIORITY        = 64;
37 const u8        DEFAULT_ACTOR_PLAYER_ID         = 0;
38 const u8        DEFAULT_IS_RELEASE_PRIORITY_FIX = 0;
39 const bool      DEFAULT_IS_FRONT_BYPASS         = false;
40 const u32       DEFAULT_USER_PARAM              = 0xffffffff;  // 無効値だとわかるように
41 const u32       DEFAULT_EXTRA_USER_PARAM_COUNT  = 0;
42 const u32       DEFAULT_SEQ_START_OFFSET        = 0;
43 const u32       DEFAULT_WARC_WAVE_COUNT         = 0;
44 const u32       DEFAULT_PLAYER_HEAP_SIZE        = 0;
45 
46 // optionParameter の各ビットの意味
47 enum SoundInfoBitFlag
48 {
49     SOUND_INFO_STRING_ID = 0x00,
50     SOUND_INFO_PAN_PARAM,           // u8 PanMode, u8 PanCurve
51     SOUND_INFO_PLAYER_PARAM,        // u8 PlayerPriority, u8 ActorPlayerId
52 
53     SOUND_INFO_OFFSET_TO_3D_PARAM = 0x08,
54     SOUND_INFO_OFFSET_TO_SEND_PARAM,
55     SOUND_INFO_OFFSET_TO_MOD_PARAM,
56 
57     SOUND_INFO_OFFSET_TO_RVL_PARAM = 0x10,
58     SOUND_INFO_OFFSET_TO_CTR_PARAM,
59 
60     SOUND_INFO_REFERENCE_TO_EXTRA_USER_PARAM_TABLE = 0x1e,
61     SOUND_INFO_USER_PARAM = 0x1f
62 };
63 
64 enum WaveSoundInfoBitFlag
65 {
66     WAVE_SOUND_INFO_PRIORITY = 0x00
67 };
68 
69 enum SequenceSoundInfoBitFlag
70 {
71     SEQ_SOUND_INFO_START_OFFSET = 0x00,
72     SEQ_SOUND_INFO_PRIORITY
73 };
74 
75 enum BankInfoBitFlag
76 {
77     BANK_INFO_STRING_ID = 0x00
78 };
79 
80 enum PlayerInfoBitFlag
81 {
82     PLAYER_INFO_STRING_ID = 0x00,
83     PLAYER_INFO_HEAP_SIZE               // プレイヤーヒープサイズ
84 };
85 
86 enum SoundGroupInfoBitFlag
87 {
88     SOUND_GROUP_INFO_STRING_ID = 0x00
89 };
90 
91 enum GroupInfoBitFlag
92 {
93     GROUP_INFO_STRING_ID = 0x00
94 };
95 
96 enum WaveArchiveInfoBitFlag
97 {
98     WAVE_ARCHIVE_INFO_STRING_ID = 0x00,
99     WAVE_ARCHIVE_INFO_WAVE_COUNT
100 };
101 
GetItemTypeEnum(u32 id)102 ItemType GetItemTypeEnum( u32 id )
103 {
104     return static_cast<ItemType>( Util::GetItemType(id) );
105 }
106 } // anonymous namespace
107 
108 //
109 // SoundArchiveFile::FileHeader
110 //
111 const Util::ReferenceWithSize*
GetReferenceBy(u16 typeId) const112 SoundArchiveFile::FileHeader::GetReferenceBy( u16 typeId ) const
113 {
114     for ( int i = 0; i < BLOCK_SIZE; i++ )
115     {
116         if ( toBlocks[ i ].typeId == typeId )
117         {
118             return &toBlocks[ i ];
119         }
120     }
121     return NULL;
122 }
123 
124 #if 0
125 const SoundArchiveFile::StringBlock*
126 SoundArchiveFile::FileHeader::GetStringBlock() const
127 {
128     // return reinterpret_cast<const StringBlock*>( GetBlock( SoundArchiveFile_StringBlock ) );
129     return NULL;
130 }
131 
132 const SoundArchiveFile::InfoBlock*
133 SoundArchiveFile::FileHeader::GetInfoBlock() const
134 {
135     // return reinterpret_cast<const InfoBlock*>( GetBlock( SoundArchiveFile_InfoBlock ) );
136     return NULL;
137 }
138 
139 const SoundArchiveFile::FileBlock*
140 SoundArchiveFile::FileHeader::GetFileBlock() const
141 {
142     // return reinterpret_cast<const FileBlock*>( GetBlock( SoundArchiveFile_FileBlock ) );
143     return NULL;
144 }
145 #endif
146 
147 // ブロックサイズの取得
GetStringBlockSize() const148 u32 SoundArchiveFile::FileHeader::GetStringBlockSize() const
149 {
150     return GetReferenceBy( ElementType_SoundArchiveFile_StringBlock )->size;
151 }
GetInfoBlockSize() const152 u32 SoundArchiveFile::FileHeader::GetInfoBlockSize() const
153 {
154     return GetReferenceBy( ElementType_SoundArchiveFile_InfoBlock )->size;
155 }
GetFileBlockSize() const156 u32 SoundArchiveFile::FileHeader::GetFileBlockSize() const
157 {
158     return GetReferenceBy( ElementType_SoundArchiveFile_FileBlock )->size;
159 }
160 
161 // ブロックへのオフセットの取得
GetStringBlockOffset() const162 s32 SoundArchiveFile::FileHeader::GetStringBlockOffset() const
163 {
164     return GetReferenceBy( ElementType_SoundArchiveFile_StringBlock )->offset;
165 }
GetInfoBlockOffset() const166 s32 SoundArchiveFile::FileHeader::GetInfoBlockOffset() const
167 {
168     return GetReferenceBy( ElementType_SoundArchiveFile_InfoBlock )->offset;
169 }
GetFileBlockOffset() const170 s32 SoundArchiveFile::FileHeader::GetFileBlockOffset() const
171 {
172     return GetReferenceBy( ElementType_SoundArchiveFile_FileBlock )->offset;
173 }
174 
175 //
176 // SoundArchiveFile::StringBlock
177 //
178 const void*
GetSection(Sections section) const179 SoundArchiveFile::StringBlockBody::GetSection( Sections section ) const
180 {
181     if ( section > Sections_Max ) return NULL;
182     return ut::AddOffsetToPtr( this, toSection[section].offset );
183 }
184 
185 const char*
GetString(SoundArchive::ItemId stringId) const186 SoundArchiveFile::StringBlockBody::GetString( SoundArchive::ItemId stringId ) const
187 {
188     if ( stringId == SoundArchive::INVALID_ID )
189     {
190         return NULL;
191     }
192     const StringTable* table = GetStringTable();
193     if ( table == NULL ) return NULL;
194 
195     return table->GetString( stringId );
196 }
197 
GetItemIdImpl(Sections section,const char * str) const198 u32 SoundArchiveFile::StringBlockBody::GetItemIdImpl(
199         Sections section, const char* str ) const
200 {
201     const PatriciaTree* tree = GetPatriciaTree( section );
202     const PatriciaTree::NodeData* nodeData = tree->GetNodeDataBy( str );
203     if ( nodeData == NULL )
204     {
205         return SoundArchive::INVALID_ID;
206     }
207     if ( std::strcmp( str, GetString( nodeData->stringId ) ) == 0 )
208     {
209         return nodeData->itemId;
210     }
211     return SoundArchive::INVALID_ID;
212 }
213 
DumpTree() const214 void SoundArchiveFile::StringBlockBody::DumpTree() const
215 {
216     for ( int section = Sections_PatriciaTree; section <= Sections_Max; section++ )
217     {
218         const PatriciaTree* tree = GetPatriciaTree( (Sections)section );
219 
220         NN_LOG("Section[%d] rootIdx(%d) count(%d)\n",
221                 section, tree->rootIdx, tree->nodeTable.count );
222         for ( u32 i = 0; i < tree->nodeTable.count; i++ )
223         {
224             const PatriciaTree::Node* node = &tree->nodeTable.item[i];
225             const PatriciaTree::NodeData* data = &node->nodeData;
226             NN_LOG("  idx(%4d) str(%4d) itemId(0x%08X) left(%4d) right(%4d)\n",
227                     i, data->stringId, data->itemId,
228                     node->leftIdx, node->rightIdx );
229         }
230     }
231 }
232 
233 const SoundArchiveFile::PatriciaTree::NodeData*
GetNodeDataBy(const char * str,std::size_t len) const234 SoundArchiveFile::PatriciaTree::GetNodeDataBy( const char* str, std::size_t len ) const
235 {
236     if ( rootIdx >= nodeTable.count )
237     {
238         return NULL;
239     }
240 
241     const Node* node = &nodeTable.item[ rootIdx ];
242     if ( len == 0 )
243     {
244         len = std::strlen( str );    // TODO: strnlen ?
245     }
246 
247     while( ( node->flags & Node::FLAG_LEAF ) == 0 )
248     {
249         const int pos = ( node->bit >> 3 );
250         const int bit = ( node->bit & 7 );
251         u32 nodeIdx;
252         if ( pos < static_cast<int>(len) && str[pos] & ( 1 << ( 7 - bit ) ) )
253         {
254             nodeIdx = node->rightIdx;
255         }
256         else
257         {
258             nodeIdx = node->leftIdx;
259         }
260         node = &nodeTable.item[ nodeIdx ];
261     }
262     return &node->nodeData;
263 }
264 
265 
266 //
267 // SoundArchiveFile::InfoBlockBody
268 //
269 const SoundArchiveFile::SoundInfo*
GetSoundInfo(SoundArchive::ItemId itemId) const270 SoundArchiveFile::InfoBlockBody::GetSoundInfo( SoundArchive::ItemId itemId ) const
271 {
272     if ( GetItemTypeEnum( itemId ) != ItemType_Sound )
273     {
274         return NULL;
275     }
276 
277     u32 index = Util::GetItemIndex( itemId );
278     const Util::ReferenceTable& table = GetSoundInfoReferenceTable();
279     if ( index >= table.count )
280     {
281         return NULL;
282     }
283     return reinterpret_cast<const SoundInfo*>( table.GetReferedItem( index ) );
284 }
285 
286 const SoundArchiveFile::BankInfo*
GetBankInfo(SoundArchive::ItemId itemId) const287 SoundArchiveFile::InfoBlockBody::GetBankInfo( SoundArchive::ItemId itemId ) const
288 {
289     if ( GetItemTypeEnum( itemId ) != ItemType_Bank )
290     {
291         return NULL;
292     }
293 
294     u32 index = Util::GetItemIndex( itemId );
295     const Util::ReferenceTable& table = GetBankInfoReferenceTable();
296     if ( index >= table.count )
297     {
298         return NULL;
299     }
300     return reinterpret_cast<const BankInfo*>( table.GetReferedItem( index ) );
301 }
302 
303 const SoundArchiveFile::PlayerInfo*
GetPlayerInfo(SoundArchive::ItemId itemId) const304 SoundArchiveFile::InfoBlockBody::GetPlayerInfo( SoundArchive::ItemId itemId ) const
305 {
306     if ( GetItemTypeEnum( itemId ) != ItemType_Player )
307     {
308         return NULL;
309     }
310 
311     u32 index = Util::GetItemIndex( itemId );
312     const Util::ReferenceTable& table = GetPlayerInfoReferenceTable();
313     if ( index >= table.count )
314     {
315         return NULL;
316     }
317     return reinterpret_cast<const PlayerInfo*>( table.GetReferedItem( index ) );
318 }
319 
320 const SoundArchiveFile::SoundGroupInfo*
GetSoundGroupInfo(SoundArchive::ItemId itemId) const321 SoundArchiveFile::InfoBlockBody::GetSoundGroupInfo( SoundArchive::ItemId itemId ) const
322 {
323     if ( GetItemTypeEnum( itemId ) != ItemType_SoundGroup )
324     {
325         return NULL;
326     }
327 
328     u32 index = Util::GetItemIndex( itemId );
329     const Util::ReferenceTable& table = GetSoundGroupInfoReferenceTable();
330     if ( index >= table.count )
331     {
332         return NULL;
333     }
334     return reinterpret_cast<const SoundGroupInfo*>( table.GetReferedItem( index ) );
335 }
336 
337 const SoundArchiveFile::GroupInfo*
GetGroupInfo(SoundArchive::ItemId itemId) const338 SoundArchiveFile::InfoBlockBody::GetGroupInfo( SoundArchive::ItemId itemId ) const
339 {
340     if ( GetItemTypeEnum( itemId ) != ItemType_Group )
341     {
342         return NULL;
343     }
344 
345     u32 index = Util::GetItemIndex( itemId );
346     const Util::ReferenceTable& table = GetGroupInfoReferenceTable();
347     if ( index >= table.count )
348     {
349         return NULL;
350     }
351     return reinterpret_cast<const GroupInfo*>( table.GetReferedItem( index ) );
352 }
353 
354 const SoundArchiveFile::WaveArchiveInfo*
GetWaveArchiveInfo(SoundArchive::ItemId itemId) const355 SoundArchiveFile::InfoBlockBody::GetWaveArchiveInfo( SoundArchive::ItemId itemId ) const
356 {
357     if ( GetItemTypeEnum( itemId ) != ItemType_WaveArchive )
358     {
359         return NULL;
360     }
361 
362     u32 index = Util::GetItemIndex( itemId );
363     const Util::ReferenceTable& table = GetWaveArchiveInfoReferenceTable();
364     if ( index >= table.count )
365     {
366         return NULL;
367     }
368     return reinterpret_cast<const WaveArchiveInfo*>( table.GetReferedItem( index ) );
369 }
370 
371 const SoundArchiveFile::FileInfo*
GetFileInfo(SoundArchive::FileId itemId) const372 SoundArchiveFile::InfoBlockBody::GetFileInfo( SoundArchive::FileId itemId ) const
373 {
374     u32 index = Util::GetItemIndex( itemId );
375     const Util::ReferenceTable& table = GetFileInfoReferenceTable();
376     if ( index >= table.count )
377     {
378         return NULL;
379     }
380     return reinterpret_cast<const FileInfo*>( table.GetReferedItem( index ) );
381 }
382 
383 SoundArchive::FileId
GetItemFileId(SoundArchive::ItemId id) const384 SoundArchiveFile::InfoBlockBody::GetItemFileId( SoundArchive::ItemId id ) const
385 {
386     SoundArchive::FileId fileId = SoundArchive::INVALID_ID;
387 
388     switch ( Util::GetItemType( id ) )
389     {
390     case ItemType_Sound:
391         {
392             const SoundInfo* info = GetSoundInfo( id );
393             if ( info != NULL )
394             {
395                 fileId = info->fileId;
396             }
397         }
398         break;
399     case ItemType_Bank:
400         {
401             const BankInfo* info = GetBankInfo( id );
402             if ( info != NULL )
403             {
404                 fileId = info->fileId;
405             }
406         }
407         break;
408     case ItemType_WaveArchive:
409         {
410             const WaveArchiveInfo* info = GetWaveArchiveInfo( id );
411             if ( info != NULL )
412             {
413                 fileId = info->fileId;
414             }
415         }
416         break;
417     case ItemType_Group:
418         {
419             const GroupInfo* info = GetGroupInfo( id );
420             if ( info != NULL )
421             {
422                 fileId = info->fileId;
423             }
424         }
425         break;
426     case ItemType_SoundGroup:
427         // 複数個の FileId を持つことがあるため、別関数を使う必要がある。
428         break;
429     case ItemType_Player:
430         // ファイル ID は無い
431         break;
432     }
433 
434     return fileId;
435 }
436 
437 SoundArchive::StringId
GetItemStringId(SoundArchive::ItemId id) const438 SoundArchiveFile::InfoBlockBody::GetItemStringId( SoundArchive::ItemId id ) const
439 {
440     SoundArchive::FileId stringId = SoundArchive::INVALID_ID;
441 
442     switch ( Util::GetItemType( id ) )
443     {
444     case ItemType_Sound:
445         {
446             const SoundInfo* info = GetSoundInfo( id );
447             if ( info != NULL )
448             {
449                 stringId = info->GetStringId();
450             }
451         }
452         break;
453     case ItemType_Bank:
454         {
455             const BankInfo* info = GetBankInfo( id );
456             if ( info != NULL )
457             {
458                 stringId = info->GetStringId();
459             }
460         }
461         break;
462     case ItemType_WaveArchive:
463         {
464             const WaveArchiveInfo* info = GetWaveArchiveInfo( id );
465             if ( info != NULL )
466             {
467                 stringId = info->GetStringId();
468             }
469         }
470         break;
471     case ItemType_SoundGroup:
472         {
473             const SoundGroupInfo* info = GetSoundGroupInfo( id );
474             if ( info != NULL )
475             {
476                 stringId = info->GetStringId();
477             }
478         }
479         break;
480     case ItemType_Group:
481         {
482             const GroupInfo* info = GetGroupInfo( id );
483             if ( info != NULL )
484             {
485                 stringId = info->GetStringId();
486             }
487         }
488         break;
489     case ItemType_Player:
490         {
491             const PlayerInfo* info = GetPlayerInfo( id );
492             if ( info != NULL )
493             {
494                 stringId = info->GetStringId();
495             }
496         }
497         break;
498     }
499 
500     return stringId;
501 }
502 
503 const SoundArchiveFile::SoundArchivePlayerInfo*
GetSoundArchivePlayerInfo() const504 SoundArchiveFile::InfoBlockBody::GetSoundArchivePlayerInfo() const
505 {
506     return reinterpret_cast<const SoundArchivePlayerInfo*>(
507             ut::AddOffsetToPtr( this, toSoundArchivePlayerInfo.offset ) );
508 }
509 
510 
511 const Util::ReferenceTable&
GetSoundInfoReferenceTable() const512 SoundArchiveFile::InfoBlockBody::GetSoundInfoReferenceTable() const
513 {
514     return *reinterpret_cast<const Util::ReferenceTable*>(
515             ut::AddOffsetToPtr( this, toSoundInfoReferenceTable.offset ) );
516 }
517 
518 const Util::ReferenceTable&
GetBankInfoReferenceTable() const519 SoundArchiveFile::InfoBlockBody::GetBankInfoReferenceTable() const
520 {
521     return *reinterpret_cast<const Util::ReferenceTable*>(
522             ut::AddOffsetToPtr( this, toBankInfoReferenceTable.offset ) );
523 }
524 
525 const Util::ReferenceTable&
GetPlayerInfoReferenceTable() const526 SoundArchiveFile::InfoBlockBody::GetPlayerInfoReferenceTable() const
527 {
528     return *reinterpret_cast<const Util::ReferenceTable*>(
529             ut::AddOffsetToPtr( this, toPlayerInfoReferenceTable.offset ) );
530 }
531 
532 const Util::ReferenceTable&
GetSoundGroupInfoReferenceTable() const533 SoundArchiveFile::InfoBlockBody::GetSoundGroupInfoReferenceTable() const
534 {
535     return *reinterpret_cast<const Util::ReferenceTable*>(
536             ut::AddOffsetToPtr( this, toSoundGroupInfoReferenceTable.offset ) );
537 }
538 
539 const Util::ReferenceTable&
GetGroupInfoReferenceTable() const540 SoundArchiveFile::InfoBlockBody::GetGroupInfoReferenceTable() const
541 {
542     return *reinterpret_cast<const Util::ReferenceTable*>(
543             ut::AddOffsetToPtr( this, toGroupInfoReferenceTable.offset ) );
544 }
545 
546 const Util::ReferenceTable&
GetWaveArchiveInfoReferenceTable() const547 SoundArchiveFile::InfoBlockBody::GetWaveArchiveInfoReferenceTable() const
548 {
549     return *reinterpret_cast<const Util::ReferenceTable*>(
550             ut::AddOffsetToPtr( this, toWaveArchiveInfoReferenceTable.offset ) );
551 }
552 
553 const Util::ReferenceTable&
GetFileInfoReferenceTable() const554 SoundArchiveFile::InfoBlockBody::GetFileInfoReferenceTable() const
555 {
556     return *reinterpret_cast<const Util::ReferenceTable*>(
557             ut::AddOffsetToPtr( this, toFileInfoReferenceTable.offset ) );
558 }
559 
560 
561 //
562 // SoundArchiveFile::SoundInfo
563 //
564 
GetSoundType() const565 SoundArchive::SoundType SoundArchiveFile::SoundInfo::GetSoundType() const
566 {
567     switch ( toDetailSoundInfo.typeId )
568     {
569     case ElementType_SoundArchiveFile_StreamSoundInfo:
570         return SoundArchive::SOUND_TYPE_STRM;
571     case ElementType_SoundArchiveFile_WaveSoundInfo:
572         return SoundArchive::SOUND_TYPE_WAVE;
573     case ElementType_SoundArchiveFile_SequenceSoundInfo:
574         return SoundArchive::SOUND_TYPE_SEQ;
575     default:
576         return SoundArchive::SOUND_TYPE_INVALID;
577     }
578 }
579 
580 const SoundArchiveFile::StreamSoundInfo&
GetStreamSoundInfo() const581 SoundArchiveFile::SoundInfo::GetStreamSoundInfo() const
582 {
583     NW_ASSERT( toDetailSoundInfo.typeId ==
584             ElementType_SoundArchiveFile_StreamSoundInfo );
585 
586     return *reinterpret_cast<const StreamSoundInfo*>(
587             ut::AddOffsetToPtr( this, toDetailSoundInfo.offset ) );
588 }
589 
590 const SoundArchiveFile::WaveSoundInfo&
GetWaveSoundInfo() const591 SoundArchiveFile::SoundInfo::GetWaveSoundInfo() const
592 {
593     NW_ASSERT( toDetailSoundInfo.typeId ==
594             ElementType_SoundArchiveFile_WaveSoundInfo );
595 
596     return *reinterpret_cast<const WaveSoundInfo*>(
597             ut::AddOffsetToPtr( this, toDetailSoundInfo.offset ) );
598 }
599 
600 const SoundArchiveFile::SequenceSoundInfo&
GetSequenceSoundInfo() const601 SoundArchiveFile::SoundInfo::GetSequenceSoundInfo() const
602 {
603     NW_ASSERT( toDetailSoundInfo.typeId ==
604             ElementType_SoundArchiveFile_SequenceSoundInfo );
605 
606     return *reinterpret_cast<const SequenceSoundInfo*>(
607             ut::AddOffsetToPtr( this, toDetailSoundInfo.offset ) );
608 }
609 
610 const SoundArchiveFile::Sound3DInfo*
GetSound3DInfo() const611 SoundArchiveFile::SoundInfo::GetSound3DInfo() const
612 {
613     u32 offset;
614     bool result = optionParameter.GetValue( &offset, SOUND_INFO_OFFSET_TO_3D_PARAM );
615     if ( result == false )
616     {
617         return NULL;    // 3D パラメータが省かれている (格納されていない)
618     }
619 
620     return reinterpret_cast<const Sound3DInfo*>(
621             ut::AddOffsetToPtr( this, offset ) );
622 }
623 
GetStringId() const624 u32 SoundArchiveFile::SoundInfo::GetStringId() const
625 {
626     u32 value;
627     bool result = optionParameter.GetValue( &value, SOUND_INFO_STRING_ID );
628     if ( result == false )
629     {
630         return DEFAULT_STRING_ID;
631     }
632     return value;
633 }
634 
GetPanMode() const635 PanMode SoundArchiveFile::SoundInfo::GetPanMode() const
636 {
637     u32 value;
638     bool result = optionParameter.GetValue( &value, SOUND_INFO_PAN_PARAM );
639     if ( result == false )
640     {
641         return DEFAULT_PAN_MODE;
642     }
643     return static_cast<PanMode>( Util::DevideBy8bit( value, 0 ) );
644 }
645 
GetPanCurve() const646 PanCurve SoundArchiveFile::SoundInfo::GetPanCurve() const
647 {
648     u32 value;
649     bool result = optionParameter.GetValue( &value, SOUND_INFO_PAN_PARAM );
650     if ( result == false )
651     {
652         return DEFAULT_PAN_CURVE;
653     }
654     return static_cast<PanCurve>( Util::DevideBy8bit( value, 1 ) );
655 }
656 
GetPlayerPriority() const657 u8 SoundArchiveFile::SoundInfo::GetPlayerPriority() const
658 {
659     u32 value;
660     bool result = optionParameter.GetValue( &value, SOUND_INFO_PLAYER_PARAM );
661     if ( result == false )
662     {
663         return DEFAULT_PLAYER_PRIORITY;
664     }
665     return Util::DevideBy8bit( value, 0 );
666 }
667 
GetActorPlayerId() const668 u8 SoundArchiveFile::SoundInfo::GetActorPlayerId() const
669 {
670     u32 value;
671     bool result = optionParameter.GetValue( &value, SOUND_INFO_PLAYER_PARAM );
672     if ( result == false )
673     {
674         return DEFAULT_ACTOR_PLAYER_ID;
675     }
676     return Util::DevideBy8bit( value, 1 );
677 }
678 
GetUserParam() const679 u32 SoundArchiveFile::SoundInfo::GetUserParam() const
680 {
681     u32 value;
682     bool result = optionParameter.GetValue( &value, SOUND_INFO_USER_PARAM );
683     if ( result == false )
684     {
685         return DEFAULT_USER_PARAM;
686     }
687     return value;
688 }
IsFrontBypass() const689 bool SoundArchiveFile::SoundInfo::IsFrontBypass() const
690 {
691     u32 value;
692     bool result = optionParameter.GetValue( &value, SOUND_INFO_OFFSET_TO_CTR_PARAM );
693     if ( result == false )
694     {
695         return DEFAULT_IS_FRONT_BYPASS;
696     }
697     return ( value & ( 1 << 0 ) );
698 }
699 
700 #if 0
701 u32 SoundArchiveFile::SoundInfo::GetUserExtraParamCount()
702 {
703     u32 value = optionParameter.GetValue( SOUND_INFO_REFERENCE_TO_EXTRA_USER_PARAM_TABLE );
704     if ( value == 0 )
705     {
706         return DEFAULT_EXTRA_USER_PARAM_COUNT;
707     }
708     return value;
709 }
710 
711 u32 SoundArchiveFile::SoundInfo::GetUserExtraParam( int index )
712 {
713     u32 value = optionParameter.GetValue( SOUND_INFO_REFERENCE_TO_EXTRA_USER_PARAM_TABLE );
714     if ( value == 0 )
715     {
716         return DEFAULT_USER_PARAM;
717     }
718     // value 先のアドレスに、値が書かれている?
719 }
720 #endif
721 
722 
723 //
724 // SoundArchiveFile::WaveSoundInfo
725 //
726 
GetChannelPriority() const727 u8 SoundArchiveFile::WaveSoundInfo::GetChannelPriority() const
728 {
729     u32 value;
730     bool result = optionParameter.GetValue( &value, WAVE_SOUND_INFO_PRIORITY );
731     if ( result == false )
732     {
733         return DEFAULT_CHANNEL_PRIORITY;
734     }
735     return Util::DevideBy8bit( value, 0 );
736 }
737 
GetIsReleasePriorityFix() const738 u8 SoundArchiveFile::WaveSoundInfo::GetIsReleasePriorityFix() const
739 {
740     u32 value;
741     bool result = optionParameter.GetValue( &value, WAVE_SOUND_INFO_PRIORITY );
742     if ( result == false )
743     {
744         return DEFAULT_IS_RELEASE_PRIORITY_FIX;
745     }
746     return Util::DevideBy8bit( value, 1 );
747 }
748 
749 
750 //
751 // SoundArchiveFile::SequenceSoundInfo
752 //
753 const Util::Table<ut::ResU32>&
GetBankIdTable() const754 SoundArchiveFile::SequenceSoundInfo::GetBankIdTable() const
755 {
756     return *reinterpret_cast<const Util::Table<ut::ResU32>*>(
757             ut::AddOffsetToPtr( this, toBankIdTable.offset ) );
758 }
GetBankIds(u32 * bankIds) const759 void SoundArchiveFile::SequenceSoundInfo::GetBankIds( u32* bankIds ) const
760 {
761     const Util::Table<ut::ResU32>& table = GetBankIdTable();
762     for ( u32 i = 0; i < SoundArchive::SEQ_BANK_MAX; i++ )
763     {
764         if ( i >= table.count )
765         {
766             bankIds[ i ] = SoundArchive::INVALID_ID;
767         }
768         else
769         {
770             bankIds[ i ] = table.item[ i ];
771         }
772     }
773 }
GetStartOffset() const774 u32 SoundArchiveFile::SequenceSoundInfo::GetStartOffset() const
775 {
776     u32 value;
777     bool result = optionParameter.GetValue( &value, SEQ_SOUND_INFO_START_OFFSET );
778     if ( result == false )
779     {
780         return DEFAULT_SEQ_START_OFFSET;
781     }
782     return value;
783 }
GetChannelPriority() const784 u8 SoundArchiveFile::SequenceSoundInfo::GetChannelPriority() const
785 {
786     u32 value;
787     bool result = optionParameter.GetValue( &value, SEQ_SOUND_INFO_PRIORITY );
788     if ( result == false )
789     {
790         return DEFAULT_CHANNEL_PRIORITY;
791     }
792     return Util::DevideBy8bit( value, 0 );
793 }
IsReleasePriorityFix() const794 bool SoundArchiveFile::SequenceSoundInfo::IsReleasePriorityFix() const
795 {
796     u32 value;
797     bool result = optionParameter.GetValue( &value, SEQ_SOUND_INFO_PRIORITY );
798     if ( result == false )
799     {
800         return DEFAULT_CHANNEL_PRIORITY;
801     }
802     if ( Util::DevideBy8bit( value, 1 ) > 0 ) return true;
803     return false;
804 }
805 
806 //
807 // SoundArchiveFile::BankInfo
808 //
GetStringId() const809 u32 SoundArchiveFile::BankInfo::GetStringId() const
810 {
811     u32 value;
812     bool result = optionParameter.GetValue( &value, BANK_INFO_STRING_ID );
813     if ( result == false )
814     {
815         return DEFAULT_STRING_ID;
816     }
817     return value;
818 }
819 
820 //
821 // SoundArchiveFile::PlayerInfo
822 //
GetStringId() const823 u32 SoundArchiveFile::PlayerInfo::GetStringId() const
824 {
825     u32 value;
826     bool result = optionParameter.GetValue( &value, PLAYER_INFO_STRING_ID );
827     if ( result == false )
828     {
829         return DEFAULT_STRING_ID;
830     }
831     return value;
832 }
GetPlayerHeapSize() const833 u32 SoundArchiveFile::PlayerInfo::GetPlayerHeapSize() const
834 {
835     u32 value;
836     bool result = optionParameter.GetValue( &value, PLAYER_INFO_HEAP_SIZE );
837     if ( result == false )
838     {
839         return DEFAULT_PLAYER_HEAP_SIZE;
840     }
841     return value;
842 }
843 
844 //
845 // SoundArchiveFile::SoundGroupInfo
846 //
GetStringId() const847 u32 SoundArchiveFile::SoundGroupInfo::GetStringId() const
848 {
849     u32 value;
850     bool result = optionParameter.GetValue( &value, SOUND_GROUP_INFO_STRING_ID );
851     if ( result == false )
852     {
853         return DEFAULT_STRING_ID;
854     }
855     return value;
856 }
857 
858 //
859 // SoundArchiveFile::GroupInfo
860 //
GetStringId() const861 u32 SoundArchiveFile::GroupInfo::GetStringId() const
862 {
863     u32 value;
864     bool result = optionParameter.GetValue( &value, GROUP_INFO_STRING_ID );
865     if ( result == false )
866     {
867         return DEFAULT_STRING_ID;
868     }
869     return value;
870 }
871 
872 //
873 // SoundArchiveFile::WaveArchiveInfo
874 //
GetStringId() const875 u32 SoundArchiveFile::WaveArchiveInfo::GetStringId() const
876 {
877     u32 value;
878     bool result = optionParameter.GetValue( &value, WAVE_ARCHIVE_INFO_STRING_ID );
879     if ( result == false )
880     {
881         return DEFAULT_STRING_ID;
882     }
883     return value;
884 }
GetWaveCount() const885 u32 SoundArchiveFile::WaveArchiveInfo::GetWaveCount() const
886 {
887     u32 value;
888     bool result = optionParameter.GetValue( &value, WAVE_ARCHIVE_INFO_WAVE_COUNT );
889     if ( result == false )
890     {
891         return DEFAULT_WARC_WAVE_COUNT;
892     }
893     return value;
894 }
895 
896 //
897 // SoundArchiveFile::FileInfo
898 //
899 
GetFileLocationType() const900 SoundArchiveFile::FileLocationType SoundArchiveFile::FileInfo::GetFileLocationType() const
901 {
902     switch ( toFileLocation.typeId )
903     {
904     case ElementType_SoundArchiveFile_InternalFileInfo:
905         return FILE_LOCATION_TYPE_INTERNAL;
906     case ElementType_SoundArchiveFile_ExternalFileInfo:
907         return FILE_LOCATION_TYPE_EXTERNAL;
908     case 0:
909         return FILE_LOCATION_TYPE_NONE;
910     default:
911         NW_ASSERTMSG( false, "invalid file location type");
912         return FILE_LOCATION_TYPE_NONE;
913     }
914 }
915 
916 const SoundArchiveFile::InternalFileInfo*
GetInternalFileInfo() const917 SoundArchiveFile::FileInfo::GetInternalFileInfo() const
918 {
919     if ( GetFileLocationType() != FILE_LOCATION_TYPE_INTERNAL )
920     {
921         return NULL;
922     }
923 
924     return reinterpret_cast<const InternalFileInfo*>(
925             ut::AddOffsetToPtr( this, toFileLocation.offset ) );
926 }
927 
928 const SoundArchiveFile::ExternalFileInfo*
GetExternalFileInfo() const929 SoundArchiveFile::FileInfo::GetExternalFileInfo() const
930 {
931     if ( GetFileLocationType() != FILE_LOCATION_TYPE_EXTERNAL )
932     {
933         return NULL;
934     }
935 
936     return reinterpret_cast<const ExternalFileInfo*>(
937             ut::AddOffsetToPtr( this, toFileLocation.offset ) );
938 }
939 
940 #if 0
941 const void*
942 SoundArchiveFile::FileInfo::GetFileAddress( const void* dataBlockBodyAddress ) const
943 {
944     // TODO: toFileImage.typeId には、
945     //  (1) FILE ブロックに入っていることを示す ID ((* この関数で扱う *))
946     //  (2) 外部ファイルパスを示す ID [サウンドアーカイブファイル外]
947     //  (3) 「グループ埋め込みファイル」テーブルを示す ID がありえる。
948     //
949     //  1-3 のうち、1/2/3 とも同時に存在しうる。
950     //  ([1,3] と [2] は、同時に存在しない気もする。同時に存在する意味がないから。 )
951     //
952     //  TODO としては、typeId で 1 でないなら、この関数は NULL を返す必要がある
953     return reinterpret_cast<const void*>(
954             ut::AddOffsetToPtr( dataBlockBodyAddress, toFileImage.offset ) );
955 }
956 #endif
957 
958 } // namespace nw::snd::internal
959 } // namespace nw::snd
960 } // namespace nw
961