[sdiy] Frequency follower idea. Question about FM.
cheater cheater
cheater00 at gmail.com
Thu Sep 9 18:12:57 CEST 2010
Hi guys,
I was wondering recently about syncing VCOs to other oscillators, and
I came up with a framework idea of how this could be done in a new and
I think interesting way. I wonder what you guys think about it.
One of the problems is: you want an analogue LFO that is tempo-synced,
but you want e.g. a sinewave, or a triangle wave, and very importantly
it must reach the amplitude maximum. If you just coarsely set the
frequency of the VCO and then sync it to sequencer pulses, then you
lose the amplitude (the typical DCO problem). If on the other hand you
don't want to lose the amplitude (because, for example, the LFO
modulates the pitch and it's important that it reaches a certain
interval), then the only other way for the VCO to catch up is for its
pitch to be raised temporarily. It's similar to how beatmatching works
with vinyl. Of course, this can work well for audio-rate VCOs as well.
So here's the idea with how vinyl works vs how VCOs work. We have two
VCOs vs two adapters with vinyl records on them.
1. unsynced VCOs - two records are playing with separate tempo. There
is no sync.
2. Hardsynced VCOs: every time VCO1 reaches its sync point, the VCO2
is also reset towards its own sync point. This can be seen as speeding
up VCO2 to a very high speed of oscillation until it reaches its sync
point. The analogy here would be that when vinyl 1 reaches a kick,
vinyl 2 is sped up to nearly-infinite speed until it reaches the kick.
Since the speed is infinite, the operation takes an infinitesimal
amount of time, and in the next measure vinyl 1 and vinyl 2 start out
perfectly in phase. Because they are probably set to different tempos
(the probability of having the same tempos is 0), they will quickly
drift out of sync.
3. Beatmatching: this is how records are synced: vinyl 1 is playing at
a certain rate, vinyl 2 is playing at another rate. First the two are
synced together. Then the dj checks if vinyl 2 is slower or faster and
adjusts the rate of deck 2 to be higher or lower. At the same time he
either pushes vinyl 2 forward or taps it with the finger to slow it
down.
This could look like this with VCOs: You sync the two VCOs together.
You have access to the phases of both VCOs and check how quickly they
fall apart. The derivative of their difference is the difference in
frequency that needs to be added to VCO2. Then, the oscillators are in
frequency sync (let's call this part we have just accomplished
"frequency calibration"). However, after this happens, the oscillator
needs to be 'pushed forward'. We can do this by injecting some phase
to the VCO. However, so that there is no click*, we can limit the rate
at which the VCO is being "pushed forward". We can do this by
frequency-modulating the VCO one time with a windowing function to
speed it up, or inverted windowing function to slow it down (let's
call that part "phase calibration"). During the phase calibration, the
frequency calibration should be somehow disabled. However, in a
running process, it would be undesirable to have a state-machine, so
maybe some form of continuous process could be invented from this.
I have below included the mathematics behind this technique. One
question is how to realize a fairly smooth windowing function.
*I believe if we have a carrier at frequency f_1 and it is modulated
by something that has frequency content (much) lower than f_1, then
you should not get any new audio-rate harmonics that are not "part of
f_1", should you? How does this work exactly? Is there a special rule
that says that your modulator needs to be band-limited to a certain
frequency dependent on f_1? I understand that this question is not
stated 100% properly, but any hints in this region are good. Basically
I have an audio-rate carrier, and I want to frequency-modulate it so
that no clicks/added harmonics are perceived in the output.
Also on a similar note, the MF-107 FreqBox: Does anyone know how this
thing functions? Does it have a PLL inside? I assume it has a PLL and
a VCO, and the PLL can sync the VCO, while the original signal can FM
the VCO. An env follower can FM and AM the VCO.
Here are the maths for the calibration:
p_1, p_2
phases of oscillators 1 and 2
r = p_1 - p_2
Phase difference between oscillators 1 and 2.
dr/dt
the rate of change of the phase difference.
If for example r is negative, and keeps on falling (we are
"unwrapping" r, instead of counting it modulo 2pi) then raising the
pitch of vco2 a bit will make the difference r drop a little less.
Therefore, we need to heighten the frequency by -h*dr/dt, where h is
some constant:
f_2 |-> f_2 + (-h) * dr/dt
After this happens, dr/dt ~= 0 (is nearly equal to zero). Therefore r
is constant. We need to inject the amount r of voltage into oscillator
2's accumulator:
r = p_1 - p_2
p_2 = p_1 - r
if we want p_2 to be equal to p_1, we need to add something to it:
p_2 + x = p_1
p_1 - r + x = p_1
x = r
Therefore we need to add r to p_2 :)
To add r to p_2 we can do a frequency modulation by a window function w(t).
The (unwrapped) phase of vco2 called p_2 is the integral of its frequency f_2:
p_2(t_now) = b Int_0^{t_now} f_2(t) dt + p_2(0)
That is, the phase at time t=t_now is the integral from time t=0 to
t=t_now of the frequency control voltage f_2(t) over the time-variable
"t", multiplied by an amplitude "b" (which depends on the design of
the VCO), and all that added to the phase it had at t=0.
similarly, for vco1:
p_1(t_now) = b Int_0^{t_now} f_1(t) dt + p_1(0).
We assume that f_1=f_2=const starting at some point we'll start
calling t=1. The number 1 is chosen arbitrarily. It might mean t=1
second. At t=1, the accumulators had phases p_1(1) and p_2(1) and the
VCOs were at the same frequencies, meaning the phase rises at the same
speed. We rebase our integral and with those constraints we can start
counting it from t=1.
This means that
p_1(t_now) = b Int_1^{t_now} f_1(t) dt + p_1(1)
and
p_2(t_now) = b Int_1^{t_now} f_1(t) dt + p_2(1)
therefore for t_now > 1, p_1(t_now) - p_2(t_now = p_1(1) - p_2(1).
This difference is our, now constant, value r.
We need to add r to p_2 somehow. This means that starting with t_now >
T, we want this to be the case:
p_2(t_now) = b Int_1^{t_now} f_2(t) dt + r + p_2(1)
The only parameter we can manipulate is f_2(t). If we do not
manipulate it, after t=1 it will stay equal to f_1(t) and therefore
constant.
So we can do this:
p_2(t_now) = b Int_1^{t_now} f_2(t) + k*w(t) dt + p_2(1)
= b Int_1^{t_now} f_2(t) dt + b Int_1^{t_now} k*w(t) dt + p_2(1)
But what we want is p_2(t_now) = b Int_1^{t_now} f_2(t) dt + r + p_2(1)
Therefore, we need to choose w(t) such that:
b Int_1^{t_now} k*w(t) dt = r
We know b (it comes from the design of our oscillator), we know r, we
need to find k and w(t).
We need our function w to be such that its integral is 1 when counted
from point t_0>1 where we begin emitting it, until T where we will
have stopped emitting it. We also want it to not add any phase
afterwards, that means, for t>T w(t)=0. And we don't want it to add
any frequency before we start emitting it, that means for t<t_0,
w(t)=0. This means that:
Int_{t_0}^T w(t) dt = 1
for u < t_0 < T < v: Int_u^v w(t) dt = 1
So we have chosen our window function, therefore we have w(t).
Our equation looks like this:
b Int_1^{t_now} k*w(t) dt = r
b*k Int_1^{t_now} w(t) dt = r
Because 1 < t_0 and t_now > T, we can say:
b*k * 1 = r
Therefore k = r/b.
This means we need to inject our windowing function once, while its
amplitude is multiplied by the number r/b.
I believe it is possible to extend this technique to a continuous time
control system. The technique above will only work for when VCO1 has a
constant frequency. A continuous control system could work for the
case when VCO1 is of changing frequency.
This technique could sound fairly differently depending on what
windowing function is chosen.
A continuous technique could work like this:
We define two areas in which p_2(t) can be:
(A) it's either in in the area p_2(t) \in (p_1(t)-pi, p_1(t) ) <mod 2pi>
(B) or it's in the area p_2(t) \in (p_1(t), p_1(t) + pi) <mod 2pi>
The cases p_2(t) = p_1(t) and p_2(t) = p_1(t)+pi <mod 2pi> are
excluded for clarity, since the probability they will happen is 0.
There is a comparator that outputs 1 for case (A) and -1 for case (B).
Let's call it L(t).
This means, for example, if VCO2 is just a tiny amount behind VCO1,
L(t) will be +1, and if it's just in front of VCO1, L(t) will be -1.
Assume we have case (A). Every now and then, while L(t) is positive,
we feed a small amount of charge, say K, into the phase accumulator
p_2(t) to "catch up" and perform phase calibration. As soon as we
overtake VCO1, L(t) will become negative, and K will also become
negative, therefore "slowing down" p_2(t). This means that our p_2(t)
will be jumping back and forth from being just under to just above
p_1(t).
Of course a continuous version of summation is an integration. So a
way to do the above is to have an current following L(t) and add that
current, call it M(t), to p_2(t). (I am, of course, not good enough
with electronics to work out the specifics of that).
However, we still need to make sure that the change only happens
gradually: starts up slow, speeds up, and ends slow. Therefore before
we inject M(t) into p_2(t), we pull it through a sine shaper. The
shaper should somehow auto-adjust so that the electric charge
injection becomes slowest as p_2 approaches p_1. I am not sure what
the specifics could be of this. Does anyone have any ideas?
To prevent oscillation of the system when p_2(t) ~= p_1(t) and when
p_2(t) ~= p_1(t) - pi <mod 2pi>, we put a low-pass filter of some
frequency F on M(t) so that it does not "zipper" along with L(t). In
the latter case the system should be knocked out of place into either
state domain (A) or state domain (B) by the fact that frequencies are
different.
Of course, of f_1 > f_2, then we would need to keep on emitting M(t)
indefinitely, because p_2(t) would keep on lagging behind.
However, the closer we get to the state p_1(t) ~= p_2(t), the easier
it will be for us to start marking up the frequency. This is because
the rate of change of r will be lower and lower. This means that we
have a system that is now under control and we can slowly start doing
other things with it. We look at L(t) statistically. If f_2 < f_1,
then L(t) will be mostly positive. If f_2 > f_1, then L(t) will be
mostly negative. The closer f_2 is to f_1, the more even the
distribution of L(t) will be across the values +1 and -1. We can take
the low-pass-filtered M(t) and inject it into some form of
sample-holding capacitor. The charge of that capacitor will be
mirrored into some form of positive voltage which raises or lowers the
frequency of VCO2. As f_2 -> f_1, M(t) will tend to 0, and the
frequency of f_2 will stabilize.
This technique could work better than the previous one for the
situation where f_1 changes. However the faster f_1 changes, the
higher the frequency of the lowpass filter on M(t) should be, so that
f_2 has enough resource to catch up. Therefore: F(t) ~ f_1'(t) (note
the derivative sign)
This fourth approach can be analogous to the DJ catching up with two
hands on the record adapter 2, trying to run his hands so quickly that
adapter 2 is in sync with adapter 1; then, a second person starts
correcting the pitch, during which the dj slows down his hands and
finally lets go of the record what so ever.
Of course both techniques I described above can also be enhanced to
allow keeping the two oscillators at a certain desired difference of
phases r = r_0. This could prove sonically interesting.
You can assume that the second technique will not work *ideally*, that
is, there will be some sway in the value of r, even if f_1 is
relatively constant. This will probably create a somewhat random
phasing sound which is very pleasing to the ear.
If the low pass filtered M(t) is completely disconnected from the core
of VCO2, L(t) can be used as a measure of how close together f_1 and
f_2 are. You could do it this way: you check how symmetric L(t) is
(over a short period of time) and the longer it is symmetric, the
higher voltage you output from an integrator. On the other hand if
L(t) stops being symmetric, the charge in the integrator is reduced.
The integrator should have a low rise rate and a high fall rate. It
can be used to amplitude-modulate VCO2, making VCO2 output only when
VCO1 is near its frequency. This can be used for a resonator. Because
of the relatively low parts count for a minimum implementation using a
fixed frequency LPF for M(t) and a fixed frequency oscillator for
VCO2, you could easily imagine banks of such oscillators, working as a
very interesting resonator bank. This could be very musically
pleasing, giving a sweeping tone from VCO1 a nice arpeggiated
characteristic. You could even use some sort of fixed AD envelope to
give the resonances a plucked sound.
The electronic implementation is left as an excercise for the reader.
Cheers,
D.
More information about the Synth-diy
mailing list