[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