trigint - An Integer-based Trigonometry Library
Back when I was writing the A440 sample code for my iPad Dev Camp presentation, I needed to generate a 440 Hz sine wave. The simplest way to do this is to use the sin() or sinf() standard C library functions. But there was one minor caveat: these functions required using floating point data types. However, floating point on the iPhone hardware is (or at least was) not that fast compared to integer calculations, especially when compiled in Thumb mode, which is the default. You could disable Thumb mode, but then the code size would be ~35% larger.
Or, you could avoid floating point altogether. Thus, I wrote trigint, a 100% integer-based trigonometry library. It uses a 16-entry lookup table plus linear interpolation so it’s quite memory efficient, yet still accurate enough for most purposes. Since it’s written in ANSI C99, it can be used on 8-bit microcontrollers, like an Atmel AVR with avr-gcc. Here’s the code and the API documentation.
How fast is it? Take a look at the numbers on a 1st generation iPod Touch. In summary, trigint_sin16()
is about 4.4 times faster than sinf()
and 6.7 times faster than sin()
in Thumb mode. Without Thumb mode, the gap closes a bit to 3.8 times faster and 6.2 times faster, respectively. I haven’t, yet run the benchmark on the iPhone 4 or the iPad, so it may not matter as much on the more modern hardware; however, it’s still useful for the the 8-bit MCUs like the AVR, though.
trigint is essentially a C version of the Scott Dattalo’s sine wave routine for the PIC microcontroller. Credit goes to Scott for coming up with the algorithm. He’s also got a whole write up of sine wave theory. Scott is one of the most brilliant assembly coders I’ve ever run into. He helped me optimize a CRC-16 routine in PIC assembly, years ago.