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