søndag 16. april 2017

Juno 60 pre-filter level control

The Juno 60 mixes several waveforms before the filter, and it has a clever way of controlling the sub oscillator volume. As the sub oscillator output is a square wave, the wave is considered a binary on/off signal. It is connected to the base of a transistor, which when turned on and off either sinks its collector to ground or leaves it as it is.

To control the wave volume, the collector input is connected to the panel potentiometer (through a series of buffers/mux/demuxes, but that doesn't really matter, the principle is the same). The wave's amplitude (or "on value") will then equal the level of the panel potentiometer, though negative as the potentiometer value is inverted by IC17 on panel board A. The voltage is passed through an analog switch, IC16, which in turn is controlled by the Sub oscillator on/off switch, to completely disable the sub oscillator (incidentally, this feature has been removed from the Juno 106, here the potentiometer voltage is connected directly to the transistor collector).

Interestingly, the same arrangement exists for the pulse wave, only this time the analog switch connects the transistor to -15V instead of to a variable voltage. If one would like a controllable pulse wave volume, it would likely be easy to inject the control signal here.

As for the saw wave, it also has a switch and a transistor connected to it. However, as the saw wave is not binary, it cannot be controlled the same way. Instead, the wave is connected to the collector, and the transistor base is connected to the analog switch on panel board A. The wave is then sunk to ground if the transistor is on. In other words, the saw wave has no pre-filter volume control, only an on/off switch.

The noise input has its own volume control on panel board A (all voices use the same noise generator).

Oh, and by the way - all waveforms have a range of 0 to maximum -15V (the datasheet says the saw wave is 12V p.p, I have not checked the others but they have to be about the same to be mixable - the sub oscillator level for example originates as a 0 to +5V voltage but is inverted and amplified by IC17, and the pulse wave level is always 0 to -15V). They are fed through a 10uF non-polar capacitor (C5) just before the filter, which probably centers them around 0V.

onsdag 5. april 2017

Juno 106 vs 6/60 DCOs

There are some differences between the DCOs in the Juno 106 and the Juno 6/60 - except for the fact that the DCOs on the 106 are integrated into a single chip.

First of all, according to the datasheet, the 106 uses an NPN instead of a PNP transistor to reset the integrator (saw wave converter).

More interestingly, the way they sum the saw wave and the pulse waves are very different.

The Juno 60 has a separate control line for the pulse wave, connected to TR2. It looks just like the one for the saw wave (TR3) so one can assume that it turns on and off the pulse output. Also, the output of the pulse is sent through D2 which will block any positive halves of the pulse (? which sort of makes sense as the saw wave is also negative only).

The 106 on the other hand, has no such control line, which means that the pulse output is always on. The pulse output has a diode to ground which I assume means that it will never be negative (?).

So how can the 106 output a saw wave and no square wave? One theory may be that if the user selects saw wave only, the pwm is set to 50%. Summing the sqare and saw waves will chop up the saw wave just as it reaches its half period, and move the remainder upwards. If the amplitude of the saw and square waves are equal, the saw wave will magically realign with its phase shifted half a period, this time centered around 0V.

DISCLAIMER: This is only my initial theory after studying the datasheets, no measurements have been made. 

But how about when both the saw and pulse waves are on? Wouldn't this mess up how the wave turns out? Since the saw wave is positive and the pulse is negative, couldn't the total amplitude end up being double?

Well, the high part of the pulse will always come at the second half of the period, thus it will never "lift" the saw wave from higher that minus half the total voltage p-p. Also, The parts that are lifted will only be lifted by 1 x the voltage p-p.

In practice, this means that if we could set the duty cycle to 0%, the output would be a saw wave that starts at 0 and drops to minus the total voltage p-p. If the duty cycle is 50%, we get a saw wave with the same amplitude centered around 0V.

This is interesting and may reveal a flaw in my assumptions. As the wave is centered around 0V by a capacitor later, summing a pulse and saw wave this way will only shift the saw wave phase! I need to check if the polarity and phase assumptions for the square wave actually holds. What happens if instead the polarity is reversed or the phase shifted by half a period?

TODO: Write about SUB OSC and level control (done by using the output from the DAC) and how the passing through a diode affects the signal (reversed in one)- one uses NPN and the other uses PNP, 60 has a resistor to GND at the transistor base. The 106 has no on-off switch for the SUB OSC, only a volume control.

Both the 106 and the 60 DCOs have their outputs mixed with noise (with adjustable volume) right before a 10uF non-polarized cap and injected into the IR3109/800170 filter chips. The mixing point has no opamp connected to it so I assume this job is done by the chips. I guess the cap is there to filter out any DC component and center the waves around 0V. I have not looked closely at this - what happens here when the frequency changes for example, will still stay centered during the transition because the amplitude is still the same?

BTW: NP in the juno datasheet means Non-polarized (capacitor). MF means metal film (resistor).  G (capacitor) may mean 2% (needed for accuracy in the integrator).

mandag 3. april 2017

DCO saw core testing

I built the DCO saw core on a prototyping board Friday evening, and after some initial trouble, I got it working very well.

The core is heavily inspired by the Juno 6/60 DCO. The output of the MCU charges a capacitor, turning the output square wave into positive/negative spikes on each square wave edge. These in turn briefly switch on a transistor that discharges a capacitor. When the transistor is off, the capacitor is charged using a constant-current scheme where the cap is connected across an opamp (just like in a normal saw core VCO, see section "That old opamp trick again" of http://xonik.no/theory/vco/reference_current.html).

The Juno 60 uses a 2SA1015 PNP transistor. I tried replacing this with both a 2N3906 and a BC557, they both work very well.

MCU output pulse train (top) vs. transistor control spikes (bottom). top is 5V/square, bottom is 1V/square and shifted down to make both visible

I had no DAC available for the trial, so the charging current was regulated using a potentiometer as a voltage divider, buffering the output with an opamp and piping the result through a resistor to convert it to a current. After initially screwing up and connecting the center pin of the pot to ground, things started working very well.
A perfect 5v p-p saw wave generated from the pulse train on top. 

A few challenges still persist:

1) The output wave starts at 0 and goes downwards until it is reset. It has to be centered

2) My calculations are based on an assumption that the maximum voltage should be 5V. I completely forgot that it has to be 5V on each side of the wave, making the full wave 10Vp.p.

