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