New build (abb6360) posted here.

Hm, I did a brief test in poly mode just applying a large pitch offset and it works, I don’t really understand how this is happening unless I uploaded the wrong build or something. In which case my apologies! The midi code should now be doing all pitch assignments through the function other apps use for setting note values – the only exceptions to this are the velocity / pressure / CC outputs in some modes.

Good catch!

I like this idea, implemented. Note that you can also use the panic grid key on the tuning page (5th from the right on the 3rd from the bottom row) to reload your previously saved tuning, or long-press it to reset to the factory default tuning table.

What grid edition are you using? The bottom two rows take advantage of the 16 brightness steps of current-edition grids, selected brightness levels may need some tweaking for usability on 4-step grids. Pressing the rightmost key on the bottom row seven times results in both the leftmost key on the bottom row and the leftmost key on the 2nd-from-bottom row being fully lit, I expect this to also be the result on a 4-step grid.

2 Likes

Thank you!

I tried that as well, and yes, large pitch changes (= setting one waypoint ridiculously high and let Ansible do the interpolation) transfer well to POLY mode. But unfortunately, the fine pitch adjustments I made on the TUNING page to correct the DAC offsets are still not working in POLY. I made 2 videos to illustrate. In TUNING mode, I tuned every waypoint of every voice as precise as possible. This is how each of the four voices (starting with voice 1) sounds when using this tuning table in KRIA:

This is great, pitches deviate 2 cents mex. Now, this is how the same notes sound when played in POLY:

Not good, pitch deviates somewhat like 15 to 18 cents.

So it looks like large pitch adjustments are carried over from KRIA to POLY, but subtle ones somewhat get lost. Unfortunately, these subtle changes are essential for POLY usage.


Thanks much for implementing the change to KEY1 behavior, works great!

16 level brightness from end of 2015. Here’s how it looks:

1 Like

Yeah this is interesting. I think what’s going on here is probably that the same tuning table is being used, but the midi mode pitch calculation is not quite the same. In particular there is an additional pitch shift applied when assigning midi pitches, this spot in the code notes that there is a -2 octave shift. With the way the CV output code is structured this is effectively being applied as a pitch bend, ignoring the tuning table for those 2 octaves.

The note on this says this value (-3277) is chosen because this is N -24 on Teletype. This is true, but it does not match up with the pitch table being used – it turns out the Teletype N op uses another slightly different note -> DAC ticks lookup table.

Of the three tuning tables Teletype’s seems the most correct to me.

Comparison using a Python shell
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul  8 2019, 19:29:22) [MSC v.1916 32 bit
(Intel)] on win32

# ansible ET method
# different slope from the others and discards 2 bits of precision
>>> [round(i * 4092 / 120) << 2 for i in range(121)]
[0, 136, 272, 408, 544, 680, 820, 956, 1092, 1228, 1364, 1500, 1636,
...
14732, 14868, 15004, 15140, 15276, 15412, 15548, 15688, 15824, 15960, 16096, 16232, 16368]

# ansible midi SEMI14 method
# uses integer truncation rather than rounding
>>> [int(i * 16384 / 120) for i in range(121)]
[0, 136, 273, 409, 546, 682, 819, 955, 1092, 1228, 1365, 1501, 1638, 
 ...
14745, 14882, 15018, 15155, 15291, 15428, 15564, 15701, 15837, 15974, 16110, 16247, 16384]

# teletype N op method
# rounds and keeps full precision
>>> [round(i * 16384 / 120) for i in range(121)]
[0, 137, 273, 410, 546, 683, 819, 956, 1092, 1229, 1365, 1502, 1638, 
 ...
14746, 14882, 15019, 15155, 15292, 15428, 15565, 15701, 15838, 15974, 16111, 16247, 16384]

The DAC hardware and control code should all be the same, so I think we should just move the table Teletype defines into libavr32 and use it for all the pitch calculations on Ansible as well as the Teletype note table. Looking at the DAC’s datasheet I think 16384 / 120 = 136.5333… ticks per semitone is the correct value rather than 4092 * 4 / 120 = 136.4 ticks per semitone, but there could be a consideration I’m overlooking, like something that’s different about Ansible’s design.


Do you have a Teletype or Crow connected to Ansible? As a short-term way to address the tuning issues while this is getting sorted out on the code side I believe you can use MIDI.SHIFT or a crow equivalent (does not look like this is wired up in the crow firmware yet but this is easy to add) to reprogram this -2 octave shift, then save it to flash on Ansible. You may have to experiment with this value, 15+ cents seems like a lot for this discrepancy to completely account for it but it’s at least part of the problem.

3 Likes

Thanks for explaining what is happening there, although I have to admit that I don’t quite understand it. Or in other words: My understanding of what you wrote is that there is -2 octave shift between POLY and KRIA, which is in contrast to my observations:
(a) The pitch range that’s covered is the same in POLY as it is in KRIA, so there is no 2 octave pitch shift between POLY and KRIA.
(b) The pitch deviations between the four voices happen in every octave of the whole pitch range of POLY, so they are not limited to a specific 2 octave range.
Don’t know if this helps…in any case, I am thankful for you looking into this.

P.S. One last thing: When using the bottom row of the TUNING page in Kria, I noticed that sometimes I was not able to get the tuning of a specific note completely on spot, as it was either 1 or 2 cents too high or too low. Don’t know if it is at all relevant in this context, it certainly doesn’t bother me.

I think it’s more like this: specifying a midi note results in some corresponding output voltage being calculated based on the midi note number. The pitch calculation then subtracts 2V from the calculated voltage to get the CV output into a more usable range – this results in the pitch range being basically the same as for Kria / Earthsea / etc. But the constant value the code is using to represent this shift is not actually the right offset because of the slightly different tuning tables, so it doesn’t exactly cancel out the note-based shift, resulting in (or at least contributing to) the discrepancy you measured between Kria and midi output voltages.

This is an inevitable result of quantization error and non-ideal DAC characteristics, the DACs can only output a finite set of voltages and some of those are closer approximations to the perfect pitch value than others.

2 Likes