Wednesday, January 27, 2021

Trying to create a CV curve to convert exponential VCA to linear.

In this post I'll try to explain exactly how the xxx2164 (SSM2164, v2164, AS2164 etc) responds to CV and how it (in theory) can be linearised when controlled digitally. I've written V2164 throughout the post as this is the chip I have at hand, but they should all be similar.

NB: I write my math as I go along, so it reflects my way of thinking. It may not be the most direct route to the final result, nor the best way of explaining, but at least I think the results are correct

Whether or not the results are useful in practice are to be seen. The V2164 is temperature sensitive and may not follow the stated -0.033V/dB response at all (or indeed any) temperature. There may also be differences between chips, and the DAC resolution may not be high enough to prevent stepping even when using 16bit DACs.

The V2164 

V2164 has a -33mV/dB response, meaning a 33mV increase leads to a 1dB attenuation.

When using the V2164 with a 3.3V control signal, I realised that it very quickly gets very quiet and thus it's hard to set the exact gain/ attenuation that you want. As mentioned here, the usefull CV range is 2V which results in 2V / 0.033V = 60dB attenuation.

The signal amplitude is doubled/halved for every 6dB change (0.2V in our case) as noted here. That would as far as I understand, mean that the signal is halved 10 times at 2V. With a +/-5V signal input, output would be

$$((((((((((5 / 2) / 2) / 2) / 2) / 2) / 2) / 2) / 2) / 2) / 2) = 5 / 2^{10} = +/- 0.0049V$$

But what is the function / relation between CV and VCA response?


Decibel - change in amplitude 

At any time, the increase in dB between two levels \(a_0\) and \(a\), can be written as

$$d = 20 \cdot log_{10}({a \over a_0})$$

where \(log_{10}\) is the 10-logarithm. From now on I'll write just \(log\)

For example, if the initial amplitude a_0 was 1V and the new level a was 2V, the increase would be

$$d = 20 \cdot log({2 \over 1}) = 6.02dB$$

which is indeed what we said above - a doubling of amplitude is the same as a 6dB change. Let's confirm this with our calculation above - going from 0.0049V to 5V:

$$d = 20 \cdot log({5 \over 0.0049}) = 60.2dB$$

So, how can we rewrite the formula to represent the relationship between our CV and output amplitude?

Let's first express the amplitude change as a function of change in dB

$$d = 20 \cdot log({a \over a_0})$$ $$10^{({d \over 20})} = 10^{log({a \over a_0})} = {a \over a_0}$$ $${a \over a_0} = 10^{({d \over 20})}$$

Taking it one step further to make it easy to plot, we move \(a_0\) to the other side:

$$a = a_0 \cdot 10^{({d \over 20})}$$


Let's check with our initial ratio:

$$a = 1 \cdot 10^{({6.02 \over 20})} = 2$$

Just as expected. Here is a plot of this function:

X is change in dB, Y is amplitude. We can see that the initial amplitude is 1 and that 6dB gives an amplitude of 2. Increasing dB by another 6dB to 12dB shows another doubling of amplitude to 4


From decibel formula to CV response

One final step is necessary, we need to go from the general equation for change in decibel to response to our CV. This should be fairly easy. We know that the response is -0.033V per dB (note: negative volt, i.e. a voltage increase leads to attenuation, not amplification):

$$d_{dB} = {v_{V} \over {-0.033_{V \over dB}}}$$

which gives us a as a function of v volts:

$$a = a_0 \cdot 10^{({{v \over {-0.033}} \over 20})}$$ $$a = a_0 \cdot 10^{({v \over {-0.66}})}$$


Let's check:

Increasing the CV with 0.033V should attenuate the signal 1dB, meaning that a 0.2V signal should attenuate the signal 6dB, which means halving the amplitude. We choose 1 as the initial amplitude, because with CV = 0 the V2164 should have unity gain. While at it, let's rename amplitude a to gain g as that is really what we're talking about when it comes to the VCA:

$$g = g_0 \cdot 10^{({v \over {-0.66}})}$$

\(g_0 = 1\) (unity gain when CV is 0) gives us

$$g = 10^{({v \over {-0.66}})}$$

and finally

$$g = 10^{({0.2 \over {-0.66}})} = 0.5$$

Again, as expected. Here is a plot of the function:

X is CV in volts, Y is gain (unitless). As expected, the signal starts at 1 when the CV is 0, and drops exponentially when the CV increases. at 0.2V the gain has halved to 0.5


Finding the equation for a linear response

Great! Now we know what we're up against. Next, we need something that takes a number - our internal linear control signal, let's call it c - and converts it into something we can input to the VCA CV to counter the function above. We need something that increases it's drop at the same rate as the function above decreases its drop.

