-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRIFF.hpp
374 lines (321 loc) · 12.8 KB
/
RIFF.hpp
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
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
#pragma once
//---------------------------------------------------------------------------//
//
// RIFF.hpp
// Structure declarations for RIFF/RF64 file format
//
// See Also:
// https://tech.ebu.ch/docs/tech/tech3306.pdf
// https://tech.ebu.ch/docs/tech/tech3306-2009.pdf
// http://d0ec7852ef61.seesaa.net/article/183599694.html
//
//---------------------------------------------------------------------------//
#include <cstdint>
#pragma warning(disable: 4200)
#pragma warning(disable: 4201)
//---------------------------------------------------------------------------//
static constexpr char chunkId_RIFF[4] = { 'R', 'I', 'F', 'F' };
static constexpr char chunkId_JUNK[4] = { 'J', 'U', 'N', 'K' };
static constexpr char chunkId_fmt [4] = { 'f', 'm', 't', ' ' };
static constexpr char chunkId_data[4] = { 'd', 'a', 't', 'a' };
static constexpr char chunkId_fact[4] = { 'f', 'a', 'c', 't' };
static constexpr char chunkId_RF64[4] = { 'R', 'F', '6', '4' };
static constexpr char chunkId_ds64[4] = { 'd', 's', '6', '4' };
static constexpr char chunkId_LIST[4] = { 'L', 'I', 'S', 'T' };
static constexpr char chunkId_INFO[4] = { 'I', 'N', 'F', 'O' };
static constexpr char chunkId_wavl[4] = { 'w', 'a', 'v', 'l' };
static constexpr char chunkId_slnt[4] = { 's', 'l', 'n', 't' };
static constexpr char chunkId_cue [4] = { 'c', 'u', 'e', ' ' };
static constexpr char chunkId_plst[4] = { 'p', 'l', 's', 't' };
static constexpr char chunkId_list[4] = { 'l', 'i', 's', 't' };
static constexpr char chunkId_labl[4] = { 'l', 'a', 'b', 'l' };
static constexpr char chunkId_note[4] = { 'n', 'o', 't', 'e' };
static constexpr char chunkId_ltxt[4] = { 'l', 't', 'x', 't' };
static constexpr char chunkId_smpl[4] = { 's', 'm', 'p', 'l' };
static constexpr char chunkId_inst[4] = { 'i', 'n', 's', 't' };
static constexpr char chunkId_r64m[4] = { 'r', '6', '4', 'm' };
static constexpr char chunkId_bext[4] = { 'b', 'e', 'x', 't' };
static constexpr char chunkId_iXML[4] = { 'i', 'X', 'M', 'L' };
static constexpr char chunkId_qlty[4] = { 'q', 'l', 't', 'y' };
static constexpr char chunkId_mext[4] = { 'm', 'e', 'x', 't' };
static constexpr char chunkId_levl[4] = { 'l', 'e', 'v', 'l' };
static constexpr char chunkId_link[4] = { 'l', 'i', 'n', 'k' };
static constexpr char chunkId_axml[4] = { 'a', 'x', 'm', 'l' };
static constexpr char chunkId_cont[4] = { 'c', 'o', 'n', 't' };
static constexpr char riffType_WAVE[4] = { 'W', 'A', 'V', 'E' };
//---------------------------------------------------------------------------//
struct Guid;
struct RiffChunk;
struct JunkChunk;
struct FormatChunk;
struct DataChunk;
struct RF64Chunk;
struct ChunkSize64;
struct DataSize64ChunkLight;
struct DataSize64Chunk;
struct FormatExtensibleChunk;
struct CuePoint;
struct CueChunk;
struct ListChunk;
struct LabelChunk;
struct MarkerEntry;
struct MarkerChunk;
//---------------------------------------------------------------------------//
#pragma pack(push, 1)
//---------------------------------------------------------------------------//
struct Guid
{
uint32_t data1;
uint16_t data2;
uint16_t data3;
uint32_t data4;
uint32_t data5;
};
//---------------------------------------------------------------------------//
struct RiffChunk
{
char chunkId[4]; // 'RIFF'
uint32_t chunkSize; // 4 byte size of the traditional RIFF/WAVE file
char riffType[4]; // 'WAVE'
};
//---------------------------------------------------------------------------//
struct JunkChunk
{
char chunkId[4]; // 'JUNK'
uint32_t chunkSize; // 4 byte size of the 'JUNK' chunk. This must be
// at least 28 if the chunk is intended as a
// place-holder for a 'ds64' chunk.
uint8_t chunkData[0]; // dummy bytes
};
//---------------------------------------------------------------------------//
struct FormatChunk
{
char chunkId[4]; // 'fmt '
uint32_t chunkSize; // 4 byte size of the 'fmt ' chunk
uint16_t formatType; // WAVE_FORMAT_PCM = 0x0001, etc.
uint16_t channelCount; // 1 = mono, 2 = stereo, etc.
uint32_t sampleRate; // 32000, 44100, 48000, etc.
uint32_t bytesPerSecond; // only important for compressed formats
uint16_t blockAlignment; // container size (in bytes) of one set of samples
uint16_t bitsPerSample; // valid bits per sample 16, 20 or 24
uint16_t cbSize = 0; // extra information (after cbSize) to store
uint8_t extraData[22]; // extra data of WAVE_FORMAT_EXTENSIBLE when necessary
};
//---------------------------------------------------------------------------//
struct DataChunk
{
char chunkId[4]; // 'data'
uint32_t chunkSize; // 4 byte size of the 'data' chunk
uint8_t waveData[0]; // audio samples
};
//---------------------------------------------------------------------------//
struct FactChunk
{
char chunkId[4]; // 'fact'
uint32_t chunkSize; // 4 byte size of the 'data' chunk
uint32_t sample_count; // total sample count
};
//---------------------------------------------------------------------------//
struct RF64Chunk
{
char chunkId[4]; // 'RF64'
uint32_t chunkSize; // -1 = 0xFFFFFFFF means don't use this data, use
// riffSizeHigh and riffSizeLow in 'ds64' chunk instead
char rf64Type[4]; // 'WAVE'
};
//---------------------------------------------------------------------------//
struct ChunkSize64
{
char chunkId[4]; // chunk ID (i.e. "big1" – this chunk is a big one)
union
{
uint64_t chunkSize; // 8 byte size of the chunk
struct
{
uint32_t chunkSizeLow;
uint32_t chunkSizeHigh;
};
};
};
//---------------------------------------------------------------------------//
struct DataSize64ChunkLight
{
char chunkId[4]; // 'ds64'
uint32_t chunkSize; // 4 byte size of the 'ds64' chunk
union
{
uint64_t riffSize; // 8 byte size of the RF64 block
struct
{
uint32_t riffSizeLow;
uint32_t riffSizeHigh;
};
};
union
{
uint64_t dataSize; // 8 byte size of the data chunk
struct
{
uint32_t dataSizeLow;
uint32_t dataSizeHigh;
};
};
};
//---------------------------------------------------------------------------//
struct DataSize64Chunk
{
char chunkId[4]; // 'ds64'
uint32_t chunkSize; // 4 byte size of the 'ds64' chunk
union
{
uint64_t riffSize; // 8 byte size of the RF64 block
struct
{
uint32_t riffSizeLow;
uint32_t riffSizeHigh;
};
};
union
{
uint64_t dataSize; // 8 byte size of the data chunk
struct
{
uint32_t dataSizeLow;
uint32_t dataSizeHigh;
};
};
union
{
uint64_t sampleCount;// 8 byte sample count of fact chunk
struct
{
uint32_t sampleCountLow;
uint32_t sampleCountHigh;
};
};
uint32_t tableLength; // number of valid entries in array "table"
ChunkSize64 table[0];
};
//---------------------------------------------------------------------------//
struct FormatExtensibleChunk
{
char chunkId[4]; // 'fmt '
uint32_t chunkSize; // 4 byte size of the 'fmt ' chunk
uint16_t formatType; // WAVE_FORMAT_EXTENSIBLE = 0xFFFE
uint16_t channelCount; // 1 = mono, 2 = stereo, etc.
uint32_t sampleRate; // 32000, 44100, 48000, etc.
uint32_t bytesPerSecond; // only important for compressed formats
uint16_t blockAlignment; // container size (in bytes) of one set of samples
uint16_t bitsPerSample; // bits per sample in container size * 8, i.e. 8, 16, 24
uint16_t cbSize = 22; // extra information (after cbSize) to store
uint16_t validBitsPerSample; // valid bits per sample i.e. 8, 16, 20, 24
uint32_t channelMask; // channel mask for channel allocation
Guid subFormat; // KSDATAFORMAT_SUBTYPE_PCM
// data1 = 0x00000001
// data2 = 0x0000
// data3 = 0x0010
// data4 = 0xAA000080
// data5 = 0x719B3800
};
//---------------------------------------------------------------------------//
struct CuePoint // declare CuePoint structure
{
uint32_t identifier; // unique identifier for the cue point
uint32_t position; // position of the cue point in the play order
char dataChunkId[4]; // normally 'data'
uint32_t chunkStart; // used for wave lists
uint32_t blockStart; // Start of compressed data block containing the cue point
// (not used for PCM)
uint32_t sampleOffset; // sample offset of cue point (absolute for PCM,
// relative to block start for compressed data)
};
//---------------------------------------------------------------------------//
struct CueChunk // declare CueChunk structure
{
char chunkId[4]; // 'cue '
uint32_t chunkSize; // 4 byte size of the 'cue ' chunk
uint32_t cuePointCount; // number of cue points (markers)
CuePoint cuePoints[0]; // cue points
};
//---------------------------------------------------------------------------//
struct ListChunk // declare ListChunk structure
{
char chunkId[4]; // 'list'
uint32_t chunkSize; // 4 byte size of the 'list' chunk
char typeId[4]; // 'adtl' associated data list
};
//---------------------------------------------------------------------------//
struct LabelChunk // declare LabelChunk structure
{
char chunkId[4]; // 'labl'
uint32_t chunkSize; // 4 byte size of the 'labl' chunk
uint32_t identifier; // unique identifier for the cue point
char text[0]; // label text: null terminated string (ANSI)
};
//---------------------------------------------------------------------------//
struct MarkerEntry // declare MarkerEntry structure
{
uint32_t flags; // flags field
union
{
uint64_t sampleOffse; // 8 byte marker's offset in samples in data chunk
struct
{
uint32_t sampleOffsetLow;
uint32_t sampleOffsetHigh;
};
};
union
{
uint64_t byteOffset; // 8 byte of the beginning of the nearest
struct // compressed frame next to marker (timely before)
{
uint32_t byteOffsetLow;
uint32_t byteOffsetHigh;
};
};
union
{
uint64_t intraSmplOffset; // 8 byte of marker's offset in samples
struct // relative to the position of the first sample in frame
{
uint32_t intraSmplOffsetHigh;
uint32_t intraSmplOffsetLow;
};
};
uint8_t labelText[256]; // null terminated label string
// (the encoding depends on the Bit 4 of "flags" field)
uint32_t lablChunkIdentifier; // link to 'labl' subchunk of 'list' chunk8
Guid vendorAndProduct; // GUID identifying specific vendor application
uint32_t userData1; // 4 byte application specific user data
uint32_t userData2; // 4 byte application specific user data
uint32_t userData3; // 4 byte application specific user data
uint32_t userData4; // 4 byte application specific user data
};
//---------------------------------------------------------------------------//
struct MarkerChunk // declare MarkerChunk structure
{
char chunkId[4]; // 'r64m'
uint32_t chunkSize; // 4 byte size of the 'r64m' chunk
MarkerEntry markers[0]; // marker entries
};
//---------------------------------------------------------------------------//
//
// Definition of the flags field of MarkerEntry structure
//
// The flags field defines different features of the chunk and validity of fields in the struct.
// Bit 0 0 entry is invalid (skip entry)
// 1 entry is valid
// Bit 1 0 byteOffset is invalid (do not use)
// 1 byteOffset is valid
// Bit 2 0 intraSmplOffset is invalid (do not use)
// 1 intraSmplOffset is valid
// Bit 3 0 labelText is holding marker’s label string (if label string is empty, marker has no label)
// 1 marker’s label is stored in ‘labl’ chunk; use lablChunkIdentifier to retrieve
// Bit 4 0 labelText string is ANSI
// 1 labelText string is UTF-8
//
//---------------------------------------------------------------------------//
#pragma pack(pop)
//---------------------------------------------------------------------------//
// RIFF.hpp