Thanks guys, I was unaware of the "tempo" setting on [metro] and [delay]. This is exactly what I was after! Thanks also for the endorsement of [vline~]--I will use this in the future.
> Date: Thu, 11 Feb 2016 09:44:10 +0100
> From: Roman Haefeli <reduzent@gmail.com>
> To: pd-list@lists.iem.at
> Subject: Re: [PD] achieving smooth tempo change
> Message-ID: <1455180250.4171.22.camel@nl-16900.ad.zhdk.ch>
> Content-Type: text/plain; charset="utf-8"
>
> Hi Liam
>
> A thread that covers the same topic:
> http://lists.puredata.info/pipermail/pd-list/2016-01/112812.html
>
> On Thu, 2016-02-11 at 05:14 +0000, Liam Goodacre wrote:
> > Any DAW or sequencer has a global setting which allows you to change
> > the tempo smoothly across all elements. But fool around on PD for a
> > while and you will realize that this is not a simple operation. If you
> > have more than one time object going at once, it is very hard to keep
> > them in time with each other while changing the period.
> >
> > Consider the example of two metros set to 500 and 1000 ms, banging in
> > synch with one another. The "cold" inlet of both are connected to a
> > float, with the second one being multiplied by 2 along the way. I'm
> > sure you don't even need to try this to know that the two metros will
> > quickly faze out quite if you scroll through the value. The metro
> > duration updates only after the cycle is complete, so one updates
> > before the other and it quickly gets chaotic, especially if you drag
> > the value for more than one complete metro cycle. Of course you could
> > keep them in time by using a trigger to reset the metros, but this is
> > not good from a musical perspective, because I don't want to go
> > restart the bar every time I change the tempo. Another possibility is
> > to store the new time value and load it only when both cycles
> > coincide. This should keep both metros in time, although the
> > transition wouldn't be very smooth.
>
> Checkout the help of [delay] (>= Pd 0.45). It illustrates a new 'tempo'
> method that tackles this exact problem, i.e. using 'tempo' allows to
> change time intervals in the middle of a running interval. The same
> method can be used for [metro] and [timer], too.
>
>
> > [line] works differently, in that the time is specified in the "hot"
> > inlet. But this also doesn't update smoothly if you interrupt it with
> > a new message before the cycle has finished, because the new value
> > sent to it will take the last point as a starting point. The total
> > duration of its cycle will be {elapsed time} + {new time}, which isn't
> > very good if you want to change tempo smoothly. I worked on trying to
> > solve this for a while, and came up with a prototype solution which I
> > am attaching. It works by taking the new time and subtracting it from
> > elapsed time for the new value, so that the line finishes its cycle as
> > if the new time value had been given at the beginning. The patch works
> > reasonably well for one iteration, but completely fails for more than
> > one (ie. if you scroll through the time values). I still haven't
> > figured out why.
>
> I think you're on the right path. If an update happens, measure the time
> since the start of the ramp, calculate the current position, generate a
> new ramp that starts at the current position and takes the proportional
> rest of the time interval to complete. I cannot think of another way to
> achieve that.
>
> I think this is supposed to work even when updating more than once
> during one ramp.
>
> > Before I open up for suggestions, here are a few other points:
> >
> > 1. The simplest solution to this would be to have one and only one
> > time object, set to say 1/16th beat or whatever is the smallest time
> > interval you want, acting globally on all other sequenced events. This
> > would work simply and elegantly, but unfortunately it is not an option
> > for my project. Keeping time locally is essential to me, and I would
> > sooner give up tempo change altogether than give this up.
>
> And it doesn't work well, if you want to have many different ratios of
> beats in parallel. Soon your common partial interval will be so small,
> that [metro] significantly hogs the CPU. If you're interested in keeping
> many different timing ratios in sync, checkout master.pd and
> abs/master-poly.pd from https://github.com/reduzent/netpd-instruments/ .
> While [master] provides the master clock, any instance of [master-poly]
> can derive any arbitrary integer ratio time interval for it (for
> instance, [master-poly 9 5] would create 9 ticks withing the time of 5
> master ticks).
>
> > 2. Another option would be to use the [timer] object, either as an
> > alternative to the others, or to help calculate feedback for them. I'm
> > hesitant to do this because a: it seems like it would require more CPU
> > and b: it it seems like an empirical solution to a deterministic
> > problem.
>
> I don't know how this is a deterministic problem. You don't know when
> the user decides to make a tempo change. So you're left with measuring
> the time elapsed since ramp start or last interval or whatever. If you
> know beforehand, when a tempo change is going to occur, then you don't
> need [timer] to get elapsed time.
>
> > My intuition says that this
> > problem can be solved mathematically, without resorting to
> > measurement. However, I am willing to be convinced that this is the
> > right way to go.
> >
> > 3. I assume that [line] and [line~] will work identically in this
> > regard,
>
> No, [line~] does start and end ramps exactly on block boundaries, while
> [vline~] is sub-sample precise. Only [vline~] takes into account the
> precision of [metro] and [delay]. For the things you're working on, I
> strongly suggest using [vline~], since [line~] would cause all kinds of
> glitches.
>
> > and that [delay] and
> > [metro] will work similarly. But [line] and [delay] work in very
> > different ways, and so the solution, if it exists, is likely to be
> > quite different for these objects. Ultimately I want to find a
> > solution for all time objects, so I'm willing to hear anything you've
> > got!
>
> Checkout the 'tempo' method of [metro], [delay], [timer].
>
> Roman