[PD-cvs] externals/sc4pd/source PitchShift.cpp,NONE,1.1 main.cpp,1.19,1.20

Tim Blechmann timblech at users.sourceforge.net
Fri Aug 6 10:34:44 CEST 2004


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

Modified Files:
	main.cpp 
Added Files:
	PitchShift.cpp 
Log Message:
checkin of PitchShift~

Index: main.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/sc4pd/source/main.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -d -r1.19 -r1.20
*** main.cpp	4 Aug 2004 18:23:15 -0000	1.19
--- main.cpp	6 Aug 2004 08:34:42 -0000	1.20
***************
*** 63,67 ****
  	 "          DelayL~, DelayC~, CombN~, CombL~, CombC~, AllpassN~, "
  	 "AllpassL~,\n"
! 	 "          AllpassC~"
  	 "\n"
  	 );
--- 63,67 ----
  	 "          DelayL~, DelayC~, CombN~, CombL~, CombC~, AllpassN~, "
  	 "AllpassL~,\n"
! 	 "          AllpassC~, PitchShift~"
  	 "\n"
  	 );

--- NEW FILE: PitchShift.cpp ---
/* 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: 
   
*/

#include "sc4pd.hpp"

/* ------------------------ PitchShift~ -----------------------------*/

class PitchShift_ar
    :public flext_dsp
{
    FLEXT_HEADER(PitchShift_ar,flext_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_windowsize(float f)
    {
	m_windowsize = f;
    }

    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_windowsize);
    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,"windowSize",m_set_windowsize);
    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 /* *out, *in,*/ *dlybuf;
    float winsize, pchratio;
    float fdelaylen, slope;
    long framesize, last;
    
    //out = ZOUT(0);
    //in = ZIN(0);
    pchratio = m_pitchratio;
    winsize = m_windowsize;
	
    delaybufsize = (long)ceil(winsize * 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)(winsize * 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, 
	winsize, 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;
    winsize = m_windowsize;
    pchdisp = m_pitchdispersion;
    timedisp = m_timedispersion;
    timedisp = sc_clip(timedisp, 0.f, winsize) * 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, 
	winsize, pchdisp, timedisp;
    long remain, nsmps, idelaylen, irdphase, irdphaseb, iwrphase, mask, idsamp;
    long counter, stage, framesize;
    
    RGET;
    
    nout = *out;
    nin = *in;
    
    pchratio = m_pitchratio;
    winsize = m_windowsize;
    pchdisp = m_pitchdispersion;
    timedisp = m_timedispersion;
    
    timedisp = sc_clip(timedisp, 0.f, winsize) * 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;
}
    

/* todo: does a control rate PitchShift make sense? */





More information about the Pd-cvs mailing list