Value read from table is halved

Why does this happen? The output of table/read is divided by 2

(To get it back up to the scale I want I have to left-shift by 1)

That divide by (1<<21) inside the tb/disp/print f looks a bit suspicious. How does it behave with unipolar values? What values do you get with a disp/dial b?

this is direct into a disp/dial b

cheers

Ah! I see now what’s going on. The int8_t values -64 and 64 in the 8-bit table only amount for half of its full scale (table description says values go from -128 to 127).

The tricky part is that int8_t 64 indeed does not equal Q27 64.0

In other words, int8_t -128 corresponds to frac -64.0 (“axoloti units”), and 127 to 64.0. That’s just something we have to deal with.

The table read, write and alloc objects actually share some gain shifting information, so that when you use a low-bit table the values read out still make sense in axoloti units. If this makes any sense.

Personally, I never get these conversions right the first time when I edit objects. I usually hook up some disp/hex, disp/i or disp/dial objects just about everywhere then bit shift things until they start making sense. ¯_(ツ)_/¯

Ok that makes more sense now. Weirdly -128 gives -64, and 127 gives -63.5

Is that due to some rounding or truncation error between the scaling?

Sounds like you’re correct. 8-bit resolution can only describe 256 values.

If we scaled these values from -64.0 to reach 64.0 within 256 steps, we’d get really messed up and hardly useful fractions of numbers (red column). There would also be no common 0.0 point - int 0 would scale to something like Q27 0.25. A MIDI nightmare!

1 Like

Thanks, I appreciate your taking time to explain/illustrate this :slight_smile: I found that either <<1 or math/round solved the problem.

<<1 slightly more efficient?

Aside - I find working with the Axoloti/Ksoloti boards quite educational! Working closer to the metal

1 Like

Yes, << and >> are slightly more efficient, though it might just be that modern compilers can recognize code where a bit shift would work and optimize it in.

As to how much more efficient, probably not much, unless very fast loops are being run (looking at you, virtual analog filters).

In general, * x or even / x are okay if the code becomes easier to understand that way.

Agree about the educational aspect of Axoloti - it was always a strong candidate! It’s amazing that you can just patch up an object and write some garbage inside without having to deal with all the pitfalls of writing and flashing a working firmware.