In the old days, when hardware did not (or very slowly) supported floating-point calculations, fixed-point numbers were used to represent floating-point numbers in form of integers. They have some advantages, like a constant precision. However, the downside is that their values are limited to a certain range, depending on said precision.

The library defines a type BKFInt20 and its unsigned variant BKFUInt20. This is a 32 bit fixed-point number which has its integer part in the upper 12 bits and the fractional part in the lower 20 bits. Its absolute integer value is 4095 for the unsigned version and 2047 for the signed one, respectively.

BKFInt20, BKFUInt20

+-------------------------------------------------------------------+
|                          32 bit integer                           |
+-------------------------+-----------------------------------------+
|  integer part 12 bits   |         fractional part 20 bits         |
|                         |                                         |
| I I I I I I I I I I I I | F F F F F F F F F F F F F F F F F F F F |
+-------------------------+-----------------------------------------+

Calculation Examples

The following expression is frequently used in the code examples:

BK_C_3 * BK_FINT20_UNIT

This means that BK_C_3 (which has the value 36) is multiplied by the fixed-point fractional part which is expressed by BK_FINT20_UNIT. The result is a integer that is shifted by 20 bits to the left, so its value is now in the upper 12 bits of the 32 bit integer.

MORE TODO

Volume and Frame Values

Volume and frame values (amplitudes) are also fixed-point numbers. They are expressed by the type BKFrame which is a 16 bit signed integer that has only a fractional part of 15 bits.

BKFrame

+-------------------------------------------------------------------+
|                          32 bit integer                           |
+-----------------------------------+-------------------------------+
|              unused               |    fractional part 15 bits    |
|                                   |                               |
| - - - - - - - - - - - - - - - - - | F F F F F F F F F F F F F F F |
+-----------------------------------+-------------------------------+

This allows to multiply two volume or amplitude values and shift the result by 15 bits to the right to get the multiplied value.

Anyway, volume values are expressed with the type BKInt to allow the multiplication of two volume values and shifted the result with BK_VOLUME_SHIFT to create the fractional value.

BKInt volume1 = 21900;
BKInt volume2 = 16500;

// = 11027
BKInt volume = (volume1 * volume2) >> BK_VOLUME_SHIFT;

MORE TODO

References