Max 5 API Reference
00001 /* 00002 * Copyright 2001-2005 - Cycling '74 00003 * Derek Gerstmann - derek@cycling74.com 00004 * 00005 * Coherent checker noise functor object 00006 * 00007 */ 00008 00009 /*************************************************************************/ 00010 00011 #include "jit.noise.h" 00012 #include "jit.common.h" 00013 #include "jit.functor.h" 00014 00015 /*************************************************************************/ 00016 00017 // the checker noise object 00018 typedef struct _jit_functor_noise_checker 00019 { 00020 t_jit_object ob; 00021 00022 // pseudo random permutation table 00023 long *p; 00024 00025 // size and mask for tables 00026 long tablesize; 00027 long tablemask; 00028 00029 // seed for random number generation 00030 long seed; 00031 00032 // signed mode (0 = unsigned, 1 = signed) 00033 long sign; 00034 00035 // abs mode (0 = normal, 1 = absolute) 00036 long abs; 00037 00038 // smoothing factor 00039 t_jit_functor_combined_value smooth; 00040 00041 } t_jit_functor_noise_checker; 00042 00043 t_class *_jit_functor_noise_checker_class; 00044 00045 /*************************************************************************/ 00046 00047 t_jit_object *jit_functor_noise_checker_new(void); 00048 t_jit_err jit_functor_noise_checker_free(t_jit_functor_noise_checker *x); 00049 00050 t_jit_err jit_functor_noise_checker_abs(t_jit_functor_noise_checker *x, void *attr, long argc, t_atom *argv); 00051 t_jit_err jit_functor_noise_checker_sign(t_jit_functor_noise_checker *x, void *attr, long argc, t_atom *argv); 00052 t_jit_err jit_functor_noise_checker_seed(t_jit_functor_noise_checker *x, void *attr, long argc, t_atom *argv); 00053 t_jit_err jit_functor_noise_checker_smooth(t_jit_functor_noise_checker *x, void *attr, long argc, t_atom *argv); 00054 t_jit_err jit_functor_noise_checker_tablesize(t_jit_functor_noise_checker *x, void *attr, long argc, t_atom *argv); 00055 t_jit_err jit_functor_noise_checker_recalc(t_jit_functor_noise_checker *x); 00056 00057 long jit_functor_noise_checker_eval_fixed(t_jit_functor_noise_checker *x, long dimcount, long *vals); 00058 float jit_functor_noise_checker_eval_float32(t_jit_functor_noise_checker *x, long dimcount, float *vals); 00059 double jit_functor_noise_checker_eval_float64(t_jit_functor_noise_checker *x, long dimcount, double *vals); 00060 00061 /*************************************************************************/ 00062 00063 t_jit_err jit_functor_noise_checker_init(void) 00064 { 00065 t_jit_object *attr; 00066 00067 // create class 00068 _jit_functor_noise_checker_class = jit_class_new("jit_functor_noise_checker", 00069 (method)jit_functor_noise_checker_new,(method)jit_functor_noise_checker_free, 00070 sizeof(t_jit_functor_noise_checker), A_GIMME, 0L); 00071 00072 // add attributes 00073 attr = jit_object_new(_jit_sym_jit_attr_offset,"abs",_jit_sym_long,0, 00074 (method)0L,(method)jit_functor_noise_checker_abs,calcoffset(t_jit_functor_noise_checker,abs)); 00075 jit_class_addattr(_jit_functor_noise_checker_class,attr); 00076 attr = jit_object_new(_jit_sym_jit_attr_offset,"sign",_jit_sym_long,0, 00077 (method)0L,(method)jit_functor_noise_checker_sign,calcoffset(t_jit_functor_noise_checker,sign)); 00078 jit_class_addattr(_jit_functor_noise_checker_class,attr); 00079 attr = jit_object_new(_jit_sym_jit_attr_offset,"seed",_jit_sym_long,0, 00080 (method)0L,(method)jit_functor_noise_checker_seed,calcoffset(t_jit_functor_noise_checker,seed)); 00081 jit_class_addattr(_jit_functor_noise_checker_class,attr); 00082 attr = jit_object_new(_jit_sym_jit_attr_offset,"smooth",_jit_sym_long,0, 00083 (method)0L,(method)jit_functor_noise_checker_smooth,calcoffset(t_jit_functor_noise_checker,smooth.float64)); 00084 jit_class_addattr(_jit_functor_noise_checker_class,attr); 00085 00086 // add methods 00087 jit_class_addmethod(_jit_functor_noise_checker_class, 00088 (method)jit_functor_noise_checker_eval_fixed, "evalfixed", A_CANT, 0L); 00089 jit_class_addmethod(_jit_functor_noise_checker_class, 00090 (method)jit_functor_noise_checker_eval_float32, "evalfloat32", A_CANT, 0L); 00091 jit_class_addmethod(_jit_functor_noise_checker_class, 00092 (method)jit_functor_noise_checker_eval_float64, "evalfloat64", A_CANT, 0L); 00093 00094 // register functor *then* class 00095 jit_functor_setup_class(_jit_functor_noise_checker_class,"noise","checker"); 00096 jit_class_register(_jit_functor_noise_checker_class); 00097 00098 return JIT_ERR_NONE; 00099 } 00100 00101 t_jit_object *jit_functor_noise_checker_new(void) 00102 { 00103 t_jit_functor_noise_checker *x; 00104 00105 if (x = (t_jit_functor_noise_checker *)jit_object_alloc(_jit_functor_noise_checker_class)) { 00106 00107 // initialization 00108 x->p = NULL; 00109 00110 x->seed = JIT_NOISE_DEFAULT_SEED; 00111 x->tablesize = jit_math_roundup_poweroftwo(JIT_NOISE_DEFAULT_TABLESIZE); 00112 x->tablemask = x->tablesize - 1; 00113 00114 x->sign = FALSE; 00115 x->abs = FALSE; 00116 JIT_FUNCTOR_COMBINED_VALUE_SETALL(x->smooth, 0.0); 00117 00118 00119 // allocate permutation and uniform tables 00120 jit_functor_noise_permutations_init(&x->p, x->tablesize, x->seed); 00121 jit_functor_noise_checker_recalc(x); 00122 } 00123 00124 return (t_jit_object *)x; 00125 } 00126 00127 t_jit_err jit_functor_noise_checker_free(t_jit_functor_noise_checker *x) 00128 { 00129 if(x->p) 00130 jit_disposeptr((char*)x->p); 00131 x->p = NULL; 00132 00133 return JIT_ERR_NONE; 00134 } 00135 00136 t_jit_err jit_functor_noise_checker_abs( 00137 t_jit_functor_noise_checker *x, void *attr, long argc, t_atom *argv) 00138 { 00139 long v; 00140 00141 if (x) { 00142 v = jit_atom_getlong(argv); 00143 if (x->abs != v) { 00144 x->abs = (v > 0) ? TRUE : FALSE; 00145 jit_functor_noise_checker_recalc(x); 00146 } 00147 return JIT_ERR_NONE; 00148 } 00149 return JIT_ERR_INVALID_PTR; 00150 } 00151 00152 t_jit_err jit_functor_noise_checker_sign( 00153 t_jit_functor_noise_checker *x, void *attr, long argc, t_atom *argv) 00154 { 00155 long v; 00156 00157 if (x) { 00158 v = jit_atom_getlong(argv); 00159 if (x->sign != v) { 00160 x->sign = (v > 0) ? TRUE : FALSE; 00161 jit_functor_noise_checker_recalc(x); 00162 } 00163 return JIT_ERR_NONE; 00164 } 00165 return JIT_ERR_INVALID_PTR; 00166 } 00167 00168 t_jit_err jit_functor_noise_checker_seed( 00169 t_jit_functor_noise_checker *x, void *attr, long argc, t_atom *argv) 00170 { 00171 long v; 00172 00173 if (x) { 00174 v = jit_atom_getlong(argv); 00175 if (x->seed != v) { 00176 x->seed = v; 00177 00178 // allocate permutation and uniform tables 00179 jit_functor_noise_permutations_init(&x->p, x->tablesize, x->seed); 00180 jit_functor_noise_checker_recalc(x); 00181 } 00182 return JIT_ERR_NONE; 00183 } 00184 return JIT_ERR_INVALID_PTR; 00185 } 00186 00187 t_jit_err jit_functor_noise_checker_smooth( 00188 t_jit_functor_noise_checker *x, void *attr, long argc, t_atom *argv) 00189 { 00190 double v; 00191 00192 if (x) 00193 { 00194 v = jit_atom_getfloat(argv); 00195 v *= 0.5; 00196 if (x->smooth.float64 != v && v >= 0.0 && v <= 1.0) 00197 { 00198 JIT_FUNCTOR_COMBINED_VALUE_SETALL(x->smooth, v); 00199 jit_functor_noise_checker_recalc(x); 00200 } 00201 return JIT_ERR_NONE; 00202 } 00203 return JIT_ERR_INVALID_PTR; 00204 } 00205 t_jit_err jit_functor_noise_checker_tablesize( 00206 t_jit_functor_noise_checker *x, void *attr, long argc, t_atom *argv) 00207 { 00208 long v; 00209 00210 if (x) { 00211 v = jit_atom_getlong(argv); 00212 if (x->tablesize != v && v > 0) { 00213 00214 x->tablesize = jit_math_roundup_poweroftwo(v); 00215 x->tablemask = x->tablesize - 1; 00216 00217 // allocate permutation and uniform tables 00218 jit_functor_noise_permutations_init(&x->p, x->tablesize, x->seed); 00219 jit_functor_noise_checker_recalc(x); 00220 } 00221 return JIT_ERR_NONE; 00222 } 00223 return JIT_ERR_INVALID_PTR; 00224 } 00225 00226 t_jit_err jit_functor_noise_checker_recalc(t_jit_functor_noise_checker *x) 00227 { 00228 // calculate intermediary values for efficiency 00229 return JIT_ERR_NONE; 00230 } 00231 00232 // fixes % for negative numbers 00233 static long jit_math_mod_fixed(long a, long b) 00234 { 00235 long n = (long)FixDiv(a,b); 00236 a -= n*b; 00237 if (a < 0) 00238 return a + b; 00239 return a; 00240 } 00241 00242 static float jit_math_mod_float32(float a, float b) 00243 { 00244 long n = (long)(a/b); 00245 a -= n*b; 00246 if (a < 0) 00247 return a + b; 00248 return a; 00249 } 00250 00251 static double jit_math_mod_float64(double a, double b) 00252 { 00253 long n = (long)(a/b); 00254 a -= n*b; 00255 if (a < 0) 00256 return a + b; 00257 return a; 00258 } 00259 00260 float smooth_pulse_float32(float a1, float a2, float b1, float b2, float x) 00261 { 00262 if (x < a1 || x >= b2) 00263 return 0.0f; 00264 00265 if (x >= a2) 00266 { 00267 if (x < b1) 00268 return 1.0f; 00269 00270 x = (x - b1) / (b2 - b1); 00271 return 1.0f - (x*x * (3.0f - 2.0f*x)); 00272 } 00273 00274 x = (x - a1) / (a2 - a1); 00275 return x*x * (3.0f - 2.0f*x); 00276 } 00277 00278 double smooth_pulse_float64(double a1, double a2, double b1, double b2, double x) 00279 { 00280 if (x < a1 || x >= b2) 00281 return 0.0; 00282 00283 if (x >= a2) 00284 { 00285 if (x < b1) 00286 return 1.0; 00287 x = (x - b1) / (b2 - b1); 00288 return 1.0 - (x*x * (3.0 - 2.0*x)); 00289 } 00290 00291 x = (x - a1) / (a2 - a1); 00292 return x*x * (3.0 - 2.0*x); 00293 } 00294 00295 long jit_functor_noise_checker_eval_fixed( 00296 t_jit_functor_noise_checker *x, long dimcount, long *vals) 00297 { 00298 long i; 00299 long check; 00300 long val; 00301 float conv; 00302 float fuzz; 00303 float temp; 00304 long checker[JIT_MATRIX_MAX_DIMCOUNT]; 00305 00306 // convert to long 00307 for(i = 0; i < dimcount; i++) 00308 checker[i] = FixedFloor(vals[i] + JIT_NOISE_FIXED_DISALIGN); 00309 00310 // check the dimensional value for oddness 00311 check = checker[0] & 1; 00312 for (i = 1; i < dimcount; i++) { 00313 check = check ^ (checker[i] & 1); 00314 } 00315 00316 if (x->smooth.float32 != 0.0f) 00317 { 00318 conv = FixedToFloat(vals[0]); 00319 temp = jit_math_mod_float32(conv, 1.0f); 00320 fuzz = smooth_pulse_float32(0.0f, x->smooth.float32, 1.0f - x->smooth.float32, 1.0f, temp); 00321 for(i = 1; i < dimcount; i++) 00322 { 00323 conv = FixedToFloat(vals[i]); 00324 temp = jit_math_mod_float32(conv, 1.0f); 00325 fuzz = fuzz * smooth_pulse_float32(0.0f, x->smooth.float32, 1.0f - x->smooth.float32, 1.0, temp); 00326 } 00327 00328 // assign value based on oddness 00329 val = check ? FloatToFixed(0.5f - fuzz) : FloatToFixed(0.5f + fuzz); 00330 } 00331 else 00332 { 00333 // assign value based on oddness 00334 val = check ? FloatToFixed(-1.0f) : FloatToFixed(1.0f); 00335 } 00336 00337 // do conversion 00338 if(!x->sign) 00339 val = FixMul(FloatToFixed(0.5f), val) + FloatToFixed(0.5f); 00340 00341 if(x->abs) 00342 val = JIT_MATH_FIXED_ABS(val); 00343 00344 return val; 00345 } 00346 00347 float jit_functor_noise_checker_eval_float32( 00348 t_jit_functor_noise_checker *x, long dimcount, float *vals) 00349 { 00350 long i; 00351 long check; 00352 float val; 00353 float fuzz; 00354 float temp; 00355 long checker[JIT_MATRIX_MAX_DIMCOUNT]; 00356 00357 // convert to long 00358 for(i = 0; i < dimcount; i++) 00359 checker[i] = JIT_MATH_F32_FLOOR(vals[i] + JIT_NOISE_F32_DISALIGN); 00360 00361 // check the dimensional value for oddness 00362 check = checker[0] & 1; 00363 for (i = 1; i < dimcount; i++) { 00364 check = check ^ (checker[i] & 1); 00365 } 00366 00367 if (x->smooth.float32 != 0.0f) 00368 { 00369 temp = jit_math_mod_float32(vals[0], 1.0f); 00370 fuzz = smooth_pulse_float32(0.0f, x->smooth.float32, 1.0f - x->smooth.float32, 1.0f, temp); 00371 for(i = 1; i < dimcount; i++) 00372 { 00373 temp = jit_math_mod_float32(vals[i], 1.0f); 00374 fuzz = fuzz * smooth_pulse_float32(0.0f, x->smooth.float32, 1.0f - x->smooth.float32, 1.0, temp); 00375 } 00376 00377 // assign value based on oddness 00378 val = check ? 0.5f - fuzz : 0.5f + fuzz; 00379 } 00380 else 00381 { 00382 // assign value based on oddness 00383 val = check ? -1.0 : 1.0; 00384 } 00385 00386 // do conversion 00387 if(!x->sign) 00388 val = 0.5 * val + 0.5; 00389 00390 if(x->abs) 00391 val = JIT_MATH_F32_ABS(val); 00392 00393 return val; 00394 } 00395 00396 double jit_functor_noise_checker_eval_float64( 00397 t_jit_functor_noise_checker *x, long dimcount, double *vals) 00398 { 00399 long i; 00400 long check; 00401 double val; 00402 double fuzz; 00403 double temp; 00404 long checker[JIT_MATRIX_MAX_DIMCOUNT]; 00405 00406 // convert to long 00407 for(i = 0; i < dimcount; i++) 00408 checker[i] = JIT_MATH_F64_FLOOR(vals[i] + JIT_NOISE_F64_DISALIGN); 00409 00410 // check the dimensional value for oddness 00411 check = checker[0] & 1; 00412 for (i = 1; i < dimcount; i++) { 00413 check = check ^ (checker[i] & 1); 00414 } 00415 00416 if (x->smooth.float64 != 0.0) 00417 { 00418 temp = jit_math_mod_float64(vals[0], 1.0); 00419 fuzz = smooth_pulse_float64(0.0, x->smooth.float64, 1 - x->smooth.float64, 1.0, temp); 00420 for(i = 1; i < dimcount; i++) 00421 { 00422 temp = jit_math_mod_float64(vals[i], 1.0); 00423 fuzz = fuzz * smooth_pulse_float64(0.0, x->smooth.float64, 1 - x->smooth.float64, 1.0, temp); 00424 } 00425 00426 // assign value based on oddness 00427 val = check ? 0.5 - fuzz : 0.5 + fuzz; 00428 } 00429 else 00430 { 00431 // assign value based on oddness 00432 val = check ? -1.0 : 1.0; 00433 } 00434 00435 // do conversion 00436 if(!x->sign) 00437 val = 0.5 * val + 0.5; 00438 00439 if(x->abs) 00440 val = JIT_MATH_F64_ABS(val); 00441 00442 return val; 00443 }
Copyright © 2008, Cycling '74