3) For some reason, the charging stops at -8V. Not sure if this is due to the opamp or something else, but it has to be fixed. The Juno 60 service manual says they have a 12Vp-p output, so it should be possible to fix this.
The charging of the cap maxes out at 8V (looks like 10V here but Y-offset was wrong).
4) Charging starts at the negative going edge of the MCU output wave while the MCU output wave is first high then low through the course of a cycle. This has to change, either in code or by replacing the PNP with an NPN transistor (The Juno 106 service manual says it uses an NPN but I couldn't get this working immediately. I'll look into it).

5) With a 100k charging current resistor, the charging current won't be strong enough for the highest frequencies. A 39k resistor may work (but not for a 10Vp-p wave).

6) I should check if a constant reset timer interval may work (e.g. not a 50/50 duty cycle for the MCU output wave). If so I'll save some clock cycles during frequency calculations.

torsdag 30. mars 2017

Alternative approach - DCO MCU

It would be possible to use a lower-end PIC32 MCU as the DCO MCU. We'll get a few advantages:

1) It can run at a higher speed so calculations will be faster
2) It may have enough ROM to store a full lookup table, or where we may only have to interpolate every second sample. As the MCU is 32bit, interpolation is a simple case of adding two adjacent samples and shifting right by one (dividing by 2).
3) Even with a lookup table, 16 bit multiplications are supported in hardware so calculations will be very fast
4) Both input and output SPIs are buffered so we need not fear losing bytes
5) It natively supports I2S so interfacing with cheap DACs from ebay is possible.

1) It may possibly be harder to write an accurate timer as it has a different architecture with more complex pipelining?
2) Price (but not an issue if using DACs from ebay).

BTW: a faster interpolation without the use of a derivative lookup table is also possible on the PIC18F if we choose one with at least 64k program memory, such as the PIC18F26k40. Chosing the PIC18F27K40 means we will not have to do any interpolation at all as it has 128k program memory.

søndag 26. mars 2017

SPI Daisy chaining

Just  a quick tip from the PIC18F datasheet: SPI interfaces on multiple MCUs may be daisy chained, connecting the output of one to the input of the next. They will then function as a long shift register, shifted 8 bits for every SPI send. NB: Chip select must be connected to all MCUs if used.

DCO: SPI and DAC accuracy

A few compromises have to be made when making the DCO. There are however a few things that must be done right.

First of all, we cannot afford to lose any input commands. This will put the SPI input buffer in an unknown state, possibly locking up the DCO.

With this in mind, we can do a few calculations.

First of all - each frequency update is based on a 16bit integer. The SPI buffer is only 8 bits long, so two bytes must be transferred. Each transfer triggers an interrupt, and that interrupt must copy the transferred byte from the SPI buffer to somewhere else before the next byte arrives.

Fortunately, the SPI buffer is, as it says, buffered. This means that it is not written until the last bit of the byte is received. In addition, there is a short delay between bytes.

