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