Fix some greedy sed changes in imported code. Also provide a sys/types.h for compatib...
[kugel-rb.git] / apps / plugins / pdbox / PDa / src / d_fft.c
blob6e2713a960d0f725cca5b7395ff2327fe210c5cf
1 /* Copyright (c) 1997-1999 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. */
5 #include "m_pd.h"
7 /* ------------------------ fft~ and ifft~ -------------------------------- */
8 static t_class *sigfft_class, *sigifft_class;
10 typedef struct fft
12 t_object x_obj;
13 float x_f;
14 } t_sigfft;
16 static void *sigfft_new(void)
18 t_sigfft *x = (t_sigfft *)pd_new(sigfft_class);
19 outlet_new(&x->x_obj, gensym("signal"));
20 outlet_new(&x->x_obj, gensym("signal"));
21 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
22 x->x_f = 0;
23 return (x);
26 static void *sigifft_new(void)
28 t_sigfft *x = (t_sigfft *)pd_new(sigifft_class);
29 outlet_new(&x->x_obj, gensym("signal"));
30 outlet_new(&x->x_obj, gensym("signal"));
31 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
32 x->x_f = 0;
33 return (x);
36 static t_int *sigfft_swap(t_int *w)
38 t_sample *in1 = (t_sample *)(w[1]);
39 t_sample *in2 = (t_sample *)(w[2]);
40 int n = w[3];
41 for (;n--; in1++, in2++)
43 float f = *in1;
44 *in1 = *in2;
45 *in2 = f;
47 return (w+4);
50 static t_int *sigfft_perform(t_int *w)
52 t_sample *in1 = (t_sample *)(w[1]);
53 t_sample *in2 = (t_sample *)(w[2]);
54 int n = w[3];
55 mayer_fft(n, in1, in2);
56 return (w+4);
59 static t_int *sigifft_perform(t_int *w)
61 t_sample *in1 = (t_sample *)(w[1]);
62 t_sample *in2 = (t_sample *)(w[2]);
63 int n = w[3];
64 mayer_ifft(n, in1, in2);
65 return (w+4);
68 static void sigfft_dspx(t_sigfft *x, t_signal **sp, t_int *(*f)(t_int *w))
70 #ifdef ROCKBOX
71 (void) x;
72 #endif
73 int n = sp[0]->s_n;
74 t_sample *in1 = sp[0]->s_vec;
75 t_sample *in2 = sp[1]->s_vec;
76 t_sample *out1 = sp[2]->s_vec;
77 t_sample *out2 = sp[3]->s_vec;
78 if (out1 == in2 && out2 == in1)
79 dsp_add(sigfft_swap, 3, out1, out2, n);
80 else if (out1 == in2)
82 dsp_add(copy_perform, 3, in2, out2, n);
83 dsp_add(copy_perform, 3, in1, out1, n);
85 else
87 if (out1 != in1) dsp_add(copy_perform, 3, in1, out1, n);
88 if (out2 != in2) dsp_add(copy_perform, 3, in2, out2, n);
90 dsp_add(f, 3, sp[2]->s_vec, sp[3]->s_vec, n);
93 static void sigfft_dsp(t_sigfft *x, t_signal **sp)
95 sigfft_dspx(x, sp, sigfft_perform);
98 static void sigifft_dsp(t_sigfft *x, t_signal **sp)
100 sigfft_dspx(x, sp, sigifft_perform);
103 static void sigfft_setup(void)
105 sigfft_class = class_new(gensym("fft~"), sigfft_new, 0,
106 sizeof(t_sigfft), 0, 0);
107 CLASS_MAINSIGNALIN(sigfft_class, t_sigfft, x_f);
108 class_addmethod(sigfft_class, (t_method)sigfft_dsp, gensym("dsp"), 0);
110 sigifft_class = class_new(gensym("ifft~"), sigifft_new, 0,
111 sizeof(t_sigfft), 0, 0);
112 CLASS_MAINSIGNALIN(sigifft_class, t_sigfft, x_f);
113 class_addmethod(sigifft_class, (t_method)sigifft_dsp, gensym("dsp"), 0);
114 class_sethelpsymbol(sigifft_class, gensym("fft~"));
117 /* ----------------------- rfft~ -------------------------------- */
119 static t_class *sigrfft_class;
121 typedef struct rfft
123 t_object x_obj;
124 float x_f;
125 } t_sigrfft;
127 static void *sigrfft_new(void)
129 t_sigrfft *x = (t_sigrfft *)pd_new(sigrfft_class);
130 outlet_new(&x->x_obj, gensym("signal"));
131 outlet_new(&x->x_obj, gensym("signal"));
132 x->x_f = 0;
133 return (x);
136 static t_int *sigrfft_flip(t_int *w)
138 t_sample *in = (t_sample *)(w[1]);
139 t_sample *out = (t_sample *)(w[2]);
140 int n = w[3];
141 while (n--) *(--out) = *in++;
142 *(--out) = 0; /* to hell with it */
143 return (w+4);
146 static t_int *sigrfft_perform(t_int *w)
148 t_sample *in = (t_sample *)(w[1]);
149 int n = w[2];
150 mayer_realfft(n, in);
151 return (w+3);
154 static void sigrfft_dsp(t_sigrfft *x, t_signal **sp)
156 #ifdef ROCKBOX
157 (void) x;
158 #endif
159 int n = sp[0]->s_n, n2 = (n>>1);
160 t_sample *in1 = sp[0]->s_vec;
161 t_sample *out1 = sp[1]->s_vec;
162 t_sample *out2 = sp[2]->s_vec;
163 if (n < 4)
165 error("fft: minimum 4 points");
166 return;
168 if (in1 == out2) /* this probably never happens */
170 dsp_add(sigrfft_perform, 2, out2, n);
171 dsp_add(copy_perform, 3, out2, out1, n2);
172 dsp_add(sigrfft_flip, 3, out2 + (n2+1), out2 + n2, n2-1);
174 else
176 if (in1 != out1) dsp_add(copy_perform, 3, in1, out1, n);
177 dsp_add(sigrfft_perform, 2, out1, n);
178 dsp_add(sigrfft_flip, 3, out1 + (n2+1), out2 + n2, n2-1);
180 dsp_add_zero(out1 + n2, n2);
181 dsp_add_zero(out2 + n2, n2);
184 static void sigrfft_setup(void)
186 sigrfft_class = class_new(gensym("rfft~"), sigrfft_new, 0,
187 sizeof(t_sigrfft), 0, 0);
188 CLASS_MAINSIGNALIN(sigrfft_class, t_sigrfft, x_f);
189 class_addmethod(sigrfft_class, (t_method)sigrfft_dsp, gensym("dsp"), 0);
190 class_sethelpsymbol(sigrfft_class, gensym("fft~"));
193 /* ----------------------- rifft~ -------------------------------- */
195 static t_class *sigrifft_class;
197 typedef struct rifft
199 t_object x_obj;
200 float x_f;
201 } t_sigrifft;
203 static void *sigrifft_new(void)
205 t_sigrifft *x = (t_sigrifft *)pd_new(sigrifft_class);
206 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
207 outlet_new(&x->x_obj, gensym("signal"));
208 x->x_f = 0;
209 return (x);
212 static t_int *sigrifft_perform(t_int *w)
214 t_sample *in = (t_sample *)(w[1]);
215 int n = w[2];
216 mayer_realifft(n, in);
217 return (w+3);
220 static void sigrifft_dsp(t_sigrifft *x, t_signal **sp)
222 #ifdef ROCKBOX
223 (void) x;
224 #endif
225 int n = sp[0]->s_n, n2 = (n>>1);
226 t_sample *in1 = sp[0]->s_vec;
227 t_sample *in2 = sp[1]->s_vec;
228 t_sample *out1 = sp[2]->s_vec;
229 if (n < 4)
231 error("fft: minimum 4 points");
232 return;
234 if (in2 == out1)
236 dsp_add(sigrfft_flip, 3, out1+1, out1 + n, (n2-1));
237 dsp_add(copy_perform, 3, in1, out1, n2);
239 else
241 if (in1 != out1) dsp_add(copy_perform, 3, in1, out1, n2);
242 dsp_add(sigrfft_flip, 3, in2+1, out1 + n, n2-1);
244 dsp_add(sigrifft_perform, 2, out1, n);
247 static void sigrifft_setup(void)
249 sigrifft_class = class_new(gensym("rifft~"), sigrifft_new, 0,
250 sizeof(t_sigrifft), 0, 0);
251 CLASS_MAINSIGNALIN(sigrifft_class, t_sigrifft, x_f);
252 class_addmethod(sigrifft_class, (t_method)sigrifft_dsp, gensym("dsp"), 0);
253 class_sethelpsymbol(sigrifft_class, gensym("fft~"));
256 /* ----------------------- framp~ -------------------------------- */
258 #if 0
259 static t_class *sigframp_class;
261 typedef struct framp
263 t_object x_obj;
264 float x_f;
265 } t_sigframp;
267 static void *sigframp_new(void)
269 t_sigframp *x = (t_sigframp *)pd_new(sigframp_class);
270 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
271 outlet_new(&x->x_obj, gensym("signal"));
272 outlet_new(&x->x_obj, gensym("signal"));
273 x->x_f = 0;
274 return (x);
277 static t_int *sigframp_perform(t_int *w)
279 float *inreal = (t_float *)(w[1]);
280 float *inimag = (t_float *)(w[2]);
281 float *outfreq = (t_float *)(w[3]);
282 float *outamp = (t_float *)(w[4]);
283 float lastreal = 0, currentreal = inreal[0], nextreal = inreal[1];
284 float lastimag = 0, currentimag = inimag[0], nextimag = inimag[1];
285 int n = w[5];
286 int m = n + 1;
287 float fbin = 1, oneovern2 = 1.f/((float)n * (float)n);
289 inreal += 2;
290 inimag += 2;
291 *outamp++ = *outfreq++ = 0;
292 n -= 2;
293 while (n--)
295 float re, im, pow, freq;
296 lastreal = currentreal;
297 currentreal = nextreal;
298 nextreal = *inreal++;
299 lastimag = currentimag;
300 currentimag = nextimag;
301 nextimag = *inimag++;
302 re = currentreal - 0.5f * (lastreal + nextreal);
303 im = currentimag - 0.5f * (lastimag + nextimag);
304 pow = re * re + im * im;
305 if (pow > 1e-19)
307 float detune = ((lastreal - nextreal) * re +
308 (lastimag - nextimag) * im) / (2.0f * pow);
309 if (detune > 2 || detune < -2) freq = pow = 0;
310 else freq = fbin + detune;
312 else freq = pow = 0;
313 *outfreq++ = freq;
314 *outamp++ = oneovern2 * pow;
315 fbin += 1.0f;
317 while (m--) *outamp++ = *outfreq++ = 0;
318 return (w+6);
321 t_int *sigsqrt_perform(t_int *w);
323 static void sigframp_dsp(t_sigframp *x, t_signal **sp)
325 int n = sp[0]->s_n, n2 = (n>>1);
326 if (n < 4)
328 error("framp: minimum 4 points");
329 return;
331 dsp_add(sigframp_perform, 5, sp[0]->s_vec, sp[1]->s_vec,
332 sp[2]->s_vec, sp[3]->s_vec, n2);
333 dsp_add(sigsqrt_perform, 3, sp[3]->s_vec, sp[3]->s_vec, n2);
336 static void sigframp_setup(void)
338 sigframp_class = class_new(gensym("framp~"), sigframp_new, 0,
339 sizeof(t_sigframp), 0, 0);
340 CLASS_MAINSIGNALIN(sigframp_class, t_sigframp, x_f);
341 class_addmethod(sigframp_class, (t_method)sigframp_dsp, gensym("dsp"), 0);
343 #endif
345 /* ------------------------ global setup routine ------------------------- */
347 void d_fft_setup(void)
349 sigfft_setup();
350 sigrfft_setup();
351 sigrifft_setup();
352 // sigframp_setup();