1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_WaveFile.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_WAVE_FILE_
19 #define NW_SND_WAVE_FILE_
20 
21 #include <nn/types.h>
22 
23 #include <nw/snd/snd_Global.h>
24 #include <nw/snd/snd_Util.h>                // Util::Table
25 #include <nw/ut/ut_BinaryFileFormat.h>      // ut::BinaryFileHeader など
26 #include <nw/ut/ut_BinaryReader.h>          // ResU32 など
27 
28 namespace nw {
29 namespace snd {
30 namespace internal {
31 
32 /*
33     波形ファイル (.bcwav) の構造
34 
35     bcwav
36      |
37      +-- FileHeader
38      +-- InfoBlock
39      |    |
40      |    +-- BinaryBlockHeader
41      |    +-- InfoBlockBody
42      |         |
43      |         +-- u8 encoding
44      |         +-- u8 isLoop
45      |         +-- u32 sampleRate
46      |         +-- u32 loopStart
47      |         +-- u32 loopEnd
48      |         +-- u32 reserved
49      |         +-- Table< reference to ChannelInfo >
50      |              |
51      |              +-- s32 count
52      |              +-- reference to ChannelInfo[0] ----------------+
53      |              +-- reference to ChannelInfo[1]                 |
54      |              +-- ... (2ch までしかサポートしていない?!)    |
55      |                                                              |
56      |    +---------------------------------------------------------+
57      |    |
58      |    +-> ChannelInfo
59      |         |
60      |         +-- reference to Samples (DataBlockBody を起点とするサンプルへのオフセット)
61      |         +-- reference to AdpcmInfo --+
62      |                                      |
63      |    +---------------------------------+
64      |    |
65      |    +-> AdpcmInfo
66      |         |
67      |         +-- DspAdpcmParam (snd_Global.h)
68      |         |    |
69      |         |    +-- u16 coef[16]
70      |         |    +-- u16 predScale
71      |         |    +-- u16 yn1
72      |         |    +-- u16 yn2
73      |         |
74      |         +-- DspAdpcmLoopParam (snd_Global.h)
75      |              |
76      |              +-- u16 loopPredScale
77      |              +-- u16 loopYn1
78      |              +-- u16 loopYn2
79      |
80      +-- DataBlock
81           |
82           +-- BinaryBlockHeader
83           +-- DataBlockBody (サンプルデータ)
84 */
85 
86 struct WaveFile
87 {
88     enum EncodeMethod
89     {
90         PCM8        = 0,
91         PCM16,              // バイトオーダーはプラットフォームに依存
92         DSP_ADPCM,
93         IMA_ADPCM
94     };
95 
96     //
97     // 前方宣言
98     //
99     struct InfoBlock;
100     struct ChannelInfo;
101     struct DspAdpcmInfo;
102     struct DataBlock;
103 
104     struct FileHeader : public Util::SoundFileHeader
105     {
106         const InfoBlock* GetInfoBlock() const;
107         const DataBlock* GetDataBlock() const;
108     };
109 
110     struct InfoBlockBody
111     {
112         u8              encoding;           // EncodeMethod が入る
113         u8              isLoop;             // 0: ループなし, 1: ループあり
114         u16             padding;
115         nw::ut::ResU32  sampleRate;         // サンプリングレート
116         nw::ut::ResU32  loopStartFrame;     // ループ開始 (ループなしなら 0)
117         nw::ut::ResU32  loopEndFrame;       // ループ終端 (ループなしなら 0)
118         nw::ut::ResU32  reserved;
119         Util::ReferenceTable channelInfoReferenceTable;
120 
GetChannelCountWaveFile::InfoBlockBody121         inline s32 GetChannelCount() const { return channelInfoReferenceTable.count; }
122         const ChannelInfo& GetChannelInfo( s32 channelIndex ) const;
123     };
124 
125     struct InfoBlock
126     {
127         ut::BinaryBlockHeader   header;
128         InfoBlockBody           body;
129     };
130 
131     struct ChannelInfo
132     {
133         Util::Reference     referToSamples;     // 起点は DATA ブロックボディ
134         Util::Reference     referToAdpcmInfo;
135         nw::ut::ResU32      reserved;
136 
137         const void* GetSamplesAddress( const void* dataBlockBodyAddress ) const;
138         const DspAdpcmInfo& GetDspAdpcmInfo() const;
139     };
140 
141     struct DspAdpcmInfo
142     {
143         DspAdpcmParam      adpcmParam;
144         DspAdpcmLoopParam  adpcmLoopParam;
145     };
146 
147     struct DataBlock
148     {
149         ut::BinaryBlockHeader   header;
150         union
151         {
152             s8  pcm8[1];
153             s16 pcm16[1];
154             u8  byte[1];
155         };
156     };
157 };  // struct WaveFile
158 
159 } // namespace nw::snd::internal
160 } // namespace nw::snd
161 } // namespace nw
162 
163 #endif /* NW_SND_WAVE_FILE_ */
164