So let's see what we've got.


We want the following to be true:

$$10^{({f(c) \over {-0.66}})} = k \cdot c$$

where k is a constant (rate of change, stigningstall in norwegian), in other words, we want something that makes our exponential function linear. We already know that \(f(c) = v\) from our definition, so let's use that.


Now we need to figure out what the relationship between v and c is:

$$log(10^{({v \over {-0.66}})}) = log( k \cdot c)$$ $${v \over {-0.66}} = log( k \cdot c)$$ $$v = -0.66 \cdot log( k \cdot c)$$

This works fine for positive k (e.g. rising linear response), which is what we usually want. However, after \(k \cdot c = 1\) it becomes a negative number which we cannot represent directly with a DAC. Also, when \(k \cdot c = 0\), \(log(k \cdot c)\) is infinite, which means we can never really reach all the way down to 0 gain using an exponentially controlled VCA.

As x approaches 0 from above, y approaches infinity. When x (or rather \(k \cdot c\) in our case) is > 1, y is negative.


Combining the equation for v with our equation for g yields exactly what we want - a linear response (rate of change k times control signal c on the horizontal axis, gain g on the vertical).


For a negative k (e.g. falling response), \(log(k \cdot c)\) is not defined for positive control signals c as \(k \cdot c\) is a negative number. To still be able to use a positive control signal c to represent a falling curve, we need to add something to offset our zero point: \(log(p + k \cdot c)\) where p is the desired gain at c = 0 (e.g. what we get when we set c to 0 and combine our two equations). 

The combined response is not defined for positive values of c when k is negative. 

Adding a constant "shifts" the graph to the right. Here p is 2 and k = -0.5: we get a gain of 2 when c is 0 and a gain of 0 when c is 4. NB: This is just in theory, as explained above we cannot reach g = 2 for c = 0 because the logarithm approaches infinity. More on that further down.


p may still be present for positive values of k, however the same limitation applies - if \(p + k \cdot c < 0\) the result is not defined, and if \(-0.66 \cdot log(p + k \cdot c)\) is negative it cannot be represented directly by a DAC.


Our relation between c and v is thus:

$$v = -0.66 \cdot log( p + k \cdot c)$$

with the limitations

$$p + k \cdot c >= 0$$ $$log(p + k \cdot c) < 0$$


Using this in our equation for the VCA gives us

$$g = 10^{({{-0.66 \cdot log( p + k \cdot c)} \over {-0.66}})}$$ $$g = p + k \cdot c$$

which is indeed a straight line with gain p at \(c = 0\) and gain 0 at \(k \cdot c = -p\)


How to use this in practice

Now, we still have the issue of not being able to reach g = 0. We need to look back at what we said in the beginning, the effective CV range of the V2164 is 0 to 2V, and at 2V it has an attenuation of 60dB (or gain of -60dB). This is what we should use as our minimum value for g. The maximum value should be whatever we want as our maximum gain, noting that unity gain (g=1) is the highest we can get using a DAC directly connected to the VCA.

We need to know exactly what we mean by -60dB in this case. Here, it means -60dB down from unity gain. A change in dB from an initial value of a_0 to a new value a is written as 

$$d = 20 \cdot log({a \over a_0})$$

For us, \(a_0\) is 1 so 

$$20 \cdot log(a) = -60$$ $$log(a) = -3$$ $$a = 10^{-3} = 0.001$$

Let \(c_{start}\) and \(c_{end}\) be the two extremes for our control signal:

This gives us two equations from \(g = p + k \cdot c\)

I) \(g_{start} = p + k \cdot c_{start}\)

II) \(g_{end} = p + k \cdot c_{end}\)

We can now pick our \(g_{start}\), \(g_{end}\), \(c_{start}\) and \(c_{end}\) to find k and p.

Let's give two examples based on whether we want a rising or falling response to our control signal. We choose to use volts as the unit for our control signal and set 0V to 5V as the range. We could also choose the range to match whatever representation we use in our code, for example 0 to 65535 if we represent the control signal as an unsigned int.


For rising control signals

\(g_{start} = 0.001\), \(g_{end} = 1\), \(c_{start} = 0V\) and \(c_{end} = 5V\)

I) \(0.001 = p + k \cdot 0 => p = 0.001\)

II) \(1 = p + k \cdot 5V\)

I + II) \(k \cdot 5V = 1 - 0.001 => k = {0.999 \over 5}\)

Finally, we insert this into our formula for v, \(v = -0.66 \cdot log(p + k \cdot c)\)

\(v = -0.66 \cdot log(0.001 + {0.999 \over 5} \cdot c)\)

