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