From c1419b43ea354fa04360450ae4f64612df065099 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 14 Nov 2005 21:59:09 +0000 Subject: these pragmas are only used for MSVC, not MinGW or Cygwin, therefore changing the define from NT to _MSC_VER svn path=/trunk/externals/ggee/; revision=3903 --- filters/hlshelf.c | 452 +++++++++++++++++++++++++++--------------------------- 1 file changed, 226 insertions(+), 226 deletions(-) (limited to 'filters/hlshelf.c') diff --git a/filters/hlshelf.c b/filters/hlshelf.c index a2189d7..7cf99c5 100755 --- a/filters/hlshelf.c +++ b/filters/hlshelf.c @@ -1,226 +1,226 @@ -/* (C) Guenter Geiger */ - - -#include -#include - -#ifdef NT -#pragma warning( disable : 4244 ) -#pragma warning( disable : 4305 ) -#endif - -/* ------------------------ hlshelf ----------------------------- */ - - -#ifndef M_PI -#define M_PI 3.141593f -#endif - -#define SRATE 44100.0 -#define MAX_GAIN 120.0f - -static t_class *hlshelf_class; - - -typedef struct _hlshelf -{ - t_object x_obj; - float s_rate; - float s_gain0; - float s_gain1; - float s_gain2; - float s_ltransfq; - float s_htransfq; - float s_lradians; - float s_hradians; -} t_hlshelf; - - -int hlshelf_check_stability(t_float fb1, - t_float fb2, - t_float ff1, - t_float ff2, - t_float ff3) -{ - float discriminant = fb1 * fb1 + 4 * fb2; - - if (discriminant < 0) /* imaginary roots -- resonant filter */ - { - /* they're conjugates so we just check that the product - is less than one */ - if (fb2 >= -1.0f) goto stable; - } - else /* real roots */ - { - /* check that the parabola 1 - fb1 x - fb2 x^2 has a - vertex between -1 and 1, and that it's nonnegative - at both ends, which implies both roots are in [1-,1]. */ - if (fb1 <= 2.0f && fb1 >= -2.0f && - 1.0f - fb1 -fb2 >= 0 && 1.0f + fb1 - fb2 >= 0) - goto stable; - } - return 0; -stable: - return 1; -} - - -void hlshelf_check(t_hlshelf *x) -{ - - if(x->s_gain0 - x->s_gain1 > MAX_GAIN) { - x->s_gain0 = x->s_gain1 + MAX_GAIN; - post("setting gain0 to %f",x->s_gain0); - } - - - if(x->s_gain1 > MAX_GAIN) { - x->s_gain1 = MAX_GAIN; - post("setting gain1 to %f",x->s_gain1); - } - - if(x->s_gain2 - x->s_gain1 > MAX_GAIN) { - x->s_gain2 = x->s_gain1 + MAX_GAIN; - post("setting gain2 to %f",x->s_gain2); - } - - /* constrain: 0 <= x->s_ltransfq < x->s_htransfq. */ - x->s_ltransfq = (x->s_ltransfq < x->s_htransfq) ? x->s_ltransfq : x->s_htransfq - 0.5f; - - if (x->s_ltransfq < 0) x->s_ltransfq = 0.0f; - - x->s_lradians = M_PI * x->s_ltransfq / x->s_rate; - x->s_hradians= M_PI * (0.5f - (x->s_htransfq / x->s_rate)); - -} - - -void hlshelf_bang(t_hlshelf *x) -{ - t_atom at[6]; - float c0, c1, c2, d0, d1, d2; /* output coefs */ - float a1, a2, b1, b2, g1, g2; /* temp coefs */ - double xf; - - hlshelf_check(x); - - /* low shelf */ - xf = 0.5 * 0.115129255 * (double)(x->s_gain0 - x->s_gain1); /* ln(10) / 20 = 0.115129255 */ - if(xf < -200.) /* exp(x) -> 0 */ - { - a1 = 1.0f; - b1 = -1.0f; - g1 = 0.0f; - } - else - { - double t = tan(x->s_lradians); - double e = exp(xf); - double r = t / e; - double kr = t * e; - - a1 = (r - 1) / (r + 1); - b1 = (kr - 1) / (kr + 1); - g1 = (kr + 1) / (r + 1); - } - - /* high shelf */ - xf = 0.5 * 0.115129255 * (double)(x->s_gain2 - x->s_gain1); /* ln(10) / 20 = 0.115129255 */ - if(xf < -200.) /* exp(x) -> 0 */ - { - a2 = -1.0f; - b2 = 1.0f; - g2 = 0.0f; - } - else - { - double t = tan(x->s_hradians); - double e = exp(xf); - double r = t / e; - double kr = t * e; - - a2 = (1 - r) / (1 + r); - b2 = (1 - kr) / (1 + kr); - g2 = (1 + kr) / (1 + r); - } - - /* form product */ - c0 = g1 * g2 * (float)(exp((double)(x->s_gain1) * 0.05f * 2.302585093f)); ; - c1 = a1 + a2; - c2 = a1 * a2; - d0 = 1.0f; - d1 = b1 + b2; - d2 = b1 * b2; - - if (!hlshelf_check_stability(-c1/d0,-c2/d0,d0/d0,d1/d0,d2/d0)) { - post("hlshelf: filter unstable -> resetting"); - c0=1.;c1=0.;c2=0.; - d0=1.;d1=0.;d2=0.; - } - - SETFLOAT(at,-c1/d0); - SETFLOAT(at+1,-c2/d0); - SETFLOAT(at+2,d0/d0); - SETFLOAT(at+3,d1/d0); - SETFLOAT(at+4,d2/d0); - - outlet_list(x->x_obj.ob_outlet,&s_list,5,at); -} - -void hlshelf_float(t_hlshelf *x,t_floatarg f) -{ - x->s_gain0 = f; - hlshelf_bang(x); -} - - -static void *hlshelf_new(t_symbol* s,t_int argc, t_atom* at) -{ - t_hlshelf *x = (t_hlshelf *)pd_new(hlshelf_class); - t_float k0 = atom_getfloat(at); - t_float k1 = atom_getfloat(at+1); - t_float k2 = atom_getfloat(at+2); - t_float f1 = atom_getfloat(at+3); - t_float f2 = atom_getfloat(at+4); - - - f1 = atom_getfloat(at); - f2 = atom_getfloat(at); - - if ((f1 == 0.0f && f2 == 0.0f) || f1 > f2){ /* all gains = 0db */ - f1 = 150.0f; - f2 = 5000.0f; - } - - if (f1 < 0) f1 = 0.0f; - if (f2 > SRATE) f2 = .5f*SRATE; - - x->s_rate = SRATE; /* srate default */ - x->s_gain0 = k0; - x->s_gain1 = k1; - x->s_gain2 = k2; - - x->s_ltransfq = 0.0f; - x->s_htransfq = SRATE/2; - - x->s_lradians = M_PI * x->s_ltransfq / x->s_rate; - x->s_hradians= M_PI * (0.5f - (x->s_htransfq / x->s_rate)); - - floatinlet_new(&x->x_obj, &x->s_gain1); - floatinlet_new(&x->x_obj, &x->s_gain2); - floatinlet_new(&x->x_obj, &x->s_ltransfq); - floatinlet_new(&x->x_obj, &x->s_htransfq); - outlet_new(&x->x_obj, &s_list); - - return (x); -} - -void hlshelf_setup(void) -{ - hlshelf_class = class_new(gensym("hlshelf"), (t_newmethod)hlshelf_new, 0, - sizeof(t_hlshelf), 0, A_GIMME, 0); - class_addbang(hlshelf_class,hlshelf_bang); - class_addfloat(hlshelf_class,hlshelf_float); -} - - +/* (C) Guenter Geiger */ + + +#include +#include + +#ifdef _MSC_VER +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +/* ------------------------ hlshelf ----------------------------- */ + + +#ifndef M_PI +#define M_PI 3.141593f +#endif + +#define SRATE 44100.0 +#define MAX_GAIN 120.0f + +static t_class *hlshelf_class; + + +typedef struct _hlshelf +{ + t_object x_obj; + float s_rate; + float s_gain0; + float s_gain1; + float s_gain2; + float s_ltransfq; + float s_htransfq; + float s_lradians; + float s_hradians; +} t_hlshelf; + + +int hlshelf_check_stability(t_float fb1, + t_float fb2, + t_float ff1, + t_float ff2, + t_float ff3) +{ + float discriminant = fb1 * fb1 + 4 * fb2; + + if (discriminant < 0) /* imaginary roots -- resonant filter */ + { + /* they're conjugates so we just check that the product + is less than one */ + if (fb2 >= -1.0f) goto stable; + } + else /* real roots */ + { + /* check that the parabola 1 - fb1 x - fb2 x^2 has a + vertex between -1 and 1, and that it's nonnegative + at both ends, which implies both roots are in [1-,1]. */ + if (fb1 <= 2.0f && fb1 >= -2.0f && + 1.0f - fb1 -fb2 >= 0 && 1.0f + fb1 - fb2 >= 0) + goto stable; + } + return 0; +stable: + return 1; +} + + +void hlshelf_check(t_hlshelf *x) +{ + + if(x->s_gain0 - x->s_gain1 > MAX_GAIN) { + x->s_gain0 = x->s_gain1 + MAX_GAIN; + post("setting gain0 to %f",x->s_gain0); + } + + + if(x->s_gain1 > MAX_GAIN) { + x->s_gain1 = MAX_GAIN; + post("setting gain1 to %f",x->s_gain1); + } + + if(x->s_gain2 - x->s_gain1 > MAX_GAIN) { + x->s_gain2 = x->s_gain1 + MAX_GAIN; + post("setting gain2 to %f",x->s_gain2); + } + + /* constrain: 0 <= x->s_ltransfq < x->s_htransfq. */ + x->s_ltransfq = (x->s_ltransfq < x->s_htransfq) ? x->s_ltransfq : x->s_htransfq - 0.5f; + + if (x->s_ltransfq < 0) x->s_ltransfq = 0.0f; + + x->s_lradians = M_PI * x->s_ltransfq / x->s_rate; + x->s_hradians= M_PI * (0.5f - (x->s_htransfq / x->s_rate)); + +} + + +void hlshelf_bang(t_hlshelf *x) +{ + t_atom at[6]; + float c0, c1, c2, d0, d1, d2; /* output coefs */ + float a1, a2, b1, b2, g1, g2; /* temp coefs */ + double xf; + + hlshelf_check(x); + + /* low shelf */ + xf = 0.5 * 0.115129255 * (double)(x->s_gain0 - x->s_gain1); /* ln(10) / 20 = 0.115129255 */ + if(xf < -200.) /* exp(x) -> 0 */ + { + a1 = 1.0f; + b1 = -1.0f; + g1 = 0.0f; + } + else + { + double t = tan(x->s_lradians); + double e = exp(xf); + double r = t / e; + double kr = t * e; + + a1 = (r - 1) / (r + 1); + b1 = (kr - 1) / (kr + 1); + g1 = (kr + 1) / (r + 1); + } + + /* high shelf */ + xf = 0.5 * 0.115129255 * (double)(x->s_gain2 - x->s_gain1); /* ln(10) / 20 = 0.115129255 */ + if(xf < -200.) /* exp(x) -> 0 */ + { + a2 = -1.0f; + b2 = 1.0f; + g2 = 0.0f; + } + else + { + double t = tan(x->s_hradians); + double e = exp(xf); + double r = t / e; + double kr = t * e; + + a2 = (1 - r) / (1 + r); + b2 = (1 - kr) / (1 + kr); + g2 = (1 + kr) / (1 + r); + } + + /* form product */ + c0 = g1 * g2 * (float)(exp((double)(x->s_gain1) * 0.05f * 2.302585093f)); ; + c1 = a1 + a2; + c2 = a1 * a2; + d0 = 1.0f; + d1 = b1 + b2; + d2 = b1 * b2; + + if (!hlshelf_check_stability(-c1/d0,-c2/d0,d0/d0,d1/d0,d2/d0)) { + post("hlshelf: filter unstable -> resetting"); + c0=1.;c1=0.;c2=0.; + d0=1.;d1=0.;d2=0.; + } + + SETFLOAT(at,-c1/d0); + SETFLOAT(at+1,-c2/d0); + SETFLOAT(at+2,d0/d0); + SETFLOAT(at+3,d1/d0); + SETFLOAT(at+4,d2/d0); + + outlet_list(x->x_obj.ob_outlet,&s_list,5,at); +} + +void hlshelf_float(t_hlshelf *x,t_floatarg f) +{ + x->s_gain0 = f; + hlshelf_bang(x); +} + + +static void *hlshelf_new(t_symbol* s,t_int argc, t_atom* at) +{ + t_hlshelf *x = (t_hlshelf *)pd_new(hlshelf_class); + t_float k0 = atom_getfloat(at); + t_float k1 = atom_getfloat(at+1); + t_float k2 = atom_getfloat(at+2); + t_float f1 = atom_getfloat(at+3); + t_float f2 = atom_getfloat(at+4); + + + f1 = atom_getfloat(at); + f2 = atom_getfloat(at); + + if ((f1 == 0.0f && f2 == 0.0f) || f1 > f2){ /* all gains = 0db */ + f1 = 150.0f; + f2 = 5000.0f; + } + + if (f1 < 0) f1 = 0.0f; + if (f2 > SRATE) f2 = .5f*SRATE; + + x->s_rate = SRATE; /* srate default */ + x->s_gain0 = k0; + x->s_gain1 = k1; + x->s_gain2 = k2; + + x->s_ltransfq = 0.0f; + x->s_htransfq = SRATE/2; + + x->s_lradians = M_PI * x->s_ltransfq / x->s_rate; + x->s_hradians= M_PI * (0.5f - (x->s_htransfq / x->s_rate)); + + floatinlet_new(&x->x_obj, &x->s_gain1); + floatinlet_new(&x->x_obj, &x->s_gain2); + floatinlet_new(&x->x_obj, &x->s_ltransfq); + floatinlet_new(&x->x_obj, &x->s_htransfq); + outlet_new(&x->x_obj, &s_list); + + return (x); +} + +void hlshelf_setup(void) +{ + hlshelf_class = class_new(gensym("hlshelf"), (t_newmethod)hlshelf_new, 0, + sizeof(t_hlshelf), 0, A_GIMME, 0); + class_addbang(hlshelf_class,hlshelf_bang); + class_addfloat(hlshelf_class,hlshelf_float); +} + + -- cgit v1.2.1