1 /*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.cs.princeton.edu/
7 http://soundlab.cs.princeton.edu/
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
26 // file: ulib_math.cpp
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
32 //-----------------------------------------------------------------------------
33 #include "ulib_math.h"
34 #include "util_math.h"
37 static double g_pi
= 3.14159265358979323846;
38 static double g_twopi
= 2.0 * 3.14159265358979323846;
39 static double g_e
= ::exp( 1.0 );
43 DLL_QUERY
libmath_query( Chuck_DL_Query
* QUERY
)
46 QUERY
->set_name( QUERY
, "math" );
49 math.sin( math.pi /2.0 ) => stdout;
53 //! see \example math.ck
54 QUERY
->add_export( QUERY
, "float", "sin", sin_impl
, TRUE
);
55 QUERY
->add_param( QUERY
, "float", "x" );
58 QUERY
->add_export( QUERY
, "float", "cos", cos_impl
, TRUE
);
59 QUERY
->add_param( QUERY
, "float", "x" );
62 QUERY
->add_export( QUERY
, "float", "tan", tan_impl
, TRUE
);
63 QUERY
->add_param( QUERY
, "float", "x" );
66 QUERY
->add_export( QUERY
, "float", "asin", asin_impl
, TRUE
);
67 QUERY
->add_param( QUERY
, "float", "x" );
70 QUERY
->add_export( QUERY
, "float", "acos", acos_impl
, TRUE
);
71 QUERY
->add_param( QUERY
, "float", "x" );
74 QUERY
->add_export( QUERY
, "float", "atan", atan_impl
, TRUE
);
75 QUERY
->add_param( QUERY
, "float", "x" );
78 QUERY
->add_export( QUERY
, "float", "atan2", atan2_impl
, TRUE
);
79 QUERY
->add_param( QUERY
, "float", "x" );
82 QUERY
->add_export( QUERY
, "float", "sinh", sinh_impl
, TRUE
);
83 QUERY
->add_param( QUERY
, "float", "x" );
86 QUERY
->add_export( QUERY
, "float", "cosh", cosh_impl
, TRUE
);
87 QUERY
->add_param( QUERY
, "float", "x" );
90 QUERY
->add_export( QUERY
, "float", "tanh", tanh_impl
, TRUE
);
91 QUERY
->add_param( QUERY
, "float", "x" );
94 QUERY
->add_export( QUERY
, "float", "hypot", hypot_impl
, TRUE
);
95 QUERY
->add_param( QUERY
, "float", "x" );
96 QUERY
->add_param( QUERY
, "float", "y" );
99 QUERY
->add_export( QUERY
, "float", "pow", pow_impl
, TRUE
);
100 QUERY
->add_param( QUERY
, "float", "x" );
101 QUERY
->add_param( QUERY
, "float", "y" );
104 QUERY
->add_export( QUERY
, "float", "sqrt", sqrt_impl
, TRUE
);
105 QUERY
->add_param( QUERY
, "float", "x" );
108 QUERY
->add_export( QUERY
, "float", "exp", exp_impl
, TRUE
);
109 QUERY
->add_param( QUERY
, "float", "x" );
112 QUERY
->add_export( QUERY
, "float", "log", log_impl
, TRUE
);
113 QUERY
->add_param( QUERY
, "float", "x" );
116 QUERY
->add_export( QUERY
, "float", "log2", log2_impl
, TRUE
);
117 QUERY
->add_param( QUERY
, "float", "x" );
120 QUERY
->add_export( QUERY
, "float", "log10", log10_impl
, TRUE
);
121 QUERY
->add_param( QUERY
, "float", "x" );
124 QUERY
->add_export( QUERY
, "float", "floor", floor_impl
, TRUE
);
125 QUERY
->add_param( QUERY
, "float", "x" );
128 QUERY
->add_export( QUERY
, "float", "ceil", ceil_impl
, TRUE
);
129 QUERY
->add_param( QUERY
, "float", "x" );
132 QUERY
->add_export( QUERY
, "float", "round", round_impl
, TRUE
);
133 QUERY
->add_param( QUERY
, "float", "x" );
136 QUERY
->add_export( QUERY
, "float", "trunc", trunc_impl
, TRUE
);
137 QUERY
->add_param( QUERY
, "float", "x" );
140 QUERY
->add_export( QUERY
, "float", "fmod", fmod_impl
, TRUE
);
141 QUERY
->add_param( QUERY
, "float", "x" );
142 QUERY
->add_param( QUERY
, "float", "y" );
145 QUERY
->add_export( QUERY
, "float", "remainder", remainder_impl
, TRUE
);
146 QUERY
->add_param( QUERY
, "float", "x" );
147 QUERY
->add_param( QUERY
, "float", "y" );
150 QUERY
->add_export( QUERY
, "float", "min", min_impl
, TRUE
);
151 QUERY
->add_param( QUERY
, "float", "x" );
152 QUERY
->add_param( QUERY
, "float", "y" );
155 //! see \example powerup.ck
156 QUERY
->add_export( QUERY
, "float", "max", max_impl
, TRUE
);
157 QUERY
->add_param( QUERY
, "float", "x" );
158 QUERY
->add_param( QUERY
, "float", "y" );
161 QUERY
->add_export( QUERY
, "int", "nextpow2", nextpow2_impl
, TRUE
);
162 QUERY
->add_param( QUERY
, "int", "n" );
165 //! see \example math.ck
166 QUERY
->add_export( QUERY
, "float", "pi", (f_ck_func
)&g_pi
, FALSE
);
169 QUERY
->add_export( QUERY
, "float", "twopi", (f_ck_func
)&g_twopi
, FALSE
);
172 QUERY
->add_export( QUERY
, "float", "e", (f_ck_func
)&g_e
, FALSE
);
178 CK_DLL_FUNC( sin_impl
)
180 RETURN
->v_float
= ::sin( GET_CK_FLOAT(ARGS
) );
184 CK_DLL_FUNC( cos_impl
)
186 RETURN
->v_float
= ::cos( GET_CK_FLOAT(ARGS
) );
190 CK_DLL_FUNC( tan_impl
)
192 RETURN
->v_float
= ::tan( GET_CK_FLOAT(ARGS
) );
196 CK_DLL_FUNC( asin_impl
)
198 RETURN
->v_float
= ::asin( GET_CK_FLOAT(ARGS
) );
202 CK_DLL_FUNC( acos_impl
)
204 RETURN
->v_float
= ::acos( GET_CK_FLOAT(ARGS
) );
208 CK_DLL_FUNC( atan_impl
)
210 RETURN
->v_float
= ::atan( GET_CK_FLOAT(ARGS
) );
214 CK_DLL_FUNC( atan2_impl
)
216 t_CKFLOAT x
= GET_CK_FLOAT(ARGS
);
217 t_CKFLOAT y
= *((t_CKFLOAT
*)ARGS
+ 1 );
218 RETURN
->v_float
= ::atan2( x
, y
);
222 CK_DLL_FUNC( sinh_impl
)
224 RETURN
->v_float
= ::sinh( GET_CK_FLOAT(ARGS
) );
228 CK_DLL_FUNC( cosh_impl
)
230 RETURN
->v_float
= ::cosh( GET_CK_FLOAT(ARGS
) );
234 CK_DLL_FUNC( tanh_impl
)
236 RETURN
->v_float
= ::tanh( GET_CK_FLOAT(ARGS
) );
240 CK_DLL_FUNC( hypot_impl
)
242 t_CKFLOAT x
= GET_CK_FLOAT(ARGS
);
243 t_CKFLOAT y
= *((t_CKFLOAT
*)ARGS
+ 1);
244 RETURN
->v_float
= ::hypot( x
, y
);
248 CK_DLL_FUNC( pow_impl
)
250 t_CKFLOAT x
= GET_CK_FLOAT(ARGS
);
251 t_CKFLOAT y
= *((t_CKFLOAT
*)ARGS
+ 1);
252 RETURN
->v_float
= ::pow( x
, y
);
256 CK_DLL_FUNC( sqrt_impl
)
258 RETURN
->v_float
= ::sqrt( GET_CK_FLOAT(ARGS
) );
262 CK_DLL_FUNC( exp_impl
)
264 RETURN
->v_float
= ::exp( GET_CK_FLOAT(ARGS
) );
268 CK_DLL_FUNC( log_impl
)
270 RETURN
->v_float
= ::log( GET_CK_FLOAT(ARGS
) );
274 CK_DLL_FUNC( log2_impl
)
276 RETURN
->v_float
= ::log( GET_CK_FLOAT(ARGS
) )/::log( 2.0 );
280 CK_DLL_FUNC( log10_impl
)
282 RETURN
->v_float
= ::log10( GET_CK_FLOAT(ARGS
) );
286 CK_DLL_FUNC( floor_impl
)
288 RETURN
->v_float
= ::floor( GET_CK_FLOAT(ARGS
) );
292 CK_DLL_FUNC( ceil_impl
)
294 RETURN
->v_float
= ::ceil( GET_CK_FLOAT(ARGS
) );
298 CK_DLL_FUNC( round_impl
)
300 RETURN
->v_float
= round( GET_CK_FLOAT(ARGS
) );
304 CK_DLL_FUNC( trunc_impl
)
306 RETURN
->v_float
= trunc( GET_CK_FLOAT(ARGS
) );
310 CK_DLL_FUNC( fmod_impl
)
312 t_CKFLOAT x
= GET_CK_FLOAT(ARGS
);
313 t_CKFLOAT y
= *((t_CKFLOAT
*)ARGS
+ 1);
314 RETURN
->v_float
= fmod( x
, y
);
318 CK_DLL_FUNC( remainder_impl
)
320 t_CKFLOAT x
= GET_CK_FLOAT(ARGS
);
321 t_CKFLOAT y
= *((t_CKFLOAT
*)ARGS
+ 1);
322 RETURN
->v_float
= remainder( x
, y
);
326 CK_DLL_FUNC( min_impl
)
328 t_CKFLOAT x
= GET_CK_FLOAT(ARGS
);
329 t_CKFLOAT y
= *((t_CKFLOAT
*)ARGS
+ 1);
330 RETURN
->v_float
= x
< y
? x
: y
;
334 CK_DLL_FUNC( max_impl
)
336 t_CKFLOAT x
= GET_CK_FLOAT(ARGS
);
337 t_CKFLOAT y
= *((t_CKFLOAT
*)ARGS
+ 1);
338 RETURN
->v_float
= x
> y
? x
: y
;
341 // nextpow2 - thanks to Niklas Werner, via music-dsp
342 CK_DLL_FUNC( nextpow2_impl
)
344 t_CKINT x
= GET_CK_INT(ARGS
);
346 for( ; x
&= x
-1; xx
= x
);
347 RETURN
->v_int
= xx
* 2;