ref: 87636d0635b083ee032b5885ef932af3dd3b0309
parent: 46b006901aca0014cdd4222a285bc9b29565902e
author: Paul Brossier <piem@piem.org>
date: Tue Mar 11 20:32:32 EDT 2014
src/io/source_wavread.c: use the return value of fread to detect short read and compute seek_start
--- a/src/io/source_wavread.c
+++ b/src/io/source_wavread.c
@@ -52,6 +52,8 @@
uint_t read_index;
uint_t eof;
+ size_t seek_start;
+
unsigned char *short_output;
fmat_t *output;
};
@@ -67,6 +69,7 @@
aubio_source_wavread_t * new_aubio_source_wavread(char_t * path, uint_t samplerate, uint_t hop_size) {
aubio_source_wavread_t * s = AUBIO_NEW(aubio_source_wavread_t);
+ size_t bytes_read = 0, bytes_expected = 44;
unsigned char buf[5];
unsigned int format, channels, sr, byterate, blockalign, bitspersample;//, data_size;
@@ -94,7 +97,7 @@
}
// ChunkID
- fread(buf, 4, 1, s->fid);
+ bytes_read += fread(buf, 1, 4, s->fid);
buf[4] = '\0';
if ( strcmp((const char *)buf, "RIFF") != 0 ) {
AUBIO_ERR("source_wavread: could not find RIFF header in %s\n", s->path);
@@ -102,10 +105,10 @@
}
// ChunkSize
- fread(buf, 4, 1, s->fid);
+ bytes_read += fread(buf, 1, 4, s->fid);
// Format
- fread(buf, 4, 1, s->fid);
+ bytes_read += fread(buf, 1, 4, s->fid);
buf[4] = '\0';
if ( strcmp((const char *)buf, "WAVE") != 0 ) {
AUBIO_ERR("source_wavread: wrong format in RIFF header in %s\n", s->path);
@@ -113,7 +116,7 @@
}
// Subchunk1ID
- fread(buf, 4, 1, s->fid);
+ bytes_read += fread(buf, 1, 4, s->fid);
buf[4] = '\0';
if ( strcmp((const char *)buf, "fmt ") != 0 ) {
AUBIO_ERR("source_wavread: fmt RIFF header in %s\n", s->path);
@@ -121,7 +124,7 @@
}
// Subchunk1Size
- fread(buf, 4, 1, s->fid);
+ bytes_read += fread(buf, 1, 4, s->fid);
format = read_little_endian(buf, 4);
if ( format != 16 ) {
// TODO accept format 18
@@ -134,7 +137,7 @@
}
// AudioFormat
- fread(buf, 2, 1, s->fid);
+ bytes_read += fread(buf, 1, 2, s->fid);
if ( buf[0] != 1 || buf[1] != 0) {
AUBIO_ERR("source_wavread: AudioFormat should be PCM, in %s\n", s->path);
goto beach;
@@ -141,23 +144,23 @@
}
// NumChannels
- fread(buf, 2, 1, s->fid);
+ bytes_read += fread(buf, 1, 2, s->fid);
channels = read_little_endian(buf, 2);
// SampleRate
- fread(buf, 4, 1, s->fid);
+ bytes_read += fread(buf, 1, 4, s->fid);
sr = read_little_endian(buf, 4);
// ByteRate
- fread(buf, 4, 1, s->fid);
+ bytes_read += fread(buf, 1, 4, s->fid);
byterate = read_little_endian(buf, 4);
// BlockAlign
- fread(buf, 2, 1, s->fid);
+ bytes_read += fread(buf, 1, 2, s->fid);
blockalign = read_little_endian(buf, 2);
// BitsPerSample
- fread(buf, 2, 1, s->fid);
+ bytes_read += fread(buf, 1, 2, s->fid);
bitspersample = read_little_endian(buf, 2);
#if 0
if ( bitspersample != 16 ) {
@@ -200,7 +203,7 @@
}
// Subchunk2ID
- fread(buf, 4, 1, s->fid);
+ bytes_read += fread(buf, 1, 4, s->fid);
buf[4] = '\0';
if ( strcmp((const char *)buf, "data") != 0 ) {
AUBIO_ERR("source_wavread: data RIFF header not found in %s\n", s->path);
@@ -208,10 +211,18 @@
}
// Subchunk2Size
- fread(buf, 4, 1, s->fid);
+ bytes_read += fread(buf, 1, 4, s->fid);
//data_size = buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24);
//AUBIO_MSG("found %d frames in %s\n", 8 * data_size / bitspersample / channels, s->path);
+ // check the total number of bytes read is correct
+ if ( bytes_read != bytes_expected ) {
+ AUBIO_ERR("source_wavread: short read (%zd instead of %zd) in %s\n",
+ bytes_read, bytes_expected, s->path);
+ goto beach;
+ }
+ s->seek_start = bytes_read;
+
s->output = new_fmat(s->input_channels, AUBIO_WAVREAD_BUFSIZE);
s->blockalign= blockalign;
s->bitspersample = bitspersample;
@@ -340,7 +351,7 @@
}
uint_t aubio_source_wavread_seek (aubio_source_wavread_t * s, uint_t pos) {
- uint_t ret = fseek(s->fid, 44 + pos * s->blockalign, SEEK_SET);
+ uint_t ret = fseek(s->fid, s->seek_start + pos * s->blockalign, SEEK_SET);
s->eof = 0;
s->read_index = 0;
return ret;