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: 19580 $ 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 ut::ResF32 decayRatio; // 減衰率 336 u8 decayCurve; // 減衰カーブタイプ (nw::snd::DecayCurve が入る) 337 u8 dopplerFactor; // ドップラーファクター 338 u8 padding[2]; // padding 339 Util::BitFlag optionParameter; // 予備 340 }; 341 342 struct BankInfo 343 { 344 // データ 345 ut::ResU32 fileId; 346 Util::Reference toWaveArchiveItemIdTable; 347 Util::BitFlag optionParameter; 348 349 // アクセサ 350 u32 GetStringId() const; 351 352 NW_INLINE const Util::Table<ut::ResU32>* GetWaveArchiveItemIdTableSoundArchiveFile::BankInfo353 GetWaveArchiveItemIdTable() const 354 { 355 return reinterpret_cast<const Util::Table<ut::ResU32>*>( 356 ut::AddOffsetToPtr( this, toWaveArchiveItemIdTable.offset ) ); 357 } 358 }; 359 360 struct PlayerInfo 361 { 362 // データ 363 ut::ResU32 playableSoundMax; // プレイヤー最大再生数 364 Util::BitFlag optionParameter; 365 366 // アクセサ 367 u32 GetStringId() const; 368 u32 GetPlayerHeapSize() const; 369 }; 370 371 struct WaveSoundGroupInfo; 372 struct SoundGroupInfo 373 { 374 // データ 375 ut::ResU32 startId; // アイテム ID (startId と endId の ItemType は同一) 376 ut::ResU32 endId; 377 Util::Reference toFileIdTable; 378 Util::Reference toDetailSoundGroupInfo; 379 Util::BitFlag optionParameter; 380 381 // アクセサ 382 u32 GetStringId() const; 383 GetFileIdTableSoundArchiveFile::SoundGroupInfo384 NW_INLINE const Util::Table<ut::ResU32>* GetFileIdTable() const 385 { 386 return reinterpret_cast<const Util::Table<ut::ResU32>*>( 387 ut::AddOffsetToPtr( this, toFileIdTable.offset ) ); 388 } GetWaveSoundGroupInfoSoundArchiveFile::SoundGroupInfo389 NW_INLINE const WaveSoundGroupInfo* GetWaveSoundGroupInfo() const 390 { 391 if ( toDetailSoundGroupInfo.typeId != 392 ElementType_SoundArchiveFile_WaveSoundGroupInfo ) 393 { 394 return NULL; 395 } 396 397 return reinterpret_cast<const WaveSoundGroupInfo*>( 398 ut::AddOffsetToPtr( this, toDetailSoundGroupInfo.offset ) ); 399 } 400 401 #if 0 // 必要になるかもしれない 402 u32 GetFileIdCount() const { return GetFileIdTable().count; } 403 u32 GetFileId( u32 index ) const 404 { 405 if ( index >= GetFileIdCount() ) return SoundArchive::INVALID_ID; 406 return GetFileIdTable().item[ index ]; 407 } 408 #endif 409 }; 410 411 struct WaveSoundGroupInfo 412 { 413 // データ 414 Util::Reference toWaveArchiveItemIdTable; 415 Util::BitFlag optionParameter; // 仮。なにが割り当てられるかは未定。 416 417 // アクセサ 418 NW_INLINE const Util::Table<ut::ResU32>* GetWaveArchiveItemIdTableSoundArchiveFile::WaveSoundGroupInfo419 GetWaveArchiveItemIdTable() const 420 { 421 return reinterpret_cast<const Util::Table<ut::ResU32>*>( 422 ut::AddOffsetToPtr( this, toWaveArchiveItemIdTable.offset ) ); 423 } 424 }; 425 426 struct GroupInfo 427 { 428 // データ 429 ut::ResU32 fileId; 430 Util::BitFlag optionParameter; 431 432 // アクセサ 433 u32 GetStringId() const; 434 }; 435 436 struct WaveArchiveInfo 437 { 438 // データ 439 ut::ResU32 fileId; 440 bool isLoadIndividual; 441 u8 padding1; 442 u16 padding2; 443 Util::BitFlag optionParameter; 444 445 // アクセサ 446 u32 GetStringId() const; 447 u32 GetWaveCount() const; 448 }; 449 450 enum FileLocationType 451 { 452 FILE_LOCATION_TYPE_INTERNAL, // サウンドアーカイブ内に配置 453 FILE_LOCATION_TYPE_EXTERNAL, // サウンドアーカイブ外に配置 454 FILE_LOCATION_TYPE_NONE 455 // ファイル単体にアクセスできない (=ロードできない) 456 // * バンクファイルかウェーブサウンドセットファイルのうち、 457 // 次の条件を満たすものが該当 458 // * 波形アーカイブ設定が【自動(共有)】で、 459 // * 出力設定が【埋め込み】のグループに属している 460 }; 461 462 struct InternalFileInfo; // サウンドアーカイブ FILE ブロック内に格納 463 struct ExternalFileInfo; // サウンドアーカイブ外に格納 464 465 struct FileInfo 466 { 467 // データ 468 Util::Reference toFileLocation; 469 Util::BitFlag optionParameter; // 仮。なにが割り当てられるかは未定。 470 471 // アクセサ 472 FileLocationType GetFileLocationType() const; 473 const InternalFileInfo* GetInternalFileInfo() const; 474 const ExternalFileInfo* GetExternalFileInfo() const; 475 476 #if 0 477 // サウンドアーカイブファイル上のアドレスを取得 478 // ROM 上のバイナリサウンドアーカイブファイルの先頭をアドレス 0 とする。 479 const void* GetFileAddress( const void* dataBlockBodyAddress ) const; 480 // TODO: ↑ これは必要ない? 481 #endif 482 }; 483 484 struct InternalFileInfo 485 { 486 // データ 487 Util::ReferenceWithSize toFileImageFromFileBlockBody; 488 489 // アクセサ GetFileSizeSoundArchiveFile::InternalFileInfo490 inline u32 GetFileSize() const 491 { 492 return toFileImageFromFileBlockBody.size; 493 } GetOffsetFromFileBlockHeadSoundArchiveFile::InternalFileInfo494 inline u32 GetOffsetFromFileBlockHead() const 495 { 496 return toFileImageFromFileBlockBody.offset + sizeof(ut::BinaryBlockHeader); 497 } 498 }; 499 500 struct ExternalFileInfo 501 { 502 // データ 503 // TODO: u32 fileSize や u16? filePathLength が入るかも 504 char filePath[1]; 505 }; 506 507 struct SoundArchivePlayerInfo 508 { 509 nw::ut::ResU16 sequenceSoundMax; 510 nw::ut::ResU16 sequenceTrackMax; 511 nw::ut::ResU16 streamSoundMax; 512 nw::ut::ResU16 streamTrackMax; 513 nw::ut::ResU16 streamChannelMax; 514 nw::ut::ResU16 waveSoundMax; 515 nw::ut::ResU16 waveTrackmax; 516 u16 padding; 517 nw::ut::ResU32 options; // TODO: 仮 518 }; 519 520 521 // ------------------------------------------------------------------------ 522 // ファイルブロック 523 524 struct FileBlockBody 525 { 526 // ボディのアドレスを取るためだけ 527 }; 528 529 struct FileBlock 530 { 531 ut::BinaryBlockHeader header; 532 FileBlockBody body; 533 }; 534 535 }; 536 537 } // namespace nw::snd::internal 538 } // namespace nw::snd 539 } // namespace nw 540 541 #endif /* NW_SND_SOUND_ARCHIVE_FILE_H_ */ 542 543