Skip to content

Instantly share code, notes, and snippets.

@44100hertz
Last active January 26, 2017 17:21
Show Gist options
  • Save 44100hertz/ea9dc356ed22adf4642eacb1d6659d3a to your computer and use it in GitHub Desktop.
Save 44100hertz/ea9dc356ed22adf4642eacb1d6659d3a to your computer and use it in GitHub Desktop.
16-bit ultrafast approximate sine via lookup table
package fastSine
import "math"
// Generate any sort of 16-bit lookup table.
// fn expected to take in range 0.0-1.0, output full-range int16
func makeLUT(fn func(float64) int16, size int) []int16 {
lut := make([]int16, size)
for i := 0; i < size; i++ {
lut[i] = fn(float64(i) / float64(size))
}
return lut
}
// Closure to get a full sine wave function using a LUT.
// Size is LUT size; will return a range 4 times that.
func FastSine(size int) func(uint16) int16 {
sineLUT := func(off float64) int16 {
// Set range to 1/4 sine wave
off = off * math.Pi / 2.0
// Convert to 16-bit range
return int16(math.Sin(off) * float64(0x7fff))
}
lut := makeLUT(sineLUT, size)
return func (off uint16) int16 {
qsine := uint16(len(lut))
switch off / qsine {
case 0:
return lut[off]
case 1:
return lut[qsine * 2 - off]
case 2:
return -lut[off - qsine * 2]
case 3:
return -lut[qsine * 4 - off]
}
return 0 // Probably unreachable; satisfies compiler
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment