Hi RJ, On 23-Nov-08, at 2:21 AM, Russell Ryan wrote:
> Hey Albert, > > > Albert Santoni wrote: >> Hi RJ, >> >> On 20-Nov-08, at 1:38 PM, Russell Ryan wrote: >> >>> Hi everybody, >>> >>> Just an update on what I've been poking around at. >>> >>> I'm trying to figure out how to implement looping, and in the >>> process >>> I've spent a lot of time staring at how EngineBuffer works. >>> Anybody with >>> some experience here please do chime in and correct anything I've >>> gotten >>> wrong or give background/history of some of what is in here. >>> >>> I made a brief summary of how EngineBuffer::process works. >>> Interestingly >>> enough, it actually has some looping code baked into it, and after >>> looking at it more and more it looks like it might have worked at >>> one >>> point. Does anybody know if it ever did work? >>> >>> Furthermore, there's this 'crossfading' thing inside of >>> EngineBuffer. As >>> far as I can tell, the crossfading is supposed to happen when you >>> ask >>> for a beat-synchronized loop so that there is less abrupt jumping >>> between the end of the loop and the start. Does anybody know the >>> intent >>> or who wrote the crossfading stuff? (keep in mind, this is inside >>> one >>> engine buffer, not crossfading between two enginebuffers). >> >> I think it's safe to say that nobody has any ideas about the old >> looping or "crossfading" stuff. You're more than welcome to just >> delete it, since it's not doing anything useful at the moment >> anyways. Your best hint might be to dig through the SVN log for >> enginebuffer.cpp, in particular, look before r899, which looks like >> the last time Tue touched that file. (On a side note, the comment >> for r429 will show you just how messed up their original design >> was.) :) >> >> Getting rid of the old crossfading/looping logic (as you appear to >> have done in your new EngineBuffer::process()) will go a long way >> towards cleaning up EngineBuffer. Other than that, as Adam >> mentioned, we brainstormed a bit about doing some intelligent >> caching of other parts of the song, the aim of which would be to >> help looping avoid hitting the harddrive in an RT thread. :) > Yep, stripping that crap out should definitely clean things up. > >> >> One tricky bit with the looping code that we've got in the branch >> is that when we tell the Reader to seek to a new spot, it runs >> asynchronously in a separate thread and then fill EngineBuffer >> itself with audio. So I think when we loop back to the start of a >> song, we're jumping to some point in EngineBuffer and praying that >> the Reader has filled it faster than us... (I think?) > Yep, that's how trunk works now. When EngineBuffer processes a > buffer of audio, it calls Reader::wake() if by next buffer we will > be out of data. That wakes up the Reader thread and it will read > data from the SoundSource until enough is ready. It is sort of > praying, but (imho) in practice, Reader sleeps until it is > explicitly woken by the EngineBuffer. If there isn't enough time for > Reader to work in between process() calls then your latency is too > low :). > > Looping is really nothing more than seeking (same for cueing). They > all translate to seek requests on EngineBuffer anyway. It seems to > me that the simplest and most straightforward way to do looping is > to keep the seek metaphor. The way I'm doing looping in the branch > is really simple because of this. > > The important fanciness that would make looping rock solid is a sane > caching setup. > > I think Reader should be extended to support a way for users of it > to specify regions of interest that it would be advantageous to keep > cached. To keep EngineBuffer::process as simple as can be, the whole > thing should be invisible to it. The old looping code has a complex > series of steps by which EngineBuffer can cache the contents of the > loop in a temporary buffer. This is part of what makes EngineBuffer > so complicated, and I feel like it does not belong there. > > To summarize, > > 1) Looping is just seeking, so lets keep that as the way we loop. > Fancy things like caching will be handled in other ways. > Bingo, this is definitely the way to go. > 2) I see two options for caching: > a) Invisible 'best-effort' cache inside Reader. Completely > transparent to users of Reader > b) Explicit caches wherever they are needed. i.e. a looping > EngineObject is in charge of caching for loops. This can be > (easily?) built into EngineObject::process such that the > EngineBuffer does not realize that the data it's working with is > cached. > > Thoughts? > RJ Now that you mention it, option A above sounds basically like what Garth, Adam, and I came up with in a brief brainstorming session at the GSoC summit. Option B is what I had in mind originally, but I think it's a messy solution. If we go with Option A, then we don't have to modify EngineBuffer. Now, exactly how we do that is still up for discussion. I think Adam and Garth conjured up a subclass of Reader called CachingReader or something that would add the extra caching layer. However, after looking at Reader, I don't know if there's a good reason to subclass instead of just modifying Reader. One thing that strikes me as odd after looking at Reader is that it allows EngineBuffer to directly access it's internal wave buffer via Reader::getWavePtr() and getBufferWavePtr(). This is crappy design - EngineBuffer should just ask Reader to "give me N samples" via a function like "getNextAudio(destinationBuffer, numSamples)". If we were to change Reader to work like this, it would make it easier for us to code the caching part, because getNextAudio() would just pull the requested number of samples from whatever cached blocks it needs to. Does this make sense? Thanks, Albert ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ Mixxx-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mixxx-devel
