1818
1919#include " SDWaveFile.h"
2020
21+ struct SubChunkHeader {
22+ uint32_t id;
23+ uint32_t size;
24+ };
25+
2126// based on: http://soundfile.sapp.org/doc/WaveFormat/
2227struct WaveFileHeader {
2328 uint32_t chunkId;
2429 uint32_t chunkSize;
2530 uint32_t format;
2631 struct {
27- uint32_t id;
28- uint32_t size;
32+ struct SubChunkHeader header;
2933 uint16_t audioFormat;
3034 uint16_t numChannels;
3135 uint32_t sampleRate;
3236 uint32_t byteRate;
3337 uint16_t blockAlign;
3438 uint16_t bitsPerSample;
3539 } subChunk1;
36- struct {
37- uint32_t id;
38- uint32_t size;
39- } subChunk2;
40+ struct SubChunkHeader subChunk2Header;
4041} __attribute__((packed));
4142
4243SDWaveFile::SDWaveFile () :
@@ -53,7 +54,8 @@ SDWaveFile::SDWaveFile(const char* filename) :
5354 _sampleRate(-1 ),
5455 _bitsPerSample(-1 ),
5556 _channels(-1 ),
56- _frames(-1 )
57+ _frames(-1 ),
58+ _dataOffset(0 )
5759{
5860
5961}
@@ -129,8 +131,8 @@ long SDWaveFile::currentTime()
129131
130132 uint32_t position = _file.position ();
131133
132- if (position >= sizeof ( struct WaveFileHeader ) ) {
133- position -= sizeof ( struct WaveFileHeader ) ;
134+ if (position >= _dataOffset ) {
135+ position -= _dataOffset ;
134136 }
135137
136138 return (position) / (_blockAlign * _sampleRate);
@@ -142,7 +144,7 @@ int SDWaveFile::cue(long time)
142144 return 1 ;
143145 }
144146
145- long offset = (time * _blockAlign) - sizeof ( struct WaveFileHeader ) ;
147+ long offset = (time * _blockAlign) - _dataOffset ;
146148
147149 if (offset < 0 ) {
148150 offset = 0 ;
@@ -180,7 +182,7 @@ int SDWaveFile::read(void* buffer, size_t size)
180182
181183 if (position == 0 ) {
182184 // replace the header with 0's
183- memset (buffer, 0x00 , sizeof ( struct WaveFileHeader ) );
185+ memset (buffer, 0x00 , _dataOffset );
184186 }
185187
186188 if (read) {
@@ -226,50 +228,81 @@ void SDWaveFile::readHeader()
226228 }
227229
228230 struct WaveFileHeader header;
231+ int headerSize;
232+ int subChunk2Offset = 0 ;
233+ struct SubChunkHeader sch;
229234
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) {
231237 _file.close ();
232238 return ;
233239 }
234- _file.close ();
235-
236- _headerRead = true ;
237240
238241 header.chunkId = __REV (header.chunkId );
239242 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 );
242244
243245 if (header.chunkId != 0x52494646 ) { // "RIFF"
246+ _file.close ();
244247 return ;
245248 }
246249
247250 if ((fileSize - 8 ) != header.chunkSize ) {
251+ _file.close ();
248252 return ;
249253 }
250254
251255 if (header.format != 0x57415645 ) { // "WAVE"
256+ _file.close ();
252257 return ;
253258 }
254259
255- if (header.subChunk1 .id != 0x666d7420 ) { // "fmt "
260+ if (header.subChunk1 .header .id != 0x666d7420 ) { // "fmt "
261+ _file.close ();
256262 return ;
257263 }
258264
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 ();
261267 return ;
262268 }
263269
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 ();
265293 return ;
266294 }
267295
296+ _dataOffset = sizeof (struct WaveFileHeader ) + subChunk2Offset;
297+ _file.close ();
298+
299+ _headerRead = true ;
300+
268301 _channels = header.subChunk1 .numChannels ;
269302 _sampleRate = header.subChunk1 .sampleRate ;
270303 _bitsPerSample = header.subChunk1 .bitsPerSample ;
271304 _blockAlign = header.subChunk1 .blockAlign ;
272- _frames = header.subChunk2 .size / _blockAlign;
305+ _frames = header.subChunk2Header .size / _blockAlign;
273306
274307 _isValid = true ;
275308}
0 commit comments