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]

 



Hi Jan!

Thanks for your mail.

Answers interspersed below, hopefully simple to read.

On Mon, Nov 6, 2017 at 11:06 AM, Jan Stary <hans@xxxxxxxx> 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
    }

It compiles and links without error or warning (link with -lsox).

I ran it on a file a few megabytes long, and it did a few thousand
seeks, then failed on the read.  (It's amazing with modern hardware
how fast something like this runs.)

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.

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


>
> ... (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.

> ... (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.

>
>> (2) I'm doing this programmatically because i anticipate running the
>> program many times, and i want to be as sure of correctness as i can.
>> (In fact, i'm not actually programming it in C, but i'm using the C
>> calling conventions, and in principle i could certainly do this in C.)
>
> What makes you think that writing your own code will make
> your use of SoX more "correct"?

Well, i don't think that at all!!! :) :) :)

Or more exactly, correct or not it may very well not be very idiomatic.

I think the best, simplest way to obtain the same samples over and
over would be to seek to them, and read them again.  That may even be
possible, by executing some kind of a reset, however i don't know.

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

dan

------------------------------------------------------------------------------
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