[nama] Re: Latency compensation

  • From: "S. Massy" <lists@xxxxxxxxxxxx>
  • To: nama@xxxxxxxxxxxxx
  • Date: Fri, 20 Apr 2012 21:08:05 -0400

Hello,

Will respond later, but I just wanted to let you know that we can use
the -etd op from ecasound for latency generation, like this (say, for 5
ms compensation):
-etd:5,0,1,100,100
It seems pretty reliable as measured with jack_delay: adds maybe a
0.01ms latency, which is no big deal.

Cheers,
S.M.

On Mon, Apr 16, 2012 at 02:06:57PM -1000, Joel Roth wrote:
> On Mon, Apr 16, 2012 at 04:44:19PM -0400, S. Massy wrote:
> > On Sun, Apr 15, 2012 at 10:22:06AM -1000, Joel Roth wrote:
> > > Thought about this issue last night. Here's an outline:
> > > 
> > > Case 1 - ordinary tracks, no buses except Main
> > > 
> > > + Get latency for each user track by querying LADSPA effects
> > > + Adjust each track to suit highest latency found
> > > 
> > > Case 2 - sub-buses
> > > 
> > > + if track is mix track for a sub-bus, add latency of the loop device
> > > + Recurse over member tracks, adjust latencies to match max latency
> > > + Add max to mix track's total
> > I guess I'm stating the obvious here, but, as far as I can see, the
> > formula would be: latency_comp = max_latency-this_track_latency. The only
> > tracks exempt from compensation would be those with max_latency.
> > 
> > Other thoughts/questions:
> > - Do we compensate on the sub-buss user-track or pre-compensate on the
> >   member tracks themselves? The latter seems simpler.
> 
> The key to my (necessarily recursive) thinking, probably expressed poorly
> above, is that all member tracks of a bus (all nodes that
> immediately precede another node) must have equal 
> latency. That leads to the next question:
> 
> > - How do we handle sub-busses on sub-busses?
> 
> max_latency( track ) = sum_latency( track->effects ) + max_latency( 
> track->predecessors )
> 
> > - What about ssend busses, insert tracks, etc. 
> 
> Does anyone even use send busses? The principle of
> divide-and-conquer says 'worry about this later'.
> 
> Insert tracks are just another term to add to the above
> formula. 
> 
> max_latency( track ) = sum_latency( track->effects ) 
>                                               + max_latency( 
> track->predecessors )
>                                               + latency( track->inserts )
> 
> > What cases, besides
> >   external inserts, employ loops?
> 
> Anytime the output of one track feeds the input of another
> track, there is a loop in between. 
> 
> > - Latency compensation for recording? 
> 
> Ecasound already does this by default, or when set
> explicitly with the command -z:multitrack,offset-in-samples
> 
> Measuring this precisely (it depends on the soundcard ADC
> IIRC) will probably lead to better results than Ecasound defaults.
> 
> > Master bus adds another loop hop,
> >   so recorded material should probably be compensated for that.
> 
> If all material, recorded and "live", goes through the
> Master track (and its loop device), it adds a constant
> latency to all paths, therefore requires no compensation.
> 
> I believe most if not all cases can be addressed by starting
> with the Master track and recursing over its predecessors.
> 
> > > 
> > > + Ask Massy to figure this one out. :-)
> > > 
> > > Seriously, for JACK client programs I think it will be:
> > > + loop devices
> > > + JACK I/O latencies
> > > + JACK client latencies
> > > + soundcard loopback latency (for hardware inserts)
> > Yes, I wrote on LAU to try and find out how we could estimate that. I
> > think fixing this will help the sound quality of inserts.
> 
> > > Now, we can implement compensation in two ways
> > > + adding an extra offset term to 'playat'
> > I like this because it does not involve extra processing.
> > 
> > > + using LADSPA 1436 (lcrDelay)
> > I haven't looked into it, but aren't there simpler delay plugins? 
> 
> I hope so, I experimented with it before and didn't
> get the results I wanted. 
> > > 
> > > lcrDelay is the most general solution, since playat can only
> > > be used for WAV file playback.
> > - What would be examples of non-wave playback? Compensating between two
> >   paths using the same source file but introducing different delays,
> >   such as external inserts?
> 
> 1. Compensating wet and dry paths of an insert.
> 2. Compensating "live" signals from a synthesizer
>    or metronome.
> 
> > - LCR_Delay might introduce a latency of it own.
> 
> Well, given that it is being used to add latency,
> I don't think that would be a problem.
>  
> > > In terms of cycles, the cheapest would be to use lcrDelay
> > > only when necessary.
> > - LCR_Delay may introduce its own latency.
> > - LCR_Delay may introduce sound colouration (no idea).
> > - If one track introduces latency, all other tracks need compensation,
> >   so tracks are more likely to need compensation than not.
> > 
> > I'd prefer no processing at all for compensation, but, if that's the
> > only way, I suggest using processing across the board, i.e on every
> > track to minimise jitter and other possible side effects, as well aas
> > simplify the process. The problem is, of course, I don't know how CPU
> > hungry that processing would be.
> 
> I didn't think about jitter. I plan for the case that there
> are enough cycles available for processing. I doubt that
> delays cost anything more than amplifying a signal, which
> I consider to be cheap.
>  
> > That's it for now.
> 
> Having already written a few recursive routines for Nama,
> I'm confident we can solve this in a similar way.
> 
> Best,
>  
> > Cheers,
> > S.M.
> > 
> 
> -- 
> Joel Roth
> 

-- 

Other related posts: