diff options
Diffstat (limited to 'sc4pd/source')
96 files changed, 20753 insertions, 0 deletions
diff --git a/sc4pd/source/AllpassC.cpp b/sc4pd/source/AllpassC.cpp new file mode 100644 index 0000000..72c05f5 --- /dev/null +++ b/sc4pd/source/AllpassC.cpp @@ -0,0 +1,315 @@ +/* sc4pd + AllpassC~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Rashid Ali & Frank Lowe: Duo Exchange + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class AllpassC_ar : public FeedbackDelay_ar +{ + FLEXT_HEADER(AllpassC_ar,FeedbackDelay_ar); + + AllpassC_ar (int argc, t_atom *argv); + ~AllpassC_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + delay_changed = decay_changed = false; + FeedbackDelay_Reset(); + } + + void m_delay(float f) + { + m_delaytime=f; + delay_changed = true; + } + + void m_decay(float f) + { + m_decaytime=f; + decay_changed = true; + } + +private: + bool delay_changed, decay_changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_delay); + FLEXT_CALLBACK_F(m_decay); +}; + +FLEXT_LIB_DSP_V("AllpassC~",AllpassC_ar); + +AllpassC_ar::AllpassC_ar (int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"delaytime",m_delay); + FLEXT_ADDMETHOD_(0,"decaytime",m_decay); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 3) + { + post("3 arguments are needed"); + return; + } + + m_maxdelaytime = sc_getfloatarg(Args,0); + m_delaytime = sc_getfloatarg(Args,1); + m_decaytime = sc_getfloatarg(Args,2); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +AllpassC_ar::~AllpassC_ar () +{ + DelayUnit_Dtor(); +} + +void AllpassC_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + float d0, d1, d2, d3; + + if (delay_changed || decay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + + if (irdphase0 < 0) + { + dlybuf[iwrphase & mask] = ZXP(nin); + ZXP(nout) = 0.f; + } + else + { + if (irdphase1 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + } + else if (irdphase2 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + } + else if (irdphase3 < 0) + { + d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + } + else + { + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + d3 = dlybuf[irdphase3 & mask]; + } + float value = cubicinterp(frac, d0, d1, d2, d3); + float dwr = ZXP(nin) + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + } + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + + for (int i = 0; i!= n;++i) + { + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + + if (irdphase0 < 0) + { + dlybuf[iwrphase & mask] = ZXP(nin); + ZXP(nout) = 0.f; + } + else + { + if (irdphase1 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + } + else if (irdphase2 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + } + else if (irdphase3 < 0) + { + d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + } + else + { + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + d3 = dlybuf[irdphase3 & mask]; + } + float value = cubicinterp(frac, d0, d1, d2, d3); + float dwr = ZXP(nin) + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + } + iwrphase++; + } + } + + m_iwrphase = iwrphase; + m_numoutput += n; + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void AllpassC_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + float d0, d1, d2, d3; + + if(delay_changed || decay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for(int i=0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + float d0 = dlybuf[irdphase0 & mask]; + float d1 = dlybuf[irdphase1 & mask]; + float d2 = dlybuf[irdphase2 & mask]; + float d3 = dlybuf[irdphase3 & mask]; + float value = cubicinterp(frac, d0, d1, d2, d3); + float dwr = ZXP(nin) + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + for(int i=0; i!= n;++i) + { + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + float d0 = dlybuf[irdphase0 & mask]; + float d1 = dlybuf[irdphase1 & mask]; + float d2 = dlybuf[irdphase2 & mask]; + float d3 = dlybuf[irdphase3 & mask]; + float value = cubicinterp(frac, d0, d1, d2, d3); + float dwr = ZXP(nin) + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + iwrphase++; + } + } + m_iwrphase = iwrphase; +} + +/* todo: AllpassC for control rate ? */ diff --git a/sc4pd/source/AllpassL.cpp b/sc4pd/source/AllpassL.cpp new file mode 100644 index 0000000..2353df3 --- /dev/null +++ b/sc4pd/source/AllpassL.cpp @@ -0,0 +1,276 @@ +/* sc4pd + AllpassL~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Rashid Ali & Frank Lowe: Duo Exchange + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class AllpassL_ar : public FeedbackDelay_ar +{ + FLEXT_HEADER(AllpassL_ar,FeedbackDelay_ar); + + AllpassL_ar (int argc, t_atom *argv); + ~AllpassL_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + delay_changed = decay_changed = false; + FeedbackDelay_Reset(); + } + + void m_delay(float f) + { + m_delaytime=f; + delay_changed = true; + } + + void m_decay(float f) + { + m_decaytime=f; + decay_changed = true; + } + +private: + bool delay_changed, decay_changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_delay); + FLEXT_CALLBACK_F(m_decay); +}; + +FLEXT_LIB_DSP_V("AllpassL~",AllpassL_ar); + +AllpassL_ar::AllpassL_ar (int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"delaytime",m_delay); + FLEXT_ADDMETHOD_(0,"decaytime",m_decay); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 3) + { + post("3 arguments are needed"); + return; + } + + m_maxdelaytime = sc_getfloatarg(Args,0); + m_delaytime = sc_getfloatarg(Args,1); + m_decaytime = sc_getfloatarg(Args,2); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +AllpassL_ar::~AllpassL_ar () +{ + DelayUnit_Dtor(); +} + +void AllpassL_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + + if (delay_changed || decay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + + float zin = ZXP(nin); + if (irdphase < 0) + { + dlybuf[iwrphase & mask] = zin; + ZXP(nout) = - feedbk * zin; //check: probably a bug = 0? + } + else if (irdphaseb < 0) + { + float d1 = dlybuf[irdphase & mask]; + float value = d1 - frac * d1; + float dwr = zin + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + } + else + { + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + float value = lininterp(frac, d1, d2); + float dwr = zin + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + } + + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + + float zin = ZXP(nin); + for (int i = 0; i!= n;++i) + { + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + + float zin = ZXP(nin); + if (irdphase < 0) + { + dlybuf[iwrphase & mask] = zin; + ZXP(nout) = - feedbk * zin; + } + else if (irdphaseb < 0) + { + float d1 = dlybuf[irdphase & mask]; + float value = d1 - frac * d1; + float dwr = zin + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + } + else + { + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + float value = lininterp(frac, d1, d2); + float dwr = zin + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + } + iwrphase++; + } + } + + m_iwrphase = iwrphase; + m_numoutput += n; + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void AllpassL_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + + if(delay_changed || decay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for(int i=0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + float value = lininterp(frac, d1, d2); + float dwr = ZXP(nin) + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + + for(int i=0; i!= n;++i) + { + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + float value = lininterp(frac, d1, d2); + float dwr = ZXP(nin) + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + iwrphase++; + } + } + m_iwrphase = iwrphase; +} + +/* todo: AllpassL for control rate ? */ diff --git a/sc4pd/source/AllpassN.cpp b/sc4pd/source/AllpassN.cpp new file mode 100644 index 0000000..a03130b --- /dev/null +++ b/sc4pd/source/AllpassN.cpp @@ -0,0 +1,348 @@ +/* sc4pd + AllpassN~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Efzeg: Boogie + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class AllpassN_ar : public FeedbackDelay_ar +{ + FLEXT_HEADER(AllpassN_ar,FeedbackDelay_ar); + + AllpassN_ar (int argc, t_atom *argv); + ~AllpassN_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + delay_changed = decay_changed = false; + FeedbackDelay_Reset(); + } + + void m_delay(float f) + { + m_delaytime=f; + delay_changed = true; + } + + void m_decay(float f) + { + m_decaytime=f; + decay_changed = true; + } + +private: + bool delay_changed, decay_changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_delay); + FLEXT_CALLBACK_F(m_decay); +}; + +FLEXT_LIB_DSP_V("AllpassN~",AllpassN_ar); + +AllpassN_ar::AllpassN_ar (int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"delaytime",m_delay); + FLEXT_ADDMETHOD_(0,"decaytime",m_decay); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 3) + { + post("3 arguments are needed"); + return; + } + + m_maxdelaytime = sc_getfloatarg(Args,0); + m_delaytime = sc_getfloatarg(Args,1); + m_decaytime = sc_getfloatarg(Args,2); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +AllpassN_ar::~AllpassN_ar () +{ + DelayUnit_Dtor(); +} + +void AllpassN_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + + if (delay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long irdphase = iwrphase - (long)dsamp; + + if (irdphase < 0) + { + float dwr = ZXP(nin); + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = -feedbk * dwr; + } + else + { + float value = dlybuf[irdphase & mask]; + float dwr = feedbk * value + ZXP(nin); + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + } + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long irdphase = iwrphase - (long)dsamp; + float* dlybuf1 = dlybuf - ZOFF; + float* dlyN = dlybuf1 + m_idelaylen; + if (decay_changed) + { + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + long remain = n; + while (remain) + { + float* dlywr = dlybuf1 + (iwrphase & mask); + float* dlyrd = dlybuf1 + (irdphase & mask); + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + if (irdphase < 0) + { + dlyrd += nsmps; + for (int i = 0; i!= nsmps;++i) + { + float dwr = ZXP(nin); + ZXP(dlywr) = dwr; + ZXP(nout) = -feedbk * dwr; + feedbk += feedbk_slope; + } + } + else + { + for (int i = 0; i!= nsmps;++i) + { + float x1 = ZXP(dlyrd); + float dwr = x1 * feedbk + ZXP(nin); + ZXP(dlywr) = dwr; + ZXP(nout) = x1 - feedbk * dwr; + feedbk += feedbk_slope; + } + } + iwrphase += nsmps; + irdphase += nsmps; + } + decay_changed=false; + } + else + { + long remain = n; + while (remain) + { + float* dlyrd = dlybuf1 + (irdphase & mask); + float* dlywr = dlybuf1 + (iwrphase & mask); + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + + if (irdphase < 0) + { + feedbk = -feedbk; + for (int i = 0; i!= nsmps;++i) + { + float dwr = ZXP(nin); + ZXP(dlywr) = dwr; + ZXP(nout) = feedbk * dwr; + } + feedbk = -feedbk; + } + else + { + for (int i = 0; i!= nsmps;++i) + { + float x1 = ZXP(dlyrd); + float dwr = x1 * feedbk + ZXP(nin); + ZXP(dlywr) = dwr; + ZXP(nout) = x1 - feedbk * dwr; + } + } + iwrphase += nsmps; + irdphase += nsmps; + } + m_feedbk = feedbk; + } + } + + m_iwrphase = iwrphase; + m_numoutput += n; + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void AllpassN_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + + if(delay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for(int i=0; i!= n;++i) + { + dsamp += dsamp_slope; + ++iwrphase; + long irdphase = iwrphase - (long)dsamp; + float value = dlybuf[irdphase & mask]; + float dwr = value * feedbk + ZXP(nin); + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + feedbk += feedbk_slope; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long irdphase = iwrphase - (long)dsamp; + float* dlybuf1 = dlybuf - ZOFF; + float* dlyrd = dlybuf1 + (irdphase & mask); + float* dlywr = dlybuf1 + (iwrphase & mask); + float* dlyN = dlybuf1 + m_idelaylen; + + if(decay_changed) + { + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + long remain = n; + while (remain) + { + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + + for(int i=0; i!= nsmps;++i) + { + float value = ZXP(dlyrd); + float dwr = value * feedbk + ZXP(nin); + ZXP(dlywr) = dwr; + ZXP(nout) = value - feedbk * dwr; + feedbk += feedbk_slope; + } + if (dlyrd == dlyN) dlyrd = dlybuf1; + if (dlywr == dlyN) dlywr = dlybuf1; + } + m_feedbk = feedbk; + decay_changed = false; + } + else + { + long remain = n; + while (remain) + { + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + + for (int i = 0; i!= nsmps; ++i) + { + float value = ZXP(dlyrd); + float dwr = value * feedbk + ZXP(nin); + ZXP(dlywr) = dwr; + ZXP(nout) = value - feedbk * dwr; + } + if (dlyrd == dlyN) dlyrd = dlybuf1; + if (dlywr == dlyN) dlywr = dlybuf1; + } + + } + iwrphase += n; + } + m_iwrphase = iwrphase; +} + +/* todo: AllpassN for control rate ? */ diff --git a/sc4pd/source/BPF.cpp b/sc4pd/source/BPF.cpp new file mode 100644 index 0000000..f998dd4 --- /dev/null +++ b/sc4pd/source/BPF.cpp @@ -0,0 +1,190 @@ +/* sc4pd + BPF~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Jo Kondo: Works For Piano + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ BPF~ -------------------------------*/ + +class BPF_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(BPF_ar,sc4pd_dsp); + +public: + BPF_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + } + + void m_set_freq(float f) + { + m_freq=f; + changed = true; + } + + void m_set_rq(float f) + { + m_bw=f; + changed = true; + } + + +private: + float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq, m_bw; + bool changed; + float mRadiansPerSample, mFilterSlope; + int mFilterLoops, mFilterRemain; + + FLEXT_CALLBACK_F(m_set_freq); + FLEXT_CALLBACK_F(m_set_rq); +}; + +FLEXT_LIB_DSP_V("BPF~",BPF_ar); + +BPF_ar::BPF_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq); + FLEXT_ADDMETHOD_(0,"krq",m_set_rq); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + m_bw = sc_getfloatarg(Args,1); + changed = true; + + AddOutSignal(); + + m_a0 = 0.f; + m_b1 = 0.f; + m_b2 = 0.f; + m_y1 = 0.f; + m_y2 = 0.f; +} + +void BPF_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float y0; + float y1 = m_y1; + float y2 = m_y2; + float a0 = m_a0; + float b1 = m_b1; + float b2 = m_b2; + + if (changed) + { + float pfreq = m_freq * mRadiansPerSample; + float pbw = m_bw * pfreq * 0.5; + + float C = 1.f / tan(pbw); + float D = 2.f * cos(pfreq); + + float next_a0 = 1.f / (1.f + C); + float next_b1 = C * D * next_a0 ; + float next_b2 = (1.f - C) * next_a0; + + float a0_slope = (next_a0 - a0) * mFilterSlope; + float b1_slope = (next_b1 - b1) * mFilterSlope; + float b2_slope = (next_b2 - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - y2); + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * (y2 - y1); + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * (y1 - y0); + + a0 += a0_slope; + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - y2); + y2 = y1; + y1 = y0; + } + + m_a0 = a0; + m_b1 = b1; + m_b2 = b2; + changed = false; + } + else + { + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - y2); + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * (y2 - y1); + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * (y1 - y0); + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - y2); + y2 = y1; + y1 = y0; + } + } + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + +/* no control rate BPF filter */ diff --git a/sc4pd/source/BPZ2.cpp b/sc4pd/source/BPZ2.cpp new file mode 100644 index 0000000..a18a9dc --- /dev/null +++ b/sc4pd/source/BPZ2.cpp @@ -0,0 +1,140 @@ +/* sc4pd + BPZ2~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: William Parker: Compassion Seizes Bed-Stuy + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ BPZ2~ -------------------------------*/ + +class BPZ2_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(BPZ2_ar,sc4pd_dsp); + +public: + BPZ2_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mFilterLoops=sc_filterloops(); + mFilterRemain=sc_filterremain(); + } + +private: + float m_x1, m_x2; + int mFilterLoops, mFilterRemain; +}; + +FLEXT_LIB_DSP_V("BPZ2~",BPZ2_ar); + +BPZ2_ar::BPZ2_ar(int argc, t_atom *argv) +{ + AddOutSignal(); + + m_x1=0; + m_x2=0; +} + +void BPZ2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float x0; + float x1 = m_x1; + float x2 = m_x2; + + for (int i = 0; i!=mFilterLoops ;++i) + { + x0 = ZXP(nin); + ZXP(nout) = (x0 - x2) * 0.5f; + x2 = ZXP(nin); + ZXP(nout) = (x2 - x1) * 0.5f; + x1 = ZXP(nin); + ZXP(nout) = (x1 - x0) * 0.5f; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + x0 = ZXP(nin); + ZXP(nout) = (x0 - x2) * 0.5f; + x2 = x1; + x1 = x0; + } + m_x1 = x1; + m_x2 = x2; +} + +/* ------------------------ BPZ2 -------------------------------*/ + +class BPZ2_kr: + public flext_base +{ + FLEXT_HEADER(BPZ2_kr,flext_base); + +public: + BPZ2_kr(int argc, t_atom *argv); + +protected: + void m_perform (float f); + +private: + float m_x1; + float m_x2; + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB_V("BPZ2",BPZ2_kr); + +BPZ2_kr::BPZ2_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + + AddOutFloat(); + + m_x2 = m_x1 = 0; +} + +void BPZ2_kr::m_perform(float f) +{ + ToOutFloat(0,(f - m_x2) * 0.5f); + m_x2=m_x1; + m_x1=f; +} + diff --git a/sc4pd/source/BRF.cpp b/sc4pd/source/BRF.cpp new file mode 100644 index 0000000..e6db680 --- /dev/null +++ b/sc4pd/source/BRF.cpp @@ -0,0 +1,199 @@ +/* sc4pd + BRF~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Jo Kondo: Works For Piano + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ BRF~ -------------------------------*/ + +class BRF_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(BRF_ar,sc4pd_dsp); + +public: + BRF_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + } + + void m_set_freq(float f) + { + m_freq=f; + changed = true; + } + + void m_set_rq(float f) + { + m_bw=f; + changed = true; + } + + +private: + float m_y1, m_y2, m_a0, m_a1, m_b2, m_freq, m_bw; + bool changed; + float mRadiansPerSample, mFilterSlope; + int mFilterLoops, mFilterRemain; + + FLEXT_CALLBACK_F(m_set_freq); + FLEXT_CALLBACK_F(m_set_rq); +}; + +FLEXT_LIB_DSP_V("BRF~",BRF_ar); + +BRF_ar::BRF_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq); + FLEXT_ADDMETHOD_(0,"krq",m_set_rq); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + m_bw = sc_getfloatarg(Args,1); + changed = true; + + AddOutSignal(); + + m_a0 = 0.f; + m_a1 = 0.f; + m_b2 = 0.f; + m_y1 = 0.f; + m_y2 = 0.f; +} + +void BRF_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float ay; + float y0; + float y1 = m_y1; + float y2 = m_y2; + float a0 = m_a0; + float a1 = m_a1; + float b2 = m_b2; + + if (changed) + { + float pfreq = m_freq * mRadiansPerSample; + float pbw = m_bw * pfreq * 0.5; + + float C = tan(pbw); + float D = 2.f * cos(pfreq); + + float next_a0 = 1.f / (1.f + C); + float next_a1 = -D * next_a0; + float next_b2 = (1.f - C) * next_a0; + + float a0_slope = (next_a0 - a0) * mFilterSlope; + float a1_slope = (next_a1 - a1) * mFilterSlope; + float b2_slope = (next_b2 - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + ay = a1 * y1; + y0 = ZXP(nin) - ay - b2 * y2; + ZXP(nout) = a0 * (y0 + y2) + ay; + + ay = a1 * y0; + y2 = ZXP(nin) - ay - b2 * y1; + ZXP(nout) = a0 * (y2 + y1) + ay; + + ay = a1 * y2; + y1 = ZXP(nin) - ay - b2 * y0; + ZXP(nout) = a0 * (y1 + y0) + ay; + + a0 += a0_slope; + a1 += a1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + ay = a1 * y1; + y0 = ZXP(nin) - ay - b2 * y2; + ZXP(nout) = a0 * (y0 + y2) + ay; + y2 = y1; + y1 = y0; + } + + m_a0 = a0; + m_a1 = a1; + m_b2 = b2; + changed = false; + } + else + { + for (int i = 0; i!= mFilterLoops;++i) + { + ay = a1 * y1; + y0 = ZXP(nin) - ay - b2 * y2; + ZXP(nout) = a0 * (y0 + y2) + ay; + + ay = a1 * y0; + y2 = ZXP(nin) - ay - b2 * y1; + ZXP(nout) = a0 * (y2 + y1) + ay; + + ay = a1 * y2; + y1 = ZXP(nin) - ay - b2 * y0; + ZXP(nout) = a0 * (y1 + y0) + ay; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + ay = a1 * y1; + y0 = ZXP(nin) - ay - b2 * y2; + ZXP(nout) = a0 * (y0 + y2) + ay; + y2 = y1; + y1 = y0; + } + } + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + +/* no control rate BRF filter */ diff --git a/sc4pd/source/BRZ2.cpp b/sc4pd/source/BRZ2.cpp new file mode 100644 index 0000000..4c14fa2 --- /dev/null +++ b/sc4pd/source/BRZ2.cpp @@ -0,0 +1,140 @@ +/* sc4pd + BRZ2~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: William Parker: Compassion Seizes Bed-Stuy + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ BRZ2~ -------------------------------*/ + +class BRZ2_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(BRZ2_ar,sc4pd_dsp); + +public: + BRZ2_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mFilterLoops=sc_filterloops(); + mFilterRemain=sc_filterremain(); + } + +private: + float m_x1, m_x2; + int mFilterLoops, mFilterRemain; +}; + +FLEXT_LIB_DSP_V("BRZ2~",BRZ2_ar); + +BRZ2_ar::BRZ2_ar(int argc, t_atom *argv) +{ + AddOutSignal(); + + m_x1=0; + m_x2=0; +} + +void BRZ2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float x0; + float x1 = m_x1; + float x2 = m_x2; + + for (int i = 0; i!=mFilterLoops ;++i) + { + x0 = ZXP(nin); + ZXP(nout) = (x0 + x2) * 0.5f; + x2 = ZXP(nin); + ZXP(nout) = (x2 + x1) * 0.5f; + x1 = ZXP(nin); + ZXP(nout) = (x1 + x0) * 0.5f; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + x0 = ZXP(nin); + ZXP(nout) = (x0 + x2) * 0.5f; + x2 = x1; + x1 = x0; + } + m_x1 = x1; + m_x2 = x2; +} + +/* ------------------------ BRZ2 -------------------------------*/ + +class BRZ2_kr: + public flext_base +{ + FLEXT_HEADER(BRZ2_kr,flext_base); + +public: + BRZ2_kr(int argc, t_atom *argv); + +protected: + void m_perform (float f); + +private: + float m_x1; + float m_x2; + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB_V("BRZ2",BRZ2_kr); + +BRZ2_kr::BRZ2_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + + AddOutFloat(); + + m_x2 = m_x1 = 0; +} + +void BRZ2_kr::m_perform(float f) +{ + ToOutFloat(0,(f + m_x2) * 0.5f); + m_x2=m_x1; + m_x1=f; +} + diff --git a/sc4pd/source/BrownNoise.cpp b/sc4pd/source/BrownNoise.cpp new file mode 100644 index 0000000..316ee42 --- /dev/null +++ b/sc4pd/source/BrownNoise.cpp @@ -0,0 +1,156 @@ +/* sc4pd + BrownNoise, BrownNoise~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: AMM: Laminal + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ BrownNoise~ -------------------------------*/ + +class BrownNoise_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(BrownNoise_ar,sc4pd_dsp); + +public: + BrownNoise_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_level; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("BrownNoise~",BrownNoise_ar); + +BrownNoise_ar::BrownNoise_ar(int argc, t_atom *argv) +{ + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + m_level=rgen.frand2(); + + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AddOutSignal(); +} + + +void BrownNoise_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + RGET; + + float z = m_level; + + for (int i = 0; i!= n;++i) + { + z += frand8(s1, s2, s3); + if (z > 1.f) + z = 2.f - z; + else + if (z < -1.f) + z = -2.f - z; + (*(nout)++) = z; + } + m_level = z; + + RPUT; +} + + +/* ------------------------ BrownNoise ---------------------------------*/ + +class BrownNoise_kr: + public flext_base +{ + FLEXT_HEADER(BrownNoise_kr,flext_base); + +public: + BrownNoise_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_level; + RGen rgen; + FLEXT_CALLBACK(m_perform); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("BrownNoise",BrownNoise_kr); + +BrownNoise_kr::BrownNoise_kr(int argc, t_atom *argv) +{ + FLEXT_ADDBANG(0,m_perform); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + m_level=rgen.frand2(); + + AddOutFloat(); +} + +void BrownNoise_kr::m_perform() +{ + float z = m_level + rgen.frand8(); + if (z > 1.f) + z = 2.f - z; + else + if (z < -1.f) + z = -2.f - z; + ToOutFloat(0,z); + m_level = z; +} diff --git a/sc4pd/source/ClipNoise.cpp b/sc4pd/source/ClipNoise.cpp new file mode 100644 index 0000000..39c0d61 --- /dev/null +++ b/sc4pd/source/ClipNoise.cpp @@ -0,0 +1,136 @@ +/* sc4pd + ClipNoise, ClipNoise~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Henry Threadgill: Everybodys Mouth's A Book + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ ClipNoise~ -------------------------------*/ + +class ClipNoise_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(ClipNoise_ar,sc4pd_dsp); + +public: + ClipNoise_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("ClipNoise~",ClipNoise_ar); + +ClipNoise_ar::ClipNoise_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + AddOutSignal(); +} + + +void ClipNoise_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + RGET; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = fcoin(s1, s2, s3); + } + + RPUT; +} + + +/* ------------------------ ClipNoise ---------------------------------*/ + +class ClipNoise_kr: + public flext_base +{ + FLEXT_HEADER(ClipNoise_kr,flext_base); + +public: + ClipNoise_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + RGen rgen; + FLEXT_CALLBACK(m_perform); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("ClipNoise",ClipNoise_kr); + +ClipNoise_kr::ClipNoise_kr(int argc, t_atom *argv) +{ + FLEXT_ADDBANG(0,m_perform); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + AddOutInt(); +} + +void ClipNoise_kr::m_perform() +{ + ToOutInt(0,rgen.fcoin()); +} diff --git a/sc4pd/source/CoinGate.cpp b/sc4pd/source/CoinGate.cpp new file mode 100644 index 0000000..fc47aca --- /dev/null +++ b/sc4pd/source/CoinGate.cpp @@ -0,0 +1,84 @@ +/* sc4pd + CoinGate + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: the sounds coming through my open window + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ CoinGate ---------------------------------*/ + +class CoinGate_kr: + public flext_base +{ + FLEXT_HEADER(CoinGate_kr,flext_base); + +public: + CoinGate_kr(int argc, t_atom *argv); + +protected: + void m_bang(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float prob; + FLEXT_CALLBACK(m_bang); + FLEXT_CALLBACK_I(m_seed); + RGen rgen; +}; + +FLEXT_LIB_V("CoinGate",CoinGate_kr); + +CoinGate_kr::CoinGate_kr(int argc, t_atom *argv) +{ + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + prob = sc_getfloatarg(Args,0); + + FLEXT_ADDBANG(0,m_bang); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + AddOutBang(); +} + +void CoinGate_kr::m_bang() +{ + if(rgen.frand() < prob) + ToOutBang(0); +} diff --git a/sc4pd/source/CombC.cpp b/sc4pd/source/CombC.cpp new file mode 100644 index 0000000..bed7384 --- /dev/null +++ b/sc4pd/source/CombC.cpp @@ -0,0 +1,314 @@ +/* sc4pd + CombC~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Butcher/Charles/Doerner: The Contest Of Pleasures + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class CombC_ar : public FeedbackDelay_ar +{ + FLEXT_HEADER(CombC_ar,FeedbackDelay_ar); + + CombC_ar (int argc, t_atom *argv); + ~CombC_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + delay_changed = decay_changed = false; + FeedbackDelay_Reset(); + } + + void m_delay(float f) + { + m_delaytime=f; + delay_changed = true; + } + + void m_decay(float f) + { + m_decaytime=f; + decay_changed = true; + } + +private: + bool delay_changed, decay_changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_delay); + FLEXT_CALLBACK_F(m_decay); +}; + +FLEXT_LIB_DSP_V("CombC~",CombC_ar); + +CombC_ar::CombC_ar (int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"delaytime",m_delay); + FLEXT_ADDMETHOD_(0,"decaytime",m_decay); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 3) + { + post("3 arguments are needed"); + return; + } + + m_maxdelaytime = sc_getfloatarg(Args,0); + m_delaytime = sc_getfloatarg(Args,1); + m_decaytime = sc_getfloatarg(Args,2); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +CombC_ar::~CombC_ar () +{ + DelayUnit_Dtor(); +} + +void CombC_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + float d0, d1, d2, d3; + + if (delay_changed || decay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + + + if (irdphase0 < 0) + { + dlybuf[iwrphase & mask] = ZXP(nin); + ZXP(nout) = 0.f; + } + else + { + if (irdphase1 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + } + else if (irdphase2 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + } + else if (irdphase3 < 0) + { + d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + } + else + { + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + d3 = dlybuf[irdphase3 & mask]; + } + float value = cubicinterp(frac, d0, d1, d2, d3); + dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value; + ZXP(nout) = value; + } + + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + + for (int i = 0; i!= n;++i) + { + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + + if (irdphase0 < 0) + { + dlybuf[iwrphase & mask] = ZXP(nin); + ZXP(nout) = 0.f; + } + else + { + if (irdphase1 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + } + else if (irdphase2 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + } + else if (irdphase3 < 0) + { + d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + } + else + { + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + d3 = dlybuf[irdphase3 & mask]; + } + float value = cubicinterp(frac, d0, d1, d2, d3); + dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value; + ZXP(nout) = value; + } + iwrphase++; + } + } + + m_iwrphase = iwrphase; + m_numoutput += n; + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void CombC_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + float d0, d1, d2, d3; + + if(delay_changed || decay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for(int i=0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + float d0 = dlybuf[irdphase0 & mask]; + float d1 = dlybuf[irdphase1 & mask]; + float d2 = dlybuf[irdphase2 & mask]; + float d3 = dlybuf[irdphase3 & mask]; + float value = cubicinterp(frac, d0, d1, d2, d3); + dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value; + ZXP(nout) = value; + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + + for(int i=0; i!= n;++i) + { + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + float d0 = dlybuf[irdphase0 & mask]; + float d1 = dlybuf[irdphase1 & mask]; + float d2 = dlybuf[irdphase2 & mask]; + float d3 = dlybuf[irdphase3 & mask]; + float value = cubicinterp(frac, d0, d1, d2, d3); + dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value; + ZXP(nout) = value; + iwrphase++; + } + } + m_iwrphase = iwrphase; +} + +/* todo: CombC for control rate ? */ diff --git a/sc4pd/source/CombL.cpp b/sc4pd/source/CombL.cpp new file mode 100644 index 0000000..9af21ae --- /dev/null +++ b/sc4pd/source/CombL.cpp @@ -0,0 +1,272 @@ +/* sc4pd + CombL~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Butcher/Charles/Doerner: The Contest Of Pleasures + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class CombL_ar : public FeedbackDelay_ar +{ + FLEXT_HEADER(CombL_ar,FeedbackDelay_ar); + + CombL_ar (int argc, t_atom *argv); + ~CombL_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + delay_changed = decay_changed = false; + FeedbackDelay_Reset(); + } + + void m_delay(float f) + { + m_delaytime=f; + delay_changed = true; + } + + void m_decay(float f) + { + m_decaytime=f; + decay_changed = true; + } + +private: + bool delay_changed, decay_changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_delay); + FLEXT_CALLBACK_F(m_decay); +}; + +FLEXT_LIB_DSP_V("CombL~",CombL_ar); + +CombL_ar::CombL_ar (int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"delaytime",m_delay); + FLEXT_ADDMETHOD_(0,"decaytime",m_decay); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 3) + { + post("3 arguments are needed"); + return; + } + + m_maxdelaytime = sc_getfloatarg(Args,0); + m_delaytime = sc_getfloatarg(Args,1); + m_decaytime = sc_getfloatarg(Args,2); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +CombL_ar::~CombL_ar () +{ + DelayUnit_Dtor(); +} + +void CombL_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + + if (delay_changed || decay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + + float zin = ZXP(nin); + if (irdphase < 0) + { + dlybuf[iwrphase & mask] = zin; + ZXP(nout) = 0.f; + } + else if (irdphaseb < 0) + { + float d1 = dlybuf[irdphase & mask]; + float value = d1 - frac * d1; + dlybuf[iwrphase & mask] = zin + feedbk * value; + ZXP(nout) = value; + } + else + { + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + float value = lininterp(frac, d1, d2); + dlybuf[iwrphase & mask] = zin + feedbk * value; + ZXP(nout) = value; + } + + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + + for (int i = 0; i!= n;++i) + { + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + + float zin = ZXP(nin); + if (irdphase < 0) + { + dlybuf[iwrphase & mask] = zin; + ZXP(nout) = 0.f; + } + else if (irdphaseb < 0) + { + float d1 = dlybuf[irdphase & mask]; + float value = d1 - frac * d1; + dlybuf[iwrphase & mask] = zin + feedbk * value; + ZXP(nout) = value; + } + else + { + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + float value = lininterp(frac, d1, d2); + dlybuf[iwrphase & mask] = zin + feedbk * value; + ZXP(nout) = value; + } + iwrphase++; + } + + + } + + m_iwrphase = iwrphase; + m_numoutput += n; + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void CombL_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + + if(delay_changed || decay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for(int i=0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + float value = lininterp(frac, d1, d2); + dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value; + ZXP(nout) = value; + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + + for(int i=0; i!= n;++i) + { + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + float value = lininterp(frac, d1, d2); + dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value; + ZXP(nout) = value; + iwrphase++; + + } + } + m_iwrphase = iwrphase; +} + +/* todo: CombL for control rate ? */ diff --git a/sc4pd/source/CombN.cpp b/sc4pd/source/CombN.cpp new file mode 100644 index 0000000..9c6f33e --- /dev/null +++ b/sc4pd/source/CombN.cpp @@ -0,0 +1,341 @@ +/* sc4pd + CombN~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & John Tilbury: Duos For Doris + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class CombN_ar : public FeedbackDelay_ar +{ + FLEXT_HEADER(CombN_ar,FeedbackDelay_ar); + + CombN_ar (int argc, t_atom *argv); + ~CombN_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + delay_changed = decay_changed = false; + FeedbackDelay_Reset(); + } + + void m_delay(float f) + { + m_delaytime=f; + delay_changed = true; + } + + void m_decay(float f) + { + m_decaytime=f; + decay_changed = true; + } + +private: + bool delay_changed, decay_changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_delay); + FLEXT_CALLBACK_F(m_decay); +}; + +FLEXT_LIB_DSP_V("CombN~",CombN_ar); + +CombN_ar::CombN_ar (int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"delaytime",m_delay); + FLEXT_ADDMETHOD_(0,"decaytime",m_decay); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 3) + { + post("3 arguments are needed"); + return; + } + + m_maxdelaytime = sc_getfloatarg(Args,0); + m_delaytime = sc_getfloatarg(Args,1); + m_decaytime = sc_getfloatarg(Args,2); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +CombN_ar::~CombN_ar () +{ + DelayUnit_Dtor(); +} + +void CombN_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + + if (delay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long irdphase = iwrphase - (long)dsamp; + + if (irdphase < 0) + { + dlybuf[iwrphase & mask] = ZXP(nin); + ZXP(nout) = 0.f; + } + else + { + float value = dlybuf[irdphase & mask]; + dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value; + ZXP(nout) = value; + } + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long irdphase = iwrphase - (long)dsamp; + float* dlybuf1 = dlybuf - ZOFF; + float* dlyN = dlybuf1 + m_idelaylen; + if (decay_changed) + { + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + long remain = n; + while (remain) + { + float* dlyrd = dlybuf1 + (irdphase & mask); + float* dlywr = dlybuf1 + (iwrphase & mask); + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + + if (irdphase < 0) + { + feedbk += nsmps * feedbk_slope; + dlyrd += nsmps; + for (int i = 0; i!= nsmps;++i) + { + ZXP(dlywr) = ZXP(nin); + ZXP(nout) = 0.f; + } + } + else + { + for (int i = 0; i!= nsmps;++i) + { + float value = ZXP(dlyrd); + ZXP(dlywr) = value * feedbk + ZXP(nin); + ZXP(nout) = value; + feedbk += feedbk_slope; + } + } + iwrphase += nsmps; + irdphase += nsmps; + } + m_feedbk = feedbk; + decay_changed=false; + } + else + { + long remain = n; + while (remain) + { + float* dlywr = dlybuf1 + (iwrphase & mask); + float* dlyrd = dlybuf1 + (irdphase & mask); + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + if (irdphase < 0) + { + for (int i = 0; i!= nsmps;++i) + { + ZXP(dlywr) = ZXP(nin); + ZXP(nout) = 0.f; + } + } + else + { + for (int i = 0; i!= nsmps;++i) + { + float value = ZXP(dlyrd); + ZXP(dlywr) = value * feedbk + ZXP(nin); + ZXP(nout) = value; + } + } + iwrphase += nsmps; + irdphase += nsmps; + } + + } + } + + m_iwrphase = iwrphase; + m_numoutput += n; + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void CombN_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + + if(delay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for(int i=0; i!= n;++i) + { + dsamp += dsamp_slope; + ++iwrphase; + long irdphase = iwrphase - (long)dsamp; + float value = dlybuf[irdphase & mask]; + dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value; + ZXP(nout) = value; + feedbk += feedbk_slope; + + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long irdphase = iwrphase - (long)dsamp; + float* dlybuf1 = dlybuf - ZOFF; + float* dlyrd = dlybuf1 + (irdphase & mask); + float* dlywr = dlybuf1 + (iwrphase & mask); + float* dlyN = dlybuf1 + m_idelaylen; + + if(decay_changed) + { + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + long remain = n; + while (remain) + { + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + + for(int i=0; i!= nsmps;++i) + { + float value = ZXP(dlyrd); + ZXP(dlywr) = value * feedbk + ZXP(nin); + ZXP(nout) = value; + feedbk += feedbk_slope; + } + if (dlyrd == dlyN) dlyrd = dlybuf1; + if (dlywr == dlyN) dlywr = dlybuf1; + } + m_feedbk = feedbk; + decay_changed = false; + } + else + { + long remain = n; + while (remain) + { + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + + for (int i = 0; i!= nsmps; ++i) + { + float value = ZXP(dlyrd); + ZXP(dlywr) = value * feedbk + ZXP(nin); + ZXP(nout) = value; + } + if (dlyrd == dlyN) dlyrd = dlybuf1; + if (dlywr == dlyN) dlywr = dlybuf1; + } + + } + iwrphase += n; + + + } + m_iwrphase = iwrphase; +} + +/* todo: CombN for control rate ? */ diff --git a/sc4pd/source/Convolution.cpp b/sc4pd/source/Convolution.cpp new file mode 100644 index 0000000..0026b01 --- /dev/null +++ b/sc4pd/source/Convolution.cpp @@ -0,0 +1,222 @@ +/* sc4pd + Convolution~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Ambarchi/Muller/Voice Crack: Oystered + +*/ + +#include "sc4pd.hpp" +#include "fftlib.h" + +/* ------------------------ Convolution~ -------------------------------*/ + +class Convolution_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(Convolution_ar,sc4pd_dsp); + +public: + Convolution_ar(int argc, t_atom *argv); + ~Convolution_ar(); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + +private: + int m_pos, m_insize, m_fftsize,m_mask; + int m_log2n; + + float *m_inbuf1,*m_inbuf2, *m_fftbuf1, *m_fftbuf2, *m_outbuf,*m_overlapbuf; + +}; + +FLEXT_LIB_DSP_V("Convolution~",Convolution_ar); + +Convolution_ar::Convolution_ar(int argc, t_atom *argv) +{ + + //parse arguments + AtomList Args(argc,argv); + + m_insize = sc_getfloatarg(Args,0); + + AddInSignal("signal"); + AddInSignal("kernel"); + AddOutSignal(); + + + //require size N+M-1 to be a power of two + + m_fftsize=2*(m_insize); + + //just use memory for the input buffers and fft buffers + int insize = m_insize * sizeof(float); + int fftsize = m_fftsize * sizeof(float); + + m_inbuf1 = new float[m_insize]; + m_inbuf2 = new float[m_insize]; + + m_fftbuf1 = new float[m_fftsize]; + m_fftbuf2 = new float[m_fftsize]; + + m_outbuf = new float[m_fftsize]; + m_overlapbuf = new float[m_insize]; + + memset(m_outbuf, 0, fftsize); + memset(m_overlapbuf, 0, insize); + + m_log2n = LOG2CEIL(m_fftsize); + + //test for full input buffer + m_mask = m_insize; + m_pos = 0; +} + +Convolution_ar::~Convolution_ar() +{ + delete m_inbuf1; + delete m_inbuf2; + + delete m_fftbuf1; + delete m_fftbuf2; + + delete m_outbuf; + delete m_overlapbuf; +} + +void Convolution_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + +} + +extern float* cosTable[32]; + +void Convolution_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + float *in1 = in[0]; + float *in2 = in[1]; + + float *out1 = m_inbuf1 + m_pos; + float *out2 = m_inbuf2 + m_pos; + + int numSamples = 2*n; //??? mWorld->mFullRate.mBufLength; + + // copy input + CopySamples(out1, in1, numSamples); + CopySamples(out2, in2, numSamples); + + m_pos += numSamples; + + if (m_pos & m_insize) + { + + //have collected enough samples to transform next frame + m_pos = 0; //reset collection counter + + // copy to fftbuf + + uint32 insize=m_insize * sizeof(float); + memcpy(m_fftbuf1, m_inbuf1, insize); + memcpy(m_fftbuf2, m_inbuf2, insize); + + //zero pad second part of buffer to allow for convolution + memset(m_fftbuf1+m_insize, 0, insize); + memset(m_fftbuf2+m_insize, 0, insize); + + int log2n = m_log2n; + + + // do windowing + DoWindowing(log2n, m_fftbuf1, m_fftsize); + DoWindowing(log2n, m_fftbuf2, m_fftsize); + + // do fft +/* #if __VEC__ + ctoz(m_fftbuf1, 2, outbuf1, 1, 1L<<log2n); ctoz(m_fftbuf2, 2, outbuf2, 1, 1L<<log2n); + #else */ + +//in place transform for now + rffts(m_fftbuf1, log2n, 1, cosTable[log2n]); + rffts(m_fftbuf2, log2n, 1, cosTable[log2n]); +//#endif + +//complex multiply time + int numbins = m_fftsize >> 1; //m_fftsize - 2 >> 1; + + float * p1= m_fftbuf1; + float * p2= m_fftbuf2; + + p1[0] *= p2[0]; + p1[1] *= p2[1]; + + //complex multiply + for (int i=1; i<numbins; ++i) { + float real,imag; + int realind,imagind; + realind= 2*i; imagind= realind+1; + real= p1[realind]*p2[realind]- p1[imagind]*p2[imagind]; + imag= p1[realind]*p2[imagind]+ p1[imagind]*p2[realind]; + p1[realind] = real; //p2->bin[i]; + p1[imagind]= imag; + } + + //copy second part from before to overlap + memcpy(m_overlapbuf, m_outbuf+m_insize, m_insize * sizeof(float)); + + //inverse fft into outbuf + memcpy(m_outbuf, m_fftbuf1, m_fftsize * sizeof(float)); + + //in place + riffts(m_outbuf, log2n, 1, cosTable[log2n]); + + DoWindowing(log2n, m_outbuf, m_fftsize); + } + + //write out samples copied from outbuf, with overlap added in + + float *output = out[0]; + float *nout= m_outbuf+m_pos; + float *overlap= m_overlapbuf+m_pos; + + for (int i=0; i<numSamples; ++i) + { + *++output = *++nout + *++overlap; + } + +} + + + + diff --git a/sc4pd/source/Crackle.cpp b/sc4pd/source/Crackle.cpp new file mode 100644 index 0000000..8f6c28f --- /dev/null +++ b/sc4pd/source/Crackle.cpp @@ -0,0 +1,153 @@ +/* sc4pd + Crackle, Crackle~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: David S. Ware: Threads + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Crackle~ -------------------------------*/ + +class Crackle_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(Crackle_ar,sc4pd_dsp); + +public: + Crackle_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_paramf = f; + } + +private: + FLEXT_CALLBACK_F(m_set); + float m_paramf; + float m_y1, m_y2; +}; + +FLEXT_LIB_DSP_V("Crackle~",Crackle_ar); + +Crackle_ar::Crackle_ar(int argc, t_atom *argv) + : m_y1(0.3f),m_y2(0.f) +{ + FLEXT_ADDMETHOD_(0,"parameter",m_set); + //parse arguments + AtomList Args(argc,argv); + m_paramf=sc_getfloatarg(Args,0); + + if (m_paramf == 0) + m_paramf = 1; + + AddOutSignal(); +} + + +void Crackle_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float paramf = m_paramf; + float y1 = m_y1; + float y2 = m_y2; + float y0; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = y0 = fabs(y1 * paramf - y2 - 0.05f); + y2 = y1; + y1 = y0; + } + + m_y1=y1; + m_y2=y2; +} + + +/* ------------------------ Crackle ---------------------------------*/ + +class Crackle_kr: + public flext_base +{ + FLEXT_HEADER(Crackle_kr,flext_base); + +public: + Crackle_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_set(float f) + { + m_paramf = f; + } + +private: + float m_paramf; + float m_y1, m_y2; + FLEXT_CALLBACK(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("Crackle",Crackle_kr); + +Crackle_kr::Crackle_kr(int argc, t_atom *argv) + : m_y1(0.3f),m_y2(0.f) +{ + FLEXT_ADDBANG(0,m_perform); + FLEXT_ADDMETHOD_(0,"parameter",m_set); + + //parse arguments + AtomList Args(argc,argv); + m_paramf=sc_getfloatarg(Args,0); + + if (m_paramf == 0) + m_paramf = 1; + + AddOutFloat(); +} + +void Crackle_kr::m_perform() +{ + float y0 = fabs(m_y1 * m_paramf - m_y2 - 0.05f); + m_y2 = m_y1; + m_y1 = y0; + + ToOutFloat(0,y0); +} diff --git a/sc4pd/source/Decay.cpp b/sc4pd/source/Decay.cpp new file mode 100644 index 0000000..c11a7a8 --- /dev/null +++ b/sc4pd/source/Decay.cpp @@ -0,0 +1,212 @@ +/* sc4pd + Decay~, Decay + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: AMM: AMMMusic 1966 + +*/ + +#include "sc4pd.hpp" + +/* todo: linear interpolation is broken */ +/* ------------------------ Decay~ -----------------------------*/ + +class Decay_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Decay_ar,sc4pd_dsp); + +public: + Decay_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + void m_set(float f); + +private: + FLEXT_CALLBACK_F(m_set); + float m_b1; //leak + float m_y1; //z-1 + float decayTime; +}; + +FLEXT_LIB_DSP_V("Decay~",Decay_ar); + +Decay_ar::Decay_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"decayTime",m_set); + + AtomList Args(argc,argv); + + decayTime = sc_getfloatarg(Args,0); + + AddOutSignal(); + + m_y1 = 0.f; +} + +void Decay_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + float b1 = m_b1; + float y1 = m_y1; + + if (b1 == m_b1) + { + if (b1 == 1.f) + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0 + y1; + } + + } + else if (b1 == 0.f) + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0; + } + } + else + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0 + b1 * y1; + } + } + } + else + { + float b1_slope = CALCSLOPE(m_b1, b1); + if (b1 >= 0.f && m_b1 >= 0) + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0 + b1 * (y1 - y0); + b1 += b1_slope; + } + } + else if (b1 <= 0.f && m_b1 <= 0) + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0 + b1 * (y1 + y0); + b1 += b1_slope; + } + } + else + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = (1.f - fabs(b1)) * y0 + b1 * y1; + b1 += b1_slope; + } + } + } + m_y1 = zapgremlins(y1); +} + +void Decay_ar::m_set(float f) +{ + decayTime = f; + m_b1= f == 0.f ? 0.f : exp(log001 / (decayTime * Samplerate())); +} + +void Decay_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + m_b1= decayTime == 0.f ? 0.f : exp(log001 / (decayTime * Samplerate())); +} + +/* todo: does it make sense to implement a message-based Decay? + Probably not... */ + + +/* ------------------------ Decay ------------------------------*/ + +// class Decay_kr +// :public flext_base +// { +// FLEXT_HEADER(Decay_kr,flext_base); + +// public: +// Decay_kr(int argc,t_atom * argv); + +// protected: +// void m_set(float f); +// void m_perform(float f); + +// private: +// float m_b1; //leak +// float m_y1; //z-1 + +// FLEXT_CALLBACK_F(m_set); +// FLEXT_CALLBACK_F(m_perform); +// }; + +// FLEXT_LIB_V("Decay",Decay_kr); + +// Decay_kr::Decay_kr(int argc,t_atom * argv) +// { +// AtomList Args(argc,argv); + +// m_b1 = sc_getfloatarg(Args,0); +// m_y1 = 0.f; + + +// AddInFloat(); +// AddOutFloat(); + +// FLEXT_ADDMETHOD(0,m_perform); +// FLEXT_ADDMETHOD_(0,"leak",m_set); +// } + +// void Decay_kr::m_perform(float f) +// { +// m_y1 = f + m_y1 * m_b1; +// ToOutFloat(0,m_y1); +// } + +// void Decay_kr::m_set(float f) +// { +// m_b1=f; +// } diff --git a/sc4pd/source/Decay2.cpp b/sc4pd/source/Decay2.cpp new file mode 100644 index 0000000..a78a180 --- /dev/null +++ b/sc4pd/source/Decay2.cpp @@ -0,0 +1,154 @@ +/* sc4pd + Decay2~, Decay2 + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: AMM: AMMMusic 1966 + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ Decay2~ -----------------------------*/ + +class Decay2_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Decay2_ar,sc4pd_dsp); + +public: + Decay2_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + void m_attack(float f); + void m_decay(float f); + +private: + FLEXT_CALLBACK_F(m_decay); + FLEXT_CALLBACK_F(m_attack); + float m_attackTime, m_y1a, m_b1a, n_b1a; + float m_decayTime, m_y1b, m_b1b, n_b1b; + bool changed; +}; + +FLEXT_LIB_DSP_V("Decay2~",Decay2_ar); + +Decay2_ar::Decay2_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"decayTime",m_decay); + FLEXT_ADDMETHOD_(0,"attackTime",m_attack); + + AtomList Args(argc,argv); + + m_decayTime = sc_getfloatarg(Args,1); //decay + m_attackTime = sc_getfloatarg(Args,0);//attack + + AddOutSignal(); + + m_y1a = m_y1b = 0.f; //different than in sc + +} + +void Decay2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + float y1a = m_y1a; + float y1b = m_y1b; + float b1a = m_b1a; + float b1b = m_b1b; + + if(changed) + { + float b1a_slope = CALCSLOPE(n_b1a, b1a); + float b1b_slope = CALCSLOPE(n_b1b, b1b); + m_b1a = n_b1a; + m_b1b = n_b1b; + + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + y1a = y0 + b1a * y1a; + y1b = y0 + b1b * y1b; + + ZXP (nout) = y1a - y1b; + b1a += b1a_slope; + b1b += b1b_slope; + } + changed = false; + } + else + { + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + y1a = y0 + b1a * y1a; + y1b = y0 + b1b * y1b; + + ZXP (nout) = y1a - y1b; + } + } + + m_y1a = zapgremlins(y1a); + m_y1b = zapgremlins(y1b); +} + +void Decay2_ar::m_decay(float f) +{ + m_decayTime = f; + n_b1a = f == 0.f ? 0.f : exp(log001 / (f * Samplerate())); + changed = true; +} + +void Decay2_ar::m_attack(float f) +{ + m_attackTime = f; + n_b1b = f == 0.f ? 0.f : exp(log001 / (f * Samplerate())); + changed = true; +} + +void Decay2_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + m_b1a = m_decayTime == 0.f ? 0.f : exp(log001 / + (m_decayTime * Samplerate())); + m_b1b = m_attackTime == 0.f ? 0.f : exp(log001 / + (m_attackTime * Samplerate())); + changed = false; +} + +/* todo: does it make sense to implement a message-based Decay2? + Probably not... */ + diff --git a/sc4pd/source/DelayC.cpp b/sc4pd/source/DelayC.cpp new file mode 100644 index 0000000..50ab366 --- /dev/null +++ b/sc4pd/source/DelayC.cpp @@ -0,0 +1,287 @@ +/* sc4pd + DelayC~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Tom Cora: Halleluja, Anyway + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class DelayC_ar : private DelayUnit_ar +{ + FLEXT_HEADER(DelayC_ar,DelayUnit_ar); + + DelayC_ar (int argc, t_atom *argv); + ~DelayC_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + changed = false; + DelayUnit_Reset(); + } + + void m_set(float f) + { + m_delaytime=f; + changed = true; + } + +private: + bool changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("DelayC~",DelayC_ar); + +DelayC_ar::DelayC_ar (int argc, t_atom *argv) +{ + + FLEXT_ADDMETHOD_(0,"delaytime",m_set); + + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("2 arguments are needed"); + return; + } + + m_delaytime = sc_getfloatarg(Args,0); + m_maxdelaytime = sc_getfloatarg(Args,1); + + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +DelayC_ar::~DelayC_ar () +{ + DelayUnit_Dtor(); +} + +void DelayC_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + long mask = m_mask; + float d0, d1, d2, d3; + + if (changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + + dlybuf[iwrphase & mask] = ZXP(nin); + if (irdphase0 < 0) + { + ZXP(nout) = 0.f; + } + else + { + if (irdphase1 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + } + else if (irdphase2 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + } + else if (irdphase3 < 0) + { + d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + } + else + { + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + d3 = dlybuf[irdphase3 & mask]; + } + ZXP(nout) = cubicinterp(frac, d0, d1, d2, d3); + } + iwrphase++; + } + m_dsamp = dsamp; + changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + for (int i = 0; i!= n;++i) + { + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + + dlybuf[iwrphase & mask] = ZXP(nin); + if (irdphase0 < 0) + { + ZXP(nout) = 0.f; + } + else + { + if (irdphase1 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + } + else if (irdphase2 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + } + else if (irdphase3 < 0) + { + d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + } + else + { + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + d3 = dlybuf[irdphase3 & mask]; + } + ZXP(nout) = cubicinterp(frac, d0, d1, d2, d3); + } + iwrphase++; + } + } + + m_iwrphase = iwrphase; + + m_numoutput += n; + + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void DelayC_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + long mask = m_mask; + + if (changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + for (int i = 0; i!= n;++i) + { + dlybuf[iwrphase & mask] = ZXP(nin); + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + float d0 = dlybuf[irdphase0 & mask]; + float d1 = dlybuf[irdphase1 & mask]; + float d2 = dlybuf[irdphase2 & mask]; + float d3 = dlybuf[irdphase3 & mask]; + ZXP(nout) = cubicinterp(frac, d0, d1, d2, d3); + iwrphase++; + } + m_dsamp = dsamp; + changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + for (int i = 0; i!= n;++i) + { + dlybuf[iwrphase & mask] = ZXP(nin); + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + float d0 = dlybuf[irdphase0 & mask]; + float d1 = dlybuf[irdphase1 & mask]; + float d2 = dlybuf[irdphase2 & mask]; + float d3 = dlybuf[irdphase3 & mask]; + ZXP(nout) = cubicinterp(frac, d0, d1, d2, d3); + iwrphase++; + } + } + m_iwrphase = iwrphase; +} + +/* todo: DelayC for control rate ? */ diff --git a/sc4pd/source/DelayL.cpp b/sc4pd/source/DelayL.cpp new file mode 100644 index 0000000..46b5458 --- /dev/null +++ b/sc4pd/source/DelayL.cpp @@ -0,0 +1,236 @@ +/* sc4pd + DelayL~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Tom Cora: Halleluja, Anyway + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class DelayL_ar : private DelayUnit_ar +{ + FLEXT_HEADER(DelayL_ar,DelayUnit_ar); + + DelayL_ar (int argc, t_atom *argv); + ~DelayL_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + changed = false; + DelayUnit_Reset(); + } + + void m_set(float f) + { + m_delaytime=f; + changed = true; + } + +private: + bool changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("DelayL~",DelayL_ar); + +DelayL_ar::DelayL_ar (int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"delaytime",m_set); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("2 arguments are needed"); + return; + } + + m_delaytime = sc_getfloatarg(Args,0); + m_maxdelaytime = sc_getfloatarg(Args,1); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +DelayL_ar::~DelayL_ar () +{ + DelayUnit_Dtor(); +} + +void DelayL_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + long mask = m_mask; + + if (changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + + dlybuf[iwrphase & mask] = ZXP(nin); + if (irdphase < 0) + { + ZXP(nout) = 0.f; + } + else if (irdphaseb < 0) + { + float d1 = dlybuf[irdphase & mask]; + ZXP(nout) = d1 - frac * d1; + } + else + { + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + ZXP(nout) = lininterp(frac, d1, d2); + } + iwrphase++; + } + m_dsamp = dsamp; + changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + for (int i = 0; i!= n;++i) + { + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + + dlybuf[iwrphase & mask] = ZXP(nin); + if (irdphase < 0) + { + ZXP(nout) = 0.f; + } + else if (irdphaseb < 0) + { + float d1 = dlybuf[irdphase & mask]; + ZXP(nout) = d1 - frac * d1; + } + else + { + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + ZXP(nout) = lininterp(frac, d1, d2); + } + iwrphase++; + } + } + + m_iwrphase = iwrphase; + + m_numoutput += n; + + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void DelayL_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + long mask = m_mask; + + if (changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + for (int i = 0; i!= n;++i) + { + dlybuf[iwrphase & mask] = ZXP(nin); + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + ZXP(nout) = lininterp(frac, d1, d2); + iwrphase++; + } + m_dsamp = dsamp; + changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + for (int i = 0; i!= n;++i) + { + dlybuf[iwrphase & mask] = ZXP(nin); + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + ZXP(nout) = lininterp(frac, d1, d2); + iwrphase++; + } + + } + m_iwrphase = iwrphase; +} + +/* todo: DelayL for control rate ? */ diff --git a/sc4pd/source/DelayN.cpp b/sc4pd/source/DelayN.cpp new file mode 100644 index 0000000..6bbbb18 --- /dev/null +++ b/sc4pd/source/DelayN.cpp @@ -0,0 +1,238 @@ +/* sc4pd + DelayN~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class DelayN_ar : private DelayUnit_ar +{ + FLEXT_HEADER(DelayN_ar,DelayUnit_ar); + + DelayN_ar (int argc, t_atom *argv); + ~DelayN_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + changed = false; + DelayUnit_Reset(); + } + + void m_set(float f) + { + m_delaytime=f; + changed = true; + } + +private: + bool changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("DelayN~",DelayN_ar); + +DelayN_ar::DelayN_ar (int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"delaytime",m_set); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("2 arguments are needed"); + return; + } + + m_delaytime = sc_getfloatarg(Args,0); + m_maxdelaytime = sc_getfloatarg(Args,1); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +DelayN_ar::~DelayN_ar () +{ + DelayUnit_Dtor(); +} + +void DelayN_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + long mask = m_mask; + + if (changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long irdphase = iwrphase - (long)dsamp; + + dlybuf[iwrphase & mask] = ZXP(nin); + if (irdphase < 0) + { + ZXP(nout) = 0.f; + } + else + { + ZXP(nout) = dlybuf[irdphase & mask]; + } + iwrphase++; + } + m_dsamp = dsamp; + changed = false; + } + else + { + long irdphase = iwrphase - (long)dsamp; + float* dlybuf1 = dlybuf - ZOFF; + float* dlyN = dlybuf1 + m_idelaylen; + long remain = n; + + while (remain) + { + float* dlywr = dlybuf1 + (iwrphase & mask); + float* dlyrd = dlybuf1 + (irdphase & mask); + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + if (irdphase < 0) + { + for (int i = 0; i!= nsmps;++i) + { + ZXP(dlywr) = ZXP(nin); + ZXP(nout) = 0.f; + } + } + else + { + for (int i = 0; i!= nsmps;++i) + { + ZXP(dlywr) = ZXP(nin); + ZXP(nout) = ZXP(dlyrd); + } + } + iwrphase += nsmps; + irdphase += nsmps; + } + } + + m_iwrphase = iwrphase; + + m_numoutput += n; + + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void DelayN_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + long mask = m_mask; + + if (changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + for (int i = 0; i!= n;++i) + { + dlybuf[iwrphase & mask] = ZXP(nin); + dsamp += dsamp_slope; + ++iwrphase; + long irdphase = iwrphase - (long)dsamp; + ZXP(nout) = dlybuf[irdphase & mask]; + } + m_dsamp = dsamp; + changed = false; + } + else + { + long irdphase = iwrphase - (long)dsamp; + float* dlybuf1 = dlybuf - ZOFF; + float* dlyrd = dlybuf1 + (irdphase & mask); + float* dlywr = dlybuf1 + (iwrphase & mask); + float* dlyN = dlybuf1 + m_idelaylen; + long remain = n; + while (remain) + { + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + for (int i = 0; i!= nsmps;++i) + { + ZXP(dlywr) = ZXP(nin); + ZXP(nout) = ZXP(dlyrd); + } + if (dlyrd == dlyN) dlyrd = dlybuf1; + if (dlywr == dlyN) dlywr = dlybuf1; + } + iwrphase += n; + } + m_iwrphase = iwrphase; +} + +/* todo: DelayN for control rate ? */ diff --git a/sc4pd/source/DelayUnit.cpp b/sc4pd/source/DelayUnit.cpp new file mode 100644 index 0000000..bd57f7d --- /dev/null +++ b/sc4pd/source/DelayUnit.cpp @@ -0,0 +1,81 @@ +/* sc4pd + public class for several delay objects + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +void DelayUnit_ar::DelayUnit_AllocDelayLine() +{ + long delaybufsize = (long)ceil(m_maxdelaytime * Samplerate() + 1.f); + delaybufsize = delaybufsize + Blocksize(); + delaybufsize = NEXTPOWEROFTWO(delaybufsize); // round up to next power of two + m_fdelaylen = m_idelaylen = delaybufsize; + + delete[] m_dlybuf; + m_dlybuf = new float[delaybufsize] ; + m_mask = delaybufsize - 1; +} + +void DelayUnit_ar::DelayUnit_Dtor() +{ + delete[] m_dlybuf; +} + +float DelayUnit_ar::CalcDelay(float delaytime) +{ + float next_dsamp = delaytime * Samplerate(); + return sc_clip(next_dsamp, 1.f, m_fdelaylen); +} + +void DelayUnit_ar::DelayUnit_Reset() +{ + m_dlybuf = 0; + + DelayUnit_AllocDelayLine(); + + m_dsamp = CalcDelay(m_delaytime); + + m_numoutput = 0; + m_iwrphase = 0; +} + +void FeedbackDelay_ar::FeedbackDelay_Reset() +{ + DelayUnit_Reset(); + + m_feedbk = CalcFeedback(m_delaytime, m_decaytime); +} diff --git a/sc4pd/source/DelayUnit.hpp b/sc4pd/source/DelayUnit.hpp new file mode 100644 index 0000000..a5951e5 --- /dev/null +++ b/sc4pd/source/DelayUnit.hpp @@ -0,0 +1,67 @@ +/* sc4pd + public class for several delay objects + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: + +*/ + +//#include "sc4pd.hpp" + +class DelayUnit_ar + : public sc4pd_dsp +{ + FLEXT_HEADER(DelayUnit_ar,sc4pd_dsp); + +public: + /* functions */ + void DelayUnit_AllocDelayLine(); + void DelayUnit_Reset(); + float CalcDelay(float delaytime); + void DelayUnit_Dtor(); + + /* data */ + float *m_dlybuf; + float m_dsamp, m_fdelaylen; + float m_delaytime, m_maxdelaytime; + long m_iwrphase, m_idelaylen, m_mask; + long m_numoutput; +}; + +/* todo: a delay for control messages? */ + +class FeedbackDelay_ar : public DelayUnit_ar +{ + FLEXT_HEADER(FeedbackDelay_ar,DelayUnit_ar); + float m_feedbk, m_decaytime; + void FeedbackDelay_Reset(); +}; diff --git a/sc4pd/source/Dust.cpp b/sc4pd/source/Dust.cpp new file mode 100644 index 0000000..f7b27a1 --- /dev/null +++ b/sc4pd/source/Dust.cpp @@ -0,0 +1,188 @@ +/* sc4pd: + Dust, Dust~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Assif Tsahar & Tatsuya Nakatani: Come Sunday +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Dust~ -------------------------------------*/ + +class Dust_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(Dust_ar,sc4pd_dsp); + +public: + Dust_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp (int n,t_signalvec const * insigs, + t_signalvec const * outsigs); + + void m_set(float f) + { + m_density = f; + m_thresh = m_density/Samplerate(); + m_scale = m_thresh > 0.f ? 1.f / m_thresh : 0.f; + } + + void m_seed(int i) + { + rgen.init(i); + } + +private: + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_I(m_seed); + float m_density, m_thresh, m_scale; + RGen rgen; + +}; + +FLEXT_LIB_DSP_V("Dust~",Dust_ar); + +Dust_ar::Dust_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"set",m_set); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + m_density=sc_getfloatarg(Args,0); + + rgen.init(timeseed()); + + + AddOutSignal(); +} + +void Dust_ar::m_dsp(int n,t_signalvec const * insigs, + t_signalvec const * outsigs) +{ + m_thresh = m_density/Samplerate(); + m_scale = m_thresh > 0.f ? 1.f / m_thresh : 0.f; +} + +void Dust_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + RGET; + float thresh = m_thresh; + float scale = m_scale; + + for (int i = 0; i!= n;++i) + { + float z = frand(s1,s2,s3); + if (z < thresh) + (*(nout)++) = z * scale; + else + (*(nout)++) = 0.f; + } + + RPUT; +} + + +/* ------------------------ Dust ---------------------------------------*/ + +class Dust_kr: + public flext_base +{ + FLEXT_HEADER(Dust_kr,flext_base); + +public: + Dust_kr(int argc, t_atom *argv); + +protected: + void m_set(float f); + Timer Dust_timer; + void m_doit(void*); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_density, m_scale; + float mtbt; //medium time between trigger + RGen rgen; + FLEXT_CALLBACK_1(m_set,float); + FLEXT_CALLBACK_T(m_doit); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("Dust",Dust_kr); + +Dust_kr::Dust_kr(int argc, t_atom *argv) + : Dust_timer(false) +{ + FLEXT_ADDMETHOD(0,m_set); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + m_density=sc_getfloatarg(Args,0); + + rgen.init(timeseed()); + AddOutFloat(); + + FLEXT_ADDTIMER(Dust_timer,m_doit); + + m_set(m_density); +} + +void Dust_kr::m_set(float f) +{ + Dust_timer.Reset(); + + if(f==0) + { + return; + } + m_density = f; + mtbt = 1/f*1000; + + Dust_timer.Delay(mtbt * 0.002 * rgen.frand()); +} + +void Dust_kr::m_doit(void*) +{ + ToOutFloat(0,rgen.frand()); + + Dust_timer.Delay(mtbt * 0.002 * rgen.frand()); +} diff --git a/sc4pd/source/Dust2.cpp b/sc4pd/source/Dust2.cpp new file mode 100644 index 0000000..2db7981 --- /dev/null +++ b/sc4pd/source/Dust2.cpp @@ -0,0 +1,188 @@ +/* sc4pd: + Dust2, Dust2~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Herbert Eimert: Epitaph für Aikichi Kuboyama + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Dust2~ -------------------------------------*/ + +class Dust2_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(Dust2_ar,sc4pd_dsp); + +public: + Dust2_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp (int n,t_signalvec const * insigs, + t_signalvec const * outsigs); + + void m_set(float f) + { + m_density = f; + m_thresh = m_density/Samplerate(); + m_scale = m_thresh > 0.f ? 1.f / m_thresh : 0.f; + } + + void m_seed(int i) + { + rgen.init(i); + } + +private: + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_I(m_seed); + float m_density, m_thresh, m_scale; + RGen rgen; + +}; + +FLEXT_LIB_DSP_V("Dust2~",Dust2_ar); + +Dust2_ar::Dust2_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"set",m_set); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + m_density=sc_getfloatarg(Args,0); + + rgen.init(timeseed()); + + AddOutSignal(); +} + +void Dust2_ar::m_dsp(int n,t_signalvec const * insigs, + t_signalvec const * outsigs) +{ + m_thresh = m_density/Samplerate(); + m_scale = m_thresh > 0.f ? 2.f / m_thresh : 0.f; +} + +void Dust2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + RGET; + float thresh = m_thresh; + float scale = m_scale; + + for (int i = 0; i!= n;++i) + { + float z = frand(s1,s2,s3); + if (z < thresh) + (*(nout)++) = z * scale - 1.f; + else + (*(nout)++) = 0.f; + } + + RPUT; +} + + +/* ------------------------ Dust2 ---------------------------------------*/ + +class Dust2_kr: + public flext_base +{ + FLEXT_HEADER(Dust2_kr,flext_base); + +public: + Dust2_kr(int argc, t_atom *argv); + +protected: + void m_set(float f); + Timer Dust2_timer; + void m_doit(void*); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_density, m_scale; + float mtbt; //medium time between trigger + RGen rgen; + FLEXT_CALLBACK_1(m_set,float); + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_T(m_doit); +}; + +FLEXT_LIB_V("Dust2",Dust2_kr); + +Dust2_kr::Dust2_kr(int argc, t_atom *argv) + : Dust2_timer(false) +{ + FLEXT_ADDMETHOD(0,m_set); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + m_density=sc_getfloatarg(Args,0); + + rgen.init(timeseed()); + AddOutFloat(); + + FLEXT_ADDTIMER(Dust2_timer,m_doit); + + m_set(m_density); +} + +void Dust2_kr::m_set(float f) +{ + Dust2_timer.Reset(); + + if(f==0) + { + return; + } + m_density = f; + mtbt = 1/f*1000; + + Dust2_timer.Delay(mtbt * 0.002 * rgen.frand()); +} + +void Dust2_kr::m_doit(void*) +{ + ToOutFloat(0,2*rgen.frand() - 1 ); + + Dust2_timer.Delay(mtbt * 0.002 * rgen.frand()); +} diff --git a/sc4pd/source/ExpRand.cpp b/sc4pd/source/ExpRand.cpp new file mode 100644 index 0000000..a08f6fa --- /dev/null +++ b/sc4pd/source/ExpRand.cpp @@ -0,0 +1,160 @@ +/* sc4pd + ExpRand, ExpRand~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Jim O'Rourke & Loren Mazzacane Connors: In Bern + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ ExpRand~ -------------------------------*/ + +class ExpRand_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(ExpRand_ar,sc4pd_dsp); + +public: + ExpRand_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_sample; + float lo; + float hi; + int sc_n; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("ExpRand~",ExpRand_ar); + +ExpRand_ar::ExpRand_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + + rgen.init(timeseed()); + + AddOutSignal(); +} + +void ExpRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + float ratio = hi / lo; + m_sample = pow(ratio,rgen.frand()) * lo; +} + + +void ExpRand_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float sample = m_sample; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = sample; + } +} + + +/* ------------------------ ExpRand ---------------------------------*/ + +class ExpRand_kr: + public flext_base +{ + FLEXT_HEADER(ExpRand_kr,flext_base); + +public: + ExpRand_kr(int argc, t_atom *argv); + +protected: + void m_loadbang(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float lo; + float hi; + int sc_n; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("ExpRand",ExpRand_kr); + +ExpRand_kr::ExpRand_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + + rgen.init(timeseed()); + + AddOutFloat(); +} + +void ExpRand_kr::m_loadbang() +{ + float ratio = hi / lo; + ToOutFloat(0,pow(ratio,rgen.frand()) * lo); +} diff --git a/sc4pd/source/FOS.cpp b/sc4pd/source/FOS.cpp new file mode 100644 index 0000000..6bd3c26 --- /dev/null +++ b/sc4pd/source/FOS.cpp @@ -0,0 +1,258 @@ +/* sc4pd + FOS, FOS~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Susie Ibarra & Assif Tsahar: Home Cookin' + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ FOS~ -------------------------------*/ + +class FOS_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(FOS_ar,sc4pd_dsp); + +public: + FOS_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + void m_set_a0(float f) + { + next_a0=f; + } + + void m_set_a1(float f) + { + next_a1=f; + } + + void m_set_b1(float f) + { + next_b1=f; + } + + void m_ar() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + } + + void m_kr() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + } + +private: + float next_a0, next_a1, next_b1; + float m_y1, m_a0, m_a1, m_b1; + + DEFSIGCALL (m_signal_fun); + DEFSIGFUN (m_signal_ar); + DEFSIGFUN (m_signal_kr); + + FLEXT_CALLBACK_F(m_set_a0); + FLEXT_CALLBACK_F(m_set_a1); + FLEXT_CALLBACK_F(m_set_b1); + FLEXT_CALLBACK(m_ar); + FLEXT_CALLBACK(m_kr); +}; + +FLEXT_LIB_DSP_V("FOS~",FOS_ar); + +FOS_ar::FOS_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"a0",m_set_a0); + FLEXT_ADDMETHOD_(0,"a1",m_set_a1); + FLEXT_ADDMETHOD_(0,"b1",m_set_b1); + FLEXT_ADDMETHOD_(0,"ar",m_ar); + FLEXT_ADDMETHOD_(0,"kr",m_kr); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count()<3) + { + post("needs at least 3 arguments"); + return; + } + m_a0 = sc_getfloatarg(Args,0); + m_a1 = sc_getfloatarg(Args,1); + m_b1 = sc_getfloatarg(Args,2); + + if(sc_ar(Args)) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + AddInSignal(); + AddInSignal(); + AddInSignal(); + AddInSignal(); + } + else // if not given, use control rate + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + + AddOutSignal(); + + m_y1 = 0.f; + m_a0 = 0.f; + m_a1 = 0.f; + m_b1 = 0.f; +} + +void FOS_ar::m_signal_ar(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + float *a0 = *(in+1); + float *a1 = *(in+2); + float *b1 = *(in+3); + + float y1 = m_y1; + + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin) + ZXP(b1) * y1; + ZXP(nout) = ZXP(a0) * y0 + ZXP(a1) * y1; + y1 = y0; + } + m_y1 = zapgremlins(y1); +} + + +void FOS_ar::m_signal_kr(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float y1 = m_y1; + float a0 = m_a0; + float a1 = m_a1; + float b1 = m_b1; + float a0_slope = CALCSLOPE(next_a0, a0); + float a1_slope = CALCSLOPE(next_a1, a1); + float b1_slope = CALCSLOPE(next_b1, b1); + + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin) + b1 * y1; + ZXP(nout) = a0 * y0 + a1 * y1; + y1 = y0; + + a0 += a0_slope; + a1 += a1_slope; + b1 += b1_slope; + } +} + +/* ------------------------ FOS ---------------------------------*/ + + +class FOS_kr: + public flext_base +{ + FLEXT_HEADER(FOS_kr,flext_base); + +public: + FOS_kr(int argc, t_atom *argv); + +protected: + void m_perform(float f); + + void m_set_a0(float f) + { + m_a0=f; + } + + void m_set_a1(float f) + { + m_a1=f; + } + + void m_set_b1(float f) + { + m_b1=f; + } + + +private: + float m_y1, m_a0, m_a1, m_b1; + + FLEXT_CALLBACK_F(m_set_a0); + FLEXT_CALLBACK_F(m_set_a1); + FLEXT_CALLBACK_F(m_set_b1); + FLEXT_CALLBACK_F(m_perform); +}; + + +FLEXT_LIB_V("FOS",FOS_kr); + +FOS_kr::FOS_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD_(0,"a0",m_set_a0); + FLEXT_ADDMETHOD_(0,"a1",m_set_a1); + FLEXT_ADDMETHOD_(0,"b1",m_set_b1); + + AddOutFloat(); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count()!=3) + { + post("needs 3 arguments"); + return; + } + + m_a0 = sc_getfloatarg(Args,0); + m_a1 = sc_getfloatarg(Args,1); + m_b1 = sc_getfloatarg(Args,2); + + m_y1 = 0.f; + m_a0 = 0.f; + m_a1 = 0.f; + m_b1 = 0.f; +} + +void FOS_kr::m_perform(float f) +{ + m_y1 = m_a0 * (f + m_b1 * m_y1) + m_a1 * m_y1; + ToOutFloat(0,m_y1); +} diff --git a/sc4pd/source/GrayNoise.cpp b/sc4pd/source/GrayNoise.cpp new file mode 100644 index 0000000..b9c3e40 --- /dev/null +++ b/sc4pd/source/GrayNoise.cpp @@ -0,0 +1,143 @@ +/* sc4pd + GrayNoise, GrayNoise~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe: Harsh + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ GrayNoise~ -------------------------------*/ + +class GrayNoise_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(GrayNoise_ar,sc4pd_dsp); + +public: + GrayNoise_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + int m_counter; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("GrayNoise~",GrayNoise_ar); + +GrayNoise_ar::GrayNoise_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + AddOutSignal(); +} + + +void GrayNoise_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + RGET; + int counter = m_counter; + + for (int i = 0; i!= n;++i) + { + counter ^= 1L << (trand(s1,s2,s3) & 31); + (*(nout)++) = counter * 4.65661287308e-10f; + } + + m_counter=counter; + RPUT; +} + + +/* ------------------------ GrayNoise ---------------------------------*/ + +class GrayNoise_kr: + public flext_base +{ + FLEXT_HEADER(GrayNoise_kr,flext_base); + +public: + GrayNoise_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + int m_counter; + RGen rgen; + FLEXT_CALLBACK(m_perform); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("GrayNoise",GrayNoise_kr); + +GrayNoise_kr::GrayNoise_kr(int argc, t_atom *argv) +{ + FLEXT_ADDBANG(0,m_perform); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + AddOutFloat(); +} + +void GrayNoise_kr::m_perform() +{ + m_counter ^= 1L << (rgen.trand() & 31); + m_counter * 4.65661287308e-10f; + ToOutFloat(0,m_counter * 4.65661287308e-10f); +} diff --git a/sc4pd/source/HPF.cpp b/sc4pd/source/HPF.cpp new file mode 100644 index 0000000..85de643 --- /dev/null +++ b/sc4pd/source/HPF.cpp @@ -0,0 +1,180 @@ +/* sc4pd + HPF~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Peter Kowald & Tatsuya Nakatani: + 13 Definitions of Truth + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ HPF~ -------------------------------*/ + +class HPF_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(HPF_ar,sc4pd_dsp); + +public: + HPF_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + } + + void m_set_freq(float f) + { + m_freq=f; + changed = true; + } + +private: + float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq; + bool changed; + float mRadiansPerSample, mFilterSlope; + int mFilterLoops, mFilterRemain; + + FLEXT_CALLBACK_F(m_set_freq); +}; + +FLEXT_LIB_DSP_V("HPF~",HPF_ar); + +HPF_ar::HPF_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + changed = true; + + AddOutSignal(); + + m_a0 = 0.f; + m_b1 = 0.f; + m_b2 = 0.f; + m_y1 = 0.f; + m_y2 = 0.f; +} + +void HPF_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float y0; + float y1 = m_y1; + float y2 = m_y2; + float a0 = m_a0; + float b1 = m_b1; + float b2 = m_b2; + + if (changed) + { + float pfreq = m_freq * mRadiansPerSample * 0.5; + + float C = tan(pfreq); + float C2 = C * C; + float sqrt2C = C * sqrt2; + 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; + + float a0_slope = (next_a0 - a0) * mFilterSlope; + float b1_slope = (next_b1 - b1) * mFilterSlope; + float b2_slope = (next_b2 - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - 2.f * y1 + y2); + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * (y2 - 2.f * y0 + y1); + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * (y1 - 2.f * y2 + y0); + + a0 += a0_slope; + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - 2.f * y1 + y2); + y2 = y1; + y1 = y0; + } + + m_a0 = a0; + m_b1 = b1; + m_b2 = b2; + changed = false; + } + else + { + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - 2.f * y1 + y2); + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * (y2 - 2.f * y0 + y1); + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * (y1 - 2.f * y2 + y0); + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - 2.f * y1 + y2); + y2 = y1; + y1 = y0; + } + } + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + +/* no control rate HPF filter */ diff --git a/sc4pd/source/HPZ1.cpp b/sc4pd/source/HPZ1.cpp new file mode 100644 index 0000000..0ab5f91 --- /dev/null +++ b/sc4pd/source/HPZ1.cpp @@ -0,0 +1,132 @@ +/* sc4pd + HPZ1~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: William Parker: Compassion Seizes Bed-Stuy + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ HPZ1~ -------------------------------*/ + +class HPZ1_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(HPZ1_ar,sc4pd_dsp); + +public: + HPZ1_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + float m_x1; +}; + +FLEXT_LIB_DSP_V("HPZ1~",HPZ1_ar); + +HPZ1_ar::HPZ1_ar(int argc, t_atom *argv) +{ + AddOutSignal(); + + m_x1=0; +} + +void HPZ1_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float x0; + float x1 = m_x1; + + int t = n >> 2; + for (int i = 0; i!= t;++i) + { + x0 = ZXP(nin); + ZXP(nout) = 0.5f * (x0 - x1); + x1 = ZXP(nin); + ZXP(nout) = 0.5f * (x1 - x0); + x0 = ZXP(nin); + ZXP(nout) = 0.5f * (x0 - x1); + x1 = ZXP(nin); + ZXP(nout) = 0.5f * (x1 - x0); + } + + t = n & 3; + for (int i = 0; i!= t;++i) + { + x0 = ZXP(nin); + ZXP(nout) = 0.5f * (x0 - x1); + x1 = x0; + } + m_x1 = x1; +} + +/* ------------------------ HPZ1 -------------------------------*/ + +class HPZ1_kr: + public flext_base +{ + FLEXT_HEADER(HPZ1_kr,flext_base); + +public: + HPZ1_kr(int argc, t_atom *argv); + +protected: + void m_perform (float f); + +private: + float m_x1; + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB_V("HPZ1",HPZ1_kr); + +HPZ1_kr::HPZ1_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + + AddOutFloat(); + + m_x1=0; +} + +void HPZ1_kr::m_perform(float f) +{ + ToOutFloat(0,0.5f * (f - m_x1)); + m_x1=f; +} + diff --git a/sc4pd/source/HPZ2.cpp b/sc4pd/source/HPZ2.cpp new file mode 100644 index 0000000..c561455 --- /dev/null +++ b/sc4pd/source/HPZ2.cpp @@ -0,0 +1,140 @@ +/* sc4pd + HPZ2~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: William Parker: Compassion Seizes Bed-Stuy + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ HPZ2~ -------------------------------*/ + +class HPZ2_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(HPZ2_ar,sc4pd_dsp); + +public: + HPZ2_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mFilterLoops=sc_filterloops(); + mFilterRemain=sc_filterremain(); + } + +private: + float m_x1, m_x2; + int mFilterLoops, mFilterRemain; +}; + +FLEXT_LIB_DSP_V("HPZ2~",HPZ2_ar); + +HPZ2_ar::HPZ2_ar(int argc, t_atom *argv) +{ + AddOutSignal(); + + m_x1=0; + m_x2=0; +} + +void HPZ2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float x0; + float x1 = m_x1; + float x2 = m_x2; + + for (int i = 0; i!=mFilterLoops ;++i) + { + x0 = ZXP(nin); + ZXP(nout) = (x0 - 2.f * x1 + x2) * 0.25f; + x2 = ZXP(nin); + ZXP(nout) = (x2 - 2.f * x0 + x1) * 0.25f; + x1 = ZXP(nin); + ZXP(nout) = (x1 - 2.f * x2 + x0) * 0.25f; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + x0 = ZXP(nin); + ZXP(nout) = (x0 - 2.f * x1 + x2) * 0.25f; + x2 = x1; + x1 = x0; + } + m_x1 = x1; + m_x2 = x2; +} + +/* ------------------------ HPZ2 -------------------------------*/ + +class HPZ2_kr: + public flext_base +{ + FLEXT_HEADER(HPZ2_kr,flext_base); + +public: + HPZ2_kr(int argc, t_atom *argv); + +protected: + void m_perform (float f); + +private: + float m_x1; + float m_x2; + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB_V("HPZ2",HPZ2_kr); + +HPZ2_kr::HPZ2_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + + AddOutFloat(); + + m_x2 = m_x1 = 0; +} + +void HPZ2_kr::m_perform(float f) +{ + ToOutFloat(0,(f - 2.f * m_x1 + m_x2) * 0.25f); + m_x2=m_x1; + m_x1=f; +} + diff --git a/sc4pd/source/Hasher.cpp b/sc4pd/source/Hasher.cpp new file mode 100644 index 0000000..1fc8085 --- /dev/null +++ b/sc4pd/source/Hasher.cpp @@ -0,0 +1,115 @@ +/* sc4pd + Hasher~, Hasher + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Philip Jeck: Stoke + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Hasher~ -----------------------------------*/ + +class Hasher_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Hasher_ar,sc4pd_dsp); + +public: + Hasher_ar(); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); +private: + +}; + +FLEXT_LIB_DSP("Hasher~",Hasher_ar); + +Hasher_ar::Hasher_ar() +{ + AddOutSignal(); +} + +void Hasher_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + int32 *nin = (int32*)*in; + t_sample *nout = *out; + + for (int i = 0; i!= n;++i) + { + union { float f; int i; } u; + int z = (*(nin)++); + u.i = 0x40000000 | ((uint32)Hash(z) >> 9); + (*(nout)++) = u.f -3.f; + } +} + + +/* ------------------------ Hasher ------------------------------------*/ + +class Hasher_kr + :public flext_base +{ + FLEXT_HEADER(Hasher_kr,flext_base); + +public: + Hasher_kr(); + +protected: + void m_perform(float f); + +private: + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB("Hasher",Hasher_kr); + +Hasher_kr::Hasher_kr() +{ + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); +} + +void Hasher_kr::m_perform(float f) +{ + int32 * fi = (int32*) &f; + + union { float f; int i; } u; + int z = *fi; + u.i = 0x40000000 | ((uint32)Hash(z) >> 9); + + ToOutFloat(0,u.f -3.f); +} diff --git a/sc4pd/source/IRand.cpp b/sc4pd/source/IRand.cpp new file mode 100644 index 0000000..8b5c723 --- /dev/null +++ b/sc4pd/source/IRand.cpp @@ -0,0 +1,159 @@ +/* sc4pd + IRand, IRand~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Assif Tsahar: Open Systems + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ IRand~ -------------------------------*/ + +class IRand_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(IRand_ar,sc4pd_dsp); + +public: + IRand_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_sample; + int lo; + int hi; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("IRand~",IRand_ar); + +IRand_ar::IRand_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=int(sc_getfloatarg(Args,0)); + hi=int(sc_getfloatarg(Args,1)); + + rgen.init(timeseed()); + + AddOutSignal(); +} + +void IRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + int range = hi - lo; + m_sample = float(rgen.irand(range) + lo); +} + + +void IRand_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float sample = m_sample; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = sample; + } +} + + +/* ------------------------ IRand ---------------------------------*/ + +class IRand_kr: + public flext_base +{ + FLEXT_HEADER(IRand_kr,flext_base); + +public: + IRand_kr(int argc, t_atom *argv); + +protected: + void m_loadbang(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + int lo; + int hi; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("IRand",IRand_kr); + +IRand_kr::IRand_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=int(sc_getfloatarg(Args,0)); + hi=int(sc_getfloatarg(Args,1)); + + rgen.init(timeseed()); + + AddOutInt(); +} + +void IRand_kr::m_loadbang() +{ + int range = hi - lo; + + ToOutInt(0,rgen.irand(range) + lo); +} diff --git a/sc4pd/source/Impulse.cpp b/sc4pd/source/Impulse.cpp new file mode 100644 index 0000000..86ca165 --- /dev/null +++ b/sc4pd/source/Impulse.cpp @@ -0,0 +1,264 @@ +/* sc4pd + Impulse, Impulse~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: AMM: AMMMusic 1966 + +*/ + +#include "sc4pd.hpp" + +/* todo: implement phase offset as in sc3 +/* ------------------------ Impulse~ -------------------------------*/ + +class Impulse_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(Impulse_ar,sc4pd_dsp); + +public: + Impulse_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_freq=f; + } + + void m_ar() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + } + + void m_kr() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + } + +private: + double mPhase, mPhaseOffset; + float mFreqMul; + float m_freq; //for kr arguments + + DEFSIGCALL (m_signal_fun); + DEFSIGFUN (m_signal_ar); + DEFSIGFUN (m_signal_kr); + + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK(m_ar); + FLEXT_CALLBACK(m_kr); +}; + +FLEXT_LIB_DSP_V("Impulse~",Impulse_ar); + +Impulse_ar::Impulse_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"freq",m_set); + FLEXT_ADDMETHOD_(0,"ar",m_ar); + FLEXT_ADDMETHOD_(0,"kr",m_kr); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + if(sc_ar(Args)) + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + else // if not given, use control rate + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + + AddOutSignal(); +} + +void Impulse_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + mFreqMul = 1 / Samplerate(); + +} + +void Impulse_ar::m_signal_ar(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *freq = *in; + t_sample *xout = *out; + + float freqmul = mFreqMul; + double phase = mPhase; + + for (int i = 0; i!= n;++i) + { + float z; + if (phase >= 1.f) + { + phase -= 1.f; + z = 1.f; + } + else + { + z = 0.f; + } + phase += (*(freq)++) * freqmul; + (*(xout)++) = z; + } + + mPhase=phase; +} + + +void Impulse_ar::m_signal_kr(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *xout = *out; + + float freq = m_freq * mFreqMul; + float freqmul = mFreqMul; + double phase = mPhase; + + for (int i = 0; i!= n;++i) + { + float z; + if (phase >= 1.f) + { + phase -= 1.f; + z = 1.f; + } + else + { + z = 0.f; + } + phase += freq; + (*(xout)++) = z; + } + + mPhase=phase; +} + +/* ------------------------ Impulse ---------------------------------*/ + +/* todo: remove obsolete messages */ + +class Impulse_kr: + public flext_base +{ + FLEXT_HEADER(Impulse_kr,flext_base); + +public: + Impulse_kr(int argc, t_atom *argv); + +protected: + void m_perform(void*); + + void m_set(float f) + { + m_freq_set = f; + m_freq = f * mFreqMul; + } + + void m_set_kr(float f) + { + if (f != 0) + { + dt = f * 0.001; + mFreqMul = dt; + m_freq = m_freq_set * mFreqMul; + m_timer.Reset(); + m_timer.Periodic(dt); + } + } + +private: + + double mPhase, mPhaseOffset; + float mFreqMul; + float m_freq; //for kr arguments + + float dt; + float m_freq_set; + + Timer m_timer; + + FLEXT_CALLBACK_F(m_set_kr); + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_T(m_perform); +}; + + +FLEXT_LIB_V("Impulse",Impulse_kr); + +Impulse_kr::Impulse_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_set); + FLEXT_ADDMETHOD_(0,"kr",m_set_kr); + + FLEXT_ADDTIMER(m_timer,m_perform); + + AddOutFloat(); + + //parse arguments + AtomList Args(argc,argv); + + m_freq_set = sc_getfloatarg(Args,0); + + dt = sc_getfloatarg(Args,1) * 0.001; + + if (dt == 0) + dt = 0.02; // 20 ms as default control rate as in line + mFreqMul = dt; + + m_freq = m_freq_set * mFreqMul; + + m_timer.Periodic(dt); + +} + +void Impulse_kr::m_perform(void*) +{ + float z; + if (mPhase >= 1.f) + { + mPhase -= 1.f; + z = 1.f; + } + else + { + z = 0.f; + } + + mPhase += m_freq; + ToOutFloat(0,z); +} diff --git a/sc4pd/source/Integrator.cpp b/sc4pd/source/Integrator.cpp new file mode 100644 index 0000000..85253ee --- /dev/null +++ b/sc4pd/source/Integrator.cpp @@ -0,0 +1,199 @@ +/* sc4pd + Integrator~, Integrator + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: AMM: AMMMusic 1966 + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Integrator~ -----------------------------*/ + +class Integrator_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Integrator_ar,sc4pd_dsp); + +public: + Integrator_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + void m_set(float f); + +private: + FLEXT_CALLBACK_F(m_set); + float m_b1; //leak + float m_y1; //z-1 +}; + +FLEXT_LIB_DSP_V("Integrator~",Integrator_ar); + +Integrator_ar::Integrator_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"leak",m_set); + + AtomList Args(argc,argv); + + m_b1 = sc_getfloatarg(Args,0); + + AddOutSignal(); + + m_y1 = 0.f; +} + +void Integrator_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + float b1 = m_b1; + float y1 = m_y1; + + if (b1 == m_b1) + { + if (b1 == 1.f) + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0 + y1; + } + + } + else if (b1 == 0.f) + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0; + } + } + else + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0 + b1 * y1; + } + } + } + else + { + float b1_slope = CALCSLOPE(m_b1, b1); + if (b1 >= 0.f && m_b1 >= 0) + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0 + b1 * (y1 - y0); + b1 += b1_slope; + } + } + else if (b1 <= 0.f && m_b1 <= 0) + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0 + b1 * (y1 + y0); + b1 += b1_slope; + } + } + else + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = (1.f - fabs(b1)) * y0 + b1 * y1; + b1 += b1_slope; + } + } + } + m_y1 = zapgremlins(y1); +} + +void Integrator_ar::m_set(float f) +{ + m_b1=f; +} + +/* ------------------------ Integrator ------------------------------*/ + +class Integrator_kr + :public flext_base +{ + FLEXT_HEADER(Integrator_kr,flext_base); + +public: + Integrator_kr(int argc,t_atom * argv); + +protected: + void m_set(float f); + void m_perform(float f); + +private: + float m_b1; //leak + float m_y1; //z-1 + + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB_V("Integrator",Integrator_kr); + +Integrator_kr::Integrator_kr(int argc,t_atom * argv) +{ + AtomList Args(argc,argv); + + m_b1 = sc_getfloatarg(Args,0); + m_y1 = 0.f; + + + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD_(0,"leak",m_set); +} + +void Integrator_kr::m_perform(float f) +{ + m_y1 = f + m_y1 * m_b1; + ToOutFloat(0,m_y1); +} + +void Integrator_kr::m_set(float f) +{ + m_b1=f; +} diff --git a/sc4pd/source/LFClipNoise.cpp b/sc4pd/source/LFClipNoise.cpp new file mode 100644 index 0000000..1583431 --- /dev/null +++ b/sc4pd/source/LFClipNoise.cpp @@ -0,0 +1,195 @@ +/* sc4pd + LFClipNoise, LFClipNoise~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Elliott Sharp: Revenge Of The Stuttering Child + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFClipNoise~ -------------------------------*/ + +class LFClipNoise_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFClipNoise_ar,sc4pd_dsp); + +public: + LFClipNoise_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + m_freq = f; + } + +private: + RGen rgen; + float m_freq; + float m_level; + int m_counter; + int m_sr; + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("LFClipNoise~",LFClipNoise_ar); + +LFClipNoise_ar::LFClipNoise_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + m_counter=0; + m_level=0; + + rgen.init(timeseed()); + + AddOutSignal(); +} + +void LFClipNoise_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + m_sr = Samplerate(); +} + + +void LFClipNoise_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float level = m_level; + int32 counter = m_counter; + + RGET; + + int remain = n; + do + { + if (counter<=0) + { + counter = (int)(m_sr / sc_max(m_freq, .001f)); + counter = sc_max(1, counter); + level = fcoin(s1,s2,s3); + } + int nsmps = sc_min(remain, counter); + remain -= nsmps; + counter -= nsmps; + + for (int i = 0; i!= nsmps;++i) + { + (*(nout)++)=level; + } + } + while(remain); + + m_level = level; + m_counter = counter; + + RPUT; +} + + +/* ------------------------ LFClipNoise ---------------------------------*/ + +class LFClipNoise_kr: + public flext_base +{ + FLEXT_HEADER(LFClipNoise_kr,flext_base); + +public: + LFClipNoise_kr(int argc, t_atom *argv); + +protected: + void m_perform(void*); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + double dt = sc_max(1/f, .001f); + m_timer.Reset(); + m_timer.Periodic(dt); + } + +private: + RGen rgen; + Timer m_timer; + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_T(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("LFClipNoise",LFClipNoise_kr); + +LFClipNoise_kr::LFClipNoise_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + FLEXT_ADDTIMER(m_timer,m_perform); + + //parse arguments + AtomList Args(argc,argv); + + double dt = sc_max(1/sc_getfloatarg(Args,0), .001f); + + rgen.init(timeseed()); + + m_timer.Periodic(dt); + + AddOutFloat(); +} + +void LFClipNoise_kr::m_perform(void*) +{ + ToOutFloat(0,rgen.fcoin()); +} diff --git a/sc4pd/source/LFDNoise0.cpp b/sc4pd/source/LFDNoise0.cpp new file mode 100644 index 0000000..316b5a4 --- /dev/null +++ b/sc4pd/source/LFDNoise0.cpp @@ -0,0 +1,166 @@ +/* sc4pd + LFDNoise0~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + * + * DynNoiseUGens.cpp + * xSC3plugins + * + * Created by Alberto de Campo, Sekhar Ramacrishnan, Julian Rohrhuber on Sun May 30 2004. + * Copyright (c) 2004 HfbK. All rights reserved. + * + * + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phil Minton & Veryan Weston: Ways Past + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFDNoise0~ -------------------------------*/ + +class LFDNoise0_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFDNoise0_ar,sc4pd_dsp); + +public: + LFDNoise0_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + m_freq = f; + } + +private: + RGen rgen; + float m_freq; + float m_level; + float m_phase; + float m_smpdur; + + bool m_ar; + + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("LFDNoise0~",LFDNoise0_ar); + +LFDNoise0_ar::LFDNoise0_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + m_phase=0.f; + m_level=0.f; + + rgen.init(timeseed()); + + m_ar = sc_ar(Args); + + if (m_ar) + AddInSignal("freqency"); + else + AddInSignal("\"set\" frequency"); + AddOutSignal(); +} + +void LFDNoise0_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + m_smpdur = sc_sampledur(); +} + + +void LFDNoise0_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float level = m_level; + float phase = m_phase; + + RGET; + + if (m_ar) + { + t_sample *nin = *in; + float smpdur = m_smpdur; + for (int i = 0; i!= n; ++i) + { + phase -= ZXP(nin) * smpdur; + if (phase <= 0) + { + phase = sc_wrap(phase, 0.f, 1.f); + level = frand2(s1,s2,s3); + } + ZXP(nout) = level; + } + } + else + { + float dphase = m_smpdur * m_freq; + for (int i = 0; i!= n; ++i) + { + phase -= dphase; + if (phase <= 0) + { + phase = sc_wrap(phase, 0.f, 1.f); + level = frand2(s1,s2,s3); + } + ZXP(nout) = level; + } + } + + + m_level = level; + m_phase = phase; + + RPUT; +} + + diff --git a/sc4pd/source/LFDNoise1.cpp b/sc4pd/source/LFDNoise1.cpp new file mode 100644 index 0000000..8336b80 --- /dev/null +++ b/sc4pd/source/LFDNoise1.cpp @@ -0,0 +1,172 @@ +/* sc4pd + LFDNoise1~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + * + * DynNoiseUGens.cpp + * xSC3plugins + * + * Created by Alberto de Campo, Sekhar Ramacrishnan, Julian Rohrhuber on Sun May 30 2004. + * Copyright (c) 2004 HfbK. All rights reserved. + * + * + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phil Minton & Veryan Weston: Ways Past + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFDNoise1~ -------------------------------*/ + +class LFDNoise1_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFDNoise1_ar,sc4pd_dsp); + +public: + LFDNoise1_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + m_freq = f; + } + +private: + RGen rgen; + float m_freq; + float m_prevlevel; + float m_nextlevel; + float m_phase; + float m_smpdur; + + bool m_ar; + + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("LFDNoise1~",LFDNoise1_ar); + +LFDNoise1_ar::LFDNoise1_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + rgen.init(timeseed()); + + m_phase=0.f; + m_prevlevel=0.f; + m_nextlevel = rgen.frand2(); + + + m_ar = sc_ar(Args); + + if (m_ar) + AddInSignal("freqency"); + else + AddInSignal("\"set\" frequency"); + AddOutSignal(); +} + +void LFDNoise1_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + m_smpdur = sc_sampledur(); +} + + +void LFDNoise1_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float prevLevel = m_prevlevel; + float nextLevel = m_nextlevel; + float phase = m_phase; + + RGET; + + if (m_ar) + { + t_sample *nin = *in; + float smpdur = m_smpdur; + for (int i = 0; i!= n; ++i) + { + phase -= ZXP(nin) * smpdur; + if (phase <= 0) + { + phase = sc_wrap(phase, 0.f, 1.f); + prevLevel = nextLevel; + nextLevel = frand2(s1,s2,s3); + } + ZXP(nout) = nextLevel + ( phase * (prevLevel - nextLevel) ); + } + } + else + { + float dphase = m_smpdur * m_freq; + for (int i = 0; i!= n; ++i) + { + phase -= dphase; + if (phase <= 0) + { + phase = sc_wrap(phase, 0.f, 1.f); + prevLevel = nextLevel; + nextLevel = frand2(s1,s2,s3); + } + ZXP(nout) = nextLevel + ( phase * (prevLevel - nextLevel) ); + } + } + + m_prevlevel = prevLevel; + m_nextlevel = nextLevel; + m_phase = phase; + + RPUT; +} + + diff --git a/sc4pd/source/LFDNoise2.cpp b/sc4pd/source/LFDNoise2.cpp new file mode 100644 index 0000000..136b1c9 --- /dev/null +++ b/sc4pd/source/LFDNoise2.cpp @@ -0,0 +1,188 @@ +/* sc4pd + LFDNoise2~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + * + * DynNoiseUGens.cpp + * xSC3plugins + * + * Created by Alberto de Campo, Sekhar Ramacrishnan, Julian Rohrhuber on Sun May 30 2004. + * Copyright (c) 2004 HfbK. All rights reserved. + * + * + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phil Minton & Veryan Weston: Ways Past + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFDNoise2~ -------------------------------*/ + +class LFDNoise2_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFDNoise2_ar,sc4pd_dsp); + +public: + LFDNoise2_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + m_freq = f; + } + +private: + RGen rgen; + float m_freq; + float m_levela, m_levelb, m_levelc, m_leveld; + float m_phase; + float m_smpdur; + + bool m_ar; + + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("LFDNoise2~",LFDNoise2_ar); + +LFDNoise2_ar::LFDNoise2_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + rgen.init(timeseed()); + + RGET; + + m_phase=0.f; + m_levela = frand2(s1, s2, s3) * 0.8f;// limits max interpol. overshoot to 1. + m_levelb = frand2(s1, s2, s3) * 0.8f; + m_levelc = frand2(s1, s2, s3) * 0.8f; + m_leveld = frand2(s1, s2, s3) * 0.8f; + + RPUT; + + m_ar = sc_ar(Args); + + if (m_ar) + AddInSignal("freqency"); + else + AddInSignal("\"set\" frequency"); + AddOutSignal(); +} + +void LFDNoise2_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + m_smpdur = sc_sampledur(); +} + + +void LFDNoise2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float a = m_levela; + float b = m_levelb; + float c = m_levelc; + float d = m_leveld; + + float phase = m_phase; + + RGET; + + if (m_ar) + { + t_sample *nin = *in; + float smpdur = m_smpdur; + for (int i = 0; i!= n; ++i) + { + phase -= ZXP(nin) * smpdur; + if (phase <= 0) + { + phase = sc_wrap(phase, 0.f, 1.f); + a = b; + b = c; + c = d; + d = frand2(s1,s2,s3) * 0.8f; // limits max interpol. overshoot to 1. + + } + ZXP(nout) = cubicinterp(1.f - phase, a, b, c, d); + } + } + else + { + float dphase = m_smpdur * m_freq; + for (int i = 0; i!= n; ++i) + { + phase -= dphase; + if (phase <= 0) + { + phase = sc_wrap(phase, 0.f, 1.f); + a = b; + b = c; + c = d; + d = frand2(s1,s2,s3) * 0.8f; // limits max interpol. overshoot to 1. + } + ZXP(nout) = cubicinterp(1.f - phase, a, b, c, d); + } + } + + + m_phase = phase; + + m_levela = a; + m_levelb = b; + m_levelc = c; + m_leveld = d; + + RPUT; +} + + diff --git a/sc4pd/source/LFNoise0.cpp b/sc4pd/source/LFNoise0.cpp new file mode 100644 index 0000000..9ee9ff6 --- /dev/null +++ b/sc4pd/source/LFNoise0.cpp @@ -0,0 +1,195 @@ +/* sc4pd + LFNoise0, LFNoise0~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Elliott Sharp: Revenge Of The Stuttering Child + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFNoise0~ -------------------------------*/ + +class LFNoise0_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFNoise0_ar,sc4pd_dsp); + +public: + LFNoise0_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + m_freq = f; + } + +private: + RGen rgen; + float m_freq; + float m_level; + int m_counter; + int m_sr; + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("LFNoise0~",LFNoise0_ar); + +LFNoise0_ar::LFNoise0_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + m_counter=0; + m_level=0; + + rgen.init(timeseed()); + + AddOutSignal(); +} + +void LFNoise0_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + m_sr = Samplerate(); +} + + +void LFNoise0_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float level = m_level; + int32 counter = m_counter; + + RGET; + + int remain = n; + do + { + if (counter<=0) + { + counter = (int)(m_sr / sc_max(m_freq, .001f)); + counter = sc_max(1, counter); + level = frand2(s1,s2,s3); + } + int nsmps = sc_min(remain, counter); + remain -= nsmps; + counter -= nsmps; + + for (int i = 0; i!= nsmps;++i) + { + (*(nout)++)=level; + } + } + while(remain); + + m_level = level; + m_counter = counter; + + RPUT; +} + + +/* ------------------------ LFNoise0 ---------------------------------*/ + +class LFNoise0_kr: + public flext_base +{ + FLEXT_HEADER(LFNoise0_kr,flext_base); + +public: + LFNoise0_kr(int argc, t_atom *argv); + +protected: + void m_perform(void*); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + double dt = sc_max(1/f, .001f); + m_timer.Reset(); + m_timer.Periodic(dt); + } + +private: + RGen rgen; + Timer m_timer; + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_T(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("LFNoise0",LFNoise0_kr); + +LFNoise0_kr::LFNoise0_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + FLEXT_ADDTIMER(m_timer,m_perform); + + //parse arguments + AtomList Args(argc,argv); + + double dt = sc_max(1/sc_getfloatarg(Args,0), .001f); + + rgen.init(timeseed()); + + m_timer.Periodic(dt); + + AddOutFloat(); +} + +void LFNoise0_kr::m_perform(void*) +{ + ToOutFloat(0,rgen.frand2()); +} diff --git a/sc4pd/source/LFNoise1.cpp b/sc4pd/source/LFNoise1.cpp new file mode 100644 index 0000000..c164942 --- /dev/null +++ b/sc4pd/source/LFNoise1.cpp @@ -0,0 +1,232 @@ +/* sc4pd + LFNoise1, LFNoise1~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Fred Frith: Gravity + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFNoise1~ -------------------------------*/ + +class LFNoise1_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFNoise1_ar,sc4pd_dsp); + +public: + LFNoise1_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + m_freq = f; + } + +private: + RGen rgen; + float m_freq; + float m_level; + float m_slope; + int m_counter; + int m_sr; + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("LFNoise1~",LFNoise1_ar); + +LFNoise1_ar::LFNoise1_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + rgen.init(timeseed()); + + m_counter=0; + m_level=rgen.frand2(); + m_slope=0; + + AddOutSignal(); +} + +void LFNoise1_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + m_sr = Samplerate(); +} + + +void LFNoise1_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float level = m_level; + int32 counter = m_counter; + float slope = m_slope; + + RGET; + + int remain = n; + do + { + if (counter<=0) + { + counter = (int)(m_sr / sc_max(m_freq, .001f)); + counter = sc_max(1, counter); + float nextlevel = frand2(s1,s2,s3); + slope = (nextlevel - level) / counter; + } + int nsmps = sc_min(remain, counter); + remain -= nsmps; + counter -= nsmps; + + for (int i = 0; i!= nsmps;++i) + { + (*(nout)++)=level; + level+=slope; + } + } + while(remain); + + m_level = level; + m_counter = counter; + m_slope = slope; + + RPUT; +} + + +/* ------------------------ LFNoise1 ---------------------------------*/ + +class LFNoise1_kr: + public flext_base +{ + FLEXT_HEADER(LFNoise1_kr,flext_base); + +public: + LFNoise1_kr(int argc, t_atom *argv); + +protected: + void m_perform(void*); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float); + +private: + RGen rgen; + float m_level; + float m_slope; + + float dt; //in s + float tick; //in s + int counter; + + Timer m_timer; + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_T(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("LFNoise1",LFNoise1_kr); + +LFNoise1_kr::LFNoise1_kr(int argc, t_atom *argv) + : tick(0.01) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + FLEXT_ADDTIMER(m_timer,m_perform); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + m_level=rgen.frand2(); + + AddOutFloat(); + + m_set(sc_getfloatarg(Args,0)); +} + +void LFNoise1_kr::m_set(float f) +{ + dt = sc_max(1/f, .001f); + counter = (dt/tick); + + float nextlevel = rgen.frand2(); + m_slope = (nextlevel - m_level) / counter; + + m_timer.Reset(); + m_timer.Delay(tick); +} + +void LFNoise1_kr::m_perform(void*) +{ + m_level+=m_slope; + ToOutFloat(0,m_level); + if (--counter) + { + m_timer.Reset(); + m_timer.Delay(tick); + } + else + { + counter = (dt/tick); + float nextlevel = rgen.frand2(); + m_slope = (nextlevel - m_level) / counter; + + m_timer.Reset(); + m_timer.Delay(tick); + + } +} diff --git a/sc4pd/source/LFNoise2.cpp b/sc4pd/source/LFNoise2.cpp new file mode 100644 index 0000000..3b1fd37 --- /dev/null +++ b/sc4pd/source/LFNoise2.cpp @@ -0,0 +1,271 @@ +/* sc4pd + LFNoise2, LFNoise2~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Guenther Mueller & Toshimaru Nakamura: Tint + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFNoise2~ -------------------------------*/ + +class LFNoise2_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFNoise2_ar,sc4pd_dsp); + +public: + LFNoise2_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + m_freq = f; + } + +private: + RGen rgen; + float m_freq; + float m_level; + float m_slope; + float m_curve; + int m_counter; + int m_sr; + float m_nextvalue; + float m_nextmidpt; + + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("LFNoise2~",LFNoise2_ar); + +LFNoise2_ar::LFNoise2_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + rgen.init(timeseed()); + + m_counter=0; + m_level=rgen.frand2(); + m_slope=0; + m_curve=0; + m_nextvalue=0; + m_nextmidpt=0; + + AddOutSignal(); +} + +void LFNoise2_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + m_sr = Samplerate(); +} + + +void LFNoise2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float level = m_level; + int32 counter = m_counter; + float slope = m_slope; + float curve = m_curve; + + RGET; + + int remain = n; + do + { + if (counter<=0) + { + float value = m_nextvalue; + m_nextvalue = frand2(s1,s2,s3); + level = m_nextmidpt; + m_nextmidpt = (m_nextvalue + value) * .5; + + counter = (int32)(m_sr / sc_max(m_freq, .001f)); + counter = sc_max(2, counter); + float fseglen = (float)counter; + curve = 2.f * (m_nextmidpt - level - fseglen * slope) + / (fseglen * fseglen + fseglen); + } + int nsmps = sc_min(remain, counter); + remain -= nsmps; + counter -= nsmps; + + for (int i = 0; i!= nsmps;++i) + { + (*(nout)++)=level; + slope+=curve; + level+=slope; + } + } + while(remain); + + m_level = level; + m_counter = counter; + m_slope = slope; + m_curve = curve; + + RPUT; +} + + +/* ------------------------ LFNoise2 ---------------------------------*/ + +class LFNoise2_kr: + public flext_base +{ + FLEXT_HEADER(LFNoise2_kr,flext_base); + +public: + LFNoise2_kr(int argc, t_atom *argv); + +protected: + void m_perform(void*); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float); + +private: + RGen rgen; + float m_level; + float m_slope; + float m_curve; + float m_nextvalue; + float m_nextmidpt; + + float dt; //in s + float tick; //in s + int counter; + + Timer m_timer; + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_T(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("LFNoise2",LFNoise2_kr); + +LFNoise2_kr::LFNoise2_kr(int argc, t_atom *argv) + : tick(0.01) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + FLEXT_ADDTIMER(m_timer,m_perform); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + m_level=rgen.frand2(); + + AddOutFloat(); + + m_set(sc_getfloatarg(Args,0)); +} + + +void LFNoise2_kr::m_set(float f) +{ + dt = sc_max(1/f, .001f); + counter = (dt/tick); + counter = sc_max(2, counter); + + float value = m_nextvalue; + m_nextvalue = rgen.frand2(); + m_level = m_nextmidpt; + m_nextmidpt = (m_nextvalue + value) * .5; + + float fseglen = (float)counter; + m_curve = 2.f * (m_nextmidpt - m_level - fseglen * m_slope) + / (fseglen * fseglen + fseglen); + + + m_timer.Reset(); + m_timer.Delay(tick); +} + +void LFNoise2_kr::m_perform(void*) +{ + m_slope+=m_curve; + m_level+=m_slope; + ToOutFloat(0,m_level); + if (--counter) + { + m_timer.Reset(); + m_timer.Delay(tick); + } + else + { + counter = (dt/tick); + + counter = sc_max(2, counter); + + float value = m_nextvalue; + m_nextvalue = rgen.frand2(); + m_level = m_nextmidpt; + m_nextmidpt = (m_nextvalue + value) * .5; + + float fseglen = (float)counter; + m_curve = 2.f * (m_nextmidpt - m_level - fseglen * m_slope) / + (fseglen * fseglen + fseglen); + + m_timer.Reset(); + m_timer.Delay(tick); + + } +} + diff --git a/sc4pd/source/LFPulse.cpp b/sc4pd/source/LFPulse.cpp new file mode 100644 index 0000000..ad16e65 --- /dev/null +++ b/sc4pd/source/LFPulse.cpp @@ -0,0 +1,292 @@ +/* sc4pd + LFPulse, LFPulse~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & Oren Ambarchi: Flypaper + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFPulse~ -------------------------------*/ + +class LFPulse_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFPulse_ar,sc4pd_dsp); + +public: + LFPulse_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_freq=f; + } + + void m_ar() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + } + + void m_kr() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + } + + void m_width (float f) + { + nextDuty = f; + } + + +private: + double mPhase; + float mFreqMul; + float m_freq; //for kr arguments + float mDuty; + float nextDuty; + + DEFSIGCALL (m_signal_fun); + DEFSIGFUN (m_signal_ar); + DEFSIGFUN (m_signal_kr); + + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_F(m_width); + FLEXT_CALLBACK(m_ar); + FLEXT_CALLBACK(m_kr); +}; + +FLEXT_LIB_DSP_V("LFPulse~",LFPulse_ar); + +LFPulse_ar::LFPulse_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"freq",m_set); + FLEXT_ADDMETHOD_(0,"width",m_width); + FLEXT_ADDMETHOD_(0,"ar",m_ar); + FLEXT_ADDMETHOD_(0,"kr",m_kr); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + nextDuty = sc_getfloatarg(Args,1); + + if(sc_ar(Args)) + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + else // if not given, use control rate + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + + AddOutSignal(); +} + +void LFPulse_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + mFreqMul = 1 / Samplerate(); + +} + +void LFPulse_ar::m_signal_ar(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *freq = *in; + t_sample *xout = *out; + + float freqmul = mFreqMul; + double phase = mPhase; + float duty = mDuty; + + for (int i = 0; i!= n;++i) + { + float z; + if (phase >= 1.f) + { + phase -= 1.f; + duty = mDuty = nextDuty; + // output at least one sample from the opposite polarity + z = duty < 0.5 ? 1.f : 0.f; + } + else + { + z = phase < duty ? 1.f : 0.f; + } + + phase += (*(freq)++) * freqmul; + (*(xout)++) = z; + } + + mPhase=phase; +} + + +void LFPulse_ar::m_signal_kr(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *xout = *out; + + double phase = mPhase; + float duty = mDuty; + float freq = m_freq * mFreqMul; + + for (int i = 0; i!= n;++i) + { + float z; + if (phase >= 1.f) + { + phase -= 1.f; + duty = mDuty = nextDuty; + // output at least one sample from the opposite polarity + z = duty < 0.5 ? 1.f : 0.f; + } + else + { + z = phase < duty ? 1.f : 0.f; + } + + phase += freq; + (*(xout)++) = z; + } + mPhase=phase; +} + +/* ------------------------ LFPulse ---------------------------------*/ + +/* todo: remove obsolete messages */ + +class LFPulse_kr: + public flext_base +{ + FLEXT_HEADER(LFPulse_kr,flext_base); + +public: + LFPulse_kr(int argc, t_atom *argv); + +protected: + void m_perform(void*); + + void m_set(float f) + { + m_freq_set = f; + m_freq = f * mFreqMul; + } + + void m_set_kr(float f) + { + if (f != 0) + { + dt = f * 0.001; + mFreqMul = dt; + m_freq = m_freq_set * mFreqMul; + m_timer.Reset(); + m_timer.Periodic(dt); + } + } + + void m_set_width(float f) + { + nextDuty=f; + } + +private: + double mPhase; + float mFreqMul; + float mDuty; + float nextDuty; + float m_freq; + float dt; + float m_freq_set; + + Timer m_timer; + + FLEXT_CALLBACK_F(m_set_kr); + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_F(m_set_width); + FLEXT_CALLBACK_T(m_perform); +}; + + +FLEXT_LIB_V("LFPulse",LFPulse_kr); + +LFPulse_kr::LFPulse_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_set); + FLEXT_ADDMETHOD_(0,"kr",m_set_kr); + FLEXT_ADDMETHOD_(0,"width",m_set_width); + + FLEXT_ADDTIMER(m_timer,m_perform); + + AddOutFloat(); + + //parse arguments + AtomList Args(argc,argv); + + m_freq_set = sc_getfloatarg(Args,0); + + nextDuty = sc_getfloatarg(Args,1); + + dt = sc_getfloatarg(Args,2) * 0.001; + + if (dt == 0) + dt = 0.02; // 20 ms as default control rate as in line + mFreqMul = dt; + + m_freq = m_freq_set * mFreqMul; + + m_timer.Periodic(dt); + +} + +void LFPulse_kr::m_perform(void*) +{ + float z; + if (mPhase >= 1.f) + { + mPhase -= 1.f; + mDuty = nextDuty; + // output at least one sample from the opposite polarity + z = mDuty < 0.5 ? 1.f : 0.f; + } + else + { + z = mPhase < mDuty ? 1.f : 0.f; + } + mPhase += m_freq; + ToOutFloat(0,z); +} diff --git a/sc4pd/source/LFSaw.cpp b/sc4pd/source/LFSaw.cpp new file mode 100644 index 0000000..0e406d0 --- /dev/null +++ b/sc4pd/source/LFSaw.cpp @@ -0,0 +1,256 @@ +/* sc4pd + LFSaw, LFSaw~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & Oren Ambarchi: Flypaper + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFSaw~ -------------------------------*/ + +class LFSaw_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFSaw_ar,sc4pd_dsp); + +public: + LFSaw_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_freq=f; + } + + void m_ar() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + } + + void m_kr() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + } + +private: + double mPhase; + float mFreqMul; + float m_freq; //for kr arguments + + DEFSIGCALL (m_signal_fun); + DEFSIGFUN (m_signal_ar); + DEFSIGFUN (m_signal_kr); + + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK(m_ar); + FLEXT_CALLBACK(m_kr); +}; + +FLEXT_LIB_DSP_V("LFSaw~",LFSaw_ar); + +LFSaw_ar::LFSaw_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"freq",m_set); + FLEXT_ADDMETHOD_(0,"ar",m_ar); + FLEXT_ADDMETHOD_(0,"kr",m_kr); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + if(sc_ar(Args)) + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + else // if not given, use control rate + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + + AddOutSignal(); +} + +void LFSaw_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + mFreqMul = 2 / Samplerate(); +} + +void LFSaw_ar::m_signal_ar(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *freq = *in; + t_sample *xout = *out; + + float freqmul = mFreqMul; + double phase = mPhase; + + for (int i = 0; i!= n;++i) + { + float z = phase; // out must be written last for in place operation + phase += (*(freq)++) * freqmul; + if (phase >= 1.f) + phase -= 2.f; + else + if (phase <= -1.f) + phase += 2.f; + (*(xout)++) = z; + } + + mPhase=phase; +} + + +void LFSaw_ar::m_signal_kr(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *xout = *out; + + float freq = m_freq * mFreqMul; + double phase = mPhase; + + if (freq >= 0.f) + { + for (int i = 0; i!= n;++i) + { + (*(xout)++) = phase; + phase += freq; + if (phase >= 1.f) phase -= 2.f; + } + } + else + { + for (int i = 0; i!= n;++i) + { + (*(xout)++) = phase; + phase += freq; + if (phase <= -1.f) phase += 2.f; + } + } + + mPhase=phase; +} + +/* ------------------------ LFSaw ---------------------------------*/ + +class LFSaw_kr: + public flext_base +{ + FLEXT_HEADER(LFSaw_kr,flext_base); + +public: + LFSaw_kr(int argc, t_atom *argv); + +protected: + void m_perform(void*); + + void m_set(float f) + { + m_freq_set = f; + m_freq = f * mFreqMul; + } + + void m_set_kr(float f) + { + if (f != 0) + { + dt = f * 0.001; + mFreqMul = 2*dt; + m_freq = m_freq_set * mFreqMul; + m_timer.Reset(); + m_timer.Periodic(dt); + } + } + +private: + double mPhase; + float mFreqMul; + float m_freq; + float dt; + float m_freq_set; + + Timer m_timer; + + FLEXT_CALLBACK_F(m_set_kr); + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_T(m_perform); +}; + + +FLEXT_LIB_V("LFSaw",LFSaw_kr); + +LFSaw_kr::LFSaw_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_set); + FLEXT_ADDMETHOD_(0,"kr",m_set_kr); + // FLEXT_ADDBANG(0,m_perform); + FLEXT_ADDTIMER(m_timer,m_perform); + + AddOutFloat(); + + //parse arguments + AtomList Args(argc,argv); + + m_freq_set = sc_getfloatarg(Args,0); + + dt = sc_getfloatarg(Args,1) * 0.001; + + if (dt == 0 ) + dt = 0.02; // 20 ms as default control rate as in line + mFreqMul = 2 * dt; /* test this !!! */ + + m_freq = m_freq_set * mFreqMul; + + m_timer.Periodic(dt); + +} + +void LFSaw_kr::m_perform(void*) +{ + if (m_freq >= 0.f) + { + ToOutFloat(0,mPhase); + mPhase += m_freq; + if (mPhase >= 1.f) mPhase -= 2.f; + } + else + { + ToOutFloat(0,mPhase); + mPhase += m_freq; + if (mPhase <= -1.f) mPhase += 2.f; + } +} diff --git a/sc4pd/source/LPF.cpp b/sc4pd/source/LPF.cpp new file mode 100644 index 0000000..a11e784 --- /dev/null +++ b/sc4pd/source/LPF.cpp @@ -0,0 +1,180 @@ +/* sc4pd + LPF~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Peter Kowald & Tatsuya Nakatani: + 13 Definitions of Truth + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ LPF~ -------------------------------*/ + +class LPF_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LPF_ar,sc4pd_dsp); + +public: + LPF_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + } + + void m_set_freq(float f) + { + m_freq=f; + changed = true; + } + +private: + float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq; + bool changed; + float mRadiansPerSample, mFilterSlope; + int mFilterLoops, mFilterRemain; + + FLEXT_CALLBACK_F(m_set_freq); +}; + +FLEXT_LIB_DSP_V("LPF~",LPF_ar); + +LPF_ar::LPF_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + changed = true; + + AddOutSignal(); + + m_a0 = 0.f; + m_b1 = 0.f; + m_b2 = 0.f; + m_y1 = 0.f; + m_y2 = 0.f; +} + +void LPF_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float y0; + float y1 = m_y1; + float y2 = m_y2; + float a0 = m_a0; + float b1 = m_b1; + float b2 = m_b2; + + if (changed) + { + float pfreq = m_freq * mRadiansPerSample * 0.5; + + float C = 1.f / tan(pfreq); + float C2 = C * C; + float sqrt2C = C * sqrt2; + 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; + + float a0_slope = (next_a0 - a0) * mFilterSlope; + float b1_slope = (next_b1 - b1) * mFilterSlope; + float b2_slope = (next_b2 - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 + 2.f * y1 + y2); + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * (y2 + 2.f * y0 + y1); + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * (y1 + 2.f * y2 + y0); + + a0 += a0_slope; + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 + 2.f * y1 + y2); + y2 = y1; + y1 = y0; + } + + m_a0 = a0; + m_b1 = b1; + m_b2 = b2; + changed = false; + } + else + { + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 + 2.f * y1 + y2); + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * (y2 + 2.f * y0 + y1); + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * (y1 + 2.f * y2 + y0); + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 + 2.f * y1 + y2); + y2 = y1; + y1 = y0; + } + } + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + +/* no control rate LPF filter */ diff --git a/sc4pd/source/LPZ1.cpp b/sc4pd/source/LPZ1.cpp new file mode 100644 index 0000000..70e495b --- /dev/null +++ b/sc4pd/source/LPZ1.cpp @@ -0,0 +1,132 @@ +/* sc4pd + LPZ1~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: William Parker: Compassion Seizes Bed-Stuy + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ LPZ1~ -------------------------------*/ + +class LPZ1_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LPZ1_ar,sc4pd_dsp); + +public: + LPZ1_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + float m_x1; +}; + +FLEXT_LIB_DSP_V("LPZ1~",LPZ1_ar); + +LPZ1_ar::LPZ1_ar(int argc, t_atom *argv) +{ + AddOutSignal(); + + m_x1=0; +} + +void LPZ1_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float x0; + float x1 = m_x1; + + int t = n >> 2; + for (int i = 0; i!= t;++i) + { + x0 = ZXP(nin); + ZXP(nout) = 0.5f * (x0 + x1); + x1 = ZXP(nin); + ZXP(nout) = 0.5f * (x1 + x0); + x0 = ZXP(nin); + ZXP(nout) = 0.5f * (x0 + x1); + x1 = ZXP(nin); + ZXP(nout) = 0.5f * (x1 + x0); + } + + t = n & 3; + for (int i = 0; i!= t;++i) + { + x0 = ZXP(nin); + ZXP(nout) = 0.5f * (x0 + x1); + x1 = x0; + } + m_x1 = x1; +} + +/* ------------------------ LPZ1 -------------------------------*/ + +class LPZ1_kr: + public flext_base +{ + FLEXT_HEADER(LPZ1_kr,flext_base); + +public: + LPZ1_kr(int argc, t_atom *argv); + +protected: + void m_perform (float f); + +private: + float m_x1; + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB_V("LPZ1",LPZ1_kr); + +LPZ1_kr::LPZ1_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + + AddOutFloat(); + + m_x1=0; +} + +void LPZ1_kr::m_perform(float f) +{ + ToOutFloat(0,0.5f * (f + m_x1)); + m_x1=f; +} + diff --git a/sc4pd/source/LPZ2.cpp b/sc4pd/source/LPZ2.cpp new file mode 100644 index 0000000..4165690 --- /dev/null +++ b/sc4pd/source/LPZ2.cpp @@ -0,0 +1,140 @@ +/* sc4pd + LPZ2~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: William Parker: Compassion Seizes Bed-Stuy + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ LPZ2~ -------------------------------*/ + +class LPZ2_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LPZ2_ar,sc4pd_dsp); + +public: + LPZ2_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mFilterLoops=sc_filterloops(); + mFilterRemain=sc_filterremain(); + } + +private: + float m_x1, m_x2; + int mFilterLoops, mFilterRemain; +}; + +FLEXT_LIB_DSP_V("LPZ2~",LPZ2_ar); + +LPZ2_ar::LPZ2_ar(int argc, t_atom *argv) +{ + AddOutSignal(); + + m_x1=0; + m_x2=0; +} + +void LPZ2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float x0; + float x1 = m_x1; + float x2 = m_x2; + + for (int i = 0; i!=mFilterLoops ;++i) + { + x0 = ZXP(nin); + ZXP(nout) = (x0 + 2.f * x1 + x2) * 0.25f; + x2 = ZXP(nin); + ZXP(nout) = (x2 + 2.f * x0 + x1) * 0.25f; + x1 = ZXP(nin); + ZXP(nout) = (x1 + 2.f * x2 + x0) * 0.25f; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + x0 = ZXP(nin); + ZXP(nout) = (x0 + 2.f * x1 + x2) * 0.25f; + x2 = x1; + x1 = x0; + } + m_x1 = x1; + m_x2 = x2; +} + +/* ------------------------ LPZ2 -------------------------------*/ + +class LPZ2_kr: + public flext_base +{ + FLEXT_HEADER(LPZ2_kr,flext_base); + +public: + LPZ2_kr(int argc, t_atom *argv); + +protected: + void m_perform (float f); + +private: + float m_x1; + float m_x2; + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB_V("LPZ2",LPZ2_kr); + +LPZ2_kr::LPZ2_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + + AddOutFloat(); + + m_x2 = m_x1 = 0; +} + +void LPZ2_kr::m_perform(float f) +{ + ToOutFloat(0,(f + 2.f * m_x1 + m_x2) * 0.25f); + m_x2=m_x1; + m_x1=f; +} + diff --git a/sc4pd/source/Lag.cpp b/sc4pd/source/Lag.cpp new file mode 100644 index 0000000..5daf6d1 --- /dev/null +++ b/sc4pd/source/Lag.cpp @@ -0,0 +1,124 @@ +/* sc4pd + Lag~, Lag + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: VA: Live from the Vision Festival + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Lag~ -----------------------------*/ + +class Lag_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Lag_ar,sc4pd_dsp); + +public: + Lag_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + void m_set(float f); + +private: + FLEXT_CALLBACK_F(m_set); + float m_b1, n_b1; + float m_y1; + float m_lag; + bool changed; +}; + +FLEXT_LIB_DSP_V("Lag~",Lag_ar); + +Lag_ar::Lag_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"lagTime",m_set); + + AtomList Args(argc,argv); + + m_lag = sc_getfloatarg(Args,0); + + AddOutSignal(); + + m_y1 = 0.f; +} + +void Lag_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + changed = false; + m_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate())); +} + +void Lag_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + float y1 = m_y1; + float b1 = m_b1; + + if (changed) + { + float b1_slope = CALCSLOPE(m_b1, n_b1); + m_b1 = n_b1; + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + ZXP(nout) = y1 = y0 + b1 * (y1 - y0); + b1 += b1_slope; + } + changed = false; + } + else + { + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + ZXP(nout) = y1 = y0 + b1 * (y1 - y0); + } + } + m_y1 = zapgremlins(y1); +} + +void Lag_ar::m_set(float f) +{ + m_lag = f; + n_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate())); + changed = true; +} + +/* todo: does a control rate Lag make sense? */ diff --git a/sc4pd/source/Lag2.cpp b/sc4pd/source/Lag2.cpp new file mode 100644 index 0000000..dc85fcb --- /dev/null +++ b/sc4pd/source/Lag2.cpp @@ -0,0 +1,132 @@ +/* sc4pd + Lag2~, Lag2 + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: DKV Trio: Baraka + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Lag2~ -----------------------------*/ + +class Lag2_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Lag2_ar,sc4pd_dsp); + +public: + Lag2_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + void m_set(float f); + +private: + FLEXT_CALLBACK_F(m_set); + float m_b1, n_b1; + float m_y1a, m_y1b; + float m_lag; + bool changed; +}; + +FLEXT_LIB_DSP_V("Lag2~",Lag2_ar); + +Lag2_ar::Lag2_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"lagTime",m_set); + + AtomList Args(argc,argv); + + m_lag = sc_getfloatarg(Args,0); + + AddOutSignal(); + + m_b1 = 0.f; + m_y1a = 0.f; + m_y1b = 0.f; +} + +void Lag2_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + changed = false; + m_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate())); +} + +void Lag2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + float y1a = m_y1a; + float y1b = m_y1b; + float b1 = m_b1; + + if (changed) + { + float b1_slope = CALCSLOPE(m_b1, n_b1); + m_b1 = n_b1; + for (int i = 0; i!= n;++i) + { + float y0a = ZXP(nin); + y1a = y0a + b1 * (y1a - y0a); + y1b = y1a + b1 * (y1b - y1a); + ZXP(nout) = y1b; + b1 += b1_slope; + } + changed = false; + } + else + { + for (int i = 0; i!= n;++i) + { + float y0a = ZXP(nin); + y1a = y0a + b1 * (y1a - y0a); + y1b = y1a + b1 * (y1b - y1a); + ZXP(nout) = y1b; + } + } + m_y1a = zapgremlins(y1a); + m_y1b = zapgremlins(y1b); +} + +void Lag2_ar::m_set(float f) +{ + m_lag = f; + n_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate())); + changed = true; +} + +/* todo: does a control rate Lag2 make sense? */ diff --git a/sc4pd/source/Lag3.cpp b/sc4pd/source/Lag3.cpp new file mode 100644 index 0000000..8865555 --- /dev/null +++ b/sc4pd/source/Lag3.cpp @@ -0,0 +1,137 @@ +/* sc4pd + Lag3~, Lag3 + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: DKV Trio: Baraka + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Lag3~ -----------------------------*/ + +class Lag3_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Lag3_ar,sc4pd_dsp); + +public: + Lag3_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + void m_set(float f); + +private: + FLEXT_CALLBACK_F(m_set); + float m_b1, n_b1; + float m_y1a, m_y1b,m_y1c; + float m_lag; + bool changed; +}; + +FLEXT_LIB_DSP_V("Lag3~",Lag3_ar); + +Lag3_ar::Lag3_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"lagTime",m_set); + + AtomList Args(argc,argv); + + m_lag = sc_getfloatarg(Args,0); + + AddOutSignal(); + + m_b1 = 0.f; + m_y1a = 0.f; + m_y1b = 0.f; + m_y1c = 0.f; +} + +void Lag3_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + changed = false; + m_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate())); +} + +void Lag3_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + float y1a = m_y1a; + float y1b = m_y1b; + float y1c = m_y1c; + float b1 = m_b1; + + if (changed) + { + float b1_slope = CALCSLOPE(m_b1, n_b1); + m_b1 = n_b1; + for (int i = 0; i!= n;++i) + { + float y0a = ZXP(nin); + y1a = y0a + b1 * (y1a - y0a); + y1b = y1a + b1 * (y1b - y1a); + y1c = y1b + b1 * (y1c - y1b); + ZXP(nout) = y1c; + b1 += b1_slope; + } + changed = false; + } + else + { + for (int i = 0; i!= n;++i) + { + float y0a = ZXP(nin); + y1a = y0a + b1 * (y1a - y0a); + y1b = y1a + b1 * (y1b - y1a); + y1c = y1b + b1 * (y1c - y1b); + ZXP(nout) = y1c; + } + } + m_y1a = zapgremlins(y1a); + m_y1b = zapgremlins(y1b); + m_y1b = zapgremlins(y1c); +} + +void Lag3_ar::m_set(float f) +{ + m_lag = f; + n_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate())); + changed = true; +} + +/* todo: does a control rate Lag3 make sense? */ diff --git a/sc4pd/source/Latoocarfian.cpp b/sc4pd/source/Latoocarfian.cpp new file mode 100644 index 0000000..1e20632 --- /dev/null +++ b/sc4pd/source/Latoocarfian.cpp @@ -0,0 +1,217 @@ +/* sc4pd + Latoocarfian, Latoocarfian~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & John Tilbury: Duos For Doris + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ Latoocarfian~ -------------------------------*/ + +class Latoocarfian_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(Latoocarfian_ar,sc4pd_dsp); + +public: + Latoocarfian_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set_a(float f) + { + m_a = f; + } + + void m_set_b(float f) + { + m_b = f; + } + + void m_set_c(float f) + { + m_c = f; + } + + void m_set_d(float f) + { + m_d = f; + } + +private: + float m_x, m_y; //state + float m_a, m_b, m_c, m_d; //parameters + + FLEXT_CALLBACK_F(m_set_a); + FLEXT_CALLBACK_F(m_set_b); + FLEXT_CALLBACK_F(m_set_c); + FLEXT_CALLBACK_F(m_set_d); +}; + +FLEXT_LIB_DSP_V("Latoocarfian~",Latoocarfian_ar); + +Latoocarfian_ar::Latoocarfian_ar(int argc, t_atom *argv) + :m_x(4),m_y(1) +{ + FLEXT_ADDMETHOD_(0,"a",m_set_a); + FLEXT_ADDMETHOD_(0,"b",m_set_b); + FLEXT_ADDMETHOD_(0,"c",m_set_c); + FLEXT_ADDMETHOD_(0,"d",m_set_d); + + //parse arguments + AtomList Args(argc,argv); + if (Args.Count()!=4) + { + post("4 arguments needed"); + } + m_a = sc_getfloatarg(Args,0); + m_b = sc_getfloatarg(Args,1); + m_c = sc_getfloatarg(Args,2); + m_d = sc_getfloatarg(Args,3); + + AddOutSignal(); + AddOutSignal(); // supercollider is only using the x coordinate +} + + +void Latoocarfian_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *xout = *out; + t_sample *yout = *(out+1); + + float a = m_a; + float b = m_b; + float c = m_c; + float d = m_d; + + float x = m_x; + float y = m_y; + + for (int i = 0; i!= n;++i) + { + float x_new=sin(y*b)+c*sin(x*b); + float y_new=sin(x*a)+d*sin(y*a); + (*(xout)++)=x=x_new; + (*(yout)++)=y=y_new; + } + m_x = x; + m_y = y; +} + + + +/* ------------------------ Latoocarfian ---------------------------------*/ + +class Latoocarfian_kr: + public flext_base +{ + FLEXT_HEADER(Latoocarfian_kr,flext_base); + +public: + Latoocarfian_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_set_a(float f) + { + m_a = f; + } + + void m_set_b(float f) + { + m_b = f; + } + + void m_set_c(float f) + { + m_c = f; + } + + void m_set_d(float f) + { + m_d = f; + } + +private: + float m_x, m_y; //state + float m_a, m_b, m_c, m_d; //parameters + + FLEXT_CALLBACK_F(m_set_a); + FLEXT_CALLBACK_F(m_set_b); + FLEXT_CALLBACK_F(m_set_c); + FLEXT_CALLBACK_F(m_set_d); + FLEXT_CALLBACK(m_perform); +}; + + +FLEXT_LIB_V("Latoocarfian",Latoocarfian_kr); + +Latoocarfian_kr::Latoocarfian_kr(int argc, t_atom *argv) + :m_x(1),m_y(1) +{ + FLEXT_ADDMETHOD_(0,"a",m_set_a); + FLEXT_ADDMETHOD_(0,"b",m_set_b); + FLEXT_ADDMETHOD_(0,"c",m_set_c); + FLEXT_ADDMETHOD_(0,"d",m_set_d); + + FLEXT_ADDBANG(0,m_perform); + + //parse arguments + AtomList Args(argc,argv); + if (Args.Count()!=4) + { + post("4 arguments needed"); + } + m_a = sc_getfloatarg(Args,0); + m_b = sc_getfloatarg(Args,1); + m_c = sc_getfloatarg(Args,2); + m_d = sc_getfloatarg(Args,3); + + + AddOutFloat(); + AddOutFloat(); // one outlet more than sc +} + +void Latoocarfian_kr::m_perform() +{ + m_x=sin(m_y*m_b)+m_c*sin(m_x*m_b); + m_y=sin(m_x*m_a)+m_d*sin(m_y*m_a); + + ToOutFloat(0,m_x); + ToOutFloat(1,m_y); +} diff --git a/sc4pd/source/LinCong.cpp b/sc4pd/source/LinCong.cpp new file mode 100644 index 0000000..fdead9c --- /dev/null +++ b/sc4pd/source/LinCong.cpp @@ -0,0 +1,211 @@ +/* sc4pd + LinCong, LinCong~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & John Tilbury: Duos For Doris + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LinCong~ -------------------------------*/ + +class LinCong_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LinCong_ar,sc4pd_dsp); + +public: + LinCong_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set_seed(float f) + { + m_seed = (int)f; + } + + void m_set_mul(float f) + { + m_mul = (int)f; + } + + void m_set_add(float f) + { + m_add = (int)f; + } + + void m_set_mod(float f) + { + m_mod = (int)f; + m_scale = 2/f; //output between -1 and 1 + } + +private: + unsigned int m_seed; //seed + unsigned int m_mul, m_add, m_mod; //parameters + + float m_scale; + + FLEXT_CALLBACK_F(m_set_seed); + FLEXT_CALLBACK_F(m_set_mul); + FLEXT_CALLBACK_F(m_set_add); + FLEXT_CALLBACK_F(m_set_mod); +}; + +FLEXT_LIB_DSP_V("LinCong~",LinCong_ar); + +LinCong_ar::LinCong_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_set_seed); + FLEXT_ADDMETHOD_(0,"mul",m_set_mul); + FLEXT_ADDMETHOD_(0,"add",m_set_add); + FLEXT_ADDMETHOD_(0,"mod",m_set_mod); + + //parse arguments + AtomList Args(argc,argv); + if (Args.Count()!=4) + { + post("4 arguments needed"); + } + m_seed = sc_getfloatarg(Args,0); + m_mul = sc_getfloatarg(Args,1); + m_add = sc_getfloatarg(Args,2); + m_set_mod(sc_getfloatarg(Args,3)); + + AddOutSignal(); +} + + +void LinCong_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *xout = *out; + + + unsigned int seed = m_seed; + unsigned int mul = m_mul; + unsigned int add = m_add; + unsigned int mod = m_mod; + + float scale = m_scale; + + for (int i = 0; i!= n;++i) + { + seed=(seed * mul + add) % mod; + (*(xout)++)=float(seed)*scale - 1; + } + + m_seed = seed; +} + + + +/* ------------------------ LinCong ---------------------------------*/ + +class LinCong_kr: + public flext_base +{ + FLEXT_HEADER(LinCong_kr,flext_base); + +public: + LinCong_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_set_seed(float f) + { + m_seed = (int)f; + } + + void m_set_mul(float f) + { + m_mul = (int)f; + } + + void m_set_add(float f) + { + m_add = (int)f; + } + + void m_set_mod(float f) + { + m_mod = (int)f; + m_scale = 2/f; //output between -1 and 1 + } + +private: + unsigned int m_seed; //seed + unsigned int m_mul, m_add, m_mod; //parameters + + float m_scale; + + FLEXT_CALLBACK_F(m_set_seed); + FLEXT_CALLBACK_F(m_set_mul); + FLEXT_CALLBACK_F(m_set_add); + FLEXT_CALLBACK_F(m_set_mod); + FLEXT_CALLBACK(m_perform); +}; + + +FLEXT_LIB_V("LinCong",LinCong_kr); + +LinCong_kr::LinCong_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_set_seed); + FLEXT_ADDMETHOD_(0,"mul",m_set_mul); + FLEXT_ADDMETHOD_(0,"add",m_set_add); + FLEXT_ADDMETHOD_(0,"mod",m_set_mod); + FLEXT_ADDBANG(0,m_perform); + + //parse arguments + AtomList Args(argc,argv); + if (Args.Count()!=4) + { + post("4 arguments needed"); + } + m_seed = sc_getfloatarg(Args,0); + m_mul = sc_getfloatarg(Args,1); + m_add = sc_getfloatarg(Args,2); + m_set_mod(sc_getfloatarg(Args,3)); + + AddOutFloat(); +} + +void LinCong_kr::m_perform() +{ + m_seed=(m_seed * m_mul + m_add) % m_mod; + ToOutFloat(0,float(m_seed) * m_scale - 1); +} diff --git a/sc4pd/source/LinExp.cpp b/sc4pd/source/LinExp.cpp new file mode 100644 index 0000000..69e9e0a --- /dev/null +++ b/sc4pd/source/LinExp.cpp @@ -0,0 +1,223 @@ +/* sc4pd + LinExp~, LinExp + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: The Ex & Tom Cora - And The Weathermen Shrug + Their Shoulders + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LinExp~ -----------------------------*/ + +class LinExp_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(LinExp_ar,sc4pd_dsp); + +public: + LinExp_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set_srclo(float f) + { + m_srclo = f; + m_reset(); + } + + void m_set_srchi(float f) + { + m_srchi = f; + m_reset(); + } + + void m_set_dstlo(float f) + { + m_dstlo = f; + m_reset(); + } + + void m_set_dsthi(float f) + { + m_dsthi = f; + m_reset(); + } + + void m_reset() + { + m_dstratio = m_dsthi/m_dstlo; + m_rsrcrange = 1. / (m_srchi - m_srclo); + m_rrminuslo = m_rsrcrange * -m_srclo; + } + +private: + FLEXT_CALLBACK_F(m_set_srclo); + FLEXT_CALLBACK_F(m_set_srchi); + FLEXT_CALLBACK_F(m_set_dstlo); + FLEXT_CALLBACK_F(m_set_dsthi); + float m_dstratio, m_rsrcrange, m_rrminuslo, m_dstlo; + float m_srclo, m_srchi, m_dsthi; //we will be able to reset the values +}; + +FLEXT_LIB_DSP_V("LinExp~",LinExp_ar); + +LinExp_ar::LinExp_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"srclo",m_set_srclo); + FLEXT_ADDMETHOD_(0,"srchi",m_set_srchi); + FLEXT_ADDMETHOD_(0,"dstlo",m_set_dstlo); + FLEXT_ADDMETHOD_(0,"dsthi",m_set_dsthi); + + AtomList Args(argc,argv); + + if (Args.Count() != 4) + post("4 arguments are required"); + else + { + m_srclo = sc_getfloatarg(Args,0); + m_srchi = sc_getfloatarg(Args,1); + m_dstlo = sc_getfloatarg(Args,2); + m_dsthi = sc_getfloatarg(Args,3); + + m_reset(); + AddOutSignal(); + } +} + +void LinExp_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + float dstlo = m_dstlo; + float dstratio = m_dstratio; + float rsrcrange = m_rsrcrange; + float rrminuslo = m_rrminuslo; + + for (int i = 0; i!= n;++i) + { + ZXP(nout) = dstlo * pow(dstratio, ZXP(nin) * rsrcrange + rrminuslo); + } +} + +/* ------------------------ LinExp ------------------------------*/ + +class LinExp_kr + :public flext_base +{ + FLEXT_HEADER(LinExp_kr,flext_base); + +public: + LinExp_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + + void m_set_srclo(float f) + { + m_srclo = f; + m_reset(); + } + + void m_set_srchi(float f) + { + m_srchi = f; + m_reset(); + } + + void m_set_dstlo(float f) + { + m_dstlo = f; + m_reset(); + } + + void m_set_dsthi(float f) + { + m_dsthi = f; + m_reset(); + } + + void m_reset() + { + m_dstratio = m_dsthi/m_dstlo; + m_rsrcrange = 1. / (m_srchi - m_srclo); + m_rrminuslo = m_rsrcrange * -m_srclo; + } + +private: + FLEXT_CALLBACK_F(m_set_srclo); + FLEXT_CALLBACK_F(m_set_srchi); + FLEXT_CALLBACK_F(m_set_dstlo); + FLEXT_CALLBACK_F(m_set_dsthi); + float m_dstratio, m_rsrcrange, m_rrminuslo, m_dstlo; + float m_srclo, m_srchi, m_dsthi; //we will be able to reset the values + + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB_V("LinExp",LinExp_kr); + +LinExp_kr::LinExp_kr(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD_(0,"srclo",m_set_srclo); + FLEXT_ADDMETHOD_(0,"srchi",m_set_srchi); + FLEXT_ADDMETHOD_(0,"dstlo",m_set_dstlo); + FLEXT_ADDMETHOD_(0,"dsthi",m_set_dsthi); + + AtomList Args(argc,argv); + + if (Args.Count() != 4) + post("4 arguments are required"); + else + { + m_srclo = sc_getfloatarg(Args,0); + m_srchi = sc_getfloatarg(Args,1); + m_dstlo = sc_getfloatarg(Args,2); + m_dsthi = sc_getfloatarg(Args,3); + + m_reset(); + + AddInFloat(); + AddOutFloat(); + } +} + +void LinExp_kr::m_perform(float f) +{ + ToOutFloat(0,m_dstlo * pow(m_dstratio, f * m_rsrcrange + m_rrminuslo)); +} diff --git a/sc4pd/source/LinRand.cpp b/sc4pd/source/LinRand.cpp new file mode 100644 index 0000000..80266f1 --- /dev/null +++ b/sc4pd/source/LinRand.cpp @@ -0,0 +1,177 @@ +/* sc4pd + LinRand, LinRand~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Jim O'Rourke & Loren Mazzacane Connors: In Bern + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LinRand~ -------------------------------*/ + +class LinRand_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LinRand_ar,sc4pd_dsp); + +public: + LinRand_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_sample; + float lo; + float hi; + int sc_n; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("LinRand~",LinRand_ar); + +LinRand_ar::LinRand_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + + if (Args.Count() != 3) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + sc_n=sc_getfloatarg(Args,2); + + rgen.init(timeseed()); + + AddOutSignal(); +} + +void LinRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + float range = hi - lo; + float a, b; + a = rgen.frand(); + b = rgen.frand(); + if (sc_n <= 0) { + m_sample = sc_min(a, b) * range + lo; + } else { + m_sample = sc_max(a, b) * range + lo; + } +} + + +void LinRand_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float sample = m_sample; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = sample; + } +} + + +/* ------------------------ LinRand ---------------------------------*/ + +class LinRand_kr: + public flext_base +{ + FLEXT_HEADER(LinRand_kr,flext_base); + +public: + LinRand_kr(int argc, t_atom *argv); + +protected: + void m_loadbang(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float lo; + float hi; + int sc_n; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("LinRand",LinRand_kr); + +LinRand_kr::LinRand_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + if (Args.Count() != 3) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + sc_n=sc_getfloatarg(Args,2); + + rgen.init(timeseed()); + + AddOutFloat(); +} + +void LinRand_kr::m_loadbang() +{ + float range = hi - lo; + float a, b; + a = rgen.frand(); + b = rgen.frand(); + if (sc_n <= 0) { + ToOutFloat(0,sc_min(a, b) * range + lo); + } else { + ToOutFloat(0,sc_max(a, b) * range + lo); + } +} diff --git a/sc4pd/source/Logistic.cpp b/sc4pd/source/Logistic.cpp new file mode 100644 index 0000000..a956fda --- /dev/null +++ b/sc4pd/source/Logistic.cpp @@ -0,0 +1,198 @@ +/* sc4pd + Logistic, Logistic~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Fred Frith: Gravity + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ Logistic~ -------------------------------*/ + +class Logistic_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(Logistic_ar,sc4pd_dsp); + +public: + Logistic_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_freq = sc_min(f,m_sr); + } + + void m_param(float f) + { + m_paramf = f; + } + +private: + int m_freq; + float m_paramf; + + int m_sr; + double m_y1; + int m_counter; + + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_F(m_param); +}; + +FLEXT_LIB_DSP_V("Logistic~",Logistic_ar); + +Logistic_ar::Logistic_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"set",m_set); + FLEXT_ADDMETHOD_(0,"parameter",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + m_paramf = sc_getfloatarg(Args,1); + m_y1 = sc_getfloatarg(Args,2); + + m_sr=48000; // this is just a guess (i'll think about this later) + + AddOutSignal(); +} + +void Logistic_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + m_sr = Samplerate(); + m_paramf = sc_min(m_paramf,m_sr); +} + + +void Logistic_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + if(m_sr == m_paramf) + { + /* it might be possible to implement this without the branch */ + + double y1 = m_y1; + double paramf = m_paramf; + for (int i = 0; i!= n;++i) + { + (*(nout)++)= y1 = paramf * y1 * (1.0 - y1); + } + m_y1 = y1; + } + else + { + double y1 = m_y1; + double paramf = m_paramf; + int counter = m_counter; + int remain = n; + do + { + if (counter<=0) + { + counter = (int)(m_sr / sc_max(m_freq, .001f)); + counter = sc_max(1, counter); + y1 = paramf * y1 * (1.0 - y1); + } + + int nsmps = sc_min(remain, counter); + remain -= nsmps; + counter -= nsmps; + + for (int i = 0; i!= nsmps;++i) + { + (*(nout)++)=y1; + } + } + while(remain); + m_y1 = y1; + m_counter = counter; + } +} + + +/* ------------------------ Logistic ---------------------------------*/ + +class Logistic_kr: + public flext_base +{ + FLEXT_HEADER(Logistic_kr,flext_base); + +public: + Logistic_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_param(float f) + { + m_paramf = f; + } + +private: + float m_paramf; + double m_y1; + + FLEXT_CALLBACK(m_perform); + FLEXT_CALLBACK_F(m_param); +}; + +FLEXT_LIB_V("Logistic",Logistic_kr); + +Logistic_kr::Logistic_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"parameter",m_param); + FLEXT_ADDBANG(0,m_perform); + + //parse arguments + AtomList Args(argc,argv); + + m_paramf = sc_getfloatarg(Args,0); + m_y1 = sc_getfloatarg(Args,1); + + AddOutFloat(); +} + +void Logistic_kr::m_perform() +{ + m_y1 = m_paramf * m_y1 * (1.0 - m_y1); + ToOutFloat(0,m_y1); +} diff --git a/sc4pd/source/MantissaMask.cpp b/sc4pd/source/MantissaMask.cpp new file mode 100644 index 0000000..c7c70c2 --- /dev/null +++ b/sc4pd/source/MantissaMask.cpp @@ -0,0 +1,153 @@ +/* sc4pd + MantissaMask~, MantissaMask + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Wolfgang Mitterer: Amusie + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ MantissaMask~ -----------------------------*/ + +class MantissaMask_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(MantissaMask_ar,sc4pd_dsp); + +public: + MantissaMask_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + void m_set(float f); + +private: + FLEXT_CALLBACK_F(m_set); + int32 mask; + +}; + +FLEXT_LIB_DSP_V("MantissaMask~",MantissaMask_ar); + +MantissaMask_ar::MantissaMask_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"set",m_set); + + AtomList Args(argc,argv); + int bits = sc_getfloatarg(Args,0); + + AddOutSignal(); + + mask = -1 << (23 - bits); + +} + +void MantissaMask_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + int32 *nout = (int32*)*out; + int32 *nin = (int32*)*in; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = mask & (*(nin)++); + } +} + +void MantissaMask_ar::m_set(float f) +{ + int bits = (int) f; + if ( bits < 0 || bits > 23) + { + post("value doesn't make sense"); + return; + } + mask = -1 << (23 - bits); +} + +/* ------------------------ MantissaMask ------------------------------*/ + +class MantissaMask_kr + :public flext_base +{ + FLEXT_HEADER(MantissaMask_kr,flext_base); + +public: + MantissaMask_kr(int argc,t_atom * argv); + +protected: + void m_set(float f); + void m_perform(float f); + +private: + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_F(m_perform); + int32 mask; +}; + +FLEXT_LIB_V("MantissaMask",MantissaMask_kr); + +MantissaMask_kr::MantissaMask_kr(int argc,t_atom * argv) +{ + + AtomList Args(argc,argv); + int bits = sc_getfloatarg(Args,0); + + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD_(0,"set",m_set); + mask = -1 << (23 - bits); +} + +void MantissaMask_kr::m_perform(float f) +{ + float g; + int32 *gp = (int32*) &g; + + *(gp) = mask & *((int32*) &f); + + ToOutFloat(0,g); +} + +void MantissaMask_kr::m_set(float f) +{ + int bits = (int) f; + if ( bits < 0 || bits > 23) + { + post("value doesn't make sense"); + return; + } + mask = -1 << (23 - bits); +} diff --git a/sc4pd/source/Median.cpp b/sc4pd/source/Median.cpp new file mode 100644 index 0000000..4383a1b --- /dev/null +++ b/sc4pd/source/Median.cpp @@ -0,0 +1,213 @@ +/* sc4pd + Median, Median~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Morton Feldman: For John Cage + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Median(~) ---------------------------------*/ + + +const int kMAXMEDIANSIZE = 32; + +class median_shared +{ +public: + + inline void Init(long size, float value); + inline float Insert(float value); + +private: + float m_medianValue[kMAXMEDIANSIZE]; + long m_medianAge[kMAXMEDIANSIZE]; + long m_medianSize, m_medianIndex; +}; + +void median_shared::Init(long size, float value) +{ + // initialize the arrays with the first value + m_medianSize = size; + for (int i=0; i<size; ++i) { + m_medianValue[i] = value; + m_medianAge[i] = i; + } +} + +inline float median_shared::Insert(float value) +{ + long i, last, pos=-1; + + // keeps a sorted list of the previous n=size values + // the oldest is removed and the newest is inserted. + // values between the oldest and the newest are shifted over by one. + + // values and ages are both arrays that are 'size' long. + // the median value is always values[size>>1] + + last = m_medianSize - 1; + // find oldest bin and age the other bins. + for (i=0; i<m_medianSize; ++i) { + if (m_medianAge[i] == last) { // is it the oldest bin ? + pos = i; + } else { + m_medianAge[i]++; // age the bin + } + } + // move values to fill in place of the oldest and make a space for the newest + // search lower if value is too small for the open space + while (pos != 0 && value < m_medianValue[pos-1]) { + m_medianValue[pos] = m_medianValue[pos-1]; + m_medianAge[pos] = m_medianAge[pos-1]; + pos--; + } + // search higher if value is too big for the open space + while (pos != last && value > m_medianValue[pos+1]) { + m_medianValue[pos] = m_medianValue[pos+1]; + m_medianAge[pos] = m_medianAge[pos+1]; + pos++; + } + m_medianValue[pos] = value; + m_medianAge[pos] = 0; // this is the newest bin, age = 0 + return m_medianValue[m_medianSize>>1]; +} + + +/* ------------------------ Median~ -----------------------------------*/ + +class Median_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Median_ar,sc4pd_dsp); + +public: + Median_ar(int argc, t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp (int n,t_signalvec const * insigs, + t_signalvec const * outsigs); + + void m_set(float f) + { + m_size=(int)f; + Median.Init(m_size,Median.Insert(0)); /* this is not beautiful, but i'm not + aware of a nicer way */ + } + +private: + FLEXT_CALLBACK_F(m_set); + + median_shared Median; //median + int m_size; //median size +}; + +FLEXT_LIB_DSP_V("Median~",Median_ar); + +Median_ar::Median_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"set",m_set); + + AtomList Args(argc,argv); + m_size=sc_getfloatarg(Args,0); + + AddOutSignal(); +} + +void Median_ar::m_dsp(int n,t_signalvec const * insigs, + t_signalvec const * outsigs) +{ + Median.Init(m_size,0); //how is this done in SuperCollider? +} + +void Median_ar::m_signal(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = Median.Insert(*(nin)++); + } +} + + +/* ------------------------ Median ------------------------------------*/ + +class Median_kr + :public sc4pd_dsp +{ + FLEXT_HEADER(Median_kr,sc4pd_dsp); + +public: + Median_kr(int argc, t_atom * argv); + +protected: + void m_set(float f) + { + m_size=(int)f; + Median.Init(m_size,Median.Insert(0)); /* this is not beautiful, but i'm not + aware of a nicer way */ + } + void m_perform(float f); + +private: + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_F(m_perform); + + median_shared Median; //median + int m_size; //median size +}; + +FLEXT_LIB_V("Median",Median_kr); + +Median_kr::Median_kr(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"set",m_set); + FLEXT_ADDMETHOD(0,m_perform); + + + AtomList Args(argc,argv); + m_size=(int)sc_getfloatarg(Args,0); + + float m_set=sc_getfloatarg(Args,1); + + Median.Init(m_size,m_set); + AddOutFloat(); +} + +void Median_kr::m_perform(float f) +{ + ToOutFloat(0,Median.Insert(f)); +} diff --git a/sc4pd/source/NRand.cpp b/sc4pd/source/NRand.cpp new file mode 100644 index 0000000..e91ad71 --- /dev/null +++ b/sc4pd/source/NRand.cpp @@ -0,0 +1,173 @@ +/* sc4pd + NRand, NRand~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Jim O'Rourke & Loren Mazzacane Connors: In Bern + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ NRand~ -------------------------------*/ + +class NRand_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(NRand_ar,sc4pd_dsp); + +public: + NRand_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_sample; + float lo; + float hi; + int sc_n; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("NRand~",NRand_ar); + +NRand_ar::NRand_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + + if (Args.Count() != 3) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + sc_n=sc_getfloatarg(Args,2); + + rgen.init(timeseed()); + + AddOutSignal(); +} + +void NRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + float range = hi - lo; + float sum = 0; + for (int i=0; i<sc_n; ++i) + { + sum += rgen.frand(); + } + m_sample = (sum/sc_n) * range + lo; +} + + +void NRand_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float sample = m_sample; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = sample; + } +} + + +/* ------------------------ NRand ---------------------------------*/ + +class NRand_kr: + public flext_base +{ + FLEXT_HEADER(NRand_kr,flext_base); + +public: + NRand_kr(int argc, t_atom *argv); + +protected: + void m_loadbang(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float lo; + float hi; + int sc_n; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("NRand",NRand_kr); + +NRand_kr::NRand_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + if (Args.Count() != 3) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + sc_n=sc_getfloatarg(Args,2); + + rgen.init(timeseed()); + + AddOutFloat(); +} + +void NRand_kr::m_loadbang() +{ + float range = hi - lo; + float sum = 0; + for (int i=0; i<sc_n; ++i) + { + sum += rgen.frand(); + } + ToOutFloat(0,(sum/sc_n) * range + lo); +} diff --git a/sc4pd/source/OnePole.cpp b/sc4pd/source/OnePole.cpp new file mode 100644 index 0000000..3de6ef4 --- /dev/null +++ b/sc4pd/source/OnePole.cpp @@ -0,0 +1,245 @@ +/* sc4pd + OnePole, OnePole~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Goh Lee Kwang: Internal Pleasures + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ OnePole~ -------------------------------*/ + +class OnePole_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(OnePole_ar,sc4pd_dsp); + +public: + OnePole_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + void m_set(float f) + { + n_b1=f; + changed = true; + } + + void m_ar() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + } + + void m_kr() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + } + +private: + float m_b1, m_y1; + float n_b1; + bool changed; + + DEFSIGCALL (m_signal_fun); + DEFSIGFUN (m_signal_ar); + DEFSIGFUN (m_signal_kr); + + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK(m_ar); + FLEXT_CALLBACK(m_kr); +}; + +FLEXT_LIB_DSP_V("OnePole~",OnePole_ar); + +OnePole_ar::OnePole_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"coef",m_set); + FLEXT_ADDMETHOD_(0,"ar",m_ar); + FLEXT_ADDMETHOD_(0,"kr",m_kr); + + //parse arguments + AtomList Args(argc,argv); + + m_b1 = sc_getfloatarg(Args,0); + + if(sc_ar(Args)) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + AddInSignal(); + AddInSignal(); + } + else // if not given, use control rate + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + + AddOutSignal(); + + m_y1 = 0.f; +} + +void OnePole_ar::m_signal_ar(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + float *b1p = *(in+1); + + float y1 = m_y1; + + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + float b1 = ZXP(b1p); + ZXP(nout) = y1 = y0 + b1 * (y1 - y0); + } + m_y1 = zapgremlins(y1); +} + + +void OnePole_ar::m_signal_kr(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float b1 = m_b1; + float y1 = m_y1; + + if (changed) + { + m_b1=n_b1; + float b1_slope = CALCSLOPE(m_b1, b1); + if (b1 >= 0.f && m_b1 >= 0) + { + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + ZXP(nout) = y1 = y0 + b1 * (y1 - y0); + b1 += b1_slope; + } + } + else if (b1 <= 0.f && m_b1 <= 0) + { + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + ZXP(nout) = y1 = y0 + b1 * (y1 + y0); + b1 += b1_slope; + } + } + else + { + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + ZXP(nout) = y1 = (1.f - fabs(b1)) * y0 + b1 * y1; + b1 += b1_slope; + } + } + changed = false; + } + else + { + if (b1 >= 0.f) + { + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + ZXP(nout) = y1 = y0 + b1 * (y1 - y0); + } + } + else + { + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + ZXP(nout) = y1 = y0 + b1 * (y1 + y0); + } + } + + } + m_y1 = zapgremlins(y1); +} + +/* ------------------------ OnePole ---------------------------------*/ + + +class OnePole_kr: + public flext_base +{ + FLEXT_HEADER(OnePole_kr,flext_base); + +public: + OnePole_kr(int argc, t_atom *argv); + +protected: + void m_perform(float f); + + void m_set(float f) + { + m_b1=f; + } + +private: + float m_b1, m_y1; + + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_F(m_perform); +}; + + +FLEXT_LIB_V("OnePole",OnePole_kr); + +OnePole_kr::OnePole_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD_(0,"set",m_set); + + AddOutFloat(); + + //parse arguments + AtomList Args(argc,argv); + + m_b1 = sc_getfloatarg(Args,0); + + m_y1=0; +} + +void OnePole_kr::m_perform(float f) +{ + m_y1= ((1-abs(m_b1))*f)+m_b1*m_y1; + ToOutFloat(0,m_y1); +} diff --git a/sc4pd/source/OneZero.cpp b/sc4pd/source/OneZero.cpp new file mode 100644 index 0000000..82c9ad5 --- /dev/null +++ b/sc4pd/source/OneZero.cpp @@ -0,0 +1,200 @@ +/* sc4pd + OneZero, OneZero~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Goh Lee Kwang: Internal Pleasures + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ OneZero~ -------------------------------*/ + +class OneZero_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(OneZero_ar,sc4pd_dsp); + +public: + OneZero_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + n_b1=f; + changed = true; + } + +private: + float m_b1, m_x1; + float n_b1; + bool changed; + + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("OneZero~",OneZero_ar); + +OneZero_ar::OneZero_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"coef",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_b1 = sc_getfloatarg(Args,0); + + AddOutSignal(); + + m_x1 = 0.f; +} + +void OneZero_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float b1 = m_b1; + float x1 = m_x1; + + if (changed) + { + m_b1=n_b1; + float b1_slope = CALCSLOPE(m_b1, b1); + if (b1 >= 0.f && m_b1 >= 0) + { + for (int i = 0; i!= n;++i) + { + float x0 = ZXP(nin); + ZXP(nout) = x0 + b1 * (x1 - x0); + x1 = x0; + b1 += b1_slope; + } + } + else if (b1 <= 0.f && m_b1 <= 0) + { + for (int i = 0; i!= n;++i) + { + float x0 = ZXP(nin); + ZXP(nout) = x0 + b1 * (x1 + x0); + x1 = x0; + b1 += b1_slope; + } + } + else + { + for (int i = 0; i!= n;++i) + { + float x0 = ZXP(nin); + ZXP(nout) = (1.f - fabs(b1)) * x0 + b1 * x1; + x1 = x0; + b1 += b1_slope; + } + } + changed = false; + } + else + { + if (b1 >= 0.f) + { + for (int i = 0; i!= n;++i) + { + float x0 = ZXP(nin); + ZXP(nout) = x0 + b1 * (x1 - x0); + x1 = x0; + } + } + else + { + for (int i = 0; i!= n;++i) + { + float x0 = ZXP(nin); + ZXP(nout) = x0 + b1 * (x1 + x0); + x1 = x0; + } + } + } + m_x1 = x1; +} + +/* ------------------------ OneZero ---------------------------------*/ + + +class OneZero_kr: + public flext_base +{ + FLEXT_HEADER(OneZero_kr,flext_base); + +public: + OneZero_kr(int argc, t_atom *argv); + +protected: + void m_perform(float f); + + void m_set(float f) + { + m_b1=f; + } + +private: + float m_b1, m_x1; + + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_F(m_perform); +}; + + +FLEXT_LIB_V("OneZero",OneZero_kr); + +OneZero_kr::OneZero_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD_(0,"set",m_set); + + AddOutFloat(); + + //parse arguments + AtomList Args(argc,argv); + + m_b1 = sc_getfloatarg(Args,0); + + m_x1=0; +} + +void OneZero_kr::m_perform(float f) +{ + ToOutFloat(0,((1-abs(m_b1))*f)+m_b1*m_x1); + m_x1=f; +} diff --git a/sc4pd/source/PinkNoise.cpp b/sc4pd/source/PinkNoise.cpp new file mode 100644 index 0000000..296f383 --- /dev/null +++ b/sc4pd/source/PinkNoise.cpp @@ -0,0 +1,174 @@ +/* sc4pd + PinkNoise, PinkNoise~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Gottfried Michael Koenig: Klangfiguren II + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ PinkNoise~ -------------------------------*/ + +class PinkNoise_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(PinkNoise_ar,sc4pd_dsp); + +public: + PinkNoise_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + uint32 m_dice[16]; + int32 m_total; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("PinkNoise~",PinkNoise_ar); + +PinkNoise_ar::PinkNoise_ar(int argc, t_atom *argv) + : m_total(0) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + for (int i=0; i<16; ++i) + { + uint32 newrand = rgen.trand() >> 13; + m_total += newrand; + m_dice[i] = newrand; + } + + AddOutSignal(); +} + + +void PinkNoise_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + RGET; + uint32 total = m_total; + uint32 *dice = m_dice; + + for (int i = 0; i!= n;++i) + { + uint32 counter = trand(s1,s2,s3); // Magnus Jonsson's suggestion. + uint32 newrand = counter >> 13; + int k = (CTZ(counter)) & 15; + uint32 prevrand = dice[k]; + dice[k] = newrand; + total += (newrand - prevrand); + newrand = trand(s1,s2,s3) >> 13; + uint32 ifval = (total + newrand) | 0x40000000; + (*(nout)++) = ((*(float*)&ifval) - 3.0f); + } + RPUT; +} + + +/* ------------------------ PinkNoise ---------------------------------*/ + +class PinkNoise_kr: + public flext_base +{ + FLEXT_HEADER(PinkNoise_kr,flext_base); + +public: + PinkNoise_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + uint32 m_dice[16]; + int32 m_total; + RGen rgen; + FLEXT_CALLBACK(m_perform); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("PinkNoise",PinkNoise_kr); + +PinkNoise_kr::PinkNoise_kr(int argc, t_atom *argv) + : m_total(0) +{ + FLEXT_ADDBANG(0,m_perform); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + for (int i=0; i<16; ++i) + { + uint32 newrand = rgen.trand() >> 13; + m_total += newrand; + m_dice[i] = newrand; + } + + AddOutFloat(); +} + +void PinkNoise_kr::m_perform() +{ + uint32 counter = rgen.trand(); // Magnus Jonsson's suggestion. + uint32 newrand = counter >> 13; + int k = (CTZ(counter)) & 15; + uint32 prevrand = m_dice[k]; + m_dice[k] = newrand; + m_total += (newrand - prevrand); + newrand = rgen.trand() >> 13; + uint32 ifval = (m_total + newrand) | 0x40000000; + + ToOutFloat(0,((*(float*)&ifval) - 3.0f)); +} diff --git a/sc4pd/source/PitchShift.cpp b/sc4pd/source/PitchShift.cpp new file mode 100644 index 0000000..8a3f265 --- /dev/null +++ b/sc4pd/source/PitchShift.cpp @@ -0,0 +1,629 @@ +/* sc4pd + PitchShift~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Bernhard Lang: Differenz / Wiederholung 2 + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ PitchShift~ -----------------------------*/ + +class PitchShift_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(PitchShift_ar,sc4pd_dsp); + +public: + PitchShift_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_set_pitchratio (float f) + { + m_pitchratio = f; + } + + void m_set_pitchdispersion (float f) + { + m_pitchdispersion = f; + } + + void m_set_timedispersion (float f) + { + m_timedispersion = f; + } + +private: + float m_windowsize,m_pitchratio,m_pitchdispersion,m_timedispersion; + RGen rgen; + + + float *m_dlybuf; + float m_dsamp1, m_dsamp1_slope, m_ramp1, m_ramp1_slope; + float m_dsamp2, m_dsamp2_slope, m_ramp2, m_ramp2_slope; + float m_dsamp3, m_dsamp3_slope, m_ramp3, m_ramp3_slope; + float m_dsamp4, m_dsamp4_slope, m_ramp4, m_ramp4_slope; + float m_fdelaylen, m_slope; + long m_iwrphase, m_idelaylen, m_mask; + long m_counter, m_stage, m_numoutput, m_framesize; + + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_set_pitchratio); + FLEXT_CALLBACK_F(m_set_pitchdispersion); + FLEXT_CALLBACK_F(m_set_timedispersion); +}; + +FLEXT_LIB_DSP_V("PitchShift~",PitchShift_ar); + +PitchShift_ar::PitchShift_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"pitchRatio",m_set_pitchratio); + FLEXT_ADDMETHOD_(0,"pitchDispersion",m_set_pitchdispersion); + FLEXT_ADDMETHOD_(0,"timeDispersion",m_set_timedispersion); + + AtomList Args(argc,argv); + + if (Args.Count() != 4) + { + post("4 arguments needed"); + return; + } + + m_windowsize = sc_getfloatarg(Args,0); + m_pitchratio = sc_getfloatarg(Args,1); + m_pitchdispersion = sc_getfloatarg(Args,2); + m_timedispersion = sc_getfloatarg(Args,3); + + rgen.init(timeseed()); + + AddOutSignal(); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); +} + +void PitchShift_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + /* initialization from PitchShift_Ctor(PitchShift *unit) */ + + long delaybufsize; + float *dlybuf; + float pchratio; + float fdelaylen, slope; + long framesize, last; + + //out = ZOUT(0); + //in = ZIN(0); + pchratio = m_pitchratio; + + delaybufsize = (long)ceil(m_windowsize * SAMPLERATE * 3.f + 3.f); + fdelaylen = delaybufsize - 3; + + delaybufsize = delaybufsize + BUFLENGTH; + delaybufsize = NEXTPOWEROFTWO(delaybufsize); // round up to next power of two + dlybuf = new float[delaybufsize]; + //(float*)RTAlloc(unit->mWorld, delaybufsize * sizeof(float)); + + *dlybuf = 0; + + m_dlybuf = dlybuf; + m_idelaylen = delaybufsize; + m_fdelaylen = fdelaylen; + m_iwrphase = 0; + m_numoutput = 0; + m_mask = last = (delaybufsize - 1); + + m_framesize = framesize = ((long)(m_windowsize * SAMPLERATE) + 2) & ~3; + m_slope = slope = 2.f / framesize; + m_stage = 3; + m_counter = framesize >> 2; + m_ramp1 = 0.5; + m_ramp2 = 1.0; + m_ramp3 = 0.5; + m_ramp4 = 0.0; + + m_ramp1_slope = -slope; + m_ramp2_slope = -slope; + m_ramp3_slope = slope; + m_ramp4_slope = slope; + + dlybuf[last ] = 0.f; // put a few zeroes where we start the read heads + dlybuf[last-1] = 0.f; + dlybuf[last-2] = 0.f; + + m_numoutput = 0; + + // start all read heads 2 samples behind the write head + m_dsamp1 = m_dsamp2 = m_dsamp3 = m_dsamp4 = 2.f; + // pch ratio is initially zero for the read heads + m_dsamp1_slope = m_dsamp2_slope = m_dsamp3_slope = m_dsamp4_slope = 1.f; +} + + +void PitchShift_ar::m_signal_z(int n, t_sample *const *in, + t_sample *const *out) +{ + + float *nout, *nin, *dlybuf; + float disppchratio, pchratio, pchratio1, value; + float dsamp1, dsamp1_slope, ramp1, ramp1_slope; + float dsamp2, dsamp2_slope, ramp2, ramp2_slope; + float dsamp3, dsamp3_slope, ramp3, ramp3_slope; + float dsamp4, dsamp4_slope, ramp4, ramp4_slope; + float fdelaylen, d1, d2, frac, slope, samp_slope, startpos, + pchdisp, timedisp; + long remain, nsmps, idelaylen, irdphase, irdphaseb, iwrphase; + long mask, idsamp; + long counter, stage, framesize, numoutput; + + RGET; + + nout = *out; + nin = *in; + + pchratio = m_pitchratio; + pchdisp = m_pitchdispersion; + timedisp = m_timedispersion; + timedisp = sc_clip(timedisp, 0.f, m_windowsize) * SAMPLERATE; + + dlybuf = m_dlybuf; + fdelaylen = m_fdelaylen; + idelaylen = m_idelaylen; + iwrphase = m_iwrphase; + numoutput = m_numoutput; + + counter = m_counter; + stage = m_stage; + mask = m_mask; + framesize = m_framesize; + + dsamp1 = m_dsamp1; + dsamp2 = m_dsamp2; + dsamp3 = m_dsamp3; + dsamp4 = m_dsamp4; + + dsamp1_slope = m_dsamp1_slope; + dsamp2_slope = m_dsamp2_slope; + dsamp3_slope = m_dsamp3_slope; + dsamp4_slope = m_dsamp4_slope; + + ramp1 = m_ramp1; + ramp2 = m_ramp2; + ramp3 = m_ramp3; + ramp4 = m_ramp4; + + ramp1_slope = m_ramp1_slope; + ramp2_slope = m_ramp2_slope; + ramp3_slope = m_ramp3_slope; + ramp4_slope = m_ramp4_slope; + + slope = m_slope; + + remain = n; + while (remain) + { + if (counter <= 0) + { + counter = framesize >> 2; + m_stage = stage = (stage + 1) & 3; + disppchratio = pchratio; + if (pchdisp != 0.f) + { + disppchratio += (pchdisp * frand2(s1,s2,s3)); + } + disppchratio = sc_clip(disppchratio, 0.f, 4.f); + pchratio1 = disppchratio - 1.f; + samp_slope = -pchratio1; + startpos = pchratio1 < 0.f ? 2.f : framesize * pchratio1 + 2.f; + startpos += (timedisp * frand(s1,s2,s3)); + switch(stage) + { + case 0 : + m_dsamp1_slope = dsamp1_slope = samp_slope; + dsamp1 = startpos; + ramp1 = 0.0; + m_ramp1_slope = ramp1_slope = slope; + m_ramp3_slope = ramp3_slope = -slope; + break; + case 1 : + m_dsamp2_slope = dsamp2_slope = samp_slope; + dsamp2 = startpos; + ramp2 = 0.0; + m_ramp2_slope = ramp2_slope = slope; + m_ramp4_slope = ramp4_slope = -slope; + break; + case 2 : + m_dsamp3_slope = dsamp3_slope = samp_slope; + dsamp3 = startpos; + ramp3 = 0.0; + m_ramp3_slope = ramp3_slope = slope; + m_ramp1_slope = ramp1_slope = -slope; + break; + case 3 : + m_dsamp4_slope = dsamp4_slope = samp_slope; + dsamp4 = startpos; + ramp4 = 0.0; + m_ramp2_slope = ramp2_slope = -slope; + m_ramp4_slope = ramp4_slope = slope; + break; + } + } + nsmps = sc_min(remain, counter); + remain -= nsmps; + counter -= nsmps; + + while (nsmps--) { + numoutput++; + iwrphase = (iwrphase + 1) & mask; + + dsamp1 += dsamp1_slope; + idsamp = (long)dsamp1; + frac = dsamp1 - idsamp; + irdphase = (iwrphase - idsamp) & mask; + irdphaseb = (irdphase - 1) & mask; + if (numoutput < idelaylen) + { + if (irdphase > iwrphase) + { + value = 0.f; + } + else if (irdphaseb > iwrphase) + { + d1 = dlybuf[irdphase]; + value = (d1 - frac * d1) * ramp1; + } + else + { + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value = (d1 + frac * (d2 - d1)) * ramp1; + } + } + else + { + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value = (d1 + frac * (d2 - d1)) * ramp1; + } + ramp1 += ramp1_slope; + + dsamp2 += dsamp2_slope; + idsamp = (long)dsamp2; + frac = dsamp2 - idsamp; + irdphase = (iwrphase - idsamp) & mask; + irdphaseb = (irdphase - 1) & mask; + if (numoutput < idelaylen) + { + if (irdphase > iwrphase) + { + //value += 0.f; + } + else if (irdphaseb > iwrphase) + { + d1 = dlybuf[irdphase]; + value += (d1 - frac * d1) * ramp2; + } + else + { + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp2; + + } + } + else + { + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp2; + } + ramp2 += ramp2_slope; + + dsamp3 += dsamp3_slope; + idsamp = (long)dsamp3; + frac = dsamp3 - idsamp; + irdphase = (iwrphase - idsamp) & mask; + irdphaseb = (irdphase - 1) & mask; + if (numoutput < idelaylen) + { + if (irdphase > iwrphase) + { + //value += 0.f; + } + else if (irdphaseb > iwrphase) + { + d1 = dlybuf[irdphase]; + value += (d1 - frac * d1) * ramp3; + } + else + { + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp3; + } + } + else + { + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp3; + } + ramp3 += ramp3_slope; + + dsamp4 += dsamp4_slope; + idsamp = (long)dsamp4; + frac = dsamp4 - idsamp; + irdphase = (iwrphase - idsamp) & mask; + irdphaseb = (irdphase - 1) & mask; + + if (numoutput < idelaylen) + { + if (irdphase > iwrphase) + { + //value += 0.f; + } else if (irdphaseb > iwrphase) { + d1 = dlybuf[irdphase]; + value += (d1 - frac * d1) * ramp4; + } + else + { + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp4; + } + } + else + { + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp4; + } + ramp4 += ramp4_slope; + + dlybuf[iwrphase] = ZXP(nin); + ZXP(nout) = value *= 0.5; + } + } + + m_counter = counter; + m_stage = stage; + m_mask = mask; + + m_dsamp1 = dsamp1; + m_dsamp2 = dsamp2; + m_dsamp3 = dsamp3; + m_dsamp4 = dsamp4; + + m_ramp1 = ramp1; + m_ramp2 = ramp2; + m_ramp3 = ramp3; + m_ramp4 = ramp4; + + m_numoutput = numoutput; + m_iwrphase = iwrphase; + + if (numoutput >= idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + } + RPUT; +} + +void PitchShift_ar::m_signal_(int n, t_sample *const *in, + t_sample *const *out) +{ + float *nout, *nin, *dlybuf; + float disppchratio, pchratio, pchratio1, value; + float dsamp1, dsamp1_slope, ramp1, ramp1_slope; + float dsamp2, dsamp2_slope, ramp2, ramp2_slope; + float dsamp3, dsamp3_slope, ramp3, ramp3_slope; + float dsamp4, dsamp4_slope, ramp4, ramp4_slope; + float fdelaylen, d1, d2, frac, slope, samp_slope, startpos, + pchdisp, timedisp; + long remain, nsmps, idelaylen, irdphase, irdphaseb, iwrphase, mask, idsamp; + long counter, stage, framesize; + + RGET; + + nout = *out; + nin = *in; + + pchratio = m_pitchratio; + pchdisp = m_pitchdispersion; + timedisp = m_timedispersion; + + timedisp = sc_clip(timedisp, 0.f, m_windowsize) * SAMPLERATE; + + dlybuf = m_dlybuf; + fdelaylen = m_fdelaylen; + idelaylen = m_idelaylen; + iwrphase = m_iwrphase; + + counter = m_counter; + stage = m_stage; + mask = m_mask; + framesize = m_framesize; + + dsamp1 = m_dsamp1; + dsamp2 = m_dsamp2; + dsamp3 = m_dsamp3; + dsamp4 = m_dsamp4; + + dsamp1_slope = m_dsamp1_slope; + dsamp2_slope = m_dsamp2_slope; + dsamp3_slope = m_dsamp3_slope; + dsamp4_slope = m_dsamp4_slope; + + ramp1 = m_ramp1; + ramp2 = m_ramp2; + ramp3 = m_ramp3; + ramp4 = m_ramp4; + + ramp1_slope = m_ramp1_slope; + ramp2_slope = m_ramp2_slope; + ramp3_slope = m_ramp3_slope; + ramp4_slope = m_ramp4_slope; + + slope = m_slope; + + remain = n; + while (remain) + { + if (counter <= 0) + { + counter = framesize >> 2; + m_stage = stage = (stage + 1) & 3; + disppchratio = pchratio; + if (pchdisp != 0.f) + { + disppchratio += (pchdisp * frand2(s1,s2,s3)); + } + disppchratio = sc_clip(disppchratio, 0.f, 4.f); + pchratio1 = disppchratio - 1.f; + samp_slope = -pchratio1; + startpos = pchratio1 < 0.f ? 2.f : framesize * pchratio1 + 2.f; + startpos += (timedisp * frand(s1,s2,s3)); + switch(stage) + { + case 0 : + m_dsamp1_slope = dsamp1_slope = samp_slope; + dsamp1 = startpos; + ramp1 = 0.0; + m_ramp1_slope = ramp1_slope = slope; + m_ramp3_slope = ramp3_slope = -slope; + break; + case 1 : + m_dsamp2_slope = dsamp2_slope = samp_slope; + dsamp2 = startpos; + ramp2 = 0.0; + m_ramp2_slope = ramp2_slope = slope; + m_ramp4_slope = ramp4_slope = -slope; + break; + case 2 : + m_dsamp3_slope = dsamp3_slope = samp_slope; + dsamp3 = startpos; + ramp3 = 0.0; + m_ramp3_slope = ramp3_slope = slope; + m_ramp1_slope = ramp1_slope = -slope; + break; + case 3 : + m_dsamp4_slope = dsamp4_slope = samp_slope; + dsamp4 = startpos; + ramp4 = 0.0; + m_ramp2_slope = ramp2_slope = -slope; + m_ramp4_slope = ramp4_slope = slope; + break; + } + } + + nsmps = sc_min(remain, counter); + remain -= nsmps; + counter -= nsmps; + + for (int i = 0; i!= nsmps;++i) + { + iwrphase = (iwrphase + 1) & mask; + + dsamp1 += dsamp1_slope; + idsamp = (long)dsamp1; + frac = dsamp1 - idsamp; + irdphase = (iwrphase - idsamp) & mask; + irdphaseb = (irdphase - 1) & mask; + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value = (d1 + frac * (d2 - d1)) * ramp1; + ramp1 += ramp1_slope; + + dsamp2 += dsamp2_slope; + idsamp = (long)dsamp2; + frac = dsamp2 - idsamp; + irdphase = (iwrphase - idsamp) & mask; + irdphaseb = (irdphase - 1) & mask; + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp2; + ramp2 += ramp2_slope; + + dsamp3 += dsamp3_slope; + idsamp = (long)dsamp3; + frac = dsamp3 - idsamp; + irdphase = (iwrphase - idsamp) & mask; + irdphaseb = (irdphase - 1) & mask; + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp3; + ramp3 += ramp3_slope; + + dsamp4 += dsamp4_slope; + idsamp = (long)dsamp4; + frac = dsamp4 - idsamp; + irdphase = (iwrphase - idsamp) & mask; + irdphaseb = (irdphase - 1) & mask; + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp4; + ramp4 += ramp4_slope; + + dlybuf[iwrphase] = ZXP(nin); + ZXP(nout) = value *= 0.5; + } + } + + m_counter = counter; + + m_dsamp1 = dsamp1; + m_dsamp2 = dsamp2; + m_dsamp3 = dsamp3; + m_dsamp4 = dsamp4; + + m_ramp1 = ramp1; + m_ramp2 = ramp2; + m_ramp3 = ramp3; + m_ramp4 = ramp4; + + m_iwrphase = iwrphase; + + RPUT; +} + + +/* a control rate PitchShift doesn't make sense */ diff --git a/sc4pd/source/RHPF.cpp b/sc4pd/source/RHPF.cpp new file mode 100644 index 0000000..fb79d2b --- /dev/null +++ b/sc4pd/source/RHPF.cpp @@ -0,0 +1,192 @@ +/* sc4pd + RHPF~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Peter Kowald & Tatsuya Nakatani: + 13 Definitions of Truth + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ RHPF~ -------------------------------*/ + +class RHPF_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(RHPF_ar,sc4pd_dsp); + +public: + RHPF_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + } + + void m_set_freq(float f) + { + m_freq=f; + changed = true; + } + + void m_set_rq(float f) + { + m_reson=f; + changed = true; + } + + +private: + float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq, m_reson; + bool changed; + float mRadiansPerSample, mFilterSlope; + int mFilterLoops, mFilterRemain; + + FLEXT_CALLBACK_F(m_set_freq); + FLEXT_CALLBACK_F(m_set_rq); +}; + +FLEXT_LIB_DSP_V("RHPF~",RHPF_ar); + +RHPF_ar::RHPF_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq); + FLEXT_ADDMETHOD_(0,"krq",m_set_rq); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + m_reson = sc_getfloatarg(Args,1); + changed = true; + + AddOutSignal(); + + m_a0 = 0.f; + m_b1 = 0.f; + m_b2 = 0.f; + m_y1 = 0.f; + m_y2 = 0.f; +} + +void RHPF_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float y0; + float y1 = m_y1; + float y2 = m_y2; + float a0 = m_a0; + float b1 = m_b1; + float b2 = m_b2; + + if (changed) + { + float qres = sc_max(0.001, m_reson); + float pfreq = m_freq * mRadiansPerSample; + + float D = tan(pfreq * qres * 0.5); + float C = ((1.f-D)/(1.f+D)); + float cosf = cos(pfreq); + + float next_b1 = (1.f + C) * cosf; + float next_b2 = -C; + float next_a0 = (1.f + C + next_b1) * .25; + + float a0_slope = (next_a0 - a0) * mFilterSlope; + float b1_slope = (next_b1 - b1) * mFilterSlope; + float b2_slope = (next_b2 - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y0 - 2.f * y1 + y2; + + y2 = a0 * ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = y2 - 2.f * y0 + y1; + + y1 = a0 * ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = y1 - 2.f * y2 + y0; + + a0 += a0_slope; + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y0 - 2.f * y1 + y2; + y2 = y1; + y1 = y0; + } + + m_a0 = a0; + m_b1 = b1; + m_b2 = b2; + changed = false; + } + else + { + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y0 - 2.f * y1 + y2; + + y2 = a0 * ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = y2 - 2.f * y0 + y1; + + y1 = a0 * ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = y1 - 2.f * y2 + y0; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y0 - 2.f * y1 + y2; + y2 = y1; + y1 = y0; + } + } + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + +/* no control rate RHPF filter */ diff --git a/sc4pd/source/RLPF.cpp b/sc4pd/source/RLPF.cpp new file mode 100644 index 0000000..89fc46c --- /dev/null +++ b/sc4pd/source/RLPF.cpp @@ -0,0 +1,192 @@ +/* sc4pd + RLPF~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Peter Kowald & Tatsuya Nakatani: + 13 Definitions of Truth + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ RLPF~ -------------------------------*/ + +class RLPF_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(RLPF_ar,sc4pd_dsp); + +public: + RLPF_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + } + + void m_set_freq(float f) + { + m_freq=f; + changed = true; + } + + void m_set_rq(float f) + { + m_reson=f; + changed = true; + } + + +private: + float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq, m_reson; + bool changed; + float mRadiansPerSample, mFilterSlope; + int mFilterLoops, mFilterRemain; + + FLEXT_CALLBACK_F(m_set_freq); + FLEXT_CALLBACK_F(m_set_rq); +}; + +FLEXT_LIB_DSP_V("RLPF~",RLPF_ar); + +RLPF_ar::RLPF_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq); + FLEXT_ADDMETHOD_(0,"rq",m_set_rq); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + m_reson = sc_getfloatarg(Args,1); + changed = true; + + AddOutSignal(); + + m_a0 = 0.f; + m_b1 = 0.f; + m_b2 = 0.f; + m_y1 = 0.f; + m_y2 = 0.f; +} + +void RLPF_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float y0; + float y1 = m_y1; + float y2 = m_y2; + float a0 = m_a0; + float b1 = m_b1; + float b2 = m_b2; + + if (changed) + { + float qres = sc_max(0.001, m_reson); + float pfreq = m_freq * mRadiansPerSample; + + float D = tan(pfreq * qres * 0.5); + float C = ((1.f-D)/(1.f+D)); + float cosf = cos(pfreq); + + float next_b1 = (1.f + C) * cosf; + float next_b2 = -C; + float next_a0 = (1.f + C - next_b1) * .25; + + float a0_slope = (next_a0 - a0) * mFilterSlope; + float b1_slope = (next_b1 - b1) * mFilterSlope; + float b2_slope = (next_b2 - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y0 + 2.f * y1 + y2; + + y2 = a0 * ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = y2 + 2.f * y0 + y1; + + y1 = a0 * ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = y1 + 2.f * y2 + y0; + + a0 += a0_slope; + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y0 + 2.f * y1 + y2; + y2 = y1; + y1 = y0; + } + + m_a0 = a0; + m_b1 = b1; + m_b2 = b2; + changed = false; + } + else + { + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y0 + 2.f * y1 + y2; + + y2 = a0 * ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = y2 + 2.f * y0 + y1; + + y1 = a0 * ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = y1 + 2.f * y2 + y0; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y0 + 2.f * y1 + y2; + y2 = y1; + y1 = y0; + } + } + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + +/* no control rate RLPF filter */ diff --git a/sc4pd/source/Rand.cpp b/sc4pd/source/Rand.cpp new file mode 100644 index 0000000..c310aa9 --- /dev/null +++ b/sc4pd/source/Rand.cpp @@ -0,0 +1,160 @@ +/* sc4pd + Rand, Rand~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: the sounds coming through my open window + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ Rand~ -------------------------------*/ + +class Rand_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(Rand_ar,sc4pd_dsp); + +public: + Rand_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_sample; + float lo; + float hi; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("Rand~",Rand_ar); + +Rand_ar::Rand_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + + rgen.init(timeseed()); + + AddOutSignal(); +} + +void Rand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + float range = hi - lo; + m_sample = rgen.frand() * range + lo; +} + + +void Rand_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float sample = m_sample; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = sample; + } +} + + +/* ------------------------ Rand ---------------------------------*/ + +class Rand_kr: + public flext_base +{ + FLEXT_HEADER(Rand_kr,flext_base); + +public: + Rand_kr(int argc, t_atom *argv); + +protected: + void m_loadbang(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float lo; + float hi; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("Rand",Rand_kr); + +Rand_kr::Rand_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + + rgen.init(timeseed()); + + AddOutFloat(); +} + +void Rand_kr::m_loadbang() +{ + float range = hi - lo; + + ToOutFloat(0,rgen.frand() * range + lo); +} diff --git a/sc4pd/source/Resonz.cpp b/sc4pd/source/Resonz.cpp new file mode 100644 index 0000000..4561b9a --- /dev/null +++ b/sc4pd/source/Resonz.cpp @@ -0,0 +1,190 @@ +/* sc4pd + Resonz~, Resonz + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: MIMEO: Electric Chair And Table + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Resonz~ -----------------------------*/ + +class Resonz_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Resonz_ar,sc4pd_dsp); + +public: + Resonz_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_set_freq(float f) + { + m_freq = f; + m_ffreq = m_freq * mRadiansPerSample; + changed = true; + } + void m_set_rq(float f) + { + m_rq = f; + changed = true; + } + +private: + FLEXT_CALLBACK_F(m_set_freq); + FLEXT_CALLBACK_F(m_set_rq); + float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq, m_rq, m_ffreq; + bool changed; + + float mRadiansPerSample, mFilterSlope, mFilterLoops, mFilterRemain; +}; + +FLEXT_LIB_DSP_V("Resonz~",Resonz_ar); + +Resonz_ar::Resonz_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"freq",m_set_freq); + FLEXT_ADDMETHOD_(0,"rq",m_set_rq); + + AtomList Args(argc,argv); + m_freq = sc_getfloatarg(Args,0); + m_rq = sc_getfloatarg(Args,1); + + AddOutSignal(); + + m_a0 = 0.f; + m_b1 = 0.f; + m_b2 = 0.f; + m_y1 = 0.f; + m_y2 = 0.f; + changed = false; +} + +void Resonz_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + + m_ffreq = m_freq * mRadiansPerSample; +} + +void Resonz_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + float y0; + float y1 = m_y1; + float y2 = m_y2; + float a0 = m_a0; + float b1 = m_b1; + float b2 = m_b2; + + if (changed = true) + { + float B = m_ffreq * m_rq; + float R = 1.f - B * 0.5f; + float twoR = 2.f * R; + float R2 = R * R; + float cost = (twoR * cos(m_ffreq)) / (1.f + R2); + float b1_next = twoR * cost; + float b2_next = -R2; + float a0_next = (1.f - R2) * 0.5f; + float a0_slope = (a0_next - a0) * mFilterSlope; + float b1_slope = (b1_next - b1) * mFilterSlope; + float b2_slope = (b2_next - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - y2); + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * (y2 - y1); + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * (y1 - y0); + + a0 += a0_slope; + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - y2); + y2 = y1; + y1 = y0; + } + + m_a0 = a0_next; + m_b1 = b1_next; + m_b2 = b2_next; + changed = false; + } + else + { + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - y2); + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * (y2 - y1); + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * (y1 - y0); + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - y2); + y2 = y1; + y1 = y0; + } + } + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + + +/* no control rate resonz */ diff --git a/sc4pd/source/SOS.cpp b/sc4pd/source/SOS.cpp new file mode 100644 index 0000000..29aaecb --- /dev/null +++ b/sc4pd/source/SOS.cpp @@ -0,0 +1,258 @@ +/* sc4pd + SOS~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Susie Ibarra & Assif Tsahar: Home Cookin' + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ SOS~ -------------------------------*/ + +class SOS_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(SOS_ar,sc4pd_dsp); + +public: + SOS_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + mFilterSlope = sc_filterslope(); + } + + void m_set_a0(float f) + { + next_a0=f; + } + + void m_set_a1(float f) + { + next_a1=f; + } + + void m_set_a2(float f) + { + next_a2=f; + } + + void m_set_b1(float f) + { + next_b1=f; + } + + void m_set_b2(float f) + { + next_b2=f; + } + + void m_ar() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + } + + void m_kr() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + } + +private: + float next_a0, next_a1, next_a2, next_b1, next_b2; + float m_y1, m_y2, m_a0, m_a1, m_a2, m_b1, m_b2; + + float mFilterSlope; + int mFilterLoops, mFilterRemain; + + DEFSIGCALL (m_signal_fun); + DEFSIGFUN (m_signal_ar); + DEFSIGFUN (m_signal_kr); + + FLEXT_CALLBACK_F(m_set_a0); + FLEXT_CALLBACK_F(m_set_a1); + FLEXT_CALLBACK_F(m_set_a2); + FLEXT_CALLBACK_F(m_set_b1); + FLEXT_CALLBACK_F(m_set_b2); + FLEXT_CALLBACK(m_ar); + FLEXT_CALLBACK(m_kr); +}; + +FLEXT_LIB_DSP_V("SOS~",SOS_ar); + +SOS_ar::SOS_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"a0",m_set_a0); + FLEXT_ADDMETHOD_(0,"a1",m_set_a1); + FLEXT_ADDMETHOD_(0,"a2",m_set_a2); + FLEXT_ADDMETHOD_(0,"b1",m_set_b1); + FLEXT_ADDMETHOD_(0,"b2",m_set_b2); + FLEXT_ADDMETHOD_(0,"ar",m_ar); + FLEXT_ADDMETHOD_(0,"kr",m_kr); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count()<5) + { + post("needs at least 5 arguments"); + return; + } + m_a0 = sc_getfloatarg(Args,0); + m_a1 = sc_getfloatarg(Args,1); + m_a2 = sc_getfloatarg(Args,2); + m_b1 = sc_getfloatarg(Args,3); + m_b2 = sc_getfloatarg(Args,4); + + if(sc_ar(Args)) + { + AddInSignal(); + AddInSignal(); + AddInSignal(); + AddInSignal(); + AddInSignal(); + AddInSignal(); + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + } + else // if not given, use control rate + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + + AddOutSignal(); + + m_y1 = 0.f; + m_a0 = 0.f; + m_a1 = 0.f; + m_a2 = 0.f; + m_b1 = 0.f; + m_b2 = 0.f; +} + +void SOS_ar::m_signal_ar(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + float *a0 = *(in+1); + float *a1 = *(in+2); + float *a2 = *(in+3); + float *b1 = *(in+4); + float *b2 = *(in+5); + + float y0; + float y1 = m_y1; + float y2 = m_y2; + + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + ZXP(b1) * y1 + ZXP(b2) * y2; + ZXP(nout) = ZXP(a0) * y0 + ZXP(a1) * y1 + ZXP(a2) * y2; + + y2 = ZXP(nin) + ZXP(b1) * y0 + ZXP(b2) * y1; + ZXP(nout) = ZXP(a0) * y2 + ZXP(a1) * y0 + ZXP(a2) * y1; + + y1 = ZXP(nin) + ZXP(b1) * y2 + ZXP(b2) * y0; + ZXP(nout) = ZXP(a0) * y1 + ZXP(a1) * y2 + ZXP(a2) * y0; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + ZXP(b1) * y1 + ZXP(b2) * y2; + ZXP(nout) = ZXP(a0) * y0 + ZXP(a1) * y1 + ZXP(a2) * y2; + y2 = y1; + y1 = y0; + } + + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); + +} + + +void SOS_ar::m_signal_kr(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float y0; + float y1 = m_y1; + float y2 = m_y2; + float a0 = m_a0; + float a1 = m_a1; + float a2 = m_a2; + float b1 = m_b1; + float b2 = m_b2; + float a0_slope = (next_a0 - a0) * mFilterSlope; + float a1_slope = (next_a1 - a1) * mFilterSlope; + float a2_slope = (next_a2 - a2) * mFilterSlope; + float b1_slope = (next_b1 - b1) * mFilterSlope; + float b2_slope = (next_b2 - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * y0 + a1 * y1 + a2 * y2; + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * y2 + a1 * y0 + a2 * y1; + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * y1 + a1 * y2 + a2 * y0; + + a0 += a0_slope; + a1 += a1_slope; + a2 += a2_slope; + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * y0 + a1 * y1 + a2 * y2; + y2 = y1; + y1 = y0; + } + + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + +/* no kr SOS */ diff --git a/sc4pd/source/TExpRand.cpp b/sc4pd/source/TExpRand.cpp new file mode 100644 index 0000000..a0087e7 --- /dev/null +++ b/sc4pd/source/TExpRand.cpp @@ -0,0 +1,210 @@ +/* sc4pd + TExpRand, TExpRand~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Assif Tsahar: Open Systems + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ TExpRand~ -------------------------------*/ + +class TExpRand_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(TExpRand_ar,sc4pd_dsp); + +public: + TExpRand_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_bang(); + + void m_sethi(float f) + { + hi = f; + ratio = hi / lo; + } + + void m_setlo(float f) + { + lo = f; + ratio = hi / lo; + } + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_sample; + float lo; + float hi; + float ratio; + RGen rgen; + + FLEXT_CALLBACK(m_bang); + FLEXT_CALLBACK_F(m_setlo); + FLEXT_CALLBACK_F(m_sethi); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("TExpRand~",TExpRand_ar); + +TExpRand_ar::TExpRand_ar(int argc, t_atom *argv) +{ + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + ratio = hi / lo; + + rgen.init(timeseed()); + + AddOutSignal(); + + FLEXT_ADDBANG(0,m_bang); + FLEXT_ADDMETHOD_(0,"setlo",m_setlo); + FLEXT_ADDMETHOD_(0,"sethi",m_sethi); + FLEXT_ADDMETHOD_(0,"seed",m_seed); +} + +void TExpRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + m_sample = pow(ratio, rgen.frand()) * lo; +} + + +void TExpRand_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float sample = m_sample; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = sample; + } +} + +void TExpRand_ar::m_bang() +{ + m_sample = pow(ratio, rgen.frand()) * lo; +} + +/* ------------------------ TExpRand ---------------------------------*/ + +class TExpRand_kr: + public flext_base +{ + FLEXT_HEADER(TExpRand_kr,flext_base); + +public: + TExpRand_kr(int argc, t_atom *argv); + +protected: + void m_loadbang(); + void m_bang(); + + void m_sethi(float f) + { + hi = f; + ratio = hi / lo; + } + + void m_setlo(float f) + { + lo = f; + ratio = hi / lo; + } + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float lo; + float hi; + float ratio; + RGen rgen; + FLEXT_CALLBACK(m_bang); + FLEXT_CALLBACK_F(m_setlo); + FLEXT_CALLBACK_F(m_sethi); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("TExpRand",TExpRand_kr); + +TExpRand_kr::TExpRand_kr(int argc, t_atom *argv) +{ + AtomList Args(argc,argv); + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + ratio = hi / lo; + + rgen.init(timeseed()); + + AddOutFloat(); + + FLEXT_ADDBANG(0,m_bang); + FLEXT_ADDMETHOD_(0,"setlo",m_setlo); + FLEXT_ADDMETHOD_(0,"sethi",m_sethi); + FLEXT_ADDMETHOD_(0,"seed",m_seed); +} + +void TExpRand_kr::m_loadbang() +{ + ToOutFloat(0,pow(ratio, rgen.frand()) * lo); +} + +void TExpRand_kr::m_bang() +{ + ToOutFloat(0,pow(ratio, rgen.frand()) * lo); +} diff --git a/sc4pd/source/TIRand.cpp b/sc4pd/source/TIRand.cpp new file mode 100644 index 0000000..1c59a6e --- /dev/null +++ b/sc4pd/source/TIRand.cpp @@ -0,0 +1,210 @@ +/* sc4pd + TIRand, TIRand~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Sachiko M: Debris + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ TIRand~ -------------------------------*/ + +class TIRand_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(TIRand_ar,sc4pd_dsp); + +public: + TIRand_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_bang(); + + void m_sethi(int i) + { + hi = i; + range = hi - lo; + } + + void m_setlo(int i) + { + lo = i; + range = hi - lo; + } + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_sample; + int lo; + int hi; + int range; + RGen rgen; + + FLEXT_CALLBACK(m_bang); + FLEXT_CALLBACK_I(m_setlo); + FLEXT_CALLBACK_I(m_sethi); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("TIRand~",TIRand_ar); + +TIRand_ar::TIRand_ar(int argc, t_atom *argv) +{ + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=int(sc_getfloatarg(Args,0)); + hi=int(sc_getfloatarg(Args,1)); + range = hi - lo; + + rgen.init(timeseed()); + + AddOutSignal(); + + FLEXT_ADDBANG(0,m_bang); + FLEXT_ADDMETHOD_(0,"setlo",m_setlo); + FLEXT_ADDMETHOD_(0,"sethi",m_sethi); + FLEXT_ADDMETHOD_(0,"seed",m_seed); +} + +void TIRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + m_sample = float(rgen.irand(range) + lo); +} + + +void TIRand_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float sample = m_sample; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = sample; + } +} + +void TIRand_ar::m_bang() +{ + m_sample = float(rgen.irand(range) + lo); +} + +/* ------------------------ TIRand ---------------------------------*/ + +class TIRand_kr: + public flext_base +{ + FLEXT_HEADER(TIRand_kr,flext_base); + +public: + TIRand_kr(int argc, t_atom *argv); + +protected: + void m_loadbang(); + void m_bang(); + + void m_sethi(int i) + { + hi = i; + range = hi - lo; + } + + void m_setlo(int i) + { + lo = i; + range = hi - lo; + } + + void m_seed(int i) + { + rgen.init(i); + } + +private: + int lo; + int hi; + int range; + RGen rgen; + FLEXT_CALLBACK(m_bang); + FLEXT_CALLBACK_I(m_setlo); + FLEXT_CALLBACK_I(m_sethi); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("TIRand",TIRand_kr); + +TIRand_kr::TIRand_kr(int argc, t_atom *argv) +{ + AtomList Args(argc,argv); + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=int(sc_getfloatarg(Args,0)); + hi=int(sc_getfloatarg(Args,1)); + range = hi - lo; + + rgen.init(timeseed()); + + AddOutInt(); + + FLEXT_ADDBANG(0,m_bang); + FLEXT_ADDMETHOD_(0,"setlo",m_setlo); + FLEXT_ADDMETHOD_(0,"sethi",m_sethi); + FLEXT_ADDMETHOD_(0,"seed",m_seed); +} + +void TIRand_kr::m_loadbang() +{ + ToOutInt(0,rgen.irand(range) + lo); +} + +void TIRand_kr::m_bang() +{ + ToOutInt(0,rgen.irand(range) + lo); +} diff --git a/sc4pd/source/TRand.cpp b/sc4pd/source/TRand.cpp new file mode 100644 index 0000000..d54c196 --- /dev/null +++ b/sc4pd/source/TRand.cpp @@ -0,0 +1,210 @@ +/* sc4pd + TRand, TRand~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Annette Krebs & Taku Sugimoto: A Duo In Berlin + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ TRand~ -------------------------------*/ + +class TRand_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(TRand_ar,sc4pd_dsp); + +public: + TRand_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_bang(); + + void m_sethi(float f) + { + hi = f; + range = hi - lo; + } + + void m_setlo(float f) + { + lo = f; + range = hi - lo; + } + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_sample; + float lo; + float hi; + float range; + RGen rgen; + + FLEXT_CALLBACK(m_bang); + FLEXT_CALLBACK_F(m_setlo); + FLEXT_CALLBACK_F(m_sethi); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("TRand~",TRand_ar); + +TRand_ar::TRand_ar(int argc, t_atom *argv) +{ + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + range = hi - lo; + + rgen.init(timeseed()); + + AddOutSignal(); + + FLEXT_ADDBANG(0,m_bang); + FLEXT_ADDMETHOD_(0,"setlo",m_setlo); + FLEXT_ADDMETHOD_(0,"sethi",m_sethi); + FLEXT_ADDMETHOD_(0,"seed",m_seed); +} + +void TRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + m_sample = rgen.frand() * range + lo; +} + + +void TRand_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float sample = m_sample; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = sample; + } +} + +void TRand_ar::m_bang() +{ + m_sample = rgen.frand() * range + lo; +} + +/* ------------------------ TRand ---------------------------------*/ + +class TRand_kr: + public flext_base +{ + FLEXT_HEADER(TRand_kr,flext_base); + +public: + TRand_kr(int argc, t_atom *argv); + +protected: + void m_loadbang(); + void m_bang(); + + void m_sethi(float f) + { + hi = f; + range = hi - lo; + } + + void m_setlo(float f) + { + lo = f; + range = hi - lo; + } + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float lo; + float hi; + float range; + RGen rgen; + FLEXT_CALLBACK(m_bang); + FLEXT_CALLBACK_F(m_setlo); + FLEXT_CALLBACK_F(m_sethi); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("TRand",TRand_kr); + +TRand_kr::TRand_kr(int argc, t_atom *argv) +{ + AtomList Args(argc,argv); + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + range = hi - lo; + + rgen.init(timeseed()); + + AddOutFloat(); + + FLEXT_ADDBANG(0,m_bang); + FLEXT_ADDMETHOD_(0,"setlo",m_setlo); + FLEXT_ADDMETHOD_(0,"sethi",m_sethi); + FLEXT_ADDMETHOD_(0,"seed",m_seed); +} + +void TRand_kr::m_loadbang() +{ + ToOutFloat(0,rgen.frand() * range + lo); +} + +void TRand_kr::m_bang() +{ + ToOutFloat(0,rgen.frand() * range + lo); +} diff --git a/sc4pd/source/TwoPole.cpp b/sc4pd/source/TwoPole.cpp new file mode 100644 index 0000000..b37d17f --- /dev/null +++ b/sc4pd/source/TwoPole.cpp @@ -0,0 +1,167 @@ +/* sc4pd + TwoPole~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: VA: Insight + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ TwoPole~ -------------------------------*/ + +class TwoPole_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(TwoPole_ar,sc4pd_dsp); + +public: + TwoPole_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + } + + void m_set_freq(float f) + { + m_freq=f; + changed = true; + } + + void m_set_radius(float f) + { + m_reson=f; + changed = true; + } + + +private: + float m_b1, m_b2, m_y1, m_y2, m_freq, m_reson; + bool changed; + float mRadiansPerSample, mFilterSlope; + int mFilterLoops, mFilterRemain; + + FLEXT_CALLBACK_F(m_set_freq); + FLEXT_CALLBACK_F(m_set_radius); +}; + +FLEXT_LIB_DSP_V("TwoPole~",TwoPole_ar); + +TwoPole_ar::TwoPole_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq); + FLEXT_ADDMETHOD_(0,"kradius",m_set_radius); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + m_reson = sc_getfloatarg(Args,1); + changed = false; + + AddOutSignal(); + + m_b1 = 0.f; + m_b2 = 0.f; + m_y1 = 0.f; + m_y2 = 0.f; +} + +void TwoPole_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float y0; + float y1 = m_y1; + float y2 = m_y2; + + if (changed) + { + float b1 = m_b1; + float b2 = m_b2; + float b1_next = 2.f * m_reson * cos(m_freq * mRadiansPerSample); + float b2_next = -(m_reson * m_reson); + float b1_slope = (b1_next - b1) * mFilterSlope; + float b2_slope = (b2_next - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + ZXP(nout) = y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = y1 = ZXP(nin) + b1 * y2 + b2 * y0; + + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + ZXP(nout) = y0 = ZXP(nin) + b1 * y1 + b2 * y2; + y2 = y1; + y1 = y0; + } + + m_b1 = b1; + m_b2 = b2; + changed = false; + } + else + { + float b1 = m_b1; + float b2 = m_b2; + + for (int i = 0; i!= mFilterLoops;++i) + { + ZXP(nout) = y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = y1 = ZXP(nin) + b1 * y2 + b2 * y0; + } + for (int i = 0; i!= mFilterRemain;++i) + { + ZXP(nout) = y0 = ZXP(nin) + b1 * y1 + b2 * y2; + y2 = y1; + y1 = y0; + } + } + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + +/* no control rate two pole filter */ diff --git a/sc4pd/source/TwoZero.cpp b/sc4pd/source/TwoZero.cpp new file mode 100644 index 0000000..85a7633 --- /dev/null +++ b/sc4pd/source/TwoZero.cpp @@ -0,0 +1,175 @@ +/* sc4pd + TwoZero~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: VA: Insight + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ TwoZero~ -------------------------------*/ + +class TwoZero_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(TwoZero_ar,sc4pd_dsp); + +public: + TwoZero_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + } + + void m_set_freq(float f) + { + m_freq=f; + changed = true; + } + + void m_set_radius(float f) + { + m_reson=f; + changed = true; + } + + +private: + float m_b1, m_b2, m_x1, m_x2, m_freq, m_reson; + bool changed; + float mRadiansPerSample, mFilterSlope; + int mFilterLoops, mFilterRemain; + + FLEXT_CALLBACK_F(m_set_freq); + FLEXT_CALLBACK_F(m_set_radius); +}; + +FLEXT_LIB_DSP_V("TwoZero~",TwoZero_ar); + +TwoZero_ar::TwoZero_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq); + FLEXT_ADDMETHOD_(0,"kradius",m_set_radius); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + m_reson = sc_getfloatarg(Args,1); + changed = false; + + AddOutSignal(); + + m_b1 = 0.f; + m_b2 = 0.f; + m_x1 = 0.f; + m_x2 = 0.f; +} + +void TwoZero_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float x0; + float x1 = m_x1; + float x2 = m_x2; + + if (changed) + { + float b1 = m_b1; + float b2 = m_b2; + float b1_next = -2.f * m_reson * cos(m_freq * mRadiansPerSample); + float b2_next = (m_reson * m_reson); + float b1_slope = (b1_next - b1) * mFilterSlope; + float b2_slope = (b2_next - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + x0 = ZXP(nin); + ZXP(nout) = x0 + b1 * x1 + b2 * x2; + x2 = ZXP(nin); + ZXP(nout) = x2 + b1 * x0 + b2 * x1; + x1 = ZXP(nin); + ZXP(nout) = x1 + b1 * x2 + b2 * x0; + + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + x0 = ZXP(nin); + ZXP(nout) = x0 + b1 * x1 + b2 * x2; + x2 = x1; + x1 = x0; + } + + m_b1 = b1; + m_b2 = b2; + changed = false; + } + else + { + float b1 = m_b1; + float b2 = m_b2; + + for (int i = 0; i!= mFilterLoops;++i) + { + x0 = ZXP(nin); + ZXP(nout) = x0 + b1 * x1 + b2 * x2; + x2 = ZXP(nin); + ZXP(nout) = x2 + b1 * x0 + b2 * x1; + x1 = ZXP(nin); + ZXP(nout) = x1 + b1 * x2 + b2 * x0; + } + for (int i = 0; i!= mFilterRemain;++i) + { + x0 = ZXP(nin); + ZXP(nout) = x0 + b1 * x1 + b2 * x2; + x2 = x1; + x1 = x0; + } + } + m_x1 = x1; + m_x2 = x2; +} + +/* no control rate twozero filter */ diff --git a/sc4pd/source/WhiteNoise.cpp b/sc4pd/source/WhiteNoise.cpp new file mode 100644 index 0000000..5def735 --- /dev/null +++ b/sc4pd/source/WhiteNoise.cpp @@ -0,0 +1,137 @@ +/* sc4pd + WhiteNoise, WhiteNoise~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Otomo Yoshihide: Ensemble Cathode + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ WhiteNoise~ -------------------------------*/ + +class WhiteNoise_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(WhiteNoise_ar,sc4pd_dsp); + +public: + WhiteNoise_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("WhiteNoise~",WhiteNoise_ar); + +WhiteNoise_ar::WhiteNoise_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + AddOutSignal(); +} + + +void WhiteNoise_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + RGET; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = frand2(s1, s2, s3); + } + + RPUT +} + + +/* ------------------------ WhiteNoise ---------------------------------*/ + +class WhiteNoise_kr: + public flext_base +{ + FLEXT_HEADER(WhiteNoise_kr,flext_base); + +public: + WhiteNoise_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + RGen rgen; + FLEXT_CALLBACK(m_perform); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("WhiteNoise",WhiteNoise_kr); + +WhiteNoise_kr::WhiteNoise_kr(int argc, t_atom *argv) +{ + FLEXT_ADDBANG(0,m_perform); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + AddOutFloat(); +} + +void WhiteNoise_kr::m_perform() +{ + ToOutFloat(0,rgen.frand2()); +} diff --git a/sc4pd/source/absdif.cpp b/sc4pd/source/absdif.cpp new file mode 100644 index 0000000..e31a3dd --- /dev/null +++ b/sc4pd/source/absdif.cpp @@ -0,0 +1,132 @@ +/* sc4pd + absdif, absdif~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + + +inline float sc_absdif (float a, float b) +{ + float f=a-b; + return fabsf(f); +} + + +/* ------------------------ absdif~ -----------------------------*/ + +class absdif_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(absdif_ar,sc4pd_dsp); + +public: + absdif_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("absdif~",absdif_ar); + +absdif_ar::absdif_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void absdif_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_absdif( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ absdif ------------------------------*/ + +class absdif_kr + :public flext_base +{ + FLEXT_HEADER(absdif_kr,flext_base); + +public: + absdif_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("absdif",absdif_kr); + +absdif_kr::absdif_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void absdif_kr::m_perform(float f) +{ + ToOutFloat(0,sc_absdif(f,b)); +} + +void absdif_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/amclip.cpp b/sc4pd/source/amclip.cpp new file mode 100644 index 0000000..8bd2edf --- /dev/null +++ b/sc4pd/source/amclip.cpp @@ -0,0 +1,128 @@ +/* sc4pd + amclip, amclip(~) + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & Toshimaru Nakamura: Weather Sky + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ amclip~ -----------------------------*/ + +class amclip_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(amclip_ar,sc4pd_dsp); + +public: + amclip_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("amclip~",amclip_ar); + +amclip_ar::amclip_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void amclip_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_amclip( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ amclip ------------------------------*/ + +class amclip_kr + :public flext_base +{ + FLEXT_HEADER(amclip_kr,flext_base); + +public: + amclip_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("amclip",amclip_kr); + +amclip_kr::amclip_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void amclip_kr::m_perform(float f) +{ + ToOutFloat(0,f*b); +} + +void amclip_kr::m_set(float f) +{ + if (f>0) + b=f; + else + b=0; +} diff --git a/sc4pd/source/difsqr.cpp b/sc4pd/source/difsqr.cpp new file mode 100644 index 0000000..26051f4 --- /dev/null +++ b/sc4pd/source/difsqr.cpp @@ -0,0 +1,131 @@ +/* sc4pd + difsqr, difsqr~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + + +inline float sc_difsqr (float a, float b) +{ + return a*a-b*b; +} + + +/* ------------------------ difsqr~ -----------------------------*/ + +class difsqr_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(difsqr_ar,sc4pd_dsp); + +public: + difsqr_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("difsqr~",difsqr_ar); + +difsqr_ar::difsqr_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void difsqr_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_difsqr( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ difsqr ------------------------------*/ + +class difsqr_kr + :public flext_base +{ + FLEXT_HEADER(difsqr_kr,flext_base); + +public: + difsqr_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("difsqr",difsqr_kr); + +difsqr_kr::difsqr_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void difsqr_kr::m_perform(float f) +{ + ToOutFloat(0,sc_difsqr(f,b)); +} + +void difsqr_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/excess.cpp b/sc4pd/source/excess.cpp new file mode 100644 index 0000000..eeefb3d --- /dev/null +++ b/sc4pd/source/excess.cpp @@ -0,0 +1,124 @@ +/* sc4pd + excess, excess~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & Toshimaru Nakamura: Weather Sky + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ excess~ -----------------------------*/ + +class excess_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(excess_ar,sc4pd_dsp); + +public: + excess_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("excess~",excess_ar); + +excess_ar::excess_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void excess_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_excess( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ excess ------------------------------*/ + +class excess_kr + :public flext_base +{ + FLEXT_HEADER(excess_kr,flext_base); + +public: + excess_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("excess",excess_kr); + +excess_kr::excess_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void excess_kr::m_perform(float f) +{ + ToOutFloat(0,sc_excess(f,b)); +} + +void excess_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/fftlib.c b/sc4pd/source/fftlib.c new file mode 100644 index 0000000..4bbdcb1 --- /dev/null +++ b/sc4pd/source/fftlib.c @@ -0,0 +1,3306 @@ +/* FFT library */ +/* Library of in-place fast fourier transforms */ +/* Forward and inverse complex transforms */ +/* and real forward transform */ +/* Optimized for RISC processors with many registers */ +/* Version 1.1 John Green NUWC New London CT January 96 */ +/* Version 1.1 renamed as fftlib from fftbig */ +/* Version 1.1 removed (float *)((char *) ptr) optimization */ +/* Version 1.0 John Green NUWC New London CT December 95 */ +/* (John Green) green_jt@vsdec.nl.nuwc.navy.mil */ +/* green_jt@vsdec.nl.nuwc.navy.mil */ + +#include <math.h> +#include "fftlib.h" + +#define MAXMROOT 9 /* 2^(MAXMROOT-1) = # of elements in BRcnt */ + +/* Bit reversed counter */ +static const unsigned char BRcnt[256] = { + 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, + 48, 176, 112, 240, 8, 136, 72, 200, 40, 168, 104, 232, + 24, 152, 88, 216, 56, 184, 120, 248, 4, 132, 68, 196, + 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244, + 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, + 60, 188, 124, 252, 2, 130, 66, 194, 34, 162, 98, 226, + 18, 146, 82, 210, 50, 178, 114, 242, 10, 138, 74, 202, + 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250, + 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, + 54, 182, 118, 246, 14, 142, 78, 206, 46, 174, 110, 238, + 30, 158, 94, 222, 62, 190, 126, 254, 1, 129, 65, 193, + 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241, + 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, + 57, 185, 121, 249, 5, 133, 69, 197, 37, 165, 101, 229, + 21, 149, 85, 213, 53, 181, 117, 245, 13, 141, 77, 205, + 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253, + 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, + 51, 179, 115, 243, 11, 139, 75, 203, 43, 171, 107, 235, + 27, 155, 91, 219, 59, 187, 123, 251, 7, 135, 71, 199, + 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247, + 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, + 63, 191, 127, 255 }; + +/* Table of powers of 2 */ +static const long Ntbl[21] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, + 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576}; + +long FFTInit(long *fftMptr, long fftN, float *Utbl){ +/* Compute cosine table and check size for complex ffts */ +/* INPUTS */ +/* fftN = size of fft */ +/* OUTPUTS */ +/* *fftMptr = log2 of fft size */ +/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */ +/* RETURNS */ +/* 1 if fftN is invalid, 0 otherwise */ +long i1, ErrVal; +ErrVal = 0; +*fftMptr = (long)(log(fftN)/log(2.0) + 0.5); +if ((*fftMptr >= 3) & (*fftMptr <= 19) & (int)(pow(2,*fftMptr)+.5) == fftN) + for (i1 = 0; i1 <= fftN/4; i1++) + Utbl[i1] = cos( ( 3.1415926535897932384626433832795 * 2.0 * i1 ) / fftN ); +else + ErrVal = 1; +return ErrVal; +} + +long rFFTInit(long *fftMptr, long fftN, float *Utbl){ +/* Compute cosine table and check size for a real input fft */ +/* INPUTS */ +/* fftN = size of fft */ +/* OUTPUTS */ +/* *fftMptr = log2 of fft size */ +/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */ +/* RETURNS */ +/* 1 if fftN is invalid, 0 otherwise */ +long i1, ErrVal; +ErrVal = 0; +*fftMptr = (long)(log(fftN)/log(2.0) + 0.5); +if ((*fftMptr >= 4) & (*fftMptr <= 20) & (int)(pow(2,*fftMptr)+.5) == fftN) + + for (i1 = 0; i1 <= fftN/4; i1++) + Utbl[i1] = cos( ( 3.1415926535897932384626433832795 * 2.0 * i1 ) / fftN ); +else + ErrVal = 1; +return ErrVal; +} + +void ffts(float *ioptr, long M, long Rows, float *Utbl){ +/* Compute in-place complex fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array */ + +long Flyinc; +long FlyOffsetA; +long FlyOffsetAIm; +long FlyOffsetB; +long FlyOffsetBIm; +long NsameU1; +long NsameU2; +long NsameU4; +long diffUcnt; +long LoopCnt; + +float scale; +float fly0r; +float fly0i; +float fly1r; +float fly1i; +float fly2r; +float fly2i; +float fly3r; +float fly3i; +float fly4r; +float fly4i; +float fly5r; +float fly5i; +float fly6r; +float fly6i; +float fly7r; +float fly7i; +float U0r; +float U0i; +float U1r; +float U1i; +float U2r; +float U2i; +float U3r; +float U3i; +float t0r; +float t0i; +float t1r; +float t1i; + +float *fly0P; +float *fly1P; +float *fly2P; +float *fly3P; + +float *U0rP; +float *U0iP; +float *U1rP; +float *U1iP; +float *U2rP; +float *U2iP; +float *IOP; +long U3offset; + +long stage; +long NdiffU; +long LoopN; + +const long BRshift = MAXMROOT - (M>>1); +const long Nrems2 = Ntbl[M-(M>>1)+1]; +const long Nroot_1_ColInc = (Ntbl[M-1]-Ntbl[M-(M>>1)])*2; + +scale = 2.0; +for (;Rows>0;Rows--){ + +FlyOffsetA = Ntbl[M] * (2/2); +FlyOffsetAIm = FlyOffsetA + 1; +FlyOffsetB = FlyOffsetA + 2; +FlyOffsetBIm = FlyOffsetB + 1; + +/* BitrevR2 ** bit reverse and first radix 2 stage ******/ + +for (stage = 0; stage < Ntbl[M-(M>>1)]*2; stage += Ntbl[M>>1]*2){ + for (LoopN = (Ntbl[(M>>1)-1]-1); LoopN >= 0; LoopN--){ + LoopCnt = (Ntbl[(M>>1)-1]-1); + fly0P = ioptr+ Nroot_1_ColInc + ((int)BRcnt[LoopN] >> BRshift)*(2*2) + stage; + IOP = ioptr + (LoopN<<(M+1)/2) * 2 + stage; + fly1P = IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2); + fly0r = *(fly0P); + fly0i = *(fly0P+1); + fly1r = *(fly0P+FlyOffsetA); + fly1i = *(fly0P+FlyOffsetAIm); + for (; LoopCnt > LoopN;){ + fly2r = *(fly0P+2); + fly2i = *(fly0P+(2+1)); + fly3r = *(fly0P+FlyOffsetB); + fly3i = *(fly0P+FlyOffsetBIm); + fly4r = *(fly1P); + fly4i = *(fly1P+1); + fly5r = *(fly1P+FlyOffsetA); + fly5i = *(fly1P+FlyOffsetAIm); + fly6r = *(fly1P+2); + fly6i = *(fly1P+(2+1)); + fly7r = *(fly1P+FlyOffsetB); + fly7i = *(fly1P+FlyOffsetBIm); + + t0r = fly0r + fly1r; + t0i = fly0i + fly1i; + fly1r = fly0r - fly1r; + fly1i = fly0i - fly1i; + t1r = fly2r + fly3r; + t1i = fly2i + fly3i; + fly3r = fly2r - fly3r; + fly3i = fly2i - fly3i; + fly0r = fly4r + fly5r; + fly0i = fly4i + fly5i; + fly5r = fly4r - fly5r; + fly5i = fly4i - fly5i; + fly2r = fly6r + fly7r; + fly2i = fly6i + fly7i; + fly7r = fly6r - fly7r; + fly7i = fly6i - fly7i; + + *(fly1P) = t0r; + *(fly1P+1) = t0i; + *(fly1P+2) = fly1r; + *(fly1P+(2+1)) = fly1i; + *(fly1P+FlyOffsetA) = t1r; + *(fly1P+FlyOffsetAIm) = t1i; + *(fly1P+FlyOffsetB) = fly3r; + *(fly1P+FlyOffsetBIm) = fly3i; + *(fly0P) = fly0r; + *(fly0P+1) = fly0i; + *(fly0P+2) = fly5r; + *(fly0P+(2+1)) = fly5i; + *(fly0P+FlyOffsetA) = fly2r; + *(fly0P+FlyOffsetAIm) = fly2i; + *(fly0P+FlyOffsetB) = fly7r; + *(fly0P+FlyOffsetBIm) = fly7i; + + fly0P -= Nrems2; + fly0r = *(fly0P); + fly0i = *(fly0P+1); + fly1r = *(fly0P+FlyOffsetA); + fly1i = *(fly0P+FlyOffsetAIm); + LoopCnt -= 1; + fly1P = (IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2)); + }; + fly2r = *(fly0P+2); + fly2i = *(fly0P+(2+1)); + fly3r = *(fly0P+FlyOffsetB); + fly3i = *(fly0P+FlyOffsetBIm); + + t0r = fly0r + fly1r; + t0i = fly0i + fly1i; + fly1r = fly0r - fly1r; + fly1i = fly0i - fly1i; + t1r = fly2r + fly3r; + t1i = fly2i + fly3i; + fly3r = fly2r - fly3r; + fly3i = fly2i - fly3i; + + *(fly0P) = t0r; + *(fly0P+1) = t0i; + *(fly0P+2) = fly1r; + *(fly0P+(2+1)) = fly1i; + *(fly0P+FlyOffsetA) = t1r; + *(fly0P+FlyOffsetAIm) = t1i; + *(fly0P+FlyOffsetB) = fly3r; + *(fly0P+FlyOffsetBIm) = fly3i; + + }; +}; + + + +/**** FFTC **************/ + +NdiffU = 2; +Flyinc = (NdiffU); + +NsameU4 = Ntbl[M]/4; +LoopN = Ntbl[M-3]; + +stage = ((M-1)/3); +if ( (M-1-(stage * 3)) != 0 ){ + FlyOffsetA = Flyinc << 2; + FlyOffsetB = FlyOffsetA << 1; + FlyOffsetAIm = FlyOffsetA + 1; + FlyOffsetBIm = FlyOffsetB + 1; + if ( (M-1-(stage * 3)) == 1 ){ + /* 1 radix 2 stage */ + + IOP = ioptr; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + /* Butterflys */ + /* + t0 - - t0 + t1 - - t1 + f2 - 1- f5 + f1 - -i- f7 + f4 - - f4 + f0 - - f0 + f6 - 1- f2 + f3 - -i- f1 + */ + + for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){ + t0r = *(fly0P); + t0i = *(fly0P + 1); + t1r = *(fly1P); + t1i = *(fly1P + 1); + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly1r = *(fly3P); + fly1i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly0r = *(fly1P + FlyOffsetA); + fly0i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly3r = *(fly3P + FlyOffsetA); + fly3i = *(fly3P + FlyOffsetAIm); + + fly5r = t0r - fly2r; + fly5i = t0i - fly2i; + t0r = t0r + fly2r; + t0i = t0i + fly2i; + + fly7r = t1r - fly1i; + fly7i = t1i + fly1r; + t1r = t1r + fly1i; + t1i = t1i - fly1r; + + fly2r = fly4r - fly6r; + fly2i = fly4i - fly6i; + fly4r = fly4r + fly6r; + fly4i = fly4i + fly6i; + + fly1r = fly0r - fly3i; + fly1i = fly0i + fly3r; + fly0r = fly0r + fly3i; + fly0i = fly0i - fly3r; + + *(fly2P) = fly5r; + *(fly2P + 1) = fly5i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + *(fly0P + FlyOffsetA) = fly4r; + *(fly0P + FlyOffsetAIm) = fly4i; + *(fly3P + FlyOffsetA) = fly1r; + *(fly3P + FlyOffsetAIm) = fly1i; + *(fly1P + FlyOffsetA) = fly0r; + *(fly1P + FlyOffsetAIm) = fly0i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + }; + + NsameU4 >>= 1; + LoopN >>= 1; + NdiffU <<= 1; + Flyinc = Flyinc << 1; + } + else{ + /* 1 radix 4 stage */ + IOP = ioptr; + + U3r = 0.7071067811865475244008443621; /* sqrt(0.5); */ + U3i = U3r; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + /* Butterflys */ + /* + t0 - - t0 - - t0 + t1 - - t1 - - t1 + f2 - 1- f5 - - f5 + f1 - -i- f7 - - f7 + f4 - - f4 - 1- f6 + f0 - - f0 -U3 - f3 + f6 - 1- f2 - -i- f4 + f3 - -i- f1 -U3a- f2 + */ + + for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){ + t0r = *(fly0P); + t0i = *(fly0P + 1); + t1r = *(fly1P); + t1i = *(fly1P + 1); + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly1r = *(fly3P); + fly1i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly0r = *(fly1P + FlyOffsetA); + fly0i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly3r = *(fly3P + FlyOffsetA); + fly3i = *(fly3P + FlyOffsetAIm); + + fly5r = t0r - fly2r; + fly5i = t0i - fly2i; + t0r = t0r + fly2r; + t0i = t0i + fly2i; + + fly7r = t1r - fly1i; + fly7i = t1i + fly1r; + t1r = t1r + fly1i; + t1i = t1i - fly1r; + + fly2r = fly4r - fly6r; + fly2i = fly4i - fly6i; + fly4r = fly4r + fly6r; + fly4i = fly4i + fly6i; + + fly1r = fly0r - fly3i; + fly1i = fly0i + fly3r; + fly0r = fly0r + fly3i; + fly0i = fly0i - fly3r; + + + fly6r = t0r - fly4r; + fly6i = t0i - fly4i; + t0r = t0r + fly4r; + t0i = t0i + fly4i; + + fly3r = fly5r - fly2i; + fly3i = fly5i + fly2r; + fly5r = fly5r + fly2i; + fly5i = fly5i - fly2r; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r - U3i * fly0i; + fly4i = t1i + U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly2r = fly7r + U3i * fly1r; + fly2r = fly2r - U3r * fly1i; + fly2i = fly7i + U3r * fly1r; + fly2i = fly2i + U3i * fly1i; + fly7r = scale * fly7r - fly2r; + fly7i = scale * fly7i - fly2i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly2P + FlyOffsetA) = fly3r; + *(fly2P + FlyOffsetAIm) = fly3i; + *(fly2P) = fly5r; + *(fly2P + 1) = fly5i; + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + *(fly3P + FlyOffsetA) = fly2r; + *(fly3P + FlyOffsetAIm) = fly2i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + + }; + + NsameU4 >>= 2; + LoopN >>= 2; + NdiffU <<= 2; + Flyinc = Flyinc << 2; + }; +}; + +NsameU2 = NsameU4 >> 1; +NsameU1 = NsameU2 >> 1; +Flyinc <<= 1; +FlyOffsetA = Flyinc << 2; +FlyOffsetB = FlyOffsetA << 1; +FlyOffsetAIm = FlyOffsetA + 1; +FlyOffsetBIm = FlyOffsetB + 1; +LoopN >>= 1; +/* ****** RADIX 8 Stages */ +for (stage = stage<<1; stage > 0 ; stage--){ + + /* an fft stage is done in two parts to ease use of the single quadrant cos table */ + +/* fftcalc1(iobuf, Utbl, N, NdiffU, LoopN); */ + if(!(stage&1)){ + U0rP = &Utbl[0]; + U0iP = &Utbl[Ntbl[M-2]]; + U1rP = U0rP; + U1iP = U0iP; + U2rP = U0rP; + U2iP = U0iP; + U3offset = (Ntbl[M]) / 8; + + IOP = ioptr; + + U0r = *U0rP, + U0i = *U0iP; + U1r = *U1rP, + U1i = *U1iP; + U2r = *U2rP, + U2i = *U2iP; + U3r = *( U2rP + U3offset); + U3i = *( U2iP - U3offset); + } + + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + for (diffUcnt = (NdiffU)>>1; diffUcnt != 0; diffUcnt--){ + + /* Butterflys */ + /* + f0 - - t0 - - t0 - - t0 + f1 -U0 - t1 - - t1 - - t1 + f2 - - f2 -U1 - f5 - - f3 + f3 -U0 - f1 -U1a- f7 - - f7 + f4 - - f4 - - f4 -U2 - f6 + f5 -U0 - f0 - - f0 -U3 - f4 + f6 - - f6 -U1 - f2 -U2a- f2 + f7 -U0 - f3 -U1a- f1 -U3a- f5 + */ + + fly0r = *(IOP); + fly0i = *(IOP+1); + fly1r = *(fly1P); + fly1i = *(fly1P+1); + + for (LoopCnt = LoopN-1; LoopCnt > 0 ; LoopCnt--){ + + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly3r = *(fly3P); + fly3i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly5r = *(fly1P + FlyOffsetA); + fly5i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly7r = *(fly3P + FlyOffsetA); + fly7i = *(fly3P + FlyOffsetAIm); + + t1r = fly0r - U0r * fly1r; + t1r = t1r - U0i * fly1i; + t1i = fly0i + U0i * fly1r; + t1i = t1i - U0r * fly1i; + t0r = scale * fly0r - t1r; + t0i = scale * fly0i - t1i; + + fly1r = fly2r - U0r * fly3r; + fly1r = fly1r - U0i * fly3i; + fly1i = fly2i + U0i * fly3r; + fly1i = fly1i - U0r * fly3i; + fly2r = scale * fly2r - fly1r; + fly2i = scale * fly2i - fly1i; + + fly0r = fly4r - U0r * fly5r; + fly0r = fly0r - U0i * fly5i; + fly0i = fly4i + U0i * fly5r; + fly0i = fly0i - U0r * fly5i; + fly4r = scale * fly4r - fly0r; + fly4i = scale * fly4i - fly0i; + + fly3r = fly6r - U0r * fly7r; + fly3r = fly3r - U0i * fly7i; + fly3i = fly6i + U0i * fly7r; + fly3i = fly3i - U0r * fly7i; + fly6r = scale * fly6r - fly3r; + fly6i = scale * fly6i - fly3i; + + + fly5r = t0r - U1r * fly2r; + fly5r = fly5r - U1i * fly2i; + fly5i = t0i + U1i * fly2r; + fly5i = fly5i - U1r * fly2i; + t0r = scale * t0r - fly5r; + t0i = scale * t0i - fly5i; + + fly7r = t1r + U1i * fly1r; + fly7r = fly7r - U1r * fly1i; + fly7i = t1i + U1r * fly1r; + fly7i = fly7i + U1i * fly1i; + t1r = scale * t1r - fly7r; + t1i = scale * t1i - fly7i; + + fly2r = fly4r - U1r * fly6r; + fly2r = fly2r - U1i * fly6i; + fly2i = fly4i + U1i * fly6r; + fly2i = fly2i - U1r * fly6i; + fly4r = scale * fly4r - fly2r; + fly4i = scale * fly4i - fly2i; + + fly1r = fly0r + U1i * fly3r; + fly1r = fly1r - U1r * fly3i; + fly1i = fly0i + U1r * fly3r; + fly1i = fly1i + U1i * fly3i; + fly0r = scale * fly0r - fly1r; + fly0i = scale * fly0i - fly1i; + + fly6r = t0r - U2r * fly4r; + fly6r = fly6r - U2i * fly4i; + fly6i = t0i + U2i * fly4r; + fly6i = fly6i - U2r * fly4i; + t0r = scale * t0r - fly6r; + t0i = scale * t0i - fly6i; + + fly3r = fly5r - U2i * fly2r; + fly3r = fly3r + U2r * fly2i; + fly3i = fly5i - U2r * fly2r; + fly3i = fly3i - U2i * fly2i; + fly2r = scale * fly5r - fly3r; + fly2i = scale * fly5i - fly3i; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r - U3i * fly0i; + fly4i = t1i + U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly5r = fly7r + U3i * fly1r; + fly5r = fly5r - U3r * fly1i; + fly5i = fly7i + U3r * fly1r; + fly5i = fly5i + U3i * fly1i; + fly7r = scale * fly7r - fly5r; + fly7i = scale * fly7i - fly5i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly2P) = fly3r; + *(fly2P + 1) = fly3i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + + fly0r = *(fly0P + FlyOffsetB); + fly0i = *(fly0P + FlyOffsetBIm); + + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + + fly1r = *(fly1P + FlyOffsetB); + fly1i = *(fly1P + FlyOffsetBIm); + + *(fly3P + FlyOffsetA) = fly5r; + *(fly3P + FlyOffsetAIm) = fly5i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + }; + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly3r = *(fly3P); + fly3i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly5r = *(fly1P + FlyOffsetA); + fly5i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly7r = *(fly3P + FlyOffsetA); + fly7i = *(fly3P + FlyOffsetAIm); + + t1r = fly0r - U0r * fly1r; + t1r = t1r - U0i * fly1i; + t1i = fly0i + U0i * fly1r; + t1i = t1i - U0r * fly1i; + t0r = scale * fly0r - t1r; + t0i = scale * fly0i - t1i; + + fly1r = fly2r - U0r * fly3r; + fly1r = fly1r - U0i * fly3i; + fly1i = fly2i + U0i * fly3r; + fly1i = fly1i - U0r * fly3i; + fly2r = scale * fly2r - fly1r; + fly2i = scale * fly2i - fly1i; + + fly0r = fly4r - U0r * fly5r; + fly0r = fly0r - U0i * fly5i; + fly0i = fly4i + U0i * fly5r; + fly0i = fly0i - U0r * fly5i; + fly4r = scale * fly4r - fly0r; + fly4i = scale * fly4i - fly0i; + + fly3r = fly6r - U0r * fly7r; + fly3r = fly3r - U0i * fly7i; + fly3i = fly6i + U0i * fly7r; + fly3i = fly3i - U0r * fly7i; + fly6r = scale * fly6r - fly3r; + fly6i = scale * fly6i - fly3i; + + fly5r = t0r - U1r * fly2r; + fly5r = fly5r - U1i * fly2i; + fly5i = t0i + U1i * fly2r; + fly5i = fly5i - U1r * fly2i; + t0r = scale * t0r - fly5r; + t0i = scale * t0i - fly5i; + + fly7r = t1r + U1i * fly1r; + fly7r = fly7r - U1r * fly1i; + fly7i = t1i + U1r * fly1r; + fly7i = fly7i + U1i * fly1i; + t1r = scale * t1r - fly7r; + t1i = scale * t1i - fly7i; + + fly2r = fly4r - U1r * fly6r; + fly2r = fly2r - U1i * fly6i; + fly2i = fly4i + U1i * fly6r; + fly2i = fly2i - U1r * fly6i; + fly4r = scale * fly4r - fly2r; + fly4i = scale * fly4i - fly2i; + + fly1r = fly0r + U1i * fly3r; + fly1r = fly1r - U1r * fly3i; + fly1i = fly0i + U1r * fly3r; + fly1i = fly1i + U1i * fly3i; + fly0r = scale * fly0r - fly1r; + fly0i = scale * fly0i - fly1i; + + U0i = *(U0iP = (U0iP - NsameU4)); + U0r = *(U0rP = (U0rP + NsameU4)); + U1r = *(U1rP = (U1rP + NsameU2)); + U1i = *(U1iP = (U1iP - NsameU2)); + if(stage&1) + U0r = -U0r; + + fly6r = t0r - U2r * fly4r; + fly6r = fly6r - U2i * fly4i; + fly6i = t0i + U2i * fly4r; + fly6i = fly6i - U2r * fly4i; + t0r = scale * t0r - fly6r; + t0i = scale * t0i - fly6i; + + fly3r = fly5r - U2i * fly2r; + fly3r = fly3r + U2r * fly2i; + fly3i = fly5i - U2r * fly2r; + fly3i = fly3i - U2i * fly2i; + fly2r = scale * fly5r - fly3r; + fly2i = scale * fly5i - fly3i; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r - U3i * fly0i; + fly4i = t1i + U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly5r = fly7r + U3i * fly1r; + fly5r = fly5r - U3r * fly1i; + fly5i = fly7i + U3r * fly1r; + fly5i = fly5i + U3i * fly1i; + fly7r = scale * fly7r - fly5r; + fly7i = scale * fly7i - fly5i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + + U2r = *(U2rP = (U2rP + NsameU1)); + U2i = *(U2iP = (U2iP - NsameU1)); + + *(fly2P) = fly3r; + *(fly2P + 1) = fly3i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + + U3r = *( U2rP + U3offset); + U3i = *( U2iP - U3offset); + + *(fly3P + FlyOffsetA) = fly5r; + *(fly3P + FlyOffsetAIm) = fly5i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + IOP = IOP + 2; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + }; + NsameU4 = -NsameU4; + + if(stage&1){ + LoopN >>= 3; + NsameU1 >>= 3; + NsameU2 >>= 3; + NsameU4 >>= 3; + NdiffU <<= 3; + Flyinc <<= 3; + FlyOffsetA <<= 3; + FlyOffsetB <<= 3; + FlyOffsetAIm = FlyOffsetA + 1; + FlyOffsetBIm = FlyOffsetB + 1; + } +} +ioptr += 2*Ntbl[M]; +} +} + +void iffts(float *ioptr, long M, long Rows, float *Utbl){ +/* Compute in-place inverse complex fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array */ + +long Flyinc; +long FlyOffsetA; +long FlyOffsetAIm; +long FlyOffsetB; +long FlyOffsetBIm; +long NsameU1; +long NsameU2; +long NsameU4; +long diffUcnt; +long LoopCnt; + +float scale; +float fly0r; +float fly0i; +float fly1r; +float fly1i; +float fly2r; +float fly2i; +float fly3r; +float fly3i; +float fly4r; +float fly4i; +float fly5r; +float fly5i; +float fly6r; +float fly6i; +float fly7r; +float fly7i; +float U0r; +float U0i; +float U1r; +float U1i; +float U2r; +float U2i; +float U3r; +float U3i; +float t0r; +float t0i; +float t1r; +float t1i; + +float *fly0P; +float *fly1P; +float *fly2P; +float *fly3P; +float *U0rP; +float *U0iP; +float *U1rP; +float *U1iP; +float *U2rP; +float *U2iP; +float *IOP; +long U3offset; + +long stage; +long NdiffU; +long LoopN; + +const long BRshift = MAXMROOT - (M>>1); +const long Nrems2 = Ntbl[M-(M>>1)+1]; +const long Nroot_1_ColInc = (Ntbl[M-1]-Ntbl[M-(M>>1)])*2; + +for (;Rows>0;Rows--){ + +FlyOffsetA = Ntbl[M] * 2/2; +FlyOffsetAIm = FlyOffsetA + 1; +FlyOffsetB = FlyOffsetA + 2; +FlyOffsetBIm = FlyOffsetB + 1; + +/* BitrevR2 ** bit reverse and first radix 2 stage ******/ + +scale = 1./Ntbl[M]; +for (stage = 0; stage < Ntbl[M-(M>>1)]*2; stage += Ntbl[M>>1]*2){ + for (LoopN = (Ntbl[(M>>1)-1]-1); LoopN >= 0; LoopN--){ + LoopCnt = (Ntbl[(M>>1)-1]-1); + fly0P = ioptr + Nroot_1_ColInc + ((int)BRcnt[LoopN] >> BRshift)*(2*2) + stage; + IOP = ioptr + (LoopN<<(M+1)/2) * 2 + stage; + fly1P = IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2); + fly0r = *(fly0P); + fly0i = *(fly0P+1); + fly1r = *(fly0P+FlyOffsetA); + fly1i = *(fly0P+FlyOffsetAIm); + for (; LoopCnt > LoopN;){ + fly2r = *(fly0P+2); + fly2i = *(fly0P+(2+1)); + fly3r = *(fly0P+FlyOffsetB); + fly3i = *(fly0P+FlyOffsetBIm); + fly4r = *(fly1P); + fly4i = *(fly1P+1); + fly5r = *(fly1P+FlyOffsetA); + fly5i = *(fly1P+FlyOffsetAIm); + fly6r = *(fly1P+2); + fly6i = *(fly1P+(2+1)); + fly7r = *(fly1P+FlyOffsetB); + fly7i = *(fly1P+FlyOffsetBIm); + + t0r = fly0r + fly1r; + t0i = fly0i + fly1i; + fly1r = fly0r - fly1r; + fly1i = fly0i - fly1i; + t1r = fly2r + fly3r; + t1i = fly2i + fly3i; + fly3r = fly2r - fly3r; + fly3i = fly2i - fly3i; + fly0r = fly4r + fly5r; + fly0i = fly4i + fly5i; + fly5r = fly4r - fly5r; + fly5i = fly4i - fly5i; + fly2r = fly6r + fly7r; + fly2i = fly6i + fly7i; + fly7r = fly6r - fly7r; + fly7i = fly6i - fly7i; + + *(fly1P) = scale*t0r; + *(fly1P+1) = scale*t0i; + *(fly1P+2) = scale*fly1r; + *(fly1P+(2+1)) = scale*fly1i; + *(fly1P+FlyOffsetA) = scale*t1r; + *(fly1P+FlyOffsetAIm) = scale*t1i; + *(fly1P+FlyOffsetB) = scale*fly3r; + *(fly1P+FlyOffsetBIm) = scale*fly3i; + *(fly0P) = scale*fly0r; + *(fly0P+1) = scale*fly0i; + *(fly0P+2) = scale*fly5r; + *(fly0P+(2+1)) = scale*fly5i; + *(fly0P+FlyOffsetA) = scale*fly2r; + *(fly0P+FlyOffsetAIm) = scale*fly2i; + *(fly0P+FlyOffsetB) = scale*fly7r; + *(fly0P+FlyOffsetBIm) = scale*fly7i; + + fly0P -= Nrems2; + fly0r = *(fly0P); + fly0i = *(fly0P+1); + fly1r = *(fly0P+FlyOffsetA); + fly1i = *(fly0P+FlyOffsetAIm); + LoopCnt -= 1; + fly1P = (IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2)); + }; + fly2r = *(fly0P+2); + fly2i = *(fly0P+(2+1)); + fly3r = *(fly0P+FlyOffsetB); + fly3i = *(fly0P+FlyOffsetBIm); + + t0r = fly0r + fly1r; + t0i = fly0i + fly1i; + fly1r = fly0r - fly1r; + fly1i = fly0i - fly1i; + t1r = fly2r + fly3r; + t1i = fly2i + fly3i; + fly3r = fly2r - fly3r; + fly3i = fly2i - fly3i; + + *(fly0P) = scale*t0r; + *(fly0P+1) = scale*t0i; + *(fly0P+2) = scale*fly1r; + *(fly0P+(2+1)) = scale*fly1i; + *(fly0P+FlyOffsetA) = scale*t1r; + *(fly0P+FlyOffsetAIm) = scale*t1i; + *(fly0P+FlyOffsetB) = scale*fly3r; + *(fly0P+FlyOffsetBIm) = scale*fly3i; + + }; +}; + +/**** FFTC **************/ + +scale = 2.0; + +NdiffU = 2; +Flyinc = (NdiffU); + +NsameU4 = Ntbl[M]/4; +LoopN = Ntbl[M-3]; + +stage = ((M-1)/3); +if ( (M-1-(stage * 3)) != 0 ){ + FlyOffsetA = Flyinc << 2; + FlyOffsetB = FlyOffsetA << 1; + FlyOffsetAIm = FlyOffsetA + 1; + FlyOffsetBIm = FlyOffsetB + 1; + if ( (M-1-(stage * 3)) == 1 ){ + /* 1 radix 2 stage */ + + IOP = ioptr; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + /* Butterflys */ + /* + t0 - - t0 + t1 - - t1 + f2 - 1- f5 + f1 - -i- f7 + f4 - - f4 + f0 - - f0 + f6 - 1- f2 + f3 - -i- f1 + */ + + for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){ + t0r = *(fly0P); + t0i = *(fly0P + 1); + t1r = *(fly1P); + t1i = *(fly1P + 1); + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly1r = *(fly3P); + fly1i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly0r = *(fly1P + FlyOffsetA); + fly0i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly3r = *(fly3P + FlyOffsetA); + fly3i = *(fly3P + FlyOffsetAIm); + + fly5r = t0r - fly2r; + fly5i = t0i - fly2i; + t0r = t0r + fly2r; + t0i = t0i + fly2i; + + fly7r = t1r + fly1i; + fly7i = t1i - fly1r; + t1r = t1r - fly1i; + t1i = t1i + fly1r; + + fly2r = fly4r - fly6r; + fly2i = fly4i - fly6i; + fly4r = fly4r + fly6r; + fly4i = fly4i + fly6i; + + fly1r = fly0r + fly3i; + fly1i = fly0i - fly3r; + fly0r = fly0r - fly3i; + fly0i = fly0i + fly3r; + + *(fly2P) = fly5r; + *(fly2P + 1) = fly5i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + *(fly0P + FlyOffsetA) = fly4r; + *(fly0P + FlyOffsetAIm) = fly4i; + *(fly3P + FlyOffsetA) = fly1r; + *(fly3P + FlyOffsetAIm) = fly1i; + *(fly1P + FlyOffsetA) = fly0r; + *(fly1P + FlyOffsetAIm) = fly0i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + }; + + NsameU4 >>= 1; + LoopN >>= 1; + NdiffU <<= 1; + Flyinc = Flyinc << 1; + } + else{ + /* 1 radix 4 stage */ + IOP = ioptr; + + U3r = 0.7071067811865475244008443621; /* sqrt(0.5); */ + U3i = U3r; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + /* Butterflys */ + /* + t0 - - t0 - - t0 + t1 - - t1 - - t1 + f2 - 1- f5 - - f5 + f1 - -i- f7 - - f7 + f4 - - f4 - 1- f6 + f0 - - f0 -U3 - f3 + f6 - 1- f2 - -i- f4 + f3 - -i- f1 -U3a- f2 + */ + + for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){ + t0r = *(fly0P); + t0i = *(fly0P + 1); + t1r = *(fly1P); + t1i = *(fly1P + 1); + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly1r = *(fly3P); + fly1i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly0r = *(fly1P + FlyOffsetA); + fly0i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly3r = *(fly3P + FlyOffsetA); + fly3i = *(fly3P + FlyOffsetAIm); + + fly5r = t0r - fly2r; + fly5i = t0i - fly2i; + t0r = t0r + fly2r; + t0i = t0i + fly2i; + + fly7r = t1r + fly1i; + fly7i = t1i - fly1r; + t1r = t1r - fly1i; + t1i = t1i + fly1r; + + fly2r = fly4r - fly6r; + fly2i = fly4i - fly6i; + fly4r = fly4r + fly6r; + fly4i = fly4i + fly6i; + + fly1r = fly0r + fly3i; + fly1i = fly0i - fly3r; + fly0r = fly0r - fly3i; + fly0i = fly0i + fly3r; + + fly6r = t0r - fly4r; + fly6i = t0i - fly4i; + t0r = t0r + fly4r; + t0i = t0i + fly4i; + + fly3r = fly5r + fly2i; + fly3i = fly5i - fly2r; + fly5r = fly5r - fly2i; + fly5i = fly5i + fly2r; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r + U3i * fly0i; + fly4i = t1i - U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly2r = fly7r + U3i * fly1r; + fly2r = fly2r + U3r * fly1i; + fly2i = fly7i - U3r * fly1r; + fly2i = fly2i + U3i * fly1i; + fly7r = scale * fly7r - fly2r; + fly7i = scale * fly7i - fly2i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly2P + FlyOffsetA) = fly3r; + *(fly2P + FlyOffsetAIm) = fly3i; + *(fly2P) = fly5r; + *(fly2P + 1) = fly5i; + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + *(fly3P + FlyOffsetA) = fly2r; + *(fly3P + FlyOffsetAIm) = fly2i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + + }; + + NsameU4 >>= 2; + LoopN >>= 2; + NdiffU <<= 2; + Flyinc = Flyinc << 2; + }; +}; + +NsameU2 = NsameU4 >> 1; +NsameU1 = NsameU2 >> 1; +Flyinc <<= 1; +FlyOffsetA = Flyinc << 2; +FlyOffsetB = FlyOffsetA << 1; +FlyOffsetAIm = FlyOffsetA + 1; +FlyOffsetBIm = FlyOffsetB + 1; +LoopN >>= 1; + +/* ****** RADIX 8 Stages */ +for (stage = stage<<1; stage > 0 ; stage--){ + + /* an fft stage is done in two parts to ease use of the single quadrant cos table */ + +/* fftcalc1(iobuf, Utbl, N, NdiffU, LoopN); */ + if(!(stage&1)){ + U0rP = &Utbl[0]; + U0iP = &Utbl[Ntbl[M-2]]; + U1rP = U0rP; + U1iP = U0iP; + U2rP = U0rP; + U2iP = U0iP; + U3offset = (Ntbl[M]) / 8; + + IOP = ioptr; + + U0r = *U0rP, + U0i = *U0iP; + U1r = *U1rP, + U1i = *U1iP; + U2r = *U2rP, + U2i = *U2iP; + U3r = *( U2rP + U3offset); + U3i = *( U2iP - U3offset); + } + + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + for (diffUcnt = (NdiffU)>>1; diffUcnt > 0; diffUcnt--){ + + /* Butterflys */ + /* + f0 - - t0 - - t0 - - t0 + f1 -U0 - t1 - - t1 - - t1 + f2 - - f2 -U1 - f5 - - f3 + f3 -U0 - f1 -U1a- f7 - - f7 + f4 - - f4 - - f4 -U2 - f6 + f5 -U0 - f0 - - f0 -U3 - f4 + f6 - - f6 -U1 - f2 -U2a- f2 + f7 -U0 - f3 -U1a- f1 -U3a- f5 + */ + + fly0r = *(IOP); + fly0i = *(IOP+1); + fly1r = *(fly1P); + fly1i = *(fly1P+1); + + for (LoopCnt = LoopN-1; LoopCnt > 0 ; LoopCnt--){ + + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly3r = *(fly3P); + fly3i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly5r = *(fly1P + FlyOffsetA); + fly5i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly7r = *(fly3P + FlyOffsetA); + fly7i = *(fly3P + FlyOffsetAIm); + + t1r = fly0r - U0r * fly1r; + t1r = t1r + U0i * fly1i; + t1i = fly0i - U0i * fly1r; + t1i = t1i - U0r * fly1i; + t0r = scale * fly0r - t1r; + t0i = scale * fly0i - t1i; + + fly1r = fly2r - U0r * fly3r; + fly1r = fly1r + U0i * fly3i; + fly1i = fly2i - U0i * fly3r; + fly1i = fly1i - U0r * fly3i; + fly2r = scale * fly2r - fly1r; + fly2i = scale * fly2i - fly1i; + + fly0r = fly4r - U0r * fly5r; + fly0r = fly0r + U0i * fly5i; + fly0i = fly4i - U0i * fly5r; + fly0i = fly0i - U0r * fly5i; + fly4r = scale * fly4r - fly0r; + fly4i = scale * fly4i - fly0i; + + fly3r = fly6r - U0r * fly7r; + fly3r = fly3r + U0i * fly7i; + fly3i = fly6i - U0i * fly7r; + fly3i = fly3i - U0r * fly7i; + fly6r = scale * fly6r - fly3r; + fly6i = scale * fly6i - fly3i; + + + fly5r = t0r - U1r * fly2r; + fly5r = fly5r + U1i * fly2i; + fly5i = t0i - U1i * fly2r; + fly5i = fly5i - U1r * fly2i; + t0r = scale * t0r - fly5r; + t0i = scale * t0i - fly5i; + + fly7r = t1r + U1i * fly1r; + fly7r = fly7r + U1r * fly1i; + fly7i = t1i - U1r * fly1r; + fly7i = fly7i + U1i * fly1i; + t1r = scale * t1r - fly7r; + t1i = scale * t1i - fly7i; + + fly2r = fly4r - U1r * fly6r; + fly2r = fly2r + U1i * fly6i; + fly2i = fly4i - U1i * fly6r; + fly2i = fly2i - U1r * fly6i; + fly4r = scale * fly4r - fly2r; + fly4i = scale * fly4i - fly2i; + + fly1r = fly0r + U1i * fly3r; + fly1r = fly1r + U1r * fly3i; + fly1i = fly0i - U1r * fly3r; + fly1i = fly1i + U1i * fly3i; + fly0r = scale * fly0r - fly1r; + fly0i = scale * fly0i - fly1i; + + fly6r = t0r - U2r * fly4r; + fly6r = fly6r + U2i * fly4i; + fly6i = t0i - U2i * fly4r; + fly6i = fly6i - U2r * fly4i; + t0r = scale * t0r - fly6r; + t0i = scale * t0i - fly6i; + + fly3r = fly5r - U2i * fly2r; + fly3r = fly3r - U2r * fly2i; + fly3i = fly5i + U2r * fly2r; + fly3i = fly3i - U2i * fly2i; + fly2r = scale * fly5r - fly3r; + fly2i = scale * fly5i - fly3i; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r + U3i * fly0i; + fly4i = t1i - U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly5r = fly7r + U3i * fly1r; + fly5r = fly5r + U3r * fly1i; + fly5i = fly7i - U3r * fly1r; + fly5i = fly5i + U3i * fly1i; + fly7r = scale * fly7r - fly5r; + fly7i = scale * fly7i - fly5i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly2P) = fly3r; + *(fly2P + 1) = fly3i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + + fly0r = *(fly0P + FlyOffsetB); + fly0i = *(fly0P + FlyOffsetBIm); + + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + + fly1r = *(fly1P + FlyOffsetB); + fly1i = *(fly1P + FlyOffsetBIm); + + *(fly3P + FlyOffsetA) = fly5r; + *(fly3P + FlyOffsetAIm) = fly5i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + + }; + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly3r = *(fly3P); + fly3i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly5r = *(fly1P + FlyOffsetA); + fly5i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly7r = *(fly3P + FlyOffsetA); + fly7i = *(fly3P + FlyOffsetAIm); + + t1r = fly0r - U0r * fly1r; + t1r = t1r + U0i * fly1i; + t1i = fly0i - U0i * fly1r; + t1i = t1i - U0r * fly1i; + t0r = scale * fly0r - t1r; + t0i = scale * fly0i - t1i; + + fly1r = fly2r - U0r * fly3r; + fly1r = fly1r + U0i * fly3i; + fly1i = fly2i - U0i * fly3r; + fly1i = fly1i - U0r * fly3i; + fly2r = scale * fly2r - fly1r; + fly2i = scale * fly2i - fly1i; + + fly0r = fly4r - U0r * fly5r; + fly0r = fly0r + U0i * fly5i; + fly0i = fly4i - U0i * fly5r; + fly0i = fly0i - U0r * fly5i; + fly4r = scale * fly4r - fly0r; + fly4i = scale * fly4i - fly0i; + + fly3r = fly6r - U0r * fly7r; + fly3r = fly3r + U0i * fly7i; + fly3i = fly6i - U0i * fly7r; + fly3i = fly3i - U0r * fly7i; + fly6r = scale * fly6r - fly3r; + fly6i = scale * fly6i - fly3i; + + fly5r = t0r - U1r * fly2r; + fly5r = fly5r + U1i * fly2i; + fly5i = t0i - U1i * fly2r; + fly5i = fly5i - U1r * fly2i; + t0r = scale * t0r - fly5r; + t0i = scale * t0i - fly5i; + + fly7r = t1r + U1i * fly1r; + fly7r = fly7r + U1r * fly1i; + fly7i = t1i - U1r * fly1r; + fly7i = fly7i + U1i * fly1i; + t1r = scale * t1r - fly7r; + t1i = scale * t1i - fly7i; + + fly2r = fly4r - U1r * fly6r; + fly2r = fly2r + U1i * fly6i; + fly2i = fly4i - U1i * fly6r; + fly2i = fly2i - U1r * fly6i; + fly4r = scale * fly4r - fly2r; + fly4i = scale * fly4i - fly2i; + + fly1r = fly0r + U1i * fly3r; + fly1r = fly1r + U1r * fly3i; + fly1i = fly0i - U1r * fly3r; + fly1i = fly1i + U1i * fly3i; + fly0r = scale * fly0r - fly1r; + fly0i = scale * fly0i - fly1i; + + U0i = *(U0iP = (U0iP - NsameU4)); + U0r = *(U0rP = (U0rP + NsameU4)); + U1r = *(U1rP = (U1rP + NsameU2)); + U1i = *(U1iP = (U1iP - NsameU2)); + if(stage&1) + U0r = - U0r; + + fly6r = t0r - U2r * fly4r; + fly6r = fly6r + U2i * fly4i; + fly6i = t0i - U2i * fly4r; + fly6i = fly6i - U2r * fly4i; + t0r = scale * t0r - fly6r; + t0i = scale * t0i - fly6i; + + fly3r = fly5r - U2i * fly2r; + fly3r = fly3r - U2r * fly2i; + fly3i = fly5i + U2r * fly2r; + fly3i = fly3i - U2i * fly2i; + fly2r = scale * fly5r - fly3r; + fly2i = scale * fly5i - fly3i; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r + U3i * fly0i; + fly4i = t1i - U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly5r = fly7r + U3i * fly1r; + fly5r = fly5r + U3r * fly1i; + fly5i = fly7i - U3r * fly1r; + fly5i = fly5i + U3i * fly1i; + fly7r = scale * fly7r - fly5r; + fly7i = scale * fly7i - fly5i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + + U2r = *(U2rP = (U2rP + NsameU1)); + U2i = *(U2iP = (U2iP - NsameU1)); + + *(fly2P) = fly3r; + *(fly2P + 1) = fly3i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + + U3r = *( U2rP + U3offset); + U3i = *( U2iP - U3offset); + + *(fly3P + FlyOffsetA) = fly5r; + *(fly3P + FlyOffsetAIm) = fly5i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + IOP = IOP + 2; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + }; + NsameU4 = -NsameU4; + + if(stage&1){ + LoopN >>= 3; + NsameU1 >>= 3; + NsameU2 >>= 3; + NsameU4 >>= 3; + NdiffU <<= 3; + Flyinc = Flyinc << 3; + FlyOffsetA <<= 3; + FlyOffsetB <<= 3; + FlyOffsetAIm = FlyOffsetA + 1; + FlyOffsetBIm = FlyOffsetB + 1; + } +} +ioptr += 2*Ntbl[M]; +} +} + +/* rffts */ +/* compute multiple real input FFTs on 'Rows' consecutively stored arrays */ +/* ioptr = pointer to the data in and out */ +/* M = log2 of fft size */ +/* Rows = number of FFTs to compute */ +/* Utbl = Pointer to cosine table */ + +void rffts(float *ioptr, long M, long Rows, float *Utbl){ +/* Compute in-place real fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = real input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array in the following order */ +/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */ + +long Flyinc; +long FlyOffsetA; +long FlyOffsetAIm; +long FlyOffsetB; +long FlyOffsetBIm; +long NsameU1; +long NsameU2; +long NsameU4; +long diffUcnt; +long LoopCnt; +float scale; +float fly0r; +float fly0i; +float fly1r; +float fly1i; +float fly2r; +float fly2i; +float fly3r; +float fly3i; +float fly4r; +float fly4i; +float fly5r; +float fly5i; +float fly6r; +float fly6i; +float fly7r; +float fly7i; +float U0r; +float U0i; +float U1r; +float U1i; +float U2r; +float U2i; +float U3r; +float U3i; +float t0r; +float t0i; +float t1r; +float t1i; + +float *fly0P; +float *fly1P; +float *fly2P; +float *fly3P; + +float *U0rP; +float *U0iP; +float *U1rP; +float *U1iP; +float *U2rP; +float *U2iP; +float *IOP; +long U3offset; + +long stage; +long NdiffU; +long LoopN; + +const long BRshift = MAXMROOT - ((M-1)>>1); /* for RFFT */ +const long Nrems2 = Ntbl[(M-1)-((M-1)>>1)+1]; /* for RFFT */ +const long Nroot_1_ColInc = (Ntbl[(M-1)-1]-Ntbl[(M-1)-((M-1)>>1)])*2; /* for RFFT */ + +for (;Rows>0;Rows--){ + +M=M-1; /* for RFFT */ + +FlyOffsetA = Ntbl[M] * 2/2; +FlyOffsetAIm = FlyOffsetA + 1; +FlyOffsetB = FlyOffsetA + 2; +FlyOffsetBIm = FlyOffsetB + 1; + +/* BitrevR2 ** bit reverse shuffle and first radix 2 stage ******/ + +scale = 0.5; +for (stage = 0; stage < Ntbl[M-(M>>1)]*2; stage += Ntbl[M>>1]*2){ + for (LoopN = (Ntbl[(M>>1)-1]-1); LoopN >= 0; LoopN--){ + LoopCnt = (Ntbl[(M>>1)-1]-1); + fly0P = ioptr + Nroot_1_ColInc + ((int)BRcnt[LoopN] >> BRshift)*(2*2) + stage; + IOP = ioptr + (LoopN<<(M+1)/2) * 2 + stage; + fly1P = IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2); + fly0r = *fly0P; + fly0i = *(fly0P+1); + fly1r = *(fly0P+FlyOffsetA); + fly1i = *(fly0P+FlyOffsetAIm); + for (; LoopCnt > LoopN;){ + fly2r = *(fly0P+2); + fly2i = *(fly0P+(2+1)); + fly3r = *(fly0P+FlyOffsetB); + fly3i = *(fly0P+FlyOffsetBIm); + fly4r = *fly1P; + fly4i = *(fly1P+1); + fly5r = *(fly1P+FlyOffsetA); + fly5i = *(fly1P+FlyOffsetAIm); + fly6r = *(fly1P+2); + fly6i = *(fly1P+(2+1)); + fly7r = *(fly1P+FlyOffsetB); + fly7i = *(fly1P+FlyOffsetBIm); + + t0r = fly0r + fly1r; + t0i = fly0i + fly1i; + fly1r = fly0r - fly1r; + fly1i = fly0i - fly1i; + t1r = fly2r + fly3r; + t1i = fly2i + fly3i; + fly3r = fly2r - fly3r; + fly3i = fly2i - fly3i; + fly0r = fly4r + fly5r; + fly0i = fly4i + fly5i; + fly5r = fly4r - fly5r; + fly5i = fly4i - fly5i; + fly2r = fly6r + fly7r; + fly2i = fly6i + fly7i; + fly7r = fly6r - fly7r; + fly7i = fly6i - fly7i; + + *fly1P = scale*t0r; + *(fly1P+1) = scale*t0i; + *(fly1P+2) = scale*fly1r; + *(fly1P+(2+1)) = scale*fly1i; + *(fly1P+FlyOffsetA) = scale*t1r; + *(fly1P+FlyOffsetAIm) = scale*t1i; + *(fly1P+FlyOffsetB) = scale*fly3r; + *(fly1P+FlyOffsetBIm) = scale*fly3i; + *fly0P = scale*fly0r; + *(fly0P+1) = scale*fly0i; + *(fly0P+2) = scale*fly5r; + *(fly0P+(2+1)) = scale*fly5i; + *(fly0P+FlyOffsetA) = scale*fly2r; + *(fly0P+FlyOffsetAIm) = scale*fly2i; + *(fly0P+FlyOffsetB) = scale*fly7r; + *(fly0P+FlyOffsetBIm) = scale*fly7i; + + fly0P -= Nrems2; + fly0r = *fly0P; + fly0i = *(fly0P+1); + fly1r = *(fly0P+FlyOffsetA); + fly1i = *(fly0P+FlyOffsetAIm); + LoopCnt -= 1; + fly1P = (IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2)); + }; + fly2r = *(fly0P+2); + fly2i = *(fly0P+(2+1)); + fly3r = *(fly0P+FlyOffsetB); + fly3i = *(fly0P+FlyOffsetBIm); + + t0r = fly0r + fly1r; + t0i = fly0i + fly1i; + fly1r = fly0r - fly1r; + fly1i = fly0i - fly1i; + t1r = fly2r + fly3r; + t1i = fly2i + fly3i; + fly3r = fly2r - fly3r; + fly3i = fly2i - fly3i; + + *fly0P = scale*t0r; + *(fly0P+1) = scale*t0i; + *(fly0P+2) = scale*fly1r; + *(fly0P+(2+1)) = scale*fly1i; + *(fly0P+FlyOffsetA) = scale*t1r; + *(fly0P+FlyOffsetAIm) = scale*t1i; + *(fly0P+FlyOffsetB) = scale*fly3r; + *(fly0P+FlyOffsetBIm) = scale*fly3i; + + }; +}; + + + +/**** FFTC **************/ + +scale = 2.0; + +NdiffU = 2; +Flyinc = (NdiffU); + +NsameU4 = Ntbl[M+1]/4; /* for RFFT */ +LoopN = Ntbl[M-3]; + +stage = ((M-1)/3); +if ( (M-1-(stage * 3)) != 0 ){ + FlyOffsetA = Flyinc << 2; + FlyOffsetB = FlyOffsetA << 1; + FlyOffsetAIm = FlyOffsetA + 1; + FlyOffsetBIm = FlyOffsetB + 1; + if ( (M-1-(stage * 3)) == 1 ){ + /* 1 radix 2 stage */ + + IOP = ioptr; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + /* Butterflys */ + /* + t0 - - t0 + t1 - - t1 + f2 - 1- f5 + f1 - -i- f7 + f4 - - f4 + f0 - - f0 + f6 - 1- f2 + f3 - -i- f1 + */ + + for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){ + t0r = *(fly0P); + t0i = *(fly0P + 1); + t1r = *(fly1P); + t1i = *(fly1P + 1); + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly1r = *(fly3P); + fly1i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly0r = *(fly1P + FlyOffsetA); + fly0i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly3r = *(fly3P + FlyOffsetA); + fly3i = *(fly3P + FlyOffsetAIm); + + fly5r = t0r - fly2r; + fly5i = t0i - fly2i; + t0r = t0r + fly2r; + t0i = t0i + fly2i; + + fly7r = t1r - fly1i; + fly7i = t1i + fly1r; + t1r = t1r + fly1i; + t1i = t1i - fly1r; + + fly2r = fly4r - fly6r; + fly2i = fly4i - fly6i; + fly4r = fly4r + fly6r; + fly4i = fly4i + fly6i; + + fly1r = fly0r - fly3i; + fly1i = fly0i + fly3r; + fly0r = fly0r + fly3i; + fly0i = fly0i - fly3r; + + *(fly2P) = fly5r; + *(fly2P + 1) = fly5i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + *(fly0P + FlyOffsetA) = fly4r; + *(fly0P + FlyOffsetAIm) = fly4i; + *(fly3P + FlyOffsetA) = fly1r; + *(fly3P + FlyOffsetAIm) = fly1i; + *(fly1P + FlyOffsetA) = fly0r; + *(fly1P + FlyOffsetAIm) = fly0i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + }; + + NsameU4 >>= 1; + LoopN >>= 1; + NdiffU <<= 1; + Flyinc = Flyinc << 1; + } + else{ + /* 1 radix 4 stage */ + IOP = ioptr; + + U3r = 0.7071067811865475244008443621; /* sqrt(0.5); */ + U3i = U3r; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + /* Butterflys */ + /* + t0 - - t0 - - t0 + t1 - - t1 - - t1 + f2 - 1- f5 - - f5 + f1 - -i- f7 - - f7 + f4 - - f4 - 1- f6 + f0 - - f0 -U3 - f3 + f6 - 1- f2 - -i- f4 + f3 - -i- f1 -U3a- f2 + */ + + for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){ + t0r = *(fly0P); + t0i = *(fly0P + 1); + t1r = *(fly1P); + t1i = *(fly1P + 1); + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly1r = *(fly3P); + fly1i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly0r = *(fly1P + FlyOffsetA); + fly0i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly3r = *(fly3P + FlyOffsetA); + fly3i = *(fly3P + FlyOffsetAIm); + + fly5r = t0r - fly2r; + fly5i = t0i - fly2i; + t0r = t0r + fly2r; + t0i = t0i + fly2i; + + fly7r = t1r - fly1i; + fly7i = t1i + fly1r; + t1r = t1r + fly1i; + t1i = t1i - fly1r; + + fly2r = fly4r - fly6r; + fly2i = fly4i - fly6i; + fly4r = fly4r + fly6r; + fly4i = fly4i + fly6i; + + fly1r = fly0r - fly3i; + fly1i = fly0i + fly3r; + fly0r = fly0r + fly3i; + fly0i = fly0i - fly3r; + + fly6r = t0r - fly4r; + fly6i = t0i - fly4i; + t0r = t0r + fly4r; + t0i = t0i + fly4i; + + fly3r = fly5r - fly2i; + fly3i = fly5i + fly2r; + fly5r = fly5r + fly2i; + fly5i = fly5i - fly2r; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r - U3i * fly0i; + fly4i = t1i + U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly2r = fly7r + U3i * fly1r; + fly2r = fly2r - U3r * fly1i; + fly2i = fly7i + U3r * fly1r; + fly2i = fly2i + U3i * fly1i; + fly7r = scale * fly7r - fly2r; + fly7i = scale * fly7i - fly2i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly2P + FlyOffsetA) = fly3r; + *(fly2P + FlyOffsetAIm) = fly3i; + *(fly2P) = fly5r; + *(fly2P + 1) = fly5i; + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + *(fly3P + FlyOffsetA) = fly2r; + *(fly3P + FlyOffsetAIm) = fly2i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + + }; + + NsameU4 >>= 2; + LoopN >>= 2; + NdiffU <<= 2; + Flyinc = Flyinc << 2; + }; +}; + +NsameU2 = NsameU4 >> 1; +NsameU1 = NsameU2 >> 1; +Flyinc <<= 1; +FlyOffsetA = Flyinc << 2; +FlyOffsetB = FlyOffsetA << 1; +FlyOffsetAIm = FlyOffsetA + 1; +FlyOffsetBIm = FlyOffsetB + 1; +LoopN >>= 1; + +/* ****** RADIX 8 Stages */ +for (stage = stage<<1; stage > 0 ; stage--){ + + /* an fft stage is done in two parts to ease use of the single quadrant cos table */ + +/* fftcalc1(iobuf, Utbl, N, NdiffU, LoopN); */ + if(!(stage&1)){ + U0rP = &Utbl[0]; + U0iP = &Utbl[Ntbl[M-1]]; /* for RFFT */ + U1rP = U0rP; + U1iP = U0iP; + U2rP = U0rP; + U2iP = U0iP; + U3offset = (Ntbl[M+1]) / 8; /* for RFFT */ + + IOP = ioptr; + + U0r = *U0rP, + U0i = *U0iP; + U1r = *U1rP, + U1i = *U1iP; + U2r = *U2rP, + U2i = *U2iP; + U3r = *( U2rP + U3offset); + U3i = *( U2iP - U3offset); + } + + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + for (diffUcnt = (NdiffU)>>1; diffUcnt > 0; diffUcnt--){ + + /* Butterflys */ + /* + f0 - - t0 - - t0 - - t0 + f1 -U0 - t1 - - t1 - - t1 + f2 - - f2 -U1 - f5 - - f3 + f3 -U0 - f1 -U1a- f7 - - f7 + f4 - - f4 - - f4 -U2 - f6 + f5 -U0 - f0 - - f0 -U3 - f4 + f6 - - f6 -U1 - f2 -U2a- f2 + f7 -U0 - f3 -U1a- f1 -U3a- f5 + */ + + fly0r = *(IOP); + fly0i = *(IOP+1); + fly1r = *(fly1P); + fly1i = *(fly1P+1); + + for (LoopCnt = LoopN-1; LoopCnt > 0 ; LoopCnt--){ + + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly3r = *(fly3P); + fly3i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly5r = *(fly1P + FlyOffsetA); + fly5i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly7r = *(fly3P + FlyOffsetA); + fly7i = *(fly3P + FlyOffsetAIm); + + t1r = fly0r - U0r * fly1r; + t1r = t1r - U0i * fly1i; + t1i = fly0i + U0i * fly1r; + t1i = t1i - U0r * fly1i; + t0r = scale * fly0r - t1r; + t0i = scale * fly0i - t1i; + + fly1r = fly2r - U0r * fly3r; + fly1r = fly1r - U0i * fly3i; + fly1i = fly2i + U0i * fly3r; + fly1i = fly1i - U0r * fly3i; + fly2r = scale * fly2r - fly1r; + fly2i = scale * fly2i - fly1i; + + fly0r = fly4r - U0r * fly5r; + fly0r = fly0r - U0i * fly5i; + fly0i = fly4i + U0i * fly5r; + fly0i = fly0i - U0r * fly5i; + fly4r = scale * fly4r - fly0r; + fly4i = scale * fly4i - fly0i; + + fly3r = fly6r - U0r * fly7r; + fly3r = fly3r - U0i * fly7i; + fly3i = fly6i + U0i * fly7r; + fly3i = fly3i - U0r * fly7i; + fly6r = scale * fly6r - fly3r; + fly6i = scale * fly6i - fly3i; + + + fly5r = t0r - U1r * fly2r; + fly5r = fly5r - U1i * fly2i; + fly5i = t0i + U1i * fly2r; + fly5i = fly5i - U1r * fly2i; + t0r = scale * t0r - fly5r; + t0i = scale * t0i - fly5i; + + fly7r = t1r + U1i * fly1r; + fly7r = fly7r - U1r * fly1i; + fly7i = t1i + U1r * fly1r; + fly7i = fly7i + U1i * fly1i; + t1r = scale * t1r - fly7r; + t1i = scale * t1i - fly7i; + + fly2r = fly4r - U1r * fly6r; + fly2r = fly2r - U1i * fly6i; + fly2i = fly4i + U1i * fly6r; + fly2i = fly2i - U1r * fly6i; + fly4r = scale * fly4r - fly2r; + fly4i = scale * fly4i - fly2i; + + fly1r = fly0r + U1i * fly3r; + fly1r = fly1r - U1r * fly3i; + fly1i = fly0i + U1r * fly3r; + fly1i = fly1i + U1i * fly3i; + fly0r = scale * fly0r - fly1r; + fly0i = scale * fly0i - fly1i; + + fly6r = t0r - U2r * fly4r; + fly6r = fly6r - U2i * fly4i; + fly6i = t0i + U2i * fly4r; + fly6i = fly6i - U2r * fly4i; + t0r = scale * t0r - fly6r; + t0i = scale * t0i - fly6i; + + fly3r = fly5r - U2i * fly2r; + fly3r = fly3r + U2r * fly2i; + fly3i = fly5i - U2r * fly2r; + fly3i = fly3i - U2i * fly2i; + fly2r = scale * fly5r - fly3r; + fly2i = scale * fly5i - fly3i; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r - U3i * fly0i; + fly4i = t1i + U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly5r = fly7r + U3i * fly1r; + fly5r = fly5r - U3r * fly1i; + fly5i = fly7i + U3r * fly1r; + fly5i = fly5i + U3i * fly1i; + fly7r = scale * fly7r - fly5r; + fly7i = scale * fly7i - fly5i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly2P) = fly3r; + *(fly2P + 1) = fly3i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + + fly0r = *(fly0P + FlyOffsetB); + fly0i = *(fly0P + FlyOffsetBIm); + + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + + fly1r = *(fly1P + FlyOffsetB); + fly1i = *(fly1P + FlyOffsetBIm); + + *(fly3P + FlyOffsetA) = fly5r; + *(fly3P + FlyOffsetAIm) = fly5i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + }; + + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly3r = *(fly3P); + fly3i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly5r = *(fly1P + FlyOffsetA); + fly5i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly7r = *(fly3P + FlyOffsetA); + fly7i = *(fly3P + FlyOffsetAIm); + + t1r = fly0r - U0r * fly1r; + t1r = t1r - U0i * fly1i; + t1i = fly0i + U0i * fly1r; + t1i = t1i - U0r * fly1i; + t0r = scale * fly0r - t1r; + t0i = scale * fly0i - t1i; + + fly1r = fly2r - U0r * fly3r; + fly1r = fly1r - U0i * fly3i; + fly1i = fly2i + U0i * fly3r; + fly1i = fly1i - U0r * fly3i; + fly2r = scale * fly2r - fly1r; + fly2i = scale * fly2i - fly1i; + + fly0r = fly4r - U0r * fly5r; + fly0r = fly0r - U0i * fly5i; + fly0i = fly4i + U0i * fly5r; + fly0i = fly0i - U0r * fly5i; + fly4r = scale * fly4r - fly0r; + fly4i = scale * fly4i - fly0i; + + fly3r = fly6r - U0r * fly7r; + fly3r = fly3r - U0i * fly7i; + fly3i = fly6i + U0i * fly7r; + fly3i = fly3i - U0r * fly7i; + fly6r = scale * fly6r - fly3r; + fly6i = scale * fly6i - fly3i; + + + fly5r = t0r - U1r * fly2r; + fly5r = fly5r - U1i * fly2i; + fly5i = t0i + U1i * fly2r; + fly5i = fly5i - U1r * fly2i; + t0r = scale * t0r - fly5r; + t0i = scale * t0i - fly5i; + + fly7r = t1r + U1i * fly1r; + fly7r = fly7r - U1r * fly1i; + fly7i = t1i + U1r * fly1r; + fly7i = fly7i + U1i * fly1i; + t1r = scale * t1r - fly7r; + t1i = scale * t1i - fly7i; + + fly2r = fly4r - U1r * fly6r; + fly2r = fly2r - U1i * fly6i; + fly2i = fly4i + U1i * fly6r; + fly2i = fly2i - U1r * fly6i; + fly4r = scale * fly4r - fly2r; + fly4i = scale * fly4i - fly2i; + + fly1r = fly0r + U1i * fly3r; + fly1r = fly1r - U1r * fly3i; + fly1i = fly0i + U1r * fly3r; + fly1i = fly1i + U1i * fly3i; + fly0r = scale * fly0r - fly1r; + fly0i = scale * fly0i - fly1i; + + U0i = *(U0iP = (U0iP - NsameU4)); + U0r = *(U0rP = (U0rP + NsameU4)); + U1r = *(U1rP = (U1rP + NsameU2)); + U1i = *(U1iP = (U1iP - NsameU2)); + if(stage&1) + U0r = -U0r; + + fly6r = t0r - U2r * fly4r; + fly6r = fly6r - U2i * fly4i; + fly6i = t0i + U2i * fly4r; + fly6i = fly6i - U2r * fly4i; + t0r = scale * t0r - fly6r; + t0i = scale * t0i - fly6i; + + fly3r = fly5r - U2i * fly2r; + fly3r = fly3r + U2r * fly2i; + fly3i = fly5i - U2r * fly2r; + fly3i = fly3i - U2i * fly2i; + fly2r = scale * fly5r - fly3r; + fly2i = scale * fly5i - fly3i; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r - U3i * fly0i; + fly4i = t1i + U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly5r = fly7r + U3i * fly1r; + fly5r = fly5r - U3r * fly1i; + fly5i = fly7i + U3r * fly1r; + fly5i = fly5i + U3i * fly1i; + fly7r = scale * fly7r - fly5r; + fly7i = scale * fly7i - fly5i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + + U2r = *(U2rP = (U2rP + NsameU1)); + U2i = *(U2iP = (U2iP - NsameU1)); + + *(fly2P) = fly3r; + *(fly2P + 1) = fly3i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + + U3r = *( U2rP + U3offset); + U3i = *( U2iP - U3offset); + + *(fly3P + FlyOffsetA) = fly5r; + *(fly3P + FlyOffsetAIm) = fly5i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + IOP = IOP + 2; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + }; + NsameU4 = -NsameU4; + + if(stage&1){ + LoopN >>= 3; + NsameU1 >>= 3; + NsameU2 >>= 3; + NsameU4 >>= 3; + NdiffU <<= 3; + Flyinc = Flyinc << 3; + FlyOffsetA <<= 3; + FlyOffsetB <<= 3; + FlyOffsetAIm = FlyOffsetA + 1; + FlyOffsetBIm = FlyOffsetB + 1; + } +} + +/* Finish RFFT */ +M=M+1; + +FlyOffsetA = Ntbl[M] * 2/4; +FlyOffsetAIm = Ntbl[M] * 2/4 + 1; + +IOP = ioptr; + +fly0P = (IOP + Ntbl[M]*2/4); +fly1P = (IOP + Ntbl[M]*2/8); + +U0rP = &Utbl[Ntbl[M-3]]; + +U0r = *U0rP, + +fly0r = *(IOP); +fly0i = *(IOP + 1); +fly1r = *(fly0P); +fly1i = *(fly0P + 1); +fly2r = *(fly1P); +fly2i = *(fly1P + 1); +fly3r = *(fly1P + FlyOffsetA); +fly3i = *(fly1P + FlyOffsetAIm); + + t0r = scale * fly0r + scale * fly0i; /* compute Re(x[0]) */ + t0i = scale * fly0r - scale * fly0i; /* compute Re(x[N/2]) */ + t1r = scale * fly1r; + t1i = -scale * fly1i; + + fly0r = fly2r + fly3r; + fly0i = fly2i - fly3i; + fly1r = fly2i + fly3i; + fly1i = fly3r - fly2r; + + fly2r = fly0r + U0r * fly1r; + fly2r = fly2r + U0r * fly1i; + fly2i = fly0i - U0r * fly1r; + fly2i = fly2i + U0r * fly1i; + fly3r = scale * fly0r - fly2r; + fly3i = fly2i - scale * fly0i; + +*(IOP) = t0r; +*(IOP + 1) = t0i; +*(fly0P) = t1r; +*(fly0P + 1) = t1i; +*(fly1P) = fly2r; +*(fly1P + 1) = fly2i; +*(fly1P + FlyOffsetA) = fly3r; +*(fly1P + FlyOffsetAIm) = fly3i; + +U0rP = &Utbl[1]; +U0iP = &Utbl[Ntbl[M-2]-1]; + +U0r = *U0rP, +U0i = *U0iP; + +fly0P = (IOP + 2); +fly1P = (IOP + (Ntbl[M-2]-1)*2); + + /* Butterflys */ + /* + f0 - t0 - - f2 + f1 - t1 -U0 - f3 + f2 - f0 - - t0 + f3 - f1 -U0a- t1 + */ + +for (diffUcnt = Ntbl[M-3]-1; diffUcnt > 0 ; diffUcnt--){ + + fly0r = *(fly0P); + fly0i = *(fly0P + 1); + fly1r = *(fly1P + FlyOffsetA); + fly1i = *(fly1P + FlyOffsetAIm); + fly2r = *(fly1P); + fly2i = *(fly1P + 1); + fly3r = *(fly0P + FlyOffsetA); + fly3i = *(fly0P + FlyOffsetAIm); + + t0r = fly0r + fly1r; + t0i = fly0i - fly1i; + t1r = fly0i + fly1i; + t1i = fly1r - fly0r; + + fly0r = fly2r + fly3r; + fly0i = fly2i - fly3i; + fly1r = fly2i + fly3i; + fly1i = fly3r - fly2r; + + fly2r = t0r + U0r * t1r; + fly2r = fly2r + U0i * t1i; + fly2i = t0i - U0i * t1r; + fly2i = fly2i + U0r * t1i; + fly3r = scale * t0r - fly2r; + fly3i = fly2i - scale * t0i; + + t0r = fly0r + U0i * fly1r; + t0r = t0r + U0r * fly1i; + t0i = fly0i - U0r * fly1r; + t0i = t0i + U0i * fly1i; + t1r = scale * fly0r - t0r; + t1i = t0i - scale * fly0i; + + *(fly0P) = fly2r; + *(fly0P + 1) = fly2i; + *(fly1P + FlyOffsetA) = fly3r; + *(fly1P + FlyOffsetAIm) = fly3i; + + U0r = *(U0rP = (U0rP + 1)); + U0i = *(U0iP = (U0iP - 1)); + + *(fly1P) = t0r; + *(fly1P + 1) = t0i; + *(fly0P + FlyOffsetA) = t1r; + *(fly0P + FlyOffsetAIm) = t1i; + + fly0P += 2; + fly1P -= 2; +}; + +ioptr += Ntbl[M]; +} +} + +void riffts(float *ioptr, long M, long Rows, float *Utbl){ +/* Compute in-place real ifft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array in the following order */ +/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = real output data array */ + +long Flyinc; +long FlyOffsetA; +long FlyOffsetAIm; +long FlyOffsetB; +long FlyOffsetBIm; +long NsameU1; +long NsameU2; +long NsameU4; +long diffUcnt; +long LoopCnt; +float scale; +float fly0r; +float fly0i; +float fly1r; +float fly1i; +float fly2r; +float fly2i; +float fly3r; +float fly3i; +float fly4r; +float fly4i; +float fly5r; +float fly5i; +float fly6r; +float fly6i; +float fly7r; +float fly7i; +float U0r; +float U0i; +float U1r; +float U1i; +float U2r; +float U2i; +float U3r; +float U3i; +float t0r; +float t0i; +float t1r; +float t1i; + +float *fly0P; +float *fly1P; +float *fly2P; +float *fly3P; + +float *U0rP; +float *U0iP; +float *U1rP; +float *U1iP; +float *U2rP; +float *U2iP; +float *IOP; +long U3offset; + +long stage; +long NdiffU; +long LoopN; + +const long BRshift = MAXMROOT - ((M-1)>>1); /* for RIFFT */ +const long Nrems2 = Ntbl[(M-1)-((M-1)>>1)+1]; /* for RIFFT */ +const long Nroot_1_ColInc = (Ntbl[(M-1)-1]-Ntbl[(M-1)-((M-1)>>1)])*2; /* for RIFFT */ + +for (;Rows>0;Rows--){ + +/* Start RIFFT */ + +FlyOffsetA = Ntbl[M] * 2/4; +FlyOffsetAIm = Ntbl[M] * 2/4 + 1; + +IOP = ioptr; + +fly0P = (IOP + Ntbl[M]*2/4); +fly1P = (IOP + Ntbl[M]*2/8); + +U0rP = &Utbl[Ntbl[M-3]]; + +U0r = *U0rP, + +fly0r = *(IOP); +fly0i = *(IOP + 1); +fly1r = *(fly0P); +fly1i = *(fly0P + 1); +fly2r = *(fly1P); +fly2i = *(fly1P + 1); +fly3r = *(fly1P + FlyOffsetA); +fly3i = *(fly1P + FlyOffsetAIm); + + t0r = fly0r + fly0i; + t0i = fly0r - fly0i; + t1r = fly1r + fly1r; + t1i = -fly1i - fly1i; + + fly0r = fly2r + fly3r; + fly0i = fly2i - fly3i; + fly1r = fly2r - fly3r; + fly1i = fly2i + fly3i; + + fly3r = fly1r * U0r; + fly3r = fly3r - U0r * fly1i; + fly3i = fly1r * U0r; + fly3i = fly3i + U0r * fly1i; + + fly2r = fly0r - fly3i; + fly2i = fly0i + fly3r; + fly1r = fly0r + fly3i; + fly1i = -fly0i + fly3r; + +*(IOP) = t0r; +*(IOP + 1) = t0i; +*(fly0P) = t1r; +*(fly0P + 1) = t1i; +*(fly1P) = fly2r; +*(fly1P + 1) = fly2i; +*(fly1P + FlyOffsetA) = fly1r; +*(fly1P + FlyOffsetAIm) = fly1i; + +U0rP = &Utbl[1]; +U0iP = &Utbl[Ntbl[M-2]-1]; + +U0r = *U0rP, +U0i = *U0iP; + +fly0P = (IOP + 2); +fly1P = (IOP + (Ntbl[M-2]-1)*2); + + /* Butterflys */ + /* + f0 - t0 - f2 + f1 -t1 -U0- f3 - f1 + f2 - f0 - t0 + f3 -f1 -U0a t1 - f3 + */ + +for (diffUcnt = Ntbl[M-3]-1; diffUcnt > 0 ; diffUcnt--){ + + fly0r = *(fly0P); + fly0i = *(fly0P + 1); + fly1r = *(fly1P + FlyOffsetA); + fly1i = *(fly1P + FlyOffsetAIm); + fly2r = *(fly1P); + fly2i = *(fly1P + 1); + fly3r = *(fly0P + FlyOffsetA); + fly3i = *(fly0P + FlyOffsetAIm); + + t0r = fly0r + fly1r; + t0i = fly0i - fly1i; + t1r = fly0r - fly1r; + t1i = fly0i + fly1i; + + fly0r = fly2r + fly3r; + fly0i = fly2i - fly3i; + fly1r = fly2r - fly3r; + fly1i = fly2i + fly3i; + + + fly3r = t1r * U0r; + fly3r = fly3r - U0i * t1i; + fly3i = t1r * U0i; + fly3i = fly3i + U0r * t1i; + + t1r = fly1r * U0i; + t1r = t1r - U0r * fly1i; + t1i = fly1r * U0r; + t1i = t1i + U0i * fly1i; + + + fly2r = t0r - fly3i; + fly2i = t0i + fly3r; + fly1r = t0r + fly3i; + fly1i = -t0i + fly3r; + + t0r = fly0r - t1i; + t0i = fly0i + t1r; + fly3r = fly0r + t1i; + fly3i = -fly0i + t1r; + + + *(fly0P) = fly2r; + *(fly0P + 1) = fly2i; + *(fly1P + FlyOffsetA) = fly1r; + *(fly1P + FlyOffsetAIm) = fly1i; + + U0r = *(U0rP = (U0rP + 1)); + U0i = *(U0iP = (U0iP - 1)); + + *(fly1P) = t0r; + *(fly1P + 1) = t0i; + *(fly0P + FlyOffsetA) = fly3r; + *(fly0P + FlyOffsetAIm) = fly3i; + + fly0P += 2; + fly1P -= 2; +}; + +M=M-1; /* for RIFFT */ + +FlyOffsetA = Ntbl[M] * 2/2; +FlyOffsetAIm = FlyOffsetA + 1; +FlyOffsetB = FlyOffsetA + 2; +FlyOffsetBIm = FlyOffsetB + 1; + +/* BitrevR2 ** bit reverse shuffle and first radix 2 stage ******/ + +scale = 1./Ntbl[M+1]; +for (stage = 0; stage < Ntbl[M-(M>>1)]*2; stage += Ntbl[M>>1]*2){ + for (LoopN = (Ntbl[(M>>1)-1]-1); LoopN >= 0; LoopN--){ + LoopCnt = (Ntbl[(M>>1)-1]-1); + fly0P = ioptr + Nroot_1_ColInc + ((int)BRcnt[LoopN] >> BRshift)*(2*2) + stage; + IOP = ioptr + (LoopN<<(M+1)/2) * 2 + stage; + fly1P = IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2); + fly0r = *(fly0P); + fly0i = *(fly0P+1); + fly1r = *(fly0P+FlyOffsetA); + fly1i = *(fly0P+FlyOffsetAIm); + for (; LoopCnt > LoopN;){ + fly2r = *(fly0P+2); + fly2i = *(fly0P+(2+1)); + fly3r = *(fly0P+FlyOffsetB); + fly3i = *(fly0P+FlyOffsetBIm); + fly4r = *(fly1P); + fly4i = *(fly1P+1); + fly5r = *(fly1P+FlyOffsetA); + fly5i = *(fly1P+FlyOffsetAIm); + fly6r = *(fly1P+2); + fly6i = *(fly1P+(2+1)); + fly7r = *(fly1P+FlyOffsetB); + fly7i = *(fly1P+FlyOffsetBIm); + + t0r = fly0r + fly1r; + t0i = fly0i + fly1i; + fly1r = fly0r - fly1r; + fly1i = fly0i - fly1i; + t1r = fly2r + fly3r; + t1i = fly2i + fly3i; + fly3r = fly2r - fly3r; + fly3i = fly2i - fly3i; + fly0r = fly4r + fly5r; + fly0i = fly4i + fly5i; + fly5r = fly4r - fly5r; + fly5i = fly4i - fly5i; + fly2r = fly6r + fly7r; + fly2i = fly6i + fly7i; + fly7r = fly6r - fly7r; + fly7i = fly6i - fly7i; + + *(fly1P) = scale*t0r; + *(fly1P+1) = scale*t0i; + *(fly1P+2) = scale*fly1r; + *(fly1P+(2+1)) = scale*fly1i; + *(fly1P+FlyOffsetA) = scale*t1r; + *(fly1P+FlyOffsetAIm) = scale*t1i; + *(fly1P+FlyOffsetB) = scale*fly3r; + *(fly1P+FlyOffsetBIm) = scale*fly3i; + *(fly0P) = scale*fly0r; + *(fly0P+1) = scale*fly0i; + *(fly0P+2) = scale*fly5r; + *(fly0P+(2+1)) = scale*fly5i; + *(fly0P+FlyOffsetA) = scale*fly2r; + *(fly0P+FlyOffsetAIm) = scale*fly2i; + *(fly0P+FlyOffsetB) = scale*fly7r; + *(fly0P+FlyOffsetBIm) = scale*fly7i; + + fly0P -= Nrems2; + fly0r = *(fly0P); + fly0i = *(fly0P+1); + fly1r = *(fly0P+FlyOffsetA); + fly1i = *(fly0P+FlyOffsetAIm); + LoopCnt -= 1; + fly1P = (IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2)); + }; + fly2r = *(fly0P+2); + fly2i = *(fly0P+(2+1)); + fly3r = *(fly0P+FlyOffsetB); + fly3i = *(fly0P+FlyOffsetBIm); + + t0r = fly0r + fly1r; + t0i = fly0i + fly1i; + fly1r = fly0r - fly1r; + fly1i = fly0i - fly1i; + t1r = fly2r + fly3r; + t1i = fly2i + fly3i; + fly3r = fly2r - fly3r; + fly3i = fly2i - fly3i; + + *(fly0P) = scale*t0r; + *(fly0P+1) = scale*t0i; + *(fly0P+2) = scale*fly1r; + *(fly0P+(2+1)) = scale*fly1i; + *(fly0P+FlyOffsetA) = scale*t1r; + *(fly0P+FlyOffsetAIm) = scale*t1i; + *(fly0P+FlyOffsetB) = scale*fly3r; + *(fly0P+FlyOffsetBIm) = scale*fly3i; + + }; +}; + +/**** FFTC **************/ + +scale = 2.0; + +NdiffU = 2; +Flyinc = (NdiffU); + +NsameU4 = Ntbl[M+1]/4; /* for RIFFT */ +LoopN = Ntbl[M-3]; + +stage = ((M-1)/3); +if ( (M-1-(stage * 3)) != 0 ){ + FlyOffsetA = Flyinc << 2; + FlyOffsetB = FlyOffsetA << 1; + FlyOffsetAIm = FlyOffsetA + 1; + FlyOffsetBIm = FlyOffsetB + 1; + if ( (M-1-(stage * 3)) == 1 ){ + /* 1 radix 2 stage */ + + IOP = ioptr; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + /* Butterflys */ + /* + t0 - - t0 + t1 - - t1 + f2 - 1- f5 + f1 - -i- f7 + f4 - - f4 + f0 - - f0 + f6 - 1- f2 + f3 - -i- f1 + */ + + for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){ + t0r = *(fly0P); + t0i = *(fly0P + 1); + t1r = *(fly1P); + t1i = *(fly1P + 1); + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly1r = *(fly3P); + fly1i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly0r = *(fly1P + FlyOffsetA); + fly0i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly3r = *(fly3P + FlyOffsetA); + fly3i = *(fly3P + FlyOffsetAIm); + + fly5r = t0r - fly2r; + fly5i = t0i - fly2i; + t0r = t0r + fly2r; + t0i = t0i + fly2i; + + fly7r = t1r + fly1i; + fly7i = t1i - fly1r; + t1r = t1r - fly1i; + t1i = t1i + fly1r; + + fly2r = fly4r - fly6r; + fly2i = fly4i - fly6i; + fly4r = fly4r + fly6r; + fly4i = fly4i + fly6i; + + fly1r = fly0r + fly3i; + fly1i = fly0i - fly3r; + fly0r = fly0r - fly3i; + fly0i = fly0i + fly3r; + + *(fly2P) = fly5r; + *(fly2P + 1) = fly5i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + *(fly0P + FlyOffsetA) = fly4r; + *(fly0P + FlyOffsetAIm) = fly4i; + *(fly3P + FlyOffsetA) = fly1r; + *(fly3P + FlyOffsetAIm) = fly1i; + *(fly1P + FlyOffsetA) = fly0r; + *(fly1P + FlyOffsetAIm) = fly0i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + }; + + NsameU4 >>= 1; + LoopN >>= 1; + NdiffU <<= 1; + Flyinc = Flyinc << 1; + } + else{ + /* 1 radix 4 stage */ + IOP = ioptr; + + U3r = 0.7071067811865475244008443621; /* sqrt(0.5); */ + U3i = U3r; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + /* Butterflys */ + /* + t0 - - t0 - - t0 + t1 - - t1 - - t1 + f2 - 1- f5 - - f5 + f1 - -i- f7 - - f7 + f4 - - f4 - 1- f6 + f0 - - f0 -U3 - f3 + f6 - 1- f2 - -i- f4 + f3 - -i- f1 -U3a- f2 + */ + + for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){ + t0r = *(fly0P); + t0i = *(fly0P + 1); + t1r = *(fly1P); + t1i = *(fly1P + 1); + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly1r = *(fly3P); + fly1i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly0r = *(fly1P + FlyOffsetA); + fly0i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly3r = *(fly3P + FlyOffsetA); + fly3i = *(fly3P + FlyOffsetAIm); + + fly5r = t0r - fly2r; + fly5i = t0i - fly2i; + t0r = t0r + fly2r; + t0i = t0i + fly2i; + + fly7r = t1r + fly1i; + fly7i = t1i - fly1r; + t1r = t1r - fly1i; + t1i = t1i + fly1r; + + fly2r = fly4r - fly6r; + fly2i = fly4i - fly6i; + fly4r = fly4r + fly6r; + fly4i = fly4i + fly6i; + + fly1r = fly0r + fly3i; + fly1i = fly0i - fly3r; + fly0r = fly0r - fly3i; + fly0i = fly0i + fly3r; + + fly6r = t0r - fly4r; + fly6i = t0i - fly4i; + t0r = t0r + fly4r; + t0i = t0i + fly4i; + + fly3r = fly5r + fly2i; + fly3i = fly5i - fly2r; + fly5r = fly5r - fly2i; + fly5i = fly5i + fly2r; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r + U3i * fly0i; + fly4i = t1i - U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly2r = fly7r + U3i * fly1r; + fly2r = fly2r + U3r * fly1i; + fly2i = fly7i - U3r * fly1r; + fly2i = fly2i + U3i * fly1i; + fly7r = scale * fly7r - fly2r; + fly7i = scale * fly7i - fly2i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly2P + FlyOffsetA) = fly3r; + *(fly2P + FlyOffsetAIm) = fly3i; + *(fly2P) = fly5r; + *(fly2P + 1) = fly5i; + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + *(fly3P + FlyOffsetA) = fly2r; + *(fly3P + FlyOffsetAIm) = fly2i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + + }; + + NsameU4 >>= 2; + LoopN >>= 2; + NdiffU <<= 2; + Flyinc = Flyinc << 2; + }; +}; + +NsameU2 = NsameU4 >> 1; +NsameU1 = NsameU2 >> 1; +Flyinc <<= 1; +FlyOffsetA = Flyinc << 2; +FlyOffsetB = FlyOffsetA << 1; +FlyOffsetAIm = FlyOffsetA + 1; +FlyOffsetBIm = FlyOffsetB + 1; +LoopN >>= 1; + +/* ****** RADIX 8 Stages */ +for (stage = stage<<1; stage > 0 ; stage--){ + + /* an fft stage is done in two parts to ease use of the single quadrant cos table */ + +/* fftcalc1(iobuf, Utbl, N, NdiffU, LoopN); */ + if(!(stage&1)){ + U0rP = &Utbl[0]; + U0iP = &Utbl[Ntbl[M-1]]; /* for RIFFT */ + U1rP = U0rP; + U1iP = U0iP; + U2rP = U0rP; + U2iP = U0iP; + U3offset = (Ntbl[M+1]) / 8; /* for RIFFT */ + + IOP = ioptr; + + U0r = *U0rP, + U0i = *U0iP; + U1r = *U1rP, + U1i = *U1iP; + U2r = *U2rP, + U2i = *U2iP; + U3r = *( U2rP + U3offset); + U3i = *( U2iP - U3offset); + } + + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + for (diffUcnt = (NdiffU)>>1; diffUcnt > 0; diffUcnt--){ + + /* Butterflys */ + /* + f0 - - t0 - - t0 - - t0 + f1 -U0 - t1 - - t1 - - t1 + f2 - - f2 -U1 - f5 - - f3 + f3 -U0 - f1 -U1a- f7 - - f7 + f4 - - f4 - - f4 -U2 - f6 + f5 -U0 - f0 - - f0 -U3 - f4 + f6 - - f6 -U1 - f2 -U2a- f2 + f7 -U0 - f3 -U1a- f1 -U3a- f5 + */ + + fly0r = *(IOP); + fly0i = *(IOP+1); + fly1r = *(fly1P); + fly1i = *(fly1P+1); + + for (LoopCnt = LoopN-1; LoopCnt > 0 ; LoopCnt--){ + + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly3r = *(fly3P); + fly3i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly5r = *(fly1P + FlyOffsetA); + fly5i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly7r = *(fly3P + FlyOffsetA); + fly7i = *(fly3P + FlyOffsetAIm); + + t1r = fly0r - U0r * fly1r; + t1r = t1r + U0i * fly1i; + t1i = fly0i - U0i * fly1r; + t1i = t1i - U0r * fly1i; + t0r = scale * fly0r - t1r; + t0i = scale * fly0i - t1i; + + fly1r = fly2r - U0r * fly3r; + fly1r = fly1r + U0i * fly3i; + fly1i = fly2i - U0i * fly3r; + fly1i = fly1i - U0r * fly3i; + fly2r = scale * fly2r - fly1r; + fly2i = scale * fly2i - fly1i; + + fly0r = fly4r - U0r * fly5r; + fly0r = fly0r + U0i * fly5i; + fly0i = fly4i - U0i * fly5r; + fly0i = fly0i - U0r * fly5i; + fly4r = scale * fly4r - fly0r; + fly4i = scale * fly4i - fly0i; + + fly3r = fly6r - U0r * fly7r; + fly3r = fly3r + U0i * fly7i; + fly3i = fly6i - U0i * fly7r; + fly3i = fly3i - U0r * fly7i; + fly6r = scale * fly6r - fly3r; + fly6i = scale * fly6i - fly3i; + + + fly5r = t0r - U1r * fly2r; + fly5r = fly5r + U1i * fly2i; + fly5i = t0i - U1i * fly2r; + fly5i = fly5i - U1r * fly2i; + t0r = scale * t0r - fly5r; + t0i = scale * t0i - fly5i; + + fly7r = t1r + U1i * fly1r; + fly7r = fly7r + U1r * fly1i; + fly7i = t1i - U1r * fly1r; + fly7i = fly7i + U1i * fly1i; + t1r = scale * t1r - fly7r; + t1i = scale * t1i - fly7i; + + fly2r = fly4r - U1r * fly6r; + fly2r = fly2r + U1i * fly6i; + fly2i = fly4i - U1i * fly6r; + fly2i = fly2i - U1r * fly6i; + fly4r = scale * fly4r - fly2r; + fly4i = scale * fly4i - fly2i; + + fly1r = fly0r + U1i * fly3r; + fly1r = fly1r + U1r * fly3i; + fly1i = fly0i - U1r * fly3r; + fly1i = fly1i + U1i * fly3i; + fly0r = scale * fly0r - fly1r; + fly0i = scale * fly0i - fly1i; + + fly6r = t0r - U2r * fly4r; + fly6r = fly6r + U2i * fly4i; + fly6i = t0i - U2i * fly4r; + fly6i = fly6i - U2r * fly4i; + t0r = scale * t0r - fly6r; + t0i = scale * t0i - fly6i; + + fly3r = fly5r - U2i * fly2r; + fly3r = fly3r - U2r * fly2i; + fly3i = fly5i + U2r * fly2r; + fly3i = fly3i - U2i * fly2i; + fly2r = scale * fly5r - fly3r; + fly2i = scale * fly5i - fly3i; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r + U3i * fly0i; + fly4i = t1i - U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly5r = fly7r + U3i * fly1r; + fly5r = fly5r + U3r * fly1i; + fly5i = fly7i - U3r * fly1r; + fly5i = fly5i + U3i * fly1i; + fly7r = scale * fly7r - fly5r; + fly7i = scale * fly7i - fly5i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly2P) = fly3r; + *(fly2P + 1) = fly3i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + + fly0r = *(fly0P + FlyOffsetB); + fly0i = *(fly0P + FlyOffsetBIm); + + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + + fly1r = *(fly1P + FlyOffsetB); + fly1i = *(fly1P + FlyOffsetBIm); + + *(fly3P + FlyOffsetA) = fly5r; + *(fly3P + FlyOffsetAIm) = fly5i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + + }; + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly3r = *(fly3P); + fly3i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly5r = *(fly1P + FlyOffsetA); + fly5i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly7r = *(fly3P + FlyOffsetA); + fly7i = *(fly3P + FlyOffsetAIm); + + t1r = fly0r - U0r * fly1r; + t1r = t1r + U0i * fly1i; + t1i = fly0i - U0i * fly1r; + t1i = t1i - U0r * fly1i; + t0r = scale * fly0r - t1r; + t0i = scale * fly0i - t1i; + + fly1r = fly2r - U0r * fly3r; + fly1r = fly1r + U0i * fly3i; + fly1i = fly2i - U0i * fly3r; + fly1i = fly1i - U0r * fly3i; + fly2r = scale * fly2r - fly1r; + fly2i = scale * fly2i - fly1i; + + fly0r = fly4r - U0r * fly5r; + fly0r = fly0r + U0i * fly5i; + fly0i = fly4i - U0i * fly5r; + fly0i = fly0i - U0r * fly5i; + fly4r = scale * fly4r - fly0r; + fly4i = scale * fly4i - fly0i; + + fly3r = fly6r - U0r * fly7r; + fly3r = fly3r + U0i * fly7i; + fly3i = fly6i - U0i * fly7r; + fly3i = fly3i - U0r * fly7i; + fly6r = scale * fly6r - fly3r; + fly6i = scale * fly6i - fly3i; + + fly5r = t0r - U1r * fly2r; + fly5r = fly5r + U1i * fly2i; + fly5i = t0i - U1i * fly2r; + fly5i = fly5i - U1r * fly2i; + t0r = scale * t0r - fly5r; + t0i = scale * t0i - fly5i; + + fly7r = t1r + U1i * fly1r; + fly7r = fly7r + U1r * fly1i; + fly7i = t1i - U1r * fly1r; + fly7i = fly7i + U1i * fly1i; + t1r = scale * t1r - fly7r; + t1i = scale * t1i - fly7i; + + fly2r = fly4r - U1r * fly6r; + fly2r = fly2r + U1i * fly6i; + fly2i = fly4i - U1i * fly6r; + fly2i = fly2i - U1r * fly6i; + fly4r = scale * fly4r - fly2r; + fly4i = scale * fly4i - fly2i; + + fly1r = fly0r + U1i * fly3r; + fly1r = fly1r + U1r * fly3i; + fly1i = fly0i - U1r * fly3r; + fly1i = fly1i + U1i * fly3i; + fly0r = scale * fly0r - fly1r; + fly0i = scale * fly0i - fly1i; + + U0i = *(U0iP = (U0iP - NsameU4)); + U0r = *(U0rP = (U0rP + NsameU4)); + U1r = *(U1rP = (U1rP + NsameU2)); + U1i = *(U1iP = (U1iP - NsameU2)); + if(stage&1) + U0r = - U0r; + + fly6r = t0r - U2r * fly4r; + fly6r = fly6r + U2i * fly4i; + fly6i = t0i - U2i * fly4r; + fly6i = fly6i - U2r * fly4i; + t0r = scale * t0r - fly6r; + t0i = scale * t0i - fly6i; + + fly3r = fly5r - U2i * fly2r; + fly3r = fly3r - U2r * fly2i; + fly3i = fly5i + U2r * fly2r; + fly3i = fly3i - U2i * fly2i; + fly2r = scale * fly5r - fly3r; + fly2i = scale * fly5i - fly3i; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r + U3i * fly0i; + fly4i = t1i - U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly5r = fly7r + U3i * fly1r; + fly5r = fly5r + U3r * fly1i; + fly5i = fly7i - U3r * fly1r; + fly5i = fly5i + U3i * fly1i; + fly7r = scale * fly7r - fly5r; + fly7i = scale * fly7i - fly5i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + + U2r = *(U2rP = (U2rP + NsameU1)); + U2i = *(U2iP = (U2iP - NsameU1)); + + *(fly2P) = fly3r; + *(fly2P + 1) = fly3i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + + U3r = *( U2rP + U3offset); + U3i = *( U2iP - U3offset); + + *(fly3P + FlyOffsetA) = fly5r; + *(fly3P + FlyOffsetAIm) = fly5i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + IOP = IOP + 2; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + }; + NsameU4 = -NsameU4; + + if(stage&1){ + LoopN >>= 3; + NsameU1 >>= 3; + NsameU2 >>= 3; + NsameU4 >>= 3; + NdiffU <<= 3; + Flyinc = Flyinc << 3; + FlyOffsetA <<= 3; + FlyOffsetB <<= 3; + FlyOffsetAIm = FlyOffsetA + 1; + FlyOffsetBIm = FlyOffsetB + 1; + } +} +M=M+1; /* for RIFFT */ + +ioptr += Ntbl[M]; +} +} diff --git a/sc4pd/source/fftlib.h b/sc4pd/source/fftlib.h new file mode 100644 index 0000000..b03317d --- /dev/null +++ b/sc4pd/source/fftlib.h @@ -0,0 +1,62 @@ +long FFTInit(long *fftMptr, long fftN, float *Utbl); +/* Compute cosine table and check size for complex ffts */ +/* INPUTS */ +/* fftN = size of fft */ +/* OUTPUTS */ +/* *fftMptr = log2 of fft size */ +/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */ +/* RETURNS */ +/* 1 if fftN is invalid, 0 otherwise */ + +long rFFTInit(long *fftMptr, long fftN, float *Utbl); +/* Compute cosine table and check size for a real input fft */ +/* INPUTS */ +/* fftN = size of fft */ +/* OUTPUTS */ +/* *fftMptr = log2 of fft size */ +/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */ +/* RETURNS */ +/* 1 if fftN is invalid, 0 otherwise */ + +void ffts(float *ioptr, long M, long Rows, float *Utbl); +/* Compute in-place complex fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array */ + +void iffts(float *ioptr, long M, long Rows, float *Utbl); +/* Compute in-place inverse complex fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array */ + +void rffts(float *ioptr, long M, long Rows, float *Utbl); +/* Compute in-place real fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = real input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array in the following order */ +/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */ + + +void riffts(float *ioptr, long M, long Rows, float *Utbl); +/* Compute in-place real ifft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array in the following order */ +/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = real output data array */ diff --git a/sc4pd/source/hypot.cpp b/sc4pd/source/hypot.cpp new file mode 100644 index 0000000..83f9a89 --- /dev/null +++ b/sc4pd/source/hypot.cpp @@ -0,0 +1,125 @@ +/* sc4pd + hypot, hypot~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & Toshimaru Nakamura: Weather Sky + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ hypot~ -----------------------------*/ + +class hypot_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(hypot_ar,sc4pd_dsp); + +public: + hypot_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("hypot~",hypot_ar); + +hypot_ar::hypot_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void hypot_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = hypot( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ hypot ------------------------------*/ + +class hypot_kr + :public flext_base +{ + FLEXT_HEADER(hypot_kr,flext_base); + +public: + hypot_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("hypot",hypot_kr); + +hypot_kr::hypot_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void hypot_kr::m_perform(float f) +{ + ToOutFloat(0,hypot(f,b)); +} + +void hypot_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/main.cpp b/sc4pd/source/main.cpp new file mode 100644 index 0000000..fa81e2e --- /dev/null +++ b/sc4pd/source/main.cpp @@ -0,0 +1,308 @@ + +/* sc4pd + library initialization + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phosphor +*/ + +#include "sc4pd.hpp" + +#define SC4PD_VERSION "0.01" + + +void sc4pd_library_setup() +{ + post("\nsc4pd: by tim blechmann"); + post("based on SuperCollider by James McCartney"); + post("version "SC4PD_VERSION); + post("compiled on "__DATE__); + post("contains: Dust(~), MantissaMask(~), Hasher(~), Median(~), " + "BrownNoise(~),\n" + " ClipNoise(~), GrayNoise(~), Dust2(~), WhiteNoise(~), " + "PinkNoise(~), \n Crackle(~), Rand(~), TRand(~), " + "TExpRand(~), IRand(~), TIRand(~),\n CoinGate, " + "LinRand(~), NRand(~), ExpRand(~), LFClipNoise(~),\n" + " LFNoise0(~), LFNoise1(~), LFNoise2(~), Logistic(~), " + "Latoocarfian(~),\n" + " LinCong(~), amclip(~), scaleneg(~), excess(~), hypot(~), " + "ring1(~),\n" + " ring2(~), ring3(~), ring4(~), difsqr(~), sumsqr(~), " + "sqrdif(~),\n" + " sqrsum(~), absdif(~), LFSaw(~), LFPulse(~), Impulse(~),\n" + " Integrator(~), Decay~, Decay2~, Lag~, Lag2~, LinExp(~), " + "DelayN~,\n" + " DelayL~, DelayC~, CombN~, CombL~, CombC~, AllpassN~, " + "AllpassL~,\n" + " AllpassC~, PitchShift~, Resonz~, OnePole(~), OneZero(~), " + "TwoPole~, \n" + " TwoZero~, FOS(~), SOS~, RLPF~, RHPF~, LPF~, HPF~, BPF~, " + "BRF~,\n" + " LPZ1(~), HPZ1(~), LPZ2(~), HPZ2(~), BPZ2(~), BRZ2(~), " + "LFDNoise0~,\n" + " LFDNoise1~, LFDNoise2~, sc+~, sc-~, sc*~, sc/~, " + "Convolution~\n" + ); + + //initialize objects + FLEXT_DSP_SETUP(Dust_ar); + FLEXT_SETUP(Dust_kr); + + FLEXT_DSP_SETUP(MantissaMask_ar); + FLEXT_SETUP(MantissaMask_kr); + + FLEXT_DSP_SETUP(Hasher_ar); + FLEXT_SETUP(Hasher_kr); + + FLEXT_DSP_SETUP(Median_ar); + FLEXT_SETUP(Median_kr); + + FLEXT_DSP_SETUP(BrownNoise_ar); + FLEXT_SETUP(BrownNoise_kr); + + FLEXT_DSP_SETUP(ClipNoise_ar); + FLEXT_SETUP(ClipNoise_kr); + + FLEXT_DSP_SETUP(GrayNoise_ar); + FLEXT_SETUP(GrayNoise_kr); + + FLEXT_DSP_SETUP(WhiteNoise_ar); + FLEXT_SETUP(WhiteNoise_kr); + + FLEXT_DSP_SETUP(PinkNoise_ar); + FLEXT_SETUP(PinkNoise_kr); + + FLEXT_DSP_SETUP(Dust2_ar); + FLEXT_SETUP(Dust2_kr); + + FLEXT_DSP_SETUP(Crackle_ar); + FLEXT_SETUP(Crackle_kr); + + FLEXT_DSP_SETUP(Rand_ar); + FLEXT_SETUP(Rand_kr); + + FLEXT_DSP_SETUP(TRand_ar); + FLEXT_SETUP(TRand_kr); + + FLEXT_DSP_SETUP(TExpRand_ar); + FLEXT_SETUP(TExpRand_kr); + + FLEXT_DSP_SETUP(IRand_ar); + FLEXT_SETUP(IRand_kr); + + FLEXT_DSP_SETUP(TIRand_ar); + FLEXT_SETUP(TIRand_kr); + + FLEXT_SETUP(CoinGate_kr); + + FLEXT_DSP_SETUP(LinRand_ar); + FLEXT_SETUP(LinRand_kr); + + FLEXT_DSP_SETUP(NRand_ar); + FLEXT_SETUP(NRand_kr); + + FLEXT_DSP_SETUP(ExpRand_ar); + FLEXT_SETUP(ExpRand_kr); + + FLEXT_DSP_SETUP(LFClipNoise_ar); + FLEXT_SETUP(LFClipNoise_kr); + + FLEXT_DSP_SETUP(LFNoise0_ar); + FLEXT_SETUP(LFNoise0_kr); + + FLEXT_DSP_SETUP(LFNoise1_ar); + FLEXT_SETUP(LFNoise1_kr); + + FLEXT_DSP_SETUP(LFNoise2_ar); + FLEXT_SETUP(LFNoise2_kr); + + FLEXT_DSP_SETUP(Logistic_ar); + FLEXT_SETUP(Logistic_kr); + + FLEXT_DSP_SETUP(Latoocarfian_ar); + FLEXT_SETUP(Latoocarfian_kr); + + FLEXT_DSP_SETUP(LinCong_ar); + FLEXT_SETUP(LinCong_kr); + + FLEXT_DSP_SETUP(amclip_ar); + FLEXT_SETUP(amclip_kr); + + FLEXT_DSP_SETUP(scaleneg_ar); + FLEXT_SETUP(scaleneg_kr); + + FLEXT_DSP_SETUP(excess_ar); + FLEXT_SETUP(excess_kr); + + FLEXT_DSP_SETUP(hypot_ar); + FLEXT_SETUP(hypot_kr); + + FLEXT_DSP_SETUP(ring1_ar); + FLEXT_SETUP(ring1_kr); + + FLEXT_DSP_SETUP(ring2_ar); + FLEXT_SETUP(ring2_kr); + + FLEXT_DSP_SETUP(ring3_ar); + FLEXT_SETUP(ring3_kr); + + FLEXT_DSP_SETUP(ring4_ar); + FLEXT_SETUP(ring4_kr); + + FLEXT_DSP_SETUP(difsqr_ar); + FLEXT_SETUP(difsqr_kr); + + FLEXT_DSP_SETUP(sumsqr_ar); + FLEXT_SETUP(sumsqr_kr); + + FLEXT_DSP_SETUP(sqrsum_ar); + FLEXT_SETUP(sqrsum_kr); + + FLEXT_DSP_SETUP(sqrdif_ar); + FLEXT_SETUP(sqrdif_kr); + + FLEXT_DSP_SETUP(absdif_ar); + FLEXT_SETUP(absdif_kr); + + FLEXT_DSP_SETUP(LFSaw_ar); + FLEXT_SETUP(LFSaw_kr); + + FLEXT_DSP_SETUP(LFPulse_ar); + FLEXT_SETUP(LFPulse_kr); + + FLEXT_DSP_SETUP(Impulse_ar); + FLEXT_SETUP(Impulse_kr); + + FLEXT_DSP_SETUP(Integrator_ar); + FLEXT_SETUP(Integrator_kr); + + FLEXT_DSP_SETUP(Decay_ar); + + FLEXT_DSP_SETUP(Decay2_ar); + + FLEXT_DSP_SETUP(Lag_ar); + + FLEXT_DSP_SETUP(Lag2_ar); + + FLEXT_DSP_SETUP(Lag3_ar); + + FLEXT_DSP_SETUP(LinExp_ar); + FLEXT_SETUP(LinExp_kr); + + FLEXT_DSP_SETUP(DelayN_ar); + + FLEXT_DSP_SETUP(DelayL_ar); + + FLEXT_DSP_SETUP(DelayC_ar); + + FLEXT_DSP_SETUP(CombN_ar); + + FLEXT_DSP_SETUP(CombL_ar); + + FLEXT_DSP_SETUP(CombC_ar); + + FLEXT_DSP_SETUP(AllpassN_ar); + + FLEXT_DSP_SETUP(AllpassL_ar); + + FLEXT_DSP_SETUP(AllpassC_ar); + + FLEXT_DSP_SETUP(PitchShift_ar); + + FLEXT_DSP_SETUP(Resonz_ar); + + FLEXT_DSP_SETUP(OnePole_ar); + FLEXT_SETUP(OnePole_kr); + + FLEXT_DSP_SETUP(OneZero_ar); + FLEXT_SETUP(OneZero_kr); + + FLEXT_DSP_SETUP(TwoPole_ar); + + FLEXT_DSP_SETUP(TwoZero_ar); + + FLEXT_DSP_SETUP(FOS_ar); + FLEXT_SETUP(FOS_kr); + + FLEXT_DSP_SETUP(SOS_ar); + + FLEXT_DSP_SETUP(RLPF_ar); + + FLEXT_DSP_SETUP(RHPF_ar); + + FLEXT_DSP_SETUP(LPF_ar); + + FLEXT_DSP_SETUP(HPF_ar); + + FLEXT_DSP_SETUP(BPF_ar); + + FLEXT_DSP_SETUP(BRF_ar); + + FLEXT_DSP_SETUP(LPZ1_ar); + FLEXT_SETUP(LPZ1_kr); + + FLEXT_DSP_SETUP(HPZ1_ar); + FLEXT_SETUP(HPZ1_kr); + + FLEXT_DSP_SETUP(LPZ2_ar); + FLEXT_SETUP(LPZ2_kr); + + FLEXT_DSP_SETUP(HPZ2_ar); + FLEXT_SETUP(HPZ2_kr); + + FLEXT_DSP_SETUP(BRZ2_ar); + FLEXT_SETUP(BRZ2_kr); + + FLEXT_DSP_SETUP(BPZ2_ar); + FLEXT_SETUP(BPZ2_kr); + + FLEXT_DSP_SETUP(LFDNoise0_ar); + + FLEXT_DSP_SETUP(LFDNoise1_ar); + + FLEXT_DSP_SETUP(LFDNoise2_ar); + + FLEXT_DSP_SETUP(scadd_ar); + + FLEXT_DSP_SETUP(scsub_ar); + + FLEXT_DSP_SETUP(scmul_ar); + + FLEXT_DSP_SETUP(scdiv_ar); + + FLEXT_DSP_SETUP(Convolution_ar); + + //init ffts + init_ffts(); +} + +FLEXT_LIB_SETUP(sc4pd,sc4pd_library_setup); diff --git a/sc4pd/source/ring1.cpp b/sc4pd/source/ring1.cpp new file mode 100644 index 0000000..9c09e40 --- /dev/null +++ b/sc4pd/source/ring1.cpp @@ -0,0 +1,130 @@ +/* sc4pd + ring1, ring1~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + +inline float sc_ring1 (float a, float b) +{ + return a*b+a; +} + + +/* ------------------------ ring1~ -----------------------------*/ + +class ring1_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(ring1_ar,sc4pd_dsp); + +public: + ring1_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("ring1~",ring1_ar); + +ring1_ar::ring1_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void ring1_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_ring1( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ ring1 ------------------------------*/ + +class ring1_kr + :public flext_base +{ + FLEXT_HEADER(ring1_kr,flext_base); + +public: + ring1_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("ring1",ring1_kr); + +ring1_kr::ring1_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void ring1_kr::m_perform(float f) +{ + ToOutFloat(0,sc_ring1(f,b)); +} + +void ring1_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/ring2.cpp b/sc4pd/source/ring2.cpp new file mode 100644 index 0000000..c2432e9 --- /dev/null +++ b/sc4pd/source/ring2.cpp @@ -0,0 +1,130 @@ +/* sc4pd + ring2, ring2~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + +inline float sc_ring2 (float a, float b) +{ + return a*b+a+b; +} + + +/* ------------------------ ring2~ -----------------------------*/ + +class ring2_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(ring2_ar,sc4pd_dsp); + +public: + ring2_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("ring2~",ring2_ar); + +ring2_ar::ring2_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void ring2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_ring2( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ ring2 ------------------------------*/ + +class ring2_kr + :public flext_base +{ + FLEXT_HEADER(ring2_kr,flext_base); + +public: + ring2_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("ring2",ring2_kr); + +ring2_kr::ring2_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void ring2_kr::m_perform(float f) +{ + ToOutFloat(0,sc_ring2(f,b)); +} + +void ring2_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/ring3.cpp b/sc4pd/source/ring3.cpp new file mode 100644 index 0000000..d8de166 --- /dev/null +++ b/sc4pd/source/ring3.cpp @@ -0,0 +1,130 @@ +/* sc4pd + ring3, ring3~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + +inline float sc_ring3 (float a, float b) +{ + return a*a*b; +} + + +/* ------------------------ ring3~ -----------------------------*/ + +class ring3_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(ring3_ar,sc4pd_dsp); + +public: + ring3_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("ring3~",ring3_ar); + +ring3_ar::ring3_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void ring3_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_ring3( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ ring3 ------------------------------*/ + +class ring3_kr + :public flext_base +{ + FLEXT_HEADER(ring3_kr,flext_base); + +public: + ring3_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("ring3",ring3_kr); + +ring3_kr::ring3_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void ring3_kr::m_perform(float f) +{ + ToOutFloat(0,sc_ring3(f,b)); +} + +void ring3_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/ring4.cpp b/sc4pd/source/ring4.cpp new file mode 100644 index 0000000..f9c6035 --- /dev/null +++ b/sc4pd/source/ring4.cpp @@ -0,0 +1,131 @@ +/* sc4pd + ring4, ring4~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + + +inline float sc_ring4 (float a, float b) +{ + return (a*a*b)-(a*b*b); +} + + +/* ------------------------ ring4~ -----------------------------*/ + +class ring4_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(ring4_ar,sc4pd_dsp); + +public: + ring4_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("ring4~",ring4_ar); + +ring4_ar::ring4_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void ring4_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_ring4( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ ring4 ------------------------------*/ + +class ring4_kr + :public flext_base +{ + FLEXT_HEADER(ring4_kr,flext_base); + +public: + ring4_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("ring4",ring4_kr); + +ring4_kr::ring4_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void ring4_kr::m_perform(float f) +{ + ToOutFloat(0,sc_ring4(f,b)); +} + +void ring4_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/sc+.cpp b/sc4pd/source/sc+.cpp new file mode 100644 index 0000000..e1a7e26 --- /dev/null +++ b/sc4pd/source/sc+.cpp @@ -0,0 +1,113 @@ +/* sc4pd + sc+~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phil Minton & Veryan Weston: Ways Past + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ sc+~ -------------------------------*/ + +class scadd_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(scadd_ar,sc4pd_dsp); + +public: + scadd_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_nextsummand = f; + changed = true; + } + + float m_nextsummand, m_summand; + bool changed; + +private: + FLEXT_CALLBACK_1(m_set,float); +}; + +FLEXT_LIB_DSP_V("sc+~",scadd_ar); + +scadd_ar::scadd_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(1,m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_summand = sc_getfloatarg(Args,0); + + AddInSignal("signal"); + AddInFloat("scalar"); + AddOutSignal(); + + changed = false; +} + +void scadd_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + if (changed) + { + float xb = m_nextsummand; + float slope = CALCSLOPE(xb, m_summand); + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = ZXP(nin) + xb; + xb += slope; + } + m_summand = xb; + changed = false; + } + else + { + float xb = m_summand; + + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = ZXP(nin) + xb; + } + } +} + + diff --git a/sc4pd/source/sc-.cpp b/sc4pd/source/sc-.cpp new file mode 100644 index 0000000..0dfd2ce --- /dev/null +++ b/sc4pd/source/sc-.cpp @@ -0,0 +1,142 @@ +/* sc4pd + sc-~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phil Minton & Veryan Weston: Ways + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ sc-~ -------------------------------*/ + +class scsub_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(scsub_ar,sc4pd_dsp); + +public: + scsub_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_nextsubtrahend = f; + changed = true; + } + + float m_nextsubtrahend, m_subtrahend; + bool changed; + bool invert; + +private: + FLEXT_CALLBACK_1(m_set,float); +}; + +FLEXT_LIB_DSP_V("sc-~",scsub_ar); + +scsub_ar::scsub_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(1,m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_subtrahend = sc_getfloatarg(Args,0); + + invert = sc_inv(Args); + + AddInSignal("signal"); + AddInFloat("scalar"); + AddOutSignal(); + + changed = false; +} + +void scsub_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + if (invert) + { + if (changed) + { + float xb = m_nextsubtrahend; + float slope = CALCSLOPE(xb, m_subtrahend); + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = xb - ZXP(nin); + xb += slope; + } + m_subtrahend = xb; + changed = false; + } + else + { + float xb = m_subtrahend; + + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = xb - ZXP(nin); + } + } + } + else + { + if (changed) + { + float xb = m_nextsubtrahend; + float slope = CALCSLOPE(xb, m_subtrahend); + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = ZXP(nin) - xb; + xb += slope; + } + m_subtrahend = xb; + changed = false; + } + else + { + float xb = m_subtrahend; + + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = ZXP(nin) - xb; + } + } + } +} + diff --git a/sc4pd/source/sc4pd.hpp b/sc4pd/source/sc4pd.hpp new file mode 100644 index 0000000..13d82c0 --- /dev/null +++ b/sc4pd/source/sc4pd.hpp @@ -0,0 +1,128 @@ +/* sc4pd: + support functions + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Morton Feldman: For John Cage + +*/ + +#ifndef _SC4PD_HPP + +#include <flext.h> + +#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 406) +#error You need at least FLEXT version 0.4.6 +#endif + +#include "SC_PlugIn.h" +#include "support.hpp" + +/* this macro has to be redefined to work with flext */ + +// calculate a slope for control rate interpolation to audio rate. +//#define CALCSLOPE(next,prev) ((next - prev) * unit->mRate->mSlopeFactor) +#undef CALCSLOPE +#define CALCSLOPE(next,prev) ((next - prev) * 1/ Blocksize()) + + + +//#define SAMPLERATE (unit->mRate->mSampleRate) +#undef SAMPLERATE +#define SAMPLERATE Samplerate() + +//#define BUFLENGTH (unit->mBufLength) +#undef BUFLENGTH +#define BUFLENGTH Blocksize() + +/* to make sure the behaviour is consistent: */ + +#undef ZXP +#define ZXP(z) (*(z)++) + + + +class sc4pd_dsp + : public flext_dsp +{ + FLEXT_HEADER(sc4pd_dsp,flext_dsp); + + +/* some initialisation functions, adapted from SC_Rate.cpp*/ + + inline float sc_sampledur() + { + return 1 / Samplerate(); + } + + inline float sc_radianspersample() + { + return twopi / Samplerate(); + } + + inline float sc_bufduration() + { + return Blocksize() / Samplerate(); + } + + inline float sc_bufrate() + { + return 1 / sc_bufduration(); + } + + inline float sc_slopefactor() + { + return 1 / Blocksize(); + } + + inline int sc_filterloops() + { + return Blocksize() / 3; + } + + inline int sc_filterremain() + { + return Blocksize() % 3; + } + + inline float sc_filterslope() + { + float f = sc_filterloops(); + if (f == 0) + return 0; + else + return 1. / f; + } + +}; + + +#define _SC4PD_HPP +#endif diff --git a/sc4pd/source/scaleneg.cpp b/sc4pd/source/scaleneg.cpp new file mode 100644 index 0000000..d91b324 --- /dev/null +++ b/sc4pd/source/scaleneg.cpp @@ -0,0 +1,125 @@ +/* sc4pd + scaleneg, scaleneg(~) + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & Toshimaru Nakamura: Weather Sky + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ scaleneg~ -----------------------------*/ + +class scaleneg_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(scaleneg_ar,sc4pd_dsp); + +public: + scaleneg_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("scaleneg~",scaleneg_ar); + +scaleneg_ar::scaleneg_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void scaleneg_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_scaleneg( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ scaleneg ------------------------------*/ + +class scaleneg_kr + :public flext_base +{ + FLEXT_HEADER(scaleneg_kr,flext_base); + +public: + scaleneg_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("scaleneg",scaleneg_kr); + +scaleneg_kr::scaleneg_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void scaleneg_kr::m_perform(float f) +{ + ToOutFloat(0,sc_scaleneg(f,b)); +} + +void scaleneg_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/scdiv.cpp b/sc4pd/source/scdiv.cpp new file mode 100644 index 0000000..045d1b4 --- /dev/null +++ b/sc4pd/source/scdiv.cpp @@ -0,0 +1,142 @@ +/* sc4pd + sc/~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phil Minton & Veryan Weston: Ways + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ sc/~ -------------------------------*/ + +class scdiv_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(scdiv_ar,sc4pd_dsp); + +public: + scdiv_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_nextdivisor = f; + changed = true; + } + + float m_nextdivisor, m_divisor; + bool changed; + bool invert; + +private: + FLEXT_CALLBACK_1(m_set,float); +}; + +FLEXT_LIB_DSP_V("sc/~",scdiv_ar); + +scdiv_ar::scdiv_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(1,m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_divisor = sc_getfloatarg(Args,0); + + invert = sc_inv(Args); + + AddInSignal("signal"); + AddInFloat("scalar"); + AddOutSignal(); + + changed = false; +} + +void scdiv_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + if (invert) + { + if (changed) + { + float xb = m_nextdivisor; + float slope = CALCSLOPE(xb, m_divisor); + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = xb / ZXP(nin); + xb += slope; + } + m_divisor = xb; + changed = false; + } + else + { + float xb = m_divisor; + + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = xb / ZXP(nin); + } + } + } + else + { + if (changed) + { + float xb = m_nextdivisor; + float slope = CALCSLOPE(xb, m_divisor); + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = ZXP(nin) / xb; + xb += slope; + } + m_divisor = xb; + changed = false; + } + else + { + float xb = m_divisor; + + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = ZXP(nin) / xb; + } + } + } +} + diff --git a/sc4pd/source/scmul.cpp b/sc4pd/source/scmul.cpp new file mode 100644 index 0000000..55ac074 --- /dev/null +++ b/sc4pd/source/scmul.cpp @@ -0,0 +1,113 @@ +/* sc4pd + sc*~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phil Minton & Veryan Weston: Ways + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ sc*~ -------------------------------*/ + +class scmul_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(scmul_ar,sc4pd_dsp); + +public: + scmul_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_nextfactor = f; + changed = true; + } + + float m_nextfactor, m_factor; + bool changed; + +private: + FLEXT_CALLBACK_1(m_set,float); +}; + +FLEXT_LIB_DSP_V("sc*~",scmul_ar); + +scmul_ar::scmul_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(1,m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_factor = sc_getfloatarg(Args,0); + + AddInSignal("signal"); + AddInFloat("scalar"); + AddOutSignal(); + + changed = false; +} + +void scmul_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + if (changed) + { + float xb = m_nextfactor; + float slope = CALCSLOPE(xb, m_factor); + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = ZXP(nin) * xb; + xb += slope; + } + m_factor = xb; + changed = false; + } + else + { + float xb = m_factor; + + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = ZXP(nin) * xb; + } + } +} + + diff --git a/sc4pd/source/sqrdif.cpp b/sc4pd/source/sqrdif.cpp new file mode 100644 index 0000000..165ee2b --- /dev/null +++ b/sc4pd/source/sqrdif.cpp @@ -0,0 +1,132 @@ +/* sc4pd + sqrdif, sqrdif~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + + +inline float sc_sqrdif (float a, float b) +{ + float f=a-b; + return f*f; +} + + +/* ------------------------ sqrdif~ -----------------------------*/ + +class sqrdif_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(sqrdif_ar,sc4pd_dsp); + +public: + sqrdif_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("sqrdif~",sqrdif_ar); + +sqrdif_ar::sqrdif_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void sqrdif_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_sqrdif( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ sqrdif ------------------------------*/ + +class sqrdif_kr + :public flext_base +{ + FLEXT_HEADER(sqrdif_kr,flext_base); + +public: + sqrdif_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("sqrdif",sqrdif_kr); + +sqrdif_kr::sqrdif_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void sqrdif_kr::m_perform(float f) +{ + ToOutFloat(0,sc_sqrdif(f,b)); +} + +void sqrdif_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/sqrsum.cpp b/sc4pd/source/sqrsum.cpp new file mode 100644 index 0000000..756c07e --- /dev/null +++ b/sc4pd/source/sqrsum.cpp @@ -0,0 +1,132 @@ +/* sc4pd + sqrsum, sqrsum~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + + +inline float sc_sqrsum (float a, float b) +{ + float f=a+b; + return f*f; +} + + +/* ------------------------ sqrsum~ -----------------------------*/ + +class sqrsum_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(sqrsum_ar,sc4pd_dsp); + +public: + sqrsum_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("sqrsum~",sqrsum_ar); + +sqrsum_ar::sqrsum_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void sqrsum_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_sqrsum( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ sqrsum ------------------------------*/ + +class sqrsum_kr + :public flext_base +{ + FLEXT_HEADER(sqrsum_kr,flext_base); + +public: + sqrsum_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("sqrsum",sqrsum_kr); + +sqrsum_kr::sqrsum_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void sqrsum_kr::m_perform(float f) +{ + ToOutFloat(0,sc_sqrsum(f,b)); +} + +void sqrsum_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/sumsqr.cpp b/sc4pd/source/sumsqr.cpp new file mode 100644 index 0000000..518eb01 --- /dev/null +++ b/sc4pd/source/sumsqr.cpp @@ -0,0 +1,131 @@ +/* sc4pd + sumsqr, sumsqr~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + + +inline float sc_sumsqr (float a, float b) +{ + return a*a+b*b; +} + + +/* ------------------------ sumsqr~ -----------------------------*/ + +class sumsqr_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(sumsqr_ar,sc4pd_dsp); + +public: + sumsqr_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("sumsqr~",sumsqr_ar); + +sumsqr_ar::sumsqr_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void sumsqr_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_sumsqr( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ sumsqr ------------------------------*/ + +class sumsqr_kr + :public flext_base +{ + FLEXT_HEADER(sumsqr_kr,flext_base); + +public: + sumsqr_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("sumsqr",sumsqr_kr); + +sumsqr_kr::sumsqr_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void sumsqr_kr::m_perform(float f) +{ + ToOutFloat(0,sc_sumsqr(f,b)); +} + +void sumsqr_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/support.cpp b/sc4pd/source/support.cpp new file mode 100644 index 0000000..e753056 --- /dev/null +++ b/sc4pd/source/support.cpp @@ -0,0 +1,184 @@ +/* sc4pd: + support functions + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Nmperign & Guenter Mueller: More Gloom, More Light + +*/ + +#include "sc4pd.hpp" + +#include <flsupport.h> + + +bool sc_add (flext::AtomList& a) +{ + for (int i = 0; i!=a.Count();++i) + { + if ( flext::IsSymbol(a[i]) ) + { + const char * teststring; + teststring = flext::GetString(a[i]); + if((strcmp(teststring,"add"))==0) + return true; + } + } + return false; +} + +float sc_getfloatarg (flext::AtomList& a,int i) +{ + if (a.Count() > 0 && a.Count() > i) + return flext::GetAFloat(a[i]); + else + return 0; +} + +bool sc_ar(flext::AtomList& a) +{ + for (int i = 0; i!=a.Count();++i) + { + if ( flext::IsSymbol(a[i]) ) + { + const char * teststring; + teststring = flext::GetString(a[i]); + if((strcmp(teststring,"ar"))==0) + return true; + } + } + return false; +} + +bool sc_inv(flext::AtomList& a) +{ + for (int i = 0; i!=a.Count();++i) + { + if ( flext::IsSymbol(a[i]) ) + { + const char * teststring; + teststring = flext::GetString(a[i]); + if((strcmp(teststring,"inv"))==0) + return true; + } + } + return false; +} + +int32 timeseed() +{ + static int32 count = 0; + + double time = flext::GetOSTime(); + + double sec = trunc(time); + double usec = (time-sec)*1e6; + + time_t tsec = sec; + useconds_t tusec =usec; /* not exacty the way, it's calculated + in SuperCollider, but it's only + the seed */ + + return (int32)tsec ^ (int32)tusec ^ count--; +} + +/* from Convolution.cpp */ +extern "C" +{ + float *cosTable[32]; + float *fftWindow[32]; +} + + +float* create_cosTable(int log2n) +{ + int size = 1 << log2n; + int size2 = size / 4 + 1; + float *win = (float*)malloc(size2 * sizeof(float)); + double winc = twopi / size; + for (int i=0; i<size2; ++i) { + double w = i * winc; + win[i] = cos(w); + } + return win; +} + +float* create_fftwindow(int log2n) +{ + int size = 1 << log2n; + float *win = (float*)malloc(size * sizeof(float)); + //double winc = twopi / size; + double winc = pi / size; + for (int i=0; i<size; ++i) { + double w = i * winc; + //win[i] = 0.5 - 0.5 * cos(w); + win[i] = sin(w); + } + return win; +} + +void init_ffts() +{ +#if __VEC__ + + for (int i=0; i<32; ++i) { + fftsetup[i] = 0; + } + for (int i=0; i<15; ++i) { + fftsetup[i] = create_fftsetup(i, kFFTRadix2); + } +#else + for (int i=0; i<32; ++i) { + cosTable[i] = 0; + fftWindow[i] = 0; + } + for (int i=3; i<15; ++i) { + cosTable[i] = create_cosTable(i); + fftWindow[i] = create_fftwindow(i); + } +#endif +} + +void DoWindowing(int log2n, float * fftbuf, int bufsize) +{ + float *win = fftWindow[log2n]; + + //printf("fail? %i %d /n", log2n, win); + + if (!win) return; + float *in = fftbuf - 1; + win--; + + for (int i=0; i<bufsize; ++i) { + *++in *= *++win; + } +} + +#include "fftlib.c" diff --git a/sc4pd/source/support.hpp b/sc4pd/source/support.hpp new file mode 100644 index 0000000..12885cb --- /dev/null +++ b/sc4pd/source/support.hpp @@ -0,0 +1,124 @@ +/* sc4pd: + support functions + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phosphor + +*/ + +#ifndef _SUPPORT_HPP +#define _SUPPORT_HPP + +#include <flext.h> +#include "SC_PlugIn.h" + + +#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 406) +#error You need at least FLEXT version 0.4.6 +#endif + + +/* for argument parsing */ +bool sc_add (flext::AtomList& a); +float sc_getfloatarg (flext::AtomList& a,int i); +bool sc_ar(flext::AtomList& a); +bool sc_inv(flext::AtomList& a); + + +/* for rngs */ + +// macros to put rgen state in registers +#define RGET \ + uint32 s1 = rgen.s1; \ + uint32 s2 = rgen.s2; \ + uint32 s3 = rgen.s3; + +#define RPUT \ + rgen.s1 = s1; \ + rgen.s2 = s2; \ + rgen.s3 = s3; + +int32 timeseed(); + +/* cubic interpolation from DelayUGens.cpp */ +inline float cubicinterp(float x, float y0, float y1, float y2, float y3) +{ + // 4-point, 3rd-order Hermite (x-form) + float c0 = y1; + float c1 = 0.5f * (y2 - y0); + float c2 = y0 - 2.5f * y1 + 2.f * y2 - 0.5f * y3; + float c3 = 0.5f * (y3 - y0) + 1.5f * (y1 - y2); + + return ((c3 * x + c2) * x + c1) * x + c0; +} + +/* feedback calculation from DelayUGens.cpp */ +inline float CalcFeedback(float delaytime, float decaytime) +{ + if (delaytime == 0.f) { + return 0.f; + } else if (decaytime > 0.f) { + return exp(log001 * delaytime / decaytime); + } else if (decaytime < 0.f) { + return -exp(log001 * delaytime / -decaytime); + } else { + return 0.f; + } +} + + +/* this is adapted from thomas grill's xsample: +xsample - extended sample objects for Max/MSP and pd (pure data) + +Copyright (c) 2001-2004 Thomas Grill (xovo@gmx.net) +For information on usage and redistribution, and for a DISCLAIMER OF ALL +WARRANTIES, see the file, "license.txt," in this distribution. +*/ + +#define SETSIGFUN(VAR,FUN) v_##VAR = FUN + +#define DEFSIGFUN(NAME) void NAME(int n,t_sample *const *in,t_sample *const *out) + +#define DEFSIGCALL(NAME) \ + inline void NAME(int n,t_sample *const *in,t_sample *const *out) \ + { (this->*v_##NAME)(n,in,out); } \ + void (thisType::*v_##NAME)(int n,t_sample *const *invecs,t_sample *const *outvecs) + +#define SIGFUN(FUN) &thisType::FUN + + +/* from Convolution.cpp */ +void init_ffts(); +float* create_fftwindow(int log2n); +float* create_cosTable(int log2n); +void DoWindowing(int log2n, float * fftbuf, int bufsize); + +#endif diff --git a/sc4pd/source/template.cpp b/sc4pd/source/template.cpp new file mode 100644 index 0000000..15d9f06 --- /dev/null +++ b/sc4pd/source/template.cpp @@ -0,0 +1,37 @@ +/* sc4pd + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: + +*/ + +#include "sc4pd.hpp" |