[PD-cvs] externals/sc4pd/source DelayN.cpp,NONE,1.1 DelayUnit.cpp,NONE,1.1 DelayUnit.hpp,NONE,1.1 Lag2.cpp,NONE,1.1 Lag3.cpp,NONE,1.1 LinExp.cpp,NONE,1.1 main.cpp,1.15,1.16 sc4pd.hpp,1.2,1.3 template.cpp,1.1.1.1,1.2

Tim Blechmann timblech at users.sourceforge.net
Tue Aug 3 11:56:26 CEST 2004


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

Modified Files:
	main.cpp sc4pd.hpp template.cpp 
Added Files:
	DelayN.cpp DelayUnit.cpp DelayUnit.hpp Lag2.cpp Lag3.cpp 
	LinExp.cpp 
Log Message:
works of one morning

Index: main.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/sc4pd/source/main.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -C2 -d -r1.15 -r1.16
*** main.cpp	2 Aug 2004 21:13:50 -0000	1.15
--- main.cpp	3 Aug 2004 09:56:19 -0000	1.16
***************
*** 59,63 ****
  	 "sqrdif(~),\n"
  	 "          sqrsum(~), absdif(~), LFSaw(~), LFPulse(~), Impulse(~),\n"
! 	 "          Integrator(~), Decay~, Decay2~, Lag~\n"
  	 );
  
--- 59,64 ----
  	 "sqrdif(~),\n"
  	 "          sqrsum(~), absdif(~), LFSaw(~), LFPulse(~), Impulse(~),\n"
! 	 "          Integrator(~), Decay~, Decay2~, Lag~, Lag2~, LinExp(~)"
! 	 "DelayN~\n"
  	 );
  
***************
*** 199,202 ****
--- 200,212 ----
  
      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); 
  }
  

--- NEW FILE: DelayUnit.cpp ---
/* 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(float f, float g)
{
    m_maxdelaytime = f;
    m_delaytime = g;
    m_dlybuf = 0;
    
    DelayUnit_AllocDelayLine();
    
    m_dsamp = CalcDelay(m_delaytime);	
    
    m_numoutput = 0;
    m_iwrphase = 0;
}

Index: template.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/sc4pd/source/template.cpp,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** template.cpp	14 Jul 2004 16:21:44 -0000	1.1.1.1
--- template.cpp	3 Aug 2004 09:56:19 -0000	1.2
***************
*** 35,43 ****
  */
  
! #include <flext.h>
! 
! #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 406)
! #error You need at least FLEXT version 0.4.6
! #endif
! 
! 
--- 35,37 ----
  */
  
! #include "sc4pd.hpp"

Index: sc4pd.hpp
===================================================================
RCS file: /cvsroot/pure-data/externals/sc4pd/source/sc4pd.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** sc4pd.hpp	2 Aug 2004 21:13:50 -0000	1.2
--- sc4pd.hpp	3 Aug 2004 09:56:19 -0000	1.3
***************
*** 35,38 ****
--- 35,41 ----
  */
  
+ #ifndef _SC4PD_HPP
+ #define _SC$PD_HPP
+ 
  #include <flext.h>
  
***************
*** 52,55 ****
--- 55,69 ----
  
  
+ 
+ //#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: */
  
***************
*** 57,58 ****
--- 71,77 ----
  #define ZXP(z) (*(z)++)
  
+ 
+ 
+ 
+ 
+ #endif

--- NEW FILE: Lag2.cpp ---
/* 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 flext_dsp
{
    FLEXT_HEADER(Lag2_ar,flext_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? */

--- NEW FILE: Lag3.cpp ---
/* 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 flext_dsp
{
    FLEXT_HEADER(Lag3_ar,flext_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? */

--- NEW FILE: DelayN.cpp ---
/* 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(m_maxdelaytime, m_delaytime);
	post("start");
    }

    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 ? */

--- NEW FILE: DelayUnit.hpp ---
/* 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 flext_dsp
{
    FLEXT_HEADER(DelayUnit_ar, flext_dsp);
public:
    /* functions */
    void DelayUnit_AllocDelayLine();
    void DelayUnit_Reset(float maxdelaytime, float delaytime);  
    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? */

--- NEW FILE: LinExp.cpp ---
/* 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 flext_dsp
{
    FLEXT_HEADER(LinExp_ar,flext_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));
}





More information about the Pd-cvs mailing list