diff options
Diffstat (limited to 'src/iemlib1')
31 files changed, 5633 insertions, 0 deletions
diff --git a/src/iemlib1/biquad_freq_resp.c b/src/iemlib1/biquad_freq_resp.c new file mode 100644 index 0000000..3ebe25d --- /dev/null +++ b/src/iemlib1/biquad_freq_resp.c @@ -0,0 +1,92 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* --------------------------- biquad_freq_resp ----------------------------- */ + +typedef struct _biquad_freq_resp +{ + t_object x_obj; + float a0; + float a1; + float a2; + float b1; + float b2; + t_outlet *x_out_re; + t_outlet *x_out_im; +} t_biquad_freq_resp; + +static t_class *biquad_freq_resp_class; + +static void biquad_freq_resp_float(t_biquad_freq_resp *x, t_float f) +{ + float re1, im1, re2, im2; + float c, s, a; + + if(f < 0.0f) + f = 0.0f; + else if(f > 180.0f) + f = 180.0; + f *= 3.14159265f; + f /= 180.0f; + + c = cos(f); + s = sin(f); + + re1 = x->a0 + x->a1*c + x->a2*(c*c - s*s); + im1 = x->a1*s + x->a2*2.0f*(s*c); + re2 = 1.0f - x->b1*c - x->b2*(c*c - s*s); + im2 = -x->b1*s - x->b2*2.0f*(s*c); + a = re2*re2 + im2*im2; + outlet_float(x->x_out_im, (re1*im2 - re2*im1)/a);/* because z^-1 = e^-jwt, negative sign */ + outlet_float(x->x_out_re, (re1*re2 + im1*im2)/a); + +} +/* y/x = (a0 + a1*z-1 + a2*z-2)/(1 - b1*z-1 - b2*z-2);*/ + +static void biquad_freq_resp_list(t_biquad_freq_resp *x, t_symbol *s, int argc, t_atom *argv) +{ + if((argc == 5)&&IS_A_FLOAT(argv,4)&&IS_A_FLOAT(argv,3)&&IS_A_FLOAT(argv,2)&&IS_A_FLOAT(argv,1)&&IS_A_FLOAT(argv,0)) + { + x->b1 = (float)atom_getfloatarg(0, argc, argv); + x->b2 = (float)atom_getfloatarg(1, argc, argv); + x->a0 = (float)atom_getfloatarg(2, argc, argv); + x->a1 = (float)atom_getfloatarg(3, argc, argv); + x->a2 = (float)atom_getfloatarg(4, argc, argv); + } +} + +static void *biquad_freq_resp_new(void) +{ + t_biquad_freq_resp *x = (t_biquad_freq_resp *)pd_new(biquad_freq_resp_class); + x->x_out_re = outlet_new(&x->x_obj, &s_float); + x->x_out_im = outlet_new(&x->x_obj, &s_float); + x->b1 = 0.0f; + x->b2 = 0.0f; + x->a0 = 0.0f; + x->a1 = 0.0f; + x->a2 = 0.0f; + return (x); +} + +void biquad_freq_resp_setup(void) +{ + biquad_freq_resp_class = class_new(gensym("biquad_freq_resp"), (t_newmethod)biquad_freq_resp_new, 0, + sizeof(t_biquad_freq_resp), 0, 0); + class_addfloat(biquad_freq_resp_class, biquad_freq_resp_float); + class_addlist(biquad_freq_resp_class, (t_method)biquad_freq_resp_list); + class_sethelpsymbol(biquad_freq_resp_class, gensym("iemhelp/help-biquad_freq_resp")); +}
\ No newline at end of file diff --git a/src/iemlib1/db2v.c b/src/iemlib1/db2v.c new file mode 100644 index 0000000..bbf1c21 --- /dev/null +++ b/src/iemlib1/db2v.c @@ -0,0 +1,45 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* ---------------- db2v - dB to value converter. ----------------- */ + +static t_class *db2v_class; + +float db2v(float f) +{ + return (f <= -199.9 ? 0 : exp(0.11512925465 * f)); +} + +static void db2v_float(t_object *x, t_float f) +{ + outlet_float(x->ob_outlet, db2v(f)); +} + +static void *db2v_new(void) +{ + t_object *x = (t_object *)pd_new(db2v_class); + outlet_new(x, &s_float); + return (x); +} + +void db2v_setup(void) +{ + db2v_class = class_new(gensym("db2v"), db2v_new, 0, + sizeof(t_object), 0, 0); + class_addfloat(db2v_class, (t_method)db2v_float); + class_sethelpsymbol(db2v_class, gensym("iemhelp/help-db2v")); +} diff --git a/src/iemlib1/f2note.c b/src/iemlib1/f2note.c new file mode 100644 index 0000000..4df6612 --- /dev/null +++ b/src/iemlib1/f2note.c @@ -0,0 +1,189 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* ------ frequency to note plus cents converter --------- */ + +typedef struct _f2note +{ + t_object x_obj; + void *x_outlet_midi; + void *x_outlet_note; + void *x_outlet_cent; + int x_centomidi; + float x_refhz; + float x_refexp; + float x_reflog; + t_symbol *x_set; +} t_f2note; + +static t_class *f2note_class; + +float f2note_mtof(t_f2note *x, float midi) +{ + return(x->x_refexp * exp(0.057762265047 * midi)); +} + +float f2note_ftom(t_f2note *x, float freq) +{ + return (freq > 0 ? 17.31234049 * log(x->x_reflog * freq) : -1500); +} + +void f2note_calc_ref(t_f2note *x) +{ + float ln2=log(2.0); + + x->x_refexp = x->x_refhz*exp(-5.75*ln2); + x->x_reflog = 1.0/x->x_refexp; +} + +static void f2note_make_note(char *str, int midi) +{ + int j,k,l=0; + + j = midi / 12; + k = midi % 12; + if(k <= 5) + { + if(k <= 2) + { + if(k==0) + str[l]='c'; + else if(k==1) + { + str[l++]='#'; + str[l]='c'; + } + else + str[l]='d'; + } + else + { + if(k==3) + { + str[l++]='#'; + str[l]='d'; + } + else if(k==4) + str[l]='e'; + else + str[l]='f'; + } + } + else + { + if(k <= 8) + { + if(k==6) + { + str[l++]='#'; + str[l]='f'; + } + else if(k==7) + str[l]='g'; + else + { + str[l++]='#'; + str[l]='g'; + } + } + else + { + if(k==9) + str[l]='a'; + else if(k==10) + { + str[l++]='#'; + str[l]='a'; + } + else + str[l]='h'; + } + } + + if(j < 4) + { + str[l] -= 'a'; + str[l] += 'A'; + } + l++; + if(j < 3) + { + str[l++] = '0' + (char)(3 - j); + } + else if(j > 4) + { + str[l++] = '0' + (char)(j - 4); + } + str[l] = 0; +} + +static void f2note_bang(t_f2note *x) +{ + int i,j; + t_atom at; + char s[4]; + + i = (x->x_centomidi + 50)/100; + j = x->x_centomidi - 100*i; + outlet_float(x->x_outlet_cent, (float)j); + f2note_make_note(s, i); + SETSYMBOL(&at, gensym(s)); + outlet_anything(x->x_outlet_note, x->x_set, 1, &at); + outlet_float(x->x_outlet_midi, 0.01*(float)(x->x_centomidi)); +} + +static void f2note_float(t_f2note *x, t_floatarg freq) +{ + x->x_centomidi = (int)(100.0*f2note_ftom(x, freq) + 0.5); + f2note_bang(x); +} + +void f2note_ref(t_f2note *x, t_floatarg ref) +{ + x->x_refhz = ref; + f2note_calc_ref(x); +} + +static void *f2note_new(t_floatarg ref) +{ + t_f2note *x = (t_f2note *)pd_new(f2note_class); + + if(ref == 0.0) + ref=440.0; + x->x_refhz = ref; + x->x_centomidi = (int)(100.0*ref + 0.499); + f2note_calc_ref(x); + x->x_outlet_midi = outlet_new(&x->x_obj, &s_float); + x->x_outlet_note = outlet_new(&x->x_obj, &s_list); + x->x_outlet_cent = outlet_new(&x->x_obj, &s_float); + x->x_set = gensym("set"); + return (x); +} + +static void f2note_free(t_f2note *x) +{ +} + +void f2note_setup(void) +{ + f2note_class = class_new(gensym("f2note"), (t_newmethod)f2note_new, (t_method)f2note_free, + sizeof(t_f2note), 0, A_DEFFLOAT, 0); + class_addbang(f2note_class,f2note_bang); + class_addfloat(f2note_class,f2note_float); + class_addmethod(f2note_class, (t_method)f2note_ref, gensym("ref"), A_FLOAT, 0); + class_sethelpsymbol(f2note_class, gensym("iemhelp/help-f2note")); +} diff --git a/src/iemlib1/forpp.c b/src/iemlib1/forpp.c new file mode 100644 index 0000000..3e98539 --- /dev/null +++ b/src/iemlib1/forpp.c @@ -0,0 +1,192 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* -------------------------- forpp ------------------------------ */ + +typedef struct _forpp +{ + t_object x_obj; + int x_beg; + int x_end; + float x_delay; + int x_cur; + int x_incr; + void *x_out_end; + void *x_clock; + void *x_clock2; +} t_forpp; + +static t_class *forpp_class; + +static void forpp_tick2(t_forpp *x) +{ + outlet_bang(x->x_out_end); + clock_unset(x->x_clock2); +} + +static void forpp_tick(t_forpp *x) +{ + outlet_float(x->x_obj.ob_outlet, x->x_cur); + x->x_cur += x->x_incr; + if(x->x_incr > 0) + { + if(x->x_cur <= x->x_end) + clock_delay(x->x_clock, x->x_delay); + else + { + clock_unset(x->x_clock); + clock_delay(x->x_clock2, x->x_delay); + } + } + else + { + if(x->x_cur >= x->x_end) + clock_delay(x->x_clock, x->x_delay); + else + { + clock_unset(x->x_clock); + clock_delay(x->x_clock2, x->x_delay); + } + } +} + +static void forpp_bang(t_forpp *x) +{ + x->x_cur = x->x_beg; + outlet_float(x->x_obj.ob_outlet, x->x_cur); + x->x_cur += x->x_incr; + if(x->x_incr > 0) + { + if(x->x_cur <= x->x_end) + clock_delay(x->x_clock, x->x_delay); + else + { + clock_unset(x->x_clock); + clock_delay(x->x_clock2, x->x_delay); + } + } + else + { + if(x->x_cur >= x->x_end) + clock_delay(x->x_clock, x->x_delay); + else + { + clock_unset(x->x_clock); + clock_delay(x->x_clock2, x->x_delay); + } + } + +} + +static void forpp_start(t_forpp *x) +{ + forpp_bang(x); +} + +static void forpp_stop(t_forpp *x) +{ + if(x->x_incr > 0) + x->x_cur = x->x_end + 1; + else + x->x_cur = x->x_end - 1; + clock_unset(x->x_clock); + clock_unset(x->x_clock2); +} + +static void forpp_float(t_forpp *x, t_float beg) +{ + x->x_beg = (int)beg; + if(x->x_end < x->x_beg) + x->x_incr = -1; + else + x->x_incr = 1; +} + +static void forpp_ft1(t_forpp *x, t_float end) +{ + x->x_end = (int)end; + if(x->x_end < x->x_beg) + x->x_incr = -1; + else + x->x_incr = 1; +} + +static void forpp_ft2(t_forpp *x, t_float delay) +{ + if(delay < 0.0) + delay = 0.0; + x->x_delay = delay; +} + +static void forpp_list(t_forpp *x, t_symbol *s, int argc, t_atom *argv) +{ + if(argc == 2) + { + forpp_float(x, atom_getfloatarg(0, argc, argv)); + forpp_ft1(x, atom_getfloatarg(1, argc, argv)); + } + else if(argc == 3) + { + forpp_float(x, atom_getfloatarg(0, argc, argv)); + forpp_ft1(x, atom_getfloatarg(1, argc, argv)); + forpp_ft2(x, atom_getfloatarg(2, argc, argv)); + } +} + +static void *forpp_new(t_floatarg beg, t_floatarg end, t_floatarg delay) +{ + t_forpp *x = (t_forpp *)pd_new(forpp_class); + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2")); + outlet_new(&x->x_obj, &s_float); + x->x_out_end = outlet_new(&x->x_obj, &s_bang); + x->x_clock = clock_new(x, (t_method)forpp_tick); + x->x_clock2 = clock_new(x, (t_method)forpp_tick2); + x->x_beg = (int)beg; + x->x_end = (int)end; + if(x->x_end < x->x_beg) + x->x_incr = -1; + else + x->x_incr = 1; + if(delay < 0.0) + delay = 0.0; + x->x_delay = delay; + x->x_cur = x->x_beg; + return(x); +} + +static void forpp_ff(t_forpp *x) +{ + clock_free(x->x_clock); + clock_free(x->x_clock2); +} + +void forpp_setup(void) +{ + forpp_class = class_new(gensym("for++"), (t_newmethod)forpp_new, + (t_method)forpp_ff, sizeof(t_forpp), + 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addbang(forpp_class, forpp_bang); + class_addfloat(forpp_class, forpp_float); + class_addlist(forpp_class, forpp_list); + class_addmethod(forpp_class, (t_method)forpp_start, gensym("start"), 0); + class_addmethod(forpp_class, (t_method)forpp_stop, gensym("stop"), 0); + class_addmethod(forpp_class, (t_method)forpp_ft1, gensym("ft1"), A_FLOAT, 0); + class_addmethod(forpp_class, (t_method)forpp_ft2, gensym("ft2"), A_FLOAT, 0); + class_sethelpsymbol(forpp_class, gensym("iemhelp/help-for++")); +} diff --git a/src/iemlib1/gate.c b/src/iemlib1/gate.c new file mode 100644 index 0000000..957ee07 --- /dev/null +++ b/src/iemlib1/gate.c @@ -0,0 +1,84 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* -------------------------- gate ------------------------------ */ + +typedef struct _gate +{ + t_object x_obj; + float x_state; +} t_gate; + +static t_class *gate_class; + +static void gate_bang(t_gate *x) +{ + if(x->x_state != 0) + outlet_bang(x->x_obj.ob_outlet); +} + +static void gate_pointer(t_gate *x, t_gpointer *gp) +{ + if(x->x_state != 0) + outlet_pointer(x->x_obj.ob_outlet, gp); +} + +static void gate_float(t_gate *x, t_floatarg f) +{ + if(x->x_state != 0) + outlet_float(x->x_obj.ob_outlet, f); +} + +static void gate_symbol(t_gate *x, t_symbol *s) +{ + if(x->x_state != 0) + outlet_symbol(x->x_obj.ob_outlet, s); +} + +static void gate_list(t_gate *x, t_symbol *s, int argc, t_atom *argv) +{ + if(x->x_state != 0) + outlet_list(x->x_obj.ob_outlet, s, argc, argv); +} + +static void gate_anything(t_gate *x, t_symbol *s, int argc, t_atom *argv) +{ + if(x->x_state != 0) + outlet_anything(x->x_obj.ob_outlet, s, argc, argv); +} + +static void *gate_new(t_floatarg f) +{ + t_gate *x = (t_gate *)pd_new(gate_class); + floatinlet_new(&x->x_obj, &x->x_state); + outlet_new(&x->x_obj, 0); + x->x_state = (f==0.0)?0:1; + return (x); +} + +void gate_setup(void) +{ + gate_class = class_new(gensym("gate"), (t_newmethod)gate_new, 0, + sizeof(t_gate), 0, A_DEFFLOAT, 0); + class_addbang(gate_class, gate_bang); + class_addpointer(gate_class, gate_pointer); + class_addfloat(gate_class, gate_float); + class_addsymbol(gate_class, gate_symbol); + class_addlist(gate_class, gate_list); + class_addanything(gate_class, gate_anything); + class_sethelpsymbol(gate_class, gensym("iemhelp/help-gate")); +} diff --git a/src/iemlib1/iemlib.h b/src/iemlib1/iemlib.h new file mode 100644 index 0000000..cc882b1 --- /dev/null +++ b/src/iemlib1/iemlib.h @@ -0,0 +1,98 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifndef __IEMLIB_H__ +#define __IEMLIB_H__ + + +#define IS_A_POINTER(atom,index) ((atom+index)->a_type == A_POINTER) +#define IS_A_FLOAT(atom,index) ((atom+index)->a_type == A_FLOAT) +#define IS_A_SYMBOL(atom,index) ((atom+index)->a_type == A_SYMBOL) +#define IS_A_DOLLAR(atom,index) ((atom+index)->a_type == A_DOLLAR) +#define IS_A_DOLLSYM(atom,index) ((atom+index)->a_type == A_DOLLSYM) +#define IS_A_SEMI(atom,index) ((atom+index)->a_type == A_SEMI) +#define IS_A_COMMA(atom,index) ((atom+index)->a_type == A_COMMA) + + +#ifdef NT +int sys_noloadbang; +//t_symbol *iemgui_key_sym=0; +#include <io.h> +#else +extern int sys_noloadbang; +//extern t_symbol *iemgui_key_sym; +#include <unistd.h> +#endif + +#define DEFDELVS 64 +#define XTRASAMPS 4 +#define SAMPBLK 4 + + +#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */ + + /* machine-dependent definitions. These ifdefs really + should have been by CPU type and not by operating system! */ +#ifdef IRIX + /* big-endian. Most significant byte is at low address in memory */ +#define HIOFFSET 0 /* word offset to find MSB */ +#define LOWOFFSET 1 /* word offset to find LSB */ +#define int32 long /* a data type that has 32 bits */ +#else +#ifdef MSW + /* little-endian; most significant byte is at highest address */ +#define HIOFFSET 1 +#define LOWOFFSET 0 +#define int32 long +#else +#ifdef __FreeBSD__ +#include <machine/endian.h> +#if BYTE_ORDER == LITTLE_ENDIAN +#define HIOFFSET 1 +#define LOWOFFSET 0 +#else +#define HIOFFSET 0 /* word offset to find MSB */ +#define LOWOFFSET 1 /* word offset to find LSB */ +#endif /* BYTE_ORDER */ +#include <sys/types.h> +#define int32 int32_t +#endif +#ifdef __linux__ + +#include <endian.h> + +#if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN) +#error No byte order defined +#endif + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define HIOFFSET 1 +#define LOWOFFSET 0 +#else +#define HIOFFSET 0 /* word offset to find MSB */ +#define LOWOFFSET 1 /* word offset to find LSB */ +#endif /* __BYTE_ORDER */ + +#include <sys/types.h> +#define int32 int32_t + +#else +#ifdef __APPLE__ +#define HIOFFSET 0 /* word offset to find MSB */ +#define LOWOFFSET 1 /* word offset to find LSB */ +#define int32 int /* a data type that has 32 bits */ + +#endif /* __APPLE__ */ +#endif /* __linux__ */ +#endif /* MSW */ +#endif /* SGI */ + +union tabfudge +{ + double tf_d; + int32 tf_i[2]; +}; + +#endif diff --git a/src/iemlib1/iemlib1.c b/src/iemlib1/iemlib1.c new file mode 100644 index 0000000..3700c40 --- /dev/null +++ b/src/iemlib1/iemlib1.c @@ -0,0 +1,82 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" + +static t_class *iemlib1_class; + +static void *iemlib1_new(void) +{ + t_object *x = (t_object *)pd_new(iemlib1_class); + + return (x); +} + +void biquad_freq_resp_setup(void); +void db2v_setup(void); +void f2note_setup(void); +void forpp_setup(void); +void gate_setup(void); +void sigfilter_setup(void); +void sigFIR_setup(void); +void sighml_shelf_setup(void); +void sigiem_cot4_setup(void); +void sigiem_delay_setup(void); +void sigiem_sqrt4_setup(void); +void sigiem_pow4_setup(void); +void siglp1_t_setup(void); +void sigmov_avrg_kern_setup(void); +void sigpara_bp2_setup(void); +void sigpeakenv_setup(void); +void sigprvu_setup(void); +void sigpvu_setup(void); +void sigrvu_setup(void); +void sigsin_phase_setup(void); +void sigvcf_filter_setup(void); +void soundfile_info_setup(void); +void split_setup(void); +void v2db_setup(void); + +/* ------------------------ setup routine ------------------------- */ + +void iemlib1_setup(void) +{ + iemlib1_class = class_new(gensym("iemlib1"), iemlib1_new, 0, + sizeof(t_object), CLASS_NOINLET, 0); + + biquad_freq_resp_setup(); + db2v_setup(); + f2note_setup(); + forpp_setup(); + gate_setup(); + sigfilter_setup(); + sigFIR_setup(); + sighml_shelf_setup(); + sigiem_cot4_setup(); + sigiem_delay_setup(); + sigiem_sqrt4_setup(); + sigiem_pow4_setup(); + siglp1_t_setup(); + sigmov_avrg_kern_setup(); + sigpara_bp2_setup(); + sigpeakenv_setup(); + sigprvu_setup(); + sigpvu_setup(); + sigrvu_setup(); + sigsin_phase_setup(); + sigvcf_filter_setup(); + soundfile_info_setup(); + split_setup(); + v2db_setup(); + + post("iemlib1 (R-1.15) library loaded!"); +} diff --git a/src/iemlib1/iemlib1.dsp b/src/iemlib1/iemlib1.dsp new file mode 100644 index 0000000..7d63ad2 --- /dev/null +++ b/src/iemlib1/iemlib1.dsp @@ -0,0 +1,85 @@ +# Microsoft Developer Studio Project File - Name="iemlib1" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** NICHT BEARBEITEN ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=iemlib1 - Win32 Debug +!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE +!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl +!MESSAGE +!MESSAGE NMAKE /f "iemlib1.mak". +!MESSAGE +!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben +!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: +!MESSAGE +!MESSAGE NMAKE /f "iemlib1.mak" CFG="iemlib1 - Win32 Debug" +!MESSAGE +!MESSAGE Für die Konfiguration stehen zur Auswahl: +!MESSAGE +!MESSAGE "iemlib1 - Win32 Release" (basierend auf "Win32 (x86) External Target") +!MESSAGE "iemlib1 - Win32 Debug" (basierend auf "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "iemlib1 - Win32 Release" + +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f makefile_win" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "makefile_win.exe" +# PROP BASE Bsc_Name "makefile_win.bsc" +# PROP BASE Target_Dir "" +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "NMAKE /f makefile_win" +# PROP Rebuild_Opt "/a" +# PROP Target_File "iemlib1.exe" +# PROP Bsc_Name "iemlib1.bsc" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "iemlib1 - Win32 Debug" + +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f makefile_win" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "makefile_win.exe" +# PROP BASE Bsc_Name "makefile_win.bsc" +# PROP BASE Target_Dir "" +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "NMAKE /f makefile_win" +# PROP Rebuild_Opt "/a" +# PROP Target_File "iemlib1.exe" +# PROP Bsc_Name "iemlib1.bsc" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "iemlib1 - Win32 Release" +# Name "iemlib1 - Win32 Debug" + +!IF "$(CFG)" == "iemlib1 - Win32 Release" + +!ELSEIF "$(CFG)" == "iemlib1 - Win32 Debug" + +!ENDIF + +# Begin Source File + +SOURCE=.\makefile_win +# End Source File +# End Target +# End Project diff --git a/src/iemlib1/iemlib1.dsw b/src/iemlib1/iemlib1.dsw new file mode 100644 index 0000000..c8260a7 --- /dev/null +++ b/src/iemlib1/iemlib1.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN! + +############################################################################### + +Project: "iemlib1"=.\iemlib1.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/src/iemlib1/makefile b/src/iemlib1/makefile new file mode 100644 index 0000000..c8148cf --- /dev/null +++ b/src/iemlib1/makefile @@ -0,0 +1,72 @@ +current: all + +.SUFFIXES: .pd_linux + +INCLUDE = -I. -I/usr/local/src/pd/src + +LDFLAGS = -export-dynamic -shared +LIB = -ldl -lm -lpthread + +#select either the DBG and OPT compiler flags below: + +CFLAGS = -DPD -DUNIX -Wall -W -Werror -Wno-unused \ + -Wno-parentheses -Wno-switch -O6 -funroll-loops -fomit-frame-pointer \ + -DDL_OPEN + +SYSTEM = $(shell uname -m) + +# the sources + +SRC = biquad_freq_resp.c \ + db2v.c \ + f2note.c \ + forpp.c \ + gate.c \ + sigfilter.c \ + sigFIR.c \ + sighml_shelf.c \ + sigiem_cot4.c \ + sigiem_delay.c \ + sigiem_pow4.c \ + sigiem_sqrt4.c \ + siglp1_t.c \ + sigmov_avrg_kern.c \ + sigpara_bp2.c \ + sigpeakenv.c \ + sigprvu.c \ + sigpvu.c \ + sigrvu.c \ + sigsin_phase.c \ + sigvcf_filter.c \ + soundfile_info.c \ + split.c \ + v2db.c \ + iemlib1.c + +TARGET = iemlib1.pd_linux + + +OBJ = $(SRC:.c=.o) + +# +# ------------------ targets ------------------------------------ +# + +clean: + rm ../../lib/$(TARGET) + rm *.o + +all: $(OBJ) + @echo :: $(OBJ) + ld $(LDFLAGS) -o $(TARGET) *.o $(LIB) + strip --strip-unneeded $(TARGET) + mv $(TARGET) ../../lib + rm *.o + +$(OBJ) : %.o : %.c + touch $*.c + cc $(CFLAGS) $(INCLUDE) -c -o $*.o $*.c + + + + diff --git a/src/iemlib1/makefile.darwin b/src/iemlib1/makefile.darwin new file mode 100644 index 0000000..338310e --- /dev/null +++ b/src/iemlib1/makefile.darwin @@ -0,0 +1,72 @@ +current: all + +.SUFFIXES: .pd_darwin + +INCLUDE = -I. -I/usr/local/src/pd-0.37-1test6/src + +LDFLAGS = -export-dynamic -shared +LIB = -ldl -lm -lpthread + +#select either the DBG and OPT compiler flags below: + +CFLAGS = -DPD -DUNIX -g -Wall -W -Werror -Wno-unused \ + -Wno-parentheses -Wno-switch -O2 $(INCLUDE) $(UCFLAGS) $(AFLAGS) \ + +MACOSXLINKFLAGS = -bundle -bundle_loader /usr/local/src/pd-0.37-1test6/bin/pd + +SYSTEM = $(shell uname -m) + +# the sources + +SRC = biquad_freq_resp.c \ + db2v.c \ + f2note.c \ + forpp.c \ + gate.c \ + sigfilter.c \ + sigFIR.c \ + sighml_shelf.c \ + sigiem_cot4.c \ + sigiem_delay.c \ + sigiem_pow4.c \ + sigiem_sqrt4.c \ + siglp1_t.c \ + sigmov_avrg_kern.c \ + sigpara_bp2.c \ + sigpeakenv.c \ + sigprvu.c \ + sigpvu.c \ + sigrvu.c \ + sigsin_phase.c \ + sigvcf_filter.c \ + soundfile_info.c \ + split.c \ + v2db.c \ + iemlib1.c + +TARGET = iemlib1.pd_darwin + + +OBJ = $(SRC:.c=.o) + +# +# ------------------ targets ------------------------------------ +# + +clean: + rm ../../lib/$(TARGET) + rm *.o + +all: $(OBJ) + @echo :: $(OBJ) + $(CC) $(MACOSXLINKFLAGS) -o $(TARGET) *.o $(LIB) + strip --strip-unneeded $(TARGET) + mv $(TARGET) ../../lib + +$(OBJ) : %.o : %.c + touch $*.c + $(CC) $(CFLAGS) -DPD $(INCLUDE) -c -o $*.o $*.c + + + + diff --git a/src/iemlib1/makefile_win b/src/iemlib1/makefile_win new file mode 100644 index 0000000..8ab353c --- /dev/null +++ b/src/iemlib1/makefile_win @@ -0,0 +1,61 @@ + +all: ..\..\lib\iemlib1.dll + +VIS_CPP_PATH = "C:\Programme\Microsoft Visual Studio\Vc98" + +PD_INST_PATH = "C:\Programme\pd" + +PD_WIN_INCLUDE_PATH = /I. /I$(PD_INST_PATH)\src /I$(VIS_CPP_PATH)\include + +PD_WIN_C_FLAGS = /nologo /W3 /WX /DMSW /DNT /DPD /DWIN32 /DWINDOWS /Ox -DPA_LITTLE_ENDIAN + +PD_WIN_L_FLAGS = /nologo + +PD_WIN_LIB = /NODEFAULTLIB:libc /NODEFAULTLIB:oldnames /NODEFAULTLIB:kernel /NODEFAULTLIB:uuid \ + $(VIS_CPP_PATH)\lib\libc.lib \ + $(VIS_CPP_PATH)\lib\oldnames.lib \ + $(VIS_CPP_PATH)\lib\kernel32.lib \ + $(VIS_CPP_PATH)\lib\wsock32.lib \ + $(VIS_CPP_PATH)\lib\winmm.lib \ + $(PD_INST_PATH)\bin\pthreadVC.lib \ + $(PD_INST_PATH)\bin\pd.lib + + +SRC = biquad_freq_resp.c \ + db2v.c \ + f2note.c \ + forpp.c \ + gate.c \ + sigfilter.c \ + sigFIR.c \ + sighml_shelf.c \ + sigiem_cot4.c \ + sigiem_delay.c \ + sigiem_sqrt4.c \ + sigiem_pow4.c \ + siglp1_t.c \ + sigmov_avrg_kern.c \ + sigpara_bp2.c \ + sigpeakenv.c \ + sigprvu.c \ + sigpvu.c \ + sigrvu.c \ + sigsin_phase.c \ + sigvcf_filter.c \ + soundfile_info.c \ + split.c \ + v2db.c \ + iemlib1.c + + +OBJ = $(SRC:.c=.obj) + +.c.obj: + cl $(PD_WIN_C_FLAGS) $(PD_WIN_INCLUDE_PATH) /c $*.c + +..\..\lib\iemlib1.dll: $(OBJ) + link $(PD_WIN_L_FLAGS) /dll /export:iemlib1_setup \ + /out:..\..\lib\iemlib1.dll $(OBJ) $(PD_WIN_LIB) + +clean: + del *.obj diff --git a/src/iemlib1/sigFIR.c b/src/iemlib1/sigFIR.c new file mode 100644 index 0000000..51c9de0 --- /dev/null +++ b/src/iemlib1/sigFIR.c @@ -0,0 +1,177 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + + +/* ---------- FIR~ - FIR-filter with table~-coef ----------- */ + +typedef struct sigFIR +{ + t_object x_obj; + float *x_coef_beg; + float *x_history_beg; + int x_rw_index; + int x_fir_order; + t_symbol *x_table_name; + float x_msi; +} t_sigFIR; + +t_class *sigFIR_class; + +static t_int *sigFIR_perform(t_int *w) +{ + float *in = (float *)(w[1]); + float *out = (float *)(w[2]); + t_sigFIR *x = (t_sigFIR *)(w[3]); + int n = (t_int)(w[4]); + int rw_index = x->x_rw_index; + int i, j; + int order = x->x_fir_order; + int ord16 = order / 16; + float sum=0.0f; + float *coef = x->x_coef_beg; + float *write_hist1=x->x_history_beg; + float *write_hist2; + float *read_hist; + float *coef_vec; + float *hist_vec; + + if(!coef) + goto sigFIRperfzero; + + write_hist1 = x->x_history_beg; + write_hist2 = write_hist1 + order; + read_hist = write_hist2; + + for(i=0; i<n; i++) + { + write_hist1[rw_index] = in[i]; + write_hist2[rw_index] = in[i]; + + sum = 0.0f; + coef_vec = coef; + hist_vec = &read_hist[rw_index]; + for(j=0; j<ord16; j++) + { + sum += coef_vec[0] * hist_vec[0]; + sum += coef_vec[1] * hist_vec[-1]; + sum += coef_vec[2] * hist_vec[-2]; + sum += coef_vec[3] * hist_vec[-3]; + sum += coef_vec[4] * hist_vec[-4]; + sum += coef_vec[5] * hist_vec[-5]; + sum += coef_vec[6] * hist_vec[-6]; + sum += coef_vec[7] * hist_vec[-7]; + sum += coef_vec[8] * hist_vec[-8]; + sum += coef_vec[9] * hist_vec[-9]; + sum += coef_vec[10] * hist_vec[-10]; + sum += coef_vec[11] * hist_vec[-11]; + sum += coef_vec[12] * hist_vec[-12]; + sum += coef_vec[13] * hist_vec[-13]; + sum += coef_vec[14] * hist_vec[-14]; + sum += coef_vec[15] * hist_vec[-15]; + coef_vec += 16; + hist_vec -= 16; + } + for(j=ord16*16; j<order; j++) + { + sum += coef[j] * read_hist[rw_index-j]; + } + out[i] = sum; + + rw_index++; + if(rw_index >= order) + rw_index -= order; + } + + x->x_rw_index = rw_index; + return(w+5); + +sigFIRperfzero: + + while(n--) + *out++ = 0.0f; + return(w+5); +} + +void sigFIR_set(t_sigFIR *x, t_symbol *table_name, t_floatarg forder) +{ + t_garray *ga; + int table_size; + int order = (int)forder; + + x->x_table_name = table_name; + if(!(ga = (t_garray *)pd_findbyclass(x->x_table_name, garray_class))) + { + if(*table_name->s_name) + error("FIR~: %s: no such table~", x->x_table_name->s_name); + x->x_coef_beg = 0; + } + else if(!garray_getfloatarray(ga, &table_size, &x->x_coef_beg)) + { + error("%s: bad template for FIR~", x->x_table_name->s_name); + x->x_coef_beg = 0; + } + else if(table_size < order) + { + error("FIR~: tablesize %d < order %d !!!!", table_size, order); + x->x_coef_beg = 0; + } + else + garray_usedindsp(ga); + x->x_rw_index = 0; + if(order > x->x_fir_order)/* resize */ + x->x_history_beg = (float *)resizebytes(x->x_history_beg, 2*x->x_fir_order*sizeof(float), 2*order*sizeof(float)); + x->x_fir_order = order; +} + +static void sigFIR_dsp(t_sigFIR *x, t_signal **sp) +{ + sigFIR_set(x, x->x_table_name, x->x_fir_order); + dsp_add(sigFIR_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n); +} + +static void *sigFIR_new(t_symbol *ref, t_floatarg np) +{ + t_sigFIR *x = (t_sigFIR *)pd_new(sigFIR_class); + + outlet_new(&x->x_obj, &s_signal); + x->x_msi = 0; + x->x_table_name = ref; + x->x_coef_beg = 0; + if((int)np < 1) + np = 1.0; + x->x_fir_order = (int)np; + x->x_history_beg = (float *)getbytes((2*x->x_fir_order)*sizeof(float)); + x->x_rw_index = 0; + return(x); +} + +static void sigFIR_free(t_sigFIR *x) +{ + if(x->x_history_beg) + freebytes(x->x_history_beg, (2*x->x_fir_order)*sizeof(float)); +} + +void sigFIR_setup(void) +{ + sigFIR_class = class_new(gensym("FIR~"), (t_newmethod)sigFIR_new, + (t_method)sigFIR_free, sizeof(t_sigFIR), 0, A_DEFSYM, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(sigFIR_class, t_sigFIR, x_msi); + class_addmethod(sigFIR_class, (t_method)sigFIR_dsp, gensym("dsp"), 0); + class_addmethod(sigFIR_class, (t_method)sigFIR_set, + gensym("set"), A_SYMBOL, A_FLOAT, 0); + class_sethelpsymbol(sigFIR_class, gensym("iemhelp/help-FIR~")); +} diff --git a/src/iemlib1/sigfilter.c b/src/iemlib1/sigfilter.c new file mode 100644 index 0000000..6a05206 --- /dev/null +++ b/src/iemlib1/sigfilter.c @@ -0,0 +1,822 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + + +/* ---------- filter~ - slow dynamic filter 1. and 2. order ----------- */ + +typedef struct sigfilter +{ + t_object x_obj; + float wn1; + float wn2; + float a0; + float a1; + float a2; + float b1; + float b2; + float sr; + float cur_f; + float cur_l; + float cur_a; + float cur_b; + float delta_f; + float delta_a; + float delta_b; + float end_f; + float end_a; + float end_b; + float ticks_per_interpol_time; + float rcp_ticks; + float interpol_time; + int ticks; + int counter_f; + int counter_a; + int counter_b; + int inv; + int hp; + int first_order; + int event_mask; + void (*calc)(); + void *x_debug_outlet; + t_atom x_at[5]; + float x_msi; +} t_sigfilter; + +t_class *sigfilter_class; + +static void sigfilter_snafu(t_sigfilter *x) +{ + +} + +static void sigfilter_lp1(t_sigfilter *x) +{ + float al; + + al = x->cur_a * x->cur_l; + x->a0 = 1.0f/(1.0f + al); + x->a1 = x->a0; + x->b1 = (al - 1.0f)*x->a0; +} + +static void sigfilter_lp2(t_sigfilter *x) +{ + float l, al, bl2, rcp; + + l = x->cur_l; + al = l*x->cur_a; + bl2 = l*l*x->cur_b + 1.0f; + rcp = 1.0f/(al + bl2); + x->a0 = rcp; + x->a1 = 2.0f*rcp; + x->a2 = x->a0; + x->b1 = rcp*2.0f*(bl2 - 2.0f); + x->b2 = rcp*(al - bl2); +} + +static void sigfilter_hp1(t_sigfilter *x) +{ + float al, rcp; + + al = x->cur_a * x->cur_l; + rcp = 1.0f/(1.0f + al); + x->a0 = rcp*al; + x->a1 = -x->a0; + x->b1 = rcp*(al - 1.0f); +} + +static void sigfilter_hp2(t_sigfilter *x) +{ + float l, al, bl2, rcp; + + l = x->cur_l; + bl2 = l*l*x->cur_b + 1.0f; + al = l*x->cur_a; + rcp = 1.0f/(al + bl2); + x->a0 = rcp*(bl2 - 1.0f); + x->a1 = -2.0f*x->a0; + x->a2 = x->a0; + x->b1 = rcp*2.0f*(bl2 - 2.0f); + x->b2 = rcp*(al - bl2); +} + +static void sigfilter_rp2(t_sigfilter *x) +{ + float l, al, l2, rcp; + + l = x->cur_l; + l2 = l*l + 1.0f; + al = l*x->cur_a; + rcp = 1.0f/(al + l2); + x->a0 = rcp*l; + x->a2 = -x->a0; + x->b1 = rcp*2.0f*(l2 - 2.0f); + x->b2 = rcp*(al - l2); +} + +static void sigfilter_bp2(t_sigfilter *x) +{ + float l, al, l2, rcp; + + l = x->cur_l; + l2 = l*l + 1.0f; + al = l*x->cur_a; + rcp = 1.0f/(al + l2); + x->a0 = rcp*al; + x->a2 = -x->a0; + x->b1 = rcp*2.0f*(l2 - 2.0f); + x->b2 = rcp*(al - l2); +} + +static void sigfilter_bs2(t_sigfilter *x) +{ + float l, al, l2, rcp; + + l = x->cur_l; + l2 = l*l + 1.0f; + al = l*x->cur_a; + rcp = 1.0f/(al + l2); + x->a0 = rcp*l2; + x->a1 = rcp*2.0f*(2.0f - l2); + x->a2 = x->a0; + x->b1 = -x->a1; + x->b2 = rcp*(al - l2); +} + +static void sigfilter_rpw2(t_sigfilter *x) +{ + float l, al, l2, rcp; + + l = x->cur_l; + l2 = l*l + 1.0f; + al = l*x->cur_a/x->cur_f; + rcp = 1.0f/(al + l2); + x->a0 = rcp*l; + x->a2 = -x->a0; + x->b1 = rcp*2.0f*(l2 - 2.0f); + x->b2 = rcp*(al - l2); +} + +static void sigfilter_bpw2(t_sigfilter *x) +{ + float l, al, l2, rcp; + + l = x->cur_l; + l2 = l*l + 1.0f; + al = l*x->cur_a/x->cur_f; + rcp = 1.0f/(al + l2); + x->a0 = rcp*al; + x->a2 = -x->a0; + x->b1 = rcp*2.0f*(l2 - 2.0f); + x->b2 = rcp*(al - l2); +} + +static void sigfilter_bsw2(t_sigfilter *x) +{ + float l, al, l2, rcp; + + l = x->cur_l; + l2 = l*l + 1.0f; + al = l*x->cur_a/x->cur_f; + rcp = 1.0f/(al + l2); + x->a0 = rcp*l2; + x->a1 = rcp*2.0f*(2.0f - l2); + x->a2 = x->a0; + x->b1 = -x->a1; + x->b2 = rcp*(al - l2); +} + +static void sigfilter_ap1(t_sigfilter *x) +{ + float al; + + al = x->cur_a * x->cur_l; + x->a0 = (1.0f - al)/(1.0f + al); + x->b1 = -x->a0; +} + +static void sigfilter_ap2(t_sigfilter *x) +{ + float l, al, bl2, rcp; + + l = x->cur_l; + bl2 = l*l*x->cur_b + 1.0f; + al = l*x->cur_a; + rcp = 1.0f/(al + bl2); + x->a1 = rcp*2.0f*(2.0f - bl2); + x->a0 = rcp*(bl2 - al); + x->b1 = -x->a1; + x->b2 = -x->a0; +} + +/*static void sigfilter_bp2(t_sigfilter *x) +{ + float l, al, l2, rcp; + + l = x->cur_l; + l2 = l*l + 1.0; + al = l*x->cur_a; + rcp = 1.0f/(al + l2); + x->a0 = rcp*al; + x->a2 = -x->a0; + x->b1 = rcp*2.0f*(2.0f - l2); + x->b2 = rcp*(l2 - al); +}*/ + +static void sigfilter_dsp_tick(t_sigfilter *x) +{ + if(x->event_mask) + { + if(x->counter_f) + { + float l, si, co; + + if(x->counter_f <= 1) + { + x->cur_f = x->end_f; + x->counter_f = 0; + x->event_mask &= 6;/*set event_mask_bit 0 = 0*/ + } + else + { + x->counter_f--; + x->cur_f *= x->delta_f; + } + l = x->cur_f * x->sr; + if(l < 1.0e-20f) + x->cur_l = 1.0e20f; + else if(l > 1.57079632f) + x->cur_l = 0.0f; + else + { + si = sin(l); + co = cos(l); + x->cur_l = co/si; + } + } + if(x->counter_a) + { + if(x->counter_a <= 1) + { + x->cur_a = x->end_a; + x->counter_a = 0; + x->event_mask &= 5;/*set event_mask_bit 1 = 0*/ + } + else + { + x->counter_a--; + x->cur_a *= x->delta_a; + } + } + if(x->counter_b) + { + if(x->counter_b <= 1) + { + x->cur_b = x->end_b; + x->counter_b = 0; + x->event_mask &= 3;/*set event_mask_bit 2 = 0*/ + } + else + { + x->counter_b--; + x->cur_b *= x->delta_b; + } + } + + (*(x->calc))(x); + + /* stability check */ + if(x->first_order) + { + if(x->b1 <= -0.9999998f) + x->b1 = -0.9999998f; + else if(x->b1 >= 0.9999998f) + x->b1 = 0.9999998f; + } + else + { + float discriminant = x->b1 * x->b1 + 4.0f * x->b2; + + if(x->b1 <= -1.9999996f) + x->b1 = -1.9999996f; + else if(x->b1 >= 1.9999996f) + x->b1 = 1.9999996f; + + if(x->b2 <= -0.9999998f) + x->b2 = -0.9999998f; + else if(x->b2 >= 0.9999998f) + x->b2 = 0.9999998f; + + if(discriminant >= 0.0f) + { + if(0.9999998f - x->b1 - x->b2 < 0.0f) + x->b2 = 0.9999998f - x->b1; + if(0.9999998f + x->b1 - x->b2 < 0.0f) + x->b2 = 0.9999998f + x->b1; + } + } + } +} + +static t_int *sigfilter_perform_2o(t_int *w) +{ + float *in = (float *)(w[1]); + float *out = (float *)(w[2]); + t_sigfilter *x = (t_sigfilter *)(w[3]); + int i, n = (t_int)(w[4]); + float wn0, wn1=x->wn1, wn2=x->wn2; + float a0=x->a0, a1=x->a1, a2=x->a2; + float b1=x->b1, b2=x->b2; + + sigfilter_dsp_tick(x); + for(i=0; i<n; i++) + { + wn0 = *in++ + b1*wn1 + b2*wn2; + *out++ = a0*wn0 + a1*wn1 + a2*wn2; + wn2 = wn1; + wn1 = wn0; + } + /* NAN protect */ + if(PD_BADFLOAT(wn2)) + wn2 = 0.0f; + if(PD_BADFLOAT(wn1)) + wn1 = 0.0f; + + x->wn1 = wn1; + x->wn2 = wn2; + return(w+5); +} +/* yn0 = *out; + xn0 = *in; + ************* + yn0 = a0*xn0 + a1*xn1 + a2*xn2 + b1*yn1 + b2*yn2; + yn2 = yn1; + yn1 = yn0; + xn2 = xn1; + xn1 = xn0; + ************************* + y/x = (a0 + a1*z-1 + a2*z-2)/(1 - b1*z-1 - b2*z-2);*/ + +static t_int *sigfilter_perf8_2o(t_int *w) +{ + float *in = (float *)(w[1]); + float *out = (float *)(w[2]); + t_sigfilter *x = (t_sigfilter *)(w[3]); + int i, n = (t_int)(w[4]); + float wn[10]; + float a0=x->a0, a1=x->a1, a2=x->a2; + float b1=x->b1, b2=x->b2; + + sigfilter_dsp_tick(x); + wn[0] = x->wn2; + wn[1] = x->wn1; + for(i=0; i<n; i+=8, in+=8, out+=8) + { + wn[2] = in[0] + b1*wn[1] + b2*wn[0]; + out[0] = a0*wn[2] + a1*wn[1] + a2*wn[0]; + wn[3] = in[1] + b1*wn[2] + b2*wn[1]; + out[1] = a0*wn[3] + a1*wn[2] + a2*wn[1]; + wn[4] = in[2] + b1*wn[3] + b2*wn[2]; + out[2] = a0*wn[4] + a1*wn[3] + a2*wn[2]; + wn[5] = in[3] + b1*wn[4] + b2*wn[3]; + out[3] = a0*wn[5] + a1*wn[4] + a2*wn[3]; + wn[6] = in[4] + b1*wn[5] + b2*wn[4]; + out[4] = a0*wn[6] + a1*wn[5] + a2*wn[4]; + wn[7] = in[5] + b1*wn[6] + b2*wn[5]; + out[5] = a0*wn[7] + a1*wn[6] + a2*wn[5]; + wn[8] = in[6] + b1*wn[7] + b2*wn[6]; + out[6] = a0*wn[8] + a1*wn[7] + a2*wn[6]; + wn[9] = in[7] + b1*wn[8] + b2*wn[7]; + out[7] = a0*wn[9] + a1*wn[8] + a2*wn[7]; + wn[0] = wn[8]; + wn[1] = wn[9]; + } + /* NAN protect */ + if(PD_BADFLOAT(wn[0])) + wn[0] = 0.0f; + if(PD_BADFLOAT(wn[1])) + wn[1] = 0.0f; + + x->wn1 = wn[1]; + x->wn2 = wn[0]; + return(w+5); +} + +static t_int *sigfilter_perform_1o(t_int *w) +{ + float *in = (float *)(w[1]); + float *out = (float *)(w[2]); + t_sigfilter *x = (t_sigfilter *)(w[3]); + int i, n = (t_int)(w[4]); + float wn0, wn1=x->wn1; + float a0=x->a0, a1=x->a1; + float b1=x->b1; + + sigfilter_dsp_tick(x); + for(i=0; i<n; i++) + { + wn0 = *in++ + b1*wn1; + *out++ = a0*wn0 + a1*wn1; + wn1 = wn0; + } + /* NAN protect */ + if(PD_BADFLOAT(wn1)) + wn1 = 0.0f; + + x->wn1 = wn1; + return(w+5); +} + +static t_int *sigfilter_perf8_1o(t_int *w) +{ + float *in = (float *)(w[1]); + float *out = (float *)(w[2]); + t_sigfilter *x = (t_sigfilter *)(w[3]); + int i, n = (t_int)(w[4]); + float wn[9]; + float a0=x->a0, a1=x->a1; + float b1=x->b1; + + sigfilter_dsp_tick(x); + wn[0] = x->wn1; + for(i=0; i<n; i+=8, in+=8, out+=8) + { + wn[1] = in[0] + b1*wn[0]; + out[0] = a0*wn[1] + a1*wn[0]; + wn[2] = in[1] + b1*wn[1]; + out[1] = a0*wn[2] + a1*wn[1]; + wn[3] = in[2] + b1*wn[2]; + out[2] = a0*wn[3] + a1*wn[2]; + wn[4] = in[3] + b1*wn[3]; + out[3] = a0*wn[4] + a1*wn[3]; + wn[5] = in[4] + b1*wn[4]; + out[4] = a0*wn[5] + a1*wn[4]; + wn[6] = in[5] + b1*wn[5]; + out[5] = a0*wn[6] + a1*wn[5]; + wn[7] = in[6] + b1*wn[6]; + out[6] = a0*wn[7] + a1*wn[6]; + wn[8] = in[7] + b1*wn[7]; + out[7] = a0*wn[8] + a1*wn[7]; + wn[0] = wn[8]; + } + /* NAN protect */ + if(PD_BADFLOAT(wn[0])) + wn[0] = 0.0f; + + x->wn1 = wn[0]; + return(w+5); +} + +static void sigfilter_ft4(t_sigfilter *x, t_floatarg t) +{ + int i = (int)((x->ticks_per_interpol_time)*t+0.49999f); + + x->interpol_time = t; + if(i <= 0) + { + x->ticks = 1; + x->rcp_ticks = 1.0; + } + else + { + x->ticks = i; + x->rcp_ticks = 1.0 / (float)i; + } +} + +static void sigfilter_ft3(t_sigfilter *x, t_floatarg b) +{ + if(b <= 0.0f) + b = 0.000001f; + if(x->hp) + b = 1.0 / b; + if(b != x->cur_b) + { + x->end_b = b; + x->counter_b = x->ticks; + x->delta_b = exp(log(b/x->cur_b)*x->rcp_ticks); + x->event_mask |= 4;/*set event_mask_bit 2 = 1*/ + } +} + +static void sigfilter_ft2(t_sigfilter *x, t_floatarg a) +{ + if(a <= 0.0f) + a = 0.000001f; + if(x->inv) + a = 1.0f / a; + if(x->hp) + a /= x->cur_b; + if(a != x->cur_a) + { + x->end_a = a; + x->counter_a = x->ticks; + x->delta_a = exp(log(a/x->cur_a)*x->rcp_ticks); + x->event_mask |= 2;/*set event_mask_bit 1 = 1*/ + } +} + +static void sigfilter_ft1(t_sigfilter *x, t_floatarg f) +{ + if(f <= 0.0f) + f = 0.000001f; + if(f != x->cur_f) + { + x->end_f = f; + x->counter_f = x->ticks; + x->delta_f = exp(log(f/x->cur_f)*x->rcp_ticks); + x->event_mask |= 1;/*set event_mask_bit 0 = 1*/ + } +} + +static void sigfilter_print(t_sigfilter *x) +{ +// post("fb1 = %g, fb2 = %g, ff1 = %g, ff2 = %g, ff3 = %g", x->b1, x->b2, x->a0, x->a1, x->a2); + x->x_at[0].a_w.w_float = x->b1; + x->x_at[1].a_w.w_float = x->b2; + x->x_at[2].a_w.w_float = x->a0; + x->x_at[3].a_w.w_float = x->a1; + x->x_at[4].a_w.w_float = x->a2; + outlet_list(x->x_debug_outlet, &s_list, 5, x->x_at); +} + +static void sigfilter_dsp(t_sigfilter *x, t_signal **sp) +{ + float si, co, f; + int i, n=(int)sp[0]->s_n; + + x->sr = 3.14159265358979323846f / (float)(sp[0]->s_sr); + x->ticks_per_interpol_time = 0.001f * (float)(sp[0]->s_sr) / (float)n; + i = (int)((x->ticks_per_interpol_time)*(x->interpol_time)+0.49999f); + if(i <= 0) + { + x->ticks = 1; + x->rcp_ticks = 1.0f; + } + else + { + x->ticks = i; + x->rcp_ticks = 1.0f / (float)i; + } + f = x->cur_f * x->sr; + if(f < 1.0e-20f) + x->cur_l = 1.0e20f; + else if(f > 1.57079632f) + x->cur_l = 0.0f; + else + { + si = sin(f); + co = cos(f); + x->cur_l = co/si; + } + if(x->first_order) + { + if(n&7) + dsp_add(sigfilter_perform_1o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n); + else + dsp_add(sigfilter_perf8_1o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n); + } + else + { + if(n&7) + dsp_add(sigfilter_perform_2o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n); + else + dsp_add(sigfilter_perf8_2o, 4, sp[0]->s_vec, sp[1]->s_vec, x, n); + } +} + +static void *sigfilter_new(t_symbol *s, int argc, t_atom *argv) +{ + t_sigfilter *x = (t_sigfilter *)pd_new(sigfilter_class); + char *filt_name; + int i; + float si, co, f=0.0f, a=0.0f, b=0.0f, interpol=0.0f; + t_symbol *filt_typ=gensym(""); + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft3")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft4")); + outlet_new(&x->x_obj, &s_signal); + x->x_debug_outlet = outlet_new(&x->x_obj, &s_list); + x->x_msi = 0.0f; + + x->x_at[0].a_type = A_FLOAT; + x->x_at[1].a_type = A_FLOAT; + x->x_at[2].a_type = A_FLOAT; + x->x_at[3].a_type = A_FLOAT; + x->x_at[4].a_type = A_FLOAT; + + x->event_mask = 1; + x->counter_f = 1; + x->counter_a = 0; + x->counter_b = 0; + x->delta_f = 0.0f; + x->delta_a = 0.0f; + x->delta_b = 0.0f; + x->interpol_time = 0.0f; + x->wn1 = 0.0f; + x->wn2 = 0.0f; + x->a0 = 0.0f; + x->a1 = 0.0f; + x->a2 = 0.0f; + x->b1 = 0.0f; + x->b2 = 0.0f; + x->sr = 3.14159265358979323846f / 44100.0f; + x->calc = sigfilter_snafu; + x->first_order = 0; + if((argc == 5)&&IS_A_FLOAT(argv,4)&&IS_A_FLOAT(argv,3)&&IS_A_FLOAT(argv,2)&&IS_A_FLOAT(argv,1)&&IS_A_SYMBOL(argv,0)) + { + filt_typ = atom_getsymbolarg(0, argc, argv); + f = (float)atom_getfloatarg(1, argc, argv); + a = (float)atom_getfloatarg(2, argc, argv); + b = (float)atom_getfloatarg(3, argc, argv); + interpol = (float)atom_getfloatarg(4, argc, argv); + } + filt_name = (char *)filt_typ->s_name; + x->cur_f = f; + f *= x->sr; + if(f < 1.0e-20f) + x->cur_l = 1.0e20f; + else if(f > 1.57079632f) + x->cur_l = 0.0f; + else + { + si = sin(f); + co = cos(f); + x->cur_l = co/si; + } + if(a <= 0.0f) + a = 0.000001f; + if(b <= 0.0f) + b = 0.000001f; + x->cur_b = b; + + if(interpol <= 0.0f) + interpol = 0.0f; + x->interpol_time = interpol; + x->ticks_per_interpol_time = 0.001f * 44100.0f / 64.0f; + i = (int)((x->ticks_per_interpol_time)*(x->interpol_time)+0.49999f); + if(i <= 0) + { + x->ticks = 1; + x->rcp_ticks = 1.0f; + } + else + { + x->ticks = i; + x->rcp_ticks = 1.0f / (float)i; + } + + x->calc = sigfilter_snafu; + + x->cur_a = 1.0f/a; /*a was Q*/ + x->inv = 1; + x->hp = 0; + + if(filt_name) + { + if(!strcmp(filt_name,"ap1")) + { + x->calc = sigfilter_ap1; + x->a1 = 1.0f; + x->first_order = 1; + } + else if(!strcmp(filt_name,"ap2")) + { + x->calc = sigfilter_ap2; + x->a2 = 1.0f; + } + else if(!strcmp(filt_name,"ap1c")) + { + x->calc = sigfilter_ap1; + x->a1 = 1.0f; + x->inv = 0; + x->cur_a = a; /*a was damping*/ + x->first_order = 1; + } + else if(!strcmp(filt_name,"ap2c")) + { + x->calc = sigfilter_ap2; + x->a2 = 1.0f; + x->inv = 0; + x->cur_a = a; /*a was damping*/ + } + else if(!strcmp(filt_name,"bpq2")) + { + x->calc = sigfilter_bp2; + } + else if(!strcmp(filt_name,"rbpq2")) + { + x->calc = sigfilter_rp2; + } + else if(!strcmp(filt_name,"bsq2")) + { + x->calc = sigfilter_bs2; + } + else if(!strcmp(filt_name,"bpw2")) + { + x->calc = sigfilter_bpw2; + x->inv = 0; + x->cur_a = a; /*a was bw*/ + } + else if(!strcmp(filt_name,"rbpw2")) + { + x->calc = sigfilter_rpw2; + x->inv = 0; + x->cur_a = a; /*a was bw*/ + } + else if(!strcmp(filt_name,"bsw2")) + { + x->calc = sigfilter_bsw2; + x->inv = 0; + x->cur_a = a; /*a was bw*/ + } + else if(!strcmp(filt_name,"hp1")) + { + x->calc = sigfilter_hp1; + x->first_order = 1; + } + else if(!strcmp(filt_name,"hp2")) + { + x->calc = sigfilter_hp2; + } + else if(!strcmp(filt_name,"lp1")) + { + x->calc = sigfilter_lp1; + x->first_order = 1; + } + else if(!strcmp(filt_name,"lp2")) + { + x->calc = sigfilter_lp2; + } + else if(!strcmp(filt_name,"hp1c")) + { + x->calc = sigfilter_hp1; + x->cur_a = 1.0f / a; + x->first_order = 1; + } + else if(!strcmp(filt_name,"hp2c")) + { + x->calc = sigfilter_hp2; + x->inv = 0; + x->cur_a = a / b; + x->cur_b = 1.0f / b; + x->hp = 1; + } + else if(!strcmp(filt_name,"lp1c")) + { + x->calc = sigfilter_lp1; + x->inv = 0; + x->cur_a = a; /*a was damping*/ + x->first_order = 1; + } + else if(!strcmp(filt_name,"lp2c")) + { + x->calc = sigfilter_lp2; + x->inv = 0; + x->cur_a = a; /*a was damping*/ + } + else + { + post("filter~-Error: 1. initial-arguments: <sym> kind: \ + lp1, lp2, hp1, hp2, \ + lp1c, lp2c, hp1c, hp2c, \ + ap1, ap2, ap1c, ap2c, \ + bpq2, rbpq2, bsq2, \ + bpw2, rbpw2, bsw2!"); + } + x->end_f = x->cur_f; + x->end_a = x->cur_a; + x->end_b = x->cur_b; + } + return (x); +} + +void sigfilter_setup(void) +{ + sigfilter_class = class_new(gensym("filter~"), (t_newmethod)sigfilter_new, + 0, sizeof(t_sigfilter), 0, A_GIMME, 0); + CLASS_MAINSIGNALIN(sigfilter_class, t_sigfilter, x_msi); + class_addmethod(sigfilter_class, (t_method)sigfilter_dsp, gensym("dsp"), 0); + class_addmethod(sigfilter_class, (t_method)sigfilter_ft1, gensym("ft1"), A_FLOAT, 0); + class_addmethod(sigfilter_class, (t_method)sigfilter_ft2, gensym("ft2"), A_FLOAT, 0); + class_addmethod(sigfilter_class, (t_method)sigfilter_ft3, gensym("ft3"), A_FLOAT, 0); + class_addmethod(sigfilter_class, (t_method)sigfilter_ft4, gensym("ft4"), A_FLOAT, 0); + class_addmethod(sigfilter_class, (t_method)sigfilter_print, gensym("print"), 0); + class_sethelpsymbol(sigfilter_class, gensym("iemhelp/help-filter~")); +} diff --git a/src/iemlib1/sighml_shelf.c b/src/iemlib1/sighml_shelf.c new file mode 100644 index 0000000..ef209d1 --- /dev/null +++ b/src/iemlib1/sighml_shelf.c @@ -0,0 +1,558 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + + +/* ---------- hml_shelf~ - high-middle-low-shelving filter ----------- */ + +typedef struct sighml_shelf +{ + t_object x_obj; + float wn1; + float wn2; + float a0; + float a1; + float a2; + float b1; + float b2; + float sr; + float cur_lf; + float cur_hf; + float cur_lg; + float cur_mg; + float cur_hg; + float delta_lf; + float delta_hf; + float delta_lg; + float delta_mg; + float delta_hg; + float end_lf; + float end_hf; + float end_lg; + float end_mg; + float end_hg; + float ticks_per_interpol_time; + float rcp_ticks; + float interpol_time; + int ticks; + int counter_lf; + int counter_hf; + int counter_lg; + int counter_mg; + int counter_hg; + int event_mask; + void *x_debug_outlet; + t_atom x_at[5]; + float x_msi; +} t_sighml_shelf; + +t_class *sighml_shelf_class; + +static void sighml_shelf_calc(t_sighml_shelf *x) +{ + float rf = x->cur_hf/x->cur_lf; + float mf = x->cur_hf*x->cur_lf; + float lg = x->cur_lg; + float rcplg = 1.0f/lg; + float mg = x->cur_mg; + float rcpmg = 1.0f/mg; + float hg = x->cur_hg; + float rcphg = 1.0f/hg; + float f = mf*x->sr; + float l = cos(f)/sin(f); + float k1 = rf*l; + float k2 = l/rf; + float k3 = l*l; + float k4 = k3*hg; + float k5 = k3*rcphg; + float k6 = rcplg + k5; + float k7 = rcpmg*k1 + k2*rcplg*rcphg*mg; + float k8 = lg + k4; + float k9 = mg*k1 + k2*lg*hg*rcpmg; + float k10 = 1.0f/(k6 + k7); + + x->b2 = k10*(k7 - k6); + x->b1 = k10*2.0f*(k5 - rcplg); + x->a2 = k10*(k8 - k9); + x->a1 = k10*2.0f*(lg - k4); + x->a0 = k10*(k8 + k9); +} +/* +high- & low- shelving-filter: +L....sqrt(lowlevel); +rL...rsqrt(lowlevel); +M....sqrt(mediumlevel); +rM...rsqrt(mediumlevel); +H....sqrt(highlevel); +rH...rsqrt(highlevel); +V....sqrt(highfrequency/lowfrequency); +P....j*2*pi*f/(2*pi*V*lowfrequency); + +Y/X = [M/(1/M)] * [(L/M + PV)/(M/L + PV)] * [(1 + HP/(VM))/(1 + MP/(VH))]; +Y/X = (L + P*(M*V + L*H/(V*M)) + P*P*H) / (rL + P*(rM*V + rL*rH/(V*rM)) + P*P*rH); + +hlshlv: lowlevel: ll; mediumlevel: lm; highlevel: hl; lowfrequency: fl; highfrequency: fh; samplerate: sr; + { + V = sqrt(fh/fl); + f = fl*V; + L = sqrt(ll); + rL = 1.0/L; + M = sqrt(lm); + rM = 1.0/M; + H = sqrt(lh); + rH = 1.0/H; + + l = cot(f*3.14159265358979323846/sr); + k1 = V*l; + k2 = l/V; + l2 = l*l; + l3 = l2*H; + l4 = l2*rH; + m1 = k2*L*H*rM; + m2 = k2*rL*rH*M; + n1 = rL + l4; + n2 = rM*k1 + m2; + p1 = L + l3; + p2 = M*k1 + m1; + a012 = 1.0/(n1 + n2); + + b2 = a012*(n2 - n1); + b1 = a012*2.0*(l4 - rL); + a2 = a012*(p1 - p2); + a1 = a012*2.0*(L - l3); + a0 = a012*(p1 + p2); + + + + + + + rf = sqrt(fh/fl); + mf = fl*rf; + L = sqrt(ll); + rL = 1.0/L; + M = sqrt(lm); + rM = 1.0/M; + H = sqrt(lh); + rH = 1.0/H; + + l = cot(fm*3.14159265358979323846/sr); + k1 = V*l; + k2 = l/V; + k3 = l*l; + k4 = k3*H; + k5 = k3*rH; + k6 = rL + k5; + k7 = rM*k1 + k2*rL*rH*M; + k8 = L + k4; + k9 = M*k1 + k2*L*H*rM; + k10 = 1.0/(k6 + k7); + + b2 = k10*(k7 - k6); + b1 = k10*2.0*(k5 - rL); + a2 = k10*(k8 - k9); + a1 = k10*2.0*(L - k4); + a0 = k10*(k8 + k9); +*/ + +static void sighml_shelf_dsp_tick(t_sighml_shelf *x) +{ + if(x->event_mask) + { + float discriminant; + + if(x->counter_lg) + { + if(x->counter_lg <= 1) + { + x->cur_lg = x->end_lg; + x->counter_lg = 0; + x->event_mask &= 30;/*set event_mask_bit 0 = 0*/ + } + else + { + x->counter_lg--; + x->cur_lg *= x->delta_lg; + } + } + if(x->counter_lf) + { + if(x->counter_lf <= 1) + { + x->cur_lf = x->end_lf; + x->counter_lf = 0; + x->event_mask &= 29;/*set event_mask_bit 1 = 0*/ + } + else + { + x->counter_lf--; + x->cur_lf *= x->delta_lf; + } + } + if(x->counter_mg) + { + if(x->counter_mg <= 1) + { + x->cur_mg = x->end_mg; + x->counter_mg = 0; + x->event_mask &= 27;/*set event_mask_bit 2 = 0*/ + } + else + { + x->counter_mg--; + x->cur_mg *= x->delta_mg; + } + } + if(x->counter_hf) + { + if(x->counter_hf <= 1) + { + x->cur_hf = x->end_hf; + x->counter_hf = 0; + x->event_mask &= 23;/*set event_mask_bit 3 = 0*/ + } + else + { + x->counter_hf--; + x->cur_hf *= x->delta_hf; + } + } + if(x->counter_hg) + { + if(x->counter_hg <= 1) + { + x->cur_hg = x->end_hg; + x->counter_hg = 0; + x->event_mask &= 15;/*set event_mask_bit 4 = 0*/ + } + else + { + x->counter_hg--; + x->cur_hg *= x->delta_hg; + } + } + sighml_shelf_calc(x); + + /* stability check */ + + discriminant = x->b1 * x->b1 + 4.0f * x->b2; + if(x->b1 <= -1.9999996f) + x->b1 = -1.9999996f; + else if(x->b1 >= 1.9999996f) + x->b1 = 1.9999996f; + + if(x->b2 <= -0.9999998f) + x->b2 = -0.9999998f; + else if(x->b2 >= 0.9999998f) + x->b2 = 0.9999998f; + + if(discriminant >= 0.0f) + { + if(0.9999998f - x->b1 - x->b2 < 0.0f) + x->b2 = 0.9999998f - x->b1; + if(0.9999998f + x->b1 - x->b2 < 0.0f) + x->b2 = 0.9999998f + x->b1; + } + } +} + +static t_int *sighml_shelf_perform(t_int *w) +{ + float *in = (float *)(w[1]); + float *out = (float *)(w[2]); + t_sighml_shelf *x = (t_sighml_shelf *)(w[3]); + int i, n = (t_int)(w[4]); + float wn0, wn1=x->wn1, wn2=x->wn2; + float a0=x->a0, a1=x->a1, a2=x->a2; + float b1=x->b1, b2=x->b2; + + sighml_shelf_dsp_tick(x); + for(i=0; i<n; i++) + { + wn0 = *in++ + b1*wn1 + b2*wn2; + *out++ = a0*wn0 + a1*wn1 + a2*wn2; + wn2 = wn1; + wn1 = wn0; + } + /* NAN protect */ + if(PD_BADFLOAT(wn2)) + wn2 = 0.0f; + if(PD_BADFLOAT(wn1)) + wn1 = 0.0f; + + x->wn1 = wn1; + x->wn2 = wn2; + return(w+5); +} +/* yn0 = *out; + xn0 = *in; + ************* + yn0 = a0*xn0 + a1*xn1 + a2*xn2 + b1*yn1 + b2*yn2; + yn2 = yn1; + yn1 = yn0; + xn2 = xn1; + xn1 = xn0; + ************************* + y/x = (a0 + a1*z-1 + a2*z-2)/(1 - b1*z-1 - b2*z-2);*/ + +static t_int *sighml_shelf_perf8(t_int *w) +{ + float *in = (float *)(w[1]); + float *out = (float *)(w[2]); + t_sighml_shelf *x = (t_sighml_shelf *)(w[3]); + int i, n = (t_int)(w[4]); + float wn[10]; + float a0=x->a0, a1=x->a1, a2=x->a2; + float b1=x->b1, b2=x->b2; + + sighml_shelf_dsp_tick(x); + wn[0] = x->wn2; + wn[1] = x->wn1; + for(i=0; i<n; i+=8, in+=8, out+=8) + { + wn[2] = in[0] + b1*wn[1] + b2*wn[0]; + out[0] = a0*wn[2] + a1*wn[1] + a2*wn[0]; + wn[3] = in[1] + b1*wn[2] + b2*wn[1]; + out[1] = a0*wn[3] + a1*wn[2] + a2*wn[1]; + wn[4] = in[2] + b1*wn[3] + b2*wn[2]; + out[2] = a0*wn[4] + a1*wn[3] + a2*wn[2]; + wn[5] = in[3] + b1*wn[4] + b2*wn[3]; + out[3] = a0*wn[5] + a1*wn[4] + a2*wn[3]; + wn[6] = in[4] + b1*wn[5] + b2*wn[4]; + out[4] = a0*wn[6] + a1*wn[5] + a2*wn[4]; + wn[7] = in[5] + b1*wn[6] + b2*wn[5]; + out[5] = a0*wn[7] + a1*wn[6] + a2*wn[5]; + wn[8] = in[6] + b1*wn[7] + b2*wn[6]; + out[6] = a0*wn[8] + a1*wn[7] + a2*wn[6]; + wn[9] = in[7] + b1*wn[8] + b2*wn[7]; + out[7] = a0*wn[9] + a1*wn[8] + a2*wn[7]; + wn[0] = wn[8]; + wn[1] = wn[9]; + } + /* NAN protect */ + if(PD_BADFLOAT(wn[0])) + wn[0] = 0.0f; + if(PD_BADFLOAT(wn[1])) + wn[1] = 0.0f; + + x->wn1 = wn[1]; + x->wn2 = wn[0]; + return(w+5); +} + +static void sighml_shelf_ft6(t_sighml_shelf *x, t_floatarg t) +{ + int i = (int)((x->ticks_per_interpol_time)*t); + + x->interpol_time = t; + if(i <= 0) + i = 1; + x->ticks = i; + x->rcp_ticks = 1.0f / (float)i; +} + +static void sighml_shelf_ft5(t_sighml_shelf *x, t_floatarg hl) +{ + float hg = exp(0.057564627325 * hl); + + if(hg != x->cur_hg) + { + x->end_hg = hg; + x->counter_hg = x->ticks; + x->delta_hg = exp(log(hg/x->cur_hg)*x->rcp_ticks); + x->event_mask |= 16;/*set event_mask_bit 4 = 1*/ + } +} + +static void sighml_shelf_ft4(t_sighml_shelf *x, t_floatarg hf) +{ + float sqhf; + + if(hf <= 0.0f) + hf = 0.000001f; + sqhf = sqrt(hf); + if(sqhf != x->cur_hf) + { + x->end_hf = sqhf; + x->counter_hf = x->ticks; + x->delta_hf = exp(log(sqhf/x->cur_hf)*x->rcp_ticks); + x->event_mask |= 8;/*set event_mask_bit 3 = 1*/ + } +} + +static void sighml_shelf_ft3(t_sighml_shelf *x, t_floatarg ml) +{ + float mg = exp(0.057564627325 * ml); + + if(mg != x->cur_mg) + { + x->end_mg = mg; + x->counter_mg = x->ticks; + x->delta_mg = exp(log(mg/x->cur_mg)*x->rcp_ticks); + x->event_mask |= 4;/*set event_mask_bit 2 = 1*/ + } +} + +static void sighml_shelf_ft2(t_sighml_shelf *x, t_floatarg lf) +{ + float sqlf; + + if(lf <= 0.0f) + lf = 0.000001f; + sqlf = sqrt(lf); + if(sqlf != x->cur_lf) + { + x->end_lf = sqlf; + x->counter_lf = x->ticks; + x->delta_lf = exp(log(sqlf/x->cur_lf)*x->rcp_ticks); + x->event_mask |= 2;/*set event_mask_bit 1 = 1*/ + } +} + +static void sighml_shelf_ft1(t_sighml_shelf *x, t_floatarg ll) +{ + float lg = exp(0.057564627325 * ll); + + if(lg != x->cur_lg) + { + x->end_lg = lg; + x->counter_lg = x->ticks; + x->delta_lg = exp(log(lg/x->cur_lg)*x->rcp_ticks); + x->event_mask |= 1;/*set event_mask_bit 0 = 1*/ + } +} + +static void sighml_shelf_print(t_sighml_shelf *x) +{ +// post("fb1 = %g, fb2 = %g, ff1 = %g, ff2 = %g, ff3 = %g", x->b1, x->b2, x->a0, x->a1, x->a2); + x->x_at[0].a_w.w_float = x->b1; + x->x_at[1].a_w.w_float = x->b2; + x->x_at[2].a_w.w_float = x->a0; + x->x_at[3].a_w.w_float = x->a1; + x->x_at[4].a_w.w_float = x->a2; + outlet_list(x->x_debug_outlet, &s_list, 5, x->x_at); +} + +static void sighml_shelf_dsp(t_sighml_shelf *x, t_signal **sp) +{ + int i, n=(int)sp[0]->s_n; + + x->sr = 3.14159265358979323846f / (float)(sp[0]->s_sr); + x->ticks_per_interpol_time = 0.001f * (float)(sp[0]->s_sr) / (float)n; + i = (int)((x->ticks_per_interpol_time)*(x->interpol_time)); + if(i <= 0) + i = 1; + x->ticks = i; + x->rcp_ticks = 1.0f / (float)i; + if(n&7) + dsp_add(sighml_shelf_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, n); + else + dsp_add(sighml_shelf_perf8, 4, sp[0]->s_vec, sp[1]->s_vec, x, n); +} + +static void *sighml_shelf_new(t_symbol *s, int argc, t_atom *argv) +{ + t_sighml_shelf *x = (t_sighml_shelf *)pd_new(sighml_shelf_class); + int i; + float lf=200.0f, hf=2000.0f, ll=0.0f, ml=0.0f, hl=0.0f, interpol=0.0f; + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft3")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft4")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft5")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft6")); + outlet_new(&x->x_obj, &s_signal); + x->x_debug_outlet = outlet_new(&x->x_obj, &s_list); + x->x_msi = 0; + + x->x_at[0].a_type = A_FLOAT; + x->x_at[1].a_type = A_FLOAT; + x->x_at[2].a_type = A_FLOAT; + x->x_at[3].a_type = A_FLOAT; + x->x_at[4].a_type = A_FLOAT; + + x->event_mask = 2; + x->counter_lg = 0; + x->counter_lf = 1; + x->counter_mg = 0; + x->counter_hf = 0; + x->counter_hg = 0; + x->delta_lg = 0.0f; + x->delta_lf = 0.0f; + x->delta_mg = 0.0f; + x->delta_hf = 0.0f; + x->delta_hg = 0.0f; + x->interpol_time = 0.0f; + x->wn1 = 0.0f; + x->wn2 = 0.0f; + x->a0 = 0.0f; + x->a1 = 0.0f; + x->a2 = 0.0f; + x->b1 = 0.0f; + x->b2 = 0.0f; + x->sr = 3.14159265358979323846f / 44100.0f; + if((argc == 6)&&IS_A_FLOAT(argv,5)&&IS_A_FLOAT(argv,4)&&IS_A_FLOAT(argv,3) + &&IS_A_FLOAT(argv,2)&&IS_A_FLOAT(argv,1)&&IS_A_FLOAT(argv,0)) + { + ll = (float)atom_getfloatarg(0, argc, argv); + lf = (float)atom_getfloatarg(1, argc, argv); + ml = (float)atom_getfloatarg(2, argc, argv); + hf = (float)atom_getfloatarg(3, argc, argv); + hl = (float)atom_getfloatarg(4, argc, argv); + interpol = (float)atom_getfloatarg(5, argc, argv); + } + x->cur_lg = exp(0.057564627325 * ll); + x->cur_mg = exp(0.057564627325 * ml); + x->cur_hg = exp(0.057564627325 * hl); + if(lf <= 0.0f) + lf = 0.000001f; + if(hf <= 0.0f) + hf = 0.000001f; + x->cur_lf = sqrt(lf); + x->cur_hf = sqrt(hf); + if(interpol < 0.0f) + interpol = 0.0f; + x->interpol_time = interpol; + x->ticks_per_interpol_time = 0.5f; + i = (int)((x->ticks_per_interpol_time)*(x->interpol_time)); + if(i <= 0) + i = 1; + x->ticks = i; + x->rcp_ticks = 1.0f / (float)i; + x->end_lf = x->cur_lf; + x->end_hf = x->cur_hf; + x->end_lg = x->cur_lg; + x->end_mg = x->cur_mg; + x->end_hg = x->cur_hg; + return(x); +} + +void sighml_shelf_setup(void) +{ + sighml_shelf_class = class_new(gensym("hml_shelf~"), (t_newmethod)sighml_shelf_new, + 0, sizeof(t_sighml_shelf), 0, A_GIMME, 0); + CLASS_MAINSIGNALIN(sighml_shelf_class, t_sighml_shelf, x_msi); + class_addmethod(sighml_shelf_class, (t_method)sighml_shelf_dsp, gensym("dsp"), 0); + class_addmethod(sighml_shelf_class, (t_method)sighml_shelf_ft1, gensym("ft1"), A_FLOAT, 0); + class_addmethod(sighml_shelf_class, (t_method)sighml_shelf_ft2, gensym("ft2"), A_FLOAT, 0); + class_addmethod(sighml_shelf_class, (t_method)sighml_shelf_ft3, gensym("ft3"), A_FLOAT, 0); + class_addmethod(sighml_shelf_class, (t_method)sighml_shelf_ft4, gensym("ft4"), A_FLOAT, 0); + class_addmethod(sighml_shelf_class, (t_method)sighml_shelf_ft5, gensym("ft5"), A_FLOAT, 0); + class_addmethod(sighml_shelf_class, (t_method)sighml_shelf_ft6, gensym("ft6"), A_FLOAT, 0); + class_addmethod(sighml_shelf_class, (t_method)sighml_shelf_print, gensym("print"), 0); + class_sethelpsymbol(sighml_shelf_class, gensym("iemhelp/help-hml_shelf~")); +} diff --git a/src/iemlib1/sigiem_cot4.c b/src/iemlib1/sigiem_cot4.c new file mode 100644 index 0000000..b0990d9 --- /dev/null +++ b/src/iemlib1/sigiem_cot4.c @@ -0,0 +1,176 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* ------------------------ iem_cot4~ ----------------------------- */ + +float *iem_cot4_table_cos=(float *)0L; +float *iem_cot4_table_sin=(float *)0L; + +static t_class *sigiem_cot4_class; + +typedef struct _sigiem_cot4 +{ + t_object x_obj; + float x_sr; + float x_msi; +} t_sigiem_cot4; + +static t_int *sigiem_cot4_perform(t_int *w) +{ + t_float *in = (t_float *)(w[1]); + t_float *out = (t_float *)(w[2]); + t_float norm_freq; + t_float hout; + t_sigiem_cot4 *x = (t_sigiem_cot4 *)(w[3]); + t_float sr=x->x_sr; + int n = (int)(w[4]); + float *ctab = iem_cot4_table_cos, *stab = iem_cot4_table_sin; + float *caddr, *saddr, cf1, cf2, sf1, sf2, frac; + double dphase; + int normhipart; + int32 mytfi; + union tabfudge tf; + + tf.tf_d = UNITBIT32; + normhipart = tf.tf_i[HIOFFSET]; + +#if 0 /* this is the readable version of the code. */ + while (n--) + { + norm_freq = *in * sr; + if(norm_freq < 0.0001f) + norm_freq = 0.0001f; + else if(norm_freq > 0.9f) + norm_freq = 0.9f; + dphase = (double)(norm_freq * (float)(COSTABSIZE)) + UNITBIT32; + tf.tf_d = dphase; + mytfi = tf.tf_i[HIOFFSET] & (COSTABSIZE-1); + saddr = stab + (mytfi); + caddr = ctab + (mytfi); + tf.tf_i[HIOFFSET] = normhipart; + frac = tf.tf_d - UNITBIT32; + sf1 = saddr[0]; + sf2 = saddr[1]; + cf1 = caddr[0]; + cf2 = caddr[1]; + in++; + *out++ = (cf1 + frac * (cf2 - cf1))/(sf1 + frac * (sf2 - sf1)); + } +#endif +#if 1 /* this is the same, unwrapped by hand. prolog beg*/ + n /= 4; + norm_freq = *in * sr; + if(norm_freq < 0.0001f) + norm_freq = 0.0001f; + else if(norm_freq > 0.9f) + norm_freq = 0.9f; + dphase = (double)(norm_freq * (float)(COSTABSIZE)) + UNITBIT32; + tf.tf_d = dphase; + mytfi = tf.tf_i[HIOFFSET] & (COSTABSIZE-1); + saddr = stab + (mytfi); + caddr = ctab + (mytfi); + tf.tf_i[HIOFFSET] = normhipart; + in += 4; /*prolog end*/ + while (--n) + { + norm_freq = *in * sr; + if(norm_freq < 0.0001f) + norm_freq = 0.0001f; + else if(norm_freq > 0.9f) + norm_freq = 0.9f; + dphase = (double)(norm_freq * (float)(COSTABSIZE)) + UNITBIT32; + frac = tf.tf_d - UNITBIT32; + tf.tf_d = dphase; + sf1 = saddr[0]; + sf2 = saddr[1]; + cf1 = caddr[0]; + cf2 = caddr[1]; + mytfi = tf.tf_i[HIOFFSET] & (COSTABSIZE-1); + saddr = stab + (mytfi); + caddr = ctab + (mytfi); + hout = (cf1 + frac * (cf2 - cf1))/(sf1 + frac * (sf2 - sf1)); + *out++ = hout; + *out++ = hout; + *out++ = hout; + *out++ = hout; + in += 4; + tf.tf_i[HIOFFSET] = normhipart; + }/*epilog beg*/ + frac = tf.tf_d - UNITBIT32; + sf1 = saddr[0]; + sf2 = saddr[1]; + cf1 = caddr[0]; + cf2 = caddr[1]; + hout = (cf1 + frac * (cf2 - cf1))/(sf1 + frac * (sf2 - sf1)); + *out++ = hout; + *out++ = hout; + *out++ = hout; + *out++ = hout; + /*epilog end*/ +#endif + return (w+5); +} + +static void sigiem_cot4_dsp(t_sigiem_cot4 *x, t_signal **sp) +{ + x->x_sr = 2.0f / (float)sp[0]->s_sr; + dsp_add(sigiem_cot4_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n); +} + +static void sigiem_cot4_maketable(void) +{ + int i; + float *fp, phase, fff, phsinc = 0.5*3.141592653 / ((float)COSTABSIZE); + union tabfudge tf; + + if(!iem_cot4_table_sin) + { + iem_cot4_table_sin = (float *)getbytes(sizeof(float) * (COSTABSIZE+1)); + for(i=COSTABSIZE+1, fp=iem_cot4_table_sin, phase=0; i--; fp++, phase+=phsinc) + *fp = sin(phase); + } + if(!iem_cot4_table_cos) + { + iem_cot4_table_cos = (float *)getbytes(sizeof(float) * (COSTABSIZE+1)); + for(i=COSTABSIZE+1, fp=iem_cot4_table_cos, phase=0; i--; fp++, phase+=phsinc) + *fp = cos(phase); + } + tf.tf_d = UNITBIT32 + 0.5; + if((unsigned)tf.tf_i[LOWOFFSET] != 0x80000000) + bug("iem_cot4~: unexpected machine alignment"); +} + +static void *sigiem_cot4_new(void) +{ + t_sigiem_cot4 *x = (t_sigiem_cot4 *)pd_new(sigiem_cot4_class); + + outlet_new(&x->x_obj, gensym("signal")); + x->x_msi = 0; + return (x); +} + +void sigiem_cot4_setup(void) +{ + sigiem_cot4_class = class_new(gensym("iem_cot4~"), (t_newmethod)sigiem_cot4_new, 0, + sizeof(t_sigiem_cot4), 0, 0); + class_addcreator((t_newmethod)sigiem_cot4_new, gensym("iem_cot~"), 0); + CLASS_MAINSIGNALIN(sigiem_cot4_class, t_sigiem_cot4, x_msi); + class_addmethod(sigiem_cot4_class, (t_method)sigiem_cot4_dsp, gensym("dsp"), 0); + sigiem_cot4_maketable(); + class_sethelpsymbol(sigiem_cot4_class, gensym("iemhelp/help-iem_cot4~")); +} + diff --git a/src/iemlib1/sigiem_delay.c b/src/iemlib1/sigiem_delay.c new file mode 100644 index 0000000..56afbf3 --- /dev/null +++ b/src/iemlib1/sigiem_delay.c @@ -0,0 +1,208 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil (c) IEM KUG Graz Austria 2002 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* -------------------------- sigiem_delay~ ------------------------------ */ +static t_class *sigiem_delay_class; + +#define IEMDELAY_DEF_VEC_SIZE 64 + +typedef struct _sigiem_delay +{ + t_object x_obj; + int x_mallocsize; + t_float x_max_delay_ms; + t_float x_current_delay_ms; + t_float *x_begmem1; + t_float *x_begmem2; + int x_writeindex; + int x_blocksize; + int x_delay_samples; + t_float x_sr; + t_float x_msi; +} t_sigiem_delay; + +static void sigiem_delay_cur_del(t_sigiem_delay *x, t_floatarg f) +{ + if(f < 0.0f) + f = 0.0f; + else if(f > x->x_max_delay_ms) + f = x->x_max_delay_ms; + x->x_current_delay_ms = f; + x->x_delay_samples = (int)(0.001f*x->x_sr * f + 0.5f); +} + +static t_int *sigiem_delay_perform(t_int *w) +{ + t_float *in = (t_float *)(w[1]); + t_float *out = (t_float *)(w[2]); + t_sigiem_delay *x = (t_sigiem_delay *)(w[3]); + int n=(int)(w[4]); + int writeindex = x->x_writeindex; + t_float *vec1, *vec2, *vec3; + + vec1 = x->x_begmem1 + writeindex; + vec2 = x->x_begmem2 + writeindex; + vec3 = x->x_begmem2 + writeindex - x->x_delay_samples; + writeindex += n; + while(n--) + { + *vec1++ = *vec2++ = *in++; + *out++ = *vec3++; + } + if(writeindex >= x->x_mallocsize) + { + writeindex -= x->x_mallocsize; + } + x->x_writeindex = writeindex; + return(w+5); +} + +static t_int *sigiem_delay_perf8(t_int *w) +{ + t_float *in = (t_float *)(w[1]); + t_float *out = (t_float *)(w[2]); + t_sigiem_delay *x = (t_sigiem_delay *)(w[3]); + int i, n=(int)(w[4]); + int writeindex = x->x_writeindex; + t_float *vec1, *vec2; + + vec1 = x->x_begmem1 + writeindex; + vec2 = x->x_begmem2 + writeindex; + for(i=0; i<n; i+=8) + { + *vec1++ = *vec2++ = *in++; + *vec1++ = *vec2++ = *in++; + *vec1++ = *vec2++ = *in++; + *vec1++ = *vec2++ = *in++; + *vec1++ = *vec2++ = *in++; + *vec1++ = *vec2++ = *in++; + *vec1++ = *vec2++ = *in++; + *vec1++ = *vec2++ = *in++; + } + + vec2 = x->x_begmem2 + writeindex - x->x_delay_samples; + for(i=0; i<n; i+=8) + { + *out++ = *vec2++; + *out++ = *vec2++; + *out++ = *vec2++; + *out++ = *vec2++; + *out++ = *vec2++; + *out++ = *vec2++; + *out++ = *vec2++; + *out++ = *vec2++; + } + + writeindex += n; + if(writeindex >= x->x_mallocsize) + { + writeindex -= x->x_mallocsize; + } + x->x_writeindex = writeindex; + return(w+5); +} + +static void sigiem_delay_dsp(t_sigiem_delay *x, t_signal **sp) +{ + int blocksize = sp[0]->s_n, i; + + if(!x->x_blocksize)/*first time*/ + { + int nsamps = x->x_max_delay_ms * (t_float)sp[0]->s_sr * 0.001f; + + if(nsamps < 1) + nsamps = 1; + nsamps += ((- nsamps) & (blocksize - 1)); + nsamps += blocksize; + x->x_mallocsize = nsamps; + x->x_begmem1 = (t_float *)getbytes(2 * x->x_mallocsize * sizeof(t_float)); + x->x_begmem2 = x->x_begmem1 + x->x_mallocsize; + post("beginn = %x", (unsigned long)x->x_begmem1); + x->x_writeindex = blocksize; + x->x_sr = (t_float)sp[0]->s_sr; + x->x_blocksize = blocksize; + x->x_delay_samples = (int)(0.001f*x->x_sr * x->x_current_delay_ms + 0.5f); + } + else if((x->x_blocksize != blocksize) || ((t_float)sp[0]->s_sr != x->x_sr)) + { + int nsamps = x->x_max_delay_ms * (t_float)sp[0]->s_sr * 0.001f; + + if(nsamps < 1) + nsamps = 1; + nsamps += ((- nsamps) & (blocksize - 1)); + nsamps += blocksize; + + x->x_begmem1 = (t_float *)resizebytes(x->x_begmem1, 2*x->x_mallocsize*sizeof(t_float), 2*nsamps*sizeof(t_float)); + x->x_mallocsize = nsamps; + x->x_begmem2 = x->x_begmem1 + x->x_mallocsize; + post("beginn = %x", (unsigned long)x->x_begmem1); + if(x->x_writeindex >= nsamps) + x->x_writeindex -= nsamps; + x->x_sr = (t_float)sp[0]->s_sr; + x->x_blocksize = blocksize; + x->x_delay_samples = (int)(0.001f*x->x_sr * x->x_current_delay_ms + 0.5f); + } + + if(blocksize&7) + dsp_add(sigiem_delay_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, blocksize); + else + dsp_add(sigiem_delay_perf8, 4, sp[0]->s_vec, sp[1]->s_vec, x, blocksize); +} + +static void *sigiem_delay_new(t_floatarg max_delay_ms, t_floatarg current_delay_ms) +{ + t_sigiem_delay *x = (t_sigiem_delay *)pd_new(sigiem_delay_class); + int nsamps; + + if(max_delay_ms < 2.0f) + max_delay_ms = 2.0f; + x->x_max_delay_ms = max_delay_ms; + if(current_delay_ms < 0.0f) + current_delay_ms = 0.0f; + else if(current_delay_ms > max_delay_ms) + current_delay_ms = max_delay_ms; + x->x_current_delay_ms = current_delay_ms; + nsamps = max_delay_ms * sys_getsr() * 0.001f; + if(nsamps < 1) + nsamps = 1; + nsamps += ((- nsamps) & (IEMDELAY_DEF_VEC_SIZE - 1)); + nsamps += IEMDELAY_DEF_VEC_SIZE; + x->x_mallocsize = nsamps; + x->x_begmem1 = (t_float *)getbytes(2 * x->x_mallocsize * sizeof(t_float)); + x->x_begmem2 = x->x_begmem1 + x->x_mallocsize; + x->x_writeindex = IEMDELAY_DEF_VEC_SIZE; + x->x_blocksize = 0; + x->x_sr = 0.0f; + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); + outlet_new(&x->x_obj, &s_signal); + x->x_msi = 0.0f; + return (x); +} + +static void sigiem_delay_free(t_sigiem_delay *x) +{ + freebytes(x->x_begmem1, 2 * x->x_mallocsize * sizeof(t_float)); +} + +void sigiem_delay_setup(void) +{ + sigiem_delay_class = class_new(gensym("iem_delay~"), (t_newmethod)sigiem_delay_new, (t_method)sigiem_delay_free, + sizeof(t_sigiem_delay), 0, A_DEFFLOAT, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(sigiem_delay_class, t_sigiem_delay, x_msi); + class_addmethod(sigiem_delay_class, (t_method)sigiem_delay_dsp, gensym("dsp"), 0); + class_addmethod(sigiem_delay_class, (t_method)sigiem_delay_cur_del, gensym("ft1"), A_FLOAT, 0); +} diff --git a/src/iemlib1/sigiem_pow4.c b/src/iemlib1/sigiem_pow4.c new file mode 100644 index 0000000..ae5334c --- /dev/null +++ b/src/iemlib1/sigiem_pow4.c @@ -0,0 +1,86 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* ------------------------ iem_pow4~ ----------------------------- */ + +static t_class *sigiem_pow4_class; + +typedef struct _sigiem_pow4 +{ + t_object x_obj; + float x_exp; + float x_msi; +} t_sigiem_pow4; + +static void sigiem_pow4_ft1(t_sigiem_pow4 *x, t_floatarg f) +{ + x->x_exp = f; +} + +static t_int *sigiem_pow4_perform(t_int *w) +{ + t_float *in = (t_float *)(w[1]); + t_float *out = (t_float *)(w[2]); + t_sigiem_pow4 *x = (t_sigiem_pow4 *)(w[3]); + t_float y=x->x_exp; + t_float f, g; + int n = (int)(w[4])/4; + + while (n--) + { + f = *in; + if(f < 0.01f) + f = 0.01f; + else if(f > 1000.0f) + f = 1000.0f; + g = log(f); + f = exp(g*y); + *out++ = f; + *out++ = f; + *out++ = f; + *out++ = f; + in += 4; + } + return (w+5); +} + +static void sigiem_pow4_dsp(t_sigiem_pow4 *x, t_signal **sp) +{ + dsp_add(sigiem_pow4_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n); +} + +static void *sigiem_pow4_new(t_floatarg f) +{ + t_sigiem_pow4 *x = (t_sigiem_pow4 *)pd_new(sigiem_pow4_class); + + x->x_exp = f; + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); + outlet_new(&x->x_obj, gensym("signal")); + x->x_msi = 0; + return (x); +} + +void sigiem_pow4_setup(void) +{ + sigiem_pow4_class = class_new(gensym("iem_pow4~"), (t_newmethod)sigiem_pow4_new, 0, + sizeof(t_sigiem_pow4), 0, A_DEFFLOAT, 0); + class_addcreator((t_newmethod)sigiem_pow4_new, gensym("icot~"), 0); + CLASS_MAINSIGNALIN(sigiem_pow4_class, t_sigiem_pow4, x_msi); + class_addmethod(sigiem_pow4_class, (t_method)sigiem_pow4_dsp, gensym("dsp"), 0); + class_addmethod(sigiem_pow4_class, (t_method)sigiem_pow4_ft1, gensym("ft1"), A_FLOAT, 0); + class_sethelpsymbol(sigiem_pow4_class, gensym("iemhelp/help-iem_pow4~")); +} diff --git a/src/iemlib1/sigiem_sqrt4.c b/src/iemlib1/sigiem_sqrt4.c new file mode 100644 index 0000000..49d9982 --- /dev/null +++ b/src/iemlib1/sigiem_sqrt4.c @@ -0,0 +1,117 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +#define IEMSQRT4TAB1SIZE 256 +#define IEMSQRT4TAB2SIZE 1024 + +/* ------------------------ iem_sqrt4~ ----------------------------- */ + +float *iem_sqrt4_exptab=(float *)0L; +float *iem_sqrt4_mantissatab=(float *)0L; + +static t_class *sigiem_sqrt4_class; + +typedef struct _sigiem_sqrt4 +{ + t_object x_obj; + float x_msi; +} t_sigiem_sqrt4; + +static t_int *sigiem_sqrt4_perform(t_int *w) +{ + t_float *in = (t_float *)(w[1]); + t_float *out = (t_float *)(w[2]); + t_int n = (t_int)(w[3])/4; + + while(n--) + { + float f = *in; + float g, h; + long l = *(long *)(in); + + if(f < 0.0f) + { + *out++ = 0.0f; + *out++ = 0.0f; + *out++ = 0.0f; + *out++ = 0.0f; + } + else + { + g = iem_sqrt4_exptab[(l >> 23) & 0xff] * iem_sqrt4_mantissatab[(l >> 13) & 0x3ff]; + h = f * (1.5f * g - 0.5f * g * g * g * f); + *out++ = h; + *out++ = h; + *out++ = h; + *out++ = h; + } + in += 4; + } + return(w+4); +} + +static void sigiem_sqrt4_dsp(t_sigiem_sqrt4 *x, t_signal **sp) +{ + dsp_add(sigiem_sqrt4_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); +} + +static void sigiem_sqrt4_maketable(void) +{ + int i; + float f; + long l; + + if(!iem_sqrt4_exptab) + { + iem_sqrt4_exptab = (float *)getbytes(sizeof(float) * IEMSQRT4TAB1SIZE); + for(i=0; i<IEMSQRT4TAB1SIZE; i++) + { + l = (i ? (i == IEMSQRT4TAB1SIZE-1 ? IEMSQRT4TAB1SIZE-2 : i) : 1)<< 23; + *(long *)(&f) = l; + iem_sqrt4_exptab[i] = 1.0f/sqrt(f); + } + } + if(!iem_sqrt4_mantissatab) + { + iem_sqrt4_mantissatab = (float *)getbytes(sizeof(float) * IEMSQRT4TAB2SIZE); + for(i=0; i<IEMSQRT4TAB2SIZE; i++) + { + f = 1.0f + (1.0f/(float)IEMSQRT4TAB2SIZE) * (float)i; + iem_sqrt4_mantissatab[i] = 1.0f/sqrt(f); + } + } +} + +static void *sigiem_sqrt4_new(void) +{ + t_sigiem_sqrt4 *x = (t_sigiem_sqrt4 *)pd_new(sigiem_sqrt4_class); + + outlet_new(&x->x_obj, gensym("signal")); + x->x_msi = 0; + return (x); +} + +void sigiem_sqrt4_setup(void) +{ + sigiem_sqrt4_class = class_new(gensym("iem_sqrt4~"), (t_newmethod)sigiem_sqrt4_new, 0, + sizeof(t_sigiem_sqrt4), 0, 0); + CLASS_MAINSIGNALIN(sigiem_sqrt4_class, t_sigiem_sqrt4, x_msi); + class_addmethod(sigiem_sqrt4_class, (t_method)sigiem_sqrt4_dsp, gensym("dsp"), 0); + sigiem_sqrt4_maketable(); + class_sethelpsymbol(sigiem_sqrt4_class, gensym("iemhelp/help-iem_sqrt4~")); +} + diff --git a/src/iemlib1/siglp1_t.c b/src/iemlib1/siglp1_t.c new file mode 100644 index 0000000..060d988 --- /dev/null +++ b/src/iemlib1/siglp1_t.c @@ -0,0 +1,219 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + + +/* -- lp1_t~ - slow dynamic lowpass-filter 1. order with tau input --- */ + +typedef struct siglp1_t +{ + t_object x_obj; + float yn1; + float c0; + float c1; + float sr; + float cur_t; + float delta_t; + float end_t; + float ticks_per_interpol_time; + float rcp_ticks; + float interpol_time; + int ticks; + int counter_t; + float x_msi; +} t_siglp1_t; + +t_class *siglp1_t_class; + +static void siglp1_t_dsp_tick(t_siglp1_t *x) +{ + if(x->counter_t) + { + if(x->counter_t <= 1) + { + x->cur_t = x->end_t; + x->counter_t = 0; + } + else + { + x->counter_t--; + x->cur_t += x->delta_t; + } + if(x->cur_t == 0.0f) + x->c1 = 0.0f; + else + x->c1 = exp((x->sr)/x->cur_t); + x->c0 = 1.0f - x->c1; + } +} + +static t_int *siglp1_t_perform(t_int *w) +{ + float *in = (float *)(w[1]); + float *out = (float *)(w[2]); + t_siglp1_t *x = (t_siglp1_t *)(w[3]); + int i, n = (t_int)(w[4]); + float yn0, yn1=x->yn1; + float c0=x->c0, c1=x->c1; + + siglp1_t_dsp_tick(x); + for(i=0; i<n; i++) + { + yn0 = (*in++)*c0 + yn1*c1; + *out++ = yn0; + yn1 = yn0; + } + /* NAN protect */ + if(PD_BADFLOAT(yn1)) + yn1 = 0.0f; + x->yn1 = yn1; + return(w+5); +} + +static t_int *siglp1_t_perf8(t_int *w) +{ + float *in = (float *)(w[1]); + float *out = (float *)(w[2]); + t_siglp1_t *x = (t_siglp1_t *)(w[3]); + int i, n = (t_int)(w[4]); + float yn[9]; + float c0=x->c0, c1=x->c1; + + siglp1_t_dsp_tick(x); + yn[0] = x->yn1; + for(i=0; i<n; i+=8, in+=8, out+=8) + { + yn[1] = in[0]*c0 + yn[0]*c1; + out[0] = yn[1]; + yn[2] = in[1]*c0 + yn[1]*c1; + out[1] = yn[2]; + yn[3] = in[2]*c0 + yn[2]*c1; + out[2] = yn[3]; + yn[4] = in[3]*c0 + yn[3]*c1; + out[3] = yn[4]; + yn[5] = in[4]*c0 + yn[4]*c1; + out[4] = yn[5]; + yn[6] = in[5]*c0 + yn[5]*c1; + out[5] = yn[6]; + yn[7] = in[6]*c0 + yn[6]*c1; + out[6] = yn[7]; + yn[8] = in[7]*c0 + yn[7]*c1; + out[7] = yn[8]; + yn[0] = yn[8]; + } + /* NAN protect */ + if(PD_BADFLOAT(yn[0])) + yn[0] = 0.0f; + + x->yn1 = yn[0]; + return(w+5); +} + +static void siglp1_t_ft2(t_siglp1_t *x, t_floatarg t) +{ + int i = (int)((x->ticks_per_interpol_time)*t); + + x->interpol_time = t; + if(i <= 0) + i = 1; + x->ticks = i; + x->rcp_ticks = 1.0f / (float)i; +} + +static void siglp1_t_ft1(t_siglp1_t *x, t_floatarg time_const) +{ + if(time_const < 0.0f) + time_const = 0.0f; + if(time_const != x->cur_t) + { + x->end_t = time_const; + x->counter_t = x->ticks; + x->delta_t = (time_const - x->cur_t) * x->rcp_ticks; + } +} + +static void siglp1_t_dsp(t_siglp1_t *x, t_signal **sp) +{ + int i, n=(int)sp[0]->s_n; + + x->sr = -1000.0f / (float)(sp[0]->s_sr); + x->ticks_per_interpol_time = 0.001f * (float)(sp[0]->s_sr) / (float)n; + i = (int)((x->ticks_per_interpol_time)*(x->interpol_time)); + if(i <= 0) + i = 1; + x->ticks = i; + x->rcp_ticks = 1.0f / (float)i; + if(x->cur_t == 0.0f) + x->c1 = 0.0f; + else + x->c1 = exp((x->sr)/x->cur_t); + x->c0 = 1.0f - x->c1; + if(n&7) + dsp_add(siglp1_t_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, n); + else + dsp_add(siglp1_t_perf8, 4, sp[0]->s_vec, sp[1]->s_vec, x, n); +} + +static void *siglp1_t_new(t_symbol *s, int argc, t_atom *argv) +{ + t_siglp1_t *x = (t_siglp1_t *)pd_new(siglp1_t_class); + int i; + float time_const=0.0f, interpol=0.0f; + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2")); + outlet_new(&x->x_obj, &s_signal); + x->x_msi = 0; + x->counter_t = 1; + x->delta_t = 0.0f; + x->interpol_time = 0.0f; + x->yn1 = 0.0f; + x->sr = -1.0f / 44.1f; + if((argc >= 1)&&IS_A_FLOAT(argv,0)) + time_const = (float)atom_getfloatarg(0, argc, argv); + if((argc >= 2)&&IS_A_FLOAT(argv,1)) + interpol = (float)atom_getfloatarg(1, argc, argv); + if(time_const < 0.0f) + time_const = 0.0f; + x->cur_t = time_const; + if(time_const == 0.0f) + x->c1 = 0.0f; + else + x->c1 = exp((x->sr)/time_const); + x->c0 = 1.0f - x->c1; + if(interpol < 0.0f) + interpol = 0.0f; + x->interpol_time = interpol; + x->ticks_per_interpol_time = 0.5f; + i = (int)((x->ticks_per_interpol_time)*(x->interpol_time)); + if(i <= 0) + i = 1; + x->ticks = i; + x->rcp_ticks = 1.0f / (float)i; + x->end_t = x->cur_t; + return (x); +} + +void siglp1_t_setup(void) +{ + siglp1_t_class = class_new(gensym("lp1_t~"), (t_newmethod)siglp1_t_new, + 0, sizeof(t_siglp1_t), 0, A_GIMME, 0); + CLASS_MAINSIGNALIN(siglp1_t_class, t_siglp1_t, x_msi); + class_addmethod(siglp1_t_class, (t_method)siglp1_t_dsp, gensym("dsp"), 0); + class_addmethod(siglp1_t_class, (t_method)siglp1_t_ft1, gensym("ft1"), A_FLOAT, 0); + class_addmethod(siglp1_t_class, (t_method)siglp1_t_ft2, gensym("ft2"), A_FLOAT, 0); + class_sethelpsymbol(siglp1_t_class, gensym("iemhelp/help-lp1_t~")); +} diff --git a/src/iemlib1/sigmov_avrg_kern.c b/src/iemlib1/sigmov_avrg_kern.c new file mode 100644 index 0000000..1c77a49 --- /dev/null +++ b/src/iemlib1/sigmov_avrg_kern.c @@ -0,0 +1,143 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + + +/* -- mov_avrg_kern~ - kernel for a moving-average-filter with IIR - */ + +typedef struct sigmov_avrg_kern +{ + t_object x_obj; + double x_wn1; + double x_a0; + double x_sr; + double x_mstime; + int x_nsamps; + int x_counter; + float x_msi; +} t_sigmov_avrg_kern; + +t_class *sigmov_avrg_kern_class; + +static t_int *sigmov_avrg_kern_perform(t_int *w) +{ + float *in_direct = (float *)(w[1]); + float *in_delayed = (float *)(w[2]); + float *out = (float *)(w[3]); + t_sigmov_avrg_kern *x = (t_sigmov_avrg_kern *)(w[4]); + int i, n = (int)(w[5]); + double wn0, wn1=x->x_wn1, a0=x->x_a0; + + if(x->x_counter) + { + int counter = x->x_counter; + + if(counter >= n) + { + x->x_counter = counter - n; + for(i=0; i<n; i++) + { + wn0 = wn1 + a0*(double)(*in_direct++); + *out++ = (float)wn0; + wn1 = wn0; + } + } + else + { + x->x_counter = 0; + for(i=0; i<counter; i++) + { + wn0 = wn1 + a0*(double)(*in_direct++); + *out++ = (float)wn0; + wn1 = wn0; + } + for(i=counter; i<n; i++) + { + wn0 = wn1 + a0*(double)(*in_direct++ - *in_delayed++); + *out++ = (float)wn0; + wn1 = wn0; + } + } + } + else + { + for(i=0; i<n; i++) + { + wn0 = wn1 + a0*(double)(*in_direct++ - *in_delayed++); + *out++ = (float)wn0; + wn1 = wn0; + } + } + x->x_wn1 = wn1; + return(w+6); +} + +static void sigmov_avrg_kern_ft1(t_sigmov_avrg_kern *x, t_floatarg mstime) +{ + if(mstime < 0.04) + mstime = 0.04; + x->x_mstime = (double)mstime; + x->x_nsamps = (int)(x->x_sr * x->x_mstime); + x->x_counter = x->x_nsamps; + x->x_wn1 = 0.0; + x->x_a0 = 1.0/(double)(x->x_nsamps); +} + +static void sigmov_avrg_kern_reset(t_sigmov_avrg_kern *x) +{ + x->x_counter = x->x_nsamps; + x->x_wn1 = 0.0; +} + +static void sigmov_avrg_kern_dsp(t_sigmov_avrg_kern *x, t_signal **sp) +{ + x->x_sr = 0.001*(double)(sp[0]->s_sr); + x->x_nsamps = (int)(x->x_sr * x->x_mstime); + x->x_counter = x->x_nsamps; + x->x_wn1 = 0.0; + x->x_a0 = 1.0/(double)(x->x_nsamps); + dsp_add(sigmov_avrg_kern_perform, 5, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, x, sp[0]->s_n); +} + +static void *sigmov_avrg_kern_new(t_floatarg mstime) +{ + t_sigmov_avrg_kern *x = (t_sigmov_avrg_kern *)pd_new(sigmov_avrg_kern_class); + + if(mstime < 0.04) + mstime = 0.04; + x->x_mstime = (double)mstime; + x->x_sr = 44.1; + x->x_nsamps = (int)(x->x_sr * x->x_mstime); + x->x_counter = x->x_nsamps; + x->x_wn1 = 0.0; + x->x_a0 = 1.0/(double)(x->x_nsamps); + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); + outlet_new(&x->x_obj, &s_signal); + x->x_msi = 0; + return(x); +} + +void sigmov_avrg_kern_setup(void) +{ + sigmov_avrg_kern_class = class_new(gensym("mov_avrg_kern~"), (t_newmethod)sigmov_avrg_kern_new, + 0, sizeof(t_sigmov_avrg_kern), 0, A_FLOAT, 0); + CLASS_MAINSIGNALIN(sigmov_avrg_kern_class, t_sigmov_avrg_kern, x_msi); + class_addmethod(sigmov_avrg_kern_class, (t_method)sigmov_avrg_kern_dsp, gensym("dsp"), 0); + class_addmethod(sigmov_avrg_kern_class, (t_method)sigmov_avrg_kern_ft1, gensym("ft1"), A_FLOAT, 0); + class_addmethod(sigmov_avrg_kern_class, (t_method)sigmov_avrg_kern_reset, gensym("reset"), 0); +} diff --git a/src/iemlib1/sigpara_bp2.c b/src/iemlib1/sigpara_bp2.c new file mode 100644 index 0000000..871191e --- /dev/null +++ b/src/iemlib1/sigpara_bp2.c @@ -0,0 +1,426 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + + +/* ---------- para_bp2~ - parametric bandpass 2. order ----------- */ + +typedef struct sigpara_bp2 +{ + t_object x_obj; + float wn1; + float wn2; + float a0; + float a1; + float a2; + float b1; + float b2; + float sr; + float cur_f; + float cur_l; + float cur_a; + float cur_g; + float delta_f; + float delta_a; + float delta_g; + float end_f; + float end_a; + float end_g; + float ticks_per_interpol_time; + float rcp_ticks; + float interpol_time; + int ticks; + int counter_f; + int counter_a; + int counter_g; + int event_mask; + void *x_debug_outlet; + t_atom x_at[5]; + float x_msi; +} t_sigpara_bp2; + +t_class *sigpara_bp2_class; + +static void sigpara_bp2_calc(t_sigpara_bp2 *x) +{ + float l, al, gal, l2, rcp; + + l = x->cur_l; + l2 = l*l + 1.0; + al = l*x->cur_a; + gal = al*x->cur_g; + rcp = 1.0f/(al + l2); + x->a0 = rcp*(l2 + gal); + x->a1 = rcp*2.0f*(2.0f - l2); + x->a2 = rcp*(l2 - gal); + x->b1 = -x->a1; + x->b2 = rcp*(al - l2); +} + +static void sigpara_bp2_dsp_tick(t_sigpara_bp2 *x) +{ + if(x->event_mask) + { + float discriminant; + + if(x->counter_f) + { + float l, si, co; + + if(x->counter_f <= 1) + { + x->cur_f = x->end_f; + x->counter_f = 0; + x->event_mask &= 6;/*set event_mask_bit 0 = 0*/ + } + else + { + x->counter_f--; + x->cur_f *= x->delta_f; + } + l = x->cur_f * x->sr; + if(l < 1.0e-20f) + x->cur_l = 1.0e20f; + else if(l > 1.57079632f) + x->cur_l = 0.0f; + else + { + si = sin(l); + co = cos(l); + x->cur_l = co/si; + } + } + if(x->counter_a) + { + if(x->counter_a <= 1) + { + x->cur_a = x->end_a; + x->counter_a = 0; + x->event_mask &= 5;/*set event_mask_bit 1 = 0*/ + } + else + { + x->counter_a--; + x->cur_a *= x->delta_a; + } + } + if(x->counter_g) + { + if(x->counter_g <= 1) + { + x->cur_g = x->end_g; + x->counter_g = 0; + x->event_mask &= 3;/*set event_mask_bit 2 = 0*/ + } + else + { + x->counter_g--; + x->cur_g *= x->delta_g; + } + } + + sigpara_bp2_calc(x); + + /* stability check */ + + discriminant = x->b1 * x->b1 + 4.0f * x->b2; + if(x->b1 <= -1.9999996f) + x->b1 = -1.9999996f; + else if(x->b1 >= 1.9999996f) + x->b1 = 1.9999996f; + + if(x->b2 <= -0.9999998f) + x->b2 = -0.9999998f; + else if(x->b2 >= 0.9999998f) + x->b2 = 0.9999998f; + + if(discriminant >= 0.0f) + { + if(0.9999998f - x->b1 - x->b2 < 0.0f) + x->b2 = 0.9999998f - x->b1; + if(0.9999998f + x->b1 - x->b2 < 0.0f) + x->b2 = 0.9999998f + x->b1; + } + } +} + +static t_int *sigpara_bp2_perform(t_int *w) +{ + float *in = (float *)(w[1]); + float *out = (float *)(w[2]); + t_sigpara_bp2 *x = (t_sigpara_bp2 *)(w[3]); + int i, n = (t_int)(w[4]); + float wn0, wn1=x->wn1, wn2=x->wn2; + float a0=x->a0, a1=x->a1, a2=x->a2; + float b1=x->b1, b2=x->b2; + + sigpara_bp2_dsp_tick(x); + for(i=0; i<n; i++) + { + wn0 = *in++ + b1*wn1 + b2*wn2; + *out++ = a0*wn0 + a1*wn1 + a2*wn2; + wn2 = wn1; + wn1 = wn0; + } + /* NAN protect */ + if(PD_BADFLOAT(wn2)) + wn2 = 0.0f; + if(PD_BADFLOAT(wn1)) + wn1 = 0.0f; + + x->wn1 = wn1; + x->wn2 = wn2; + return(w+5); +} +/* yn0 = *out; + xn0 = *in; + ************* + yn0 = a0*xn0 + a1*xn1 + a2*xn2 + b1*yn1 + b2*yn2; + yn2 = yn1; + yn1 = yn0; + xn2 = xn1; + xn1 = xn0; + ************************* + y/x = (a0 + a1*z-1 + a2*z-2)/(1 - b1*z-1 - b2*z-2);*/ + +static t_int *sigpara_bp2_perf8(t_int *w) +{ + float *in = (float *)(w[1]); + float *out = (float *)(w[2]); + t_sigpara_bp2 *x = (t_sigpara_bp2 *)(w[3]); + int i, n = (t_int)(w[4]); + float wn[10]; + float a0=x->a0, a1=x->a1, a2=x->a2; + float b1=x->b1, b2=x->b2; + + sigpara_bp2_dsp_tick(x); + wn[0] = x->wn2; + wn[1] = x->wn1; + for(i=0; i<n; i+=8, in+=8, out+=8) + { + wn[2] = in[0] + b1*wn[1] + b2*wn[0]; + out[0] = a0*wn[2] + a1*wn[1] + a2*wn[0]; + wn[3] = in[1] + b1*wn[2] + b2*wn[1]; + out[1] = a0*wn[3] + a1*wn[2] + a2*wn[1]; + wn[4] = in[2] + b1*wn[3] + b2*wn[2]; + out[2] = a0*wn[4] + a1*wn[3] + a2*wn[2]; + wn[5] = in[3] + b1*wn[4] + b2*wn[3]; + out[3] = a0*wn[5] + a1*wn[4] + a2*wn[3]; + wn[6] = in[4] + b1*wn[5] + b2*wn[4]; + out[4] = a0*wn[6] + a1*wn[5] + a2*wn[4]; + wn[7] = in[5] + b1*wn[6] + b2*wn[5]; + out[5] = a0*wn[7] + a1*wn[6] + a2*wn[5]; + wn[8] = in[6] + b1*wn[7] + b2*wn[6]; + out[6] = a0*wn[8] + a1*wn[7] + a2*wn[6]; + wn[9] = in[7] + b1*wn[8] + b2*wn[7]; + out[7] = a0*wn[9] + a1*wn[8] + a2*wn[7]; + wn[0] = wn[8]; + wn[1] = wn[9]; + } + /* NAN protect */ + if(PD_BADFLOAT(wn[0])) + wn[0] = 0.0f; + if(PD_BADFLOAT(wn[1])) + wn[1] = 0.0f; + + x->wn1 = wn[1]; + x->wn2 = wn[0]; + return(w+5); +} + +static void sigpara_bp2_ft4(t_sigpara_bp2 *x, t_floatarg t) +{ + int i = (int)((x->ticks_per_interpol_time)*t); + + x->interpol_time = t; + if(i <= 0) + i = 1; + x->ticks = i; + x->rcp_ticks = 1.0f / (float)i; +} + +static void sigpara_bp2_ft3(t_sigpara_bp2 *x, t_floatarg l) +{ + float g = exp(0.11512925465 * l); + + if(g != x->cur_g) + { + x->end_g = g; + x->counter_g = x->ticks; + x->delta_g = exp(log(g/x->cur_g)*x->rcp_ticks); + x->event_mask |= 4;/*set event_mask_bit 2 = 1*/ + } +} + +static void sigpara_bp2_ft2(t_sigpara_bp2 *x, t_floatarg q) +{ + float a; + + if(q <= 0.0f) + q = 0.000001f; + a = 1.0f/q; + if(a != x->cur_a) + { + x->end_a = a; + x->counter_a = x->ticks; + x->delta_a = exp(log(a/x->cur_a)*x->rcp_ticks); + x->event_mask |= 2;/*set event_mask_bit 1 = 1*/ + } +} + +static void sigpara_bp2_ft1(t_sigpara_bp2 *x, t_floatarg f) +{ + if(f <= 0.0f) + f = 0.000001f; + if(f != x->cur_f) + { + x->end_f = f; + x->counter_f = x->ticks; + x->delta_f = exp(log(f/x->cur_f)*x->rcp_ticks); + x->event_mask |= 1;/*set event_mask_bit 0 = 1*/ + } +} + +static void sigpara_bp2_print(t_sigpara_bp2 *x) +{ +// post("fb1 = %g, fb2 = %g, ff1 = %g, ff2 = %g, ff3 = %g", x->b1, x->b2, x->a0, x->a1, x->a2); + x->x_at[0].a_w.w_float = x->b1; + x->x_at[1].a_w.w_float = x->b2; + x->x_at[2].a_w.w_float = x->a0; + x->x_at[3].a_w.w_float = x->a1; + x->x_at[4].a_w.w_float = x->a2; + outlet_list(x->x_debug_outlet, &s_list, 5, x->x_at); post("fb1 = %g, fb2 = %g, ff1 = %g, ff2 = %g, ff3 = %g", x->b1, x->b2, x->a0, x->a1, x->a2); +} + +static void sigpara_bp2_dsp(t_sigpara_bp2 *x, t_signal **sp) +{ + float si, co, f; + int i, n=(int)sp[0]->s_n; + + x->sr = 3.14159265358979323846f / (float)(sp[0]->s_sr); + x->ticks_per_interpol_time = 0.001f * (float)(sp[0]->s_sr) / (float)n; + i = (int)((x->ticks_per_interpol_time)*(x->interpol_time)); + if(i <= 0) + i = 1; + x->ticks = i; + x->rcp_ticks = 1.0f / (float)i; + f = x->cur_f * x->sr; + if(f < 1.0e-20f) + x->cur_l = 1.0e20f; + else if(f > 1.57079632f) + x->cur_l = 0.0f; + else + { + si = sin(f); + co = cos(f); + x->cur_l = co/si; + } + if(n&7) + dsp_add(sigpara_bp2_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, n); + else + dsp_add(sigpara_bp2_perf8, 4, sp[0]->s_vec, sp[1]->s_vec, x, n); +} + +static void *sigpara_bp2_new(t_symbol *s, int argc, t_atom *argv) +{ + t_sigpara_bp2 *x = (t_sigpara_bp2 *)pd_new(sigpara_bp2_class); + int i; + float si, co, f=0.0, q=1.0, l=0.0, interpol=0.0; + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft3")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft4")); + outlet_new(&x->x_obj, &s_signal); + x->x_debug_outlet = outlet_new(&x->x_obj, &s_list); + x->x_msi = 0; + + x->x_at[0].a_type = A_FLOAT; + x->x_at[1].a_type = A_FLOAT; + x->x_at[2].a_type = A_FLOAT; + x->x_at[3].a_type = A_FLOAT; + x->x_at[4].a_type = A_FLOAT; + + x->event_mask = 1; + x->counter_f = 1; + x->counter_a = 0; + x->counter_g = 0; + x->delta_f = 0.0f; + x->delta_a = 0.0f; + x->delta_g = 0.0f; + x->interpol_time = 500.0f; + x->wn1 = 0.0; + x->wn2 = 0.0; + x->a0 = 0.0; + x->a1 = 0.0; + x->a2 = 0.0; + x->b1 = 0.0; + x->b2 = 0.0; + x->sr = 3.14159265358979323846f / 44100.0f; + x->cur_a = 1.0; + if((argc == 4)&&IS_A_FLOAT(argv,3)&&IS_A_FLOAT(argv,2)&&IS_A_FLOAT(argv,1)&&IS_A_FLOAT(argv,0)) + { + f = (float)atom_getfloatarg(0, argc, argv); + q = (float)atom_getfloatarg(1, argc, argv); + l = (float)atom_getfloatarg(2, argc, argv); + interpol = (float)atom_getfloatarg(3, argc, argv); + } + if(f <= 0.0f) + f = 0.000001f; + x->cur_f = f; + f *= x->sr; + if(f < 1.0e-20f) + x->cur_l = 1.0e20f; + else if(f > 1.57079632f) + x->cur_l = 0.0f; + else + { + si = sin(f); + co = cos(f); + x->cur_l = co/si; + } + if(q <= 0.0f) + q = 0.000001f; + x->cur_a = 1.0f/q; + x->cur_g = exp(0.11512925465 * l); + if(interpol <= 0.0f) + interpol = 0.0f; + x->interpol_time = interpol; + x->ticks_per_interpol_time = 0.5f; + i = (int)((x->ticks_per_interpol_time)*(x->interpol_time)); + if(i <= 0) + i = 1; + x->ticks = i; + x->rcp_ticks = 1.0f / (float)i; + x->end_f = x->cur_f; + x->end_a = x->cur_a; + x->end_g = x->cur_g; + return(x); +} + +void sigpara_bp2_setup(void) +{ + sigpara_bp2_class = class_new(gensym("para_bp2~"), (t_newmethod)sigpara_bp2_new, + 0, sizeof(t_sigpara_bp2), 0, A_GIMME, 0); + CLASS_MAINSIGNALIN(sigpara_bp2_class, t_sigpara_bp2, x_msi); + class_addmethod(sigpara_bp2_class, (t_method)sigpara_bp2_dsp, gensym("dsp"), 0); + class_addmethod(sigpara_bp2_class, (t_method)sigpara_bp2_ft1, gensym("ft1"), A_FLOAT, 0); + class_addmethod(sigpara_bp2_class, (t_method)sigpara_bp2_ft2, gensym("ft2"), A_FLOAT, 0); + class_addmethod(sigpara_bp2_class, (t_method)sigpara_bp2_ft3, gensym("ft3"), A_FLOAT, 0); + class_addmethod(sigpara_bp2_class, (t_method)sigpara_bp2_ft4, gensym("ft4"), A_FLOAT, 0); + class_addmethod(sigpara_bp2_class, (t_method)sigpara_bp2_print, gensym("print"), 0); + class_sethelpsymbol(sigpara_bp2_class, gensym("iemhelp/help-para_bp2~")); +} diff --git a/src/iemlib1/sigpeakenv.c b/src/iemlib1/sigpeakenv.c new file mode 100644 index 0000000..a16638e --- /dev/null +++ b/src/iemlib1/sigpeakenv.c @@ -0,0 +1,102 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* ---------------- peakenv~ - simple peak-envelope-converter. ----------------- */ + +typedef struct sigpeakenv +{ + t_object x_obj; + float x_sr; + float x_old_peak; + float x_c1; + float x_releasetime; + float x_msi; +} t_sigpeakenv; + +t_class *sigpeakenv_class; + +static void sigpeakenv_reset(t_sigpeakenv *x) +{ + x->x_old_peak = 0.0f; +} + +static void sigpeakenv_ft1(t_sigpeakenv *x, t_floatarg f)/* release-time in ms */ +{ + if(f < 0.0f) + f = 0.0f; + x->x_releasetime = f; + x->x_c1 = exp(-1.0/(x->x_sr*0.001*x->x_releasetime)); +} + +static t_int *sigpeakenv_perform(t_int *w) +{ + float *in = (float *)(w[1]); + float *out = (float *)(w[2]); + t_sigpeakenv *x = (t_sigpeakenv *)(w[3]); + int n = (int)(w[4]); + float peak = x->x_old_peak; + float c1 = x->x_c1; + float absolute; + int i; + + for(i=0; i<n; i++) + { + absolute = fabs(*in++); + peak *= c1; + if(absolute > peak) + peak = absolute; + *out++ = peak; + } + /* NAN protect */ + if(PD_BADFLOAT(peak)) + peak = 0.0f; + x->x_old_peak = peak; + return(w+5); +} + +static void sigpeakenv_dsp(t_sigpeakenv *x, t_signal **sp) +{ + x->x_sr = (float)sp[0]->s_sr; + sigpeakenv_ft1(x, x->x_releasetime); + dsp_add(sigpeakenv_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n); +} + +static void *sigpeakenv_new(t_floatarg f) +{ + t_sigpeakenv *x = (t_sigpeakenv *)pd_new(sigpeakenv_class); + + if(f <= 0.0f) + f = 0.0f; + x->x_sr = 44100.0f; + sigpeakenv_ft1(x, f); + x->x_old_peak = 0.0f; + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); + outlet_new(&x->x_obj, &s_signal); + x->x_msi = 0; + return(x); +} + +void sigpeakenv_setup(void) +{ + sigpeakenv_class = class_new(gensym("peakenv~"), (t_newmethod)sigpeakenv_new, + 0, sizeof(t_sigpeakenv), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(sigpeakenv_class, t_sigpeakenv, x_msi); + class_addmethod(sigpeakenv_class, (t_method)sigpeakenv_dsp, gensym("dsp"), 0); + class_addmethod(sigpeakenv_class, (t_method)sigpeakenv_ft1, gensym("ft1"), A_FLOAT, 0); + class_addmethod(sigpeakenv_class, (t_method)sigpeakenv_reset, gensym("reset"), 0); + class_sethelpsymbol(sigpeakenv_class, gensym("iemhelp/help-peakenv~")); +} diff --git a/src/iemlib1/sigprvu.c b/src/iemlib1/sigprvu.c new file mode 100644 index 0000000..bb4b72a --- /dev/null +++ b/src/iemlib1/sigprvu.c @@ -0,0 +1,282 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* ---------------- prvu~ - simple peak&rms-vu-meter. ----------------- */ + +typedef struct sigprvu +{ + t_object x_obj; + t_atom x_at[3]; + void *x_clock_metro; + int x_metro_time; + void *x_clock_hold; + int x_hold_time; + float x_cur_peak; + float x_old_peak; + float x_hold_peak; + int x_hold; + float x_sum_rms; + float x_old_rms; + float x_rcp; + float x_sr; + float x_threshold_over; + int x_overflow_counter; + float x_release_time; + float x_c1; + int x_started; + float x_msi; +} t_sigprvu; + +t_class *sigprvu_class; +static void sigprvu_tick_metro(t_sigprvu *x); +static void sigprvu_tick_hold(t_sigprvu *x); + +static void sigprvu_reset(t_sigprvu *x) +{ + x->x_at[0].a_w.w_float = -99.9f; + x->x_at[1].a_w.w_float = -99.9f; + x->x_at[2].a_w.w_float = 0.0f; + outlet_list(x->x_obj.ob_outlet, &s_list, 3, x->x_at); + x->x_overflow_counter = 0; + x->x_cur_peak = 0.0f; + x->x_old_peak = 0.0f; + x->x_hold_peak = 0.0f; + x->x_sum_rms = 0.0f; + x->x_old_rms = 0.0f; + x->x_hold = 0; + clock_unset(x->x_clock_hold); + clock_delay(x->x_clock_metro, x->x_metro_time); +} + +static void sigprvu_stop(t_sigprvu *x) +{ + clock_unset(x->x_clock_metro); + x->x_started = 0; +} + +static void sigprvu_start(t_sigprvu *x) +{ + clock_delay(x->x_clock_metro, x->x_metro_time); + x->x_started = 1; +} + +static void sigprvu_float(t_sigprvu *x, t_floatarg f) +{ + if(f == 0.0) + { + clock_unset(x->x_clock_metro); + x->x_started = 0; + } + else + { + clock_delay(x->x_clock_metro, x->x_metro_time); + x->x_started = 1; + } +} + +static void sigprvu_t_release(t_sigprvu *x, t_floatarg release_time) +{ + if(release_time <= 20.0f) + release_time = 20.0f; + x->x_release_time = release_time; + x->x_c1 = exp(-2.0*(float)x->x_metro_time/x->x_release_time); +} + +static void sigprvu_t_metro(t_sigprvu *x, t_floatarg metro_time) +{ + if(metro_time <= 20.0f) + metro_time = 20.0f; + x->x_metro_time = (int)metro_time; + x->x_c1 = exp(-2.0*(float)x->x_metro_time/x->x_release_time); + x->x_rcp = 1.0f/(x->x_sr*(float)x->x_metro_time); +} + +static void sigprvu_t_hold(t_sigprvu *x, t_floatarg hold_time) +{ + if(hold_time <= 20.0f) + hold_time = 20.0f; + x->x_hold_time = (int)hold_time; +} + +static void sigprvu_threshold(t_sigprvu *x, t_floatarg thresh) +{ + x->x_threshold_over = thresh; +} + +static t_int *sigprvu_perform(t_int *w) +{ + float *in = (float *)(w[1]); + t_sigprvu *x = (t_sigprvu *)(w[2]); + int n = (int)(w[3]); + float peak = x->x_cur_peak, pow, sum=x->x_sum_rms; + int i; + + if(x->x_started) + { + for(i=0; i<n; i++) + { + pow = in[i]*in[i]; + if(pow > peak) + peak = pow; + sum += pow; + } + x->x_cur_peak = peak; + x->x_sum_rms = sum; + } + return(w+4); +} + +static void sigprvu_dsp(t_sigprvu *x, t_signal **sp) +{ + x->x_sr = 0.001*(float)sp[0]->s_sr; + x->x_rcp = 1.0f/(x->x_sr*(float)x->x_metro_time); + dsp_add(sigprvu_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); + clock_delay(x->x_clock_metro, x->x_metro_time); +} + +static void sigprvu_tick_hold(t_sigprvu *x) +{ + x->x_hold = 0; + x->x_hold_peak = x->x_old_peak; +} + +static void sigprvu_tick_metro(t_sigprvu *x) +{ + float dbr, dbp, cur_rms, c1=x->x_c1; + + x->x_old_peak *= c1; + /* NAN protect */ + if(PD_BADFLOAT(x->x_old_peak)) + x->x_old_peak = 0.0f; + + if(x->x_cur_peak > x->x_old_peak) + x->x_old_peak = x->x_cur_peak; + if(x->x_old_peak > x->x_hold_peak) + { + x->x_hold = 1; + x->x_hold_peak = x->x_old_peak; + clock_delay(x->x_clock_hold, x->x_hold_time); + } + if(!x->x_hold) + x->x_hold_peak = x->x_old_peak; + if(x->x_hold_peak <= 0.0000000001f) + dbp = -99.9f; + else if(x->x_hold_peak > 1000000.0f) + { + dbp = 60.0f; + x->x_hold_peak = 1000000.0f; + x->x_old_peak = 1000000.0f; + } + else + dbp = 4.3429448195f*log(x->x_hold_peak); + x->x_cur_peak = 0.0f; + if(dbp >= x->x_threshold_over) + x->x_overflow_counter++; + x->x_at[1].a_w.w_float = dbp; + x->x_at[2].a_w.w_float = (float)x->x_overflow_counter; + + cur_rms = (1.0f - c1)*x->x_sum_rms*x->x_rcp + c1*x->x_old_rms; + /* NAN protect */ + if(PD_BADFLOAT(cur_rms)) + cur_rms = 0.0f; + + if(cur_rms <= 0.0000000001f) + dbr = -99.9f; + else if(cur_rms > 1000000.0f) + { + dbr = 60.0f; + x->x_old_rms = 1000000.0f; + } + else + dbr = 4.3429448195f*log(cur_rms); + x->x_sum_rms = 0.0f; + x->x_old_rms = cur_rms; + x->x_at[0].a_w.w_float = dbr; + outlet_list(x->x_obj.ob_outlet, &s_list, 3, x->x_at); + clock_delay(x->x_clock_metro, x->x_metro_time); +} + +static void sigprvu_ff(t_sigprvu *x) +{ + clock_free(x->x_clock_metro); + clock_free(x->x_clock_hold); +} + +static void *sigprvu_new(t_floatarg metro_time, t_floatarg hold_time, + t_floatarg release_time, t_floatarg threshold) +{ + t_sigprvu *x; + float t; + int i; + + x = (t_sigprvu *)pd_new(sigprvu_class); + if(metro_time <= 0.0f) + metro_time = 300.0f; + if(metro_time <= 20.0f) + metro_time = 20.0f; + if(release_time <= 0.0f) + release_time = 300.0f; + if(release_time <= 20.0f) + release_time = 20.0f; + if(hold_time <= 0.0f) + hold_time = 1000.0f; + if(hold_time <= 20.0f) + hold_time = 20.0f; + if(threshold == 0.0f) + threshold = -0.01f; + x->x_metro_time = (int)metro_time; + x->x_release_time = release_time; + x->x_hold_time = (int)hold_time; + x->x_threshold_over = threshold; + x->x_c1 = exp(-2.0*(float)x->x_metro_time/x->x_release_time); + x->x_cur_peak = 0.0f; + x->x_old_peak = 0.0f; + x->x_hold_peak = 0.0f; + x->x_hold = 0; + x->x_sum_rms = 0.0f; + x->x_old_rms = 0.0f; + x->x_sr = 44.1f; + x->x_rcp = 1.0f/(x->x_sr*(float)x->x_metro_time); + x->x_overflow_counter = 0; + x->x_clock_metro = clock_new(x, (t_method)sigprvu_tick_metro); + x->x_clock_hold = clock_new(x, (t_method)sigprvu_tick_hold); + x->x_started = 1; + outlet_new(&x->x_obj, &s_list); + x->x_at[0].a_type = A_FLOAT; + x->x_at[1].a_type = A_FLOAT; + x->x_at[2].a_type = A_FLOAT; + x->x_msi = 0.0f; + return(x); +} + +void sigprvu_setup(void) +{ + sigprvu_class = class_new(gensym("prvu~"), (t_newmethod)sigprvu_new, + (t_method)sigprvu_ff, sizeof(t_sigprvu), 0, + A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(sigprvu_class, t_sigprvu, x_msi); + class_addmethod(sigprvu_class, (t_method)sigprvu_dsp, gensym("dsp"), 0); + class_addfloat(sigprvu_class, sigprvu_float); + class_addmethod(sigprvu_class, (t_method)sigprvu_reset, gensym("reset"), 0); + class_addmethod(sigprvu_class, (t_method)sigprvu_start, gensym("start"), 0); + class_addmethod(sigprvu_class, (t_method)sigprvu_stop, gensym("stop"), 0); + class_addmethod(sigprvu_class, (t_method)sigprvu_t_release, gensym("t_release"), A_FLOAT, 0); + class_addmethod(sigprvu_class, (t_method)sigprvu_t_metro, gensym("t_metro"), A_FLOAT, 0); + class_addmethod(sigprvu_class, (t_method)sigprvu_t_hold, gensym("t_hold"), A_FLOAT, 0); + class_addmethod(sigprvu_class, (t_method)sigprvu_threshold, gensym("threshold"), A_FLOAT, 0); + class_sethelpsymbol(sigprvu_class, gensym("iemhelp/help-prvu~")); +} diff --git a/src/iemlib1/sigpvu.c b/src/iemlib1/sigpvu.c new file mode 100644 index 0000000..5dd4ea4 --- /dev/null +++ b/src/iemlib1/sigpvu.c @@ -0,0 +1,206 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* ---------------- pvu~ - simple peak-vu-meter. ----------------- */ + +typedef struct sigpvu +{ + t_object x_obj; + void *x_outlet_meter; + void *x_outlet_over; + void *x_clock; + float x_cur_peak; + float x_old_peak; + float x_threshold_over; + float x_c1; + int x_metro_time; + float x_release_time; + int x_overflow_counter; + int x_started; + float x_msi; +} t_sigpvu; + +t_class *sigpvu_class; +static void sigpvu_tick(t_sigpvu *x); + +static void sigpvu_reset(t_sigpvu *x) +{ + outlet_float(x->x_outlet_over, (t_float)0); + outlet_float(x->x_outlet_meter, -199.9); + x->x_overflow_counter = 0; + x->x_cur_peak = 0.0f; + x->x_old_peak = 0.0f; + clock_delay(x->x_clock, x->x_metro_time); +} + +static void sigpvu_stop(t_sigpvu *x) +{ + clock_unset(x->x_clock); + x->x_started = 0; +} + +static void sigpvu_start(t_sigpvu *x) +{ + clock_delay(x->x_clock, x->x_metro_time); + x->x_started = 1; +} + +static void sigpvu_float(t_sigpvu *x, t_floatarg f) +{ + if(f == 0.0) + { + clock_unset(x->x_clock); + x->x_started = 0; + } + else + { + clock_delay(x->x_clock, x->x_metro_time); + x->x_started = 1; + } +} + +static void sigpvu_t_release(t_sigpvu *x, t_floatarg release_time) +{ + if(release_time <= 20.0f) + release_time = 20.0f; + x->x_release_time = release_time; + x->x_c1 = exp(-(float)x->x_metro_time/(float)release_time); +} + +static void sigpvu_t_metro(t_sigpvu *x, t_floatarg metro_time) +{ + if(metro_time <= 20.0f) + metro_time = 20.0f; + x->x_metro_time = (int)metro_time; + x->x_c1 = exp(-(float)metro_time/(float)x->x_release_time); +} + +static void sigpvu_threshold(t_sigpvu *x, t_floatarg thresh) +{ + x->x_threshold_over = thresh; +} + +static t_int *sigpvu_perform(t_int *w) +{ + float *in = (float *)(w[1]); + t_sigpvu *x = (t_sigpvu *)(w[2]); + int n = (int)(w[3]); + float peak = x->x_cur_peak; + float absolute; + int i; + + if(x->x_started) + { + for(i=0; i<n; i++) + { + absolute = fabs(*in++); + if(absolute > peak) + peak = absolute; + } + x->x_cur_peak = peak; + } + return(w+4); +} + +static void sigpvu_dsp(t_sigpvu *x, t_signal **sp) +{ + dsp_add(sigpvu_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); + clock_delay(x->x_clock, x->x_metro_time); +} + +static void sigpvu_tick(t_sigpvu *x) +{ + float db; + int i; + + x->x_old_peak *= x->x_c1; + /* NAN protect */ + if(PD_BADFLOAT(x->x_old_peak)) + x->x_old_peak = 0.0f; + + if(x->x_cur_peak > x->x_old_peak) + x->x_old_peak = x->x_cur_peak; + if(x->x_old_peak <= 0.0000000001f) + db = -199.9f; + else if(x->x_old_peak > 1000000.0f) + { + db = 120.0f; + x->x_old_peak = 1000000.0f; + } + else + db = 8.6858896381f*log(x->x_old_peak); + if(db >= x->x_threshold_over) + { + x->x_overflow_counter++; + outlet_float(x->x_outlet_over, (t_float)x->x_overflow_counter); + } + outlet_float(x->x_outlet_meter, db); + x->x_cur_peak = 0.0f; + clock_delay(x->x_clock, x->x_metro_time); +} + +static void *sigpvu_new(t_floatarg metro_time, t_floatarg release_time, t_floatarg threshold) +{ + t_sigpvu *x; + float t; + + x = (t_sigpvu *)pd_new(sigpvu_class); + if(metro_time <= 0.0f) + metro_time = 300.0f; + if(metro_time <= 20.0f) + metro_time = 20.0f; + if(release_time <= 0.0f) + release_time = 300.0f; + if(release_time <= 20.0f) + release_time = 20.0f; + if(threshold == 0.0f) + threshold = -0.01f; + x->x_threshold_over = threshold; + x->x_overflow_counter = 0; + x->x_metro_time = (int)metro_time; + x->x_release_time = release_time; + x->x_c1 = exp(-(float)metro_time/(float)release_time); + x->x_cur_peak = 0.0f; + x->x_old_peak = 0.0f; + x->x_clock = clock_new(x, (t_method)sigpvu_tick); + x->x_outlet_meter = outlet_new(&x->x_obj, &s_float);/* left */ + x->x_outlet_over = outlet_new(&x->x_obj, &s_float); /* right */ + x->x_started = 1; + x->x_msi = 0; + return(x); +} + +static void sigpvu_ff(t_sigpvu *x) +{ + clock_free(x->x_clock); +} + +void sigpvu_setup(void ) +{ + sigpvu_class = class_new(gensym("pvu~"), (t_newmethod)sigpvu_new, + (t_method)sigpvu_ff, sizeof(t_sigpvu), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(sigpvu_class, t_sigpvu, x_msi); + class_addmethod(sigpvu_class, (t_method)sigpvu_dsp, gensym("dsp"), 0); + class_addfloat(sigpvu_class, sigpvu_float); + class_addmethod(sigpvu_class, (t_method)sigpvu_reset, gensym("reset"), 0); + class_addmethod(sigpvu_class, (t_method)sigpvu_start, gensym("start"), 0); + class_addmethod(sigpvu_class, (t_method)sigpvu_stop, gensym("stop"), 0); + class_addmethod(sigpvu_class, (t_method)sigpvu_t_release, gensym("t_release"), A_FLOAT, 0); + class_addmethod(sigpvu_class, (t_method)sigpvu_t_metro, gensym("t_metro"), A_FLOAT, 0); + class_addmethod(sigpvu_class, (t_method)sigpvu_threshold, gensym("threshold"), A_FLOAT, 0); + class_sethelpsymbol(sigpvu_class, gensym("iemhelp/help-pvu~")); +} diff --git a/src/iemlib1/sigrvu.c b/src/iemlib1/sigrvu.c new file mode 100644 index 0000000..70b9cd7 --- /dev/null +++ b/src/iemlib1/sigrvu.c @@ -0,0 +1,187 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* ---------------- rvu~ - simple peak&rms-vu-meter. ----------------- */ + +typedef struct sigrvu +{ + t_object x_obj; + void *x_clock_metro; + int x_metro_time; + float x_sum_rms; + float x_old_rms; + float x_rcp; + float x_sr; + float x_release_time; + float x_c1; + int x_started; + float x_msi; +} t_sigrvu; + +t_class *sigrvu_class; +static void sigrvu_tick_metro(t_sigrvu *x); + +static void sigrvu_reset(t_sigrvu *x) +{ + outlet_float(x->x_obj.ob_outlet, -99.9f); + x->x_sum_rms = 0.0f; + x->x_old_rms = 0.0f; + clock_delay(x->x_clock_metro, x->x_metro_time); +} + +static void sigrvu_stop(t_sigrvu *x) +{ + clock_unset(x->x_clock_metro); + x->x_started = 0; +} + +static void sigrvu_start(t_sigrvu *x) +{ + clock_delay(x->x_clock_metro, x->x_metro_time); + x->x_started = 1; +} + +static void sigrvu_float(t_sigrvu *x, t_floatarg f) +{ + if(f == 0.0) + { + clock_unset(x->x_clock_metro); + x->x_started = 0; + } + else + { + clock_delay(x->x_clock_metro, x->x_metro_time); + x->x_started = 1; + } +} + +static void sigrvu_t_release(t_sigrvu *x, t_floatarg release_time) +{ + if(release_time <= 20.0f) + release_time = 20.0f; + x->x_release_time = release_time; + x->x_c1 = exp(-2.0*(float)x->x_metro_time/x->x_release_time); +} + +static void sigrvu_t_metro(t_sigrvu *x, t_floatarg metro_time) +{ + if(metro_time <= 20.0f) + metro_time = 20.0f; + x->x_metro_time = (int)metro_time; + x->x_c1 = exp(-2.0*(float)x->x_metro_time/x->x_release_time); + x->x_rcp = 1.0f/(x->x_sr*(float)x->x_metro_time); +} + +static t_int *sigrvu_perform(t_int *w) +{ + float *in = (float *)(w[1]); + t_sigrvu *x = (t_sigrvu *)(w[2]); + int n = (int)(w[3]); + float pow, sum=x->x_sum_rms; + int i; + + if(x->x_started) + { + for(i=0; i<n; i++) + { + sum += in[i]*in[i]; + } + x->x_sum_rms = sum; + } + return(w+4); +} + +static void sigrvu_dsp(t_sigrvu *x, t_signal **sp) +{ + x->x_sr = 0.001*(float)sp[0]->s_sr; + x->x_rcp = 1.0f/(x->x_sr*(float)x->x_metro_time); + dsp_add(sigrvu_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); + clock_delay(x->x_clock_metro, x->x_metro_time); +} + +static void sigrvu_tick_metro(t_sigrvu *x) +{ + float dbr, cur_rms, c1=x->x_c1; + + cur_rms = (1.0f - c1)*x->x_sum_rms*x->x_rcp + c1*x->x_old_rms; + /* NAN protect */ + if(PD_BADFLOAT(cur_rms)) + cur_rms = 0.0f; + + if(cur_rms <= 0.0000000001f) + dbr = -99.9f; + else if(cur_rms > 1000000.0f) + { + dbr = 60.0f; + x->x_old_rms = 1000000.0f; + } + else + dbr = 4.3429448195f*log(cur_rms); + x->x_sum_rms = 0.0f; + x->x_old_rms = cur_rms; + outlet_float(x->x_obj.ob_outlet, dbr); + clock_delay(x->x_clock_metro, x->x_metro_time); +} + +static void sigrvu_ff(t_sigrvu *x) +{ + clock_free(x->x_clock_metro); +} + +static void *sigrvu_new(t_floatarg metro_time, t_floatarg release_time) +{ + t_sigrvu *x=(t_sigrvu *)pd_new(sigrvu_class); + float t; + int i; + + if(metro_time <= 0.0f) + metro_time = 300.0f; + if(metro_time <= 20.0f) + metro_time = 20.0f; + if(release_time <= 0.0f) + release_time = 300.0f; + if(release_time <= 20.0f) + release_time = 20.0f; + x->x_metro_time = (int)metro_time; + x->x_release_time = release_time; + x->x_c1 = exp(-2.0*(float)x->x_metro_time/x->x_release_time); + x->x_sum_rms = 0.0f; + x->x_old_rms = 0.0f; + x->x_sr = 44.1f; + x->x_rcp = 1.0f/(x->x_sr*(float)x->x_metro_time); + x->x_clock_metro = clock_new(x, (t_method)sigrvu_tick_metro); + x->x_started = 1; + outlet_new(&x->x_obj, &s_float); + x->x_msi = 0.0f; + return(x); +} + +void sigrvu_setup(void) +{ + sigrvu_class = class_new(gensym("rvu~"), (t_newmethod)sigrvu_new, + (t_method)sigrvu_ff, sizeof(t_sigrvu), 0, + A_DEFFLOAT, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(sigrvu_class, t_sigrvu, x_msi); + class_addmethod(sigrvu_class, (t_method)sigrvu_dsp, gensym("dsp"), 0); + class_addfloat(sigrvu_class, sigrvu_float); + class_addmethod(sigrvu_class, (t_method)sigrvu_reset, gensym("reset"), 0); + class_addmethod(sigrvu_class, (t_method)sigrvu_start, gensym("start"), 0); + class_addmethod(sigrvu_class, (t_method)sigrvu_stop, gensym("stop"), 0); + class_addmethod(sigrvu_class, (t_method)sigrvu_t_release, gensym("t_release"), A_FLOAT, 0); + class_addmethod(sigrvu_class, (t_method)sigrvu_t_metro, gensym("t_metro"), A_FLOAT, 0); + class_sethelpsymbol(sigrvu_class, gensym("iemhelp/help-rvu~")); +} diff --git a/src/iemlib1/sigsin_phase.c b/src/iemlib1/sigsin_phase.c new file mode 100644 index 0000000..0594962 --- /dev/null +++ b/src/iemlib1/sigsin_phase.c @@ -0,0 +1,129 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + + +/* --- sin_phase~ - output the phase-difference between 2 sinewaves in samples (sig) ---- */ + +typedef struct sigsin_phase +{ + t_object x_obj; + float x_prev1; + float x_prev2; + float x_cur_out; + int x_counter1; + int x_counter2; + int x_state1; + int x_state2; + float x_msi; +} t_sigsin_phase; + +t_class *sigsin_phase_class; + +static t_int *sigsin_phase_perform(t_int *w) +{ + float *in1 = (float *)(w[1]); + float *in2 = (float *)(w[2]); + float *out = (float *)(w[3]); + t_sigsin_phase *x = (t_sigsin_phase *)(w[4]); + int i, n = (t_int)(w[5]); + float prev1=x->x_prev1; + float prev2=x->x_prev2; + float cur_out=x->x_cur_out; + int counter1=x->x_counter1; + int counter2=x->x_counter2; + int state1=x->x_state1; + int state2=x->x_state2; + + for(i=0; i<n; i++) + { + if((in1[i] >= 0.0f) && (prev1 < 0.0f)) + { + state1 = 1; + counter1 = 0; + } + else if((in1[i] < 0.0f) && (prev1 >= 0.0f)) + { + state2 = 1; + counter2 = 0; + } + + if((in2[i] >= 0.0f) && (prev2 < 0.0f)) + { + state1 = 0; + cur_out = (float)(counter1); + counter1 = 0; + } + else if((in2[i] < 0.0f) && (prev2 >= 0.0f)) + { + state2 = 0; + cur_out = (float)(counter2); + counter2 = 0; + } + + if(state1) + counter1++; + if(state2) + counter2++; + + prev1 = in1[i]; + prev2 = in2[i]; + out[i] = cur_out; + } + + x->x_prev1 = prev1; + x->x_prev2 = prev2; + x->x_cur_out = cur_out; + x->x_counter1 = counter1; + x->x_counter2 = counter2; + x->x_state1 = state1; + x->x_state2 = state2; + + return(w+6); +} + +static void sigsin_phase_dsp(t_sigsin_phase *x, t_signal **sp) +{ + dsp_add(sigsin_phase_perform, 5, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, x, sp[0]->s_n); +} + +static void *sigsin_phase_new(void) +{ + t_sigsin_phase *x = (t_sigsin_phase *)pd_new(sigsin_phase_class); + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + outlet_new(&x->x_obj, &s_signal); + + x->x_prev1 = 0.0f; + x->x_prev2 = 0.0f; + x->x_cur_out = 0.0f; + x->x_counter1 = 0; + x->x_counter2 = 0; + x->x_state1 = 0; + x->x_state2 = 0; + x->x_msi = 0; + + return (x); +} + +void sigsin_phase_setup(void) +{ + sigsin_phase_class = class_new(gensym("sin_phase~"), (t_newmethod)sigsin_phase_new, + 0, sizeof(t_sigsin_phase), 0, 0); + CLASS_MAINSIGNALIN(sigsin_phase_class, t_sigsin_phase, x_msi); + class_addmethod(sigsin_phase_class, (t_method)sigsin_phase_dsp, gensym("dsp"), 0); + class_sethelpsymbol(sigsin_phase_class, gensym("iemhelp/help-sin_phase~")); +} diff --git a/src/iemlib1/sigvcf_filter.c b/src/iemlib1/sigvcf_filter.c new file mode 100644 index 0000000..ec14306 --- /dev/null +++ b/src/iemlib1/sigvcf_filter.c @@ -0,0 +1,334 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* ---------- vcf_filter~ - slow dynamic vcf_filter 1. and 2. order ----------- */ + +typedef struct sigvcf_filter +{ + t_object x_obj; + float x_wn1; + float x_wn2; + float x_msi; + char x_filtname[6]; +} t_sigvcf_filter; + +t_class *sigvcf_filter_class; + +static t_int *sigvcf_filter_perform_snafu(t_int *w) +{ + float *in = (float *)(w[1]); + float *out = (float *)(w[4]); + int n = (t_int)(w[6]); + + while(n--) + *out++ = *in++; + return(w+7); +} + +/* +lp2 + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = rcp*(wn0 + 2.0f*wn1 + wn2); + wn2 = wn1; + wn1 = wn0; + +bp2 + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = rcp*al*(wn0 - wn2); + wn2 = wn1; + wn1 = wn0; + +rbp2 + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = rcp*l*(wn0 - wn2); + wn2 = wn1; + wn1 = wn0; + +hp2 + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = rcp*(wn0 - 2.0f*wn1 + wn2); + wn2 = wn1; + wn1 = wn0; + +*/ + +static t_int *sigvcf_filter_perform_lp2(t_int *w) +{ + float *in = (float *)(w[1]); + float *lp = (float *)(w[2]); + float *q = (float *)(w[3]); + float *out = (float *)(w[4]); + t_sigvcf_filter *x = (t_sigvcf_filter *)(w[5]); + int i, n = (t_int)(w[6]); + float wn0, wn1=x->x_wn1, wn2=x->x_wn2; + float l, al, l2, rcp; + + for(i=0; i<n; i+=4) + { + l = lp[i]; + if(q[i] < 0.000001) + al = 1000000.0*l; + else if(q[i] > 1000000.0) + al = 0.000001*l; + else + al = l/q[i]; + l2 = l*l + 1.0f; + rcp = 1.0f/(al + l2); + + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = rcp*(wn0 + 2.0f*wn1 + wn2); + wn2 = wn1; + wn1 = wn0; + + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = rcp*(wn0 + 2.0f*wn1 + wn2); + wn2 = wn1; + wn1 = wn0; + + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = rcp*(wn0 + 2.0f*wn1 + wn2); + wn2 = wn1; + wn1 = wn0; + + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = rcp*(wn0 + 2.0f*wn1 + wn2); + wn2 = wn1; + wn1 = wn0; + } + /* NAN protect */ + if(PD_BADFLOAT(wn2)) + wn2 = 0.0f; + if(PD_BADFLOAT(wn1)) + wn1 = 0.0f; + + x->x_wn1 = wn1; + x->x_wn2 = wn2; + return(w+7); +} + +static t_int *sigvcf_filter_perform_bp2(t_int *w) +{ + float *in = (float *)(w[1]); + float *lp = (float *)(w[2]); + float *q = (float *)(w[3]); + float *out = (float *)(w[4]); + t_sigvcf_filter *x = (t_sigvcf_filter *)(w[5]); + int i, n = (t_int)(w[6]); + float wn0, wn1=x->x_wn1, wn2=x->x_wn2; + float l, al, l2, rcp; + + for(i=0; i<n; i+=4) + { + l = lp[i]; + if(q[i] < 0.000001) + al = 1000000.0*l; + else if(q[i] > 1000000.0) + al = 0.000001*l; + else + al = l/q[i]; + l2 = l*l + 1.0f; + rcp = 1.0f/(al + l2); + + + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = rcp*al*(wn0 - wn2); + wn2 = wn1; + wn1 = wn0; + + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = rcp*al*(wn0 - wn2); + wn2 = wn1; + wn1 = wn0; + + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = rcp*al*(wn0 - wn2); + wn2 = wn1; + wn1 = wn0; + + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = rcp*al*(wn0 - wn2); + wn2 = wn1; + wn1 = wn0; + } + /* NAN protect */ + if(PD_BADFLOAT(wn2)) + wn2 = 0.0f; + if(PD_BADFLOAT(wn1)) + wn1 = 0.0f; + + x->x_wn1 = wn1; + x->x_wn2 = wn2; + return(w+7); +} + +static t_int *sigvcf_filter_perform_rbp2(t_int *w) +{ + float *in = (float *)(w[1]); + float *lp = (float *)(w[2]); + float *q = (float *)(w[3]); + float *out = (float *)(w[4]); + t_sigvcf_filter *x = (t_sigvcf_filter *)(w[5]); + int i, n = (t_int)(w[6]); + float wn0, wn1=x->x_wn1, wn2=x->x_wn2; + float al, l, l2, rcp; + + for(i=0; i<n; i+=4) + { + l = lp[i]; + if(q[i] < 0.000001) + al = 1000000.0*l; + else if(q[i] > 1000000.0) + al = 0.000001*l; + else + al = l/q[i]; + l2 = l*l + 1.0f; + rcp = 1.0f/(al + l2); + + + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = rcp*l*(wn0 - wn2); + wn2 = wn1; + wn1 = wn0; + + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = rcp*l*(wn0 - wn2); + wn2 = wn1; + wn1 = wn0; + + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = rcp*l*(wn0 - wn2); + wn2 = wn1; + wn1 = wn0; + + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = rcp*l*(wn0 - wn2); + wn2 = wn1; + wn1 = wn0; + } + /* NAN protect */ + if(PD_BADFLOAT(wn2)) + wn2 = 0.0f; + if(PD_BADFLOAT(wn1)) + wn1 = 0.0f; + + x->x_wn1 = wn1; + x->x_wn2 = wn2; + return(w+7); +} + +static t_int *sigvcf_filter_perform_hp2(t_int *w) +{ + float *in = (float *)(w[1]); + float *lp = (float *)(w[2]); + float *q = (float *)(w[3]); + float *out = (float *)(w[4]); + t_sigvcf_filter *x = (t_sigvcf_filter *)(w[5]); + int i, n = (t_int)(w[6]); + float wn0, wn1=x->x_wn1, wn2=x->x_wn2; + float l, al, l2, rcp, forw; + + for(i=0; i<n; i+=4) + { + l = lp[i]; + if(q[i] < 0.000001) + al = 1000000.0*l; + else if(q[i] > 1000000.0) + al = 0.000001*l; + else + al = l/q[i]; + l2 = l*l + 1.0f; + rcp = 1.0f/(al + l2); + forw = rcp * (l2 - 1.0f); + + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = forw*(wn0 - 2.0f*wn1 + wn2); + wn2 = wn1; + wn1 = wn0; + + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = forw*(wn0 - 2.0f*wn1 + wn2); + wn2 = wn1; + wn1 = wn0; + + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = forw*(wn0 - 2.0f*wn1 + wn2); + wn2 = wn1; + wn1 = wn0; + + wn0 = *in++ - rcp*(2.0f*(2.0f - l2)*wn1 + (l2 - al)*wn2); + *out++ = forw*(wn0 - 2.0f*wn1 + wn2); + wn2 = wn1; + wn1 = wn0; + } + /* NAN protect */ + if(PD_BADFLOAT(wn2)) + wn2 = 0.0f; + if(PD_BADFLOAT(wn1)) + wn1 = 0.0f; + + x->x_wn1 = wn1; + x->x_wn2 = wn2; + return(w+7); +} + +static void sigvcf_filter_dsp(t_sigvcf_filter *x, t_signal **sp) +{ + if(!strcmp(x->x_filtname,"bp2")) + dsp_add(sigvcf_filter_perform_bp2, 6, sp[0]->s_vec, sp[1]->s_vec, + sp[2]->s_vec, sp[3]->s_vec, x, sp[0]->s_n); + else if(!strcmp(x->x_filtname,"rbp2")) + dsp_add(sigvcf_filter_perform_rbp2, 6, sp[0]->s_vec, sp[1]->s_vec, + sp[2]->s_vec, sp[3]->s_vec, x, sp[0]->s_n); + else if(!strcmp(x->x_filtname,"lp2")) + dsp_add(sigvcf_filter_perform_lp2, 6, sp[0]->s_vec, sp[1]->s_vec, + sp[2]->s_vec, sp[3]->s_vec, x, sp[0]->s_n); + else if(!strcmp(x->x_filtname,"hp2")) + dsp_add(sigvcf_filter_perform_hp2, 6, sp[0]->s_vec, sp[1]->s_vec, + sp[2]->s_vec, sp[3]->s_vec, x, sp[0]->s_n); + else + { + dsp_add(sigvcf_filter_perform_snafu, 6, sp[0]->s_vec, sp[1]->s_vec, + sp[2]->s_vec, sp[3]->s_vec, x, sp[0]->s_n); + post("vcf_filter~-Error: 1. initial-arguments: <sym> kind: lp2, bp2, rbp2, hp2!"); + } +} + +static void *sigvcf_filter_new(t_symbol *filt_typ) +{ + t_sigvcf_filter *x = (t_sigvcf_filter *)pd_new(sigvcf_filter_class); + char *c; + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + outlet_new(&x->x_obj, &s_signal); + x->x_msi = 0; + x->x_wn1 = 0.0; + x->x_wn2 = 0.0; + c = (char *)filt_typ->s_name; + c[5] = 0; + strcpy(x->x_filtname, c); + return(x); +} + +void sigvcf_filter_setup(void) +{ + sigvcf_filter_class = class_new(gensym("vcf_filter~"), (t_newmethod)sigvcf_filter_new, + 0, sizeof(t_sigvcf_filter), 0, A_DEFSYM, 0); + CLASS_MAINSIGNALIN(sigvcf_filter_class, t_sigvcf_filter, x_msi); + class_addmethod(sigvcf_filter_class, (t_method)sigvcf_filter_dsp, gensym("dsp"), 0); + class_sethelpsymbol(sigvcf_filter_class, gensym("iemhelp/help-vcf_filter~")); +} diff --git a/src/iemlib1/soundfile_info.c b/src/iemlib1/soundfile_info.c new file mode 100644 index 0000000..f7cbf6b --- /dev/null +++ b/src/iemlib1/soundfile_info.c @@ -0,0 +1,261 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +#include "m_pd.h" +#include "iemlib.h" +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <math.h> + +#define SFI_HEADER_SAMPLERATE 0 +#define SFI_HEADER_FILENAME 1 +#define SFI_HEADER_MULTICHANNEL_FILE_LENGTH 2 +#define SFI_HEADER_HEADERBYTES 3 +#define SFI_HEADER_CHANNELS 4 +#define SFI_HEADER_BYTES_PER_SAMPLE 5 +#define SFI_HEADER_ENDINESS 6 + +#define SFI_HEADER_SIZE 7 + + + +/* -------------------- soundfile_info ------------------------------- */ + +static t_class *soundfile_info_class; + +typedef struct _soundfile_info +{ + t_object x_obj; + long *x_begmem; + int x_size; + t_atom x_atheader[SFI_HEADER_SIZE]; + t_canvas *x_canvas; + void *x_list_out; +} t_soundfile_info; + +static short soundfile_info_str2short(char *cvec) +{ + short s=0; + unsigned char *uc=(unsigned char *)cvec; + + s += (short)(*uc); + s += (short)(*(uc+1)*256); + return(s); +} + +static long soundfile_info_str2long(char *cvec) +{ + long l=0; + unsigned char *uc=(unsigned char *)cvec; + + l += (long)(*uc); + l += (long)(*(uc+1)*256); + l += (long)(*(uc+2)*65536); + l += (long)(*(uc+3)*16777216); + return(l); +} + +static void soundfile_info_read(t_soundfile_info *x, t_symbol *filename) +{ + char completefilename[400]; + int i, n, n2, n4, filesize, read_chars, header_size=0, ch, bps, sr; + FILE *fh; + t_atom *at; + char *cvec; + long ll; + short ss; + + if(filename->s_name[0] == '/')/*make complete path + filename*/ + { + strcpy(completefilename, filename->s_name); + } + else if(((filename->s_name[0] >= 'A')&&(filename->s_name[0] <= 'Z')|| + (filename->s_name[0] >= 'a')&&(filename->s_name[0] <= 'z'))&& + (filename->s_name[1] == ':')&&(filename->s_name[2] == '/')) + { + strcpy(completefilename, filename->s_name); + } + else + { + strcpy(completefilename, canvas_getdir(x->x_canvas)->s_name); + strcat(completefilename, "/"); + strcat(completefilename, filename->s_name); + } + + fh = fopen(completefilename,"rb"); + if(!fh) + { + post("soundfile_info_read: cannot open %s !!\n", completefilename); + } + else + { + n = x->x_size; + n2 = sizeof(short) * x->x_size; + n4 = sizeof(long) * x->x_size; + fseek(fh, 0, SEEK_END); + filesize = ftell(fh); + fseek(fh,0,SEEK_SET); + read_chars = (int)fread(x->x_begmem, sizeof(char), n4, fh) /2; + fclose(fh); +// post("read chars = %d", read_chars); + cvec = (char *)x->x_begmem; + if(read_chars > 4) + { + if(strncmp(cvec, "RIFF", 4)) + { + post("soundfile_info_read-error: %s is no RIFF-WAVE-file", completefilename); + goto soundfile_info_end; + } + header_size += 8; + cvec += 8; + if(strncmp(cvec, "WAVE", 4)) + { + post("soundfile_info_read-error: %s is no RIFF-WAVE-file", completefilename); + goto soundfile_info_end; + } + header_size += 4; + cvec += 4; + + for(i=header_size/2; i<read_chars; i++) + { + if(!strncmp(cvec, "fmt ", 4)) + goto soundfile_info_fmt; + header_size += 2; + cvec += 2; + } + post("soundfile_info_read-error: %s has at begin no format-chunk", completefilename); + goto soundfile_info_end; + +soundfile_info_fmt: + header_size += 4; + cvec += 4; + ll = soundfile_info_str2long(cvec); + if(ll != 16) + { + post("soundfile_info_read-error: %s has a format-chunk not equal to 16", completefilename); + goto soundfile_info_end; + } + header_size += 4; + cvec += 4; + ss = soundfile_info_str2short(cvec); + /* format */ + if(ss != 1) /* PCM = 1 */ + { + post("soundfile_info_read-error: %s is not PCM-format coded", completefilename); + goto soundfile_info_end; + } + header_size += 2; + cvec += 2; + ss = soundfile_info_str2short(cvec); + /* channels */ + if((ss < 1) || (ss > 100)) + { + post("soundfile_info_read-error: %s has no common channel-number", completefilename); + goto soundfile_info_end; + } + SETFLOAT(x->x_atheader+SFI_HEADER_CHANNELS, (float)ss); + ch = ss; + header_size += 2; + cvec += 2; + ll = soundfile_info_str2long(cvec); + /* samplerate */ + if((ll > 400000) || (ll < 200)) + { + post("soundfile_info_read-error: %s has no common samplerate", completefilename); + goto soundfile_info_end; + } + SETFLOAT(x->x_atheader+SFI_HEADER_SAMPLERATE, (float)ll); + sr = ll; + header_size += 4; + cvec += 4; + + header_size += 4; /* bytes_per_sec */ + cvec += 4; + ss = soundfile_info_str2short(cvec); + + /* bytes_per_sample */ + if((ss < 1) || (ss > 100)) + { + post("soundfile_info_read-error: %s has no common number of bytes per sample", completefilename); + goto soundfile_info_end; + } + SETFLOAT(x->x_atheader+SFI_HEADER_BYTES_PER_SAMPLE, (float)(ss/ch)); + bps = ss; + header_size += 2; + cvec += 2; + + header_size += 2; /* bits_per_sample */ + cvec += 2; + + for(i=header_size/2; i<read_chars; i++) + { + if(!strncmp(cvec, "data", 4)) + goto soundfile_info_data; + header_size += 2; + cvec += 2; + } + post("soundfile_info_read-error: %s has at begin no data-chunk", completefilename); + goto soundfile_info_end; + +soundfile_info_data: + header_size += 8; + cvec += 8; + + SETFLOAT(x->x_atheader+SFI_HEADER_HEADERBYTES, (float)header_size); + + filesize -= header_size; + filesize /= bps; + SETFLOAT(x->x_atheader+SFI_HEADER_MULTICHANNEL_FILE_LENGTH, (float)filesize); + SETSYMBOL(x->x_atheader+SFI_HEADER_ENDINESS, gensym("l")); + SETSYMBOL(x->x_atheader+SFI_HEADER_FILENAME, gensym(completefilename)); + +/* post("ch = %d", ss); + post("sr = %d", ll); + post("bps = %d", ss/ch); + post("head = %d", header_size); + post("len = %d", filesize);*/ + + outlet_list(x->x_list_out, &s_list, SFI_HEADER_SIZE, x->x_atheader); + + +soundfile_info_end: + + ; + } + } +} + +static void soundfile_info_free(t_soundfile_info *x) +{ + freebytes(x->x_begmem, x->x_size * sizeof(long)); +} + +static void *soundfile_info_new(void) +{ + t_soundfile_info *x = (t_soundfile_info *)pd_new(soundfile_info_class); + + x->x_size = 10000; + x->x_begmem = (long *)getbytes(x->x_size * sizeof(long)); + x->x_list_out = outlet_new(&x->x_obj, &s_list); + x->x_canvas = canvas_getcurrent(); + return (x); +} + +/* ---------------- global setup function -------------------- */ + +void soundfile_info_setup(void) +{ + soundfile_info_class = class_new(gensym("soundfile_info"), (t_newmethod)soundfile_info_new, + (t_method)soundfile_info_free, sizeof(t_soundfile_info), 0, 0); + class_addmethod(soundfile_info_class, (t_method)soundfile_info_read, gensym("read"), A_SYMBOL, 0); + class_sethelpsymbol(soundfile_info_class, gensym("iemhelp/help-soundfile_info")); +} + diff --git a/src/iemlib1/split.c b/src/iemlib1/split.c new file mode 100644 index 0000000..0a3bcff --- /dev/null +++ b/src/iemlib1/split.c @@ -0,0 +1,54 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* --------------------------- split ----------------------------- */ + +typedef struct _split +{ + t_object x_obj; + t_outlet *x_out_less; + t_outlet *x_out_greater_equal; + float x_threshold; +} t_split; + +static t_class *split_class; + +static void split_float(t_split *x, t_float f) +{ + if(f < x->x_threshold) + outlet_float(x->x_out_less, f); + else + outlet_float(x->x_out_greater_equal, f); +} + +static void *split_new(t_floatarg f) +{ + t_split *x = (t_split *)pd_new(split_class); + floatinlet_new(&x->x_obj, &x->x_threshold); + x->x_out_less = outlet_new(&x->x_obj, &s_float); + x->x_out_greater_equal = outlet_new(&x->x_obj, &s_float); + x->x_threshold = f; + return (x); +} + +void split_setup(void) +{ + split_class = class_new(gensym("split"), (t_newmethod)split_new, 0, + sizeof(t_split), 0, A_DEFFLOAT, 0); + class_addfloat(split_class, split_float); + class_sethelpsymbol(split_class, gensym("iemhelp/help-split")); +}
\ No newline at end of file diff --git a/src/iemlib1/v2db.c b/src/iemlib1/v2db.c new file mode 100644 index 0000000..b3e342d --- /dev/null +++ b/src/iemlib1/v2db.c @@ -0,0 +1,45 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +#include "m_pd.h" +#include "iemlib.h" +#include <math.h> +#include <stdio.h> +#include <string.h> + +/* ---------------- v2db - value to dB converter. ----------------- */ + +static t_class *v2db_class; + +float v2db(float f) +{ + return (f <= 0 ? -199.9 : 8.6858896381*log(f)); +} + +static void v2db_float(t_object *x, t_float f) +{ + outlet_float(x->ob_outlet, v2db(f)); +} + +static void *v2db_new(void) +{ + t_object *x = (t_object *)pd_new(v2db_class); + outlet_new(x, &s_float); + return (x); +} + +void v2db_setup(void) +{ + v2db_class = class_new(gensym("v2db"), v2db_new, 0, + sizeof(t_object), 0, 0); + class_addfloat(v2db_class, (t_method)v2db_float); + class_sethelpsymbol(v2db_class, gensym("iemhelp/help-v2db")); +} |