Accept FS #10244 by Wincent Balin: more pdbox work done for GSoC; also some keyword and line-ending fixes by me

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21626 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Peter D'Hoye 2009-07-03 22:16:11 +00:00
parent eabeb928dd
commit 0d4560cb03
113 changed files with 10637 additions and 4420 deletions

View file

@ -42,6 +42,10 @@ The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl
*/
#ifdef ROCKBOX
#include "plugin.h"
#include "pdbox.h"
#else /* ROCKBOX */
#ifdef WIN32
#include <stdlib.h>
#include <string.h>
@ -52,6 +56,7 @@ The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl
#ifdef UNIX
#include <stdio.h>
#endif
#endif /* ROCKBOX */
/* structure definition of your object */
@ -114,6 +119,9 @@ static void StrCopyUntilSlash(char *target, const char *source);
// free
static void OSCroute_free(t_OSCroute *x)
{
#ifdef ROCKBOX
(void) x;
#endif
// freebytes(x->x_vec, x->x_nelement * sizeof(*x->x_vec));
}
@ -154,7 +162,9 @@ void OSCroute_setup(void) {
void *OSCroute_new(t_symbol *s, int argc, t_atom *argv)
{
#ifdef ROCKBOX
(void) s;
#endif
t_OSCroute *x = (t_OSCroute *)pd_new(OSCroute_class); // get memory for a new object & initialize
int i; //{{raf}} n not used
@ -236,6 +246,9 @@ void *OSCroute_new(t_symbol *s, int argc, t_atom *argv)
void OSCroute_version (t_OSCroute *x) {
#ifdef ROCKBOX
(void) x;
#endif
// EnterCallback();
post("OSCroute Version " OSC_ROUTE_VERSION
", by Matt Wright. pd jdl, win32: raf.\nOSCroute Compiled " __TIME__ " " __DATE__);
@ -248,15 +261,27 @@ void OSCroute_version (t_OSCroute *x) {
void OSCroute_assist (t_OSCroute *x, void *box, long msg, long arg,
char *dstString) {
#ifdef ROCKBOX
(void) box;
#endif
// EnterCallback();
if (msg==ASSIST_INLET) {
#ifdef ROCKBOX
strcpy(dstString, "Incoming OSC messages");
#else
sprintf(dstString, "Incoming OSC messages");
#endif
} else if (msg==ASSIST_OUTLET) {
if (arg < 0 || arg >= x->x_num) {
post("* OSCroute_assist: No outlet corresponds to arg %ld!", arg);
} else {
#ifdef ROCKBOX
strcpy(dstString, "subaddress + args for prefix ");
strcat(dstString, x->x_prefixes[arg]);
#else
sprintf(dstString, "subaddress + args for prefix %s", x->x_prefixes[arg]);
#endif
}
} else {
post("* OSCroute_assist: unrecognized message %ld", msg);
@ -266,6 +291,9 @@ void OSCroute_assist (t_OSCroute *x, void *box, long msg, long arg,
}
void OSCroute_list(t_OSCroute *x, t_symbol *s, int argc, t_atom *argv) {
#ifdef ROCKBOX
(void) s;
#endif
// EnterCallback();
if (argc > 0 && argv[0].a_type == A_SYMBOL) {
/* Ignore the fact that this is a "list" */

View file

@ -1,87 +1,95 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- bandpass ----------------------------*/
static t_class *bandpass_class;
void bandpass_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw* 0.01,omega);
t_float b1 = 0.;
t_float b0 = alpha;
t_float b2 = -alpha;
t_float a0 = 1 + alpha;
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha;
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("bandpass: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void bandpass_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
bandpass_bang(x);
}
static void *bandpass_new(t_floatarg f,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(bandpass_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
/* floatinlet_new(&x->x_obj, &x->x_gain); */
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
return (x);
}
void bandpass_setup(void)
{
bandpass_class = class_new(gensym("bandpass"), (t_newmethod)bandpass_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(bandpass_class,bandpass_bang);
class_addfloat(bandpass_class,bandpass_float);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#ifdef ROCKBOX
#include "plugin.h"
#include "pdbox.h"
#include "m_pd.h"
#include "math.h"
#include "filters.h"
#else /* ROCKBOX */
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
#endif /* ROCKBOX */
/* ------------------- bandpass ----------------------------*/
static t_class *bandpass_class;
void bandpass_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw* 0.01,omega);
t_float b1 = 0.;
t_float b0 = alpha;
t_float b2 = -alpha;
t_float a0 = 1 + alpha;
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha;
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("bandpass: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void bandpass_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
bandpass_bang(x);
}
static void *bandpass_new(t_floatarg f,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(bandpass_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
/* floatinlet_new(&x->x_obj, &x->x_gain); */
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
return (x);
}
void bandpass_setup(void)
{
bandpass_class = class_new(gensym("bandpass"), (t_newmethod)bandpass_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(bandpass_class,bandpass_bang);
class_addfloat(bandpass_class,bandpass_float);
}

File diff suppressed because it is too large Load diff

View file

@ -1,86 +1,93 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- equ ----------------------------*/
static t_class *equ_class;
void equ_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw*0.01,omega);
t_float b0 = 1 + alpha*e_A(x->x_gain);
t_float b1 = -2.*cos(omega);
t_float b2 = 1 - alpha*e_A(x->x_gain);
t_float a0 = 1 + alpha/e_A(x->x_gain);
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha/e_A(x->x_gain);
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw);*/
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("equ: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void equ_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
equ_bang(x);
}
static void *equ_new(t_floatarg f,t_floatarg g,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(equ_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
floatinlet_new(&x->x_obj, &x->x_gain);
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
if (g != 0.) x->x_gain = g;
return (x);
}
void equalizer_setup(void)
{
equ_class = class_new(gensym("equalizer"), (t_newmethod)equ_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(equ_class,equ_bang);
class_addfloat(equ_class,equ_float);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#ifdef ROCKBOX
#include "plugin.h"
#include "pdbox.h"
#include "m_pd.h"
#include "math.h"
#include "filters.h"
#else /* ROCKBOX */
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
#endif /* ROCKBOX */
/* ------------------- equ ----------------------------*/
static t_class *equ_class;
void equ_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw*0.01,omega);
t_float b0 = 1 + alpha*e_A(x->x_gain);
t_float b1 = -2.*cos(omega);
t_float b2 = 1 - alpha*e_A(x->x_gain);
t_float a0 = 1 + alpha/e_A(x->x_gain);
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha/e_A(x->x_gain);
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw);*/
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("equ: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void equ_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
equ_bang(x);
}
static void *equ_new(t_floatarg f,t_floatarg g,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(equ_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
floatinlet_new(&x->x_obj, &x->x_gain);
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
if (g != 0.) x->x_gain = g;
return (x);
}
void equalizer_setup(void)
{
equ_class = class_new(gensym("equalizer"), (t_newmethod)equ_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(equ_class,equ_bang);
class_addfloat(equ_class,equ_float);
}

View file

@ -1,75 +1,82 @@
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#ifndef __GGEE_FILTERS_H__
#define __GGEE_FILTERS_H__
#ifndef M_PI
#define M_PI 3.141593f
#endif
#include <math.h>
#define LN2 0.69314718
#define e_A(g) (pow(10,(g/40.)))
#define e_omega(f,r) (2.0*M_PI*f/r)
#define e_alpha(bw,omega) (sin(omega)*sinh(LN2/2. * bw * omega/sin(omega)))
#define e_beta(a,S) (sqrt((a*a + 1)/(S) - (a-1)*(a-1)))
typedef struct _rbjfilter
{
t_object x_obj;
t_float x_rate;
t_float x_freq;
t_float x_gain;
t_float x_bw;
} t_rbjfilter;
static int 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;
}
#endif
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#ifndef __GGEE_FILTERS_H__
#define __GGEE_FILTERS_H__
#ifdef ROCKBOX
#include "math.h"
#else
#include <math.h>
#endif
#ifndef M_PI
#define M_PI 3.141593f
#endif
#define LN2 0.69314718
#define e_A(g) (pow(10,(g/40.)))
#define e_omega(f,r) (2.0*M_PI*f/r)
#define e_alpha(bw,omega) (sin(omega)*sinh(LN2/2. * bw * omega/sin(omega)))
#define e_beta(a,S) (sqrt((a*a + 1)/(S) - (a-1)*(a-1)))
typedef struct _rbjfilter
{
t_object x_obj;
t_float x_rate;
t_float x_freq;
t_float x_gain;
t_float x_bw;
} t_rbjfilter;
static int check_stability(t_float fb1,
t_float fb2,
t_float ff1,
t_float ff2,
t_float ff3)
{
#ifdef ROCKBOX
(void) ff1;
(void) ff2;
(void) ff3;
#endif
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;
}
#endif

View file

@ -1,379 +1,452 @@
/* (C) Guenter Geiger <geiger@xdv.org> */
#include "m_pd.h"
#include "g_canvas.h"
/* ------------------------ gcanvas ----------------------------- */
#define BACKGROUNDCOLOR "grey"
#define DEFAULTSIZE 80
static t_class *gcanvas_class;
typedef struct _gcanvas
{
t_object x_obj;
t_glist * x_glist;
t_outlet* out2;
t_outlet* out3;
int x_width;
int x_height;
int x;
int y;
int x_xgrid;
int x_ygrid;
} t_gcanvas;
static void rectangle(void* cv,void* o,char c,int x, int y,int w,int h,char* color) {
sys_vgui(".x%x.c create rectangle \
%d %d %d %d -tags %x%c -fill %s\n",cv,x,y,x+w,y+h,o,c,color);
}
static void move_object(void* cv,void* o,char c,int x, int y,int w,int h) {
sys_vgui(".x%x.c coords %x%c %d %d %d %d\n",
cv,o,c,x,y,x+w,y+h);
}
static void color_object(void* cv,void* o,char c,char* color) {
sys_vgui(".x%x.c itemconfigure %x%c -fill %s\n", cv,
o, c,color);
}
static void delete_object(void* cv,void* o,char c) {
sys_vgui(".x%x.c delete %x%c\n",
cv, o,c);
}
static void line(void* cv,void* o,char c,int x,int y,int w,int h,char* color) {
sys_vgui(".x%x.c create line \
%d %d %d %d -tags %x%c -fill %s\n",cv,x,y,x+w,y+h,o,c,color);
}
/* widget helper functions */
void gcanvas_drawme(t_gcanvas *x, t_glist *glist, int firsttime)
{
int i;
if (firsttime) {
rectangle(glist_getcanvas(glist),x,'a',
x->x_obj.te_xpix, x->x_obj.te_ypix,
x->x_width, x->x_height,BACKGROUNDCOLOR);
for (i=1;i<x->x_xgrid;i++)
line(glist_getcanvas(glist),x,'b'+ i,
x->x_obj.te_xpix + x->x_width*i/x->x_xgrid,
x->x_obj.te_ypix,
0, x->x_height,"red");
for (i=1;i<x->x_ygrid;i++)
line(glist_getcanvas(glist),x,'B'+ i,
x->x_obj.te_xpix,
x->x_obj.te_ypix + x->x_height*i/x->x_ygrid,
x->x_width, 0,"blue");
}
else {
move_object(
glist_getcanvas(glist),x,'a',
x->x_obj.te_xpix, x->x_obj.te_ypix,
x->x_width, x->x_height);
for (i=1;i<x->x_xgrid;i++)
move_object(glist_getcanvas(glist),x,'b'+ i,
x->x_obj.te_xpix + x->x_width*i/x->x_xgrid,
x->x_obj.te_ypix,
0, x->x_height);
for (i=1;i<x->x_ygrid;i++)
move_object(glist_getcanvas(glist),x,'B'+ i,
x->x_obj.te_xpix,
x->x_obj.te_ypix + x->x_height*i/x->x_ygrid,
x->x_width, 0);
}
{
/* outlets */
int n = 3;
int nplus, i;
nplus = (n == 1 ? 1 : n-1);
for (i = 0; i < n; i++)
{
int onset = x->x_obj.te_xpix + (x->x_width - IOWIDTH) * i / nplus;
if (firsttime)
sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n",
glist_getcanvas(glist),
onset, x->x_obj.te_ypix + x->x_height - 1,
onset + IOWIDTH, x->x_obj.te_ypix + x->x_height,
x, i);
else
sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
glist_getcanvas(glist), x, i,
onset, x->x_obj.te_ypix + x->x_height - 1,
onset + IOWIDTH, x->x_obj.te_ypix + x->x_height);
}
/* inlets */
n = 0;
nplus = (n == 1 ? 1 : n-1);
for (i = 0; i < n; i++)
{
int onset = x->x_obj.te_xpix + (x->x_width - IOWIDTH) * i / nplus;
if (firsttime)
sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n",
glist_getcanvas(glist),
onset, x->x_obj.te_ypix,
onset + IOWIDTH, x->x_obj.te_ypix + 1,
x, i);
else
sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
glist_getcanvas(glist), x, i,
onset, x->x_obj.te_ypix,
onset + IOWIDTH, x->x_obj.te_ypix + 1);
}
}
}
void gcanvas_erase(t_gcanvas* x,t_glist* glist)
{
int n,i;
delete_object(glist_getcanvas(glist),x,'a');
for (i=1;i<x->x_xgrid;i++)
delete_object(glist_getcanvas(glist),x,'b'+ i);
for (i=1;i<x->x_ygrid;i++)
delete_object(glist_getcanvas(glist),x,'B'+ i);
n = 2;
while (n--) {
sys_vgui(".x%x.c delete %xo%d\n",glist_getcanvas(glist),x,n);
}
}
/* ------------------------ gcanvas widgetbehaviour----------------------------- */
static void gcanvas_getrect(t_gobj *z, t_glist *owner,
int *xp1, int *yp1, int *xp2, int *yp2)
{
int width, height;
t_gcanvas* s = (t_gcanvas*)z;
width = s->x_width;
height = s->x_height;
*xp1 = s->x_obj.te_xpix;
*yp1 = s->x_obj.te_ypix;
*xp2 = s->x_obj.te_xpix + width;
*yp2 = s->x_obj.te_ypix + height;
}
static void gcanvas_displace(t_gobj *z, t_glist *glist,
int dx, int dy)
{
t_gcanvas *x = (t_gcanvas *)z;
x->x_obj.te_xpix += dx;
x->x_obj.te_ypix += dy;
gcanvas_drawme(x, glist, 0);
canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
}
static void gcanvas_select(t_gobj *z, t_glist *glist, int state)
{
t_gcanvas *x = (t_gcanvas *)z;
color_object(glist,x,'a',state ? "blue" : BACKGROUNDCOLOR);
}
static void gcanvas_activate(t_gobj *z, t_glist *glist, int state)
{
/* t_text *x = (t_text *)z;
t_rtext *y = glist_findrtext(glist, x);
if (z->g_pd != gatom_class) rtext_activate(y, state);*/
}
static void gcanvas_delete(t_gobj *z, t_glist *glist)
{
t_text *x = (t_text *)z;
canvas_deletelinesfor(glist_getcanvas(glist), x);
}
static void gcanvas_vis(t_gobj *z, t_glist *glist, int vis)
{
t_gcanvas* s = (t_gcanvas*)z;
if (vis)
gcanvas_drawme(s, glist, 1);
else
gcanvas_erase(s,glist);
}
/* can we use the normal text save function ?? */
static void gcanvas_save(t_gobj *z, t_binbuf *b)
{
t_gcanvas *x = (t_gcanvas *)z;
binbuf_addv(b, "ssiisiiii", gensym("#X"),gensym("obj"),
(t_int)x->x_obj.te_xpix, (t_int)x->x_obj.te_ypix,
gensym("gcanvas"),x->x_width,x->x_height,
x->x_xgrid,
x->x_ygrid);
binbuf_addv(b, ";");
}
t_widgetbehavior gcanvas_widgetbehavior;
static void gcanvas_motion(t_gcanvas *x, t_floatarg dx, t_floatarg dy)
{
x->x += dx;
x->y += dy;
outlet_float(x->out2,x->y);
outlet_float(x->x_obj.ob_outlet,x->x);
}
void gcanvas_key(t_gcanvas *x, t_floatarg f)
{
post("key");
}
static void gcanvas_click(t_gcanvas *x,
t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
t_floatarg doit,int up)
{
glist_grab(x->x_glist, &x->x_obj.te_g, (t_glistmotionfn) gcanvas_motion,
(t_glistkeyfn) NULL, xpos, ypos);
x->x = xpos - x->x_obj.te_xpix;
x->y = ypos - x->x_obj.te_ypix;
outlet_float(x->out2,x->y);
outlet_float(x->x_obj.ob_outlet,x->x);
outlet_float(x->out3,0);
}
static int gcanvas_newclick(t_gobj *z, struct _glist *glist,
int xpix, int ypix, int shift, int alt, int dbl, int doit)
{
if (doit)
gcanvas_click((t_gcanvas *)z, (t_floatarg)xpix, (t_floatarg)ypix,
(t_floatarg)shift, 0, (t_floatarg)alt,dbl);
if (dbl) outlet_float(((t_gcanvas*)z)->out3,1);
return (1);
}
void gcanvas_size(t_gcanvas* x,t_floatarg w,t_floatarg h) {
x->x_width = w;
x->x_height = h;
gcanvas_drawme(x, x->x_glist, 0);
}
static void gcanvas_setwidget(void)
{
gcanvas_widgetbehavior.w_getrectfn = gcanvas_getrect;
gcanvas_widgetbehavior.w_displacefn = gcanvas_displace;
gcanvas_widgetbehavior.w_selectfn = gcanvas_select;
gcanvas_widgetbehavior.w_activatefn = gcanvas_activate;
gcanvas_widgetbehavior.w_deletefn = gcanvas_delete;
gcanvas_widgetbehavior.w_visfn = gcanvas_vis;
gcanvas_widgetbehavior.w_clickfn = gcanvas_newclick;
class_setsavefn(gcanvas_class,gcanvas_save);
}
static void *gcanvas_new(t_symbol* s,t_int ac,t_atom* at)
{
t_gcanvas *x = (t_gcanvas *)pd_new(gcanvas_class);
x->x_glist = (t_glist*) canvas_getcurrent();
/* Fetch the width */
x->x_width = DEFAULTSIZE;
if (ac-- > 0) {
if (at->a_type != A_FLOAT)
error("gcanvas: wrong argument type");
else
x->x_width = atom_getfloat(at++);
if (x->x_width < 0 || x->x_width > 2000) {
error("gcanvas: unallowed width %f",x->x_width);
x->x_width = DEFAULTSIZE;
}
}
/* Fetch the height */
x->x_height = DEFAULTSIZE;
if (ac-- > 0) {
if (at->a_type != A_FLOAT)
error("gcanvas: wrong argument type");
else
x->x_height = atom_getfloat(at++);
if (x->x_height < 0 || x->x_height > 2000) {
error("gcanvas: unallowed height %f",x->x_height);
x->x_width = DEFAULTSIZE;
}
}
/* Fetch the xgrid */
x->x_xgrid = 0;
if (ac-- > 0) {
if (at->a_type != A_FLOAT)
error("gcanvas: wrong argument type");
else
x->x_xgrid = atom_getfloat(at++);
if (x->x_xgrid < 0 || x->x_xgrid > x->x_width/2) {
error("gcanvas: unallowed xgrid %f",x->x_xgrid);
x->x_xgrid = 0;
}
}
/* Fetch the ygrid */
x->x_ygrid = 0;
if (ac-- > 0) {
if (at->a_type != A_FLOAT)
error("gcanvas: wrong argument type");
else
x->x_ygrid = atom_getfloat(at++);
if (x->x_ygrid < 0 || x->x_ygrid > x->x_height/2) {
error("gcanvas: unallowed xgrid %f",x->x_ygrid);
x->x_ygrid = 0;
}
}
outlet_new(&x->x_obj, &s_float);
x->out2 = outlet_new(&x->x_obj, &s_float);
x->out3 = outlet_new(&x->x_obj, &s_float);
return (x);
}
void gcanvas_setup(void)
{
gcanvas_class = class_new(gensym("gcanvas"), (t_newmethod)gcanvas_new, 0,
sizeof(t_gcanvas),0, A_GIMME,0);
class_addmethod(gcanvas_class, (t_method)gcanvas_click, gensym("click"),
A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
class_addmethod(gcanvas_class, (t_method)gcanvas_size, gensym("size"),
A_FLOAT, A_FLOAT, 0);
gcanvas_setwidget();
class_setwidget(gcanvas_class,&gcanvas_widgetbehavior);
}
/* (C) Guenter Geiger <geiger@xdv.org> */
#include "m_pd.h"
#include "g_canvas.h"
/* ------------------------ gcanvas ----------------------------- */
#define BACKGROUNDCOLOR "grey"
#define DEFAULTSIZE 80
static t_class *gcanvas_class;
typedef struct _gcanvas
{
t_object x_obj;
t_glist * x_glist;
t_outlet* out2;
t_outlet* out3;
int x_width;
int x_height;
int x;
int y;
int x_xgrid;
int x_ygrid;
} t_gcanvas;
static void rectangle(void* cv,void* o,char c,int x, int y,int w,int h,char* color) {
#ifdef ROCKBOX
(void) cv;
(void) o;
(void) c;
(void) x;
(void) y;
(void) w;
(void) h;
(void) color;
#else /* ROCKBOX */
sys_vgui(".x%x.c create rectangle \
%d %d %d %d -tags %x%c -fill %s\n",cv,x,y,x+w,y+h,o,c,color);
#endif /* ROCKBOX */
}
static void move_object(void* cv,void* o,char c,int x, int y,int w,int h) {
#ifdef ROCKBOX
(void) cv;
(void) o;
(void) c;
(void) x;
(void) y;
(void) w;
(void) h;
#else /* ROCKBOX */
sys_vgui(".x%x.c coords %x%c %d %d %d %d\n",
cv,o,c,x,y,x+w,y+h);
#endif /* ROCKBOX */
}
static void color_object(void* cv,void* o,char c,char* color) {
#ifdef ROCKBOX
(void) cv;
(void) o;
(void) c;
(void) color;
#else /* ROCKBOX */
sys_vgui(".x%x.c itemconfigure %x%c -fill %s\n", cv,
o, c,color);
#endif /* ROCKBOX */
}
static void delete_object(void* cv,void* o,char c) {
#ifdef ROCKBOX
(void) cv;
(void) o;
(void) c;
#else /* ROCKBOX */
sys_vgui(".x%x.c delete %x%c\n",
cv, o,c);
#endif /* ROCKBOX */
}
static void line(void* cv,void* o,char c,int x,int y,int w,int h,char* color) {
#ifdef ROCKBOX
(void) cv;
(void) o;
(void) c;
(void) x;
(void) y;
(void) w;
(void) h;
(void) color;
#else /* ROCKBOX */
sys_vgui(".x%x.c create line \
%d %d %d %d -tags %x%c -fill %s\n",cv,x,y,x+w,y+h,o,c,color);
#endif /* ROCKBOX */
}
/* widget helper functions */
void gcanvas_drawme(t_gcanvas *x, t_glist *glist, int firsttime)
{
int i;
if (firsttime) {
rectangle(glist_getcanvas(glist),x,'a',
x->x_obj.te_xpix, x->x_obj.te_ypix,
x->x_width, x->x_height,BACKGROUNDCOLOR);
for (i=1;i<x->x_xgrid;i++)
line(glist_getcanvas(glist),x,'b'+ i,
x->x_obj.te_xpix + x->x_width*i/x->x_xgrid,
x->x_obj.te_ypix,
0, x->x_height,"red");
for (i=1;i<x->x_ygrid;i++)
line(glist_getcanvas(glist),x,'B'+ i,
x->x_obj.te_xpix,
x->x_obj.te_ypix + x->x_height*i/x->x_ygrid,
x->x_width, 0,"blue");
}
else {
move_object(
glist_getcanvas(glist),x,'a',
x->x_obj.te_xpix, x->x_obj.te_ypix,
x->x_width, x->x_height);
for (i=1;i<x->x_xgrid;i++)
move_object(glist_getcanvas(glist),x,'b'+ i,
x->x_obj.te_xpix + x->x_width*i/x->x_xgrid,
x->x_obj.te_ypix,
0, x->x_height);
for (i=1;i<x->x_ygrid;i++)
move_object(glist_getcanvas(glist),x,'B'+ i,
x->x_obj.te_xpix,
x->x_obj.te_ypix + x->x_height*i/x->x_ygrid,
x->x_width, 0);
}
{
/* outlets */
int n = 3;
int nplus, i;
nplus = (n == 1 ? 1 : n-1);
for (i = 0; i < n; i++)
{
#ifndef ROCKBOX
int onset = x->x_obj.te_xpix + (x->x_width - IOWIDTH) * i / nplus;
if (firsttime)
sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n",
glist_getcanvas(glist),
onset, x->x_obj.te_ypix + x->x_height - 1,
onset + IOWIDTH, x->x_obj.te_ypix + x->x_height,
x, i);
else
sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
glist_getcanvas(glist), x, i,
onset, x->x_obj.te_ypix + x->x_height - 1,
onset + IOWIDTH, x->x_obj.te_ypix + x->x_height);
#endif /* ROCKBOX */
}
/* inlets */
n = 0;
nplus = (n == 1 ? 1 : n-1);
for (i = 0; i < n; i++)
{
#ifndef ROCKBOX
int onset = x->x_obj.te_xpix + (x->x_width - IOWIDTH) * i / nplus;
if (firsttime)
sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n",
glist_getcanvas(glist),
onset, x->x_obj.te_ypix,
onset + IOWIDTH, x->x_obj.te_ypix + 1,
x, i);
else
sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
glist_getcanvas(glist), x, i,
onset, x->x_obj.te_ypix,
onset + IOWIDTH, x->x_obj.te_ypix + 1);
#endif /* ROCKBOX */
}
}
}
void gcanvas_erase(t_gcanvas* x,t_glist* glist)
{
int n,i;
delete_object(glist_getcanvas(glist),x,'a');
for (i=1;i<x->x_xgrid;i++)
delete_object(glist_getcanvas(glist),x,'b'+ i);
for (i=1;i<x->x_ygrid;i++)
delete_object(glist_getcanvas(glist),x,'B'+ i);
n = 2;
while (n--) {
#ifndef ROCKBOX
sys_vgui(".x%x.c delete %xo%d\n",glist_getcanvas(glist),x,n);
#endif
}
}
/* ------------------------ gcanvas widgetbehaviour----------------------------- */
static void gcanvas_getrect(t_gobj *z, t_glist *owner,
int *xp1, int *yp1, int *xp2, int *yp2)
{
#ifdef ROCKBOX
(void) owner;
#endif
int width, height;
t_gcanvas* s = (t_gcanvas*)z;
width = s->x_width;
height = s->x_height;
*xp1 = s->x_obj.te_xpix;
*yp1 = s->x_obj.te_ypix;
*xp2 = s->x_obj.te_xpix + width;
*yp2 = s->x_obj.te_ypix + height;
}
static void gcanvas_displace(t_gobj *z, t_glist *glist,
int dx, int dy)
{
t_gcanvas *x = (t_gcanvas *)z;
x->x_obj.te_xpix += dx;
x->x_obj.te_ypix += dy;
gcanvas_drawme(x, glist, 0);
canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
}
static void gcanvas_select(t_gobj *z, t_glist *glist, int state)
{
t_gcanvas *x = (t_gcanvas *)z;
color_object(glist,x,'a',state ? "blue" : BACKGROUNDCOLOR);
}
static void gcanvas_activate(t_gobj *z, t_glist *glist, int state)
{
#ifdef ROCKBOX
(void) z;
(void) glist;
(void) state;
#endif
/* t_text *x = (t_text *)z;
t_rtext *y = glist_findrtext(glist, x);
if (z->g_pd != gatom_class) rtext_activate(y, state);*/
}
static void gcanvas_delete(t_gobj *z, t_glist *glist)
{
t_text *x = (t_text *)z;
canvas_deletelinesfor(glist_getcanvas(glist), x);
}
static void gcanvas_vis(t_gobj *z, t_glist *glist, int vis)
{
t_gcanvas* s = (t_gcanvas*)z;
if (vis)
gcanvas_drawme(s, glist, 1);
else
gcanvas_erase(s,glist);
}
/* can we use the normal text save function ?? */
static void gcanvas_save(t_gobj *z, t_binbuf *b)
{
t_gcanvas *x = (t_gcanvas *)z;
binbuf_addv(b, "ssiisiiii", gensym("#X"),gensym("obj"),
(t_int)x->x_obj.te_xpix, (t_int)x->x_obj.te_ypix,
gensym("gcanvas"),x->x_width,x->x_height,
x->x_xgrid,
x->x_ygrid);
binbuf_addv(b, ";");
}
t_widgetbehavior gcanvas_widgetbehavior;
static void gcanvas_motion(t_gcanvas *x, t_floatarg dx, t_floatarg dy)
{
x->x += dx;
x->y += dy;
outlet_float(x->out2,x->y);
outlet_float(x->x_obj.ob_outlet,x->x);
}
void gcanvas_key(t_gcanvas *x, t_floatarg f)
{
#ifdef ROCKBOX
(void) x;
(void) f;
#endif
post("key");
}
static void gcanvas_click(t_gcanvas *x,
t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
t_floatarg doit,int up)
{
#ifdef ROCKBOX
(void) shift;
(void) ctrl;
(void) doit;
(void) up;
#endif
glist_grab(x->x_glist, &x->x_obj.te_g, (t_glistmotionfn) gcanvas_motion,
(t_glistkeyfn) NULL, xpos, ypos);
x->x = xpos - x->x_obj.te_xpix;
x->y = ypos - x->x_obj.te_ypix;
outlet_float(x->out2,x->y);
outlet_float(x->x_obj.ob_outlet,x->x);
outlet_float(x->out3,0);
}
static int gcanvas_newclick(t_gobj *z, struct _glist *glist,
int xpix, int ypix, int shift, int alt, int dbl, int doit)
{
#ifdef ROCKBOX
(void) glist;
#endif
if (doit)
gcanvas_click((t_gcanvas *)z, (t_floatarg)xpix, (t_floatarg)ypix,
(t_floatarg)shift, 0, (t_floatarg)alt,dbl);
if (dbl) outlet_float(((t_gcanvas*)z)->out3,1);
return (1);
}
void gcanvas_size(t_gcanvas* x,t_floatarg w,t_floatarg h) {
x->x_width = w;
x->x_height = h;
gcanvas_drawme(x, x->x_glist, 0);
}
static void gcanvas_setwidget(void)
{
gcanvas_widgetbehavior.w_getrectfn = gcanvas_getrect;
gcanvas_widgetbehavior.w_displacefn = gcanvas_displace;
gcanvas_widgetbehavior.w_selectfn = gcanvas_select;
gcanvas_widgetbehavior.w_activatefn = gcanvas_activate;
gcanvas_widgetbehavior.w_deletefn = gcanvas_delete;
gcanvas_widgetbehavior.w_visfn = gcanvas_vis;
gcanvas_widgetbehavior.w_clickfn = gcanvas_newclick;
class_setsavefn(gcanvas_class,gcanvas_save);
}
static void *gcanvas_new(t_symbol* s,t_int ac,t_atom* at)
{
#ifdef ROCKBOX
(void) s;
#endif
t_gcanvas *x = (t_gcanvas *)pd_new(gcanvas_class);
x->x_glist = (t_glist*) canvas_getcurrent();
/* Fetch the width */
x->x_width = DEFAULTSIZE;
if (ac-- > 0) {
if (at->a_type != A_FLOAT)
error("gcanvas: wrong argument type");
else
x->x_width = atom_getfloat(at++);
if (x->x_width < 0 || x->x_width > 2000) {
error("gcanvas: unallowed width %f",x->x_width);
x->x_width = DEFAULTSIZE;
}
}
/* Fetch the height */
x->x_height = DEFAULTSIZE;
if (ac-- > 0) {
if (at->a_type != A_FLOAT)
error("gcanvas: wrong argument type");
else
x->x_height = atom_getfloat(at++);
if (x->x_height < 0 || x->x_height > 2000) {
error("gcanvas: unallowed height %f",x->x_height);
x->x_width = DEFAULTSIZE;
}
}
/* Fetch the xgrid */
x->x_xgrid = 0;
if (ac-- > 0) {
if (at->a_type != A_FLOAT)
error("gcanvas: wrong argument type");
else
x->x_xgrid = atom_getfloat(at++);
if (x->x_xgrid < 0 || x->x_xgrid > x->x_width/2) {
error("gcanvas: unallowed xgrid %f",x->x_xgrid);
x->x_xgrid = 0;
}
}
/* Fetch the ygrid */
x->x_ygrid = 0;
if (ac-- > 0) {
if (at->a_type != A_FLOAT)
error("gcanvas: wrong argument type");
else
x->x_ygrid = atom_getfloat(at++);
if (x->x_ygrid < 0 || x->x_ygrid > x->x_height/2) {
error("gcanvas: unallowed xgrid %f",x->x_ygrid);
x->x_ygrid = 0;
}
}
outlet_new(&x->x_obj, &s_float);
x->out2 = outlet_new(&x->x_obj, &s_float);
x->out3 = outlet_new(&x->x_obj, &s_float);
return (x);
}
void gcanvas_setup(void)
{
gcanvas_class = class_new(gensym("gcanvas"), (t_newmethod)gcanvas_new, 0,
sizeof(t_gcanvas),0, A_GIMME,0);
class_addmethod(gcanvas_class, (t_method)gcanvas_click, gensym("click"),
A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
class_addmethod(gcanvas_class, (t_method)gcanvas_size, gensym("size"),
A_FLOAT, A_FLOAT, 0);
gcanvas_setwidget();
class_setwidget(gcanvas_class,&gcanvas_widgetbehavior);
}

View file

@ -1,85 +1,94 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- highpass ----------------------------*/
static t_class *highpass_class;
void highpass_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw* 0.01,omega);
t_float b1 = -(1 + cos(omega));
t_float b0 = -b1/2.;
t_float b2 = b0;
t_float a0 = 1 + alpha;
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha;
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("highpass: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void highpass_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
highpass_bang(x);
}
static void *highpass_new(t_floatarg f,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(highpass_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
/* floatinlet_new(&x->x_obj, &x->x_gain); */
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
return (x);
}
void highpass_setup(void)
{
highpass_class = class_new(gensym("highpass"), (t_newmethod)highpass_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(highpass_class,highpass_bang);
class_addfloat(highpass_class,highpass_float);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#ifdef ROCKBOX
#include "plugin.h"
#include "pdbox.h"
#include "m_pd.h"
#include "math.h"
#include "filters.h"
#else /* ROCKBOX */
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
#endif /* ROCKBOX */
/* ------------------- highpass ----------------------------*/
static t_class *highpass_class;
void highpass_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw* 0.01,omega);
t_float b1 = -(1 + cos(omega));
t_float b0 = -b1/2.;
t_float b2 = b0;
t_float a0 = 1 + alpha;
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha;
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("highpass: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void highpass_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
highpass_bang(x);
}
static void *highpass_new(t_floatarg f,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(highpass_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
/* floatinlet_new(&x->x_obj, &x->x_gain); */
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
return (x);
}
void highpass_setup(void)
{
highpass_class = class_new(gensym("highpass"), (t_newmethod)highpass_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(highpass_class,highpass_bang);
class_addfloat(highpass_class,highpass_float);
}

View file

@ -1,90 +1,98 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- highshelf ----------------------------*/
static t_class *highshelf_class;
void highshelf_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float A = e_A(x->x_gain);
t_float cs = cos(omega);
t_float sn = sin(omega);
t_float beta = e_beta(A,x->x_bw* 0.01);
t_float b0 = A*((A+1) + (A-1)*cs + beta*sn);
t_float b1 =-2.*A*((A-1) + (A+1)*cs);
t_float b2 = A*((A+1) + (A-1)*cs - beta*sn);
t_float a0 = ((A+1) - (A-1)*cs + beta*sn);
t_float a1 = 2.*((A-1) - (A+1)*cs);
t_float a2 = ((A+1) - (A-1)*cs - beta*sn);
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw);*/
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("highshelf: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void highshelf_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
highshelf_bang(x);
}
static void *highshelf_new(t_floatarg f,t_floatarg g,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(highshelf_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
floatinlet_new(&x->x_obj, &x->x_gain);
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
if (g != 0.) x->x_gain = g;
return (x);
}
void highshelf_setup(void)
{
highshelf_class = class_new(gensym("highshelf"), (t_newmethod)highshelf_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(highshelf_class,highshelf_bang);
class_addfloat(highshelf_class,highshelf_float);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#ifdef ROCKBOX
#include "plugin.h"
#include "pdbox.h"
#include "m_pd.h"
#include "math.h"
#include "filters.h"
#else /* ROCKBOX */
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
#endif /* ROCKBOX */
/* ------------------- highshelf ----------------------------*/
static t_class *highshelf_class;
void highshelf_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float A = e_A(x->x_gain);
t_float cs = cos(omega);
t_float sn = sin(omega);
t_float beta = e_beta(A,x->x_bw* 0.01);
t_float b0 = A*((A+1) + (A-1)*cs + beta*sn);
t_float b1 =-2.*A*((A-1) + (A+1)*cs);
t_float b2 = A*((A+1) + (A-1)*cs - beta*sn);
t_float a0 = ((A+1) - (A-1)*cs + beta*sn);
t_float a1 = 2.*((A-1) - (A+1)*cs);
t_float a2 = ((A+1) - (A-1)*cs - beta*sn);
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw);*/
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("highshelf: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void highshelf_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
highshelf_bang(x);
}
static void *highshelf_new(t_floatarg f,t_floatarg g,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(highshelf_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
floatinlet_new(&x->x_obj, &x->x_gain);
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
if (g != 0.) x->x_gain = g;
return (x);
}
void highshelf_setup(void)
{
highshelf_class = class_new(gensym("highshelf"), (t_newmethod)highshelf_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(highshelf_class,highshelf_bang);
class_addfloat(highshelf_class,highshelf_float);
}

View file

@ -1,226 +1,242 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
#include <m_pd.h>
#include <math.h>
#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 <geiger@epy.co.at> */
#ifdef ROCKBOX
#include "plugin.h"
#include "pdbox.h"
#include "m_pd.h"
#include "math.h"
#else /* ROCKBOX */
#include <m_pd.h>
#include <math.h>
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#endif /* ROCKBOX */
/* ------------------------ 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)
{
#ifdef ROCKBOX
(void) ff1;
(void) ff2;
(void) ff3;
#endif
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)
{
#ifdef ROCKBOX
(void) s;
(void) argc;
#endif
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);
}

View file

@ -23,6 +23,11 @@ typedef struct _image
void image_drawme(t_image *x, t_glist *glist, int firsttime)
{
#ifdef ROCKBOX
(void) x;
(void) glist;
(void) firsttime;
#else /* ROCKBOX */
if (firsttime) {
char fname[MAXPDSTRING];
canvas_makefilename(glist_getcanvas(x->x_glist), x->x_fname->s_name,
@ -42,16 +47,20 @@ void image_drawme(t_image *x, t_glist *glist, int firsttime)
glist_getcanvas(glist), x,
text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist));
}
#endif /* ROCKBOX */
}
void image_erase(t_image* x,t_glist* glist)
{
#ifdef ROCKBOX
(void) x;
(void) glist;
#else /* ROCKBOX */
int n;
sys_vgui(".x%x.c delete %xS\n",
glist_getcanvas(glist), x);
#endif /* ROCKBOX */
}
@ -80,17 +89,23 @@ static void image_displace(t_gobj *z, t_glist *glist,
t_image *x = (t_image *)z;
x->x_obj.te_xpix += dx;
x->x_obj.te_ypix += dy;
#ifndef ROCKBOX
sys_vgui(".x%x.c coords %xSEL %d %d %d %d\n",
glist_getcanvas(glist), x,
text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist),
text_xpix(&x->x_obj, glist) + x->x_width, text_ypix(&x->x_obj, glist) + x->x_height);
#endif
image_drawme(x, glist, 0);
canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
}
static void image_select(t_gobj *z, t_glist *glist, int state)
{
#ifdef ROCKBOX
(void) z;
(void) glist;
(void) state;
#else /* ROCKBOX */
t_image *x = (t_image *)z;
if (state) {
sys_vgui(".x%x.c create rectangle \
@ -104,14 +119,17 @@ static void image_select(t_gobj *z, t_glist *glist, int state)
sys_vgui(".x%x.c delete %xSEL\n",
glist_getcanvas(glist), x);
}
#endif /* ROCKBOX */
}
static void image_activate(t_gobj *z, t_glist *glist, int state)
{
#ifdef ROCKBOX
(void) z;
(void) glist;
(void) state;
#endif
/* t_text *x = (t_text *)z;
t_rtext *y = glist_findrtext(glist, x);
if (z->g_pd != gatom_class) rtext_activate(y, state);*/
@ -154,6 +172,10 @@ void image_size(t_image* x,t_floatarg w,t_floatarg h) {
void image_color(t_image* x,t_symbol* col)
{
#ifdef ROCKBOX
(void) x;
(void) col;
#endif
/* outlet_bang(x->x_obj.ob_outlet); only bang if there was a bang ..
so color black does the same as bang, but doesn't forward the bang
*/
@ -167,11 +189,11 @@ static void image_setwidget(void)
image_widgetbehavior.w_activatefn = image_activate;
image_widgetbehavior.w_deletefn = image_delete;
image_widgetbehavior.w_visfn = image_vis;
#if (PD_VERSION_MINOR > 31)
#if defined(PD_VERSION_MINOR) && (PD_VERSION_MINOR > 31)
image_widgetbehavior.w_clickfn = NULL;
image_widgetbehavior.w_propertiesfn = NULL;
#endif
#if PD_MINOR_VERSION < 37
#if defined(PD_VERSION_MINOR) && PD_MINOR_VERSION < 37
image_widgetbehavior.w_savefn = image_save;
#endif
}

View file

@ -1,87 +1,94 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- lowpass ----------------------------*/
static t_class *lowpass_class;
void lowpass_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw*0.01,omega);
t_float b1 = 1 - cos(omega);
t_float b0 = b1/2.;
t_float b2 = b0;
t_float a0 = 1 + alpha;
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha;
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("lowpass: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void lowpass_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
lowpass_bang(x);
}
static void *lowpass_new(t_floatarg f,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(lowpass_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
/* floatinlet_new(&x->x_obj, &x->x_gain); */
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
return (x);
}
void lowpass_setup(void)
{
lowpass_class = class_new(gensym("lowpass"), (t_newmethod)lowpass_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(lowpass_class,lowpass_bang);
class_addfloat(lowpass_class,lowpass_float);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#ifdef ROCKBOX
#include "plugin.h"
#include "pdbox.h"
#include "m_pd.h"
#include "math.h"
#include "filters.h"
#else /* ROCKBOX */
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
#endif /* ROCKBOX */
/* ------------------- lowpass ----------------------------*/
static t_class *lowpass_class;
void lowpass_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw*0.01,omega);
t_float b1 = 1 - cos(omega);
t_float b0 = b1/2.;
t_float b2 = b0;
t_float a0 = 1 + alpha;
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha;
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("lowpass: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void lowpass_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
lowpass_bang(x);
}
static void *lowpass_new(t_floatarg f,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(lowpass_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
/* floatinlet_new(&x->x_obj, &x->x_gain); */
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
return (x);
}
void lowpass_setup(void)
{
lowpass_class = class_new(gensym("lowpass"), (t_newmethod)lowpass_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(lowpass_class,lowpass_bang);
class_addfloat(lowpass_class,lowpass_float);
}

View file

@ -1,91 +1,98 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- lowshelf ----------------------------*/
static t_class *lowshelf_class;
void lowshelf_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float A = e_A(x->x_gain);
t_float cs = cos(omega);
t_float sn = sin(omega);
t_float beta = e_beta(A,x->x_bw*0.01);
t_float b0 = A*((A+1) - (A-1)*cs + beta*sn);
t_float b1 = 2.*A*((A-1) - (A+1)*cs);
t_float b2 = A*((A+1) - (A-1)*cs - beta*sn);
t_float a0 = ((A+1) + (A-1)*cs + beta*sn);
t_float a1 = -2.*((A-1) + (A+1)*cs);
t_float a2 = ((A+1) + (A-1)*cs - beta*sn);
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("lowshelf: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void lowshelf_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
lowshelf_bang(x);
}
static void *lowshelf_new(t_floatarg f,t_floatarg g,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(lowshelf_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
floatinlet_new(&x->x_obj, &x->x_gain);
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
if (g != 0.) x->x_gain = g;
return (x);
}
void lowshelf_setup(void)
{
lowshelf_class = class_new(gensym("lowshelf"), (t_newmethod)lowshelf_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(lowshelf_class,lowshelf_bang);
class_addfloat(lowshelf_class,lowshelf_float);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#ifdef ROCKBOX
#include "plugin.h"
#include "pdbox.h"
#include "m_pd.h"
#include "math.h"
#include "filters.h"
#else /* ROCKBOX */
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
#endif /* ROCKBOX */
/* ------------------- lowshelf ----------------------------*/
static t_class *lowshelf_class;
void lowshelf_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float A = e_A(x->x_gain);
t_float cs = cos(omega);
t_float sn = sin(omega);
t_float beta = e_beta(A,x->x_bw*0.01);
t_float b0 = A*((A+1) - (A-1)*cs + beta*sn);
t_float b1 = 2.*A*((A-1) - (A+1)*cs);
t_float b2 = A*((A+1) - (A-1)*cs - beta*sn);
t_float a0 = ((A+1) + (A-1)*cs + beta*sn);
t_float a1 = -2.*((A-1) + (A+1)*cs);
t_float a2 = ((A+1) + (A-1)*cs - beta*sn);
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("lowshelf: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void lowshelf_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
lowshelf_bang(x);
}
static void *lowshelf_new(t_floatarg f,t_floatarg g,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(lowshelf_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
floatinlet_new(&x->x_obj, &x->x_gain);
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
if (g != 0.) x->x_gain = g;
return (x);
}
void lowshelf_setup(void)
{
lowshelf_class = class_new(gensym("lowshelf"), (t_newmethod)lowshelf_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(lowshelf_class,lowshelf_bang);
class_addfloat(lowshelf_class,lowshelf_float);
}

View file

@ -1,184 +1,194 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
#include "math.h"
#include <m_pd.h>
/* ----------------------------- moog ----------------------------- */
static t_class *moog_class;
typedef struct _moog
{
t_object x_obj;
t_pd in2;
t_sample x_1,x_2,x_3,x_4;
t_sample y_1,y_2,y_3,y_4;
} t_moog;
static void moog_reset(t_moog *x)
{
x->x_1 = x->x_2 = x->x_3 = x->x_4 = 0;
x->y_1 = x->y_2 = x->y_3 = x->y_4 = 0;
}
static void *moog_new(t_symbol *s, int argc, t_atom *argv)
{
if (argc > 1) post("moog~: extra arguments ignored");
{
t_moog *x = (t_moog *)pd_new(moog_class);
outlet_new(&x->x_obj, &s_signal);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
inlet_new(&x->x_obj, &x->in2, &s_signal, &s_signal);
moog_reset(x);
return (x);
}
}
static t_sample calc_k(t_sample f,t_sample k) {
if (k>itofix(4)) k = itofix(4);
if (k < 0) k = 0;
if (f <= itofix(3800)) return k;
k = k - mult(0.5,(f-idiv(itofix(3800),itofix(4300))));
return k;
}
t_int *moog_perform(t_int *w)
{
t_moog* x = (t_moog*) (w[1]);
t_sample *in1 = (t_sample *)(w[2]);
t_sample *p = (t_sample *)(w[3]);
t_sample *k = (t_sample *)(w[4]);
t_sample *out = (t_sample *)(w[5]);
int n = (int)(w[6]);
t_sample in;
t_sample pt,pt1;
t_sample x1 = x->x_1;
t_sample x2 = x->x_2;
t_sample x3 = x->x_3;
t_sample x4 = x->x_4;
t_sample ys1 = x->y_1;
t_sample ys2 = x->y_2;
t_sample ys3 = x->y_3;
t_sample ys4 = x->y_4;
while (n--) {
if (*p > itofix(8140)) *p = itofix(8140);
*k = calc_k(*p,*k);
pt =*p;
pt1=mult((pt+1),ftofix(0.76923077));
in = *in1++ - mult(*k,ys4);
ys1 = mult(pt1,in) + mult(0.3,x1) - mult(pt,ys1);
x1 = in;
ys2 = mult(pt1,ys1) + mult(0.3,x2) - mult(pt,ys2);
x2 = ys1;
ys3 = mult(pt1,ys2) + mult(0.3,x3) - mult(pt,ys3);
x3 = ys2;
ys4 = mult(pt1,ys3) + mult(0.3,x4) - mult(pt,ys4);
x4 = ys3;
*out++ = ys4;
}
x->y_1 = ys1;
x->y_2 = ys2;
x->y_3 = ys3;
x->y_4 = ys4;
x->x_1 = x1;
x->x_2 = x2;
x->x_3 = x3;
x->x_4 = x4;
return (w+7);
}
#define CLIP(x) x = ((x) > 1.0 ? (1.0) : (x))
t_int *moog_perf8(t_int *w)
{
t_moog* x = (t_moog*) (w[1]);
t_sample *in1 = (t_sample *)(w[2]);
t_sample *p = (t_sample *)(w[3]);
t_sample *k = (t_sample *)(w[4]);
t_sample *out = (t_sample *)(w[5]);
int n = (int)(w[6]);
t_sample x1 = x->x_1;
t_sample x2 = x->x_2;
t_sample x3 = x->x_3;
t_sample x4 = x->x_4;
t_sample ys1 = x->y_1;
t_sample ys2 = x->y_2;
t_sample ys3 = x->y_3;
t_sample ys4 = x->y_4;
t_sample temp,temp2;
t_sample pt,pt1;
t_sample in;
while (n--) {
if (*p > itofix(8140)) *p = itofix(8140);
*k = calc_k(*p,*k);
pt =mult(*p, ftofix(0.01*0.0140845)) - ftofix(0.9999999f);
pt1=mult((pt+itofix(1)),ftofix(0.76923077));
in = *in1++ - mult(*k,ys4);
ys1 = mult(pt1,(in + mult(ftofix(0.3),x1))) - mult(pt,ys1);
x1 = in;
ys2 = mult(pt1,(ys1 + mult(0.3,x2))) - mult(pt,ys2);
x2 = ys1;
ys3 = mult(pt1,(ys2 + mult(0.3,x3))) - mult(pt,ys3);
x3 = ys2;
ys4 = mult(pt1,(ys3 + mult(0.3,x4))) - mult(pt,ys4);
x4 = ys3;
*out++ = ys4;
p++;k++;
}
x->y_1 = ys1;
x->y_2 = ys2;
x->y_3 = ys3;
x->y_4 = ys4;
x->x_1 = x1;
x->x_2 = x2;
x->x_3 = x3;
x->x_4 = x4;
return (w+7);
}
void dsp_add_moog(t_moog *x, t_sample *in1, t_sample *in2, t_sample *in3, t_sample *out, int n)
{
if (n&7)
dsp_add(moog_perform, 6,(t_int)x, in1,in2,in3, out, n);
else
dsp_add(moog_perf8, 6,(t_int) x, in1, in2, in3, out, n);
}
static void moog_dsp(t_moog *x, t_signal **sp)
{
dsp_add_moog(x,sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec,sp[0]->s_n);
}
void moog_tilde_setup(void)
{
moog_class = class_new(gensym("moog~"), (t_newmethod)moog_new, 0,
sizeof(t_moog), 0, A_GIMME, 0);
class_addmethod(moog_class, nullfn, gensym("signal"), 0);
class_addmethod(moog_class, (t_method)moog_reset, gensym("reset"), 0);
class_addmethod(moog_class, (t_method)moog_dsp, gensym("dsp"), A_NULL);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
#include "math.h"
#ifdef ROCKBOX
#include "m_pd.h"
#else
#include <m_pd.h>
#endif
/* ----------------------------- moog ----------------------------- */
static t_class *moog_class;
typedef struct _moog
{
t_object x_obj;
t_pd in2;
t_sample x_1,x_2,x_3,x_4;
t_sample y_1,y_2,y_3,y_4;
} t_moog;
static void moog_reset(t_moog *x)
{
x->x_1 = x->x_2 = x->x_3 = x->x_4 = 0;
x->y_1 = x->y_2 = x->y_3 = x->y_4 = 0;
}
static void *moog_new(t_symbol *s, int argc, t_atom *argv)
{
#ifdef ROCKBOX
(void) s;
(void) argv;
#endif
if (argc > 1) post("moog~: extra arguments ignored");
{
t_moog *x = (t_moog *)pd_new(moog_class);
outlet_new(&x->x_obj, &s_signal);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
inlet_new(&x->x_obj, &x->in2, &s_signal, &s_signal);
moog_reset(x);
return (x);
}
}
static t_sample calc_k(t_sample f,t_sample k) {
if (k>itofix(4)) k = itofix(4);
if (k < 0) k = 0;
if (f <= itofix(3800)) return k;
k = k - mult(0.5,(f-idiv(itofix(3800),itofix(4300))));
return k;
}
t_int *moog_perform(t_int *w)
{
t_moog* x = (t_moog*) (w[1]);
t_sample *in1 = (t_sample *)(w[2]);
t_sample *p = (t_sample *)(w[3]);
t_sample *k = (t_sample *)(w[4]);
t_sample *out = (t_sample *)(w[5]);
int n = (int)(w[6]);
t_sample in;
t_sample pt,pt1;
t_sample x1 = x->x_1;
t_sample x2 = x->x_2;
t_sample x3 = x->x_3;
t_sample x4 = x->x_4;
t_sample ys1 = x->y_1;
t_sample ys2 = x->y_2;
t_sample ys3 = x->y_3;
t_sample ys4 = x->y_4;
while (n--) {
if (*p > itofix(8140)) *p = itofix(8140);
*k = calc_k(*p,*k);
pt =*p;
pt1=mult((pt+1),ftofix(0.76923077));
in = *in1++ - mult(*k,ys4);
ys1 = mult(pt1,in) + mult(0.3,x1) - mult(pt,ys1);
x1 = in;
ys2 = mult(pt1,ys1) + mult(0.3,x2) - mult(pt,ys2);
x2 = ys1;
ys3 = mult(pt1,ys2) + mult(0.3,x3) - mult(pt,ys3);
x3 = ys2;
ys4 = mult(pt1,ys3) + mult(0.3,x4) - mult(pt,ys4);
x4 = ys3;
*out++ = ys4;
}
x->y_1 = ys1;
x->y_2 = ys2;
x->y_3 = ys3;
x->y_4 = ys4;
x->x_1 = x1;
x->x_2 = x2;
x->x_3 = x3;
x->x_4 = x4;
return (w+7);
}
#define CLIP(x) x = ((x) > 1.0 ? (1.0) : (x))
t_int *moog_perf8(t_int *w)
{
t_moog* x = (t_moog*) (w[1]);
t_sample *in1 = (t_sample *)(w[2]);
t_sample *p = (t_sample *)(w[3]);
t_sample *k = (t_sample *)(w[4]);
t_sample *out = (t_sample *)(w[5]);
int n = (int)(w[6]);
t_sample x1 = x->x_1;
t_sample x2 = x->x_2;
t_sample x3 = x->x_3;
t_sample x4 = x->x_4;
t_sample ys1 = x->y_1;
t_sample ys2 = x->y_2;
t_sample ys3 = x->y_3;
t_sample ys4 = x->y_4;
#ifndef ROCKBOX
t_sample temp,temp2;
#endif
t_sample pt,pt1;
t_sample in;
while (n--) {
if (*p > itofix(8140)) *p = itofix(8140);
*k = calc_k(*p,*k);
pt =mult(*p, ftofix(0.01*0.0140845)) - ftofix(0.9999999f);
pt1=mult((pt+itofix(1)),ftofix(0.76923077));
in = *in1++ - mult(*k,ys4);
ys1 = mult(pt1,(in + mult(ftofix(0.3),x1))) - mult(pt,ys1);
x1 = in;
ys2 = mult(pt1,(ys1 + mult(0.3,x2))) - mult(pt,ys2);
x2 = ys1;
ys3 = mult(pt1,(ys2 + mult(0.3,x3))) - mult(pt,ys3);
x3 = ys2;
ys4 = mult(pt1,(ys3 + mult(0.3,x4))) - mult(pt,ys4);
x4 = ys3;
*out++ = ys4;
p++;k++;
}
x->y_1 = ys1;
x->y_2 = ys2;
x->y_3 = ys3;
x->y_4 = ys4;
x->x_1 = x1;
x->x_2 = x2;
x->x_3 = x3;
x->x_4 = x4;
return (w+7);
}
void dsp_add_moog(t_moog *x, t_sample *in1, t_sample *in2, t_sample *in3, t_sample *out, int n)
{
if (n&7)
dsp_add(moog_perform, 6,(t_int)x, in1,in2,in3, out, n);
else
dsp_add(moog_perf8, 6,(t_int) x, in1, in2, in3, out, n);
}
static void moog_dsp(t_moog *x, t_signal **sp)
{
dsp_add_moog(x,sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec,sp[0]->s_n);
}
void moog_tilde_setup(void)
{
moog_class = class_new(gensym("moog~"), (t_newmethod)moog_new, 0,
sizeof(t_moog), 0, A_GIMME, 0);
class_addmethod(moog_class, nullfn, gensym("signal"), 0);
class_addmethod(moog_class, (t_method)moog_reset, gensym("reset"), 0);
class_addmethod(moog_class, (t_method)moog_dsp, gensym("dsp"), A_NULL);
}

View file

@ -1,85 +1,93 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
/* ------------------- notch ----------------------------*/
static t_class *notch_class;
void notch_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw* 0.01,omega);
t_float b1 = -2.*cos(omega);
t_float b0 = 1;
t_float b2 = b0;
t_float a0 = 1 + alpha;
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha;
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("notch: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void notch_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
notch_bang(x);
}
static void *notch_new(t_floatarg f,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(notch_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
/* floatinlet_new(&x->x_obj, &x->x_gain); */
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
return (x);
}
void notch_setup(void)
{
notch_class = class_new(gensym("notch"), (t_newmethod)notch_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(notch_class,notch_bang);
class_addfloat(notch_class,notch_float);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
/*
These filter coefficients computations are taken from
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
written by Robert Bristow-Johnson
*/
#ifdef ROCKBOX
#include "plugin.h"
#include "pdbox.h"
#include "m_pd.h"
#include "math.h"
#include "filters.h"
#else /* ROCKBOX */
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <math.h>
#include "filters.h"
#endif /* ROCKBOX */
/* ------------------- notch ----------------------------*/
static t_class *notch_class;
void notch_bang(t_rbjfilter *x)
{
t_atom at[5];
t_float omega = e_omega(x->x_freq,x->x_rate);
t_float alpha = e_alpha(x->x_bw* 0.01,omega);
t_float b1 = -2.*cos(omega);
t_float b0 = 1;
t_float b2 = b0;
t_float a0 = 1 + alpha;
t_float a1 = -2.*cos(omega);
t_float a2 = 1 - alpha;
/* post("bang %f %f %f",x->x_freq, x->x_gain, x->x_bw); */
if (!check_stability(-a1/a0,-a2/a0,b0/a0,b1/a0,b2/a0)) {
post("notch: filter unstable -> resetting");
a0=1.;a1=0.;a2=0.;
b0=1.;b1=0.;b2=0.;
}
SETFLOAT(at,-a1/a0);
SETFLOAT(at+1,-a2/a0);
SETFLOAT(at+2,b0/a0);
SETFLOAT(at+3,b1/a0);
SETFLOAT(at+4,b2/a0);
outlet_list(x->x_obj.ob_outlet,&s_list,5,at);
}
void notch_float(t_rbjfilter *x,t_floatarg f)
{
x->x_freq = f;
notch_bang(x);
}
static void *notch_new(t_floatarg f,t_floatarg bw)
{
t_rbjfilter *x = (t_rbjfilter *)pd_new(notch_class);
x->x_rate = 44100.0;
outlet_new(&x->x_obj,&s_float);
/* floatinlet_new(&x->x_obj, &x->x_gain); */
floatinlet_new(&x->x_obj, &x->x_bw);
if (f > 0.) x->x_freq = f;
if (bw > 0.) x->x_bw = bw;
return (x);
}
void notch_setup(void)
{
notch_class = class_new(gensym("notch"), (t_newmethod)notch_new, 0,
sizeof(t_rbjfilter), 0,A_DEFFLOAT,A_DEFFLOAT,0);
class_addbang(notch_class,notch_bang);
class_addfloat(notch_class,notch_float);
}

File diff suppressed because it is too large Load diff

View file

@ -1,312 +1,312 @@
/* (C) Guenter Geiger <geiger@epy.co.at> */
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <sched.h>
void sys_rmpollfn(int fd);
void sys_addpollfn(int fd, void* fn, void *ptr);
/* ------------------------ shell ----------------------------- */
#define INBUFSIZE 1024
static t_class *shell_class;
static void drop_priority(void)
{
#ifdef _POSIX_PRIORITY_SCHEDULING
struct sched_param par;
int p1 ,p2, p3;
par.sched_priority = 0;
sched_setscheduler(0,SCHED_OTHER,&par);
#endif
}
typedef struct _shell
{
t_object x_obj;
int x_echo;
char *sr_inbuf;
int sr_inhead;
int sr_intail;
void* x_binbuf;
int fdpipe[2];
int fdinpipe[2];
int pid;
int x_del;
t_outlet* x_done;
t_clock* x_clock;
} t_shell;
static int shell_pid;
void shell_cleanup(t_shell* x)
{
sys_rmpollfn(x->fdpipe[0]);
if (x->fdpipe[0]>0) close(x->fdpipe[0]);
if (x->fdpipe[1]>0) close(x->fdpipe[1]);
if (x->fdinpipe[0]>0) close(x->fdinpipe[0]);
if (x->fdinpipe[1]>0) close(x->fdinpipe[1]);
x->fdpipe[0] = -1;
x->fdpipe[1] = -1;
x->fdinpipe[0] = -1;
x->fdinpipe[1] = -1;
clock_unset(x->x_clock);
}
void shell_check(t_shell* x)
{
int ret;
int status;
ret = waitpid(x->pid,&status,WNOHANG);
if (ret == x->pid) {
shell_cleanup(x);
if (WIFEXITED(status)) {
outlet_float(x->x_done,WEXITSTATUS(status));
}
else outlet_float(x->x_done,0);
}
else {
if (x->x_del < 100) x->x_del+=2; /* increment poll times */
clock_delay(x->x_clock,x->x_del);
}
}
void shell_bang(t_shell *x)
{
post("bang");
}
/* snippet from pd's code */
static void shell_doit(void *z, t_binbuf *b)
{
t_shell *x = (t_shell *)z;
int msg, natom = binbuf_getnatom(b);
t_atom *at = binbuf_getvec(b);
for (msg = 0; msg < natom;)
{
int emsg;
for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA
&& at[emsg].a_type != A_SEMI; emsg++)
;
if (emsg > msg)
{
int i;
for (i = msg; i < emsg; i++)
if (at[i].a_type == A_DOLLAR || at[i].a_type == A_DOLLSYM)
{
pd_error(x, "netreceive: got dollar sign in message");
goto nodice;
}
if (at[msg].a_type == A_FLOAT)
{
if (emsg > msg + 1)
outlet_list(x->x_obj.ob_outlet, 0, emsg-msg, at + msg);
else outlet_float(x->x_obj.ob_outlet, at[msg].a_w.w_float);
}
else if (at[msg].a_type == A_SYMBOL)
outlet_anything(x->x_obj.ob_outlet, at[msg].a_w.w_symbol,
emsg-msg-1, at + msg + 1);
}
nodice:
msg = emsg + 1;
}
}
void shell_read(t_shell *x, int fd)
{
char buf[INBUFSIZE];
t_binbuf* bbuf = binbuf_new();
int i;
int readto =
(x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1);
int ret;
ret = read(fd, buf,INBUFSIZE-1);
buf[ret] = '\0';
for (i=0;i<ret;i++)
if (buf[i] == '\n') buf[i] = ';';
if (ret < 0)
{
error("shell: pipe read error");
sys_rmpollfn(fd);
x->fdpipe[0] = -1;
close(fd);
return;
}
else if (ret == 0)
{
post("EOF on socket %d\n", fd);
sys_rmpollfn(fd);
x->fdpipe[0] = -1;
close(fd);
return;
}
else
{
int natom;
t_atom *at;
binbuf_text(bbuf, buf, strlen(buf));
natom = binbuf_getnatom(bbuf);
at = binbuf_getvec(bbuf);
shell_doit(x,bbuf);
}
binbuf_free(bbuf);
}
static void shell_send(t_shell *x, t_symbol *s,int ac, t_atom *at)
{
int i;
char tmp[MAXPDSTRING];
int size = 0;
if (x->fdinpipe[0] == -1) return; /* nothing to send to */
for (i=0;i<ac;i++) {
atom_string(at,tmp+size,MAXPDSTRING - size);
at++;
size=strlen(tmp);
tmp[size++] = ' ';
}
tmp[size-1] = '\0';
post("sending %s",tmp);
write(x->fdinpipe[0],tmp,strlen(tmp));
}
static void shell_anything(t_shell *x, t_symbol *s, int ac, t_atom *at)
{
int i;
char* argv[20];
t_symbol* sym;
if (!strcmp(s->s_name,"send")) {
post("send");
shell_send(x,s,ac,at);
return;
}
argv[0] = s->s_name;
if (x->fdpipe[0] != -1) {
post("shell: old process still running");
kill(x->pid,SIGKILL);
shell_cleanup(x);
}
if (pipe(x->fdpipe) < 0) {
error("unable to create pipe");
return;
}
if (pipe(x->fdinpipe) < 0) {
error("unable to create input pipe");
return;
}
sys_addpollfn(x->fdpipe[0],shell_read,x);
if (!(x->pid = fork())) {
int status;
char* cmd = getbytes(1024);
char* tcmd = getbytes(1024);
strcpy(cmd,s->s_name);
#if 0
for (i=1;i<=ac;i++) {
argv[i] = getbytes(255);
atom_string(at,argv[i],255);
/* post("argument %s",argv[i]); */
at++;
}
argv[i] = 0;
#endif
for (i=1;i<=ac;i++) {
atom_string(at,tcmd,255);
strcat(cmd," ");
strcat(cmd,tcmd);
at++;
}
/* reassign stdout */
dup2(x->fdpipe[1],1);
dup2(x->fdinpipe[1],0);
/* drop privileges */
drop_priority();
seteuid(getuid()); /* lose setuid priveliges */
post("executing %s",cmd);
system(cmd);
// execvp(s->s_name,argv);
exit(0);
}
x->x_del = 4;
clock_delay(x->x_clock,x->x_del);
if (x->x_echo)
outlet_anything(x->x_obj.ob_outlet, s, ac, at);
}
void shell_free(t_shell* x)
{
binbuf_free(x->x_binbuf);
}
static void *shell_new(void)
{
t_shell *x = (t_shell *)pd_new(shell_class);
x->x_echo = 0;
x->fdpipe[0] = -1;
x->fdpipe[1] = -1;
x->fdinpipe[0] = -1;
x->fdinpipe[1] = -1;
x->sr_inhead = x->sr_intail = 0;
if (!(x->sr_inbuf = (char*) malloc(INBUFSIZE))) bug("t_shell");;
x->x_binbuf = binbuf_new();
outlet_new(&x->x_obj, &s_list);
x->x_done = outlet_new(&x->x_obj, &s_bang);
x->x_clock = clock_new(x, (t_method) shell_check);
return (x);
}
void shell_setup(void)
{
shell_class = class_new(gensym("shell"), (t_newmethod)shell_new,
(t_method)shell_free,sizeof(t_shell), 0,0);
class_addbang(shell_class,shell_bang);
class_addanything(shell_class, shell_anything);
}
/* (C) Guenter Geiger <geiger@epy.co.at> */
#include "m_pd.h"
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <sched.h>
void sys_rmpollfn(int fd);
void sys_addpollfn(int fd, void* fn, void *ptr);
/* ------------------------ shell ----------------------------- */
#define INBUFSIZE 1024
static t_class *shell_class;
static void drop_priority(void)
{
#ifdef _POSIX_PRIORITY_SCHEDULING
struct sched_param par;
int p1 ,p2, p3;
par.sched_priority = 0;
sched_setscheduler(0,SCHED_OTHER,&par);
#endif
}
typedef struct _shell
{
t_object x_obj;
int x_echo;
char *sr_inbuf;
int sr_inhead;
int sr_intail;
void* x_binbuf;
int fdpipe[2];
int fdinpipe[2];
int pid;
int x_del;
t_outlet* x_done;
t_clock* x_clock;
} t_shell;
static int shell_pid;
void shell_cleanup(t_shell* x)
{
sys_rmpollfn(x->fdpipe[0]);
if (x->fdpipe[0]>0) close(x->fdpipe[0]);
if (x->fdpipe[1]>0) close(x->fdpipe[1]);
if (x->fdinpipe[0]>0) close(x->fdinpipe[0]);
if (x->fdinpipe[1]>0) close(x->fdinpipe[1]);
x->fdpipe[0] = -1;
x->fdpipe[1] = -1;
x->fdinpipe[0] = -1;
x->fdinpipe[1] = -1;
clock_unset(x->x_clock);
}
void shell_check(t_shell* x)
{
int ret;
int status;
ret = waitpid(x->pid,&status,WNOHANG);
if (ret == x->pid) {
shell_cleanup(x);
if (WIFEXITED(status)) {
outlet_float(x->x_done,WEXITSTATUS(status));
}
else outlet_float(x->x_done,0);
}
else {
if (x->x_del < 100) x->x_del+=2; /* increment poll times */
clock_delay(x->x_clock,x->x_del);
}
}
void shell_bang(t_shell *x)
{
post("bang");
}
/* snippet from pd's code */
static void shell_doit(void *z, t_binbuf *b)
{
t_shell *x = (t_shell *)z;
int msg, natom = binbuf_getnatom(b);
t_atom *at = binbuf_getvec(b);
for (msg = 0; msg < natom;)
{
int emsg;
for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA
&& at[emsg].a_type != A_SEMI; emsg++)
;
if (emsg > msg)
{
int i;
for (i = msg; i < emsg; i++)
if (at[i].a_type == A_DOLLAR || at[i].a_type == A_DOLLSYM)
{
pd_error(x, "netreceive: got dollar sign in message");
goto nodice;
}
if (at[msg].a_type == A_FLOAT)
{
if (emsg > msg + 1)
outlet_list(x->x_obj.ob_outlet, 0, emsg-msg, at + msg);
else outlet_float(x->x_obj.ob_outlet, at[msg].a_w.w_float);
}
else if (at[msg].a_type == A_SYMBOL)
outlet_anything(x->x_obj.ob_outlet, at[msg].a_w.w_symbol,
emsg-msg-1, at + msg + 1);
}
nodice:
msg = emsg + 1;
}
}
void shell_read(t_shell *x, int fd)
{
char buf[INBUFSIZE];
t_binbuf* bbuf = binbuf_new();
int i;
int readto =
(x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1);
int ret;
ret = read(fd, buf,INBUFSIZE-1);
buf[ret] = '\0';
for (i=0;i<ret;i++)
if (buf[i] == '\n') buf[i] = ';';
if (ret < 0)
{
error("shell: pipe read error");
sys_rmpollfn(fd);
x->fdpipe[0] = -1;
close(fd);
return;
}
else if (ret == 0)
{
post("EOF on socket %d\n", fd);
sys_rmpollfn(fd);
x->fdpipe[0] = -1;
close(fd);
return;
}
else
{
int natom;
t_atom *at;
binbuf_text(bbuf, buf, strlen(buf));
natom = binbuf_getnatom(bbuf);
at = binbuf_getvec(bbuf);
shell_doit(x,bbuf);
}
binbuf_free(bbuf);
}
static void shell_send(t_shell *x, t_symbol *s,int ac, t_atom *at)
{
int i;
char tmp[MAXPDSTRING];
int size = 0;
if (x->fdinpipe[0] == -1) return; /* nothing to send to */
for (i=0;i<ac;i++) {
atom_string(at,tmp+size,MAXPDSTRING - size);
at++;
size=strlen(tmp);
tmp[size++] = ' ';
}
tmp[size-1] = '\0';
post("sending %s",tmp);
write(x->fdinpipe[0],tmp,strlen(tmp));
}
static void shell_anything(t_shell *x, t_symbol *s, int ac, t_atom *at)
{
int i;
char* argv[20];
t_symbol* sym;
if (!strcmp(s->s_name,"send")) {
post("send");
shell_send(x,s,ac,at);
return;
}
argv[0] = s->s_name;
if (x->fdpipe[0] != -1) {
post("shell: old process still running");
kill(x->pid,SIGKILL);
shell_cleanup(x);
}
if (pipe(x->fdpipe) < 0) {
error("unable to create pipe");
return;
}
if (pipe(x->fdinpipe) < 0) {
error("unable to create input pipe");
return;
}
sys_addpollfn(x->fdpipe[0],shell_read,x);
if (!(x->pid = fork())) {
int status;
char* cmd = getbytes(1024);
char* tcmd = getbytes(1024);
strcpy(cmd,s->s_name);
#if 0
for (i=1;i<=ac;i++) {
argv[i] = getbytes(255);
atom_string(at,argv[i],255);
/* post("argument %s",argv[i]); */
at++;
}
argv[i] = 0;
#endif
for (i=1;i<=ac;i++) {
atom_string(at,tcmd,255);
strcat(cmd," ");
strcat(cmd,tcmd);
at++;
}
/* reassign stdout */
dup2(x->fdpipe[1],1);
dup2(x->fdinpipe[1],0);
/* drop privileges */
drop_priority();
seteuid(getuid()); /* lose setuid priveliges */
post("executing %s",cmd);
system(cmd);
// execvp(s->s_name,argv);
exit(0);
}
x->x_del = 4;
clock_delay(x->x_clock,x->x_del);
if (x->x_echo)
outlet_anything(x->x_obj.ob_outlet, s, ac, at);
}
void shell_free(t_shell* x)
{
binbuf_free(x->x_binbuf);
}
static void *shell_new(void)
{
t_shell *x = (t_shell *)pd_new(shell_class);
x->x_echo = 0;
x->fdpipe[0] = -1;
x->fdpipe[1] = -1;
x->fdinpipe[0] = -1;
x->fdinpipe[1] = -1;
x->sr_inhead = x->sr_intail = 0;
if (!(x->sr_inbuf = (char*) malloc(INBUFSIZE))) bug("t_shell");;
x->x_binbuf = binbuf_new();
outlet_new(&x->x_obj, &s_list);
x->x_done = outlet_new(&x->x_obj, &s_bang);
x->x_clock = clock_new(x, (t_method) shell_check);
return (x);
}
void shell_setup(void)
{
shell_class = class_new(gensym("shell"), (t_newmethod)shell_new,
(t_method)shell_free,sizeof(t_shell), 0,0);
class_addbang(shell_class,shell_bang);
class_addanything(shell_class, shell_anything);
}