Skip to content

Commit 485f983

Browse files
committed
Add support for fmt's extrabyte
Added, in readheader internal API, a logic to ignore the extrabyte in fmt header's chunk in WAV file.
1 parent 80f7202 commit 485f983

File tree

2 files changed

+63
-12
lines changed

2 files changed

+63
-12
lines changed

src/SDWaveFile.cpp

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ long SDWaveFile::currentTime()
129129

130130
uint32_t position = _file.position();
131131

132-
if (position >= sizeof(struct WaveFileHeader)) {
133-
position -= sizeof(struct WaveFileHeader);
132+
if (position >= (sizeof(struct WaveFileHeader) + _headerOffset)) {
133+
position -= (sizeof(struct WaveFileHeader) + _headerOffset);
134134
}
135135

136136
return (position) / (_blockAlign * _sampleRate);
@@ -142,7 +142,7 @@ int SDWaveFile::cue(long time)
142142
return 1;
143143
}
144144

145-
long offset = (time * _blockAlign) - sizeof(struct WaveFileHeader);
145+
long offset = (time * _blockAlign) - sizeof(struct WaveFileHeader) - _headerOffset;
146146

147147
if (offset < 0) {
148148
offset = 0;
@@ -173,14 +173,48 @@ int SDWaveFile::begin()
173173
return 1;
174174
}
175175

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+
176210
int SDWaveFile::read(void* buffer, size_t size)
177211
{
178212
uint32_t position = _file.position();
179213
int read = _file.read(buffer, size);
180214

181215
if (position == 0) {
182216
// replace the header with 0's
183-
memset(buffer, 0x00, sizeof(struct WaveFileHeader));
217+
memset(buffer, 0x00, size);
184218
}
185219

186220
if (read) {
@@ -206,6 +240,7 @@ void SDWaveFile::end()
206240

207241
void SDWaveFile::readHeader()
208242
{
243+
int headerSize = 0;
209244
_isValid = false;
210245

211246
if (_headerRead) {
@@ -224,10 +259,30 @@ void SDWaveFile::readHeader()
224259
_file.close();
225260
return;
226261
}
227-
228262
struct WaveFileHeader header;
229263

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) {
231286
_file.close();
232287
return;
233288
}
@@ -238,7 +293,6 @@ void SDWaveFile::readHeader()
238293
header.chunkId = __REV(header.chunkId);
239294
header.format = __REV(header.format);
240295
header.subChunk1.id = __REV(header.subChunk1.id);
241-
header.subChunk2.id = __REV(header.subChunk2.id);
242296

243297
if (header.chunkId != 0x52494646) { // "RIFF"
244298
return;
@@ -256,11 +310,6 @@ void SDWaveFile::readHeader()
256310
return;
257311
}
258312

259-
if (header.subChunk1.size != 16 || header.subChunk1.audioFormat != 1) {
260-
// not PCM
261-
return;
262-
}
263-
264313
if (header.subChunk2.id != 0x64617461) { // "data"
265314
return;
266315
}

src/SDWaveFile.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class SDWaveFile : public SoundFile
5555

5656
private:
5757
void readHeader();
58+
int findData(int offset);
5859

5960
private:
6061
bool _headerRead;
@@ -69,6 +70,7 @@ class SDWaveFile : public SoundFile
6970
int _channels;
7071
long _frames;
7172
int _blockAlign;
73+
int _headerOffset;
7274
};
7375

7476
#endif

0 commit comments

Comments
 (0)