As an example, when running the SPI bus at 200kHz, a byte is 40uS long. The delay between two bytes is 7.5uS (when output from node.js on a Raspberry PI).

Running the MCU at 20MHz we have an instruction clock of 5MHz, and each instruction takes 0.2uS. This means that with a 200kHz SPI bus and 20MHz clock, we have 237 instruction cycles to handle a received byte.

This is of course much more than we need - as long as the interrupt handler triggers immediately. But for the DCO to be as accurate as possible, we have given priority to the timer that sets the output wave period. The SPI interrupt will be blocked if a timer interrupt has been received and will not be treated until the timer interrupt handler returns. Thus, we have to make sure the time it takes to enter the timer interrupt handler, do whatever it needs to do, return from the handler and then enter the SPI (low priority) interrupt handler, takes less than 237 instructions - if not, we may be inside the timer interrupt handler when the next SPI byte arrives and we'll lose the previous byte.

This sounds all good, right? The time it takes to reset the timer is not that long. Well, we do actually have a problem. If we are to both reset the timer AND change the DAC value (that controls the current that charges the integrator capacitor making the saw wave), we run into trouble. The DAC is written to using SPI, and we have to write three bytes to set it. Unless the DAC SPI runs at several MHz, we do not have time to write to it within the 47uS we have available. In simple terms, we cannot write to the DAC inside the interrupt handler.

So what is the consequence of this? 

The only other place to write to the DAC is inside the main program loop. As we will be at an arbitrary place in the code when a timer interrupt triggers, we will get a delay from when the timer triggers to where the DAC update call is found (+ the time spent writing to the DAC).

To reduce the maximum delay, we may check if a DAC update has been requested and update the DAC at several spots in the main loop.

But how big is the consequence of delaying the DAC?

At 200kHz, updating the DAC takes approximately 135uS = 675 instruction cycles. This delay is unavoidable.

The longest single method within the main loop, recalculating the frequency, takes 723 cycles. If we break this up into 5 intervals, we'll add around 150cycles to the maximum delay, which will then be around 825 cycles or 165uS.

What does this mean?

It means that for 165uS, the DAC will output the wrong voltage, and the capacitor will charge too fast or too slow. If it charges too slow, the capacitor will be at less than 5V when the charging is reset by the period timer. If it charges too fast, it will be at more than 5V. But how much?

Let's look at the two extremes:

Going from 16.5Hz to 20kHz

Here, the DAC will have a very low charge current. The period at 20kHz is 50uS. This means that for a little more than three periods, the charging will be way too low, in fact probably so low that the wave will look completely flat. However, this is only for 3 of 20.000 cycles within a second. Question is if it is audible.

Going from 20kHz to 16.5Hz

The DAC will have a very high charge current. It charges at the same level as when the frequency is 20kHz, which means that after 50uS, the output value is 5V and after 150uS it has reached 15V (but the buffer opamp or other parts of the circuit probably saturates, keeping the maximum at around 14.3V. The cap stays at this level for one full charging cycle, around 61mS. This is not a very ideal situation.

This is of course in the extreme cases. Most often the change in pitch will be small, but a few octaves are still likely.

What can be done to remedy this?

1) Increased DAC SPI speed - pushing the speed to 2MHz will reduce the write delay to 13.5uS, with a total of 43.5uS including the delay before we reach the reset DAC code. This is if the MCU and DAC can handle the increased SPI speed

2) Increase the MCU speed from 20MHz to 32MHz - this will reduce the maximum time before the DAC write is started from 30uS to 18.75uS (as each instruction now takes 0.125uS instead of 0.2uS.

3) Check more often if we need to update the DAC, further reducing the maximum time before the DAC is written to

4) If the DAC SPI speed is sufficiently high, put the write back into the interrupt routine, removing the delay before a write altogether.

If 1) is possible, and the rest of the timer interrupt handler takes less than 47.5uS - 13.5uS = 34uS, 4) is certainly the best option.

Input SPI speed

