1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
|
#ifndef NW4R_SND_STRM_FILE_H
#define NW4R_SND_STRM_FILE_H
/*******************************************************************************
* headers
*/
#include "common.h"
#include "nw4r/snd/snd_adpcm.h"
#include "nw4r/snd/snd_global.h" // SampleFormat
#include "nw4r/snd/snd_Util.h" // Util::DataRef
#include "nw4r/ut/ut_binaryFileFormat.h"
/*******************************************************************************
* types
*/
// forward declarations
namespace nw4r { namespace ut { class FileStream; }}
namespace nw4r { namespace snd { namespace detail
{
struct StrmFile
{
/* Header */
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2f271d
struct Header
{
ut::BinaryFileHeader fileHeader; // size 0x10, offset 0x00
u32 headBlockOffset; // size 0x04, offset 0x10
u32 headBlockSize; // size 0x04, offset 0x14
u32 adpcBlockOffset; // size 0x04, offset 0x18
u32 adpcBlockSize; // size 0x04, offset 0x1c
u32 dataBlockOffset; // size 0x04, offset 0x20
u32 dataBlockSize; // size 0x04, offset 0x24
}; // size 0x28
/* HeadBlock */
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2f2d81
struct StrmDataInfo
{
u8 format; // size 0x01, offset 0x00
u8 loopFlag; // size 0x01, offset 0x01
u8 numChannels; // size 0x01, offset 0x02
u8 sampleRate24; // size 0x01, offset 0x03
u16 sampleRate; // size 0x02, offset 0x04
u16 blockHeaderOffset; // size 0x02, offset 0x06
u32 loopStart; // size 0x04, offset 0x08
u32 loopEnd; // size 0x04, offset 0x0c
u32 dataOffset; // size 0x04, offset 0x10
u32 numBlocks; // size 0x04, offset 0x14
u32 blockSize; // size 0x04, offset 0x18
u32 blockSamples; // size 0x04, offset 0x1c
u32 lastBlockSize; // size 0x04, offset 0x20
u32 lastBlockSamples; // size 0x04, offset 0x24
u32 lastBlockPaddedSize; // size 0x04, offset 0x28
u32 adpcmDataInterval; // size 0x04, offset 0x2c
u32 adpcmDataSize; // size 0x04, offset 0x30
}; // size 0x34
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2f3a1e
struct TrackInfo
{
u8 channelCount; // size 0x01, offset 0x00
u8 channelIndexTable[]; // flexible, offset 0x01 (unit size 0x01)
}; // size 0x01
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2f3196
struct TrackInfoEx
{
u8 volume; // size 0x01, offset 0x00
u8 pan; // size 0x01, offset 0x01
u8 padding[2];
u32 reserved;
u8 channelCount; // size 0x01, offset 0x08
u8 channelIndexTable[]; // flexible, offset 0x09 (unit size 0x01)
/* 3 bytes padding */
}; // size 0x0c
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2f34ef
struct TrackTable
{
u8 trackCount; // size 0x01, offset 0x00
u8 trackDataType; // size 0x01, offset 0x01
u8 padding[2];
Util::DataRef<TrackInfo, TrackInfoEx> refTrackHeader[]; // flexible, offset 0x04 (unit size 0x08)
}; // size 0x04
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2f336f
struct AdpcmParamSet
{
AdpcmParam adpcmParam; // size 0x28, offset 0x00
AdpcmLoopParam adpcmLoopParam; // size 0x06, offset 0x28
}; // size 0x2e
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2f3cbb
struct ChannelInfo
{
Util::DataRef<AdpcmParamSet> refAdpcmInfo; // size 0x08, offset 0x00
}; // size 0x08
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2f3780
struct ChannelTable
{
u8 channelCount; // size 0x01, offset 0x00
u8 padding[3];
Util::DataRef<ChannelInfo> refChannelHeader[]; // flexible, offset 0x04 (unit size 0x08)
}; // size 0x04
static u32 const SIGNATURE_HEAD_BLOCK =
NW4R_FOUR_BYTE('H', 'E', 'A', 'D');
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2f2ab0
struct HeadBlock
{
ut::BinaryBlockHeader blockHeader; // size 0x08, offset 0x00
Util::DataRef<StrmDataInfo> refDataHeader; // size 0x08, offset 0x08
Util::DataRef<TrackTable> refTrackTable; // size 0x08, offset 0x10
Util::DataRef<ChannelTable> refChannelTable; // size 0x08, offset 0x18
}; // size 0x20
/* StrmFile */
static u32 const SIGNATURE_FILE =
NW4R_FOUR_BYTE('R', 'S', 'T', 'M');
static int const FILE_VERSION = NW4R_FILE_VERSION(1, 0);
}; // "namespace" StrmFile
}}} // namespace nw4r::snd::detail
/*******************************************************************************
* classes and functions
*/
namespace nw4r { namespace snd { namespace detail
{
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2f2b8e
class StrmFileReader
{
// nested types
public:
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2f0e7
struct StrmInfo
{
SampleFormat sampleFormat; // size 0x04, offset 0x00
bool loopFlag; // size 0x01, offset 0x04
/* 3 bytes padding */
int numChannels; // size 0x04, offset 0x08
int sampleRate; // size 0x04, offset 0x0c
u16 blockHeaderOffset; // size 0x02, offset 0x10
/* 2 bytes padding */
u32 loopStart; // size 0x04, offset 0x14
u32 loopEnd; // size 0x04, offset 0x18
u32 dataOffset; // size 0x04, offset 0x1c
u32 numBlocks; // size 0x04, offset 0x20
u32 blockSize; // size 0x04, offset 0x24
u32 blockSamples; // size 0x04, offset 0x28
u32 lastBlockSize; // size 0x04, offset 0x2c
u32 lastBlockSamples; // size 0x04, offset 0x30
u32 lastBlockPaddedSize; // size 0x04, offset 0x34
u32 adpcmDataInterval; // size 0x04, offset 0x38
u32 adpcmDataSize; // size 0x04, offset 0x3c
}; // size 0x40
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2fa44
struct StrmTrackInfo
{
u8 volume; // size 0x01, offset 0x00
u8 pan; // size 0x01, offset 0x01
/* 2 bytes padding */
int channelCount; // size 0x04, offset 0x04
u8 channelIndexTable[32]; // size 0x20, offset 0x08
}; // size 0x28
// methods
public:
// cdtors
StrmFileReader();
// methods
void Setup(void const *strmData);
bool IsAvailable() const { return mHeader != nullptr; }
u32 GetAdpcBlockOffset() const
{
if (IsAvailable())
return mHeader->adpcBlockOffset;
return 0;
}
int GetTrackCount() const;
int GetChannelCount() const;
bool ReadStrmInfo(StrmInfo *strmInfo) const;
bool ReadStrmTrackInfo(StrmTrackInfo *trackInfo, int trackIndex) const;
bool ReadAdpcmInfo(AdpcmParam *adpcmParam,
AdpcmLoopParam *adpcmLoopParam,
int channelIndex) const;
private:
static bool IsValidFileHeader(void const *strmData);
static SampleFormat GetSampleFormatFromStrmFileFormat(u8 format);
// static members
public:
static int const SUPPORTED_FILE_VERSION = NW4R_FILE_VERSION(1, 0);
// members
private:
StrmFile::Header const *mHeader; // size 0x04, offset 0x00
StrmFile::HeadBlock const *mHeadBlock; // size 0x04, offset 0x04
// friends
private:
friend class StrmFileLoader;
}; // size 0x08
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2f3fc4
class StrmFileLoader
{
// methods
public:
// cdtors
StrmFileLoader(ut::FileStream &stream) : mStream(stream) {}
// methods
bool LoadFileHeader(void *buffer, u32 size);
int GetTrackCount() const;
int GetChannelCount() const;
bool ReadStrmInfo(StrmFileReader::StrmInfo *strmInfo) const;
bool ReadStrmTrackInfo(StrmFileReader::StrmTrackInfo *trackInfo,
int trackIndex) const;
bool ReadAdpcmInfo(AdpcmParam *adpcmParam,
AdpcmLoopParam *adpcmLoopParam,
int channelIndex) const;
bool ReadAdpcBlockData(u16 *yn1, u16 *yn2, int blockIndex,
int channelCount);
// members
private:
ut::FileStream &mStream; // size 0x04, offset 0x00
StrmFileReader mReader; // size 0x08, offset 0x04
}; // size 0x0c
}}} // namespace nw4r::snd::detail
#endif // NW4R_SND_STRM_FILE_H
|