[PD] achieving smooth tempo change

Liam Goodacre liamg_uw at hotmail.com
Thu Feb 11 06:14:22 CET 2016

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.

[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.

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.

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. 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, 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! 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puredata.info/pipermail/pd-list/attachments/20160211/754b5967/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: live-line.pd
Type: application/octet-stream
Size: 2622 bytes
Desc: not available
URL: <http://lists.puredata.info/pipermail/pd-list/attachments/20160211/754b5967/attachment.obj>

More information about the Pd-list mailing list