We chose 200kHz as the SPI speed at the start of this post. At this speed, 16 bytes will take 47.5uS to transfer (inc delay between bytes), giving an effective transfer rate of 21kB/s.  The Xonik M8 voice controller runs at less than 4k updates/second, so this is sufficient for updating tree DCOs at that rate. The PIC32 has a multi-byte SPI buffer, so we may actually write all bytes to the SPI buffer and forget about them, leaving the voice card MCU to do other duties while the buffer is written (though we have to write to the separate DCOs one at the time as the chip select lines must be changed between the DCO writes.

To further improve the performance of the main MCU (and reduce the delay between when a frequency update is requested and a new frequency is visible on the output), we should calculate the maximum time spent in the period timer interrupt handler and optimize the SPI speed such that the time spent transferring a byte is just barely longer than this.

Maximum delay

The maximum delay from a byte request has been received at the main voice controller to it is visible at the DCO input may be calculated as follows:

2 x matrix calculation time
+ 2 x byte transfer time
+ 1 x transfer delay
+ 1 x time spent calculating new frequency params
+ 1 x delay writing to timer registers
+ 1 x time that must be left for an update
+ 1 x longest cycle time
+ 1 x time within period interrupt handler
+ 1 x maximum delay before DAC write starts
+ 1 x DAC write time.

2 x matrix calc time because the command may arrive just after a calc has started and be written at the end of a calc update

Update: SPI and DAC speeds

The MAX5216 SPI can run at 50Mhz. The PIC SPI runs at maximum Fosc/4, which equals 5MHz with a 20MHz crystal, 8MHz with a 32Mhz. In any case, transferring 24 bits takes approx 27 instruction cycles, so setting the DAC in the interrupt routine is well within what is feasible. Thus, the delay from period start to the DAC is set is 27 * 0.125uS = 3.4uS + any cycles between the timer reset and the call to set the DAC - 7 cycles + the time it takes to call the SPI function - an estimate may be 40 cycles = 5uS in total (at 32MHz).

This means that in the case of a too-high charging current, the cap will be charged at max for about 1/10th of the charge time at 20kHz, contributing about 0.5V too much to the end result (5.5V instead of 5V). This is probably tolerable.

Similarly, the whole interrupt function will take 33 cycles (timer) + 40 cycles (DAC). Add 10 cycles to enter and store the SPI byte and the total is 83 cycles or 10.4uS. Transmission speed will then have to be more than 1.3uS per bit, which gives a max SPI speed of 769kHz (at 32MHz)

Update 2:

The only times we should have to update the charging current will be right after we have calculated and set a new frequency. For most frequencies, this update will happen right after an SPI write (for low frequencies we will get a delay, though). If we keep the DAC update outside of the interrupt handler, we will still normally not be inside the calculation routine for a new frequency when the interrupt returns, so the delay between timer update and DAC update will be minimal. We may still encounter a large delay as it may take up to one period from frequency calculation to the frequency has been set. If SPI bytes arrive faster than this (as they most likely will if the main controller runs at 2-4kHz), we may still be inside the calculation routine.

By moving the DAC update we'll shorten the delay to 43 cycles = 5.38uS, giving us a bit time of 0.673uS and a max SPI speed of 1.49MHz (at 32MHz clock speed)

Ultimately it all comes down to what is most important - a high SPI speed to minimize the time the master spends writing or a short delay before the DAC is set to assure a high max voltage accuracy.

As mentioned previously, we may use the multi-byte SPI buffer on the PIC32 based voice controller, so the exact write speed is not all that important (as we do writes as fire-and-forget) but faster is still better - we will have to write some special code that writes to the DCOs at regular intervals through one matrix recalculation cycle as we cannot afford wasting calculation time waiting for a write to complete before filling the SPI buffer with the next DCO values (Though perhaps it would be possible to come up with a chaining scheme where six bytes are clocked through the three DCOs before they are "commited" and the values read - perhaps by a chip select line going low or similar. The PIC32 is capable of generating an interrupt once the SPI buffer is empty, so it's easy to add a single line change when transmission is complete).

onsdag 22. mars 2017

SPI from raspberry PI to PIC18F

This is mostly for my own reference later:

The following is confirmed to work:

I've connected the raspberry PI as an SPI master. Only output and clock from the PI must be connected, not the PIC18F SPI out, as the PI is not 5V tolerant.

In my special PI-to-xonik m8 voice controller cable, the following pins are used:

PIN0: Signal (Master out/slave in, PI is master)
PIN2: Clock

These must be connected to the following on the EasyPIC 3 card:
RC3: Clock
RC4: Signal (SPI in)

With this connection, the following settings work:


(incidentally the same as in my libstock example)

Raspberry PI:
let mode = 'MODE_1';     // clock idle low, clock phase active to idle.

function initSPI(){

  var spiConfig = {
    'mode': SPI.MODE[mode],   
    'chipSelect': SPI.CS['none'], 
    'maxSpeed': 200000

  spi = new SPI.Spi(


lørdag 18. mars 2017

Vocoder analysis/synthesis boards arrived

I picked up the vocoder analysis/synthesis boards yesterday. They look good as always, though I noticed some differences. Nothing to be alarmed about but I get why they are a bit cheaper than other boards:

- The silk screen is a bit misplaced on some boards
- The holes aren't always dead center on the pads
- One of the boards isn't completely flat, i.e. the fibre glass is slightly bent.

These are just very tiny deviations and well within what is acceptable, they just aren't perfect.

I'm very excited to get started on the build, to see if I've managed to get the circuit and layout right :)

mandag 27. februar 2017

ETI Vocoder voltage to current converter

The VCAs in the  ETI vocoder use a voltage to current converter that is slightly different than what I'm used to. This post tries to understand what is going on. It may be wrong, so do not use the findings without verifying them first.

The transistor in the vocoder has its base tied to ground, collector connected to the control pin of the LM13600 and the emitter to the output of an opamp (and a trim pot) through a resistor.

Unlike other converters I've seen, it does not have the transistor inside the feedback loop of the op amp.

I suspect that the converter does not rely on the \(\beta\) or Hfe of the transistor, it only has to be high enough. I believe that what is important is the relationship between \(V_b\), \(V_e\) and the output voltage of the op amp.

I've chosen the VCA in the internal excitation circuit as my reference when analysing the circuit.

R34 is a 10k resistor, you can see these in most all designs using the LM13600 OTA. It's most likely there to protect the lm13600 from self destructing - the maximum control current of an LM13600 is 2mA. See my post on the Xonik VCA for an explanation of its value.

So how do we calculate the collector current (which is what controls the OTA, Iabc)?

Here is a page that explains how a transistor may be used as a constant current source:


It says that

\(I_{load} = \frac{\beta \cdot V_e}{(\beta + 1) \cdot R_e}\)

If \(\beta\), the transistor gain, is large, \(\frac{\beta}{\beta + 1}\) is approximately 1 (and thus \(I_{load} = I_c = I_e\)). Also, \(V_e\) is always one diode drop below \(V_b\) when the transistor is on (\(V_e = V_b - 0.6V\)), which means that the formula above may be simplified to

\(I_{load} = \frac{V_b - 0.6V}{Re}\)

In our case, \(I_c = I_{load}\) and \(R_e = R32\) (=22k).

What the page above fails to mention is that the bottom of \(R_e\) must be connected to ground, or at very least that \(V_e\) is the voltage across \(R_e\).

This final detail is of importance to us, because in our case the voltage at the op amp end of \(R_e\) (R32) is what varies, not the voltage at the base. The base is stuck at 0V/GND. Thus, the voltage across the resistor is not \(V_e\), it is \(V_{out} - V_e\), where \(V_{out}\) is the output voltage of the opamp (IC8b).

We also have to take into account that the vocoder uses a PNP transistor, not an NPN as in the constant current source above. while the emitter of an NPN transistor is 0.6V below the base, the emitter of a PNP transistor is 0.6V above the base. Thus, for a PNP transistor:

\(V_e = V_b + 0.6V\)

Now we can calculate the emitter current = current through \(R_e\), which will also be approximately the collector current if \(\beta\) is large:

\(I_e = \frac{V_{out} - V_e}{R_e} = \frac{V_{out} - V_b -0.6V}{R_e} = \frac{V_{out} - 0V -0.6V}{22k}\)
\(I_e = \frac{V_{out} - 0.6V}{22k}\)

What does this mean

Well, first of all, Ie is independent of the transistor \(\beta\), which means that we can replace the BC212L transistor with something else without having to look too hard for a perfect match.

Second, we can calculate the maximum current through the base. Knowing that

\(I_e = (\beta + 1) \cdot I_b\)

we get that

\(I_b = \frac{\frac{V_{out} - 0.6V}{22k}}{\beta + 1}\)

The vocoder uses a +/-12V power supply. Thus, the maximum output value of the opamp is +/-12V (in practice it will be a bit lower than this, and the vocoder may even be designed to use an even lower control voltage, but the absolute theoretical maximum is +/-12V).

The transistor only conducts if the emitter is more positive than the base. Thus, only \(V_{out}\) values > 0.6V will turn on the transistor. As the maximum \(V_{out}\) is 12V, the maximum \(I_b\) can be found as

\(I_e = \frac{12V - 0.6V}{22k} = \frac{11.4V}{22k} = 0.52mA\)

\(I_b = \frac{0.52mA}{\beta + 1}\)

Thus, when selecting the transistor to use, we need to make sure that it has a maximum \(I_b\) higher than this when entering its \(\beta\) in the formula above.

Also, we can see that \(I_e = I_c = 0.52mA\) is well within the 2mA maximum for the LM13600.


As for the trimmer potentiometer PR1 and its associated resistor R33, I assume they add a constant current that trims the 0-point of the VCA.

The potentiometer acts as a voltage divider, so the maximum current through R33 will be:


\(\frac{12V - 0.6V}{470k} = 0.024mA\)


\(\frac{-12V -0.6V}{470k} = -0.027mA\)

A final note

I suspect that the diode D5 in the op amp feedback loop is there for this reason:

When the opamp positive input is at 0V, the opamp output must be at 0.6V (one diode drop above to keep the negative output at 0V. This means that the opamp output always stays 0.6V above its positive input, which cancels out the -0.6V from \(V_e\) in the calculations above.

The voltage to current conversion formula will then be

\(I_e = \frac{V_{out} - 0.6V}{R_e}\)
\(I_e = \frac{V_{in} + 0.6V - 0.6V}{R_e}\)
\(I_e = \frac{V_{in}}{R_e}\)

where \(V_{in}\) is the input voltage at the positive opamp input terminal, i.e. the control voltage.

I tried breadboarding the circuit to confirm my suspicions.

R31, D5 and IC8b form what is called a simple precision rectifier, see this wikipedia post: https://en.wikipedia.org/wiki/Precision_rectifier. As we tap the output at the opamp output instead of at the negative input, we should see the 0.6V offset.

My measurements clearly showed that this is indeed true. The positive input and the output of IC8b follow each other closely, with a difference of 0.6V.

Input at the bottom, output on top. The difference is almost exactly 0.6V

Also, to confirm that this is indeed the precision rectifier from the wikipedia article, once the input goes below 0V, the output immediately drops to the negative rail - no surprises there. As the input is connected to the previous rectifier however, this doesn't really matter, the CV will never be negative.

The output saturates to the negative rail once the input is less than 0V

As for R31, removing it makes the circuit act like a normal buffer. Increasing the value from 3.9k to 12k has no effect at all. Replacing the diode with a wire also changes the circuit back to a buffer.

Some transistor rules:
The load should always be on the collector side
\(V_b = V_e + 0.6V\) for NPN
\(V_b = V_e -0.6V\) for PNP
The \(V_b\) to \(V_e\) relationship stays constant, the currents are what change.

If \(\beta\) is large, \(V_c = V_e\). Good designs do not rely on \(\beta\) as is varies widely.

torsdag 23. februar 2017

TL0x2 opamps - difference

- TL062 is the low power version of the TL082. 
- TL072 is the low noise version of the TL082. 

So: the TL062 uses less power, but is more noisy than the TL072.

From: http://www.freestompboxes.org/viewtopic.php?f=17&t=328

onsdag 22. februar 2017

ETI Vocoder article errors - internal excitation

There is a mismatch between the schematics and the parts list for the internal excitation module.

Schematics says C11 is 22nF, parts list says 220nF.

C11 forms a low pass filter together with R39. Together with the 100k resistor on each channel of the analysis card - the whole setup is called an inverting amplifier filter or active inverting op amp low pass filter.

According to wikipedia:


the cutoff frequency is 1 / 2 * pi * R*C

where R is the resistor in the feedback loop of the op amp.

For 22nF this is 1 /  6.28 * 47000 * 22 * 10^-9 = 154Hz
For 220nF it is 1 / 6.28 * 47000 * 220 * 10^-9 = 15.4Hz

In comparison, C12 and R40 gives:

1 / 6.28 * 10000 * 1 * 10^-6 = 1 / 0,01 = 15.9Hz.

The output from the analysis boards is the value of the envelope follower. If the volume of a frequency band is at its max continously, the envelope follower will be a DC voltage with a similar max value.

The two circuit parts sum up channels 1-9 (for the <2kHz input) and channel 13 and 14 (for the >4kHz input). For the sums to be comparable, the max sum of each parts must be the same.

R39 and R40 are selected to achieve this:
The gain of <2kHz is -10k/100k = -0.1
The gain of >4kHz is -47k/100k = -0.47

Multiplied by the number of channels on each input we get a 'maximum' sum for each input:
<2kHz: 9 channels * -0.1 = -0.9
>4kHz: 2 channels *-0.47 = 0.94

These are similar enough to be compared.

The low-pass filter is there to make sure the Vocoder only reacts to slow changes in envelope amplitudes. It is reasonable to assume that they should be roughly the same. The capacitor has been matched with the feedback resistor (R39, R40), which in turn was selected to give correct gain as described above.

The closest matching alternatives are then 15.4Hz and 15.9Hz. Thus, the correct value for C11 is 220nF.

tirsdag 21. februar 2017

Transistors in the ETI Vocoder

Many of the transistors in the ETI vocoder are either hard to find or very expensive (or both). I am trying to figure out if alternatives are available.

For the internal excitation board, two BC182L (NPN) and two BC212L (PNP) are used.

Q1 is definitely replaceable, probably with a 2N3904. It only acts as a logical inverter together with R20 and R21. It is similar to the one found here:


Not sure if we have to change the resistor values, but probably not.

Q2 is a voltage to current converter. I am not entirely sure how it is meant to work so I cannot say for sure right now what parameters to look for. The same converter circuit can be found in the analysis/synthesis section, so if one is solved, both are solved. I think looking at the exponential converter theory I've written earlier may solve some of it - the way it works is that the base is tied to ground while the emitter is connected to the output of IC8b which probably follows the envelope follower. D5 is similar to what I have in my Xonik VCA. R33 and PR1 probably adds a constant current to trim offness or similar.

Q3 and Q4 control two switches. Again, I believe they are considered binary - the output of the comparator is either high or low and the switches are also controlled by high or low voltages. We should definitely try 2N3904 and 2N2906 here.

Update: I've confirmed that Q2 is not depending on Hfe and may thus be replaced by a difference transistor (see my post on the ETI voltage to current converter). The BC557 has the same pin-out (CBE, PNP) and at least the 557B has a Hfe in the same region.

As for the BC182L, it seems that its pin out (ECB, NPN) is harder to find. However, the BC182 is still available from Farnell and RS Components (though not mouser). If the circuit board is redesigned, using a different transistor will be problem free.

BTW: Here is a nice comparison page for different transistors: http://www.edutek.ltd.uk/Transistors_NPN.html

As for the BF244 N-channel JFET, I have yet to find a replacement. It could possibly be replaced with a J112 (which also has interchangeable source and drain). I would have to look at the exact function of the transistor but I suspect that it is only used as a switch. The difference between J111/112/113 is the gate-source cutoff voltage, the zero-gate voltage drain current and the drain-source on resistance. The cutoff voltage for the BF244 varies widely, more than between the various J variants, as does the zero gate voltage drain between the versions (A,B,C) of the BF244. The vocoder article does not specify a particular version of the BF244 so this may not be very important either.

søndag 5. februar 2017

Linear interpolation

As I intend to use lookup tables for the DCO frequency and amplitude, I started looking for ways to do linear interpolation of the values in such a table to keep the number of entries low.

I may have mentioned it in a previous post, but I bought an early 80s digital sound creation book, and it has a thorough description of how to do this fast and efficiently. It is particulary space saving for symmetric waves such as sines but may be of some help even to me. Here is the text (for me to remember):

søndag 29. januar 2017


I've started working on a DCO circuit, as this will probably require fewer (but perhaps more expensive) parts and be easier to tune.

I want the DCO to work for all midi notes (C0-B8) and be within 1 to 3 cents of the correct frequency for all notes.

Looking at the Juno 6/60/106 and JX-3P DCOs I've so far set up a google docs spreadsheet, calculating all periods to get correct frequencies and the necessary voltages (currents) to get a constant amplitude.

A short intro to DCO theory

DCOs are (often) based around a relaxation oscillator, exactly like a saw core VCO (http://xonik.no/theory/vco/reference_current.html - this also explains how the capacitor is charged). A current charges a capacitor and a transistor short circuits and discharges it to restart the period.

DCOs are stable because they use a digital timer to control the discharging of a capacitor instead of relying on an accurate charging current - the period and thus frequency is computer controlled and highly accurate. For the saw ramp to reach the same amplitude as the charging period (time available to charge the capacitor during a cycle) changes, the DCO instead changes the charging current. As the frequency changes exponentially with rising notes, so must the charging current.

In my spreadsheet I have calculated two important aspects for a physical circuit - the accuracy of the timer generating the period/frequency and the accuracy of the charging current generation.


A microcontroller timer has two properties - the minimum period and the maximum count. These limits the length of an output period and the accuracy of its length. A 16bit timer can at most count to 65535 and has a maximum accuracy of +/- 0.5 times its minimum period. For example, if the timer frequency is 8MHz, each tick of the timer is 0.125uS and the accuracy is thus +/-0.0625uS. Its maximum output period length is 65536 * 0.125uS = 8192uS or 8.19mS. The consequency is that a 16 bit timer running at 8MHz has a minimum output frequency of 1/8192uS = 122Hz. (Here we assume that the timer restarts the period whenever it has counted to its maximum).

The accuracy limitation is most important to the upper end of the frequency range. The maximum needed frequency (B8 = 7902,13282Hz) has a period of 126,55uS. An inaccuracy of 0.0625 equals an error of about 0.05%. The human ear is able to hear a difference between two notes played after eachother of about 10 cents/0.6% if the notes are sine waves, less if they are complex tones. Thus, this inaccuracy is well within what is acceptable.

But what can we do to make the timer count long enough for deeper notes? We can either use a bigger timer (32bit) or more often, use a prescaler that divides the clock running the timer. If we use a prescaler of 2, the timer frequency changes from 8MHz to 4MHz, the minimum period changes from 0.125uS to 0.25uS and the maximum time from 8.19mS to 16.38mS. This makes the lowest possible frequency 61Hz. Changing the prescaler to 8 gives a minimum frequency of 15.25Hz, which is low enough for C0.

Unfortunately, increasing the prescaler also decreases the accuracy as the minimum period gets longer. I have set 3 cents as the maximum error acceptable at the highest frequency. Using a prescaler of 8 makes some of the notes at the top of the frequency range fall outside the target accuracy.

In short - using a 16bit timer, we cannot use a single prescaler value and achieve both the frequency range and the accuracy needed. To solve this, we need to change the prescaler somewhere towards the lower end of the frequency scale. To get a constant time used setting up the timer, i propose always setting the prescaler when reloading the timer.


DCOs use different ways of creating a control current. As mentioned previously, the necessary charging current changes exponentially as the notes change. The Juno 6/60 seems to use an exponential converter (I may be wrong about this though, I haven't studied it closely) to achieve this, but such a converter has the same temperature dependency problems as the one controlling the pitch in a VCO (but the effect in the DCO is on the amplitude, not the pitch, and will thus not be as noticeable).

The Juno 106 and JX-3P however just feed the output of a DAC through a resistor and into the integrator (saw ramp generator). This means that the DAC must generate a voltage that accurately approximates the exponential curve needed throughout the note range (the voltage is converted to a current through a resistor). This may be problematic as the rate of change is very small at one end then suddely very large at the other.

I've once again used the spreadsheet to calculate first the real the charging voltage needed, then the current created using a DAC of arbitrary resolution. By rounding off the needed current to the nearest value achievable with the DAC, then multiplying with the per-step voltage, then using the capacitor charging formula with the known period as t, we will find the real amplitude of the wave and thus the maximum error per note.

Using a 16bit DAC and charging a 1nF capacitor through a 100k resistor, we are able to charge the capacitor to within 0.02V (of a maximum of 5V), or 0.4% of the wanted amplitude for all notes.

When calculating the capacitor charging, I've assumed that we can follow the same formula as in my older VCO research, where I found that the voltage across the capacitor at a time t after the charging starts, V(t) = t * I/C. I is found by dividing the DAC voltage Vdac with the input resistor R. Rearranging for Vdac gives us Vdac = V(t) * C * R / t, and to calculate the resulting max charging voltage, V(t_max) = Vdac * t_max / C * R.

My calculations can be found here: https://docs.google.com/spreadsheets/d/1ROhU0L4UZ2CWLu3h5LHopaB0Jv7ewNRziecj5I6D27M/pub?gid=0&single=true&output=pdf

Further work:
- Figure out how to calculate timer values and dac settings (lookup tables?)
- How to interpolate efficiently between values in the lookup table to reduce its size while still allowing input pitch to be a 16 bit value
- How to do DCO sync
- Possibly: Changing timer/charge voltage in the middle of a cycle in order for the DCO to respond instantly (the Juno DCOs apparently only change pitch at the start of a cycle.

søndag 8. januar 2017

The ETI Vocoder

I can't remember if I've posted about this earlier, but for quite some time now I've planned on building the ETI Vocoder. I was approached by a guy who wanted me to help him etch the circuit boards, and we spent at least a year planning for this, touching up the original drawings and adding/moving connectors etc.

In the end though, after buying presensitized PCBs and doing a few test etchings, I decided not to do this at home anyway. I simply have too few time slots long enough to do the setup, etching and cleanup.

What I ended up doing instead was redoing the boards and send them off to be professionally produced. I have shrunk all the boards as much as possible (while still using through hole components). I've split the internal excitation board into two separate pcbs so that all pots are soldered to a board.

In addition, I've combined the LP/BP/HP versions of the voice board into a single circuit. This means that you have to add some solder bridges and that some parts are left out for some of the boards, so populating them is slightly harder. However, it also means that I was able to make dual channel boards that, when repeated 7 times, turns into the full voice board. Using a service like dirtyPCBs, 7 similar smaller cards are much cheaper than one large one.

In retrospect I've realized that I could possibly simplify the circuits a bit, since the left channel on a card will never be HP and the right never LP (or the other way around, I can't remember).

I've also managed to jam all the non voice boards (except one of the internal excitation parts) into two 10 x 10 cm pcbs, keeping the cost really low.