Re: [LAD] [LAU] cancelling I/O with libsndfile
OK. If you look back, this whole round of discussions was a consequence of me saying "VIO in sndfile is ALSO good because...". I didn't think it was really such a big deal in the first place: VIO is already there, and I was able to accomplish my programming goals. > 1) there's a reason to use value A > 2) there's a different reason to use value B > 3) there's no measurable difference in performance between A and B, > and thus the choice between 1+2 must be made on some other grounds There is no choice to be made though. Sndfile doesn't have a userspace cache, but does have a VIO layer that can be used by maniacs who want to milk the last bit of performance (like me, possibly impairing performance by premature optimization), or by those who need to simulate in userspace a network driver. If we were to talk counter-factually, no, I wouldn't want Eric to not write the VIO layer that is present in sndfile at least after 1.0.21... > discarded. The ghosts of thousand dead standards will back me up on > this one. The situation you're describing, i.e. a "dead" standard still applicable to the given platform, and thus able to mislead developers, isn't so common, I believe. > Variations of less than about 500 bytes made no statistically > significant difference to measured throughput. I agree that the memcpy() cost is probably hardly measurable on a PC. It might be measurable on a DSP though, or on a dedicated chip. So..., > Sure, but its because we care about performance, not standards or > "rules". And I measured it first. We might be at cross-purposes. My idea was to design the ideal standards-compliant player and write the "perfect" code, for once (and make sure that the libraries involved allow me to do it) -- Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
On Thu, Jul 7, 2011 at 10:28 AM, Dan Muresan wrote: > Hi Paul, thanks for replying. > >> to. It seems as though you think there is a difference in the >> throughput when you read from a filesystem using st_blksize or some >> other size close to it, and that you either have or could measure it. > > I was saying the man page provides the definitive guide to structuring > request sizes, and sndfile breaks the rules. The rules are there for > NFS, NTFS, EXT3, JFS, FTPS, SSHFS etc, PLUS future drivers. I don't consider man pages definitive guides for *anything*. Not even for system calls that are part of POSIX. If you want to measure this, go ahead. If what is described on the man page matches what you find, that's great, and it will be like (as a rough guess) 90% of the rest of the OS API. But if it doesn't, don't be suprised. One of the things about open source is that if you actually spend time reading (in this case, kernel) source, you rapidly come to discount man pages and other documentation as sources of definitive information. This might be a bad development (there are some good arguments to this effect), but it doesn't change the fact that it happens. However, I think you're missing Erik's point. He's not claiming that there isn't a "rule" (your term, though I think its inappropriate) for setting the i/o size based on st_blksize. He's saying that if you break the "rule" in the way that is being discussed, you will find it hard to see any effect of doing so. He may have also explained why this is likely to be the case in the future too (or I've just imagined that part). So the situation is not: * do it this way, or it will break its more like: 1) there's a reason to use value A 2) there's a different reason to use value B 3) there's no measurable difference in performance between A and B, and thus the choice between 1+2 must be made on some other grounds >> Erik is saying that he doesn't believe that you could measure the >> difference. > > Well, who knows? To be future-proof one must follow standards. Future-proof and standards surely have almost no relationshiop to each other. The future is where today's standards are changed, or discarded. The ghosts of thousand dead standards will back me up on this one. > Now, have you measured that reading exactly 10,000 bytes at a time was > optimal? That would be an argument against st_blksize being > meaningful. Variations of less than about 500 bytes made no statistically significant difference to measured throughput. > So you *do* pay attention to even block sizes in Ardour :) Sure, but its because we care about performance, not standards or "rules". And I measured it first. ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
Hi Paul, thanks for replying. > to. It seems as though you think there is a difference in the > throughput when you read from a filesystem using st_blksize or some > other size close to it, and that you either have or could measure it. I was saying the man page provides the definitive guide to structuring request sizes, and sndfile breaks the rules. The rules are there for NFS, NTFS, EXT3, JFS, FTPS, SSHFS etc, PLUS future drivers. > Erik is saying that he doesn't believe that you could measure the > difference. Well, who knows? To be future-proof one must follow standards. > values very, very far removed from st_blksize. This is why ardour st_blksize is only a common denominator. It is not a "preferred size". I.e. if st_blksize is 1024, you could use 1k, 4k or 16k as a buffer size -- just don't read() 1020 bytes, which sndfile does, all the time, with impunity :) Now, have you measured that reading exactly 10,000 bytes at a time was optimal? That would be an argument against st_blksize being meaningful. > tries to write in chunks of 256kB, although in truth it would be So you *do* pay attention to even block sizes in Ardour :) -- Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
On Thu, Jul 7, 2011 at 9:38 AM, Dan Muresan wrote: [ ... ] Dan - I'm really confused by what you're getting at, or trying to get to. It seems as though you think there is a difference in the throughput when you read from a filesystem using st_blksize or some other size close to it, and that you either have or could measure it. Erik is saying that he doesn't believe that you could measure the difference. The only empirical data I have comes from years ago (maybe 8-9 years ago) when I measured this with ext2 and possibly 2 other linux filesystems, and found that the best throughput was obtained using values very, very far removed from st_blksize. This is why ardour tries to write in chunks of 256kB, although in truth it would be better if we measured this again on ext3 and newer FS's, and if possible provided a run-time measurement. ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
> point every time. Let me fix my last statement: > Regardless of whether you choose to measure latency or CPU load > if you test two read sizes (st_blksize and st_blksize - 4) you > will not be able distinguish between the two read sizes due to > the influence of other factors. I don't think I have missed any of your points. We disagree as to what is worth spending one's time / code lines on, but if anything, you have missed my points about kernel operation / cpu load / latency. Which is fine by me -- I am happy with the way sndfile works today. The fact that you have a VIO layer solves (or at least obviates) most of the problems that I have pointed out. Note that merely rewriting a statement to make it more vague does not prove initial intention or ulterior insight. So no need to "fix" your statements like that... -- Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
Dan Muresan wrote: > > Regardless of whether you choose to measure latency or CPU load > > if you vary the st_blksize as specified in the previous email, > > you will not be able distinguish between the two values of > > st_blksize due to the influence of other factors. > > What are you talking about? How can one vary st_blksize or choose a > preferred value for it? Its late, I'm tied and I'm frustrated at your ability to miss the point every time. Let me fix my last statement: Regardless of whether you choose to measure latency or CPU load if you test two read sizes (st_blksize and st_blksize - 4) you will not be able distinguish between the two read sizes due to the influence of other factors. Erik -- -- Erik de Castro Lopo http://www.mega-nerd.com/ ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
> Regardless of whether you choose to measure latency or CPU load > if you vary the st_blksize as specified in the previous email, > you will not be able distinguish between the two values of > st_blksize due to the influence of other factors. What are you talking about? How can one vary st_blksize or choose a preferred value for it? Are you assuming that I am writing a kernel driver? Why? If you meant the actual request size, then I think that (1) none of us have performed measurements and (2) as I stated, if no measurements have been performed, and if the implementation allows it, standard recommendations should be obeyed. > The behavior of fread() can be dubious for files accessed > via NFS with respect to incomplete reads (ie EAGAIN). The > only solution to this is to use read(). Please detail this somewhat. NFS was one of the use-cases I mentioned in the beginning (and I actively use it). >> else address the issues that arise from breaking the rules (i.e. > > Breaking what rules? K&R C and even CS1 choices (fread / fwrite), unless you have a reason to break them... Not that I would be at that level... > You provide concrete proof that doing block sized reads makes > any positive performance improvement and I'll implement block > sized reads and buffering. You have already said you would accept patches and contributions for this specific issues (a userspace cache) in past e-mails. Are you retracting (or qualifying) the offer? In any case, you already have the VIO layer, which certainly WFM -- my programs work. > Until you can show concrete proof I consider this issue closed. Which issue? I was merely discussing choices. And I was arguing that YOUR VIO code is a GOOD thing. Uh, please don't remove it :) Anyway, I have found sndfile to be an extremely valuable library. -- Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
Dan Muresan wrote: > > > non-st_blksize sized blocks will be absolutley swamped, by disk > > > latencies, cache latencies, scheduling latencies and file > > > decoding overhead. > > your measurements would be so swamped with noise from other > > factors that any differences would be statistically irrelevant. > > If you could explain how any CPU load measurement ever devised by > mankind could be "swamped" (or in fact influenced at all) by a latency > factor, then yes, I might have missed your point... Load and latency > are orthogonal issues, aren't they? Regardless of whether you choose to measure latency or CPU load if you vary the st_blksize as specified in the previous email, you will not be able distinguish between the two values of st_blksize due to the influence of other factors. > So, when in doubt, I think one should heed the advice of standards and > common practice Don't you think it would be better to measure rather than rely on standards and common practice, both of which may be wrong when it comes to things like performance issues? > (like using fread and fwrite, not read and write), or The behavior of fread() can be dubious for files accessed via NFS with respect to incomplete reads (ie EAGAIN). The only solution to this is to use read(). > else address the issues that arise from breaking the rules (i.e. Breaking what rules? > provide a VIO layer, like you did, or cache non-block-sized reads in > userspace). You provide concrete proof that doing block sized reads makes any positive performance improvement and I'll implement block sized reads and buffering. Until you can show concrete proof I consider this issue closed. Erik -- -- Erik de Castro Lopo http://www.mega-nerd.com/ ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
> > non-st_blksize sized blocks will be absolutley swamped, by disk > > latencies, cache latencies, scheduling latencies and file > > decoding overhead. > your measurements would be so swamped with noise from other > factors that any differences would be statistically irrelevant. If you could explain how any CPU load measurement ever devised by mankind could be "swamped" (or in fact influenced at all) by a latency factor, then yes, I might have missed your point... Load and latency are orthogonal issues, aren't they? The decoding overhead -- I don't know. That *does* compete for CPU load indeed. The balance depends on the CPU and on the OS I guess. Remember there are ARMs, Blackfins with ucLinux, OS's and pieces of hardware yet to be invented etc. The people who write OS's for these platform usually make choices based on what standards (like POSIX) mandate, if they have an implementation choice. I have written a POSIX layer for AD's VDK (a real-time kernel) in the past, and I've certainly made my choices based on what the standards said. So, when in doubt, I think one should heed the advice of standards and common practice (like using fread and fwrite, not read and write), or else address the issues that arise from breaking the rules (i.e. provide a VIO layer, like you did, or cache non-block-sized reads in userspace). Admittedly, for PC users these are somewhat academic distinctions... -- Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
Dan Muresan wrote: > > I haven't measured it, but my educated guess is that if you're > > reading 16384 frames at a time from a FLAC file on current hardware, > > then the difference between reading st_blksize sized blocks and > > Uh, actually no. If one reads 4096, 2048, or 1024 frames the result is > the same -- 4 bytes less than st_blksize -- EVERY syscall. Try it. In > any case, I didn't optimize anything like that yet. It was a design > discussion. I was saying that's one more reason why it's good to have > the VIO layer, since there is no userspace cache. > > > non-st_blksize sized blocks will be absolutley swamped, by disk > > latencies, cache latencies, scheduling latencies and file > > decoding overhead. > > You seem to mix up latency and CPU load? A program can have low > latency, yet high(er than necessary) CPU load. I think you missed the point. The point is that if you set out to measure the difference (in CPU load or in latency) between reading st_blksize size blocks and st_blocksize - 4 blocks at the libsndfile API level, your measurements would be so swamped with noise from other factors that any differences would be statistically irrelevant. Erik -- -- Erik de Castro Lopo http://www.mega-nerd.com/ ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
> I haven't measured it, but my educated guess is that if you're > reading 16384 frames at a time from a FLAC file on current hardware, > then the difference between reading st_blksize sized blocks and Uh, actually no. If one reads 4096, 2048, or 1024 frames the result is the same -- 4 bytes less than st_blksize -- EVERY syscall. Try it. In any case, I didn't optimize anything like that yet. It was a design discussion. I was saying that's one more reason why it's good to have the VIO layer, since there is no userspace cache. > non-st_blksize sized blocks will be absolutley swamped, by disk > latencies, cache latencies, scheduling latencies and file > decoding overhead. You seem to mix up latency and CPU load? A program can have low latency, yet high(er than necessary) CPU load. -- Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
Dan Muresan wrote: > >> > I never much liked the VIO layer. It was only ever added because > >> > a large number of people requested it. I think its fragile and > >> > it exposes too much of libsndfile internals to the user. > > There is one remaining issue that I have discovered while writing > jack-file, and which can only be addressed via a VIO layer of some > sort. While reading a FLAC file, the sndfile request size stream looks > like > > 8188, 8188, 8188, 8192 etc (bytes) > > This is with the user continuously requesting 16384 frames. You will > notice that these are uneven block sizes. If I understand correctly > e.g. the stat(2) page, these are inefficient syscalls: > > "The st_blksize field [of a struct stat] gives the "preferred" > blocksize for efficient file system I/O. (Writing to a file in smaller > chunks may cause an inefficient read-modify-rewrite.)" > > Without a VIO layer (or a libsndfile user-space cache), this is not > solvable by the user at higher abstraction layers. Whaaat? You're kidding me right? I haven't measured it, but my educated guess is that if you're reading 16384 frames at a time from a FLAC file on current hardware, then the difference between reading st_blksize sized blocks and non-st_blksize sized blocks will be absolutley swamped, by disk latencies, cache latencies, scheduling latencies and file decoding overhead. You might want to google the term "premature optimisation". Erik -- -- Erik de Castro Lopo http://www.mega-nerd.com/ ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
>> > I never much liked the VIO layer. It was only ever added because >> > a large number of people requested it. I think its fragile and >> > it exposes too much of libsndfile internals to the user. There is one remaining issue that I have discovered while writing jack-file, and which can only be addressed via a VIO layer of some sort. While reading a FLAC file, the sndfile request size stream looks like 8188, 8188, 8188, 8192 etc (bytes) This is with the user continuously requesting 16384 frames. You will notice that these are uneven block sizes. If I understand correctly e.g. the stat(2) page, these are inefficient syscalls: "The st_blksize field [of a struct stat] gives the "preferred" blocksize for efficient file system I/O. (Writing to a file in smaller chunks may cause an inefficient read-modify-rewrite.)" Without a VIO layer (or a libsndfile user-space cache), this is not solvable by the user at higher abstraction layers. -- Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
Dan Muresan wrote: > > I never much liked the VIO layer. It was only ever added because > > a large number of people requested it. I think its fragile and > > it exposes too much of libsndfile internals to the user. > > Well, it doesn't seem to expose anything other than the set of chosen > functions (read / write / seek etc) -- no data structure, no special > #include's... Yes, but it means that I can't decide to replace all uses of write() with pwrite() for instance. At one stage I though this was a good idea. > My problem is that the VIO API isn't (yet) clearly specified / > documented (e.g. what the virtual read / write should return for > errors, for EOF, whether it's acceptable to return short counts). You > may also be missing an errno-like VIO function, but I can't comment > much as I don't quite understand the existing sf_error() stuff. This lack of clarity is one of the things I don't like. > By "fragile" you probably mean that the set of VIO functions, or their > API, might change in the future? More that bugs or inconsistency in the user provided VIO functions look like libsndfile bugs. > > I would be surprised if reset-by-seek didn't work on standard > > WAV/AIFF etc files with PCM data accessed via the standard > > sf_read/write* functions. > > Probably, but since I'm using sndfile, I don't want to special-case > formats in my app... You shouldn't have too. Anything that you can do with 16 bit PCM WAV files that you can't do with FLAC (and libsndfile doesn't say there is an error) is probably a bug. > At the very least, does a successful sf_seek() > guarantee that all errors have been cleared and that future I/O will > occur undisturbed (in the places where the file contains no errors, > obviously)? It should for all the standard file formats. If it doesn't for FLAC then thats a bug that I would try to fix or make sure that libsndfile notifies the client program that something has gone wrong. Erik -- -- Erik de Castro Lopo http://www.mega-nerd.com/ ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
> I never much liked the VIO layer. It was only ever added because > a large number of people requested it. I think its fragile and > it exposes too much of libsndfile internals to the user. Well, it doesn't seem to expose anything other than the set of chosen functions (read / write / seek etc) -- no data structure, no special #include's... My problem is that the VIO API isn't (yet) clearly specified / documented (e.g. what the virtual read / write should return for errors, for EOF, whether it's acceptable to return short counts). You may also be missing an errno-like VIO function, but I can't comment much as I don't quite understand the existing sf_error() stuff. By "fragile" you probably mean that the set of VIO functions, or their API, might change in the future? Do you foresee the need to add or remove stuff? It seems like a pretty standard set of functions, similar to what you'd specify for a VFS layer. > I would be surprised if reset-by-seek didn't work on standard > WAV/AIFF etc files with PCM data accessed via the standard > sf_read/write* functions. Probably, but since I'm using sndfile, I don't want to special-case formats in my app... At the very least, does a successful sf_seek() guarantee that all errors have been cleared and that future I/O will occur undisturbed (in the places where the file contains no errors, obviously)? -- Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
Dan Muresan wrote: > > You need to supply me with a small test program and if necessary > > this broken FLAC file. > > 1. Rather hard to do at the moment -- not the least because the > brokenness is injected via the vio layer. I never much liked the VIO layer. It was only ever added because a large number of people requested it. I think its fragile and it exposes too much of libsndfile internals to the user. > 2. Why? This was not a bug report. This was an API *clarification > request*. sndfile doesn't claim to support reset-by-seek (though I > wrongly assumed it would), and you yourself said "maybe not on FLAC", > "This is not possible on all file types" etc. > > Now, do you consider such behavior to be a bug (i.e. did you intend to > support reset-by-seek)? I would be surprised if reset-by-seek didn't work on standard WAV/AIFF etc files with PCM data accessed via the standard sf_read/write* functions. Erik -- -- Erik de Castro Lopo http://www.mega-nerd.com/ ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
> You need to supply me with a small test program and if necessary > this broken FLAC file. 1. Rather hard to do at the moment -- not the least because the brokenness is injected via the vio layer. 2. Why? This was not a bug report. This was an API *clarification request*. sndfile doesn't claim to support reset-by-seek (though I wrongly assumed it would), and you yourself said "maybe not on FLAC", "This is not possible on all file types" etc. Now, do you consider such behavior to be a bug (i.e. did you intend to support reset-by-seek)? If so, I will try to create a broken FLAC file, take out the vio layer, put it back if the bug disappears etc. until I get a minimal reproducing test-case -- time permitting. -- Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
Dan Muresan wrote: > >> does libsndfile ever clear the error flag on a file? E.g. if there is > >> a decoding error in a FLAC, and I sf_seek() back to the beginning, > >> will sf_read_() work "normally" again? > > > > Maybe not on FLAC. I would suggest that you write a small > > standalone test program to test this and if you don't > > With a small standalone broken FLAC file :) FLAC was just an example. You need to supply me with a small test program and if necessary this broken FLAC file. Erik -- -- Erik de Castro Lopo http://www.mega-nerd.com/ ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
>> does libsndfile ever clear the error flag on a file? E.g. if there is >> a decoding error in a FLAC, and I sf_seek() back to the beginning, >> will sf_read_() work "normally" again? > > Maybe not on FLAC. I would suggest that you write a small > standalone test program to test this and if you don't With a small standalone broken FLAC file :) FLAC was just an example. What seems to happen is that after a decoder error, a subsequent sf_seek() fails. I guess the only reliable thing to do is to close & reopen the file on error -- which is inefficient because a bunch of data structure get re-allocated, and a bunch of meta-data gets re-read. That's why I thought a sf_reset() would be useful. For example FLAC has FLAC__stream_decoder_reset(). Granted, on some formats (PCM) sf_reset() might work efficiently, on others inefficiently, and on others yet it might do a close & re-open (or return FALSE). Even better would be some way to save & restore the entire decoder (or encoder) state. That would allow a player to go back to a known point instantly, without any gaps in playback. But, of course, most external file format libraries don't have the means to cooperate with that. -- Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
Dan Muresan wrote: > Hi, > > does libsndfile ever clear the error flag on a file? E.g. if there is > a decoding error in a FLAC, and I sf_seek() back to the beginning, > will sf_read_() work "normally" again? Maybe not on FLAC. I would suggest that you write a small standalone test program to test this and if you don't get what you think you should, send me the test program and an explanation of what you think you should get. > Or, if a premature EOF is reached, will seeking back somewhere in the > file allow playback to resume? libsndfile claims to support > simultaneous reading and writing... This is not possible on all file types, especially not on compressed formats like FLAC. It does however work on PCM data for most file formats. Erik -- -- Erik de Castro Lopo http://www.mega-nerd.com/ ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
Hi, does libsndfile ever clear the error flag on a file? E.g. if there is a decoding error in a FLAC, and I sf_seek() back to the beginning, will sf_read_() work "normally" again? Or, if a premature EOF is reached, will seeking back somewhere in the file allow playback to resume? libsndfile claims to support simultaneous reading and writing... -- Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
> The intermediate one doesn't have that and may well work against > you. The same problem exists with the system level buffering, Yes. Well, the worse clash is between the kernel-space vs. the user-space caching strategy, but indeed you can't do much about it (unless you go the O_DIRECT way like databases). > is 2 seconds, so that's 8 commands to read 1/4 of second. You can't > safely start playback again unless you have at least a second or On transport relocation, I was planning to be un-safe, compromise on the cache pre-fill percentage and accept the possibility of a few application-level (not Jack-level) under-runs -- in the interest of (likely) gapless payback. The cache should catch up gradually, depending on the streaming-to-playback bandwidth ratio. But otherwise you are right. > so buffered. No assume you have a new relocate before that time. I'm not considering this yet, but I see your point about there always existing a single un-cancellable request. > If the reads happen on an NFS volume then even if the cancel would > work on the client side that doesn't imply that the data won't > be transmitted by the server anyway. So nothing would be gained This depends on whether it's a WAV or a compressed file, and on the NFS rsize and wsize mount params I guess (or I'm missing something). Thanks for the analysis. Best Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
On Tue, Jun 14, 2011 at 02:42:18PM +0300, Dan Muresan wrote: > For sure, two user-space caches add a useless extra layer of copying. Not only copying (which is cheap anyway), but also logic. Your application layer cache knows what you want to achieve, will have some ad-hoc strategies and try to do the right thing. The intermediate one doesn't have that and may well work against you. The same problem exists with the system level buffering, but you can't do much about that. > > One way to organise the buffer is to divide it in fragments > > of say 1/4 second, and have the start offset of each one > > Yes, that's exactly how my implementation works. My ringbuffer is > divided in fragments. > > > quantised to the same value. The syscall overhead becomes > > trivial for such a lenght. When you need new fragments, you > > Yes, that's why I argued for long requests over short ones. > > > the actual read() call). The one you can't cancel is no big > > deal, just let it happen. It will take little time compared > > And this is why I gave the NFS example earlier in the discussion... > > What if it the data comes from the network, e.g. a streaming server > that has just 110% the bandwidth of the actual real-time playback? As > I said, in this case you almost double the latency if you can't cancel > the request. I don't know what your app is doing, so I'll assume it's some sort of player. Now if you relocate, you send the commands to read the data at the new position to your reader thread. Assume your buffer is 2 seconds, so that's 8 commands to read 1/4 of second. You can't safely start playback again unless you have at least a second or so buffered. No assume you have a new relocate before that time. Again you send the commands to read 8 blocks of 1/4 second. There is some logic in the app that makes these cancel the previous ones that have not yet started. So you end up with 1 you can't cancel against 8 that have to be done anyway. That's not big loss. One of my players works this way. From a user point of view a relocate happens almost instantly. If the read bandwidth is just above what is required for continuous streaming, then very probably you can't support this sort of thing without extra delays. But even in this case they don't need to be very big. In the example above one extra fragment is read (the one you can't cancel) compared to the four or so you need to have done anyway before you can resume playing safely. So it takes as most 25% more time. If the reads happen on an NFS volume then even if the cancel would work on the client side that doesn't imply that the data won't be transmitted by the server anyway. So nothing would be gained by cancelling. Ciao, -- FA ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
>> that it expects to free before returning. Do you know if this might be >> the case (e.g. for the native formats, libFLAC, libvorbis)? > > No idea. I would be surpised if this works. It seems to works for FLAC, but I can't trust it either. Besides memory leaks, mutexes might remain locked, and indirectly deadlock sf_free(). >> I may need to fall back on the vio stuff. How does a sf_vio_read or >> sf_vio_write signal I/O errors? > > I never foresaw the possiblity of anybody doing this. I suspect they > should return -1. Well, forget my cancelling strategy -- errors could occur even if one writes a trivial layer (vio_read == read). An I/O API *must* specify error handling. This is not some exotic use case... >From TFC, psf_fread (): if (psf->virtual_io) return psf->vio.read ... (i.e. no processing), while the non-virtual branch returns the partial count if an error ever occurs. So I guess I should return some short count on error. Anyway, for cancelling requests EOF works -- indeed as long as one can "get out of the sf_read jail free" anything works. -- Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
Hi Fons, > It's probably a Good Thing (TM) that libsndfile doesn't do its > own buffering. First, the file system will do buffering, and if I agree, I prefer the flexibility of implementing my own user-space cache in an app-dependent way, too. > exactly this is organised will be application dependent. Having > a third layer in between this and the system is not going to help. For sure, two user-space caches add a useless extra layer of copying. > One way to organise the buffer is to divide it in fragments > of say 1/4 second, and have the start offset of each one Yes, that's exactly how my implementation works. My ringbuffer is divided in fragments. > quantised to the same value. The syscall overhead becomes > trivial for such a lenght. When you need new fragments, you Yes, that's why I argued for long requests over short ones. > the actual read() call). The one you can't cancel is no big > deal, just let it happen. It will take little time compared And this is why I gave the NFS example earlier in the discussion... What if it the data comes from the network, e.g. a streaming server that has just 110% the bandwidth of the actual real-time playback? As I said, in this case you almost double the latency if you can't cancel the request. It might be an interesting idea to do new requests in parallel with cancelled ones, but this requires another layer of ringbuffer / memory management. -- Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
On Tue, Jun 14, 2011 at 01:01:09PM +0300, Dan Muresan wrote: > > b) Work around it. > > This is what I was trying to do via pthread_cancel + sf_open_fd. It > seems to work with FLAC. 'Work around it' coild mean something entirely different : not trying to cancel anything, by using a system that doesn't require it. More below. It's probably a Good Thing (TM) that libsndfile doesn't do its own buffering. First, the file system will do buffering, and if you're playing a sound file probably decide it should read ahead. Second, any application that wants to use audio data in real time will need to do its own buffering, typically a few seconds. How exactly this is organised will be application dependent. Having a third layer in between this and the system is not going to help. If you support things like loops, random locates, shutthling, scrubbing, etc. the buffer management logic required to support all of this in an efficient way may become complicated. But only the application can do it. One way to organise the buffer is to divide it in fragments of say 1/4 second, and have the start offset of each one quantised to the same value. The syscall overhead becomes trivial for such a lenght. When you need new fragments, you send commands to the reader thread to read them. If the requirements change before they are read, you can still cancel all but one of them (you cancel the requests, not the actual read() call). The one you can't cancel is no big deal, just let it happen. It will take little time compared to what has to be done anyway. Ciao, -- FA ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
Dan Muresan wrote: > > b) Work around it. > > This is what I was trying to do via pthread_cancel + sf_open_fd. It > seems to work with FLAC. > > However, there could be memory leaks if any decoder / encoder function > (in sndfile or one of the external libs) allocates temporary memory > that it expects to free before returning. Do you know if this might be > the case (e.g. for the native formats, libFLAC, libvorbis)? No idea. I would be surpised if this works. > I may need to fall back on the vio stuff. How does a sf_vio_read or > sf_vio_write signal I/O errors? I never foresaw the possiblity of anybody doing this. I suspect they should return -1. > How does a vio_read signal EOF? Just like the read() system call, by returning zero. Erik -- -- Erik de Castro Lopo http://www.mega-nerd.com/ ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
> b) Work around it. This is what I was trying to do via pthread_cancel + sf_open_fd. It seems to work with FLAC. However, there could be memory leaks if any decoder / encoder function (in sndfile or one of the external libs) allocates temporary memory that it expects to free before returning. Do you know if this might be the case (e.g. for the native formats, libFLAC, libvorbis)? I may need to fall back on the vio stuff. How does a sf_vio_read or sf_vio_write signal I/O errors? How does a vio_read signal EOF? The API docs don't seem to say anything. -- Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
Dan Muresan wrote: > >> be nice to add a sf_reset() function or a SF_RESET sf_command() > >> parameter. > > > > What problem does that fix? Do you even know if there is a problem? > > The problem of a SNDFILE becoming invalid after a cancelled I/O. Yes, > there is a problem -- valgrind reports nasty memory errors (and > eventually I get a segfault) if I don't re-open the SNDFILE. I can't say I'm all that surpised, this is not something that was designed to work. That leaves you two options: a) Debug the problem, come up with a fix and send a patch. b) Work around it. > [ If you meant I should test the sf_seek() trick first -- I doubt that > testing a few sf_seek()s on a few FLAC files will reliably establish > whether sf_seek() really does reset all encoder and decoder structure > under all circumstances. Especially since you said you weren't sure > yourself. ] The problem you face is difficult enough with file formats that are supported natively by libsndfile. It will be much more difficult for the formats that require external libraries because the fix may require fixes in libFLAC, libogg or libvorbis. Erik -- -- Erik de Castro Lopo http://www.mega-nerd.com/ ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
> Err, if you're worried about latency, why are you streaming from > a slow NFS server? The point was that NOT cancelling introduces extra latency unnecessarily, and short requests introduce CPU overhead. I gave the NFS example to preempt the "hard disks are really fast" objection that some people are always tempted to make... For the given example, if the NFS server can stream at even 110% of the playback speed without jitter, you can still achieve glitch-free, continuous playback with as low a *skip* latency as the CPU (and chosen request size) permit. *If* you can cancel active requests, that is -- otherwise you need to double that latency. And yes, I actually do stream from a fileserver (over NFS) myself quite often. >> be nice to add a sf_reset() function or a SF_RESET sf_command() >> parameter. > > What problem does that fix? Do you even know if there is a problem? The problem of a SNDFILE becoming invalid after a cancelled I/O. Yes, there is a problem -- valgrind reports nasty memory errors (and eventually I get a segfault) if I don't re-open the SNDFILE. [ If you meant I should test the sf_seek() trick first -- I doubt that testing a few sf_seek()s on a few FLAC files will reliably establish whether sf_seek() really does reset all encoder and decoder structure under all circumstances. Especially since you said you weren't sure yourself. ] -- Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
Dan Muresan wrote: > Certainly not unique. My guess is that nobody worried about a > (possibly small) performance penalty, and instead used simpler > strategies -- or they weren't using sndfile in the first place. > > Consider this: for any request size you choose, NOT cancelling could > double your latency in the worst case if you're streaming from a slow > NFS server. Err, if you're worried about latency, why are you streaming from a slow NFS server? > This begs a question -- is it possible to "reset" the SNDFILE less > dramatically? E.g. would a seek back to offset 0, or a pair of seeks, > or some other trick also reset the data structures? Really not sure. You should try it and report back. > If not, it might > be nice to add a sf_reset() function or a SF_RESET sf_command() > parameter. What problem does that fix? Do you even know if there is a problem? Erik -- -- Erik de Castro Lopo http://www.mega-nerd.com/ ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
> To me that suggests that either you have a completely unique > problem to solve or that they are other solutions to your > problem that other people use to get around the same problem. > My guess is that your problem is not completely unique. Certainly not unique. My guess is that nobody worried about a (possibly small) performance penalty, and instead used simpler strategies -- or they weren't using sndfile in the first place. Consider this: for any request size you choose, NOT cancelling could double your latency in the worst case if you're streaming from a slow NFS server. Now, I've been able to implement my strategy by storing fd's and using sf_open_fd() as necessary. I.e. after a thread is cancelled in the middle of I/O (rendering the SNDFILE invalid), I re-open fd's using sf_open_fd(). This begs a question -- is it possible to "reset" the SNDFILE less dramatically? E.g. would a seek back to offset 0, or a pair of seeks, or some other trick also reset the data structures? If not, it might be nice to add a sf_reset() function or a SF_RESET sf_command() parameter. >> On second thought, though, this proposal could not possibly work >> without a userspace (libsndfile) cache, because read() might return >> incomplete frames, which would need to be processed in a later call. > > Modifying libsndfile to do fread/fwrite style buffering would be As I wrote above, and as Paul noticed, the virtual I/O layer (which I did not initially notice) is a good solution for this... Best, Dan ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] [LAU] cancelling I/O with libsndfile
Dan Muresan wrote: > Hi Erik -- please CC me so I can reply (I don't receive messages from > LAU directly). I'm quoting manually here: > > > > I'm trying to cancel an ongoing sf_* I/O operation (from another > > Maybe its a bad idea. :-) > > I don't think so... Issuing large requests, then cancelling as needed > gives a process the lowest possible latency for unpredictable seeks > (caused e.g. by user commands), while keeping CPU usage low (by > avoiding syscall and context switching overhead) Let me put it this way: a) When I designed libsndfile over 10 years ago, I never dreamed anybody would try this. b) In the 10 years libsndfile has been around and the probably hundreds of applications it has been used in, noone has suggested that it would be a good idea if libsndfile could do this. To me that suggests that either you have a completely unique problem to solve or that they are other solutions to your problem that other people use to get around the same problem. My guess is that your problem is not completely unique. > > Reading one frame at a time sounds like a bad idea too. > > 1 frame at a time was an extreme example. The point was that > libsndfile doesn't employ a user-space cache, but direct system calls. > Reading 10, 100 or 480 frames at a time will still incur syscall > overhead (== CPU usage), and progressively larger cancel latencies. > > > > libsndfile. It would be nice if libsndfile could allow short reads and > > > writes via some sf_command parameter. > > It does. You can read any number of frames from 1 through to as many > > frames as the file contains. > > I meant "short reads" in kernel-speak sense: read(2) can return a > number of bytes less than the number requested when interrupted by a > signal (if SA_RESTART is disabled). My proposal was to add a > sf_command() parameter that disables the looping behavior of sf_read() > on EINTR, and makes it return exactly as many frames as the first > read() call manages to get. I accept good quality, clean patches with tests for the functionality you are adding. Wherever possible, they should be cross platform. > On second thought, though, this proposal could not possibly work > without a userspace (libsndfile) cache, because read() might return > incomplete frames, which would need to be processed in a later call. Modifying libsndfile to do fread/fwrite style buffering would be relatively easy. Again, patches accepted. > > I just checked, and the address you used to post this email to the LAU > > list are not subscribed to the libsndfile-users list. Thats why the list > > is rejecting your email. > > That's exactly the problem: I subscribed about two weeks ago, received > a confirmation, Was that a confirmation or a request for confirmation? Joining a mailing list usually involves: a) Send a request to join. b) Receiving a "confirm that you want to join" message. c) Sending "confirm that you want to join". d) Receiving a "yes, you are mow a member" message. > and sent a message at that time (which received no > bounces, but no replies either). Now, the mailserver somehow forgot > about me and is rejecting my messages. Or something... All other complaints of this sort that I have received have been from people who couldn't figure out the subscribe procedure or joined from one email address and sent mail to the list from another. Cheers, Erik -- -- Erik de Castro Lopo http://www.mega-nerd.com/ ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org http://lists.linuxaudio.org/listinfo/linux-audio-dev