[sdiy] Saw DCO revisited

Fredrik Carlqvist ifrc at iar.se
Wed Dec 8 11:16:28 CET 2004


 

Hello All!

 

I have developed my saw DCO since last time, I will now describe the design
in more detail. 

Those of you who still remember the last report can skip to [NEW].

 

First, the DCO uses the CCP1 and TMR1 of a PIC18. The special event trigger
in the CCP (capture-compare) module clears the TMR1 registers and sets the
interrupt flag when the timer TMR1 reaches a value written into the CCP1
control registers. Effectively, you write a cycle length into the CCP1 and
then get interrupts with high precision (1-cycle or 100ns glitches). The
interrupt handler (ISR) toggles a bit for a square/pulse wave or resets a
ramp generator for a saw wave. If you want different pulse widths, just use
two different periods. 

 

The ramp generator itself has not changed, it looks like this:
http://www.minod.com/saw_generator.gif

 

The PIC18 derivative I use (PIC18F2320) has a built in comparator which also
triggers an interrupt to reset the ramp. Thus, by increasing the ramp slope,
I get hard synch sounds, since the ramp is reset both at the timer (pitch)
rate and when it reaches the maximum. 

 

The only trouble is to set the correct control voltage to get the right
current for charging the ramp capacitor. The CA3080 control input is just a
transistor base, and the voltage to current conversion is exponential. The
control voltage is thus A) highly temperature dependant as we all know, and
B) depends on the reference voltage to the DAC, the power supply in this
case, and C) also on component tolerances. 

 

[NEW]

Last night I implemented an auto-calibration procedure that makes me kind of
proud: Using the timer and comparator interrupts in the bisection method, a
high precision calibration is possible. (Those of you who know the bisection
method can skip the next paragraph)

 

It works like this: Initially, the "possible" range is [0,65535] (16-bit
DAC), and the initial guess is the mid point x in that interval, that is
32767 (or 2.500 volts if you wish). Now, the ramp and timer are started
simultaneously, and which interrupt comes first determines the next test
value. If the timer is first, the ramp is too slow, and the lower interval
bound is updated to the test point, otherwise, the high side is updated. So
the possible next intervals are [32767,65535] or [0,32767]. The next guess
is computed as the midpoint in the interval and the sequence is repeated
until x doesn't move. 

 

I get very high precision with this method. Calibration points are taken
once every octave, and then they are interpolated with a second degree
polynomial. The whole calibration procedure (9 points) takes just over a
second. The resulting saw amplitude is perfectly constant over the 20Hz to
5kHz range. It is adjusted for the current temperature, supply voltage and
component tolerances. 

 

The code necessary for the calibration routine was about 150 instructions of
which 60 was freed up initialization data, so it wasn't too expensive. 

 

BTW, I also tested synthetic jitter to simulate vintage machines. It sounded
like sh*t. At large amounts it was a bit cool, like DX7-ish, but the idea I
had about 'subliminal jitter' making the tone 'warm' and 'analog' or even
'natural' did not work. It sounds like a beginner at the fiddle. IF you know
what I mean. 

 

 

Fredrik C

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://synth-diy.org/pipermail/synth-diy/attachments/20041208/caff28ff/attachment.htm>


More information about the Synth-diy mailing list