1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: snd_StreamSoundFile.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_STREAM_SOUND_FILE_H_ 19 #define NW_SND_STREAM_SOUND_FILE_H_ 20 21 #include <nn/types.h> 22 #include <nw/snd/snd_Util.h> 23 #include <nw/snd/snd_Global.h> 24 #include <nw/ut/ut_BinaryFileFormat.h> 25 #include <nw/ut/ut_ResTypes.h> 26 27 namespace nw { 28 namespace snd { 29 namespace internal { 30 31 /* 32 ストリームファイル (*.bcstm) の構造 33 34 bcstm 35 | 36 +-- FileHeader 37 +-- InfoBlock 38 | | 39 | +-- BinaryBlockHeader 40 | +-- InfoBlockBody 41 | | 42 | +-- reference to StreamSoundInfo --+ 43 | | | 44 | | +------------------------------+ 45 | | | 46 | | +-> StreamSoundInfo 47 | | | 48 | | +-- u8 encodeMethod 49 | | +-- bool isLoop 50 | | +-- u8 channelCount 51 | | +-- u8 padding 52 | | +-- u32 sampleRate 53 | | +-- u32 loopStart 54 | | +-- u32 frameCount 55 | | +-- u32 blockCount 56 | | +-- u32 oneBlockBytes 57 | | +-- u32 oneBlockSamples 58 | | +-- u32 lastBlockBytes 59 | | +-- u32 lastBlockSamples 60 | | +-- u32 lastBlockPaddedBytes 61 | | +-- u32 sizeofSeekInfoAtom 62 | | +-- u32 seekInfoIntervalSamples 63 | | +-- reference to sampleDataOffset 64 | | 65 | +-- reference to TrackInfoTable --+ 66 | | | 67 | | +-----------------------------+ 68 | | | 69 | | +-> TrackInfoTable 70 | | | 71 | | +-- s32 count 72 | | +-- reference to TrackInfo[0] --+ 73 | | : | 74 | | +------------------------------------+ 75 | | | 76 | | +-> TrackInfo 77 | | | 78 | | +-- u8 volume 79 | | +-- u8 pan 80 | | +-- u16 padding 81 | | +-- reference to GlobalChannelIndexTable --+ 82 | | | 83 | | +-----------------------------------------------+ 84 | | | 85 | | +-> GlobalChannelIndexTable 86 | | | 87 | | +-- u32 count 88 | | +-- u8 globalChannelIndex[0] 89 | | : 90 | | 91 | +-- reference to ChannelInfoTable --+ 92 | | 93 | +-------------------------------+ 94 | | 95 | +-> ChannelInfoTable 96 | | 97 | +-- u32 count 98 | +-- reference to ChannelInfo[0] --+ 99 | : | 100 | +--------------------------------------+ 101 | | 102 | +-> ChannelInfo 103 | | 104 | +-- reference to detailChannelInfo --+ 105 | | 106 | +-----------------------------------------+ 107 | | 108 | +-> DspAdpcmChannelInfo 109 | . | 110 | . +-- DspAdpcm 111 | . | | 112 | . | +-- u16 coef[16] 113 | . | +-- u16 predScale 114 | . | +-- u16 yn1 115 | . | +-- u16 yn2 116 | . | 117 | . +-- DspAdpcmLoopParam 118 | . | 119 | . +-- u16 loopPredScale 120 | . +-- u16 loopYn1 121 | . +-- u16 loopYn2 122 | . 123 | +-> (他のエンコード情報もあるかも) 124 | 125 +-- SeekBlock 126 | | 127 | +-- BinaryBlockHeader 128 | +-- (ブロック全体はメモリに展開されない。 129 | 必要な部分のみ StreamSoundFileLoader でロードされる) 130 | 131 +-- DataBlock 132 | 133 +-- BinaryBlockHeader 134 +-- (ブロック全体はメモリに展開されない。 135 必要な部分のみ StreamSoundFileLoader でロードされる) 136 */ 137 struct StreamSoundFile 138 { 139 // 前方宣言 140 struct InfoBlock; 141 struct InfoBlockBody; 142 struct SeekBlock; 143 struct DataBlock; 144 145 // 定数 146 147 // ファイルヘッダー 148 // メモ : ストリームファイルは、ヘッダーおよび INFO ブロックのみ先にロードするので、 149 // Util::SoundFileHeader を継承できない。 150 struct FileHeader : public ut::BinaryFileHeader 151 { 152 private: 153 // 定数 154 static const int BLOCK_SIZE = 3; 155 156 public: 157 // データ 158 Util::ReferenceWithSize toBlocks[ BLOCK_SIZE ]; 159 160 // 各ブロックのサイズ 161 u32 GetInfoBlockSize() const; 162 u32 GetSeekBlockSize() const; 163 u32 GetDataBlockSize() const; 164 165 // ファイル先頭から各ブロックへのオフセット 166 u32 GetInfoBlockOffset() const; 167 u32 GetSeekBlockOffset() const; 168 u32 GetDataBlockOffset() const; 169 GetInfoBlockStreamSoundFile::FileHeader170 const InfoBlock* GetInfoBlock() const 171 { 172 return static_cast<const InfoBlock*>( 173 ut::AddOffsetToPtr( this, GetInfoBlockOffset() ) ); 174 } 175 176 private: 177 const Util::ReferenceWithSize* GetReferenceBy( u16 typeId ) const; 178 }; 179 180 // -------------------------- 181 // INFO ブロック 182 struct StreamSoundInfo; 183 struct TrackInfoTable; 184 struct ChannelInfoTable; 185 struct InfoBlockBody 186 { 187 // データ 188 Util::Reference toStreamSoundInfo; 189 Util::Reference toTrackInfoTable; 190 Util::Reference toChannelInfoTable; 191 192 // アクセサ 193 const StreamSoundInfo* GetStreamSoundInfo() const; 194 const TrackInfoTable* GetTrackInfoTable() const; 195 const ChannelInfoTable* GetChannelInfoTable() const; 196 }; 197 198 struct InfoBlock 199 { 200 ut::BinaryBlockHeader header; 201 InfoBlockBody body; 202 }; 203 204 struct StreamSoundInfo 205 { 206 u8 encodeMethod; // WaveFile::EncodeMethod が入る 207 bool isLoop; 208 u8 channelCount; 209 u8 padding; 210 ut::ResU32 sampleRate; 211 ut::ResU32 loopStart; 212 ut::ResU32 frameCount; 213 ut::ResU32 blockCount; 214 215 ut::ResU32 oneBlockBytes; 216 ut::ResU32 oneBlockSamples; 217 218 ut::ResU32 lastBlockBytes; 219 ut::ResU32 lastBlockSamples; 220 ut::ResU32 lastBlockPaddedBytes; 221 222 ut::ResU32 sizeofSeekInfoAtom; // シーク情報のサイズ (1ch 分) 223 ut::ResU32 seekInfoIntervalSamples; 224 225 Util::Reference sampleDataOffset; // DATA ブロックボディ先頭から、 226 // サンプルデータへのオフセット 227 }; 228 229 struct TrackInfo; 230 struct TrackInfoTable 231 { 232 // データ 233 Util::ReferenceTable table; 234 235 // アクセサ 236 const TrackInfo* GetTrackInfo( u32 index ) const; GetTrackCountStreamSoundFile::TrackInfoTable237 u32 GetTrackCount() const { return table.count; } 238 }; 239 240 struct GlobalChannelIndexTable; 241 struct TrackInfo 242 { 243 // データ 244 u8 volume; 245 u8 pan; 246 u16 padding; 247 Util::Reference toGlobalChannelIndexTable; 248 249 // アクセサ GetTrackChannelCountStreamSoundFile::TrackInfo250 NW_INLINE u32 GetTrackChannelCount() const 251 { 252 return GetGlobalChannelIndexTable().GetCount(); 253 } GetGlobalChannelIndexStreamSoundFile::TrackInfo254 NW_INLINE u8 GetGlobalChannelIndex( u32 index ) const 255 { 256 return GetGlobalChannelIndexTable().GetGlobalIndex( index ); 257 } 258 private: GetGlobalChannelIndexTableStreamSoundFile::TrackInfo259 const GlobalChannelIndexTable& GetGlobalChannelIndexTable() const 260 { 261 return *reinterpret_cast<const GlobalChannelIndexTable*>( 262 ut::AddOffsetToPtr( 263 this, 264 toGlobalChannelIndexTable.offset ) ); 265 } 266 }; 267 struct GlobalChannelIndexTable 268 { 269 // データ 270 Util::Table<u8> table; 271 // トラック内のローカルチャンネルインデックスと、 272 // ストリームサウンド全体のグローバルチャンネルインデックスを紐付けます 273 274 // アクセサ GetCountStreamSoundFile::GlobalChannelIndexTable275 NW_INLINE u32 GetCount() const { return table.count; } GetGlobalIndexStreamSoundFile::GlobalChannelIndexTable276 NW_INLINE u8 GetGlobalIndex( u32 index ) const 277 { 278 NW_ASSERT( index < table.count ); 279 return table.item[ index ]; 280 } 281 }; 282 283 struct ChannelInfo; 284 struct ChannelInfoTable 285 { 286 // データ 287 Util::ReferenceTable table; 288 289 // アクセサ GetChannelCountStreamSoundFile::ChannelInfoTable290 NW_INLINE u32 GetChannelCount() const { return table.count; } 291 const ChannelInfo* GetChannelInfo( u32 index ) const; 292 }; 293 294 struct DspAdpcmChannelInfo; // エンコードによっては、ほかにもあるかも 295 struct ChannelInfo 296 { 297 Util::Reference toDetailChannelInfo; 298 const DspAdpcmChannelInfo* GetDspAdpcmChannelInfo() const; 299 }; 300 301 struct DspAdpcmChannelInfo 302 { 303 // データ 304 DspAdpcmParam param; 305 DspAdpcmLoopParam loopParam; 306 }; 307 308 // -------------------------- 309 // SEEK ブロック (途中再生用の情報) 310 struct SeekBlock 311 { 312 ut::BinaryBlockHeader header; 313 314 // ブロック全体はメモリに展開されない。 315 // ファイルストリーム経由で、Seek, Read するため、 316 // アクセサは StreamSoundFileLoader に任せる。 317 }; 318 319 // -------------------------- 320 // DATA ブロック (サンプルデータ) 321 struct DataBlock 322 { 323 ut::BinaryBlockHeader header; 324 325 // ブロック全体はメモリに展開されない。 326 // ファイルストリーム経由で、Seek, Read するため、 327 // アクセサは StreamSoundFileLoader に任せる。 328 }; 329 }; 330 331 } // namespace nw::snd::internal 332 } // namespace nw::snd 333 } // namespace nw 334 335 336 #endif /* NW_SND_STREAM_SOUND_FILE_H_ */ 337 338