Skip to content

Commit

Permalink
added a description for maxobjects and a helper header file
Browse files Browse the repository at this point in the history
  • Loading branch information
sbl committed Jun 19, 2010
1 parent 90e2359 commit b39922d
Show file tree
Hide file tree
Showing 4 changed files with 309 additions and 38 deletions.
18 changes: 18 additions & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
sc.whitenoise~ equal power noise Generates noise whose spectrum has equal power at all frequencies

sc.brownnoise~ browninan motion Generates noise whose spectrum falls off in power by 6 dB per octave
sc.clipnoise~ Clip Noise. Generates noise whose spectrum falls off in power by 3 dB per octave.
sc.crackle~ Chaotic noise function. A noise generator based on a chaotic function.
sc.dust~ Random Impulses. Generates random impulses from 0 to +1.
sc.dust2~ Random Impulses. Generates random impulses from -1 to +1.
sc.gendy1~ An implementation of the dynamic stochastic synthesis generator conceived by Iannis Xenakis and described in Formalized Music
sc.gendy2~ An implementation of the dynamic stochastic synthesis generator conceived by Iannis Xenakis and described in Formalized Music
sc.gendy3~ An implementation of the dynamic stochastic synthesis generator conceived by Iannis Xenakis and described in Formalized Music
sc.graynoise~ Generates noise which results from flipping random bits in a word.
sc.lfclipnoise~ Clipped Noise. Randomly generates the values -1 or +1 at a rate given by the nearest integer division of the sample rate by the freq argument
sc.lfnoise0~ Generates random values at a rate
sc.lfnoise1~ Generates linearly interpolated random values at a rate
sc.lfnoise2~ Generates quadratically interpolated random values at a rate
sc.logistic~ chaotic noise function. A noise generator based on the logistic map y = chaosParam * y * (1.0 - y)
sc.mantissamask~ Reduce Precision. Masks off bits in the mantissa of the floating point sample value
sc.pinknoise~ 1/f noise Generates noise whose spectrum falls off in power by 3 dB per octave
98 changes: 98 additions & 0 deletions lib/scmax.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* scmax.h
* (c) stephen lumenta under GPL
*
* conveniences for commonly used functions
* some parts are friendly derived from tim blechmanns sc4pd project
*
* http://www.gnu.org/licenses/gpl.html
* part of sc-max http://github.com/sbl/sc-max
* see README
*/

#ifndef SCMAX_H_XHP91X4G
#define SCMAX_H_XHP91X4G

#include <cmath>

// rate conversions

#undef SAMPLERATE
#define SAMPLERATE sys_getsr()

#undef BUFLENGTH
#define BUFLENGTH sys_getblksize()

float sc_radiansPerSample(){
return TWOPI / sys_getsr();
}

float sc_bufDuration(){
return sys_getblksize() / sys_getsr();
}

float sc_bufrate(){
return 1 / sc_bufDuration();
}

float sc_slopeFactor(){
return 1 / sys_getblksize();
}

int sc_filterLoops(){
return sys_getblksize() / 3;
}

int sc_filterRemain(){
return sys_getblksize() % 3;
}

float sc_filterSlope(){
float loops = sc_filterLoops();
if (loops == 0)
return 0;
else
return 1. / loops;
}

// DSP loops

#define ZXP(z) (*(z)++)



#define LOOP(length, stmt) \
{ int xxn = (length); \
while (--xxn) { \
stmt; \
} \
}

// math
const double log001 = std::log(0.001);
const double log01 = std::log(0.01);
const double log1 = std::log(0.1);
const double rlog2 = 1./std::log(2.);
const double sqrt2 = std::sqrt(2.);
const double rsqrt2 = 1. / sqrt2;
const float pi_f = std::acos(-1.f);
const float pi2_f = pi_f * 0.5f;
const float pi32_f = pi_f * 1.5f;
const float twopi_f = pi_f * 2.f;
const float sqrt2_f = std::sqrt(2.f);
const float rsqrt2_f= 1.f/std::sqrt(2.f);


typedef float float32;

inline float32 zapgremlins(float32 x)
{
float32 absx = abs(x);
// very small numbers fail the first test, eliminating denormalized numbers
// (zero also fails the first test, but that is OK since it returns zero.)
// very large numbers fail the second test, eliminating infinities
// Not-a-Numbers fail both tests and are eliminated.
return (absx > (float32)1e-15 && absx < (float32)1e15) ? x : (float32)0.;
}

#endif
103 changes: 96 additions & 7 deletions sc.lpf~/sc.lpf~.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,19 @@
#include "ext.h"
#include "ext_obex.h"
#include "z_dsp.h"
#include "scmax.h"


//////////////////////////////////////////////////////////////////////////////////////////////////////

