4 /* sigrsqrt - reciprocal square root good to 8 mantissa bits */
6 #define DUMTAB1SIZE 256
7 #define DUMTAB2SIZE 1024
9 static float rsqrt_exptab
[DUMTAB1SIZE
], rsqrt_mantissatab
[DUMTAB2SIZE
];
11 static void init_rsqrt(void)
14 for (i
= 0; i
< DUMTAB1SIZE
; i
++)
17 long l
= (i
? (i
== DUMTAB1SIZE
-1 ? DUMTAB1SIZE
-2 : i
) : 1)<< 23;
19 rsqrt_exptab
[i
] = 1./sqrt(f
);
21 for (i
= 0; i
< DUMTAB2SIZE
; i
++)
23 float f
= 1 + (1./DUMTAB2SIZE
) * i
;
24 rsqrt_mantissatab
[i
] = 1./sqrt(f
);
28 /* these are used in externs like "bonk" */
30 float q8_rsqrt(float f
)
32 long l
= *(long *)(&f
);
33 if (f
< 0) return (0);
34 else return (rsqrt_exptab
[(l
>> 23) & 0xff] *
35 rsqrt_mantissatab
[(l
>> 13) & 0x3ff]);
38 float q8_sqrt(float f
)
40 long l
= *(long *)(&f
);
41 if (f
< 0) return (0);
42 else return (f
* rsqrt_exptab
[(l
>> 23) & 0xff] *
43 rsqrt_mantissatab
[(l
>> 13) & 0x3ff]);
46 /* the old names are OK unless we're in IRIX N32 */
49 float qsqrt(float f
) {return (q8_sqrt(f
)); }
50 float qrsqrt(float f
) {return (q8_rsqrt(f
)); }
55 typedef struct sigrsqrt
61 static t_class
*sigrsqrt_class
;
63 static void *sigrsqrt_new(void)
65 t_sigrsqrt
*x
= (t_sigrsqrt
*)pd_new(sigrsqrt_class
);
66 outlet_new(&x
->x_obj
, gensym("signal"));
71 static t_int
*sigrsqrt_perform(t_int
*w
)
73 float *in
= *(t_float
**)(w
+1), *out
= *(t_float
**)(w
+2);
74 t_int n
= *(t_int
*)(w
+3);
78 long l
= *(long *)(in
++);
79 if (f
< 0) *out
++ = 0;
82 float g
= rsqrt_exptab
[(l
>> 23) & 0xff] *
83 rsqrt_mantissatab
[(l
>> 13) & 0x3ff];
84 *out
++ = 1.5 * g
- 0.5 * g
* g
* g
* f
;
90 static void sigrsqrt_dsp(t_sigrsqrt
*x
, t_signal
**sp
)
92 dsp_add(sigrsqrt_perform
, 3, sp
[0]->s_vec
, sp
[1]->s_vec
, sp
[0]->s_n
);
95 void rsqrt_tilde_setup(void)
98 sigrsqrt_class
= class_new(gensym("rsqrt~"), (t_newmethod
)sigrsqrt_new
, 0,
99 sizeof(t_sigrsqrt
), 0, 0);
100 /* an old name for it: */
101 class_addcreator(sigrsqrt_new
, gensym("q8_rsqrt~"), 0);
102 CLASS_MAINSIGNALIN(sigrsqrt_class
, t_sigrsqrt
, x_f
);
103 class_addmethod(sigrsqrt_class
, (t_method
)sigrsqrt_dsp
, gensym("dsp"), 0);
109 /* sigrsqrt - reciprocal square root good to 8 mantissa bits */
111 #define DUMTAB1SIZE 256
112 #define DUMTAB2SIZE 1024
114 static float rsqrt_exptab
[DUMTAB1SIZE
], rsqrt_mantissatab
[DUMTAB2SIZE
];
116 static void init_rsqrt(void)
119 for (i
= 0; i
< DUMTAB1SIZE
; i
++)
122 long l
= (i
? (i
== DUMTAB1SIZE
-1 ? DUMTAB1SIZE
-2 : i
) : 1)<< 23;
124 rsqrt_exptab
[i
] = 1./sqrt(f
);
126 for (i
= 0; i
< DUMTAB2SIZE
; i
++)
128 float f
= 1 + (1./DUMTAB2SIZE
) * i
;
129 rsqrt_mantissatab
[i
] = 1./sqrt(f
);
133 /* these are used in externs like "bonk" */
135 float q8_rsqrt(float f
)
137 long l
= *(long *)(&f
);
138 if (f
< 0) return (0);
139 else return (rsqrt_exptab
[(l
>> 23) & 0xff] *
140 rsqrt_mantissatab
[(l
>> 13) & 0x3ff]);
143 float q8_sqrt(float f
)
145 long l
= *(long *)(&f
);
146 if (f
< 0) return (0);
147 else return (f
* rsqrt_exptab
[(l
>> 23) & 0xff] *
148 rsqrt_mantissatab
[(l
>> 13) & 0x3ff]);
151 /* the old names are OK unless we're in IRIX N32 */
154 float qsqrt(float f
) {return (q8_sqrt(f
)); }
155 float qrsqrt(float f
) {return (q8_rsqrt(f
)); }
160 typedef struct sigrsqrt
166 static t_class
*sigrsqrt_class
;
168 static void *sigrsqrt_new(void)
170 t_sigrsqrt
*x
= (t_sigrsqrt
*)pd_new(sigrsqrt_class
);
171 outlet_new(&x
->x_obj
, gensym("signal"));
176 static t_int
*sigrsqrt_perform(t_int
*w
)
178 float *in
= *(t_float
**)(w
+1), *out
= *(t_float
**)(w
+2);
179 t_int n
= *(t_int
*)(w
+3);
183 long l
= *(long *)(in
++);
184 if (f
< 0) *out
++ = 0;
187 float g
= rsqrt_exptab
[(l
>> 23) & 0xff] *
188 rsqrt_mantissatab
[(l
>> 13) & 0x3ff];
189 *out
++ = 1.5 * g
- 0.5 * g
* g
* g
* f
;
195 static void sigrsqrt_dsp(t_sigrsqrt
*x
, t_signal
**sp
)
197 dsp_add(sigrsqrt_perform
, 3, sp
[0]->s_vec
, sp
[1]->s_vec
, sp
[0]->s_n
);
200 void rsqrt_tilde_setup(void)
203 sigrsqrt_class
= class_new(gensym("rsqrt~"), (t_newmethod
)sigrsqrt_new
, 0,
204 sizeof(t_sigrsqrt
), 0, 0);
205 /* an old name for it: */
206 class_addcreator(sigrsqrt_new
, gensym("q8_rsqrt~"), 0);
207 CLASS_MAINSIGNALIN(sigrsqrt_class
, t_sigrsqrt
, x_f
);
208 class_addmethod(sigrsqrt_class
, (t_method
)sigrsqrt_dsp
, gensym("dsp"), 0);