On Nov 06 12:14:59, dan.hitt@xxxxxxxxx wrote: > 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 > } > $ 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@xxxxxxxxxxxxxxxxxxxxx https://lists.sourceforge.net/lists/listinfo/sox-users