Copyright © 2024 Bart Massey (Version 0.1.0)
This Rust no_std
library crate provides a function for
converting a MIDI key number into a timer period. The
function uses only 32-bit integer arithmetic, making it
suitable for embedded applications.
The code currently relies on a table built by its
build.rs
build script. This will change when const
floating-point arithmetic is stabilized: expected in
Rust 1.81.0. In the mean time the build script does
floating-point arithmetic, which is fine for
cross-compilation but may not work in weird self-hosted
embedded environments.
Here's the derivation used in the code. We are given a MIDI
key number
Given real arithmetic, the desired integer timer period
where
To make this work as an integer operation, we will do the rounding earlier and then do a rounded integer division. Note that the integer division rounds a division whose numerator and denominator have already been rounded: this "double rounding" is a source of error that is not easily avoidable, and will not affect the result too much given appropriate choices.
Let's start by scaling the numerator and denominator by some
scaling factor
The numerator is already an integer, but the denominator is not. We will use an identity to fix things up:
We can use this identity to do some algebra and rearrangement of terms.
The parenthesized term can now be extracted into a function that rounds its result to an integer.
Since the input of
where all the runtime computation is integer except the rounded division at the end. To round, we use the identity
with the numerators and denominators above.
The choice of
This work is licensed under the "MIT License". Please see the file
LICENSE.txt
in this distribution for license terms.