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 ++++++++++++--- externals/grill/xsample/source/inter.h | 106 ++++++++++++++++-------------- externals/grill/xsample/source/main.h | 4 +- 3 files changed, 105 insertions(+), 59 deletions(-) (limited to 'externals/grill/xsample/source') 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"); diff --git a/externals/grill/xsample/source/inter.h b/externals/grill/xsample/source/inter.h index e7f929e8..a87c4ac1 100755 --- a/externals/grill/xsample/source/inter.h +++ b/externals/grill/xsample/source/inter.h @@ -32,19 +32,21 @@ TMPLDEF V xinter::st_play1(const S *bdt,const I smin,const I smax,const I n,cons for(I i = 0; i < n; ++i,++si) { register const I oint = (I)(*(pos++)); register const S *fp; - if(oint < smin) { + + if(oint >= smin) + if(oint < smax) { + // normal + fp = bdt+oint*BCHNS; + } + else { + // position > last sample ... take only last sample + fp = bdt+(smin == smax?smin:smax-1)*BCHNS; + } + else { // position < 0 ... take only 0th sample fp = bdt+smin*BCHNS; } - else if(oint >= smax) { - // position > last sample ... take only last sample - fp = bdt+(smin == smax?smin:smax-1)*BCHNS; - } - else { - // normal - fp = bdt+oint*BCHNS; - } - + for(I ci = 0; ci < OCHNS; ++ci) sig[ci][si] = fp[ci]; } @@ -77,26 +79,27 @@ TMPLDEF V xinter::st_play2(const S *bdt,const I smin,const I smax,const I n,cons const F o = *(pos++); register const I oint = (I)o; - if(oint < smin) { + if(oint >= smin) + if(oint < maxo) { + // normal interpolation + register const F frac = o-oint; + register const S *const fp0 = bdt+oint*BCHNS; + register const S *const fp1 = fp0+BCHNS; + for(I ci = 0; ci < OCHNS; ++ci) + sig[ci][si] = fp0[ci]+frac*(fp1[ci]-fp0[ci]); + } + else { + // position is past last sample -> take the last sample + register const S *const fp = bdt+maxo*BCHNS; + for(I ci = 0; ci < OCHNS; ++ci) + sig[ci][si] = fp[ci]; + } + else { // position is before first sample -> take the first sample register const S *const fp = bdt+smin*BCHNS; for(I ci = 0; ci < OCHNS; ++ci) sig[ci][si] = fp[ci]; } - else if(oint >= maxo) { - // position is past last sample -> take the last sample - register const S *const fp = bdt+maxo*BCHNS; - for(I ci = 0; ci < OCHNS; ++ci) - sig[ci][si] = fp[ci]; - } - else { - // normal interpolation - register const F frac = o-oint; - register const S *const fp0 = bdt+oint*BCHNS; - register const S *const fp1 = fp0+BCHNS; - for(I ci = 0; ci < OCHNS; ++ci) - sig[ci][si] = fp0[ci]+frac*(fp1[ci]-fp0[ci]); - } } // clear rest of output channels (if buffer has less channels) @@ -137,7 +140,35 @@ TMPLDEF V xinter::st_play4(const S *bdt,const I smin,const I smax,const I n,cons register F frac; register const S *fa,*fb,*fc,*fd; - if(oint <= smin) { + if(oint > smin) + if(oint < maxo-2) { + // normal case + + fa = bdt+oint*BCHNS-BCHNS; + frac = o-oint; + fb = fa+BCHNS; + #ifdef __VEC__ + vec_dst(fa,pf,0); + #endif + fc = fb+BCHNS; + fd = fc+BCHNS; + } + else { + // after the end + + if(oint > maxo) oint = maxo,o = (float)smax; + frac = o-oint; + + fb = bdt+oint*BCHNS; + fa = fb-BCHNS; + + // \TODO what about wraparound (in loop/palindrome mode) ? + fc = fb >= maxp?maxp:fb+BCHNS; + fd = fc >= maxp?maxp:fc+BCHNS; + } + else { + // before the beginning + // if oint < first sample set it to first sample // \TODO what about wraparound (in loop/palindrome mode) ? if(oint < smin) oint = smin,o = (float)smin; @@ -150,28 +181,7 @@ TMPLDEF V xinter::st_play4(const S *bdt,const I smin,const I smax,const I n,cons fc = fb+BCHNS; fd = fc+BCHNS; } - else if(oint >= maxo-2) { - if(oint > maxo) oint = maxo,o = (float)smax; - frac = o-oint; - - fb = bdt+oint*BCHNS; - fa = fb-BCHNS; - - // \TODO what about wraparound (in loop/palindrome mode) ? - fc = fb >= maxp?maxp:fb+BCHNS; - fd = fc >= maxp?maxp:fc+BCHNS; - } - else { - fa = bdt+oint*BCHNS-BCHNS; - frac = o-oint; - fb = fa+BCHNS; -#ifdef __VEC__ - vec_dst(fa,pf,0); -#endif - fc = fb+BCHNS; - fd = fc+BCHNS; - } - + register F f1 = 0.5f*(frac-1.0f); register F f3 = frac*3.0f-1.0f; diff --git a/externals/grill/xsample/source/main.h b/externals/grill/xsample/source/main.h index e174915b..367632d6 100644 --- a/externals/grill/xsample/source/main.h +++ b/externals/grill/xsample/source/main.h @@ -12,7 +12,7 @@ WARRANTIES, see the file, "license.txt," in this distribution. #define __XSAMPLE_H -#define XSAMPLE_VERSION "0.3.0pre14" +#define XSAMPLE_VERSION "0.3.0pre15" #define FLEXT_ATTRIBUTES 1 @@ -154,7 +154,7 @@ protected: inline F scale(F smp) const { return (smp-sclmin)*sclmul; } static V arrscale(I n,const S *in,S *out,S add,S mul) { flext::ScaleSamples(out,in,mul,add,n); } - inline V arrscale(I n,const S *in,S *out) const { arrscale(n,in,out,(S)-sclmin,sclmul); } + inline V arrscale(I n,const S *in,S *out) const { arrscale(n,in,out,-sclmin*sclmul,sclmul); } static V arrmul(I n,const S *in,S *out,S mul) { flext::MulSamples(out,in,mul,n); } inline V arrmul(I n,const S *in,S *out) const { arrmul(n,in,out,(S)(1./s2u)); } -- cgit v1.2.1