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