blob: feddda42ba58c0017c921b799fc9fbef73bc9062 [file] [log] [blame]
purpose: Compute a fixed-point sin table
\ See license at end of file
\ Calculate the sin function using fractional integer arithmetic
\ where the scale factor is 2^15. 1.0 is represented by 32767,
\ pi is 102943. The argument to isin ( index -- frac ) is a
\ sample index from 0 to fs/freq/4 .
d# 16000 value fs
0 value theta
0 value thetasq
d# 32767 constant one
d# 102943 constant pi
0 value freq
0 value fstep
0 value #cycle
0 value #cycle/2
0 value #cycle/4
: set-freq ( freq sample-rate -- )
to fs ( freq )
dup to freq ( freq )
pi * to fstep
fs freq / dup to #cycle
2/ dup to #cycle/2
2/ to #cycle/4
;
: u*/ ( u1 unum udenom -- u2 ) >r um* r> um/mod nip ;
: set-period ( cycle/4 -- )
dup to #cycle/4 ( cycle/4 )
2* dup to #cycle/2 ( cycle/2 )
2* dup to #cycle ( cycle )
fs over / to freq ( period )
pi fs rot u*/ to fstep ( )
;
\ Multiply two fractional numbers where the scale factor is 2^15
: times ( n1 n2 -- n3 ) d# 32767 u*/ ;
\ Computes (1 - (theta^2 / divisor) * last)
: sin-step ( last divisor -- next ) thetasq swap / times one min one swap - ;
[ifdef] notdef
\ Cos
\ 1 - t^2/(2) + t^4/(2..4) - t^6/2..6) + t^8/(2..8)
\ 1 - (t^2/(1*2)) * (1 - (t^2/(3*4)) * (1 - (t^2/(5*6)) * (1 - (t^2/(7*8))))
: icos ( index -- frac )
fstep fs 2/ u*/ to theta
theta dup times to thetasq
one d# 90 cos-step d# 56 cos-step d# 30 cos-step d# 12 cos-step 2 cos-step one min
;
[then]
\ Taylor series expansion of sin, calculated as
\ t - t^3/(2*3) + t^5/(2*3*4*5) - t^7/(2..7) + t^9/(2...9)
\ theta * (1 - (theta^2/(2*3)) * (1 - (theta^2/(4*5)) * (1 - (theta^2/(6*7)) * (1 - (theta^2/(8*9))))))
\ This is good for the first quadrant only, i.e. 0 <= index <= fs / freq / 4
: calc-sin ( index -- frac )
fstep fs 2/ u*/ to theta
theta dup times to thetasq
one d# 72 sin-step d# 42 sin-step d# 20 sin-step 6 sin-step theta times one min
;
: one-cycle ( adr -- )
#cycle/4 1+ 0 do ( adr )
i calc-sin
2dup swap i wa+ w! ( adr isin )
2dup swap #cycle/2 i - wa+ w! ( adr isin )
negate ( adr -isin )
2dup swap #cycle/2 i + wa+ w! ( adr -isin )
over #cycle i - wa+ w! ( adr )
loop ( adr )
drop
;
[ifdef] notdef
: reduce-to-quarter-cycle ( -- )
\ Move a cycle/4 to the left until negative, then fix
#cycle/4 - dup 0<= if #cycle/4 + (sin) exit then ( theta' ) \ Quadrant 1
#cycle/4 - dup 0<= if negate (sin) exit then ( theta' ) \ Quadrant 2
#cycle/4 - dup 0<= if #cycle/4 + (sin) negate exit then ( theta' ) \ Quadrant 3
#cycle/4 - negate (sin) negate \ Quadrant 4
;
[then]
\ For isin and icos we use a cosine table instead of a sine table.
\ Argument reduction is a bit easier for cos because it is an even function.
: one-cycle-cos ( adr -- )
#cycle/4 1+ 0 do ( adr )
i calc-sin ( adr isin )
2dup swap #cycle/4 i - wa+ w! ( adr isin ) \ Quadrant 1
2dup swap #cycle/4 3 * i + wa+ w! ( adr isin ) \ Quadrant 4
negate ( adr -isin )
2dup swap #cycle/4 i + wa+ w! ( adr -isin ) \ Quadrant 2
over #cycle/4 3 * i - wa+ w! ( adr ) \ Quadrant 3
loop ( adr )
drop
;
\ The scale factor for theta is such that h# 10000 is pi radians.
\ Binary 1 is therefore pi/2^16
0 value cos-table
: init-sincos ( -- )
cos-table if exit then
h# 20000 /w* alloc-mem to cos-table
1 h# 20000 set-freq
cos-table one-cycle-cos
;
: release-cos-table ( -- ) cos-table h# 20000 /w* free-mem 0 to cos-table ;
: icos ( theta -- cos )
abs ( theta' )
dup #cycle >= if #cycle mod then ( theta' )
cos-table swap wa+ <w@ ( cos )
;
: isin ( theta -- sin ) #cycle/4 - icos ;
\ d# 16000 to fs
\ d# 150 set-freq
\ here one-cycle
\ here #cycle 2* wdump
\ LICENSE_BEGIN
\ Copyright (c) 2006 FirmWorks
\
\ Permission is hereby granted, free of charge, to any person obtaining
\ a copy of this software and associated documentation files (the
\ "Software"), to deal in the Software without restriction, including
\ without limitation the rights to use, copy, modify, merge, publish,
\ distribute, sublicense, and/or sell copies of the Software, and to
\ permit persons to whom the Software is furnished to do so, subject to
\ the following conditions:
\
\ The above copyright notice and this permission notice shall be
\ included in all copies or substantial portions of the Software.
\
\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\
\ LICENSE_END