[PD-cvs] externals/sigpack/source chop~.c, NONE, 1.1 decimate~.c, NONE, 1.1 diode~.c, NONE, 1.1 foldback~.c, NONE, 1.1 foldover~.c, NONE, 1.1 freqdiv~.c, NONE, 1.1 freqshift~.c, NONE, 1.1 harmgen~.c, NONE, 1.1 rectify~.c, NONE, 1.1 round~.c, NONE, 1.1 sIgpAck.c, NONE, 1.1 saturate~.c, NONE, 1.1 sieve~.c, NONE, 1.1 split~.c, NONE, 1.1 ustep~.c, NONE, 1.1 vowel~.c, NONE, 1.1

Hans-Christoph Steiner eighthave at users.sourceforge.net
Mon Jan 9 22:24:30 CET 2006


Update of /cvsroot/pure-data/externals/sigpack/source
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12927/d/source

Added Files:
	chop~.c decimate~.c diode~.c foldback~.c foldover~.c 
	freqdiv~.c freqshift~.c harmgen~.c rectify~.c round~.c 
	sIgpAck.c saturate~.c sieve~.c split~.c ustep~.c vowel~.c 
Log Message:
checked in code from sIgpAck0.03.ZIP; cleaned up comment warnings and changed #ifdef NT to #ifdef _MSC_VER; removed sp. prefix and set up for namespaces

--- NEW FILE: sIgpAck.c ---
#ifndef VERSION
#define VERSION "0.03"
#endif

#include <m_pd.h>


typedef struct _sigpack
{
     t_object x_obj;
} t_sigpack;

static t_class* sigpack_class;

void chop_tilde_setup();
void decimate_tilde_setup();
void diode_tilde_setup();
void foldback_tilde_setup();
void foldover_tilde_setup();
void freqdiv_tilde_setup();
void freqshift_tilde_setup();
void harmgen_tilde_setup();
void rectify_tilde_setup();
void round_tilde_setup();
void saturate_tilde_setup();
void sieve_tilde_setup();
void split_tilde_setup();
void ustep_tilde_setup();
void vowel_tilde_setup();

static void* sigpack_new(t_symbol* s) {
    t_sigpack *x = (t_sigpack *)pd_new(sigpack_class);
    return (x);
}

void sigpack_setup(void) 
{
    sigpack_class = class_new(gensym("sIgpAck"), (t_newmethod)sigpack_new, 0,
    	sizeof(t_sigpack), 0,0);

	 chop_tilde_setup();
	 decimate_tilde_setup();
	 diode_tilde_setup();
	 foldback_tilde_setup();
	 foldover_tilde_setup();
	 freqdiv_tilde_setup();
	 freqshift_tilde_setup();
	 harmgen_tilde_setup();
	 rectify_tilde_setup();
	 round_tilde_setup();
	 saturate_tilde_setup();
	 sieve_tilde_setup();
	 split_tilde_setup();
	 ustep_tilde_setup();
	 vowel_tilde_setup();
     
     post("sIgpAck"" "VERSION " weiss www.weiss-archiv.de");
}

--- NEW FILE: freqshift~.c ---
/* sIgpAck
 * for
 * pure-data
 * www.weiss-archiv.de */

#include "m_pd.h"
#include <math.h>
#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#define M_PI 3.14159265358979323846
#endif

/* ------------------------ sp.freqshift~ ----------------------------- */
/* frequency shifter */
/* code from swh_plugins by steve harris www.plugins.org.uk */

#define SIN_T_SIZE 64
#define D_SIZE 256
#define NZEROS 200

static t_class *freqshift_tilde_class;

typedef struct _freqshift_tilde
{
    t_object x_obj;
	t_float x_shift;//[0 - 5000]
	float *x_delay;
	unsigned int x_dptr;
	t_float x_fs;
	t_float x_last_shift;
	t_float x_phi;
	float *x_sint;
	float x_f;
} t_freqshift_tilde;

static void *freqshift_tilde_new(t_floatarg shift)
{
	unsigned int i;

    t_freqshift_tilde *x = (t_freqshift_tilde *)pd_new(freqshift_tilde_class);
	//x->x_shift = shift;
    outlet_new(&x->x_obj, gensym("signal"));
	outlet_new(&x->x_obj, gensym("signal"));
	floatinlet_new(&x->x_obj, &x->x_shift);
	x->x_fs = sys_getsr();
	x->x_delay = (float *)getbytes(D_SIZE * sizeof(float));
	x->x_sint = (float *)getbytes(SIN_T_SIZE * sizeof(float));
	x->x_dptr = 0;
	x->x_phi = 0.0f;
	x->x_last_shift = 0.0f;
	x->x_f = 0;
	for (i = 0; i < SIN_T_SIZE; i++) {
	x->x_sint[i] = sin(2.0f * M_PI * (float)i / (float)SIN_T_SIZE);
	}
	if (shift) x->x_shift = shift;
	else x->x_shift = 0;
    return (x);
}

/* The non-zero taps of the Hilbert transformer */
static float xcoeffs[] = {
     +0.0008103736f, +0.0008457886f, +0.0009017196f, +0.0009793364f,
     +0.0010798341f, +0.0012044365f, +0.0013544008f, +0.0015310235f,
     +0.0017356466f, +0.0019696659f, +0.0022345404f, +0.0025318040f,
     +0.0028630784f, +0.0032300896f, +0.0036346867f, +0.0040788644f,
     +0.0045647903f, +0.0050948365f, +0.0056716186f, +0.0062980419f,
     +0.0069773575f, +0.0077132300f, +0.0085098208f, +0.0093718901f,
     +0.0103049226f, +0.0113152847f, +0.0124104218f, +0.0135991079f,
     +0.0148917649f, +0.0163008758f, +0.0178415242f, +0.0195321089f,
     +0.0213953037f, +0.0234593652f, +0.0257599469f, +0.0283426636f,
     +0.0312667947f, +0.0346107648f, +0.0384804823f, +0.0430224431f,
     +0.0484451086f, +0.0550553725f, +0.0633242001f, +0.0740128560f,
     +0.0884368322f, +0.1090816773f, +0.1412745301f, +0.1988673273f,
     +0.3326528346f, +0.9997730178f, -0.9997730178f, -0.3326528346f,
     -0.1988673273f, -0.1412745301f, -0.1090816773f, -0.0884368322f,
     -0.0740128560f, -0.0633242001f, -0.0550553725f, -0.0484451086f,
     -0.0430224431f, -0.0384804823f, -0.0346107648f, -0.0312667947f,
     -0.0283426636f, -0.0257599469f, -0.0234593652f, -0.0213953037f,
     -0.0195321089f, -0.0178415242f, -0.0163008758f, -0.0148917649f,
     -0.0135991079f, -0.0124104218f, -0.0113152847f, -0.0103049226f,
     -0.0093718901f, -0.0085098208f, -0.0077132300f, -0.0069773575f,
     -0.0062980419f, -0.0056716186f, -0.0050948365f, -0.0045647903f,
     -0.0040788644f, -0.0036346867f, -0.0032300896f, -0.0028630784f,
     -0.0025318040f, -0.0022345404f, -0.0019696659f, -0.0017356466f,
     -0.0015310235f, -0.0013544008f, -0.0012044365f, -0.0010798341f,
     -0.0009793364f, -0.0009017196f, -0.0008457886f, -0.0008103736f,
};

