[sdiy] Detuning in Digital

Richie Burnett rburnett at richieburnett.co.uk
Mon Apr 2 12:23:37 CEST 2012


Hi all,

My MIDI to frequency method is almost identical to Olivier's, except that I only
store 13 values in the ROM look-up table.  These are the magic numbers to make
the oscillator play one complete octave from C to the C above.  I then use
linear interpolation for detuning between the semitone values.

Although the pitch to frequency curve is strictly exponential, a linear
approximation is accurate to better than 1 cent if only applied over the small
range between semitones.  Linear interpolation actually has a maximum error of
0.7 cents sharp that happens mid-way between two notes one semitone apart.  (It
is questionable whether this pitch error would be audible, particularly at low
frequencies.  And in addition to this, notes do not normally linger mid-way
between semitones unless to sound deliberately out of tune anyway.)

I then use binary right shifts to divide this frequency value down as required
to implement the lower octaves.  This part is exactly the same as Olivier
described.

The only thing I would add, is that I left align all of the frequency values in
the lookup table by left shifting them all as far as possible before storing
them.  This maximises the numerical precision.  In other words if my ROM is
16-bits wide, I make sure the 13 frequency values for the octave make best use
of the 16-bits resolution available in the LUT.  This gives about 1 part in
32768 frequency accuracy for the in-tune notes.

You can also easily support different tuning schemes by loading in alternative
LUTs of 13 frequency values for one octave of notes.

-Richie,

> In all my projects I represent pitch internally as a 14-bits number.
>
> 7 highest bits = MIDI note.
> 7 lowest notes = fine pitch (this means fine pitch is not adjustable
> in cents but rather in 128th, but I don't think it's an issue).
>
> I use a 12x128 entries full lookup table with whatever pitch-dependent
> quantity I am manipulating (eg: timer count for DCOs ; phase increment
> for digital oscillators) ; for only one octave. I use shifts to deduce
> the value for the other octaves.
>
> So the whole algorithm is, given a 14-bits pitch value:
> 1/ transpose it (add 12 x 128 or sub 12 x 128) until it falls in the
> range covered by the lookup table and count the number of octaves it
> has been shifted by (it's a loop with at most 10 iterations, no
> division / modulo).
> 2/ lookup the pitch value in the table.
> 3/ shift by the number of octaves found at step 1.





More information about the Synth-diy mailing list