Last active
January 26, 2017 17:21
-
-
Save 44100hertz/ea9dc356ed22adf4642eacb1d6659d3a to your computer and use it in GitHub Desktop.
16-bit ultrafast approximate sine via lookup table
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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