static float f_clamp(float x, float a, float b)
{
	const float x1 = fabs(x - a);
	const float x2 = fabs(x - b);

	x = x1 + a + b;
	x -= x2;
	x *= 0.5;

	return x;
}

// Round float to int using IEEE int* hack
static int f_round(float f) {
        f += (3<<22);
        return *((int*)&f) - 0x4b400000;
}

// Cubic interpolation function
static float cube_interp(const float fr, const float inm1, const float
                                in, const float inp1, const float inp2)
{
	return in + 0.5f * fr * (inp1 - inm1 +
	 fr * (4.0f * inp1 + 2.0f * inm1 - 5.0f * in - inp2 +
	 fr * (3.0f * (in - inp1) - inm1 + inp2)));
}

static t_int *freqshift_tilde_perform(t_int *w)
{
	t_freqshift_tilde *x = (t_freqshift_tilde *)(w[1]);
    t_float *in = (t_float *)(w[2]);
    t_float *out1 = (t_float *)(w[3]);
	t_float *out2 = (t_float *)(w[4]);
    int n = (int)(w[5]);
	float f, hilb, rm1, rm2, frac_p;
	float shift_i = x->x_last_shift;
	float sample_count = sys_getblksize();
	unsigned int i;
	int int_p;
	const float shift_c = f_clamp(x->x_shift, 0.0f, 10000.0f);
	const float shift_inc = (shift_c - x->x_last_shift) / (float)sample_count;
	const float freq_fix = (float)SIN_T_SIZE / x->x_fs;
    while (n--)
    {
		f = *in++;
		x->x_delay[x->x_dptr] = f;
		/* Perform the Hilbert FIR convolution
		 * (probably FFT would be faster) */
		hilb = 0.0f;
	    for (i = 0; i <= NZEROS/2; i++) {
	        hilb += (xcoeffs[i] * x->x_delay[(x->x_dptr - i*2) & (D_SIZE - 1)]);
		}

	    /* Calcuate the table positions for the sine modulator */
	    int_p = f_round(floor(x->x_phi));

	    /* Calculate ringmod1, the transformed input modulated with a shift Hz
	     * sinewave. This creates a +180 degree sideband at source-shift Hz and
	     * a 0 degree sindeband at source+shift Hz */
	    frac_p = x->x_phi - int_p;
	    rm1 = hilb * cube_interp(frac_p, x->x_sint[int_p], x->x_sint[int_p+1],
	                             x->x_sint[int_p+2], x->x_sint[int_p+3]);

	    /* Calcuate the table positions for the cosine modulator */
	    int_p = (int_p + SIN_T_SIZE / 4) & (SIN_T_SIZE - 1);

	    /* Calculate ringmod2, the delayed input modulated with a shift Hz
	     * cosinewave. This creates a 0 degree sideband at source+shift Hz
	     * and a -180 degree sindeband at source-shift Hz */
	    rm2 = x->x_delay[(x->x_dptr - 100) & (D_SIZE - 1)] * cube_interp(frac_p,
	          x->x_sint[int_p], x->x_sint[int_p+1], x->x_sint[int_p+2], x->x_sint[int_p+3]);

		/* Output the sum and differences of the ringmods. The +/-180 degree
	     * sidebands cancel (more of less) and just leave the shifted
	     * components */
	    *out1++ = (rm2 - rm1) * 0.5f; /*downshifting*/
	    *out2++ = (rm2 + rm1) * 0.5f; /*upshifting*/

		x->x_dptr = (x->x_dptr + 1) & (D_SIZE - 1);
	    x->x_phi += shift_i * freq_fix;
	    while (x->x_phi > SIN_T_SIZE) {
			x->x_phi -= SIN_T_SIZE;
		}
		shift_i += shift_inc;
	}	
    return (w+6);
}

