3 #include "../../pdbox.h"
6 #include "../src/m_pd.h"
7 #include <../src/m_fixed.h>
9 /* sigrsqrt - reciprocal square root good to 8 mantissa bits */
11 #define DUMTAB1SIZE 256
12 #define DUMTAB2SIZE 1024
14 static float rsqrt_exptab
[DUMTAB1SIZE
], rsqrt_mantissatab
[DUMTAB2SIZE
];
16 static void init_rsqrt(void)
19 for (i
= 0; i
< DUMTAB1SIZE
; i
++)
23 f2i
.i
= (i
? (i
== DUMTAB1SIZE
-1 ? DUMTAB1SIZE
-2 : i
) : 1)<< 23;
24 rsqrt_exptab
[i
] = 1./sqrt(f2i
.f
);
27 long l
= (i
? (i
== DUMTAB1SIZE
-1 ? DUMTAB1SIZE
-2 : i
) : 1)<< 23;
29 rsqrt_exptab
[i
] = 1./sqrt(f
);
32 for (i
= 0; i
< DUMTAB2SIZE
; i
++)
34 float f
= 1 + (1./DUMTAB2SIZE
) * i
;
35 rsqrt_mantissatab
[i
] = 1./sqrt(f
);
39 /* these are used in externs like "bonk" */
41 float q8_rsqrt(float f
)
50 return (rsqrt_exptab
[(f2i
.i
>> 23) & 0xff] *
51 rsqrt_mantissatab
[(f2i
.i
>> 13) & 0x3ff]);
54 long l
= *(long *)(&f
);
55 if (f
< 0) return (0);
56 else return (rsqrt_exptab
[(l
>> 23) & 0xff] *
57 rsqrt_mantissatab
[(l
>> 13) & 0x3ff]);
61 float q8_sqrt(float f
)
70 return (f
* rsqrt_exptab
[(f2i
.i
>> 23) & 0xff] *
71 rsqrt_mantissatab
[(f2i
.i
>> 13) & 0x3ff]);
74 long l
= *(long *)(&f
);
75 if (f
< 0) return (0);
76 else return (f
* rsqrt_exptab
[(l
>> 23) & 0xff] *
77 rsqrt_mantissatab
[(l
>> 13) & 0x3ff]);
81 /* the old names are OK unless we're in IRIX N32 */
84 float qsqrt(float f
) {return (q8_sqrt(f
)); }
85 float qrsqrt(float f
) {return (q8_rsqrt(f
)); }
90 typedef struct sigrsqrt
96 static t_class
*sigrsqrt_class
;
98 static void *sigrsqrt_new(void)
100 t_sigrsqrt
*x
= (t_sigrsqrt
*)pd_new(sigrsqrt_class
);
101 outlet_new(&x
->x_obj
, gensym("signal"));
106 static t_int
*sigrsqrt_perform(t_int
*w
)
108 float *in
= *(t_float
**)(w
+1), *out
= *(t_float
**)(w
+2);
109 t_int n
= *(t_int
*)(w
+3);
113 long l
= *(long *)(in
++);
114 if (f
< 0) *out
++ = 0;
117 float g
= rsqrt_exptab
[(l
>> 23) & 0xff] *
118 rsqrt_mantissatab
[(l
>> 13) & 0x3ff];
119 *out
++ = 1.5 * g
- 0.5 * g
* g
* g
* f
;
125 static void sigrsqrt_dsp(t_sigrsqrt
*x
, t_signal
**sp
)
130 dsp_add(sigrsqrt_perform
, 3, sp
[0]->s_vec
, sp
[1]->s_vec
, sp
[0]->s_n
);
133 void rsqrt_tilde_setup(void)
136 sigrsqrt_class
= class_new(gensym("rsqrt~"), (t_newmethod
)sigrsqrt_new
, 0,
137 sizeof(t_sigrsqrt
), 0, 0);
138 /* an old name for it: */
139 class_addcreator(sigrsqrt_new
, gensym("q8_rsqrt~"), 0);
140 CLASS_MAINSIGNALIN(sigrsqrt_class
, t_sigrsqrt
, x_f
);
141 class_addmethod(sigrsqrt_class
, (t_method
)sigrsqrt_dsp
, gensym("dsp"), 0);