Skip to content

Instantly share code, notes, and snippets.

@going-digital
Last active June 2, 2021 12:15
Show Gist options
  • Save going-digital/798f8483d83a12dec67dced5741b06c2 to your computer and use it in GitHub Desktop.
Save going-digital/798f8483d83a12dec67dced5741b06c2 to your computer and use it in GitHub Desktop.
sin(tau x) in WebAssembly
(module
;; Calculate sin(tau x) natively in WebAssembly.
;; Compiles to 57 bytes of WebAssembly code
;; Uses angle units of 0 to 1 for a circle (useful for synths). Pre-divide by 2*pi to use radians.
;; Using Bhaskara I's approximation
;; https://en.wikipedia.org/wiki/Bhaskara_I%27s_sine_approximation_formula
;; Accurate to about 0.2%
(export "sintau" (func $sintau))
(func $sintau (param $x f32) (result f32)
(local $s f32)
;; Normalise to unit circle back into $x, and sign of result in $s
(set_local $s
(f32.sub
(f32.const 0.5)
(tee_local $x
(f32.sub (get_local $x) (f32.floor (get_local $x)))
)
)
)
;; Bhaskara I formula
(f32.mul
(f32.sub
(f32.const 0.5)
(tee_local $x
;; Drop to first 180 degrees of circle, ignoring sign
(f32.min
(get_local $x)
(f32.sub
(f32.convert_u/i32 (i32.const 1))
(get_local $x)
)
)
)
)
(get_local $x)
)
(f32.div
(f32.mul (tee_local $x) (f32.convert_u/i32 (i32.const 4)))
(f32.sub (f32.const 0.3125) (get_local $x))
)
;; Reapply sign of result
(f32.copysign (get_local $s))
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment