uint_t read_index;
uint_t eof;
+ size_t seek_start;
+
unsigned char *short_output;
fmat_t *output;
};
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;
s->fid = fopen((const char *)path, "rb");
if (!s->fid) {
- AUBIO_ERR("source_wavread: could not open %s (%s)\n", s->path, strerror(errno));
+ AUBIO_ERR("source_wavread: Failed opening %s (System error: %s)\n", s->path, strerror(errno));
goto beach;
}
// 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);
}
// 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);
}
// 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);
}
// 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
}
// 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;
}
// 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 ) {
}
// 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);
}
// 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 ) {
+#ifndef HAVE_WIN_HACKS
+ AUBIO_ERR("source_wavread: short read (%zd instead of %zd) in %s\n",
+#else // mingw does not know about %zd...
+ AUBIO_ERR("source_wavread: short read (%d instead of %d) in %s\n",
+#endif
+ 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;
}
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 = 0;
+ if ((sint_t)pos < 0) {
+ return AUBIO_FAIL;
+ }
+ ret = fseek(s->fid, s->seek_start + pos * s->blockalign, SEEK_SET);
+ if (ret != 0) {
+ AUBIO_ERR("source_wavread: could not seek %s at %d (%s)\n", s->path, pos, strerror(errno));
+ return AUBIO_FAIL;
+ }
+ // reset some values
s->eof = 0;
s->read_index = 0;
- return ret;
+ return AUBIO_OK;
+}
+
+uint_t aubio_source_wavread_close (aubio_source_wavread_t * s) {
+ if (!s->fid) {
+ return AUBIO_FAIL;
+ }
+ if (fclose(s->fid)) {
+ AUBIO_ERR("source_wavread: could not close %s (%s)\n", s->path, strerror(errno));
+ return AUBIO_FAIL;
+ }
+ s->fid = NULL;
+ return AUBIO_OK;
}
void del_aubio_source_wavread(aubio_source_wavread_t * s) {
if (!s) return;
- if (s->fid) fclose(s->fid);
+ aubio_source_wavread_close(s);
if (s->short_output) AUBIO_FREE(s->short_output);
if (s->output) del_fmat(s->output);
AUBIO_FREE(s);