mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 05:05:20 -05:00
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:
parent
eabeb928dd
commit
0d4560cb03
113 changed files with 10637 additions and 4420 deletions
|
|
@ -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" */
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue