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: Mon, 6 Nov 2017 22:09:35 +0100	[thread overview]
Message-ID: <20171106210932.GA41280@www.stare.cz> (raw)
In-Reply-To: <CAOphizLLcY6LX=q3SZk0MwGq9SMeutbmLkMrhWyPStxu79hMZQ@mail.gmail.com>

On Nov 06 12:14:59, dan.hitt@gmail.com wrote:
> On Mon, Nov 6, 2017 at 11:06 AM, Jan Stary <hans@stare.cz> wrote:
> >> I do take your message to imply that SoX will read no more samples
> >> than the number of in a file total, so that, e.g., if you read the
> >> same 10 blocks of samples and sox_seek() to the beginning of them
> >> repeatedly, eventually your reads will fail.  And in fact, if the
> >> length of the file is 50 blocks, those reads will fail as soon as you
> >> have done this 5 times.  If this is not correct, please let me know!!
> >> :)
> >
> > There is a difference between SoX the utility and libsox the library.
> > I am not sure if SoX itself ever reads a block of audio more than once
> > (I can imagina situations where it would), but that's not a constraint
> > on what the libsox library can do. If it has a sox_seek(), then I suppose
> > it does what the name says; in particular, it lets you read the same
> > block of audio over ano over again as long as you keep seekign back.
> > (Disclaimer: I have never used libsox directly,
> > I only use SoX the binary.)
> 
> This is the crux of the matter, and appears not to be the case.
> 
> I wrote a little program to test exactly this assertion, that you
> cannot repeatedly
> call sox_seek().
> 
> The answer here appears to be that indeed you cannot.
> 
> Here's the test program:
> 
>     #include <stdio.h>
>     #include <stdlib.h>
>     #include <sox.h>
> 
>     int main( int argc, char** argv ) {
>       if ( argc < 2 )  {
>         fprintf(stderr,"Call with one arg, the name of a sound file.\n" );
>         exit(1);
>       }
>       int istat = sox_init();
>       if (istat != SOX_SUCCESS ) {
>         fprintf(stderr, "Failed to initialize sox, error %d.\n", istat);
>         exit(1);
>       }
>       char* infile = argv[1];
>       sox_format_t* s = sox_open_read( infile, 0, 0, 0 );
>       if ( ! s ) {
>         fprintf(stderr,"Failed to open `%s' .\n", infile);
>         exit(1);
>       }
>       int buf[1024];
>       int count = 0;
>       while ( 1 ) {
>         int rcnt = sox_read( s, buf, 1024 );
>         if ( rcnt <= 0 ) {
>           printf( "Failed on read, attempt %d\n", count );
>           exit( 0 );
>         }
>         int status = sox_seek( s, 0, SOX_SEEK_SET );
>         if ( status ) {
>           fprintf(stderr,"Failed on seek.\n" );
>           exit(1);
>         }
>         count++;
>       }
>       return 0; // not reached
>     }
> 

$ cc -o soxseek soxseek.c -lsox -I/usr/local/include/ -L/usr/local/lib
$ sox -n /tmp/file.wav synth trim 0 $((1024 * 1000))s
$ ./soxseek /tmp/file.wav                             
Failed on read, attempt 1000

That makes me suspect it's just an end of file.
To quote the outdated and incomplete libsox manpage:

  sox_read and sox_write return the number of samples successfully read
  or written. If an error occurs, or the end-of-file is reached, the return
  value is a short item count or SOX_EOF. TODO: sox_read does not
  distiguish between end-of-file and error. Need an feof() and ferror()
  concept to determine which occured.


> I ran it on a file a few megabytes long, and it did a few thousand
> seeks, then failed on the read.

The above does exactly 1000 reads of 1024,
which is exactly how many samples the file contains.
So ( rcnt <= 0 ) does not mean there was an error.

> So it behaves as though there's some kind of internal counter
> initialized to the length of the file, and each read decrements that
> counter by the amount read; when the counter runs out, then reads are
> no longer permitted.

Yes.

If I am reading your code right, it does not seek at all.
It just reads up to EOF. Which might be an error in sox_seek().
As I said, I haven't used libsox before, so I don't know if
this is a correct use of sox_seek(), but beware: not every
input is seekable (a regular file on disk should be, though).

> For me, that's the most important point: to try to have an exact
> characterization of the behavior of the library under these
> circumstances.

There is no good documentation of libsox. The libosx(3) man page
is both incomplete and outdated, and it has been for years.
You might want to look an the src/example*c files.

> >
> > ... (cut)
> > Is there anything left of the original problem then?
> 
> No.
> 
> That's been solved.
> 
> But it would be useful to have confirmation that this behavior is
> intentional, or information on how to avoid the phenoomenon, but for
> now i've dealt with it, although perhaps unnecessarily given the right
> combination of function calls and arguments.

I still suspect that it is first of all unnecessary to read the input
again and again while seeking back again and again; but I can't be sure,
because I still have no idea about what you are doing.

> > ... (cut)
> >> A sort of analogous situation is with the file system and linux: if
> >> you're reading through a file the OS will keep it in memory so you
> >> don't have too much overhead just relying on the OS itself to seek
> >> back and forth in a file --- the caching has already been done.
> >
> > You already _have_ the data in memory once you have sox_read() them,
> > so I fail to see the analogy. Why would you seek back and read it
> > again _from_the_file_ once you have it in an array?
> 
> Not necessarily, as you may be reusing the storage you've set aside.

So don't reuse it: keep the copy of what you have read
so that you don't have to read it over again.

> I think the best, simplest way to obtain the same samples over and
> over would be to seek to them, and read them again.

Why do you think that? Just sox_read() it into an array,
then keep reading that array, instead of reading from a file.

> Thanks again for your help, and if anything i've said is wrong, i'd
> appreciate any correction, clarification, or references.

I staill have no idea about what you are actually trying to do.

	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-06 21:09 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 [this message]
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
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=20171106210932.GA41280@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).