1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: snd_SoundArchiveFile.h 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: 27990 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NW_SND_SOUND_ARCHIVE_FILE_H_ 17 #define NW_SND_SOUND_ARCHIVE_FILE_H_ 18 19 #include <nw/ut/ut_BinaryFileFormat.h> // ut::BinaryFileHeader など 20 #include <nw/snd/snd_Util.h> // ReferenceWithSize など 21 #include <nw/snd/snd_Global.h> // PanMode など 22 #include <nw/snd/snd_SoundArchive.h> 23 #include <nw/snd/snd_ElementType.h> 24 25 namespace nw { 26 namespace snd { 27 namespace internal { 28 29 struct SoundArchiveFile 30 { 31 // ------------------------------------------------------------------------ 32 // ファイルヘッダー 33 34 // 前方宣言 35 struct StringBlock; 36 struct InfoBlock; 37 struct FileBlock; 38 39 // 定数 40 static const int BLOCK_SIZE = 3; 41 42 // メモ : SoundArchiveFile::FileHeader はヘッダだけ個別にロードするので、 43 // Util::SoundFileHeader を継承できない。 44 struct FileHeader : public ut::BinaryFileHeader 45 { 46 Util::ReferenceWithSize toBlocks[ BLOCK_SIZE ]; 47 48 #if 0 49 // ファイルを全ロードした場合 50 const StringBlock* GetStringBlock() const; 51 const InfoBlock* GetInfoBlock() const; 52 const FileBlock* GetFileBlock() const; 53 #endif 54 55 // 各ブロックのサイズ 56 u32 GetStringBlockSize() const; 57 u32 GetInfoBlockSize() const; 58 u32 GetFileBlockSize() const; 59 60 // 各ブロックのオフセット 61 s32 GetStringBlockOffset() const; 62 s32 GetInfoBlockOffset() const; 63 s32 GetFileBlockOffset() const; 64 65 private: 66 const Util::ReferenceWithSize* GetReferenceBy( u16 typeId ) const; 67 }; 68 69 70 // ------------------------------------------------------------------------ 71 // 文字列ブロック 72 73 struct StringTable; 74 struct PatriciaTree; 75 struct StringBlockBody 76 { 77 private: 78 enum Sections 79 { 80 Sections_StringTable, 81 Sections_PatriciaTree, 82 Sections_Max = Sections_PatriciaTree 83 }; 84 85 public: 86 // データ 87 Util::Reference toSection[ Sections_Max ]; 88 89 // アクセサ 90 const char* GetString( SoundArchive::ItemId stringId ) const; GetStringCountSoundArchiveFile::StringBlockBody91 u32 GetStringCount() const { return GetStringTable()->GetCount(); } 92 GetItemIdSoundArchiveFile::StringBlockBody93 NW_INLINE u32 GetItemId( const char* str ) const 94 { 95 return GetItemIdImpl( Sections_PatriciaTree, str ); 96 } 97 98 // デバッグ 99 void DumpTree() const; 100 101 private: 102 const void* GetSection( Sections section ) const; GetStringTableSoundArchiveFile::StringBlockBody103 NW_INLINE const StringTable* GetStringTable() const 104 { 105 return reinterpret_cast<const StringTable*>( 106 GetSection( Sections_StringTable ) ); 107 } GetPatriciaTreeSoundArchiveFile::StringBlockBody108 NW_INLINE const PatriciaTree* GetPatriciaTree( Sections section ) const 109 { 110 return reinterpret_cast<const PatriciaTree*>( 111 GetSection( section ) ); 112 } 113 u32 GetItemIdImpl( Sections section, const char* str ) const; 114 }; 115 116 struct PatriciaTree 117 { 118 struct NodeData 119 { 120 ut::ResU32 stringId; // 文字列 ID 121 ut::ResU32 itemId; // アイテム ID (サウンドID、バンクIDなど) 122 }; 123 struct Node 124 { 125 static const u16 FLAG_LEAF = ( 1 << 0 ); 126 ut::ResU16 flags; 127 ut::ResU16 bit; 128 ut::ResU32 leftIdx; 129 ut::ResU32 rightIdx; 130 NodeData nodeData; 131 }; 132 133 ut::ResU32 rootIdx; 134 Util::Table<Node> nodeTable; 135 136 const NodeData* GetNodeDataBy( const char* str, std::size_t len = 0 ) const; 137 138 // ut_ResDictionary.h の ResDicPatricia のインタフェイスを踏襲 139 // のちのち、役立つことがあるかもしれない。 140 void* operator[](int idx) const 141 { 142 NW_MINMAX_ASSERT( idx, 0L, static_cast<int>( nodeTable.count - 1 )); 143 // 辞書引き関連についてはconst correctnessを維持しなくても問題ないだろう 144 return const_cast<void*>( 145 reinterpret_cast<const void*>( &nodeTable.item[ idx ] ) ); 146 } 147 void* operator[](u32 idx) const 148 { 149 return operator[]( static_cast<int>(idx) ); 150 } 151 void* operator[](const char* s) const 152 { 153 return operator()( s, 0 ); 154 } operatorSoundArchiveFile::PatriciaTree155 void* operator()(const char* s, size_t len) const 156 { 157 return const_cast<void*>( 158 reinterpret_cast<const void*>( GetNodeDataBy( s, len ) ) ); 159 } GetNumDataSoundArchiveFile::PatriciaTree160 u32 GetNumData() const { return nodeTable.count; } GetCountSoundArchiveFile::PatriciaTree161 u32 GetCount() const { return GetNumData(); } 162 }; 163 164 struct StringBlock 165 { 166 ut::BinaryBlockHeader header; 167 StringBlockBody body; 168 }; 169 170 struct StringTable 171 { 172 // データ 173 Util::ReferenceWithSizeTable table; 174 175 // アクセサ GetStringSoundArchiveFile::StringTable176 const char* GetString( int stringId ) const 177 { 178 return reinterpret_cast<const char*>( 179 ut::AddOffsetToPtr( this, table.item[ stringId ].offset ) ); 180 } GetCountSoundArchiveFile::StringTable181 u32 GetCount() const 182 { 183 return table.count; 184 } 185 }; 186 187 188 // ------------------------------------------------------------------------ 189 // 情報ブロック 190 191 // 前方宣言 192 struct SoundInfo; 193 struct BankInfo; 194 struct PlayerInfo; 195 struct SoundGroupInfo; 196 struct GroupInfo; 197 struct WaveArchiveInfo; 198 struct FileInfo; 199 struct SoundArchivePlayerInfo; 200 201 struct InfoBlockBody 202 { 203 // 204 // データ 205 // 206 Util::Reference toSoundInfoReferenceTable; 207 Util::Reference toSoundGroupInfoReferenceTable; 208 Util::Reference toBankInfoReferenceTable; 209 Util::Reference toWaveArchiveInfoReferenceTable; 210 Util::Reference toGroupInfoReferenceTable; 211 Util::Reference toPlayerInfoReferenceTable; 212 Util::Reference toFileInfoReferenceTable; 213 Util::Reference toSoundArchivePlayerInfo; 214 215 // 216 // アクセサ 217 // GetSoundCountSoundArchiveFile::InfoBlockBody218 NW_INLINE u32 GetSoundCount() const { return GetSoundInfoReferenceTable().count; } GetBankCountSoundArchiveFile::InfoBlockBody219 NW_INLINE u32 GetBankCount() const { return GetBankInfoReferenceTable().count; } GetPlayerCountSoundArchiveFile::InfoBlockBody220 NW_INLINE u32 GetPlayerCount() const { return GetPlayerInfoReferenceTable().count; } GetSoundGroupCountSoundArchiveFile::InfoBlockBody221 NW_INLINE u32 GetSoundGroupCount() const { return GetSoundGroupInfoReferenceTable().count; } GetGroupCountSoundArchiveFile::InfoBlockBody222 NW_INLINE u32 GetGroupCount() const { return GetGroupInfoReferenceTable().count; } GetWaveArchiveCountSoundArchiveFile::InfoBlockBody223 NW_INLINE u32 GetWaveArchiveCount() const { return GetWaveArchiveInfoReferenceTable().count; } GetFileCountSoundArchiveFile::InfoBlockBody224 NW_INLINE u32 GetFileCount() const { return GetFileInfoReferenceTable().count; } 225 226 const SoundInfo* GetSoundInfo( SoundArchive::ItemId soundId ) const; 227 const BankInfo* GetBankInfo( SoundArchive::ItemId bankId ) const; 228 const PlayerInfo* GetPlayerInfo( SoundArchive::ItemId playerId ) const; 229 const SoundGroupInfo* GetSoundGroupInfo( SoundArchive::ItemId soundGroupId ) const; 230 const GroupInfo* GetGroupInfo( SoundArchive::ItemId groupId ) const; 231 const WaveArchiveInfo* GetWaveArchiveInfo( SoundArchive::ItemId warcId ) const; 232 const FileInfo* GetFileInfo( SoundArchive::FileId fileId ) const; 233 234 const SoundArchivePlayerInfo* GetSoundArchivePlayerInfo() const; 235 236 SoundArchive::FileId GetItemFileId( SoundArchive::ItemId id ) const; 237 SoundArchive::StringId GetItemStringId( SoundArchive::ItemId id ) const; 238 239 private: 240 const Util::ReferenceTable& GetSoundInfoReferenceTable() const; 241 const Util::ReferenceTable& GetBankInfoReferenceTable() const; 242 const Util::ReferenceTable& GetPlayerInfoReferenceTable() const; 243 const Util::ReferenceTable& GetSoundGroupInfoReferenceTable() const; 244 const Util::ReferenceTable& GetGroupInfoReferenceTable() const; 245 const Util::ReferenceTable& GetWaveArchiveInfoReferenceTable() const; 246 const Util::ReferenceTable& GetFileInfoReferenceTable() const; 247 }; 248 249 struct InfoBlock 250 { 251 ut::BinaryBlockHeader header; 252 InfoBlockBody body; 253 }; 254 255 256 struct StreamSoundInfo; 257 struct WaveSoundInfo; 258 struct SequenceSoundInfo; 259 struct Sound3DInfo; 260 261 struct SoundInfo 262 { 263 // データ 264 ut::ResU32 fileId; 265 ut::ResU32 playerId; 266 ut::ResU8 volume; 267 u8 padding0; 268 u16 padding1; 269 Util::Reference toDetailSoundInfo; // {Sequence,Stream,Wave}SoundInfo への参照 270 Util::BitFlag optionParameter; 271 272 // アクセサ 273 SoundArchive::SoundType GetSoundType() const; 274 const StreamSoundInfo& GetStreamSoundInfo() const; 275 const WaveSoundInfo& GetWaveSoundInfo() const; 276 const SequenceSoundInfo& GetSequenceSoundInfo() const; 277 const Sound3DInfo* GetSound3DInfo() const; 278 // いつか、3D サウンド情報を削ることもありそうなので、ポインタを返すようにする 279 280 u32 GetStringId() const; 281 PanMode GetPanMode() const; 282 PanCurve GetPanCurve() const; 283 u8 GetPlayerPriority() const; 284 u8 GetActorPlayerId() const; 285 u32 GetUserParam() const; // 通常の u32 ユーザーパラメータ 286 bool IsFrontBypass() const; 287 288 // TODO: SEND/MOD パラメータの取得関数 289 290 // TODO: 要対応 291 // u32 GetUserExtraParamCount(); // u32 テーブル形式の拡張ユーザーパラメータ 292 // u32 GetUserExtraParam( int index ); 293 }; 294 295 struct StreamSoundInfo 296 { 297 // データ 298 ut::ResU16 allocTrackCount; // トラック数 (マルチトラックの設定) 299 ut::ResU16 allocChannelCount; // マルチトラックを加味した総チャンネル数 300 Util::BitFlag optionParameter; // 使い方は未定 301 }; 302 303 struct WaveSoundInfo 304 { 305 // データ 306 ut::ResU32 index; // ウェーブサウンドセットファイル (bxwsd) 内で何番目か 307 ut::ResU32 allocTrackCount; // 必要なトラック数 308 Util::BitFlag optionParameter; 309 310 // アクセサ 311 u8 GetChannelPriority() const; 312 u8 GetIsReleasePriorityFix() const; 313 314 }; 315 316 struct SequenceSoundInfo 317 { 318 // データ 319 Util::Reference toBankIdTable; 320 ut::ResU32 allocateTrackFlags; 321 Util::BitFlag optionParameter; 322 323 // アクセサ 324 void GetBankIds( u32* bankIds ) const; // SoundArchive::SEQ_BANK_MAX だけコピー 325 u32 GetStartOffset() const; 326 u8 GetChannelPriority() const; 327 bool IsReleasePriorityFix() const; 328 private: 329 const Util::Table<ut::ResU32>& GetBankIdTable() const; 330 }; 331 332 struct Sound3DInfo 333 { 334 ut::ResU32 flags; // [0]Vol [1]Priotity [2]Pan [3]SPan [4]Filter 335 // (SoundArchive::Sound3DInfo::FLAG_CTRL_*** に対応しています) 336 ut::ResF32 decayRatio; // 減衰率 337 u8 decayCurve; // 減衰カーブタイプ (nw::snd::DecayCurve が入る) 338 u8 dopplerFactor; // ドップラーファクター 339 u8 padding[2]; // padding 340 Util::BitFlag optionParameter; // 予備 341 }; 342 343 struct BankInfo 344 { 345 // データ 346 ut::ResU32 fileId; 347 Util::Reference toWaveArchiveItemIdTable; 348 Util::BitFlag optionParameter; 349 350 // アクセサ 351 u32 GetStringId() const; 352 353 NW_INLINE const Util::Table<ut::ResU32>* GetWaveArchiveItemIdTableSoundArchiveFile::BankInfo354 GetWaveArchiveItemIdTable() const 355 { 356 return reinterpret_cast<const Util::Table<ut::ResU32>*>( 357 ut::AddOffsetToPtr( this, toWaveArchiveItemIdTable.offset ) ); 358 } 359 }; 360 361 struct PlayerInfo 362 { 363 // データ 364 ut::ResU32 playableSoundMax; // プレイヤー最大再生数 365 Util::BitFlag optionParameter; 366 367 // アクセサ 368 u32 GetStringId() const; 369 u32 GetPlayerHeapSize() const; 370 }; 371 372 struct WaveSoundGroupInfo; 373 struct SoundGroupInfo 374 { 375 // データ 376 ut::ResU32 startId; // アイテム ID (startId と endId の ItemType は同一) 377 ut::ResU32 endId; 378 Util::Reference toFileIdTable; 379 Util::Reference toDetailSoundGroupInfo; 380 Util::BitFlag optionParameter; 381 382 // アクセサ 383 u32 GetStringId() const; 384 GetFileIdTableSoundArchiveFile::SoundGroupInfo385 NW_INLINE const Util::Table<ut::ResU32>* GetFileIdTable() const 386 { 387 return reinterpret_cast<const Util::Table<ut::ResU32>*>( 388 ut::AddOffsetToPtr( this, toFileIdTable.offset ) ); 389 } GetWaveSoundGroupInfoSoundArchiveFile::SoundGroupInfo390 NW_INLINE const WaveSoundGroupInfo* GetWaveSoundGroupInfo() const 391 { 392 if ( toDetailSoundGroupInfo.typeId != 393 ElementType_SoundArchiveFile_WaveSoundGroupInfo ) 394 { 395 return NULL; 396 } 397 398 return reinterpret_cast<const WaveSoundGroupInfo*>( 399 ut::AddOffsetToPtr( this, toDetailSoundGroupInfo.offset ) ); 400 } 401 402 #if 0 // 必要になるかもしれない 403 u32 GetFileIdCount() const { return GetFileIdTable().count; } 404 u32 GetFileId( u32 index ) const 405 { 406 if ( index >= GetFileIdCount() ) return SoundArchive::INVALID_ID; 407 return GetFileIdTable().item[ index ]; 408 } 409 #endif 410 }; 411 412 struct WaveSoundGroupInfo 413 { 414 // データ 415 Util::Reference toWaveArchiveItemIdTable; 416 Util::BitFlag optionParameter; // 仮。なにが割り当てられるかは未定。 417 418 // アクセサ 419 NW_INLINE const Util::Table<ut::ResU32>* GetWaveArchiveItemIdTableSoundArchiveFile::WaveSoundGroupInfo420 GetWaveArchiveItemIdTable() const 421 { 422 return reinterpret_cast<const Util::Table<ut::ResU32>*>( 423 ut::AddOffsetToPtr( this, toWaveArchiveItemIdTable.offset ) ); 424 } 425 }; 426 427 struct GroupInfo 428 { 429 // データ 430 ut::ResU32 fileId; 431 Util::BitFlag optionParameter; 432 433 // アクセサ 434 u32 GetStringId() const; 435 }; 436 437 struct WaveArchiveInfo 438 { 439 // データ 440 ut::ResU32 fileId; 441 bool isLoadIndividual; 442 u8 padding1; 443 u16 padding2; 444 Util::BitFlag optionParameter; 445 446 // アクセサ 447 u32 GetStringId() const; 448 u32 GetWaveCount() const; 449 }; 450 451 enum FileLocationType 452 { 453 FILE_LOCATION_TYPE_INTERNAL, // サウンドアーカイブ内に配置 454 FILE_LOCATION_TYPE_EXTERNAL, // サウンドアーカイブ外に配置 455 FILE_LOCATION_TYPE_NONE 456 // ファイル単体にアクセスできない (=ロードできない) 457 // * バンクファイルかウェーブサウンドセットファイルのうち、 458 // 次の条件を満たすものが該当 459 // * 波形アーカイブ設定が【自動(共有)】で、 460 // * 出力設定が【埋め込み】のグループに属している 461 }; 462 463 struct InternalFileInfo; // サウンドアーカイブ FILE ブロック内に格納 464 struct ExternalFileInfo; // サウンドアーカイブ外に格納 465 466 struct FileInfo 467 { 468 // データ 469 Util::Reference toFileLocation; 470 Util::BitFlag optionParameter; // 仮。なにが割り当てられるかは未定。 471 472 // アクセサ 473 FileLocationType GetFileLocationType() const; 474 const InternalFileInfo* GetInternalFileInfo() const; 475 const ExternalFileInfo* GetExternalFileInfo() const; 476 477 #if 0 478 // サウンドアーカイブファイル上のアドレスを取得 479 // ROM 上のバイナリサウンドアーカイブファイルの先頭をアドレス 0 とする。 480 const void* GetFileAddress( const void* dataBlockBodyAddress ) const; 481 // TODO: ↑ これは必要ない? 482 #endif 483 }; 484 485 struct InternalFileInfo 486 { 487 // データ 488 Util::ReferenceWithSize toFileImageFromFileBlockBody; 489 490 // アクセサ GetFileSizeSoundArchiveFile::InternalFileInfo491 inline u32 GetFileSize() const 492 { 493 return toFileImageFromFileBlockBody.size; 494 } GetOffsetFromFileBlockHeadSoundArchiveFile::InternalFileInfo495 inline u32 GetOffsetFromFileBlockHead() const 496 { 497 return toFileImageFromFileBlockBody.offset + sizeof(ut::BinaryBlockHeader); 498 } 499 }; 500 501 struct ExternalFileInfo 502 { 503 // データ 504 // TODO: u32 fileSize や u16? filePathLength が入るかも 505 char filePath[1]; 506 }; 507 508 struct SoundArchivePlayerInfo 509 { 510 nw::ut::ResU16 sequenceSoundMax; 511 nw::ut::ResU16 sequenceTrackMax; 512 nw::ut::ResU16 streamSoundMax; 513 nw::ut::ResU16 streamTrackMax; 514 nw::ut::ResU16 streamChannelMax; 515 nw::ut::ResU16 waveSoundMax; 516 nw::ut::ResU16 waveTrackmax; 517 u16 padding; 518 nw::ut::ResU32 options; // TODO: 仮 519 }; 520 521 522 // ------------------------------------------------------------------------ 523 // ファイルブロック 524 525 struct FileBlockBody 526 { 527 // ボディのアドレスを取るためだけ 528 }; 529 530 struct FileBlock 531 { 532 ut::BinaryBlockHeader header; 533 FileBlockBody body; 534 }; 535 536 }; 537 538 } // namespace nw::snd::internal 539 } // namespace nw::snd 540 } // namespace nw 541 542 #endif /* NW_SND_SOUND_ARCHIVE_FILE_H_ */ 543 544