Bug found in daisy-examples/patch/Sequencer

Hey folks,

I believe I’ve found a bug in The Daisy Patch sequencer example . After using the sequencer to sequence a sound source module (Plaits), something didn’t sound quite right to me. I ran the output into a tuner (Mordax Data) and found that, for sequencer values of 0, the output was about a half a semitone sharp. I’ve tested this with multiple sound source modules to ensure that the issue is with Daisy.

Sequencer uses the following code to compute DAC output: (source)

                              round((values[stepNumber] / 12.f) * 819.2f));

Where values[stepNumber] is a semitone value 0-60

I have no previous experience with hardware or DACs so I don’t know what to make of this conversion. I did figure out where the magic number 819.2f comes from: (According to this comment), 0=0v and 4095=5v. Since 4095/5=819, there are 819 (dac units?) per volt or octave.

Unfortunately, I can’t figure out what’s actually wrong with it. Does anybody know how to fix it so that semitone values of 0 are not out of tune? I’ve found that adding an offset of ~25 to non-zero DAC output values sort of does the trick, but it seems like a hacky solution.

For reference, here’s what that conversion does to 0-12:

float prev = 0;
for (int i = 0; i <13; i++){
    float x = round((i / 12.f) * 819.f);
    cout<<to_string(i) + " -> " + to_string(x) + ", Delta: " + to_string(x-prev) + "\n";
    prev = x;
0 -> 0.000000, Delta: 0.000000
1 -> 68.000000, Delta: 68.000000
2 -> 137.000000, Delta: 69.000000
3 -> 205.000000, Delta: 68.000000
4 -> 273.000000, Delta: 68.000000
5 -> 341.000000, Delta: 68.000000
6 -> 410.000000, Delta: 69.000000
7 -> 478.000000, Delta: 68.000000
8 -> 546.000000, Delta: 68.000000
9 -> 614.000000, Delta: 68.000000
10 -> 683.000000, Delta: 69.000000
11 -> 751.000000, Delta: 68.000000
12 -> 819.000000, Delta: 68.000000

Note that the deltas are more or less the same, including the delta from 0 to 1. This makes the issue all the more confusing since, on paper, the note at 0 doesn’t appear to be out of tune.

It looks like the problem might be not software, but hardware. Or more like a combination of both. I would guess that there’s some DC offset present in output and you can’t go exactly to 0 as conversion function expects. To accurately generate voltage you would have to measure and include that offset into calculation for setting DAC values. Exact value could vary by device (and maybe even power supply used) and then using it would require a calibration procedure.

Naturally, octave width is also slightly off since we have less than 5V covered by DAC output range. Current value (819.2) assumes value of 4196 to be used for 5V - and you can’t actually set more than 4195 with 12 bit DAC.

1 Like

Ah, I see. If this offset varies per unit, does mean the Daisy Patch can’t be used for precice (or, at least, sufficiently price for playing accurate musical notes) CV sequencing? Or is there some sort of way to reliably and automatically compensate for offset?

I’m worried that if I wanted to create a sequencer program and distribute it to other users, it wouldn’t work if their Patch units had different offsets.

I happen to have 2 Daisy Patches, I’ll run some tests and see if the offset value is the same for both.

Would be interesting to know how far you can go with calibration.

I think that calibrating on one device could give you better results on another device compared to current sequencer code, even if won’t be as good as calibrating directly on that device. Ideally you would have a calibration mode in your patch, but that can be challenging to make from scratch (it would require entering data from multimeter measurements).

As an alternative, you might be able to calibrate ADC input with external voltage source and use it to calibrate DAC output. Then DMM is not required. I’ve used that for DC coupled codecs, I think that it might work with internal ADC/DAC too.

1 Like

I went ahead and tested it with my other Patch and it had the same behavior. I don’t have a multimeter but both units sounded in tune when I implemented the hacky fix (adding 25 to nonzero output values).