Re: how to interpret tell_off, and the right way to use sox_seek

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux Sound]     [ALSA Users]     [ALSA Devel]     [Linux Audio Users]     [Linux Media]     [Kernel]     [Photo Sharing]     [Gimp]     [Yosemite News]     [Linux Media]

  Powered by Linux