Update of /cvsroot/pure-data/externals/grill/xsample/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10764/source
Modified Files: groove.cpp main.h Log Message: ""
Index: groove.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/xsample/source/groove.cpp,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** groove.cpp 7 Apr 2004 02:48:18 -0000 1.25 --- groove.cpp 8 Apr 2004 04:01:44 -0000 1.26 *************** *** 18,22 ****
! #define XZONE_TABLE 512
--- 18,22 ----
! #define XZONE_TABLE 64
*************** *** 46,57 ****
V ms_xfade(I xf);
V ms_xzone(F xz); V mg_xzone(F &xz) { xz = _xzone*s2u; }
- V m_xshape(I argc = 0,const t_atom *argv = NULL); - inline V ms_xshape(const AtomList &ret) { m_xshape(ret.Count(),ret.Atoms()); } - V mg_xshape(AtomList &ret) const; - enum xs_loop { xsl__ = -1, // don't change --- 46,54 ----
V ms_xfade(I xf); + V ms_xshape(I sh);
V ms_xzone(F xz); V mg_xzone(F &xz) { xz = _xzone*s2u; }
enum xs_loop { xsl__ = -1, // don't change *************** *** 64,67 **** --- 61,69 ---- };
+ enum xs_shape { + xss__ = -1, // don't change + xss_lin = 0,xss_qsine,xss_hsine + }; + V m_loop(xs_loop lp = xsl__); *************** *** 76,81 **** xs_fade xfade; I xshape; - F xshparam; - D znmin,znmax; S **znbuf; S *znpos,*znmul,*znidx; --- 78,81 ---- *************** *** 130,133 **** --- 130,135 ---- }
+ static S fade_lin[],fade_qsine[],fade_hsine[]; + FLEXT_CALLBACK_F(m_pos) FLEXT_CALLBACK_F(m_posmod) *************** *** 138,144 **** FLEXT_CALLSET_I(ms_xfade) FLEXT_ATTRGET_I(xfade) FLEXT_CALLSET_F(ms_xzone) FLEXT_CALLGET_F(mg_xzone) - FLEXT_CALLVAR_V(mg_xshape,ms_xshape)
FLEXT_CALLVAR_F(mg_pos,m_pos) --- 140,147 ---- FLEXT_CALLSET_I(ms_xfade) FLEXT_ATTRGET_I(xfade) + FLEXT_CALLSET_I(ms_xshape) + FLEXT_ATTRGET_I(xshape) FLEXT_CALLSET_F(ms_xzone) FLEXT_CALLGET_F(mg_xzone)
FLEXT_CALLVAR_F(mg_pos,m_pos) *************** *** 153,156 **** --- 156,167 ----
+ S xgroove::fade_lin[XZONE_TABLE+1]; + S xgroove::fade_qsine[XZONE_TABLE+1]; + S xgroove::fade_hsine[XZONE_TABLE+1]; + + #ifndef PI + #define PI 3.14159265358979f + #endif + V xgroove::setup(t_classid c) { *************** *** 170,174 **** FLEXT_CADDATTR_VAR(c,"xfade",xfade,ms_xfade); FLEXT_CADDATTR_VAR(c,"xzone",mg_xzone,ms_xzone); ! FLEXT_CADDATTR_VAR(c,"xshape",mg_xshape,ms_xshape); }
--- 181,198 ---- FLEXT_CADDATTR_VAR(c,"xfade",xfade,ms_xfade); FLEXT_CADDATTR_VAR(c,"xzone",mg_xzone,ms_xzone); ! FLEXT_CADDATTR_VAR(c,"xshape",xshape,ms_xshape); ! ! // initialize fade tables ! for(int i = 0; i <= XZONE_TABLE; ++i) { ! const float x = i*(1.f/XZONE_TABLE); ! // linear ! fade_lin[i] = x; ! ! // quarter sine wave ! fade_qsine[i] = sin(x*(PI/2)); ! ! // half sine wave ! fade_hsine[i] = (sin(x*PI-PI/2)+1.f)*0.5f; ! } }
*************** *** 176,181 **** loopmode(xsl_loop),curpos(0), _xzone(0),xzone(0),pblksz(0), ! xfade(xsf_keeplooppos),xshape(0),xshparam(1), ! znbuf(NULL),znmul(NULL),znidx(NULL),znpos(NULL), bidir(1) { --- 200,205 ---- loopmode(xsl_loop),curpos(0), _xzone(0),xzone(0),pblksz(0), ! xfade(xsf_keeplooppos),xshape(xss_lin), ! znidx(NULL),znpos(NULL), bidir(1) { *************** *** 196,200 **** #if FLEXT_SYS == FLEXT_SYS_MAX ! // oldstyle command line? if(argi == 1 && argc == 2 && CanbeInt(argv[argi])) { outchns = GetAInt(argv[argi]); --- 220,224 ---- #if FLEXT_SYS == FLEXT_SYS_MAX ! // old-style command line? if(argi == 1 && argc == 2 && CanbeInt(argv[argi])) { outchns = GetAInt(argv[argi]); *************** *** 223,231 **** znbuf = new S *[outchns]; for(I i = 0; i < outchns; ++i) znbuf[i] = NULL; - znpos = NULL; - znidx = NULL; - znmul = new S[XZONE_TABLE+1];
! m_xshape(); }
--- 247,252 ---- znbuf = new S *[outchns]; for(I i = 0; i < outchns; ++i) znbuf[i] = NULL;
! ms_xshape(xshape); }
*************** *** 233,243 **** { if(znbuf) { ! for(I i = 0; i < outchns; ++i) if(znbuf[i]) delete[] znbuf[i]; delete[] znbuf; }
! if(znpos) delete[] znpos; ! if(znidx) delete[] znidx; ! delete[] znmul; }
--- 254,263 ---- { if(znbuf) { ! for(I i = 0; i < outchns; ++i) if(znbuf[i]) FreeAligned(znbuf[i]); delete[] znbuf; }
! if(znpos) FreeAligned(znpos); ! if(znidx) FreeAligned(znidx); }
*************** *** 315,368 **** }
! V xgroove::m_xshape(I argc,const t_atom *argv) { ! const F pi = 3.14159265358979f; ! xshape = 0; ! xshparam = 1; ! 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*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.f/XZONE_TABLE); } - }
! V xgroove::mg_xshape(AtomList &ret) const ! { ! ret(2); ! SetInt(ret[0],xshape); ! SetFloat(ret[1],xshparam); }
- V xgroove::do_xzone() { ! if(!s2u) return; // this can happen if DSP is off
xzone = _xzone; // make a copy for changing it
! if(xfade == xsf_inside) { // fade zone goes inside the loop -> loop gets shorter const L maxfd = (curmax-curmin)/2; if(xzone > maxfd) xzone = maxfd; --- 335,364 ---- }
! V xgroove::ms_xshape(I sh) { ! xshape = (xs_shape)sh; switch(xshape) { ! case xss_qsine: znmul = fade_qsine; break; ! case xss_hsine: znmul = fade_hsine; break; ! default: ! post("%s - shape parameter invalid, set to linear",thisName()); ! case xss_lin: ! znmul = fade_lin; break; }
! // no need to recalc the fade zone here }
V xgroove::do_xzone() { ! // \todo do we really need this? ! if(!s2u) return; // this can happen if DSP is off
xzone = _xzone; // make a copy for changing it
! if(xfade == xsf_inside) { ! // fade zone goes inside the loop -> loop becomes shorter ! ! // \todo what about round-off? const L maxfd = (curmax-curmin)/2; if(xzone > maxfd) xzone = maxfd; *************** *** 372,376 **** else if(xfade == xsf_keepfade) { // try to keep fade zone ! // shifting of loop bounds may happen
// restrict xzone to half of buffer --- 368,372 ---- else if(xfade == xsf_keepfade) { // try to keep fade zone ! // change of loop bounds may happen
// restrict xzone to half of buffer *************** *** 378,383 **** if(xzone > maxfd) xzone = maxfd;
! znsmin = curmin-xzone/2; ! znsmax = curmax+xzone/2;
// check buffer limits and shift bounds if necessary --- 374,385 ---- if(xzone > maxfd) xzone = maxfd;
! // \todo what about round-off? ! znsmin = curmin-(L)(xzone/2); ! znsmax = curmax+(L)(xzone/2); ! ! // widen loop if xzone doesn't fit into it ! // \todo check formula ! L lack = (L)ceil((xzone*2-(znsmax-znsmin))/2); ! if(lack > 0) znsmin -= lack,znsmax += lack;
// check buffer limits and shift bounds if necessary *************** *** 393,401 **** // shifting of loop bounds may happen
! const L maxfd = buf->Frames()-(curmax-curmin); if(xzone > maxfd) xzone = maxfd;
! znsmin = curmin-xzone/2; ! znsmax = curmax+xzone/2;
// check buffer limits and shift bounds if necessary --- 395,406 ---- // shifting of loop bounds may happen
! const L plen = curmax-curmin; ! if(xzone > plen) xzone = plen; ! const L maxfd = buf->Frames()-plen; if(xzone > maxfd) xzone = maxfd;
! // \todo what about round-off? ! znsmin = curmin-(L)(xzone/2); ! znsmax = curmax+(L)(xzone/2);
// check buffer limits and shift bounds if necessary *************** *** 413,418 **** // try to keep loop position and length
! znsmin = curmin-xzone/2; ! znsmax = curmax+xzone/2;
L ovr = znsmax-buf->Frames(); --- 418,428 ---- // try to keep loop position and length
! // restrict fade zone to maximum length ! const L plen = curmax-curmin; ! if(xzone > plen) xzone = plen; ! ! // \todo what about round-off? ! znsmin = curmin-(L)(xzone/2); ! znsmax = curmax+(L)(xzone/2);
L ovr = znsmax-buf->Frames(); *************** *** 425,431 **** }
- znmin = znsmin+xzone; - znmax = znsmax-xzone; - FLEXT_ASSERT(znsmin <= znsmax && (znsmax-znsmin) >= xzone*2); } --- 435,438 ---- *************** *** 632,636 ****
const F xz = xzone,xf = (F)XZONE_TABLE/xz; - const D lmin = znmin,lmax = znmax,lsh = lmax-lmin+xz;
// adapt the playing bounds to the current cross-fade zone --- 639,642 ---- *************** *** 641,668 **** 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; lpbang = true; } ! else if(o < smin) { ! o = fmod(o-smin,plen)+smax; lpbang = true; }
! if(o >= lmax) { ! // in late cross-fade zone ! o -= lsh; }
! // now: smin <= o < smax ! if(o < lmin) { ! // in early cross-fade zone ! register F inp = xz+(F)(o-lmin); // 0 <= inp < xz znidx[i] = inp*xf; - znpos[i] = lmax+inp; inzn = true; } --- 647,697 ---- register D o = curpos;
+ // calculate inner cross-fade boundaries + const D lmin = smin+xz,lmax = smax-xz,lsh = lmax-lmin+xz; + const D lmin2 = lmin-xz/2,lmax2 = lmax+xz/2; + for(I i = 0; i < n; ++i) { // normalize offset ! if(o < smin) { ! o = fmod(o-smin,plen)+smax; lpbang = true; } ! else if(!(o < smax)) { ! o = fmod(o-smin,plen)+smin; lpbang = true; }
! if(o < lmin) { ! register F inp; ! if(o < lmin2) { ! o += lsh; ! lpbang = true; ! // now lmax <= o <= lmax2 ! ! inp = xz-(F)(o-lmax); // 0 <= inp < xz ! znpos[i] = lmin-inp; ! } ! else { // in early cross-fade zone ! inp = xz+(F)(o-lmin); // 0 <= inp < xz ! znpos[i] = lmax+inp; ! } ! znidx[i] = inp*xf; ! inzn = true; } + else if(!(o < lmax)) { + register F inp; + if(!(o < lmax2)) { + o -= lsh; + lpbang = true; + // now lmin2 <= o <= lmin
! inp = xz+(F)(o-lmin); // 0 <= inp < xz ! znpos[i] = lmax+inp; ! } ! else { // in late cross-fade zone ! inp = xz-(F)(o-lmax); // 0 <= inp < xz ! znpos[i] = lmin-inp; ! } znidx[i] = inp*xf; inzn = true; } *************** *** 676,680 ****
// normalize and store current playing position - if(o < znsmin) o += plen; setpos(o);
--- 705,708 ---- *************** *** 682,687 **** playfun(n,&pos,outvecs);
if(inzn) { ! // only if we are in cross-fade zone // calculate samples in loop zone (2nd voice) --- 710,718 ---- playfun(n,&pos,outvecs);
+ // rescale position vector + arrscale(n,pos,pos); + if(inzn) { ! // only if we have touched the cross-fade zone // calculate samples in loop zone (2nd voice) *************** *** 691,695 **** 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); --- 722,726 ---- arrscale(n,znidx,znpos,XZONE_TABLE,-1); ! // calculate fade coefficients by sampling from the fade curve zonefun(znmul,0,XZONE_TABLE+1,n,1,1,&znidx,&znidx); zonefun(znmul,0,XZONE_TABLE+1,n,1,1,&znpos,&znpos); *************** *** 697,708 **** // 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 --- 728,736 ---- // mix voices for all channels for(I o = 0; o < outchns; ++o) { ! MulSamples(outvecs[o],outvecs[o],znidx,n); ! MulSamples(znbuf[o],znbuf[o],znpos,n); ! AddSamples(outvecs[o],outvecs[o],znbuf[o],n); } } } else *************** *** 771,782 **** if(pblksz != blksz) { for(I o = 0; o < outchns; ++o) { ! if(znbuf[o]) delete[] znbuf[o]; ! znbuf[o] = new S[blksz]; } ! if(znpos) delete[] znpos; ! znpos = new S[blksz]; ! if(znidx) delete[] znidx; ! znidx = new S[blksz];
pblksz = blksz; --- 799,810 ---- if(pblksz != blksz) { for(I o = 0; o < outchns; ++o) { ! if(znbuf[o]) FreeAligned(znbuf[o]); ! znbuf[o] = (S *)NewAligned(blksz*sizeof(S)); } ! if(znpos) FreeAligned(znpos); ! znpos = (S *)NewAligned(blksz*sizeof(S)); ! if(znidx) FreeAligned(znidx); ! znidx = (S *)NewAligned(blksz*sizeof(S));
pblksz = blksz; *************** *** 839,845 **** post("\t@sclmode 0/1/2/3: set range of position to units/units in loop/buffer/loop"); post("\t@xzone {unit}: length of loop crossfade zone"); ! post("\t@xsymm -1,0...1: symmetry of crossfade zone inside/outside point"); ! post("\t@xshape 0/1 [param 0...1]: shape of crossfading (linear/trig)"); ! post("\t@xkeep 0/1: try to preserve xzone/loop length"); post(""); } --- 867,872 ---- post("\t@sclmode 0/1/2/3: set range of position to units/units in loop/buffer/loop"); post("\t@xzone {unit}: length of loop crossfade zone"); ! post("\t@xfade 0/1/2/3: fade mode (keep loop/keep loop length/keep fade/inside loop)"); ! post("\t@xshape 0/1/2: shape of crossfade (linear/quarter sine/half sine)"); post(""); }
Index: main.h =================================================================== RCS file: /cvsroot/pure-data/externals/grill/xsample/source/main.h,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** main.h 7 Apr 2004 02:48:18 -0000 1.28 --- main.h 8 Apr 2004 04:01:44 -0000 1.29 *************** *** 13,17 ****
! #define XSAMPLE_VERSION "0.3.0pre19"
--- 13,17 ----
! #define XSAMPLE_VERSION "0.3.0pre20"
*************** *** 114,118 **** enum xs_intp { xsi__ = -1, // don't change ! xsi_none = 0,xsi_lin,xsi_4p }; --- 114,118 ---- enum xs_intp { xsi__ = -1, // don't change ! xsi_none = 0,xsi_4p,xsi_lin };