sox-users@lists.sourceforge.net unofficial mirror
 help / color / mirror / code / Atom feed
From: Jan Stary <hans@stare.cz>
To: sox-users@lists.sourceforge.net
Subject: Re: how to interpret tell_off, and the right way to use sox_seek
Date: Tue, 7 Nov 2017 10:13:48 +0100	[thread overview]
Message-ID: <20171107091348.GB10645@www.stare.cz> (raw)
In-Reply-To: <20171107090140.GA10645@www.stare.cz>

On Nov 07 10:01:41, hans@stare.cz wrote:
> On Nov 07 09:50:36, hans@stare.cz 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@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sox-users

  reply	other threads:[~2017-11-07  9:14 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-04  7:26 how to interpret tell_off, and the right way to use sox_seek Dan Hitt
2017-11-06 11:10 ` Jan Stary
2017-11-06 18:08   ` Dan Hitt
2017-11-06 19:06     ` Jan Stary
2017-11-06 20:14       ` Dan Hitt
2017-11-06 21:09         ` Jan Stary
2017-11-06 21:47           ` Dan Hitt
2017-11-07  8:50             ` Jan Stary
2017-11-07  9:01               ` Jan Stary
2017-11-07  9:13                 ` Jan Stary [this message]
2017-11-07  9:22                   ` Jan Stary

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://lists.sourceforge.net/lists/listinfo/sox-users

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171107091348.GB10645@www.stare.cz \
    --to=sox-users@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/sox.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).