Mathematical problem (syncing variable speed phasors)

playmodes's icon

Hi all!
I
'm just stuck with a mathematical problem i need some help to solve. Let's see if i can explain it properly:

I have 2 synced phasors, at the same frequency and phase.

At some arbitrary moment, i want phasor A to accelerate for 4 seconds until it arrives to, let's say, double the frequency of phasor B.

Phasor A stays at this new higher frequency for some time, and it decelerates for 4 seconds until it reaches again the original frequency.

The problem comes because i want that when phasor A finishes deceleration, it matches the exact phase of phasor B. This obviously means that the deceleration has to start in a specific moment in time to be able to catch phasor B in its exact phase.

I think this is related to uniformly accelerated linear motion equations, and might imply the use of derivative calculous?

I want to use this to sync 3 vertical scrolling image slides, where i want each of the 3 scrolls to alter its frequency from time to time, but then going back to normal speed and matching the exact position of the other 2 scrolls.

I imagine this might be useful to sync audio loops too: having 2 rhythm loops synced, and one starts to accelerate until it reaches double the frequency of the other one, and then going back to normal and catching phase again (beat or bar synced)

Has anyone done something like this and can point out possible solutions?My calculous is pretty oxidized and i don't know how to approach the problem....

Roman Thilenius's icon


unlike for data rate, which is really nasty...

https://cycling74.com/forums/synced-tempo-change-like-ritardandoaccelerando

...it is quite simple for signals.

you just have to take care that ramp time, base speed and end speed are in a certain relation to each other.

your personal sunday play package: click the numbers and find out the rule(s)!

rita and herbert, sundays often in partnerlook.

rita-signal.zip
zip 0.70 KB

playmodes's icon

Whoa! Thanks for your help Roman!
It's funny to see there's another actual thread revolving around a similar issue!

I tried to adapt your example to my needs, but again, i get stuck at figuring out this relationship between the base frequency of the phasors and the time the speed keeps altered and ramping up/down.
On your example, with the phasor at 1hz and the ramp times at 2000ms everything worked great...

But for my needs, i'm working at a base frequency of 0.03125hz, and ramp times need to be recalculated. In addition, i need to keep the frequency higher for a while (doesn't need to be an exact number, but ideally close to a a cycle of the base speed (around 32seconds minus the accel/decel time)

I'm afraid my dumbness is so swollen right now...

Max Patch
Copy patch and select New From Clipboard in Max.

Roman Thilenius's icon


(are you sure your phases were in sync bf you tried? bc the nonworking numbers in the example fucks that up. 0.03125/4000/24000/4000 works for me.)

it is not easy for me, either. i have a readymade patch somewhere but a ready solution wont fit to any possible case anyway, so i take the chance here in the forums to refresh my mind. :)

the good news is that... the base speed doesnt not matter! the base speed is always the base for the ramp amplitude already (see the +~)

since 1Hz is the equivalent of 1000 ms, the whole thing just works as soon as the total number of ms matches full integer seconds - and the multiplier is an integer, too.

only if you need it more flexible, then you can go deeper with more complex calculations.

for example when the fade in and the fade out have different but given lengths, then you have to calculate how the hold time has to be in order to come back to the correct phase.

in that case:

ramp-up-time*((x+y)/2) + hold-time*(y) + ramp-down-time*((x+y)/2) == must result in an integer number of seconds

to calculate, you can use "rate" values instead of actual Hz.

example:

you want accelerate from 30Hz to 90Hz in 1000ms and then you want to hold for 1600 ms.

x is always 1 and, well, y is 3 here.

1000*((1+3)/2) + 1600*(3) + ramp-down-time*((1+3)/2) == must result in an integer number of seconds

-> 1500 + 4800 + ramp-down-time*1.5 == must result in an integer*1000

-> 6300 + ramp-down-time*1.5 == [1000, 2000, 3000, 4000, 5000, ...]

(now i am not sure how to continue because i failed school, but you get the idea.)

so for [1000, ]

-> 1000 == 6300 + ramp-down-time*1.5

-> 1000/1.5 == 6300/1.5 + ramp-down-time

-> ramp-down-time == [-3533.3333, -2533.3333, -1533.3333 , -533.3333, 466.6666, ...

(strange? not, not strange, because we already used 2600ms for the first to segments. mathematically negative numbers would be correctly in place with the main beat, too.
you just cant use them unless you are marty mcfly.)


so we have to add a third segment now which may be 466.66, 1466.66, 2466.66 ms long, because 466,66 ms is what we are missing to the next cycle.

please try this example and prove me wrong.^^

Roman Thilenius's icon


damn, it´s wrong again.

llet´s do the auto lenght (at only integer speed multipliers) first.

to get the required lenght in milliseconds all you have to do is to get the rest of twice the sum of the rest of the difference of the hold time and one second plus the rest of the difference of the ramp time and one second.

couldnt be easier, huh?

$f1 -> ramp time in ms, $f2 -> hold time in ms

expr (((1000.-($f1-int($f1/1000.)*1000.)) + ((1000.-($f2-int($f2/1000.)*1000.)))*2)-int(((1000.-($f1-int($f1/1000.)*1000.)) + ((1000.-($f2-int($f2/1000.)*1000.)))*2)/1000.)*1000.)

== allowed lenght(s) for the other ramp time in ms.

playmodes's icon

Hi again! thanks for your help Roman!

Yes, you're right, the 4000 24000 4000 ramp configuration works. As you said, i might have had unsynced phasors when starting.

Actually, i got a bunch of working configurations for my phasor speed, all of them figured out "manually". This should be enough to suit my needs, and i could leave it as it is and it would work for me... but it would be great to find a generalized solution for any phasor frequency or variable ramp times!

I tried with the last expr you suggest, and result is always zero. There might be some typo somewhere... I'll try to go through it carefully and see where the error is...

in any case, thanks for your help!!!

Roman Thilenius's icon


the expr works, but later i noticed that it for some reason only works for inputs of 100s, i.e. 3300, 3400, ... and i have absolutely no idea where that comes from. so it remains on my to do list.

playmodes's icon

well, after some time it looks like we came up with a working solution!

let's see if its useful for someone else.... thanks for your help Roman!

Max Patch
Copy patch and select New From Clipboard in Max.

Vincent Goudard's icon

It sounds like what you're looking for is a phase locked loop algorithm :

https://en.wikipedia.org/wiki/Phase-locked_loop

I had done this with Max regular objects a while ago, but seeing this mail got me updating it with gen~ :

Max Patch
Copy patch and select New From Clipboard in Max.

playmodes's icon

Yeah! that's a nice implementation Vincent! thanks for pointing out the name of this concept. It will help implementing it more efficiently.

Do you know of any example patch on using this PLL on audio loops (ie, syncing and de-syncing rhythms)?

Vincent Goudard's icon

That was precisely the purpose, I used PLLs to play a series of mechanical sound loops that would synchronize at some point, along with 3D graphics elements rotating along ... But it was a long while ago and you wouldn't want to see the patch! :)

sousastep's icon

made this before I knew what PLLs were. it works well with stutter effects and LFOs. just dropping it here in case anyone finds it useful:

sousaPLL.zip
zip