[PD-cvs] externals/grill/xsample/source groove.cpp,1.25,1.26 main.h,1.28,1.29

Thomas Grill xovo at users.sourceforge.net
Thu Apr 8 06:01:47 CEST 2004


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 at sclmode 0/1/2/3: set range of position to units/units in loop/buffer/loop");
  	post("\t at xzone {unit}: length of loop crossfade zone");
! 	post("\t at xsymm -1,0...1: symmetry of crossfade zone inside/outside point");
! 	post("\t at xshape 0/1 [param 0...1]: shape of crossfading (linear/trig)");
! 	post("\t at xkeep 0/1: try to preserve xzone/loop length");
  	post("");
  } 
--- 867,872 ----
  	post("\t at sclmode 0/1/2/3: set range of position to units/units in loop/buffer/loop");
  	post("\t at xzone {unit}: length of loop crossfade zone");
! 	post("\t at xfade 0/1/2/3: fade mode (keep loop/keep loop length/keep fade/inside loop)");
! 	post("\t at 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
  	};
  	





More information about the Pd-cvs mailing list