static void freqshift_tilde_dsp(t_freqshift_tilde *x, t_signal **sp)
{
    dsp_add(freqshift_tilde_perform, 5, x, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
}

static void freqshift_tilde_free(t_freqshift_tilde *x)
{
	if(x->x_delay)
		freebytes(x->x_delay, D_SIZE * sizeof(float));
	if(x->x_sint)
		freebytes(x->x_sint, SIN_T_SIZE + 4 * sizeof(float));
}

void freqshift_tilde_setup(void)
{
    freqshift_tilde_class = class_new(gensym("sp.freqshift~"), (t_newmethod)freqshift_tilde_new, (t_method)freqshift_tilde_free,
    	sizeof(t_freqshift_tilde), 0, A_DEFFLOAT, 0);
    CLASS_MAINSIGNALIN(freqshift_tilde_class, t_freqshift_tilde, x_f);
    class_addmethod(freqshift_tilde_class, (t_method)freqshift_tilde_dsp, gensym("dsp"), 0);
}

--- NEW FILE: split~.c ---
/* sIgpAck
 * for
 * pure-data
 * www.weiss-archiv.de */

#include "m_pd.h"
#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif

/* ------------------------ sp.split~ ----------------------------- */
/* signal splitter */

static t_class *split_tilde_class;

typedef struct _split_tilde
{
    t_object x_obj;
    float x_f;
    t_sample x_thres;
} t_split_tilde;

static void *split_tilde_new(t_floatarg thres)
{
    t_split_tilde *x = (t_split_tilde *)pd_new(split_tilde_class);
    x->x_thres = thres;
    outlet_new(&x->x_obj, gensym("signal"));
	outlet_new(&x->x_obj, gensym("signal"));
    floatinlet_new(&x->x_obj, &x->x_thres);
    x->x_f = 0;
	if(thres) x->x_thres = thres;
	else x->x_thres = 0;
    return (x);
}

static t_int *split_tilde_perform(t_int *w)
{
    t_split_tilde *x = (t_split_tilde *)(w[1]);
    t_float *in = (t_float *)(w[2]);
    t_float *out1 = (t_float *)(w[3]);
	t_float *out2 = (t_float *)(w[4]);
    int n = (int)(w[5]);
    while (n--)
    {
    	float f = *in++;
    	if(f < x->x_thres)
		{
			*out1++ = f;
			*out2++ = 0;
		}
		else if(f >= x->x_thres)
		{
			*out1++ = 0;
			*out2++ = f;
		}
    }
    return (w+6);
}

static void split_tilde_dsp(t_split_tilde *x, t_signal **sp)
{
    dsp_add(split_tilde_perform, 5, x, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
}

void split_tilde_setup(void)
{
    split_tilde_class = class_new(gensym("sp.split~"), (t_newmethod)split_tilde_new, 0,
    	sizeof(t_split_tilde), 0, A_DEFFLOAT, 0);
    CLASS_MAINSIGNALIN(split_tilde_class, t_split_tilde, x_f);
    class_addmethod(split_tilde_class, (t_method)split_tilde_dsp, gensym("dsp"), 0);
}

--- NEW FILE: diode~.c ---
/* sIgpAck
 * for
 * pure-data
 * www.weiss-archiv.de */

#include "m_pd.h"
#include <math.h>
#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif

/* ------------------------ sp.diode~ ----------------------------- */
/* Mangles the signal as if it had been passed through a diode rectifier network.*/
/* code from swh_plugins by steve harris www.plugin.org.uk */

static t_class *diode_tilde_class;

typedef struct _diode_tilde
{
    t_object x_obj;
	t_sample x_mode;//0=none,1=halfWave,2=fullWave
	float x_f;
} t_diode_tilde;

static void *diode_tilde_new(t_floatarg mode)
{
    t_diode_tilde *x = (t_diode_tilde *)pd_new(diode_tilde_class);
	x->x_mode = mode;
    outlet_new(&x->x_obj, gensym("signal"));
	floatinlet_new(&x->x_obj, &x->x_mode);
	x->x_f = 0;
	if(mode) x->x_mode = mode;
	else x->x_mode = 0;
    return (x);
}

static t_int *diode_tilde_perform(t_int *w)
{
	t_diode_tilde *x = (t_diode_tilde *)(w[1]);
    t_float *in = (t_float *)(w[2]);
    t_float *out = (t_float *)(w[3]);
    int n = (int)(w[4]);
	float f, value;
    while (n--)
    {
		f = *in++;
		if(x->x_mode >= 0.0f && x->x_mode < 1.0f) {
			value = ((1.0f - x->x_mode) * f + (x->x_mode * (f > 0.0f ? f : 0.0f)));
		}
		else if (x->x_mode >= 1.0f && x->x_mode < 2.0f) {
			float fac = x->x_mode - 1.0f;
			value = ((1.0f - fac) * (f > 0 ? f : 0.0)) + (fac * fabs(f));
		}
		else if (x->x_mode >= 2) {
			float fac = x->x_mode < 3 ? x->x_mode - 2 : 1.0;
			value = (1.0 - fac) * fabs(f);
		}
		else {
			value = f;
		}
		*out++ = value;
    }
    return (w+5);
}

static void diode_tilde_dsp(t_diode_tilde *x, t_signal **sp)
{
    dsp_add(diode_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}

void diode_tilde_setup(void)
{
    diode_tilde_class = class_new(gensym("sp.diode~"), (t_newmethod)diode_tilde_new, 0,
    	sizeof(t_diode_tilde), 0, A_DEFFLOAT, 0);
    CLASS_MAINSIGNALIN(diode_tilde_class, t_diode_tilde, x_f);
    class_addmethod(diode_tilde_class, (t_method)diode_tilde_dsp, gensym("dsp"), 0);
}

--- NEW FILE: saturate~.c ---
/* sIgpAck
 * for
 * pure-data
 * www.weiss-archiv.de */

#include "m_pd.h"
#include <math.h>
#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif

/* ------------------------ sp.saturate~ ----------------------------- */
/* signal soft saturation */
/* code from www.musicdsp.org posted by bram de jong */

static t_class *saturate_tilde_class;

typedef struct _saturate_tilde
{
    t_object x_obj;
	t_sample x_thresh;
	float x_f;
} t_saturate_tilde;

static void *saturate_tilde_new(t_floatarg thresh)
{
    t_saturate_tilde *x = (t_saturate_tilde *)pd_new(saturate_tilde_class);
	x->x_thresh = thresh;
    outlet_new(&x->x_obj, gensym("signal"));
	floatinlet_new(&x->x_obj, &x->x_thresh);
	x->x_f = 0;
	if(thresh) x->x_thresh = thresh;
	else x->x_thresh = 1.;
    return (x);
}

static float sigmoid(float x)
{
	if(fabs(x) < 1)
		return x * (1.5f - 0.5f * x * x);
	else
		return x > 0.f ? 1.f : -1.f;
}

static t_int *saturate_tilde_perform(t_int *w)
{
	t_saturate_tilde *x = (t_saturate_tilde *)(w[1]);
    t_float *in = (t_float *)(w[2]);
    t_float *out = (t_float *)(w[3]);
    int n = (int)(w[4]);
	float f, value;
	float t = x->x_thresh;
    while (n--)
    {
		f = *in++;
		if(fabs(f) < t)
			value = f;
		else
		{
			if(f > 0.f)
				value = t + (1.f - t) * sigmoid((f - t)/((1 - t) * 1.5f));
			else
				value = -(t + (1.f - t) * sigmoid((-f - t)/((1 - t) * 1.5f)));
		}
		*out++ = value;
    }
    return (w+5);
}

static void saturate_tilde_dsp(t_saturate_tilde *x, t_signal **sp)
{
    dsp_add(saturate_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}

void saturate_tilde_setup(void)
{
    saturate_tilde_class = class_new(gensym("sp.saturate~"), (t_newmethod)saturate_tilde_new, 0,
    	sizeof(t_saturate_tilde), 0, A_DEFFLOAT, 0);
    CLASS_MAINSIGNALIN(saturate_tilde_class, t_saturate_tilde, x_f);
    class_addmethod(saturate_tilde_class, (t_method)saturate_tilde_dsp, gensym("dsp"), 0);
	class_addmethod(saturate_tilde_class, (t_method)saturate_tilde_dsp, gensym("sigmoid"), A_FLOAT, 0);
}

--- NEW FILE: freqdiv~.c ---
/* sIgpAck
 * for
 * pure-data
 * www.weiss-archiv.de */

#include "m_pd.h"
#include <math.h>
#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif

/* ------------------------ sp.freqdiv~ ----------------------------- */
/* frequency divider */
/* code from swh_plugins by steve harris www.plugins.org.uk */

static t_class *freqdiv_tilde_class;

typedef struct _freqdiv_tilde
{
    t_object x_obj;
	t_sample x_denominate;
	t_sample x_amp;
	float x_count;
	t_sample x_lamp;
	t_sample x_last;
	t_sample x_out;
	int x_zeroxs;
	float x_f;
} t_freqdiv_tilde;

static void *freqdiv_tilde_new(t_floatarg denominate)
{
    t_freqdiv_tilde *x = (t_freqdiv_tilde *)pd_new(freqdiv_tilde_class);
	x->x_denominate = denominate;
    outlet_new(&x->x_obj, gensym("signal"));
	floatinlet_new(&x->x_obj, &x->x_denominate);
	x->x_f = 0;
	x->x_amp = 0;
	x->x_count = 0;
	x->x_lamp = 0;
	x->x_last = 0;
	x->x_out = 0;
	x->x_zeroxs = 0;
	if (denominate) x->x_denominate = denominate;
	else x->x_denominate = 1;
    return (x);
}

static t_int *freqdiv_tilde_perform(t_int *w)
{
	t_freqdiv_tilde *x = (t_freqdiv_tilde *)(w[1]);
    t_float *in = (t_float *)(w[2]);
    t_float *out = (t_float *)(w[3]);
    int n = (int)(w[4]);
	float f;
	int den = (int)x->x_denominate;
    while (n--)
    {
		f = *in++;
		x->x_count += 1.0f;
		if ((f > 0.0f && x->x_last <= 0.0f) || (f < 0.0f && x->x_last >= 0.0))
		{
			x->x_zeroxs++;
			if (den == 1)
			{
				x->x_out = x->x_out > 0.0f ? -1.0f : 1.0f;
				x->x_lamp = x->x_amp / x->x_count;
				x->x_zeroxs = 0;
				x->x_count = 0;
				x->x_amp = 0;
			}
		}
		x->x_amp += fabs(f);
		if (den > 1 && (x->x_zeroxs % den) == den-1)
		{
			x->x_out = x->x_out > 0.0f ? -1.0f : 1.0f;
			x->x_lamp = x->x_amp / x->x_count;
			x->x_zeroxs = 0;
			x->x_count = 0;
			x->x_amp = 0;
		}
		x->x_last = f;
		*out++ = x->x_out * x->x_lamp;
    }
    return (w+5);
}

static void freqdiv_tilde_dsp(t_freqdiv_tilde *x, t_signal **sp)
{
    dsp_add(freqdiv_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}

void freqdiv_tilde_setup(void)
{
    freqdiv_tilde_class = class_new(gensym("sp.freqdiv~"), (t_newmethod)freqdiv_tilde_new, 0,
    	sizeof(t_freqdiv_tilde), 0, A_DEFFLOAT, 0);
    CLASS_MAINSIGNALIN(freqdiv_tilde_class, t_freqdiv_tilde, x_f);
    class_addmethod(freqdiv_tilde_class, (t_method)freqdiv_tilde_dsp, gensym("dsp"), 0);
}

--- NEW FILE: sieve~.c ---
/* sIgpAck
 * for
 * pure-data
 * www.weiss-archiv.de */

#include "m_pd.h"
#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif

/* ------------------------ sp.sieve~ ----------------------------- */
/* sift samples */

static t_class *sieve_tilde_class;

typedef struct _sieve_tilde
{
    t_object x_obj;
	t_sample x_mode;
	t_sample x_sample;
	t_sample x_last;
	float x_f;
} t_sieve_tilde;

static void *sieve_tilde_new(t_floatarg mode, t_floatarg sample)
{
    t_sieve_tilde *x = (t_sieve_tilde *)pd_new(sieve_tilde_class);
	x->x_mode = mode;
	x->x_sample = sample;
    outlet_new(&x->x_obj, gensym("signal"));
	floatinlet_new(&x->x_obj, &x->x_mode);
	floatinlet_new(&x->x_obj, &x->x_sample);
	x->x_last = 0;
	x->x_f = 0;
	x->x_mode = 0;
	
	if(mode) x->x_mode = mode;
	if(x->x_mode > 1) x->x_mode = 1;
	if(x->x_mode < 0) x->x_mode = 0;
    return (x);
}

static float round(float in)
{
	float y, round;
	int temp;
	{
		round = in * 10;
		temp = round;
		y = temp * 0.1;
	}
	return y;
}

static t_int *sieve_tilde_perform(t_int *w)
{
	t_sieve_tilde *x = (t_sieve_tilde *)(w[1]);
    t_float *in = (t_float *)(w[2]);
    t_float *out = (t_float *)(w[3]);
    int n = (int)(w[4]);
	float f;
	int mode = x->x_mode;
    while (n--)
    {
		f = *in++;
		switch(mode){
		case(0):
			if (round(f) != round(x->x_sample))
			{
				*out++ = f;
				x->x_last = f;
			}
			else
			{
				*out++ = x->x_last;
			}
			break;
		case(1):
			if (round(f) == round(x->x_sample))
			{
				*out++ = f;
				x->x_last = f;
			}
			else
			{
				*out++ = x->x_last;
			}
		}
    }
    return (w+5);
}

static void sieve_tilde_dsp(t_sieve_tilde *x, t_signal **sp)
{
    dsp_add(sieve_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}

void sieve_tilde_setup(void)
{
    sieve_tilde_class = class_new(gensym("sp.sieve~"), (t_newmethod)sieve_tilde_new, 0,
    	sizeof(t_sieve_tilde), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
    CLASS_MAINSIGNALIN(sieve_tilde_class, t_sieve_tilde, x_f);
    class_addmethod(sieve_tilde_class, (t_method)sieve_tilde_dsp, gensym("dsp"), 0);
}

--- NEW FILE: ustep~.c ---
/* sIgpAck
 * for
 * pure-data
 * www.weiss-archiv.de */

#include "m_pd.h"
#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif

/* ------------------------ sp.ustep~ ----------------------------- */
/* signal unity step function */

static t_class *ustep_tilde_class;

typedef struct _ustep_tilde
{
    t_object x_obj;
	t_sample x_mode;
	t_sample x_thres;
	float x_f;
} t_ustep_tilde;

static void *ustep_tilde_new(t_floatarg mode, t_floatarg thres)
{
    t_ustep_tilde *x = (t_ustep_tilde *)pd_new(ustep_tilde_class);
	x->x_mode = mode;
	x->x_thres = thres;
    outlet_new(&x->x_obj, gensym("signal"));
	floatinlet_new(&x->x_obj, &x->x_mode);
	floatinlet_new(&x->x_obj, &x->x_thres);
	x->x_f = 0;
	if(mode) x->x_mode = mode;
	else x->x_mode = 0;
	if(x->x_mode > 1) x->x_mode = 1;
	if(x->x_mode < 0) x->x_mode = 0;
	if(thres) x->x_thres = thres;
	else x->x_thres = 0.5;
    return (x);
}

static t_int *ustep_tilde_perform(t_int *w)
{
	t_ustep_tilde *x = (t_ustep_tilde *)(w[1]);
    t_float *in = (t_float *)(w[2]);
    t_float *out = (t_float *)(w[3]);
    int n = (int)(w[4]);
	float f, value;
	int mode = x->x_mode;
    while (n--)
    {
		f = *in++;
		switch(mode){
		case(0):
			if (f >= x->x_thres)
				value = 1;
			else
				value = 0;
			break;
		case(1):
			if (f >= x->x_thres)
				value = 1;
			else
				value = f;
		}
		*out++ = value;
    }
    return (w+5);
}

static void ustep_tilde_dsp(t_ustep_tilde *x, t_signal **sp)
{
    dsp_add(ustep_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}

void ustep_tilde_setup(void)
{
    ustep_tilde_class = class_new(gensym("sp.ustep~"), (t_newmethod)ustep_tilde_new, 0,
    	sizeof(t_ustep_tilde), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
    CLASS_MAINSIGNALIN(ustep_tilde_class, t_ustep_tilde, x_f);
    class_addmethod(ustep_tilde_class, (t_method)ustep_tilde_dsp, gensym("dsp"), 0);
}

--- NEW FILE: round~.c ---
/* sIgpAck
 * for
 * pure-data
 * www.weiss-archiv.de */

#include "m_pd.h"
#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif

/* ------------------------ sp.round~ ----------------------------- */
/* simple rounder */

static t_class *round_tilde_class;

typedef struct _round_tilde
{
    t_object x_obj;
	t_sample x_coarse;
	float x_f;
} t_round_tilde;

static void *round_tilde_new(t_floatarg coarse)
{
    t_round_tilde *x = (t_round_tilde *)pd_new(round_tilde_class);
	x->x_coarse = coarse;
    outlet_new(&x->x_obj, gensym("signal"));
	floatinlet_new(&x->x_obj, &x->x_coarse);
	x->x_f = 0;
	if(coarse) x->x_coarse = coarse;
	else x->x_coarse = 1;
    return (x);
}

static t_int *round_tilde_perform(t_int *w)
{
	t_round_tilde *x = (t_round_tilde *)(w[1]);
    t_float *in = (t_float *)(w[2]);
    t_float *out = (t_float *)(w[3]);
    int n = (int)(w[4]);
	float f, mult, value;
    while (n--)
    {
		f = *in++;
		mult = f * x->x_coarse;
		value = (int)mult / x->x_coarse;
		*out++ = value;
    }
    return (w+5);
}

static void round_tilde_dsp(t_round_tilde *x, t_signal **sp)
{
    dsp_add(round_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}

void round_tilde_setup(void)
{
    round_tilde_class = class_new(gensym("sp.round~"), (t_newmethod)round_tilde_new, 0,
    	sizeof(t_round_tilde), 0, A_DEFFLOAT, 0);
    CLASS_MAINSIGNALIN(round_tilde_class, t_round_tilde, x_f);
    class_addmethod(round_tilde_class, (t_method)round_tilde_dsp, gensym("dsp"), 0);
}

--- NEW FILE: decimate~.c ---
/* sIgpAck
 * for
 * pure-data
 * www.weiss-archiv.de */

#include "m_pd.h"
#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif

// ------------------------ sp.decimate~ ----------------------------- 
// signal decimation
// code from musicdsp.org posted by tobybear 

static t_class *decimate_tilde_class;

typedef struct _decimate_tilde
{
    t_object x_obj;
	t_sample x_rate;
	t_sample x_bits;
	float x_f;
} t_decimate_tilde;

static void *decimate_tilde_new(t_floatarg rate, t_floatarg bits)
{
    t_decimate_tilde *x = (t_decimate_tilde *)pd_new(decimate_tilde_class);
	x->x_rate = rate;
	x->x_bits = bits;
    outlet_new(&x->x_obj, gensym("signal"));
	floatinlet_new(&x->x_obj, &x->x_rate);
	floatinlet_new(&x->x_obj, &x->x_bits);
	x->x_f = 0;
	if (rate) x->x_rate = rate;
	else x->x_rate = 0.5;
	if (bits) x->x_bits = bits;
	else x->x_bits = 16;
    return (x);
}

static t_int *decimate_tilde_perform(t_int *w)
{
	t_decimate_tilde *x = (t_decimate_tilde *)(w[1]);
    t_float *in = (t_float *)(w[2]);
    t_float *out = (t_float *)(w[3]);
    int n = (int)(w[4]);
	float f;
	long int m=1<<(int)(x->x_bits-1);
	float y=0, cnt=0;
    while (n--)
    {
		f = *in++;
		cnt+=x->x_rate;
		if (cnt>=1)
		{
			cnt-=1;
			y=(long int)(f*m)/(float)m;
		}
		*out++ = y;
    }
    return (w+5);
}

static void decimate_tilde_dsp(t_decimate_tilde *x, t_signal **sp)
{
    dsp_add(decimate_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}

void decimate_tilde_setup(void)
{
    decimate_tilde_class = class_new(gensym("sp.decimate~"), (t_newmethod)decimate_tilde_new, 0,
    	sizeof(t_decimate_tilde), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
    CLASS_MAINSIGNALIN(decimate_tilde_class, t_decimate_tilde, x_f);
    class_addmethod(decimate_tilde_class, (t_method)decimate_tilde_dsp, gensym("dsp"), 0);
}

--- NEW FILE: foldover~.c ---
/* sIgpAck
 * for
 * pure-data
 * www.weiss-archiv.de */

#include "m_pd.h"
#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif

/* ------------------------ sp.foldover~ ----------------------------- */
/* foldover distortion */
/* code from swh_plugins by steve harris www.plugin.org.uk */

static t_class *foldover_tilde_class;

typedef struct _foldover_tilde
{
    t_object x_obj;
	t_sample x_drive_p;
	t_sample x_push;
	float x_f;
} t_foldover_tilde;

static void *foldover_tilde_new(t_floatarg drive_p, t_floatarg push)
{
    t_foldover_tilde *x = (t_foldover_tilde *)pd_new(foldover_tilde_class);
	x->x_drive_p = drive_p;
	x->x_push = push;
    outlet_new(&x->x_obj, gensym("signal"));
	floatinlet_new(&x->x_obj, &x->x_drive_p);
	floatinlet_new(&x->x_obj, &x->x_push);
	x->x_f = 0;
	if(drive_p) x->x_drive_p = drive_p;
	else x->x_drive_p = 0;
	if(push) x->x_push = push;
	else x->x_push = 0;
    return (x);
}

static t_int *foldover_tilde_perform(t_int *w)
{
	t_foldover_tilde *x = (t_foldover_tilde *)(w[1]);
    t_float *in = (t_float *)(w[2]);
    t_float *out = (t_float *)(w[3]);
    int n = (int)(w[4]);
	float f, value, y;
	float drive = x->x_drive_p + 1.0f;
    while (n--)
    {
		f = *in++;
		y = f * drive + x->x_push;
		value = 1.5f * y - 0.5f * y * y *y;
		*out++ = value;
    }
    return (w+5);
}

static void foldover_tilde_dsp(t_foldover_tilde *x, t_signal **sp)
{
    dsp_add(foldover_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}

void foldover_tilde_setup(void)
{
    foldover_tilde_class = class_new(gensym("sp.foldover~"), (t_newmethod)foldover_tilde_new, 0,
    	sizeof(t_foldover_tilde), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
    CLASS_MAINSIGNALIN(foldover_tilde_class, t_foldover_tilde, x_f);
    class_addmethod(foldover_tilde_class, (t_method)foldover_tilde_dsp, gensym("dsp"), 0);
}

--- NEW FILE: rectify~.c ---
/* sIgpAck
 * for
 * pure-data
 * www.weiss-archiv.de */

#include "m_pd.h"
#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif

/* ------------------------ sp.rectify~ ----------------------------- */
/* flips negative signal values to positive */

static t_class *rectify_tilde_class;

typedef struct _rectify_tilde
{
    t_object x_obj;
	float x_f;
} t_rectify_tilde;

static void *rectify_tilde_new(void)
{
    t_rectify_tilde *x = (t_rectify_tilde *)pd_new(rectify_tilde_class);
    outlet_new(&x->x_obj, gensym("signal"));
	x->x_f = 0;
    return (x);
}

static t_int *rectify_tilde_perform(t_int *w)
{
	t_rectify_tilde *x = (t_rectify_tilde *)(w[1]);
    t_float *in = (t_float *)(w[2]);
    t_float *out = (t_float *)(w[3]);
    int n = (int)(w[4]);
	float f, value;
    while (n--)
    {
		f = *in++;
		if (f < 0)
			value = f * -1;
		else
			value = f;
		*out++ = value;
    }
    return (w+5);
}

static void rectify_tilde_dsp(t_rectify_tilde *x, t_signal **sp)
{
    dsp_add(rectify_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}

void rectify_tilde_setup(void)
{
    rectify_tilde_class = class_new(gensym("sp.rectify~"), (t_newmethod)rectify_tilde_new, 0,
    	sizeof(t_rectify_tilde), 0, A_DEFFLOAT, 0);
    CLASS_MAINSIGNALIN(rectify_tilde_class, t_rectify_tilde, x_f);
    class_addmethod(rectify_tilde_class, (t_method)rectify_tilde_dsp, gensym("dsp"), 0);
}

--- NEW FILE: vowel~.c ---
/* sIgpAck
 * for
 * pure-data
 * www.weiss-archiv.de */

#include "m_pd.h"
#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif

/* ------------------------ sp.vowel~ ----------------------------- */
/* simple formant filter */
/* code from musicdsp.org posted by alex at smartelectronix.com */

static t_class *vowel_tilde_class;

typedef struct _vowel_tilde
{
    t_object x_obj;
	t_sample x_vowelnum;
	float x_f;
} t_vowel_tilde;

static void *vowel_tilde_new(t_floatarg vowelnum)
{
    t_vowel_tilde *x = (t_vowel_tilde *)pd_new(vowel_tilde_class);
	x->x_vowelnum = vowelnum;
    outlet_new(&x->x_obj, gensym("signal"));
	floatinlet_new(&x->x_obj, &x->x_vowelnum);
	x->x_f = 0;
	if(vowelnum) x->x_vowelnum = vowelnum;
	else x->x_vowelnum = 0;
    return (x);
}

const double coeff[5][11]= {
	{ 8.11044e-06,
      8.943665402, -36.83889529, 92.01697887, -154.337906, 181.6233289,
	  -151.8651235, 89.09614114, -35.10298511, 8.388101016, -0.923313471 ///A
	},
	{ 4.36215e-06,
      8.90438318, -36.55179099, 91.05750846, -152.422234, 179.1170248, ///E
	  -149.6496211,87.78352223, -34.60687431, 8.282228154, -0.914150747
	},
	{ 3.33819e-06,
	  8.893102966, -36.49532826, 90.96543286, -152.4545478, 179.4835618,
	  -150.315433, 88.43409371, -34.98612086, 8.407803364, -0.932568035 ///I
	},
	{ 1.13572e-06,
	  8.994734087, -37.2084849, 93.22900521, -156.6929844, 184.596544, ///O
	  -154.3755513, 90.49663749, -35.58964535, 8.478996281, -0.929252233
	},
	{ 4.09431e-07,
	  8.997322763, -37.20218544, 93.11385476, -156.2530937, 183.7080141, ///U
	  -153.2631681, 89.59539726, -35.12454591, 8.338655623, -0.910251753
	}
};

static double memory[10] = {0,0,0,0,0,0,0,0,0,0};

float formant_filter (float in, int vowelnum)
{
	float res;
	res= (float) (coeff[vowelnum][0]*in +
		coeff[vowelnum][1]*memory[0] +
		coeff[vowelnum][2]*memory[1] +
		coeff[vowelnum][3]*memory[2] +
		coeff[vowelnum][4]*memory[3] +
		coeff[vowelnum][5]*memory[4] +
		coeff[vowelnum][6]*memory[5] +
		coeff[vowelnum][7]*memory[6] +
		coeff[vowelnum][8]*memory[7] +
		coeff[vowelnum][9]*memory[8] +
		coeff[vowelnum][10]*memory[9]);

	memory[9]=memory[8];
	memory[8]=memory[7];
	memory[7]=memory[6];
	memory[6]=memory[5];
	memory[5]=memory[4];
	memory[4]=memory[3];
	memory[3]=memory[2];
	memory[2]=memory[1];
	memory[1]=memory[0];
	memory[0]=(double)res;
	return res;
}

static t_int *vowel_tilde_perform(t_int *w)
{
	t_vowel_tilde *x = (t_vowel_tilde *)(w[1]);
    t_float *in = (t_float *)(w[2]);
    t_float *out = (t_float *)(w[3]);
    int n = (int)(w[4]);
	float f, value;
    while (n--)
    {
		f = *in++;
		value = formant_filter(f, (int)x->x_vowelnum);
		*out++ = value;
    }
    return (w+5);
}

static void vowel_tilde_dsp(t_vowel_tilde *x, t_signal **sp)
{
    dsp_add(vowel_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}

void vowel_tilde_setup(void)
{
    vowel_tilde_class = class_new(gensym("sp.vowel~"), (t_newmethod)vowel_tilde_new, 0,
    	sizeof(t_vowel_tilde), 0, A_DEFFLOAT, 0);
    CLASS_MAINSIGNALIN(vowel_tilde_class, t_vowel_tilde, x_f);
    class_addmethod(vowel_tilde_class, (t_method)vowel_tilde_dsp, gensym("dsp"), 0);
	class_addmethod(vowel_tilde_class, (t_method)formant_filter, gensym("formant_filter"), A_GIMME, A_NULL); 
}

--- NEW FILE: chop~.c ---
/* sIgpAck
 * for
 * pure-data
 * www.weiss-archiv.de */

#include "m_pd.h"
#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif

// ------------------------ sp.chop~ -----------------------------
// signal chopping modulator

static t_class *chop_tilde_class;

typedef struct _chop_tilde
{
    t_object x_obj;
	t_sample x_factor;
	float x_f;
} t_chop_tilde;

static void *chop_tilde_new(t_floatarg factor)
{
    t_chop_tilde *x = (t_chop_tilde *)pd_new(chop_tilde_class);
	x->x_factor = factor;
    outlet_new(&x->x_obj, gensym("signal"));
	inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
	floatinlet_new(&x->x_obj, &x->x_factor);
	x->x_f = 0;
	if(factor) x->x_factor = factor;
	else x->x_factor = 0;
    return (x);
}

static t_int *chop_tilde_perform(t_int *w)
{
	t_chop_tilde *x = (t_chop_tilde *)(w[1]);
    t_float *in1 = (t_float *)(w[2]);
	t_float *in2 = (t_float *)(w[3]);
    t_float *out = (t_float *)(w[4]);
    int n = (int)(w[5]);
	float f, m, value;
    while (n--)
    {
		f = *in1++;
		m = *in2++;
		if(m > 0.) value = f * x->x_factor;
		else value = f;
		*out++ = value;
    }
    return (w+6);
}

static void chop_tilde_dsp(t_chop_tilde *x, t_signal **sp)
{
    dsp_add(chop_tilde_perform, 5, x, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
}

void chop_tilde_setup(void)
{
    chop_tilde_class = class_new(gensym("sp.chop~"), (t_newmethod)chop_tilde_new, 0,
    	sizeof(t_chop_tilde), 0, A_DEFFLOAT, 0);
    CLASS_MAINSIGNALIN(chop_tilde_class, t_chop_tilde, x_f);
    class_addmethod(chop_tilde_class, (t_method)chop_tilde_dsp, gensym("dsp"), 0);
}

--- NEW FILE: foldback~.c ---
/* sIgpAck
 * for
 * pure-data
 * www.weiss-archiv.de */

#include "m_pd.h"
#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif

/* ------------------------ sp.foldback~ ----------------------------- */
/* signal mirror */

static t_class *foldback_tilde_class;

typedef struct _foldback_tilde
{
    t_object x_obj;
	t_sample x_low;
	t_sample x_high;
	float x_f;
} t_foldback_tilde;

static void *foldback_tilde_new(t_floatarg low, t_floatarg high)
{
    t_foldback_tilde *x = (t_foldback_tilde *)pd_new(foldback_tilde_class);
	x->x_low = low;
	x->x_high = high;
    outlet_new(&x->x_obj, gensym("signal"));
	floatinlet_new(&x->x_obj, &x->x_low);
	floatinlet_new(&x->x_obj, &x->x_high);
	x->x_f = 0;
	if(low) x->x_low = low;
	else x->x_low = -1;
	if(high) x->x_high = high;
	else x->x_high = 1;
    return (x);
}

static t_int *foldback_tilde_perform(t_int *w)
{
	t_foldback_tilde *x = (t_foldback_tilde *)(w[1]);
    t_float *in = (t_float *)(w[2]);
    t_float *out = (t_float *)(w[3]);
    int n = (int)(w[4]);
	float f, value;
    while (n--)
    {
		f = *in++;
		if(f < x->x_low) value = (f - ((f - x->x_low) * 2));
		else if(f > x->x_high) value = (f - ((f - x->x_high) * 2));
		else value = f;
		*out++ = value;
    }
    return (w+5);
}

static void foldback_tilde_dsp(t_foldback_tilde *x, t_signal **sp)
{
    dsp_add(foldback_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}

void foldback_tilde_setup(void)
{
    foldback_tilde_class = class_new(gensym("sp.foldback~"), (t_newmethod)foldback_tilde_new, 0,
    	sizeof(t_foldback_tilde), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
    CLASS_MAINSIGNALIN(foldback_tilde_class, t_foldback_tilde, x_f);
    class_addmethod(foldback_tilde_class, (t_method)foldback_tilde_dsp, gensym("dsp"), 0);
}

--- NEW FILE: harmgen~.c ---
/* sIgpAck
 * for
 * pure-data
 * www.weiss-archiv.de */

#include "m_pd.h"
#include <math.h>
#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#define HARMONICS 11

// ------------------------ sp.harmgen~ -----------------------------
// harmonic generator
// code from swh_plugins by steve harris www.plugins.org.uk

static t_class *harmgen_tilde_class;

typedef struct _harmgen_tilde
{
    t_object x_obj;
	t_sample x_mag1;
	t_sample x_mag2;
	t_sample x_mag3;
	t_sample x_mag4;
	t_sample x_mag5;
	t_sample x_mag6;
	t_sample x_mag7;
	t_sample x_mag8;
	t_sample x_mag9;
	t_sample x_mag10;
	float x_itm;
	float x_otm;
	float x_f;
} t_harmgen_tilde;

static void *harmgen_tilde_new(t_floatarg mag1, t_floatarg mag2, t_floatarg mag3, t_floatarg mag4, t_floatarg mag5, t_floatarg mag6, t_floatarg mag7, t_floatarg mag8, t_floatarg mag9, t_floatarg mag10)
{
    t_harmgen_tilde *x = (t_harmgen_tilde *)pd_new(harmgen_tilde_class);
    outlet_new(&x->x_obj, gensym("signal"));
	floatinlet_new(&x->x_obj, &x->x_mag1);
	floatinlet_new(&x->x_obj, &x->x_mag2);
	floatinlet_new(&x->x_obj, &x->x_mag3);
	floatinlet_new(&x->x_obj, &x->x_mag4);
	floatinlet_new(&x->x_obj, &x->x_mag5);
	floatinlet_new(&x->x_obj, &x->x_mag6);
	floatinlet_new(&x->x_obj, &x->x_mag7);
	floatinlet_new(&x->x_obj, &x->x_mag8);
	floatinlet_new(&x->x_obj, &x->x_mag9);
	floatinlet_new(&x->x_obj, &x->x_mag10);
	x->x_f = 0;
	if(mag1) x->x_mag1 = mag1;
	else x->x_mag1 = 1;
	if(mag2) x->x_mag2 = mag2;
	else x->x_mag2 = 1;
	if(mag3) x->x_mag3 = mag3;
	else x->x_mag3 = 1;
	if(mag4) x->x_mag4 = mag4;
	else x->x_mag4 = 1;
	if(mag5) x->x_mag5 = mag5;
	else x->x_mag5 = 1;
	if(mag6) x->x_mag6 = mag6;
	else x->x_mag6 = 1;
	if(mag7) x->x_mag7 = mag7;
	else x->x_mag7 = 1;
	if(mag8) x->x_mag8 = mag8;
	else x->x_mag8 = 1;
	if(mag9) x->x_mag9 = mag9;
	else x->x_mag9 = 1;
	if(mag10) x->x_mag10 = mag10;
	else x->x_mag10 = 1;
    return (x);
}

/* Calculate Chebychev coefficents from partial magnitudes, adapted from
 * example in Num. Rec. */
void chebpc(float c[], float d[])
{
    int k, j;
    float sv, dd[HARMONICS];

    for (j = 0; j < HARMONICS; j++) {
        d[j] = dd[j] = 0.0;
    }

    d[0] = c[HARMONICS - 1];

    for (j = HARMONICS - 2; j >= 1; j--) {
        for (k = HARMONICS - j; k >= 1; k--) {
            sv = d[k];
            d[k] = 2.0 * d[k - 1] - dd[k];
            dd[k] = sv;
        }
        sv = d[0];
        d[0] = -dd[0] + c[j];
        dd[0] = sv;
    }

    for (j = HARMONICS - 1; j >= 1; j--) {
        d[j] = d[j - 1] - dd[j];
    }
    d[0] = -dd[0] + 0.5 * c[0];
}

static t_int *harmgen_tilde_perform(t_int *w)
{
	t_harmgen_tilde *x = (t_harmgen_tilde *)(w[1]);
    t_float *in1 = (t_float *)(w[2]);
    t_float *out = (t_float *)(w[3]);
    int n = (int)(w[4]);
	unsigned long i;
	float mag_fix, y, f, value;
	float mag[HARMONICS] = {0.0f, x->x_mag1, x->x_mag2, x->x_mag3, x->x_mag4, x->x_mag5, x->x_mag6,
		x->x_mag7, x->x_mag8, x->x_mag9, x->x_mag10};
	float p[HARMONICS];

	// Normalise magnitudes
	mag_fix = (fabs(x->x_mag1) + fabs(x->x_mag2) + fabs(x->x_mag3) + fabs(x->x_mag4) +
	           fabs(x->x_mag5) + fabs(x->x_mag6) + fabs(x->x_mag7) + fabs(x->x_mag8) +
	           fabs(x->x_mag9) + fabs(x->x_mag10));
	if (mag_fix < 1.0f) {
	  mag_fix = 1.0f;
	} else {
	  mag_fix = 1.0f / mag_fix;
	}
	for (i=0; i<HARMONICS; i++) {
	  mag[i] *= mag_fix;
	}

	// Calculate polynomial coefficients, using Chebychev aproximation
	chebpc(mag, p);
    while (n--)
    {
		f = *in1++;

		// Calculate the polynomial using Horner's Rule
		y = p[0] + (p[1] + (p[2] + (p[3] + (p[4] + (p[5] + (p[6] + (p[7] +
			(p[8] + (p[9] + p[10] * f) * f) * f) * f) * f) * f) * f) * f) *
			f) * f;

		// DC offset remove (odd harmonics cause DC offset)
		x->x_otm = 0.999f * x->x_otm + y - x->x_itm;
		x->x_itm = y;
		*out++ = x->x_otm;
    }
    return (w+5);
}

static void harmgen_tilde_dsp(t_harmgen_tilde *x, t_signal **sp)
{
    dsp_add(harmgen_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}

void harmgen_tilde_setup(void)
{
    harmgen_tilde_class = class_new(gensym("sp.harmgen~"), (t_newmethod)harmgen_tilde_new, 0,
    	sizeof(t_harmgen_tilde), 0, A_GIMME, 0);
    CLASS_MAINSIGNALIN(harmgen_tilde_class, t_harmgen_tilde, x_f);
    class_addmethod(harmgen_tilde_class, (t_method)harmgen_tilde_dsp, gensym("dsp"), 0);
}





More information about the Pd-cvs mailing list