From 76fd8bc21e49036a8187e7a6b75c36daa842cbc6 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 31 Dec 2010 03:00:34 +0000 Subject: refactored d_fft.c and d_math.c into separate objectclases svn path=/trunk/; revision=14683 --- externals/vanilla/Makefile | 4 +- externals/vanilla/TODO | 6 -- externals/vanilla/e_gfxstub.c | 174 ----------------------------------------- externals/vanilla/e_sqrt.c | 32 -------- externals/vanilla/e_sqrt.h | 22 ------ externals/vanilla/fft~.c | 47 +++++++++++ externals/vanilla/framp~.c | 97 +++++++++++++++++++++++ externals/vanilla/ifft~.c | 48 ++++++++++++ externals/vanilla/lib_d_fft.c | 7 -- externals/vanilla/lib_d_math.c | 5 -- externals/vanilla/rfft~.c | 68 ++++++++++++++++ externals/vanilla/rifft~.c | 71 +++++++++++++++++ externals/vanilla/rsqrt~.c | 2 - externals/vanilla/sqrt~.c | 21 ----- 14 files changed, 333 insertions(+), 271 deletions(-) delete mode 100644 externals/vanilla/e_gfxstub.c delete mode 100644 externals/vanilla/e_sqrt.c delete mode 100644 externals/vanilla/e_sqrt.h create mode 100644 externals/vanilla/fft~.c create mode 100644 externals/vanilla/framp~.c create mode 100644 externals/vanilla/ifft~.c delete mode 100644 externals/vanilla/lib_d_fft.c delete mode 100644 externals/vanilla/lib_d_math.c create mode 100644 externals/vanilla/rfft~.c create mode 100644 externals/vanilla/rifft~.c (limited to 'externals/vanilla') diff --git a/externals/vanilla/Makefile b/externals/vanilla/Makefile index a812a00d..2ebfa500 100644 --- a/externals/vanilla/Makefile +++ b/externals/vanilla/Makefile @@ -5,7 +5,7 @@ LIBRARY_NAME = vanilla # add your .c source files, one object per file, to the SOURCES # variable, help files will be included automatically -SOURCES = abs~.c bng.c clip~.c cnv.c dbtopow~.c dbtorms~.c del.c delay.c exp~.c ftom~.c hdl.c hradio.c hsl.c hslider.c key.c keyname.c keyup.c line.c list.c log~.c metro.c mtof~.c my_canvas.c my_numbox.c nbx.c netsend.c netreceive.c openpanel.c pipe.c powtodb~.c pow~.c print.c qlist.c radiobut.c radiobutton.c rdb.c rmstodb~.c rsqrt~.c savepanel.c sqrt~.c textfile.c tgl.c timer.c toggle.c vdl.c vradio.c vsl.c vslider.c vu.c wrap~.c random.c loadbang.c namecanvas.c cputime.c realtime.c bang~.c print~.c adc~.c dac~.c delread~.c delwrite~.c vd~.c +SOURCES = abs~.c adc~.c bang~.c bng.c clip~.c cnv.c cputime.c dac~.c dbtopow~.c dbtorms~.c del.c delay.c delread~.c delwrite~.c exp~.c fft~.c framp~.c ftom~.c hdl.c hradio.c hsl.c hslider.c ifft~.c key.c keyname.c keyup.c line.c list.c loadbang.c log~.c metro.c mtof~.c my_canvas.c my_numbox.c namecanvas.c nbx.c netreceive.c netsend.c openpanel.c pipe.c powtodb~.c pow~.c print.c print~.c qlist.c radiobut.c radiobutton.c random.c rdb.c realtime.c rfft~.c rifft~.c rmstodb~.c rsqrt~.c savepanel.c sqrt~.c textfile.c tgl.c timer.c toggle.c vdl.c vd~.c vradio.c vsl.c vslider.c vu.c wrap~.c # list all pd objects (i.e. myobject.pd) files here, and their helpfiles will # be included automatically @@ -34,7 +34,7 @@ HELPPATCHES = abs~-help.pd adc~_dac~-help.pd bang~-help.pd bng-help.pd clip~-hel #------------------------------------------------------------------------------# # -I"$(PD_INCLUDE)/pd" supports the header location for 0.43 -CFLAGS = -I"$(PD_INCLUDE)/pd" -Wall -W -g +CFLAGS = -I"$(PD_INCLUDE)" -Wall -W -g LDFLAGS = LIBS = diff --git a/externals/vanilla/TODO b/externals/vanilla/TODO index f9a86be5..f31275dd 100644 --- a/externals/vanilla/TODO +++ b/externals/vanilla/TODO @@ -2,12 +2,6 @@ - figure out how Pd-extended is going to load this stuff in order to maintain maximum capatibility -- replace pd-extended's x_gui.c with this e_gfxstub.c - -- replace pd-extended's d_math.c with this e_sqrt.c - -- move this d_math.h to pd-extended's pd/src - - move relevant help patches from pd-extended's pd/doc/5.reference to here - move relevent help patches from doc/pddp to here diff --git a/externals/vanilla/e_gfxstub.c b/externals/vanilla/e_gfxstub.c deleted file mode 100644 index e3321ec9..00000000 --- a/externals/vanilla/e_gfxstub.c +++ /dev/null @@ -1,174 +0,0 @@ -/* Copyright (c) 1997-2000 Miller Puckette. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* gfxstub stuff from pd-vanilla's x_gui.c */ - -/* dialogs. LATER, deal with the situation where the object goes -away before the panel does... */ - -#include "m_pd.h" -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif - -/* --------------------- graphics responder ---------------- */ - -/* make one of these if you want to put up a dialog window but want to be -protected from getting deleted and then having the dialog call you back. In -this design the calling object doesn't have to keep the address of the dialog -window around; instead we keep a list of all open dialogs. Any object that -might have dialogs, when it is deleted, simply checks down the dialog window -list and breaks off any dialogs that might later have sent messages to it. -Only when the dialog window itself closes do we delete the gfxstub object. */ - -static t_class *gfxstub_class; - -typedef struct _gfxstub -{ - t_pd x_pd; - t_pd *x_owner; - void *x_key; - t_symbol *x_sym; - struct _gfxstub *x_next; -} t_gfxstub; - -static t_gfxstub *gfxstub_list; - - /* create a new one. the "key" is an address by which the owner - will identify it later; if the owner only wants one dialog, this - could just be a pointer to the owner itself. The string "cmd" - is a TK command to create the dialog, with "%s" embedded in - it so we can provide a name by which the GUI can send us back - messages; e.g., "pdtk_canvas_dofont %s 10". */ - -void gfxstub_new(t_pd *owner, void *key, const char *cmd) -{ - char buf[4*MAXPDSTRING]; - char namebuf[80]; - t_gfxstub *x; - t_symbol *s; - /* if any exists with matching key, burn it. */ - for (x = gfxstub_list; x; x = x->x_next) - if (x->x_key == key) - gfxstub_deleteforkey(key); - if (strlen(cmd) + 50 > 4*MAXPDSTRING) - { - bug("audio dialog too long"); - bug("%x", cmd); - return; - } - x = (t_gfxstub *)pd_new(gfxstub_class); - sprintf(namebuf, ".gfxstub%lx", (t_int)x); - - s = gensym(namebuf); - pd_bind(&x->x_pd, s); - x->x_owner = owner; - x->x_sym = s; - x->x_key = key; - x->x_next = gfxstub_list; - gfxstub_list = x; - sprintf(buf, cmd, s->s_name); - sys_gui(buf); -} - -static void gfxstub_offlist(t_gfxstub *x) -{ - t_gfxstub *y1, *y2; - if (gfxstub_list == x) - gfxstub_list = x->x_next; - else for (y1 = gfxstub_list; y2 = y1->x_next; y1 = y2) - if (y2 == x) - { - y1->x_next = y2->x_next; - break; - } -} - - /* if the owner disappears, we still may have to stay around until our - dialog window signs off. Anyway we can now tell the GUI to destroy the - window. */ -void gfxstub_deleteforkey(void *key) -{ - t_gfxstub *y; - int didit = 1; - while (didit) - { - didit = 0; - for (y = gfxstub_list; y; y = y->x_next) - { - if (y->x_key == key) - { - sys_vgui("destroy .gfxstub%lx\n", y); - y->x_owner = 0; - gfxstub_offlist(y); - didit = 1; - break; - } - } - } -} - -/* --------- pd messages for gfxstub (these come from the GUI) ---------- */ - - /* "cancel" to request that we close the dialog window. */ -static void gfxstub_cancel(t_gfxstub *x) -{ - gfxstub_deleteforkey(x->x_key); -} - - /* "signoff" comes from the GUI to say the dialog window closed. */ -static void gfxstub_signoff(t_gfxstub *x) -{ - gfxstub_offlist(x); - pd_free(&x->x_pd); -} - -static t_binbuf *gfxstub_binbuf; - - /* a series of "data" messages rebuilds a scalar */ -static void gfxstub_data(t_gfxstub *x, t_symbol *s, int argc, t_atom *argv) -{ - if (!gfxstub_binbuf) - gfxstub_binbuf = binbuf_new(); - binbuf_add(gfxstub_binbuf, argc, argv); - binbuf_addsemi(gfxstub_binbuf); -} - /* the "end" message terminates rebuilding the scalar */ -static void gfxstub_end(t_gfxstub *x) -{ - canvas_dataproperties((t_canvas *)x->x_owner, - (t_scalar *)x->x_key, gfxstub_binbuf); - binbuf_free(gfxstub_binbuf); - gfxstub_binbuf = 0; -} - - /* anything else is a message from the dialog window to the owner; - just forward it. */ -static void gfxstub_anything(t_gfxstub *x, t_symbol *s, int argc, t_atom *argv) -{ - if (x->x_owner) - pd_typedmess(x->x_owner, s, argc, argv); -} - -static void gfxstub_free(t_gfxstub *x) -{ - pd_unbind(&x->x_pd, x->x_sym); -} - -static void gfxstub_setup(void) -{ - gfxstub_class = class_new(gensym("gfxstub"), 0, (t_method)gfxstub_free, - sizeof(t_gfxstub), CLASS_PD, 0); - class_addanything(gfxstub_class, gfxstub_anything); - class_addmethod(gfxstub_class, (t_method)gfxstub_signoff, - gensym("signoff"), 0); - class_addmethod(gfxstub_class, (t_method)gfxstub_data, - gensym("data"), A_GIMME, 0); - class_addmethod(gfxstub_class, (t_method)gfxstub_end, - gensym("end"), 0); - class_addmethod(gfxstub_class, (t_method)gfxstub_cancel, - gensym("cancel"), 0); -} diff --git a/externals/vanilla/e_sqrt.c b/externals/vanilla/e_sqrt.c deleted file mode 100644 index eb011a4a..00000000 --- a/externals/vanilla/e_sqrt.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (c) 1997-2001 Miller Puckette and others. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* sqrt-related functions from pd-vanilla's d_math.c */ - -#include "e_sqrt.h" - - /* these are used in externs like "bonk" */ - -t_float q8_rsqrt(t_float f) -{ - long l = *(long *)(&f); - if (f < 0) return (0); - else return (rsqrt_exptab[(l >> 23) & 0xff] * - rsqrt_mantissatab[(l >> 13) & 0x3ff]); -} - -t_float q8_sqrt(t_float f) -{ - long l = *(long *)(&f); - if (f < 0) return (0); - else return (f * rsqrt_exptab[(l >> 23) & 0xff] * - rsqrt_mantissatab[(l >> 13) & 0x3ff]); -} - - /* the old names are OK unless we're in IRIX N32 */ - -#ifndef N32 -t_float qsqrt(t_float f) {return (q8_sqrt(f)); } -t_float qrsqrt(t_float f) {return (q8_rsqrt(f)); } -#endif diff --git a/externals/vanilla/e_sqrt.h b/externals/vanilla/e_sqrt.h deleted file mode 100644 index 209ef02f..00000000 --- a/externals/vanilla/e_sqrt.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright (c) 1997-2001 Miller Puckette and others. -* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ - -/* these are things used in a number of objectclasses from e_sqrt.c */ - -#include "m_pd.h" -#include - -#define LOGTEN 2.302585092994 -#define DUMTAB1SIZE 256 -#define DUMTAB2SIZE 1024 - -#ifdef _WIN32 -#define int32 long -#else -#include -#define int32 int32_t -#endif - -t_float q8_sqrt(t_float f); -t_float q8_rsqrt(t_float f); diff --git a/externals/vanilla/fft~.c b/externals/vanilla/fft~.c new file mode 100644 index 00000000..246c0584 --- /dev/null +++ b/externals/vanilla/fft~.c @@ -0,0 +1,47 @@ +/* Copyright (c) 1997- Miller Puckette and others. +* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#include "m_pd.h" +#include "e_fft.h" + +/* This file interfaces to one of the Mayer, Ooura, or fftw FFT packages +to implement the "fft~", etc, Pd objects. If using Mayer, also compile +d_fft_mayer.c; if ooura, use d_fft_fftsg.c instead; if fftw, use d_fft_fftw.c +and also link in the fftw library. You can only have one of these three +linked in. The configure script can be used to select which one. +*/ + +static t_class *sigfft_class; + +static void *sigfft_new(void) +{ + t_sigfft *x = (t_sigfft *)pd_new(sigfft_class); + outlet_new(&x->x_obj, gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + x->x_f = 0; + return (x); +} + +static t_int *sigfft_perform(t_int *w) +{ + t_sample *in1 = (t_sample *)(w[1]); + t_sample *in2 = (t_sample *)(w[2]); + int n = w[3]; + mayer_fft(n, in1, in2); + return (w+4); +} + +static void sigfft_dsp(t_sigfft *x, t_signal **sp) +{ + sigfft_dspx(x, sp, sigfft_perform); +} + +void fft_tilde_setup(void) +{ + sigfft_class = class_new(gensym("fft~"), sigfft_new, 0, + sizeof(t_sigfft), 0, 0); + CLASS_MAINSIGNALIN(sigfft_class, t_sigfft, x_f); + class_addmethod(sigfft_class, (t_method)sigfft_dsp, gensym("dsp"), 0); +} diff --git a/externals/vanilla/framp~.c b/externals/vanilla/framp~.c new file mode 100644 index 00000000..4b7a3398 --- /dev/null +++ b/externals/vanilla/framp~.c @@ -0,0 +1,97 @@ +/* Copyright (c) 1997- Miller Puckette and others. +* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#include "m_pd.h" + +/* This file interfaces to one of the Mayer, Ooura, or fftw FFT packages +to implement the "fft~", etc, Pd objects. If using Mayer, also compile +d_fft_mayer.c; if ooura, use d_fft_fftsg.c instead; if fftw, use d_fft_fftw.c +and also link in the fftw library. You can only have one of these three +linked in. The configure script can be used to select which one. +*/ + +static t_class *sigframp_class; + +typedef struct framp +{ + t_object x_obj; + t_float x_f; +} t_sigframp; + +static void *sigframp_new(void) +{ + t_sigframp *x = (t_sigframp *)pd_new(sigframp_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + outlet_new(&x->x_obj, gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); + x->x_f = 0; + return (x); +} + +static t_int *sigframp_perform(t_int *w) +{ + t_sample *inreal = (t_sample *)(w[1]); + t_sample *inimag = (t_sample *)(w[2]); + t_sample *outfreq = (t_sample *)(w[3]); + t_sample *outamp = (t_sample *)(w[4]); + t_sample lastreal = 0, currentreal = inreal[0], nextreal = inreal[1]; + t_sample lastimag = 0, currentimag = inimag[0], nextimag = inimag[1]; + int n = w[5]; + int m = n + 1; + t_sample fbin = 1, oneovern2 = 1.f/((t_sample)n * (t_sample)n); + + inreal += 2; + inimag += 2; + *outamp++ = *outfreq++ = 0; + n -= 2; + while (n--) + { + t_sample re, im, pow, freq; + lastreal = currentreal; + currentreal = nextreal; + nextreal = *inreal++; + lastimag = currentimag; + currentimag = nextimag; + nextimag = *inimag++; + re = currentreal - 0.5f * (lastreal + nextreal); + im = currentimag - 0.5f * (lastimag + nextimag); + pow = re * re + im * im; + if (pow > 1e-19) + { + t_sample detune = ((lastreal - nextreal) * re + + (lastimag - nextimag) * im) / (2.0f * pow); + if (detune > 2 || detune < -2) freq = pow = 0; + else freq = fbin + detune; + } + else freq = pow = 0; + *outfreq++ = freq; + *outamp++ = oneovern2 * pow; + fbin += 1.0f; + } + while (m--) *outamp++ = *outfreq++ = 0; + return (w+6); +} + +t_int *sigsqrt_perform(t_int *w); + +static void sigframp_dsp(t_sigframp *x, t_signal **sp) +{ + int n = sp[0]->s_n, n2 = (n>>1); + if (n < 4) + { + error("framp: minimum 4 points"); + return; + } + dsp_add(sigframp_perform, 5, sp[0]->s_vec, sp[1]->s_vec, + sp[2]->s_vec, sp[3]->s_vec, n2); + dsp_add(sigsqrt_perform, 3, sp[3]->s_vec, sp[3]->s_vec, n2); +} + +void framp_tilde_setup(void) +{ + sigframp_class = class_new(gensym("framp~"), sigframp_new, 0, + sizeof(t_sigframp), 0, 0); + CLASS_MAINSIGNALIN(sigframp_class, t_sigframp, x_f); + class_addmethod(sigframp_class, (t_method)sigframp_dsp, gensym("dsp"), 0); +} diff --git a/externals/vanilla/ifft~.c b/externals/vanilla/ifft~.c new file mode 100644 index 00000000..84577df3 --- /dev/null +++ b/externals/vanilla/ifft~.c @@ -0,0 +1,48 @@ +/* Copyright (c) 1997- Miller Puckette and others. +* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#include "m_pd.h" +#include "e_fft.h" + +/* This file interfaces to one of the Mayer, Ooura, or fftw FFT packages +to implement the "fft~", etc, Pd objects. If using Mayer, also compile +d_fft_mayer.c; if ooura, use d_fft_fftsg.c instead; if fftw, use d_fft_fftw.c +and also link in the fftw library. You can only have one of these three +linked in. The configure script can be used to select which one. +*/ + +static t_class *sigifft_class; + +static void *sigifft_new(void) +{ + t_sigfft *x = (t_sigfft *)pd_new(sigifft_class); + outlet_new(&x->x_obj, gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + x->x_f = 0; + return (x); +} + +static t_int *sigifft_perform(t_int *w) +{ + t_sample *in1 = (t_sample *)(w[1]); + t_sample *in2 = (t_sample *)(w[2]); + int n = w[3]; + mayer_ifft(n, in1, in2); + return (w+4); +} + +static void sigifft_dsp(t_sigfft *x, t_signal **sp) +{ + sigfft_dspx(x, sp, sigifft_perform); +} + +void ifft_tilde_setup(void) +{ + sigifft_class = class_new(gensym("ifft~"), sigifft_new, 0, + sizeof(t_sigfft), 0, 0); + CLASS_MAINSIGNALIN(sigifft_class, t_sigfft, x_f); + class_addmethod(sigifft_class, (t_method)sigifft_dsp, gensym("dsp"), 0); + class_sethelpsymbol(sigifft_class, gensym("fft~")); +} diff --git a/externals/vanilla/lib_d_fft.c b/externals/vanilla/lib_d_fft.c deleted file mode 100644 index 6cc6085b..00000000 --- a/externals/vanilla/lib_d_fft.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "../../pd/src/d_fftroutine.c" -#include "../../pd/src/d_fft_mayer.c" -#include "../../pd/src/d_fft.c" -void lib_d_fft_setup(void) -{ - d_fft_setup(); -} diff --git a/externals/vanilla/lib_d_math.c b/externals/vanilla/lib_d_math.c deleted file mode 100644 index d9605431..00000000 --- a/externals/vanilla/lib_d_math.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "../../pd/src/d_math.c" -void lib_d_math_setup(void) -{ - d_math_setup(); -} diff --git a/externals/vanilla/rfft~.c b/externals/vanilla/rfft~.c new file mode 100644 index 00000000..5012f750 --- /dev/null +++ b/externals/vanilla/rfft~.c @@ -0,0 +1,68 @@ +/* Copyright (c) 1997- Miller Puckette and others. +* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#include "m_pd.h" +#include "e_fft.h" + +/* This file interfaces to one of the Mayer, Ooura, or fftw FFT packages +to implement the "fft~", etc, Pd objects. If using Mayer, also compile +d_fft_mayer.c; if ooura, use d_fft_fftsg.c instead; if fftw, use d_fft_fftw.c +and also link in the fftw library. You can only have one of these three +linked in. The configure script can be used to select which one. +*/ + +static t_class *sigrfft_class; + +typedef struct rfft +{ + t_object x_obj; + t_float x_f; +} t_sigrfft; + +static void *sigrfft_new(void) +{ + t_sigrfft *x = (t_sigrfft *)pd_new(sigrfft_class); + outlet_new(&x->x_obj, gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); + x->x_f = 0; + return (x); +} + +static t_int *sigrfft_perform(t_int *w) +{ + t_sample *in = (t_sample *)(w[1]); + int n = w[2]; + mayer_realfft(n, in); + return (w+3); +} + +static void sigrfft_dsp(t_sigrfft *x, t_signal **sp) +{ + int n = sp[0]->s_n, n2 = (n>>1); + t_sample *in1 = sp[0]->s_vec; + t_sample *out1 = sp[1]->s_vec; + t_sample *out2 = sp[2]->s_vec; + if (n < 4) + { + error("fft: minimum 4 points"); + return; + } + if (in1 != out1) + dsp_add(copy_perform, 3, in1, out1, n); + dsp_add(sigrfft_perform, 2, out1, n); + dsp_add(sigrfft_flip, 3, out1 + (n2+1), out2 + n2, n2-1); + dsp_add_zero(out1 + (n2+1), ((n2-1)&(~7))); + dsp_add_zero(out1 + (n2+1) + ((n2-1)&(~7)), ((n2-1)&7)); + dsp_add_zero(out2 + n2, n2); + dsp_add_zero(out2, 1); +} + +void rfft_tilde_setup(void) +{ + sigrfft_class = class_new(gensym("rfft~"), sigrfft_new, 0, + sizeof(t_sigrfft), 0, 0); + CLASS_MAINSIGNALIN(sigrfft_class, t_sigrfft, x_f); + class_addmethod(sigrfft_class, (t_method)sigrfft_dsp, gensym("dsp"), 0); + class_sethelpsymbol(sigrfft_class, gensym("fft~")); +} diff --git a/externals/vanilla/rifft~.c b/externals/vanilla/rifft~.c new file mode 100644 index 00000000..53cb1354 --- /dev/null +++ b/externals/vanilla/rifft~.c @@ -0,0 +1,71 @@ +/* Copyright (c) 1997- Miller Puckette and others. +* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +#include "m_pd.h" +#include "e_fft.h" + +/* This file interfaces to one of the Mayer, Ooura, or fftw FFT packages +to implement the "fft~", etc, Pd objects. If using Mayer, also compile +d_fft_mayer.c; if ooura, use d_fft_fftsg.c instead; if fftw, use d_fft_fftw.c +and also link in the fftw library. You can only have one of these three +linked in. The configure script can be used to select which one. +*/ + +static t_class *sigrifft_class; + +typedef struct rifft +{ + t_object x_obj; + t_float x_f; +} t_sigrifft; + +static void *sigrifft_new(void) +{ + t_sigrifft *x = (t_sigrifft *)pd_new(sigrifft_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + outlet_new(&x->x_obj, gensym("signal")); + x->x_f = 0; + return (x); +} + +static t_int *sigrifft_perform(t_int *w) +{ + t_sample *in = (t_sample *)(w[1]); + int n = w[2]; + mayer_realifft(n, in); + return (w+3); +} + +static void sigrifft_dsp(t_sigrifft *x, t_signal **sp) +{ + int n = sp[0]->s_n, n2 = (n>>1); + t_sample *in1 = sp[0]->s_vec; + t_sample *in2 = sp[1]->s_vec; + t_sample *out1 = sp[2]->s_vec; + if (n < 4) + { + error("fft: minimum 4 points"); + return; + } + if (in2 == out1) + { + dsp_add(sigrfft_flip, 3, out1+1, out1 + n, n2-1); + dsp_add(copy_perform, 3, in1, out1, n2+1); + } + else + { + if (in1 != out1) dsp_add(copy_perform, 3, in1, out1, n2+1); + dsp_add(sigrfft_flip, 3, in2+1, out1 + n, n2-1); + } + dsp_add(sigrifft_perform, 2, out1, n); +} + +void rifft_tilde_setup(void) +{ + sigrifft_class = class_new(gensym("rifft~"), sigrifft_new, 0, + sizeof(t_sigrifft), 0, 0); + CLASS_MAINSIGNALIN(sigrifft_class, t_sigrifft, x_f); + class_addmethod(sigrifft_class, (t_method)sigrifft_dsp, gensym("dsp"), 0); + class_sethelpsymbol(sigrifft_class, gensym("fft~")); +} diff --git a/externals/vanilla/rsqrt~.c b/externals/vanilla/rsqrt~.c index e84f4c31..249d4c4d 100644 --- a/externals/vanilla/rsqrt~.c +++ b/externals/vanilla/rsqrt~.c @@ -8,8 +8,6 @@ /* sigrsqrt - reciprocal square root good to 8 mantissa bits */ -static float rsqrt_exptab[DUMTAB1SIZE], rsqrt_mantissatab[DUMTAB2SIZE]; - static void init_rsqrt(void) { int i; diff --git a/externals/vanilla/sqrt~.c b/externals/vanilla/sqrt~.c index 65c09581..b6829ab5 100644 --- a/externals/vanilla/sqrt~.c +++ b/externals/vanilla/sqrt~.c @@ -4,8 +4,6 @@ #include "e_sqrt.h" -static float rsqrt_exptab[DUMTAB1SIZE], rsqrt_mantissatab[DUMTAB2SIZE]; - typedef struct sigsqrt { t_object x_obj; @@ -22,25 +20,6 @@ static void *sigsqrt_new(void) return (x); } -t_int *sigsqrt_perform(t_int *w) /* not static; also used in d_fft.c */ -{ - t_sample *in = *(t_sample **)(w+1), *out = *(t_sample **)(w+2); - t_int n = *(t_int *)(w+3); - while (n--) - { - t_sample f = *in; - long l = *(long *)(in++); - if (f < 0) *out++ = 0; - else - { - t_sample g = rsqrt_exptab[(l >> 23) & 0xff] * - rsqrt_mantissatab[(l >> 13) & 0x3ff]; - *out++ = f * (1.5 * g - 0.5 * g * g * g * f); - } - } - return (w + 4); -} - static void sigsqrt_dsp(t_sigsqrt *x, t_signal **sp) { dsp_add(sigsqrt_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); -- cgit v1.2.1