Skip to content

Commit bf2b557

Browse files
Rocketctsandeepmistry
authored andcommitted
Add support for Wave files with LIST section (#11)
1 parent 80f7202 commit bf2b557

File tree

2 files changed

+56
-22
lines changed

2 files changed

+56
-22
lines changed

src/SDWaveFile.cpp

+55-22
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,26 @@
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/
2227
struct 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

4243
SDWaveFile::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
}

src/SDWaveFile.h

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class SDWaveFile : public SoundFile
6969
int _channels;
7070
long _frames;
7171
int _blockAlign;
72+
uint32_t _dataOffset;
7273
};
7374

7475
#endif

0 commit comments

Comments
 (0)