@@ -129,8 +129,8 @@ long SDWaveFile::currentTime()
129
129
130
130
uint32_t position = _file.position ();
131
131
132
- if (position >= sizeof (struct WaveFileHeader )) {
133
- position -= sizeof (struct WaveFileHeader );
132
+ if (position >= ( sizeof (struct WaveFileHeader ) + _headerOffset )) {
133
+ position -= ( sizeof (struct WaveFileHeader ) + _headerOffset );
134
134
}
135
135
136
136
return (position) / (_blockAlign * _sampleRate);
@@ -142,7 +142,7 @@ int SDWaveFile::cue(long time)
142
142
return 1 ;
143
143
}
144
144
145
- long offset = (time * _blockAlign) - sizeof (struct WaveFileHeader );
145
+ long offset = (time * _blockAlign) - sizeof (struct WaveFileHeader ) - _headerOffset ;
146
146
147
147
if (offset < 0 ) {
148
148
offset = 0 ;
@@ -173,14 +173,48 @@ int SDWaveFile::begin()
173
173
return 1 ;
174
174
}
175
175
176
+ int SDWaveFile::findData (int offset) {
177
+ uint8_t byteread;
178
+ int count = 0 , fileSize;
179
+ uint32_t data;
180
+ uint8_t buffer[] = {0 , 0 , 0 , 0 };
181
+
182
+ fileSize = _file.size () - offset;
183
+
184
+ // check if "data" field is present
185
+ while (count < fileSize) {
186
+ if (_file.read ((void *)&byteread, 1 ) != 1 ) {
187
+ return -1 ;
188
+ }
189
+ for (int i = 0 ; i <= 2 ; i++) {
190
+ buffer[i] = buffer[i + 1 ];
191
+ }
192
+ buffer[3 ] = byteread;
193
+ count++;
194
+
195
+ if (count >= 4 ) {
196
+ data = 0 ;
197
+ data += buffer[0 ] << 24 ;
198
+ data += buffer[1 ] << 16 ;
199
+ data += buffer[2 ] << 8 ;
200
+ data += buffer[3 ];
201
+ // if find data field read return the offset size of the subchunk1
202
+ if (data == 0x64617461 ) {
203
+ return count;
204
+ }
205
+ }
206
+ }
207
+ return -1 ;
208
+ }
209
+
176
210
int SDWaveFile::read (void * buffer, size_t size)
177
211
{
178
212
uint32_t position = _file.position ();
179
213
int read = _file.read (buffer, size);
180
214
181
215
if (position == 0 ) {
182
216
// replace the header with 0's
183
- memset (buffer, 0x00 , sizeof ( struct WaveFileHeader ) );
217
+ memset (buffer, 0x00 , size );
184
218
}
185
219
186
220
if (read) {
@@ -206,6 +240,7 @@ void SDWaveFile::end()
206
240
207
241
void SDWaveFile::readHeader ()
208
242
{
243
+ int headerSize = 0 ;
209
244
_isValid = false ;
210
245
211
246
if (_headerRead) {
@@ -224,10 +259,30 @@ void SDWaveFile::readHeader()
224
259
_file.close ();
225
260
return ;
226
261
}
227
-
228
262
struct WaveFileHeader header;
229
263
230
- if (_file.read (&header, sizeof (header)) != sizeof (header)) {
264
+ headerSize = sizeof (struct WaveFileHeader ) - sizeof (header.subChunk2 );
265
+ // Read the first WAV header's chunk
266
+ if (_file.read (&header, headerSize) != headerSize) {
267
+ _file.close ();
268
+ return ;
269
+ }
270
+
271
+ if (header.subChunk1 .audioFormat != 1 ) {
272
+ _file.close ();
273
+ return ;
274
+ }
275
+
276
+ _headerOffset = findData (headerSize);
277
+ if (_headerOffset == -1 ) {
278
+ _file.close ();
279
+ return ;
280
+ }
281
+ // if findData goes fine, data label is assigned to subChunk2.id
282
+ header.subChunk2 .id = 0x64617461 ;
283
+
284
+ int size = sizeof (header.subChunk2 .size );
285
+ if (_file.read (&(header.subChunk2 .size ), size) != size) {
231
286
_file.close ();
232
287
return ;
233
288
}
@@ -238,7 +293,6 @@ void SDWaveFile::readHeader()
238
293
header.chunkId = __REV (header.chunkId );
239
294
header.format = __REV (header.format );
240
295
header.subChunk1 .id = __REV (header.subChunk1 .id );
241
- header.subChunk2 .id = __REV (header.subChunk2 .id );
242
296
243
297
if (header.chunkId != 0x52494646 ) { // "RIFF"
244
298
return ;
@@ -256,11 +310,6 @@ void SDWaveFile::readHeader()
256
310
return ;
257
311
}
258
312
259
- if (header.subChunk1 .size != 16 || header.subChunk1 .audioFormat != 1 ) {
260
- // not PCM
261
- return ;
262
- }
263
-
264
313
if (header.subChunk2 .id != 0x64617461 ) { // "data"
265
314
return ;
266
315
}
0 commit comments