diff options
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/d_math.c')
-rw-r--r-- | apps/plugins/pdbox/PDa/src/d_math.c | 1146 |
1 files changed, 1146 insertions, 0 deletions
diff --git a/apps/plugins/pdbox/PDa/src/d_math.c b/apps/plugins/pdbox/PDa/src/d_math.c new file mode 100644 index 0000000000..ee8a96692c --- /dev/null +++ b/apps/plugins/pdbox/PDa/src/d_math.c | |||
@@ -0,0 +1,1146 @@ | |||
1 | /* Copyright (c) 1997-2001 Miller Puckette and others. | ||
2 | * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
3 | * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ | ||
4 | |||
5 | /* mathematical functions and other transfer functions, including tilde | ||
6 | versions of stuff from x_acoustics.c. | ||
7 | */ | ||
8 | |||
9 | #include "m_pd.h" | ||
10 | #include <math.h> | ||
11 | #define LOGTEN 2.302585092994 | ||
12 | |||
13 | /* ------------------------- clip~ -------------------------- */ | ||
14 | static t_class *clip_class; | ||
15 | |||
16 | typedef struct _clip | ||
17 | { | ||
18 | t_object x_obj; | ||
19 | float x_f; | ||
20 | t_sample x_lo; | ||
21 | t_sample x_hi; | ||
22 | } t_clip; | ||
23 | |||
24 | static void *clip_new(t_floatarg lo, t_floatarg hi) | ||
25 | { | ||
26 | t_clip *x = (t_clip *)pd_new(clip_class); | ||
27 | x->x_lo = lo; | ||
28 | x->x_hi = hi; | ||
29 | outlet_new(&x->x_obj, gensym("signal")); | ||
30 | floatinlet_new(&x->x_obj, &x->x_lo); | ||
31 | floatinlet_new(&x->x_obj, &x->x_hi); | ||
32 | x->x_f = 0; | ||
33 | return (x); | ||
34 | } | ||
35 | |||
36 | static t_int *clip_perform(t_int *w) | ||
37 | { | ||
38 | t_clip *x = (t_clip *)(w[1]); | ||
39 | t_float *in = (t_float *)(w[2]); | ||
40 | t_float *out = (t_float *)(w[3]); | ||
41 | int n = (int)(w[4]); | ||
42 | while (n--) | ||
43 | { | ||
44 | float f = *in++; | ||
45 | if (f < x->x_lo) f = x->x_lo; | ||
46 | if (f > x->x_hi) f = x->x_hi; | ||
47 | *out++ = f; | ||
48 | } | ||
49 | return (w+5); | ||
50 | } | ||
51 | |||
52 | static void clip_dsp(t_clip *x, t_signal **sp) | ||
53 | { | ||
54 | dsp_add(clip_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
55 | } | ||
56 | |||
57 | static void clip_setup(void) | ||
58 | { | ||
59 | clip_class = class_new(gensym("clip~"), (t_newmethod)clip_new, 0, | ||
60 | sizeof(t_clip), 0, A_DEFFLOAT, A_DEFFLOAT, 0); | ||
61 | CLASS_MAINSIGNALIN(clip_class, t_clip, x_f); | ||
62 | class_addmethod(clip_class, (t_method)clip_dsp, gensym("dsp"), 0); | ||
63 | } | ||
64 | |||
65 | /* sigrsqrt - reciprocal square root good to 8 mantissa bits */ | ||
66 | |||
67 | #define DUMTAB1SIZE 256 | ||
68 | #define DUMTAB2SIZE 1024 | ||
69 | |||
70 | static float rsqrt_exptab[DUMTAB1SIZE], rsqrt_mantissatab[DUMTAB2SIZE]; | ||
71 | |||
72 | static void init_rsqrt(void) | ||
73 | { | ||
74 | int i; | ||
75 | for (i = 0; i < DUMTAB1SIZE; i++) | ||
76 | { | ||
77 | float f; | ||
78 | long l = (i ? (i == DUMTAB1SIZE-1 ? DUMTAB1SIZE-2 : i) : 1)<< 23; | ||
79 | *(long *)(&f) = l; | ||
80 | rsqrt_exptab[i] = 1./sqrt(f); | ||
81 | } | ||
82 | for (i = 0; i < DUMTAB2SIZE; i++) | ||
83 | { | ||
84 | float f = 1 + (1./DUMTAB2SIZE) * i; | ||
85 | rsqrt_mantissatab[i] = 1./sqrt(f); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | /* these are used in externs like "bonk" */ | ||
90 | |||
91 | float q8_rsqrt(float f) | ||
92 | { | ||
93 | long l = *(long *)(&f); | ||
94 | if (f < 0) return (0); | ||
95 | else return (rsqrt_exptab[(l >> 23) & 0xff] * | ||
96 | rsqrt_mantissatab[(l >> 13) & 0x3ff]); | ||
97 | } | ||
98 | |||
99 | float q8_sqrt(float f) | ||
100 | { | ||
101 | long l = *(long *)(&f); | ||
102 | if (f < 0) return (0); | ||
103 | else return (f * rsqrt_exptab[(l >> 23) & 0xff] * | ||
104 | rsqrt_mantissatab[(l >> 13) & 0x3ff]); | ||
105 | } | ||
106 | |||
107 | /* the old names are OK unless we're in IRIX N32 */ | ||
108 | |||
109 | #ifndef N32 | ||
110 | float qsqrt(float f) {return (q8_sqrt(f)); } | ||
111 | float qrsqrt(float f) {return (q8_rsqrt(f)); } | ||
112 | #endif | ||
113 | |||
114 | |||
115 | |||
116 | typedef struct sigrsqrt | ||
117 | { | ||
118 | t_object x_obj; | ||
119 | float x_f; | ||
120 | } t_sigrsqrt; | ||
121 | |||
122 | static t_class *sigrsqrt_class; | ||
123 | |||
124 | static void *sigrsqrt_new(void) | ||
125 | { | ||
126 | t_sigrsqrt *x = (t_sigrsqrt *)pd_new(sigrsqrt_class); | ||
127 | outlet_new(&x->x_obj, gensym("signal")); | ||
128 | x->x_f = 0; | ||
129 | return (x); | ||
130 | } | ||
131 | |||
132 | static t_int *sigrsqrt_perform(t_int *w) | ||
133 | { | ||
134 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
135 | t_int n = *(t_int *)(w+3); | ||
136 | while (n--) | ||
137 | { | ||
138 | float f = *in; | ||
139 | long l = *(long *)(in++); | ||
140 | if (f < 0) *out++ = 0; | ||
141 | else | ||
142 | { | ||
143 | float g = rsqrt_exptab[(l >> 23) & 0xff] * | ||
144 | rsqrt_mantissatab[(l >> 13) & 0x3ff]; | ||
145 | *out++ = 1.5 * g - 0.5 * g * g * g * f; | ||
146 | } | ||
147 | } | ||
148 | return (w + 4); | ||
149 | } | ||
150 | |||
151 | static void sigrsqrt_dsp(t_sigrsqrt *x, t_signal **sp) | ||
152 | { | ||
153 | dsp_add(sigrsqrt_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
154 | } | ||
155 | |||
156 | void sigrsqrt_setup(void) | ||
157 | { | ||
158 | init_rsqrt(); | ||
159 | sigrsqrt_class = class_new(gensym("rsqrt~"), (t_newmethod)sigrsqrt_new, 0, | ||
160 | sizeof(t_sigrsqrt), 0, 0); | ||
161 | /* an old name for it: */ | ||
162 | class_addcreator(sigrsqrt_new, gensym("q8_rsqrt~"), 0); | ||
163 | CLASS_MAINSIGNALIN(sigrsqrt_class, t_sigrsqrt, x_f); | ||
164 | class_addmethod(sigrsqrt_class, (t_method)sigrsqrt_dsp, gensym("dsp"), 0); | ||
165 | } | ||
166 | |||
167 | |||
168 | /* sigsqrt - square root good to 8 mantissa bits */ | ||
169 | |||
170 | typedef struct sigsqrt | ||
171 | { | ||
172 | t_object x_obj; | ||
173 | float x_f; | ||
174 | } t_sigsqrt; | ||
175 | |||
176 | static t_class *sigsqrt_class; | ||
177 | |||
178 | static void *sigsqrt_new(void) | ||
179 | { | ||
180 | t_sigsqrt *x = (t_sigsqrt *)pd_new(sigsqrt_class); | ||
181 | outlet_new(&x->x_obj, gensym("signal")); | ||
182 | x->x_f = 0; | ||
183 | return (x); | ||
184 | } | ||
185 | |||
186 | t_int *sigsqrt_perform(t_int *w) /* not static; also used in d_fft.c */ | ||
187 | { | ||
188 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
189 | t_int n = *(t_int *)(w+3); | ||
190 | while (n--) | ||
191 | { | ||
192 | float f = *in; | ||
193 | long l = *(long *)(in++); | ||
194 | if (f < 0) *out++ = 0; | ||
195 | else | ||
196 | { | ||
197 | float g = rsqrt_exptab[(l >> 23) & 0xff] * | ||
198 | rsqrt_mantissatab[(l >> 13) & 0x3ff]; | ||
199 | *out++ = f * (1.5 * g - 0.5 * g * g * g * f); | ||
200 | } | ||
201 | } | ||
202 | return (w + 4); | ||
203 | } | ||
204 | |||
205 | static void sigsqrt_dsp(t_sigsqrt *x, t_signal **sp) | ||
206 | { | ||
207 | dsp_add(sigsqrt_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
208 | } | ||
209 | |||
210 | void sigsqrt_setup(void) | ||
211 | { | ||
212 | sigsqrt_class = class_new(gensym("sqrt~"), (t_newmethod)sigsqrt_new, 0, | ||
213 | sizeof(t_sigsqrt), 0, 0); | ||
214 | class_addcreator(sigsqrt_new, gensym("q8_sqrt~"), 0); /* old name */ | ||
215 | CLASS_MAINSIGNALIN(sigsqrt_class, t_sigsqrt, x_f); | ||
216 | class_addmethod(sigsqrt_class, (t_method)sigsqrt_dsp, gensym("dsp"), 0); | ||
217 | } | ||
218 | |||
219 | /* ------------------------------ wrap~ -------------------------- */ | ||
220 | |||
221 | typedef struct wrap | ||
222 | { | ||
223 | t_object x_obj; | ||
224 | float x_f; | ||
225 | } t_sigwrap; | ||
226 | |||
227 | t_class *sigwrap_class; | ||
228 | |||
229 | static void *sigwrap_new(void) | ||
230 | { | ||
231 | t_sigwrap *x = (t_sigwrap *)pd_new(sigwrap_class); | ||
232 | outlet_new(&x->x_obj, gensym("signal")); | ||
233 | x->x_f = 0; | ||
234 | return (x); | ||
235 | } | ||
236 | |||
237 | static t_int *sigwrap_perform(t_int *w) | ||
238 | { | ||
239 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
240 | t_int n = *(t_int *)(w+3); | ||
241 | while (n--) | ||
242 | { | ||
243 | float f = *in++; | ||
244 | int k = f; | ||
245 | if (f > 0) *out++ = f-k; | ||
246 | else *out++ = f - (k-1); | ||
247 | } | ||
248 | return (w + 4); | ||
249 | } | ||
250 | |||
251 | static void sigwrap_dsp(t_sigwrap *x, t_signal **sp) | ||
252 | { | ||
253 | dsp_add(sigwrap_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
254 | } | ||
255 | |||
256 | void sigwrap_setup(void) | ||
257 | { | ||
258 | sigwrap_class = class_new(gensym("wrap~"), (t_newmethod)sigwrap_new, 0, | ||
259 | sizeof(t_sigwrap), 0, 0); | ||
260 | CLASS_MAINSIGNALIN(sigwrap_class, t_sigwrap, x_f); | ||
261 | class_addmethod(sigwrap_class, (t_method)sigwrap_dsp, gensym("dsp"), 0); | ||
262 | } | ||
263 | |||
264 | /* ------------------------------ mtof_tilde~ -------------------------- */ | ||
265 | |||
266 | typedef struct mtof_tilde | ||
267 | { | ||
268 | t_object x_obj; | ||
269 | float x_f; | ||
270 | } t_mtof_tilde; | ||
271 | |||
272 | t_class *mtof_tilde_class; | ||
273 | |||
274 | static void *mtof_tilde_new(void) | ||
275 | { | ||
276 | t_mtof_tilde *x = (t_mtof_tilde *)pd_new(mtof_tilde_class); | ||
277 | outlet_new(&x->x_obj, gensym("signal")); | ||
278 | x->x_f = 0; | ||
279 | return (x); | ||
280 | } | ||
281 | |||
282 | static t_int *mtof_tilde_perform(t_int *w) | ||
283 | { | ||
284 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
285 | t_int n = *(t_int *)(w+3); | ||
286 | for (; n--; in++, out++) | ||
287 | { | ||
288 | float f = *in; | ||
289 | if (f <= -1500) *out = 0; | ||
290 | else | ||
291 | { | ||
292 | if (f > 1499) f = 1499; | ||
293 | *out = 8.17579891564 * exp(.0577622650 * f); | ||
294 | } | ||
295 | } | ||
296 | return (w + 4); | ||
297 | } | ||
298 | |||
299 | static void mtof_tilde_dsp(t_mtof_tilde *x, t_signal **sp) | ||
300 | { | ||
301 | dsp_add(mtof_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
302 | } | ||
303 | |||
304 | void mtof_tilde_setup(void) | ||
305 | { | ||
306 | mtof_tilde_class = class_new(gensym("mtof~"), (t_newmethod)mtof_tilde_new, 0, | ||
307 | sizeof(t_mtof_tilde), 0, 0); | ||
308 | CLASS_MAINSIGNALIN(mtof_tilde_class, t_mtof_tilde, x_f); | ||
309 | class_addmethod(mtof_tilde_class, (t_method)mtof_tilde_dsp, gensym("dsp"), 0); | ||
310 | } | ||
311 | |||
312 | /* ------------------------------ ftom_tilde~ -------------------------- */ | ||
313 | |||
314 | typedef struct ftom_tilde | ||
315 | { | ||
316 | t_object x_obj; | ||
317 | float x_f; | ||
318 | } t_ftom_tilde; | ||
319 | |||
320 | t_class *ftom_tilde_class; | ||
321 | |||
322 | static void *ftom_tilde_new(void) | ||
323 | { | ||
324 | t_ftom_tilde *x = (t_ftom_tilde *)pd_new(ftom_tilde_class); | ||
325 | outlet_new(&x->x_obj, gensym("signal")); | ||
326 | x->x_f = 0; | ||
327 | return (x); | ||
328 | } | ||
329 | |||
330 | static t_int *ftom_tilde_perform(t_int *w) | ||
331 | { | ||
332 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
333 | t_int n = *(t_int *)(w+3); | ||
334 | for (; n--; *in++, out++) | ||
335 | { | ||
336 | float f = *in; | ||
337 | *out = (f > 0 ? 17.3123405046 * log(.12231220585 * f) : -1500); | ||
338 | } | ||
339 | return (w + 4); | ||
340 | } | ||
341 | |||
342 | static void ftom_tilde_dsp(t_ftom_tilde *x, t_signal **sp) | ||
343 | { | ||
344 | dsp_add(ftom_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
345 | } | ||
346 | |||
347 | void ftom_tilde_setup(void) | ||
348 | { | ||
349 | ftom_tilde_class = class_new(gensym("ftom~"), (t_newmethod)ftom_tilde_new, 0, | ||
350 | sizeof(t_ftom_tilde), 0, 0); | ||
351 | CLASS_MAINSIGNALIN(ftom_tilde_class, t_ftom_tilde, x_f); | ||
352 | class_addmethod(ftom_tilde_class, (t_method)ftom_tilde_dsp, gensym("dsp"), 0); | ||
353 | } | ||
354 | |||
355 | /* ------------------------------ dbtorms~ -------------------------- */ | ||
356 | |||
357 | typedef struct dbtorms_tilde | ||
358 | { | ||
359 | t_object x_obj; | ||
360 | float x_f; | ||
361 | } t_dbtorms_tilde; | ||
362 | |||
363 | t_class *dbtorms_tilde_class; | ||
364 | |||
365 | static void *dbtorms_tilde_new(void) | ||
366 | { | ||
367 | t_dbtorms_tilde *x = (t_dbtorms_tilde *)pd_new(dbtorms_tilde_class); | ||
368 | outlet_new(&x->x_obj, gensym("signal")); | ||
369 | x->x_f = 0; | ||
370 | return (x); | ||
371 | } | ||
372 | |||
373 | static t_int *dbtorms_tilde_perform(t_int *w) | ||
374 | { | ||
375 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
376 | t_int n = *(t_int *)(w+3); | ||
377 | for (; n--; in++, out++) | ||
378 | { | ||
379 | float f = *in; | ||
380 | if (f <= 0) *out = 0; | ||
381 | else | ||
382 | { | ||
383 | if (f > 485) | ||
384 | f = 485; | ||
385 | *out = exp((LOGTEN * 0.05) * (f-100.)); | ||
386 | } | ||
387 | } | ||
388 | return (w + 4); | ||
389 | } | ||
390 | |||
391 | static void dbtorms_tilde_dsp(t_dbtorms_tilde *x, t_signal **sp) | ||
392 | { | ||
393 | dsp_add(dbtorms_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
394 | } | ||
395 | |||
396 | void dbtorms_tilde_setup(void) | ||
397 | { | ||
398 | dbtorms_tilde_class = class_new(gensym("dbtorms~"), (t_newmethod)dbtorms_tilde_new, 0, | ||
399 | sizeof(t_dbtorms_tilde), 0, 0); | ||
400 | CLASS_MAINSIGNALIN(dbtorms_tilde_class, t_dbtorms_tilde, x_f); | ||
401 | class_addmethod(dbtorms_tilde_class, (t_method)dbtorms_tilde_dsp, gensym("dsp"), 0); | ||
402 | } | ||
403 | |||
404 | /* ------------------------------ rmstodb~ -------------------------- */ | ||
405 | |||
406 | typedef struct rmstodb_tilde | ||
407 | { | ||
408 | t_object x_obj; | ||
409 | float x_f; | ||
410 | } t_rmstodb_tilde; | ||
411 | |||
412 | t_class *rmstodb_tilde_class; | ||
413 | |||
414 | static void *rmstodb_tilde_new(void) | ||
415 | { | ||
416 | t_rmstodb_tilde *x = (t_rmstodb_tilde *)pd_new(rmstodb_tilde_class); | ||
417 | outlet_new(&x->x_obj, gensym("signal")); | ||
418 | x->x_f = 0; | ||
419 | return (x); | ||
420 | } | ||
421 | |||
422 | static t_int *rmstodb_tilde_perform(t_int *w) | ||
423 | { | ||
424 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
425 | t_int n = *(t_int *)(w+3); | ||
426 | for (; n--; in++, out++) | ||
427 | { | ||
428 | float f = *in; | ||
429 | if (f <= 0) *out = 0; | ||
430 | else | ||
431 | { | ||
432 | float g = 100 + 20./LOGTEN * log(f); | ||
433 | *out = (g < 0 ? 0 : g); | ||
434 | } | ||
435 | } | ||
436 | return (w + 4); | ||
437 | } | ||
438 | |||
439 | static void rmstodb_tilde_dsp(t_rmstodb_tilde *x, t_signal **sp) | ||
440 | { | ||
441 | dsp_add(rmstodb_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
442 | } | ||
443 | |||
444 | void rmstodb_tilde_setup(void) | ||
445 | { | ||
446 | rmstodb_tilde_class = class_new(gensym("rmstodb~"), (t_newmethod)rmstodb_tilde_new, 0, | ||
447 | sizeof(t_rmstodb_tilde), 0, 0); | ||
448 | CLASS_MAINSIGNALIN(rmstodb_tilde_class, t_rmstodb_tilde, x_f); | ||
449 | class_addmethod(rmstodb_tilde_class, (t_method)rmstodb_tilde_dsp, gensym("dsp"), 0); | ||
450 | } | ||
451 | |||
452 | /* ------------------------------ dbtopow~ -------------------------- */ | ||
453 | |||
454 | typedef struct dbtopow_tilde | ||
455 | { | ||
456 | t_object x_obj; | ||
457 | float x_f; | ||
458 | } t_dbtopow_tilde; | ||
459 | |||
460 | t_class *dbtopow_tilde_class; | ||
461 | |||
462 | static void *dbtopow_tilde_new(void) | ||
463 | { | ||
464 | t_dbtopow_tilde *x = (t_dbtopow_tilde *)pd_new(dbtopow_tilde_class); | ||
465 | outlet_new(&x->x_obj, gensym("signal")); | ||
466 | x->x_f = 0; | ||
467 | return (x); | ||
468 | } | ||
469 | |||
470 | static t_int *dbtopow_tilde_perform(t_int *w) | ||
471 | { | ||
472 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
473 | t_int n = *(t_int *)(w+3); | ||
474 | for (; n--; in++, out++) | ||
475 | { | ||
476 | float f = *in; | ||
477 | if (f <= 0) *out = 0; | ||
478 | else | ||
479 | { | ||
480 | if (f > 870) | ||
481 | f = 870; | ||
482 | *out = exp((LOGTEN * 0.1) * (f-100.)); | ||
483 | } | ||
484 | } | ||
485 | return (w + 4); | ||
486 | } | ||
487 | |||
488 | static void dbtopow_tilde_dsp(t_dbtopow_tilde *x, t_signal **sp) | ||
489 | { | ||
490 | dsp_add(dbtopow_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
491 | } | ||
492 | |||
493 | void dbtopow_tilde_setup(void) | ||
494 | { | ||
495 | dbtopow_tilde_class = class_new(gensym("dbtopow~"), (t_newmethod)dbtopow_tilde_new, 0, | ||
496 | sizeof(t_dbtopow_tilde), 0, 0); | ||
497 | CLASS_MAINSIGNALIN(dbtopow_tilde_class, t_dbtopow_tilde, x_f); | ||
498 | class_addmethod(dbtopow_tilde_class, (t_method)dbtopow_tilde_dsp, gensym("dsp"), 0); | ||
499 | } | ||
500 | |||
501 | /* ------------------------------ powtodb~ -------------------------- */ | ||
502 | |||
503 | typedef struct powtodb_tilde | ||
504 | { | ||
505 | t_object x_obj; | ||
506 | float x_f; | ||
507 | } t_powtodb_tilde; | ||
508 | |||
509 | t_class *powtodb_tilde_class; | ||
510 | |||
511 | static void *powtodb_tilde_new(void) | ||
512 | { | ||
513 | t_powtodb_tilde *x = (t_powtodb_tilde *)pd_new(powtodb_tilde_class); | ||
514 | outlet_new(&x->x_obj, gensym("signal")); | ||
515 | x->x_f = 0; | ||
516 | return (x); | ||
517 | } | ||
518 | |||
519 | static t_int *powtodb_tilde_perform(t_int *w) | ||
520 | { | ||
521 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
522 | t_int n = *(t_int *)(w+3); | ||
523 | for (; n--; in++, out++) | ||
524 | { | ||
525 | float f = *in; | ||
526 | if (f <= 0) *out = 0; | ||
527 | else | ||
528 | { | ||
529 | float g = 100 + 10./LOGTEN * log(f); | ||
530 | *out = (g < 0 ? 0 : g); | ||
531 | } | ||
532 | } | ||
533 | return (w + 4); | ||
534 | } | ||
535 | |||
536 | static void powtodb_tilde_dsp(t_powtodb_tilde *x, t_signal **sp) | ||
537 | { | ||
538 | dsp_add(powtodb_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
539 | } | ||
540 | |||
541 | void powtodb_tilde_setup(void) | ||
542 | { | ||
543 | powtodb_tilde_class = class_new(gensym("powtodb~"), (t_newmethod)powtodb_tilde_new, 0, | ||
544 | sizeof(t_powtodb_tilde), 0, 0); | ||
545 | CLASS_MAINSIGNALIN(powtodb_tilde_class, t_powtodb_tilde, x_f); | ||
546 | class_addmethod(powtodb_tilde_class, (t_method)powtodb_tilde_dsp, gensym("dsp"), 0); | ||
547 | } | ||
548 | |||
549 | |||
550 | /* ------------------------ global setup routine ------------------------- */ | ||
551 | |||
552 | void d_math_setup(void) | ||
553 | { | ||
554 | t_symbol *s = gensym("acoustics~.pd"); | ||
555 | clip_setup(); | ||
556 | sigrsqrt_setup(); | ||
557 | sigsqrt_setup(); | ||
558 | sigwrap_setup(); | ||
559 | mtof_tilde_setup(); | ||
560 | ftom_tilde_setup(); | ||
561 | dbtorms_tilde_setup(); | ||
562 | rmstodb_tilde_setup(); | ||
563 | dbtopow_tilde_setup(); | ||
564 | powtodb_tilde_setup(); | ||
565 | |||
566 | class_sethelpsymbol(mtof_tilde_class, s); | ||
567 | class_sethelpsymbol(ftom_tilde_class, s); | ||
568 | class_sethelpsymbol(dbtorms_tilde_class, s); | ||
569 | class_sethelpsymbol(rmstodb_tilde_class, s); | ||
570 | class_sethelpsymbol(dbtopow_tilde_class, s); | ||
571 | class_sethelpsymbol(powtodb_tilde_class, s); | ||
572 | } | ||
573 | |||
574 | /* Copyright (c) 1997-2001 Miller Puckette and others. | ||
575 | * For information on usage and redistribution, and for a DISCLAIMER OF ALL | ||
576 | * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ | ||
577 | |||
578 | /* mathematical functions and other transfer functions, including tilde | ||
579 | versions of stuff from x_acoustics.c. | ||
580 | */ | ||
581 | |||
582 | #include "m_pd.h" | ||
583 | #include <math.h> | ||
584 | #define LOGTEN 2.302585092994 | ||
585 | |||
586 | /* ------------------------- clip~ -------------------------- */ | ||
587 | static t_class *clip_class; | ||
588 | |||
589 | typedef struct _clip | ||
590 | { | ||
591 | t_object x_obj; | ||
592 | float x_f; | ||
593 | t_sample x_lo; | ||
594 | t_sample x_hi; | ||
595 | } t_clip; | ||
596 | |||
597 | static void *clip_new(t_floatarg lo, t_floatarg hi) | ||
598 | { | ||
599 | t_clip *x = (t_clip *)pd_new(clip_class); | ||
600 | x->x_lo = lo; | ||
601 | x->x_hi = hi; | ||
602 | outlet_new(&x->x_obj, gensym("signal")); | ||
603 | floatinlet_new(&x->x_obj, &x->x_lo); | ||
604 | floatinlet_new(&x->x_obj, &x->x_hi); | ||
605 | x->x_f = 0; | ||
606 | return (x); | ||
607 | } | ||
608 | |||
609 | static t_int *clip_perform(t_int *w) | ||
610 | { | ||
611 | t_clip *x = (t_clip *)(w[1]); | ||
612 | t_float *in = (t_float *)(w[2]); | ||
613 | t_float *out = (t_float *)(w[3]); | ||
614 | int n = (int)(w[4]); | ||
615 | while (n--) | ||
616 | { | ||
617 | float f = *in++; | ||
618 | if (f < x->x_lo) f = x->x_lo; | ||
619 | if (f > x->x_hi) f = x->x_hi; | ||
620 | *out++ = f; | ||
621 | } | ||
622 | return (w+5); | ||
623 | } | ||
624 | |||
625 | static void clip_dsp(t_clip *x, t_signal **sp) | ||
626 | { | ||
627 | dsp_add(clip_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
628 | } | ||
629 | |||
630 | static void clip_setup(void) | ||
631 | { | ||
632 | clip_class = class_new(gensym("clip~"), (t_newmethod)clip_new, 0, | ||
633 | sizeof(t_clip), 0, A_DEFFLOAT, A_DEFFLOAT, 0); | ||
634 | CLASS_MAINSIGNALIN(clip_class, t_clip, x_f); | ||
635 | class_addmethod(clip_class, (t_method)clip_dsp, gensym("dsp"), 0); | ||
636 | } | ||
637 | |||
638 | /* sigrsqrt - reciprocal square root good to 8 mantissa bits */ | ||
639 | |||
640 | #define DUMTAB1SIZE 256 | ||
641 | #define DUMTAB2SIZE 1024 | ||
642 | |||
643 | static float rsqrt_exptab[DUMTAB1SIZE], rsqrt_mantissatab[DUMTAB2SIZE]; | ||
644 | |||
645 | static void init_rsqrt(void) | ||
646 | { | ||
647 | int i; | ||
648 | for (i = 0; i < DUMTAB1SIZE; i++) | ||
649 | { | ||
650 | float f; | ||
651 | long l = (i ? (i == DUMTAB1SIZE-1 ? DUMTAB1SIZE-2 : i) : 1)<< 23; | ||
652 | *(long *)(&f) = l; | ||
653 | rsqrt_exptab[i] = 1./sqrt(f); | ||
654 | } | ||
655 | for (i = 0; i < DUMTAB2SIZE; i++) | ||
656 | { | ||
657 | float f = 1 + (1./DUMTAB2SIZE) * i; | ||
658 | rsqrt_mantissatab[i] = 1./sqrt(f); | ||
659 | } | ||
660 | } | ||
661 | |||
662 | /* these are used in externs like "bonk" */ | ||
663 | |||
664 | float q8_rsqrt(float f) | ||
665 | { | ||
666 | long l = *(long *)(&f); | ||
667 | if (f < 0) return (0); | ||
668 | else return (rsqrt_exptab[(l >> 23) & 0xff] * | ||
669 | rsqrt_mantissatab[(l >> 13) & 0x3ff]); | ||
670 | } | ||
671 | |||
672 | float q8_sqrt(float f) | ||
673 | { | ||
674 | long l = *(long *)(&f); | ||
675 | if (f < 0) return (0); | ||
676 | else return (f * rsqrt_exptab[(l >> 23) & 0xff] * | ||
677 | rsqrt_mantissatab[(l >> 13) & 0x3ff]); | ||
678 | } | ||
679 | |||
680 | /* the old names are OK unless we're in IRIX N32 */ | ||
681 | |||
682 | #ifndef N32 | ||
683 | float qsqrt(float f) {return (q8_sqrt(f)); } | ||
684 | float qrsqrt(float f) {return (q8_rsqrt(f)); } | ||
685 | #endif | ||
686 | |||
687 | |||
688 | |||
689 | typedef struct sigrsqrt | ||
690 | { | ||
691 | t_object x_obj; | ||
692 | float x_f; | ||
693 | } t_sigrsqrt; | ||
694 | |||
695 | static t_class *sigrsqrt_class; | ||
696 | |||
697 | static void *sigrsqrt_new(void) | ||
698 | { | ||
699 | t_sigrsqrt *x = (t_sigrsqrt *)pd_new(sigrsqrt_class); | ||
700 | outlet_new(&x->x_obj, gensym("signal")); | ||
701 | x->x_f = 0; | ||
702 | return (x); | ||
703 | } | ||
704 | |||
705 | static t_int *sigrsqrt_perform(t_int *w) | ||
706 | { | ||
707 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
708 | t_int n = *(t_int *)(w+3); | ||
709 | while (n--) | ||
710 | { | ||
711 | float f = *in; | ||
712 | long l = *(long *)(in++); | ||
713 | if (f < 0) *out++ = 0; | ||
714 | else | ||
715 | { | ||
716 | float g = rsqrt_exptab[(l >> 23) & 0xff] * | ||
717 | rsqrt_mantissatab[(l >> 13) & 0x3ff]; | ||
718 | *out++ = 1.5 * g - 0.5 * g * g * g * f; | ||
719 | } | ||
720 | } | ||
721 | return (w + 4); | ||
722 | } | ||
723 | |||
724 | static void sigrsqrt_dsp(t_sigrsqrt *x, t_signal **sp) | ||
725 | { | ||
726 | dsp_add(sigrsqrt_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
727 | } | ||
728 | |||
729 | void sigrsqrt_setup(void) | ||
730 | { | ||
731 | init_rsqrt(); | ||
732 | sigrsqrt_class = class_new(gensym("rsqrt~"), (t_newmethod)sigrsqrt_new, 0, | ||
733 | sizeof(t_sigrsqrt), 0, 0); | ||
734 | /* an old name for it: */ | ||
735 | class_addcreator(sigrsqrt_new, gensym("q8_rsqrt~"), 0); | ||
736 | CLASS_MAINSIGNALIN(sigrsqrt_class, t_sigrsqrt, x_f); | ||
737 | class_addmethod(sigrsqrt_class, (t_method)sigrsqrt_dsp, gensym("dsp"), 0); | ||
738 | } | ||
739 | |||
740 | |||
741 | /* sigsqrt - square root good to 8 mantissa bits */ | ||
742 | |||
743 | typedef struct sigsqrt | ||
744 | { | ||
745 | t_object x_obj; | ||
746 | float x_f; | ||
747 | } t_sigsqrt; | ||
748 | |||
749 | static t_class *sigsqrt_class; | ||
750 | |||
751 | static void *sigsqrt_new(void) | ||
752 | { | ||
753 | t_sigsqrt *x = (t_sigsqrt *)pd_new(sigsqrt_class); | ||
754 | outlet_new(&x->x_obj, gensym("signal")); | ||
755 | x->x_f = 0; | ||
756 | return (x); | ||
757 | } | ||
758 | |||
759 | t_int *sigsqrt_perform(t_int *w) /* not static; also used in d_fft.c */ | ||
760 | { | ||
761 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
762 | t_int n = *(t_int *)(w+3); | ||
763 | while (n--) | ||
764 | { | ||
765 | float f = *in; | ||
766 | long l = *(long *)(in++); | ||
767 | if (f < 0) *out++ = 0; | ||
768 | else | ||
769 | { | ||
770 | float g = rsqrt_exptab[(l >> 23) & 0xff] * | ||
771 | rsqrt_mantissatab[(l >> 13) & 0x3ff]; | ||
772 | *out++ = f * (1.5 * g - 0.5 * g * g * g * f); | ||
773 | } | ||
774 | } | ||
775 | return (w + 4); | ||
776 | } | ||
777 | |||
778 | static void sigsqrt_dsp(t_sigsqrt *x, t_signal **sp) | ||
779 | { | ||
780 | dsp_add(sigsqrt_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
781 | } | ||
782 | |||
783 | void sigsqrt_setup(void) | ||
784 | { | ||
785 | sigsqrt_class = class_new(gensym("sqrt~"), (t_newmethod)sigsqrt_new, 0, | ||
786 | sizeof(t_sigsqrt), 0, 0); | ||
787 | class_addcreator(sigsqrt_new, gensym("q8_sqrt~"), 0); /* old name */ | ||
788 | CLASS_MAINSIGNALIN(sigsqrt_class, t_sigsqrt, x_f); | ||
789 | class_addmethod(sigsqrt_class, (t_method)sigsqrt_dsp, gensym("dsp"), 0); | ||
790 | } | ||
791 | |||
792 | /* ------------------------------ wrap~ -------------------------- */ | ||
793 | |||
794 | typedef struct wrap | ||
795 | { | ||
796 | t_object x_obj; | ||
797 | float x_f; | ||
798 | } t_sigwrap; | ||
799 | |||
800 | t_class *sigwrap_class; | ||
801 | |||
802 | static void *sigwrap_new(void) | ||
803 | { | ||
804 | t_sigwrap *x = (t_sigwrap *)pd_new(sigwrap_class); | ||
805 | outlet_new(&x->x_obj, gensym("signal")); | ||
806 | x->x_f = 0; | ||
807 | return (x); | ||
808 | } | ||
809 | |||
810 | static t_int *sigwrap_perform(t_int *w) | ||
811 | { | ||
812 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
813 | t_int n = *(t_int *)(w+3); | ||
814 | while (n--) | ||
815 | { | ||
816 | float f = *in++; | ||
817 | int k = f; | ||
818 | if (f > 0) *out++ = f-k; | ||
819 | else *out++ = f - (k-1); | ||
820 | } | ||
821 | return (w + 4); | ||
822 | } | ||
823 | |||
824 | static void sigwrap_dsp(t_sigwrap *x, t_signal **sp) | ||
825 | { | ||
826 | dsp_add(sigwrap_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
827 | } | ||
828 | |||
829 | void sigwrap_setup(void) | ||
830 | { | ||
831 | sigwrap_class = class_new(gensym("wrap~"), (t_newmethod)sigwrap_new, 0, | ||
832 | sizeof(t_sigwrap), 0, 0); | ||
833 | CLASS_MAINSIGNALIN(sigwrap_class, t_sigwrap, x_f); | ||
834 | class_addmethod(sigwrap_class, (t_method)sigwrap_dsp, gensym("dsp"), 0); | ||
835 | } | ||
836 | |||
837 | /* ------------------------------ mtof_tilde~ -------------------------- */ | ||
838 | |||
839 | typedef struct mtof_tilde | ||
840 | { | ||
841 | t_object x_obj; | ||
842 | float x_f; | ||
843 | } t_mtof_tilde; | ||
844 | |||
845 | t_class *mtof_tilde_class; | ||
846 | |||
847 | static void *mtof_tilde_new(void) | ||
848 | { | ||
849 | t_mtof_tilde *x = (t_mtof_tilde *)pd_new(mtof_tilde_class); | ||
850 | outlet_new(&x->x_obj, gensym("signal")); | ||
851 | x->x_f = 0; | ||
852 | return (x); | ||
853 | } | ||
854 | |||
855 | static t_int *mtof_tilde_perform(t_int *w) | ||
856 | { | ||
857 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
858 | t_int n = *(t_int *)(w+3); | ||
859 | for (; n--; in++, out++) | ||
860 | { | ||
861 | float f = *in; | ||
862 | if (f <= -1500) *out = 0; | ||
863 | else | ||
864 | { | ||
865 | if (f > 1499) f = 1499; | ||
866 | *out = 8.17579891564 * exp(.0577622650 * f); | ||
867 | } | ||
868 | } | ||
869 | return (w + 4); | ||
870 | } | ||
871 | |||
872 | static void mtof_tilde_dsp(t_mtof_tilde *x, t_signal **sp) | ||
873 | { | ||
874 | dsp_add(mtof_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
875 | } | ||
876 | |||
877 | void mtof_tilde_setup(void) | ||
878 | { | ||
879 | mtof_tilde_class = class_new(gensym("mtof~"), (t_newmethod)mtof_tilde_new, 0, | ||
880 | sizeof(t_mtof_tilde), 0, 0); | ||
881 | CLASS_MAINSIGNALIN(mtof_tilde_class, t_mtof_tilde, x_f); | ||
882 | class_addmethod(mtof_tilde_class, (t_method)mtof_tilde_dsp, gensym("dsp"), 0); | ||
883 | } | ||
884 | |||
885 | /* ------------------------------ ftom_tilde~ -------------------------- */ | ||
886 | |||
887 | typedef struct ftom_tilde | ||
888 | { | ||
889 | t_object x_obj; | ||
890 | float x_f; | ||
891 | } t_ftom_tilde; | ||
892 | |||
893 | t_class *ftom_tilde_class; | ||
894 | |||
895 | static void *ftom_tilde_new(void) | ||
896 | { | ||
897 | t_ftom_tilde *x = (t_ftom_tilde *)pd_new(ftom_tilde_class); | ||
898 | outlet_new(&x->x_obj, gensym("signal")); | ||
899 | x->x_f = 0; | ||
900 | return (x); | ||
901 | } | ||
902 | |||
903 | static t_int *ftom_tilde_perform(t_int *w) | ||
904 | { | ||
905 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
906 | t_int n = *(t_int *)(w+3); | ||
907 | for (; n--; *in++, out++) | ||
908 | { | ||
909 | float f = *in; | ||
910 | *out = (f > 0 ? 17.3123405046 * log(.12231220585 * f) : -1500); | ||
911 | } | ||
912 | return (w + 4); | ||
913 | } | ||
914 | |||
915 | static void ftom_tilde_dsp(t_ftom_tilde *x, t_signal **sp) | ||
916 | { | ||
917 | dsp_add(ftom_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
918 | } | ||
919 | |||
920 | void ftom_tilde_setup(void) | ||
921 | { | ||
922 | ftom_tilde_class = class_new(gensym("ftom~"), (t_newmethod)ftom_tilde_new, 0, | ||
923 | sizeof(t_ftom_tilde), 0, 0); | ||
924 | CLASS_MAINSIGNALIN(ftom_tilde_class, t_ftom_tilde, x_f); | ||
925 | class_addmethod(ftom_tilde_class, (t_method)ftom_tilde_dsp, gensym("dsp"), 0); | ||
926 | } | ||
927 | |||
928 | /* ------------------------------ dbtorms~ -------------------------- */ | ||
929 | |||
930 | typedef struct dbtorms_tilde | ||
931 | { | ||
932 | t_object x_obj; | ||
933 | float x_f; | ||
934 | } t_dbtorms_tilde; | ||
935 | |||
936 | t_class *dbtorms_tilde_class; | ||
937 | |||
938 | static void *dbtorms_tilde_new(void) | ||
939 | { | ||
940 | t_dbtorms_tilde *x = (t_dbtorms_tilde *)pd_new(dbtorms_tilde_class); | ||
941 | outlet_new(&x->x_obj, gensym("signal")); | ||
942 | x->x_f = 0; | ||
943 | return (x); | ||
944 | } | ||
945 | |||
946 | static t_int *dbtorms_tilde_perform(t_int *w) | ||
947 | { | ||
948 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
949 | t_int n = *(t_int *)(w+3); | ||
950 | for (; n--; in++, out++) | ||
951 | { | ||
952 | float f = *in; | ||
953 | if (f <= 0) *out = 0; | ||
954 | else | ||
955 | { | ||
956 | if (f > 485) | ||
957 | f = 485; | ||
958 | *out = exp((LOGTEN * 0.05) * (f-100.)); | ||
959 | } | ||
960 | } | ||
961 | return (w + 4); | ||
962 | } | ||
963 | |||
964 | static void dbtorms_tilde_dsp(t_dbtorms_tilde *x, t_signal **sp) | ||
965 | { | ||
966 | dsp_add(dbtorms_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
967 | } | ||
968 | |||
969 | void dbtorms_tilde_setup(void) | ||
970 | { | ||
971 | dbtorms_tilde_class = class_new(gensym("dbtorms~"), (t_newmethod)dbtorms_tilde_new, 0, | ||
972 | sizeof(t_dbtorms_tilde), 0, 0); | ||
973 | CLASS_MAINSIGNALIN(dbtorms_tilde_class, t_dbtorms_tilde, x_f); | ||
974 | class_addmethod(dbtorms_tilde_class, (t_method)dbtorms_tilde_dsp, gensym("dsp"), 0); | ||
975 | } | ||
976 | |||
977 | /* ------------------------------ rmstodb~ -------------------------- */ | ||
978 | |||
979 | typedef struct rmstodb_tilde | ||
980 | { | ||
981 | t_object x_obj; | ||
982 | float x_f; | ||
983 | } t_rmstodb_tilde; | ||
984 | |||
985 | t_class *rmstodb_tilde_class; | ||
986 | |||
987 | static void *rmstodb_tilde_new(void) | ||
988 | { | ||
989 | t_rmstodb_tilde *x = (t_rmstodb_tilde *)pd_new(rmstodb_tilde_class); | ||
990 | outlet_new(&x->x_obj, gensym("signal")); | ||
991 | x->x_f = 0; | ||
992 | return (x); | ||
993 | } | ||
994 | |||
995 | static t_int *rmstodb_tilde_perform(t_int *w) | ||
996 | { | ||
997 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
998 | t_int n = *(t_int *)(w+3); | ||
999 | for (; n--; in++, out++) | ||
1000 | { | ||
1001 | float f = *in; | ||
1002 | if (f <= 0) *out = 0; | ||
1003 | else | ||
1004 | { | ||
1005 | float g = 100 + 20./LOGTEN * log(f); | ||
1006 | *out = (g < 0 ? 0 : g); | ||
1007 | } | ||
1008 | } | ||
1009 | return (w + 4); | ||
1010 | } | ||
1011 | |||
1012 | static void rmstodb_tilde_dsp(t_rmstodb_tilde *x, t_signal **sp) | ||
1013 | { | ||
1014 | dsp_add(rmstodb_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
1015 | } | ||
1016 | |||
1017 | void rmstodb_tilde_setup(void) | ||
1018 | { | ||
1019 | rmstodb_tilde_class = class_new(gensym("rmstodb~"), (t_newmethod)rmstodb_tilde_new, 0, | ||
1020 | sizeof(t_rmstodb_tilde), 0, 0); | ||
1021 | CLASS_MAINSIGNALIN(rmstodb_tilde_class, t_rmstodb_tilde, x_f); | ||
1022 | class_addmethod(rmstodb_tilde_class, (t_method)rmstodb_tilde_dsp, gensym("dsp"), 0); | ||
1023 | } | ||
1024 | |||
1025 | /* ------------------------------ dbtopow~ -------------------------- */ | ||
1026 | |||
1027 | typedef struct dbtopow_tilde | ||
1028 | { | ||
1029 | t_object x_obj; | ||
1030 | float x_f; | ||
1031 | } t_dbtopow_tilde; | ||
1032 | |||
1033 | t_class *dbtopow_tilde_class; | ||
1034 | |||
1035 | static void *dbtopow_tilde_new(void) | ||
1036 | { | ||
1037 | t_dbtopow_tilde *x = (t_dbtopow_tilde *)pd_new(dbtopow_tilde_class); | ||
1038 | outlet_new(&x->x_obj, gensym("signal")); | ||
1039 | x->x_f = 0; | ||
1040 | return (x); | ||
1041 | } | ||
1042 | |||
1043 | static t_int *dbtopow_tilde_perform(t_int *w) | ||
1044 | { | ||
1045 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
1046 | t_int n = *(t_int *)(w+3); | ||
1047 | for (; n--; in++, out++) | ||
1048 | { | ||
1049 | float f = *in; | ||
1050 | if (f <= 0) *out = 0; | ||
1051 | else | ||
1052 | { | ||
1053 | if (f > 870) | ||
1054 | f = 870; | ||
1055 | *out = exp((LOGTEN * 0.1) * (f-100.)); | ||
1056 | } | ||
1057 | } | ||
1058 | return (w + 4); | ||
1059 | } | ||
1060 | |||
1061 | static void dbtopow_tilde_dsp(t_dbtopow_tilde *x, t_signal **sp) | ||
1062 | { | ||
1063 | dsp_add(dbtopow_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
1064 | } | ||
1065 | |||
1066 | void dbtopow_tilde_setup(void) | ||
1067 | { | ||
1068 | dbtopow_tilde_class = class_new(gensym("dbtopow~"), (t_newmethod)dbtopow_tilde_new, 0, | ||
1069 | sizeof(t_dbtopow_tilde), 0, 0); | ||
1070 | CLASS_MAINSIGNALIN(dbtopow_tilde_class, t_dbtopow_tilde, x_f); | ||
1071 | class_addmethod(dbtopow_tilde_class, (t_method)dbtopow_tilde_dsp, gensym("dsp"), 0); | ||
1072 | } | ||
1073 | |||
1074 | /* ------------------------------ powtodb~ -------------------------- */ | ||
1075 | |||
1076 | typedef struct powtodb_tilde | ||
1077 | { | ||
1078 | t_object x_obj; | ||
1079 | float x_f; | ||
1080 | } t_powtodb_tilde; | ||
1081 | |||
1082 | t_class *powtodb_tilde_class; | ||
1083 | |||
1084 | static void *powtodb_tilde_new(void) | ||
1085 | { | ||
1086 | t_powtodb_tilde *x = (t_powtodb_tilde *)pd_new(powtodb_tilde_class); | ||
1087 | outlet_new(&x->x_obj, gensym("signal")); | ||
1088 | x->x_f = 0; | ||
1089 | return (x); | ||
1090 | } | ||
1091 | |||
1092 | static t_int *powtodb_tilde_perform(t_int *w) | ||
1093 | { | ||
1094 | float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); | ||
1095 | t_int n = *(t_int *)(w+3); | ||
1096 | for (; n--; in++, out++) | ||
1097 | { | ||
1098 | float f = *in; | ||
1099 | if (f <= 0) *out = 0; | ||
1100 | else | ||
1101 | { | ||
1102 | float g = 100 + 10./LOGTEN * log(f); | ||
1103 | *out = (g < 0 ? 0 : g); | ||
1104 | } | ||
1105 | } | ||
1106 | return (w + 4); | ||
1107 | } | ||
1108 | |||
1109 | static void powtodb_tilde_dsp(t_powtodb_tilde *x, t_signal **sp) | ||
1110 | { | ||
1111 | dsp_add(powtodb_tilde_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | ||
1112 | } | ||
1113 | |||
1114 | void powtodb_tilde_setup(void) | ||
1115 | { | ||
1116 | powtodb_tilde_class = class_new(gensym("powtodb~"), (t_newmethod)powtodb_tilde_new, 0, | ||
1117 | sizeof(t_powtodb_tilde), 0, 0); | ||
1118 | CLASS_MAINSIGNALIN(powtodb_tilde_class, t_powtodb_tilde, x_f); | ||
1119 | class_addmethod(powtodb_tilde_class, (t_method)powtodb_tilde_dsp, gensym("dsp"), 0); | ||
1120 | } | ||
1121 | |||
1122 | |||
1123 | /* ------------------------ global setup routine ------------------------- */ | ||
1124 | |||
1125 | void d_math_setup(void) | ||
1126 | { | ||
1127 | t_symbol *s = gensym("acoustics~.pd"); | ||
1128 | clip_setup(); | ||
1129 | sigrsqrt_setup(); | ||
1130 | sigsqrt_setup(); | ||
1131 | sigwrap_setup(); | ||
1132 | mtof_tilde_setup(); | ||
1133 | ftom_tilde_setup(); | ||
1134 | dbtorms_tilde_setup(); | ||
1135 | rmstodb_tilde_setup(); | ||
1136 | dbtopow_tilde_setup(); | ||
1137 | powtodb_tilde_setup(); | ||
1138 | |||
1139 | class_sethelpsymbol(mtof_tilde_class, s); | ||
1140 | class_sethelpsymbol(ftom_tilde_class, s); | ||
1141 | class_sethelpsymbol(dbtorms_tilde_class, s); | ||
1142 | class_sethelpsymbol(rmstodb_tilde_class, s); | ||
1143 | class_sethelpsymbol(dbtopow_tilde_class, s); | ||
1144 | class_sethelpsymbol(powtodb_tilde_class, s); | ||
1145 | } | ||
1146 | |||