typedef struct _lpf
{
t_pxobject ob;
short m_connected[2];

float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq;
float mRadiansPerSample, mFilterSlope;
int mFilterLoops, mFilterRemain;
} t_lpf;

t_class *lpf_class;
Expand Down Expand Up @@ -71,21 +77,98 @@ int main(void){
//////////////////////////////////////////////////////////////////////////////////////////////////////

void lpf_dsp(t_lpf *x, t_signal **sp, short *count){
dsp_add(lpf_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
x->mRadiansPerSample = sc_radiansPerSample();
x->mFilterSlope = sc_filterSlope();
x->mFilterLoops = sc_filterLoops();
x->mFilterRemain = sc_filterRemain();

x->m_connected[0] = count[0];
x->m_connected[1] = count[1];

// the chain
dsp_add(lpf_perform, 4, x, sp[0]->s_vec, sp[2]->s_vec, sp[1]->s_vec);
}

t_int *lpf_perform(t_int *w){
t_lpf *x = (t_lpf *)(w[1]);
t_float *in = (t_float *)(w[2]);
t_float *out = (t_float *)(w[3]);
int n = (int)w[4];
t_float *out = (t_float *)(w[4]);

t_float freq = x->m_connected[1] ? (*(t_float *)w[3]) : x->m_freq;

if (x->ob.z_disabled)
return w + 5;

while (n--) {
*out++ = *in++;
}

float y0;
float y1 = x->m_y1;
float y2 = x->m_y2;
float a0 = x->m_a0;
float b1 = x->m_b1;
float b2 = x->m_b2;

if (freq != x->m_freq) {

float pfreq = freq * x->mRadiansPerSample * 0.5;

float C = 1.f / tan(pfreq);
float C2 = C * C;
float sqrt2C = C * sqrt2_f;
float next_a0 = 1.f / (1.f + sqrt2C + C2);
float next_b1 = -2.f * (1.f - C2) * next_a0 ;
float next_b2 = -(1.f - sqrt2C + C2) * next_a0;

//post("%g %g %g %g %g %g %g %g %g %g\n", *freq, pfreq, qres, D, C, cosf, next_b1, next_b2, next_a0, y1, y2);

float a0_slope = (next_a0 - a0) * x->mFilterSlope;
float b1_slope = (next_b1 - b1) * x->mFilterSlope;
float b2_slope = (next_b2 - b2) * x->mFilterSlope;

LOOP(x->mFilterLoops,
y0 = ZXP(in) + b1 * y1 + b2 * y2;
ZXP(out) = a0 * (y0 + 2.f * y1 + y2);

y2 = ZXP(in) + b1 * y0 + b2 * y1;
ZXP(out) = a0 * (y2 + 2.f * y0 + y1);

y1 = ZXP(in) + b1 * y2 + b2 * y0;
ZXP(out) = a0 * (y1 + 2.f * y2 + y0);

a0 += a0_slope;
b1 += b1_slope;
b2 += b2_slope;
);
LOOP(x->mFilterRemain,
y0 = ZXP(in) + b1 * y1 + b2 * y2;
ZXP(out) = a0 * (y0 + 2.f * y1 + y2);
y2 = y1;
y1 = y0;
);

x->m_freq = freq;
x->m_a0 = a0;
x->m_b1 = b1;
x->m_b2 = b2;
} else {
LOOP(x->mFilterLoops,
y0 = ZXP(in) + b1 * y1 + b2 * y2;
ZXP(out) = a0 * (y0 + 2.f * y1 + y2);

y2 = ZXP(in) + b1 * y0 + b2 * y1;
ZXP(out) = a0 * (y2 + 2.f * y0 + y1);

y1 = ZXP(in) + b1 * y2 + b2 * y0;
ZXP(out) = a0 * (y1 + 2.f * y2 + y0);
);
LOOP(x->mFilterRemain,
y0 = ZXP(in) + b1 * y1 + b2 * y2;
ZXP(out) = a0 * (y0 + 2.f * y1 + y2);
y2 = y1;
y1 = y0;
);
}
x->m_y1 = zapgremlins(y1);
x->m_y2 = zapgremlins(y2);

return w + 5;
}
Expand All @@ -108,10 +191,16 @@ void *lpf_new(){

if (x) {
// number of inlets
dsp_setup((t_pxobject *)x, 1);
dsp_setup((t_pxobject *)x, 2);

outlet_new((t_object *)x, "signal");

x->m_a0 = 0.f;
x->m_b1 = 0.f;
x->m_b2 = 0.f;
x->m_y1 = 0.f;
x->m_y2 = 0.f;
x->m_freq = 0.f;
}
return (x);
}
Loading

0 comments on commit b39922d

Please sign in to comment.