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