18
18
19
19
#include " SDWaveFile.h"
20
20
21
+ struct SubChunkHeader {
22
+ uint32_t id;
23
+ uint32_t size;
24
+ };
25
+
21
26
// based on: http://soundfile.sapp.org/doc/WaveFormat/
22
27
struct WaveFileHeader {
23
28
uint32_t chunkId;
24
29
uint32_t chunkSize;
25
30
uint32_t format;
26
31
struct {
27
- uint32_t id;
28
- uint32_t size;
32
+ struct SubChunkHeader header;
29
33
uint16_t audioFormat;
30
34
uint16_t numChannels;
31
35
uint32_t sampleRate;
32
36
uint32_t byteRate;
33
37
uint16_t blockAlign;
34
38
uint16_t bitsPerSample;
35
39
} subChunk1;
36
- struct {
37
- uint32_t id;
38
- uint32_t size;
39
- } subChunk2;
40
+ struct SubChunkHeader subChunk2Header;
40
41
} __attribute__((packed));
41
42
42
43
SDWaveFile::SDWaveFile () :
@@ -53,7 +54,8 @@ SDWaveFile::SDWaveFile(const char* filename) :
53
54
_sampleRate(-1 ),
54
55
_bitsPerSample(-1 ),
55
56
_channels(-1 ),
56
- _frames(-1 )
57
+ _frames(-1 ),
58
+ _dataOffset(0 )
57
59
{
58
60
59
61
}
@@ -129,8 +131,8 @@ long SDWaveFile::currentTime()
129
131
130
132
uint32_t position = _file.position ();
131
133
132
- if (position >= sizeof ( struct WaveFileHeader ) ) {
133
- position -= sizeof ( struct WaveFileHeader ) ;
134
+ if (position >= _dataOffset ) {
135
+ position -= _dataOffset ;
134
136
}
135
137
136
138
return (position) / (_blockAlign * _sampleRate);
@@ -142,7 +144,7 @@ int SDWaveFile::cue(long time)
142
144
return 1 ;
143
145
}
144
146
145
- long offset = (time * _blockAlign) - sizeof ( struct WaveFileHeader ) ;
147
+ long offset = (time * _blockAlign) - _dataOffset ;
146
148
147
149
if (offset < 0 ) {
148
150
offset = 0 ;
@@ -180,7 +182,7 @@ int SDWaveFile::read(void* buffer, size_t size)
180
182
181
183
if (position == 0 ) {
182
184
// replace the header with 0's
183
- memset (buffer, 0x00 , sizeof ( struct WaveFileHeader ) );
185
+ memset (buffer, 0x00 , _dataOffset );
184
186
}
185
187
186
188
if (read ) {
@@ -226,50 +228,81 @@ void SDWaveFile::readHeader()
226
228
}
227
229
228
230
struct WaveFileHeader header;
231
+ int headerSize;
232
+ int subChunk2Offset = 0 ;
233
+ struct SubChunkHeader sch;
229
234
230
- if (_file.read (&header, sizeof (header)) != sizeof (header)) {
235
+ headerSize = sizeof (struct WaveFileHeader ) - sizeof (header.subChunk2Header );
236
+ if (_file.read ((void *)&header, headerSize) != headerSize) {
231
237
_file.close ();
232
238
return ;
233
239
}
234
- _file.close ();
235
-
236
- _headerRead = true ;
237
240
238
241
header.chunkId = __REV (header.chunkId );
239
242
header.format = __REV (header.format );
240
- header.subChunk1 .id = __REV (header.subChunk1 .id );
241
- header.subChunk2 .id = __REV (header.subChunk2 .id );
243
+ header.subChunk1 .header .id = __REV (header.subChunk1 .header .id );
242
244
243
245
if (header.chunkId != 0x52494646 ) { // "RIFF"
246
+ _file.close ();
244
247
return ;
245
248
}
246
249
247
250
if ((fileSize - 8 ) != header.chunkSize ) {
251
+ _file.close ();
248
252
return ;
249
253
}
250
254
251
255
if (header.format != 0x57415645 ) { // "WAVE"
256
+ _file.close ();
252
257
return ;
253
258
}
254
259
255
- if (header.subChunk1 .id != 0x666d7420 ) { // "fmt "
260
+ if (header.subChunk1 .header .id != 0x666d7420 ) { // "fmt "
261
+ _file.close ();
256
262
return ;
257
263
}
258
264
259
- if (header.subChunk1 .size != 16 || header.subChunk1 .audioFormat != 1 ) {
260
- // not PCM
265
+ if (header.subChunk1 .header . size != 16 || header.subChunk1 .audioFormat != 1 ) {
266
+ _file. close ();
261
267
return ;
262
268
}
263
269
264
- if (header.subChunk2 .id != 0x64617461 ) { // "data"
270
+ while (_file.available ()) {
271
+ if (_file.read ((void *)&(sch), sizeof (sch)) != sizeof (sch)) {
272
+ _file.close ();
273
+ return ;
274
+ }
275
+
276
+ sch.id = __REV (sch.id );
277
+
278
+ if (sch.id == 0x64617461 ) {
279
+ // found the data section
280
+ header.subChunk2Header .id = sch.id ;
281
+ header.subChunk2Header .size = sch.size ;
282
+ break ;
283
+ }
284
+
285
+ // skip this header section
286
+ _file.seek (_file.position () + sch.size );
287
+ subChunk2Offset += (sizeof (sch) + sch.size );
288
+ }
289
+
290
+ if (header.subChunk2Header .id != 0x64617461 ) { // "data"
291
+ // no data section found
292
+ _file.close ();
265
293
return ;
266
294
}
267
295
296
+ _dataOffset = sizeof (struct WaveFileHeader ) + subChunk2Offset;
297
+ _file.close ();
298
+
299
+ _headerRead = true ;
300
+
268
301
_channels = header.subChunk1 .numChannels ;
269
302
_sampleRate = header.subChunk1 .sampleRate ;
270
303
_bitsPerSample = header.subChunk1 .bitsPerSample ;
271
304
_blockAlign = header.subChunk1 .blockAlign ;
272
- _frames = header.subChunk2 .size / _blockAlign;
305
+ _frames = header.subChunk2Header .size / _blockAlign;
273
306
274
307
_isValid = true ;
275
308
}
0 commit comments