Our desired response. A 0 to 5V CV gives a gain of 0.001 to 1

For falling control signals:

\(g_{start} = 1\), \(g_{end} = 0.001\), \(c_{start} = 0V\) and \(c_{end} = 5V\)

I) \(1 = p + k \cdot 0 => p = 1\)

II) \(0.001 = p + k \cdot 5V\)

I + II) \(0.001 = 1 + k \cdot 5V => k \cdot 5V = 0.001 - 1 => k = \frac{-0.999}{5}\)


It should come as no surprise that k is indeed the negative version of the result for the rising control signal, the absolute value of the rate of change is the same for both.

Again we insert this into our formula for v, \(v = -0.66 \cdot log( p + k \cdot c)\)

$$v = -0.66 \cdot log( 1 + \frac{-0.999}{5} \cdot c)$$

Increased attenuation as CV increases. 5V CV gives a gain of 0.001

From CV seen at the VCA to signal that controls the DAC

We have one final step to make all this useful.

We have from the start assumed that whatever we are working with outputs voltages directly from our control signal, and that our \(c_{end}\) outputs exactly 2V. 

This of course is not true for a DAC. We can choose to use a DAC in two ways:

  1. We use a reference voltage of 2V. The max DAC value is then 2V
  2. We use a different reference voltage, say 5V, and use external circuitry to change this into our 2V.

In both cases, we need to know what DAC control signal results in 1V at the VCA control input

Ex: 

If we're using a 16bit DAC and a 2V reference, 1V is represented as 65536 / 2 - 1

If we're using a 16bit DAC and a 5V reference, 1V is represented as 65536 / 5 - 1


Let s be the DAC control signal, \(s_{1V}\) be the DAC control signal value that results in 1V at the VCA input, and v the output voltage seen at the VCA CV input. The relationship between v and d is then

$$v = \frac{d}{s_{1V}}$$


Entering this into our expression for v, \(v = -0.66 \cdot log( p + k \cdot c)\), gives us

$$\frac{s}{s_{1V}} = -0.66 \cdot log( p + k \cdot c)$$

$$s = -0.66 \cdot s_{1V} \cdot log( p + k \cdot c)$$

There is a possible pitfall to be aware of. How well the effort to linearise the VCA works in practice depends on the DAC resolution. The VCA attenuation increases rapidly in the beginning, a very small voltage change gives a huge attenuation. If the DAC resolution is not high enough, each step changes the voltage too much and we will get audible stepping for slow moving CVs.


Summary of useful results

The general equation to linearise the response of the V2164 is

$$s = -0.66 \cdot s_{1V} \cdot log( p + k \cdot c)$$

where 

  • \(s\) is the DAC control signal value, possibly an unsigned int for a 16bit DAC
  • \(s_{1V}\) is the DAC control signal value that gives 1V at the VCA input (e.g. 65536 / 5 - 1 with a 5v reference)
  • \(p\) is the desired VCA gain at c = 0
  • \(k\) is the rate of change (gain / control)
  • \(c\) is our internal control signal with a unit of our choosing
\(p\) and \(k\) are found by selecting min/max gain and min/max control signal values, and solving the following two equations with two unknowns:

I) \(g_{start} = p + k \cdot c_{start}\)

II) \(g_{end} = p + k \cdot c_{end}\)

In practice, gain can never reach 0. For a positive k, p must be > 0. For a negative k we need need to use a g_{end} > 0.

Remember

- k changes when we change between volts and int value for our internal control signal.

- c and s do not have to use the same units

- c is assumed to be positive in all calculations above, but it may very well be possible to use negative values here. I just haven't checked.

- low DAC resolution will lead to audible stepping


Further thoughts

If I remember correctly, the V2164 allows gain > 1 by using a negative CV.  Without actually trying, I would think that using the equations above would suffice for this as well. If you want to add 3dB of extra gain, just extend the desired attenuation down to -63dB and then add - 0.1V (3  * -0.033V) to the DAC output to shift everything 3dB up. I have not tested this though.

To linearise a different VCA with a different response, "just" replace -0.033V/dB in the initial equation for the CV response and the resulting linearising equation. The general cases are:

Let b be the CV response in volts per dB (-0.033V/dB for the V2164). We then get that:

gain as a function of CV is:

$$g = g_0 \cdot 10^{\frac{v}{b * 20}} $$

necessary linearising equation is

$$v = 20 \cdot b \cdot log( p + k \cdot c)$$

and the DAC control value for producing that v is

$$s = 20 \cdot b \cdot s_{1V} \cdot log( p + k \cdot c)$$


The end. Time to try this in real life!


Footnote: All graphs are made using https://www.desmos.com/calculator






No comments:

Post a Comment