On Nov 07 10:01:41, hans@xxxxxxxx wrote: > On Nov 07 09:50:36, hans@xxxxxxxx wrote: > > So I think you are right. It does seek back to the begining of the sine wave > > (thus reporting 0 as the first sample value in the buffer), but it gets > > exhausted at EOF anyway. I suspect now it is a bug in sox_seek() > > if we are calling it right. > > Much as I like sox, I don't trust this code very much: > > int sox_seek(sox_format_t * ft, sox_uint64_t offset, int whence) > { > /* FIXME: Implement SOX_SEEK_CUR and SOX_SEEK_END. */ > if (whence != SOX_SEEK_SET) > return SOX_EOF; /* FIXME: return SOX_EINVAL */ > > /* If file is a seekable file and this handler supports seeking, > * then invoke handler's function. > */ > if (ft->seekable && ft->handler.seek) > return (*ft->handler.seek)(ft, offset); > return SOX_EOF; /* FIXME: return SOX_EBADF */ > } This is wav's handler's seek() from src/wav.c (14.4.2): static int seek(sox_format_t * ft, uint64_t offset) { priv_t * wav = (priv_t *) ft->priv; if (ft->encoding.bits_per_sample & 7) lsx_fail_errno(ft, SOX_ENOTSUP, "seeking not supported with this encoding"); else if (wav->formatTag == WAVE_FORMAT_GSM610) { int alignment; size_t gsmoff; /* rounding bytes to blockAlign so that we * don't have to decode partial block. */ gsmoff = offset * wav->blockAlign / wav->samplesPerBlock + wav->blockAlign * ft->signal.channels / 2; gsmoff -= gsmoff % (wav->blockAlign * ft->signal.channels); ft->sox_errno = lsx_seeki(ft, (off_t)(gsmoff + wav->dataStart), SEEK_SET); if (ft->sox_errno == SOX_SUCCESS) { /* offset is in samples */ uint64_t new_offset = offset; alignment = offset % wav->samplesPerBlock; if (alignment != 0) new_offset += (wav->samplesPerBlock - alignment); wav->numSamples = ft->signal.length - (new_offset / ft->signal.channels); } } else { double wide_sample = offset - (offset % ft->signal.channels); double to_d = wide_sample * ft->encoding.bits_per_sample / 8; off_t to = to_d; ft->sox_errno = (to != to_d)? SOX_EOF : lsx_seeki(ft, (off_t)wav->dataStart + (off_t)to, SEEK_SET); if (ft->sox_errno == SOX_SUCCESS) wav->numSamples -= (size_t)wide_sample / ft->signal.channels; } return ft->sox_errno; } It seems you are right: wav->numSamples get decremented no matter what. That seems wrong, but I am not sure if that is exactly our problem. This is the lsx_seeki() (in src/formats_i.c) that eventually does fseeko() on the underlying (FILE*)ft->fp /* Implements traditional fseek() behavior. Meant to abstract out * file operations so that they could one day also work on memory * buffers. * * N.B. Can only seek forwards on non-seekable streams! */ int lsx_seeki(sox_format_t * ft, off_t offset, int whence) { if (ft->seekable == 0) { /* If a stream peel off chars else EPERM */ if (whence == SEEK_CUR) { while (offset > 0 && !feof((FILE*)ft->fp)) { getc((FILE*)ft->fp); offset--; ++ft->tell_off; } if (offset) lsx_fail_errno(ft,SOX_EOF, "offset past EOF"); else ft->sox_errno = SOX_SUCCESS; } else lsx_fail_errno(ft,SOX_EPERM, "file not seekable"); } else { if (fseeko((FILE*)ft->fp, offset, whence) == -1) lsx_fail_errno(ft,errno, "%s", strerror(errno)); else ft->sox_errno = SOX_SUCCESS; } return ft->sox_errno; } Jan ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Sox-users mailing list Sox-users@xxxxxxxxxxxxxxxxxxxxx https://lists.sourceforge.net/lists/listinfo/sox-users