From d1ecedf8e46d5486253436aa7fd5ba4dff19d65b Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Wed, 3 Sep 2003 02:38:08 +0000 Subject: "" svn path=/trunk/; revision=930 --- externals/grill/xsample/source/groove.cpp | 54 +++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 9 deletions(-) (limited to 'externals/grill/xsample/source/groove.cpp') diff --git a/externals/grill/xsample/source/groove.cpp b/externals/grill/xsample/source/groove.cpp index 90e9c5f8..accfc0d9 100644 --- a/externals/grill/xsample/source/groove.cpp +++ b/externals/grill/xsample/source/groove.cpp @@ -39,6 +39,7 @@ public: virtual BL m_reset(); virtual V m_pos(F pos); + V m_posmod(F pos); virtual V m_all(); virtual V m_min(F mn); virtual V m_max(F mx); @@ -79,9 +80,16 @@ protected: inline V setpos(F pos) { - if(pos < curmin) pos = curmin; - else if(pos > curmax) pos = curmax; - curpos = pos; + if(pos < znsmin) curpos = znsmin; + else if(pos > znsmax) curpos = znsmax; + else curpos = pos; + } + + inline V setposmod(F pos) + { + F p = pos-znsmin; + if(p >= 0) curpos = znsmin+fmod(p,znsmax-znsmin); + else curpos = znsmax+fmod(p,znsmax-znsmin); } inline V mg_pos(F &v) const { v = curpos*s2u; } @@ -116,6 +124,7 @@ private: } FLEXT_CALLBACK_F(m_pos) + FLEXT_CALLBACK_F(m_posmod) FLEXT_CALLBACK_F(m_min) FLEXT_CALLBACK_F(m_max) FLEXT_CALLBACK(m_all) @@ -150,6 +159,7 @@ V xgroove::setup(t_classid c) FLEXT_CADDATTR_VAR(c,"min",mg_min,m_min); FLEXT_CADDATTR_VAR(c,"max",mg_max,m_max); FLEXT_CADDATTR_VAR(c,"pos",mg_pos,m_pos); + FLEXT_CADDMETHOD_(c,0,"posmod",m_posmod); FLEXT_CADDATTR_VAR_E(c,"loop",loopmode,m_loop); @@ -266,6 +276,12 @@ V xgroove::m_pos(F pos) setpos(pos?pos/s2u:0); } +// motivated by Tim Blechmann +V xgroove::m_posmod(F pos) +{ + setposmod(pos?pos/s2u:0); +} + V xgroove::m_all() { xsample::m_all(); @@ -315,21 +331,30 @@ V xgroove::m_xshape(I argc,const t_atom *argv) if(argc >= 1 && CanbeInt(argv[0])) xshape = GetAInt(argv[0]); if(argc >= 2 && CanbeFloat(argv[1])) { xshparam = GetAFloat(argv[1]); +/* // clip to 0..1 if(xshparam < 0) xshparam = 0; else if(xshparam > 1) xshparam = 1; +*/ } I i; switch(xshape) { case 1: + // sine half wave for(i = 0; i <= XZONE_TABLE; ++i) - znmul[i] = ((sin(i*(pi/XZONE_TABLE)-pi/2.)+1)/2)*xshparam+i*(1./XZONE_TABLE)*(1-xshparam); + znmul[i] = sin(i*pi/(XZONE_TABLE*2))*xshparam+i*(1.f/XZONE_TABLE)*(1.f-xshparam); + break; + case 2: + // sine full wave + for(i = 0; i <= XZONE_TABLE; ++i) + znmul[i] = ((sin(i*(pi/XZONE_TABLE)-pi*0.5f)+1.f)*0.5f)*xshparam+i*(1.f/XZONE_TABLE)*(1.f-xshparam); break; case 0: default: + // linear for(i = 0; i <= XZONE_TABLE; ++i) - znmul[i] = i*(1./XZONE_TABLE); + znmul[i] = i*(1.f/XZONE_TABLE); } } @@ -607,6 +632,8 @@ V xgroove::s_pos_loopzn(I n,S *const *invecs,S *const *outvecs) register D o = curpos; for(I i = 0; i < n; ++i) { + // \TODO: exploit relationships: smin <= lmin, smax >= lmax + // normalize offset if(o >= smax) { o = fmod(o-smin,plen)+smin; @@ -644,27 +671,35 @@ V xgroove::s_pos_loopzn(I n,S *const *invecs,S *const *outvecs) } // normalize and store current playing position + if(o < znsmin) o += plen; setpos(o); + // calculate samples (1st voice) playfun(n,&pos,outvecs); - arrscale(n,pos,pos); - if(inzn) { - // only if we were in cross-fade zone + // only if we are in cross-fade zone + + // calculate samples in loop zone (2nd voice) playfun(n,&znpos,znbuf); - arrscale(n,znidx,znpos,-XZONE_TABLE,-1); + // calculate counterpart in loop fade + arrscale(n,znidx,znpos,XZONE_TABLE,-1); + // calculate fade coefficients zonefun(znmul,0,XZONE_TABLE+1,n,1,1,&znidx,&znidx); zonefun(znmul,0,XZONE_TABLE+1,n,1,1,&znpos,&znpos); + // mix voices for all channels for(I o = 0; o < outchns; ++o) { F *ov = outvecs[o],*ob = znbuf[o]; for(I i = 0; i < n; ++i,ov++,ob++) *ov = (*ov)*znidx[i]+(*ob)*znpos[i]; } } + + // rescale position vector + arrscale(n,pos,pos); } else s_pos_off(n,invecs,outvecs); @@ -791,6 +826,7 @@ V xgroove::m_help() post("\t@max {unit}: set maximum playing point"); post("\tall: select entire buffer length"); post("\tpos {unit}: set playing position (obeying the current scale mode)"); + post("\tposmod {unit}: set playing position (modulo into min/max range)"); post("\tbang/start: start playing"); post("\tstop: stop playing"); post("\trefresh: checks buffer and refreshes outlets"); -- cgit v1.2.1