[PD-cvs] externals/grill/xsample/source groove.cpp,1.28,1.29 inter.cpp,1.8,1.9 inter.h,1.8,1.9 main.cpp,1.18,1.19 main.h,1.32,1.33 play.cpp,1.9,1.10 prefix.h,1.1,1.2 record.cpp,1.16,1.17

Thomas Grill xovo at users.sourceforge.net
Sat Jan 8 05:59:46 CET 2005


Update of /cvsroot/pure-data/externals/grill/xsample/source
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17093/source

Modified Files:
	groove.cpp inter.cpp inter.h main.cpp main.h play.cpp prefix.h 
	record.cpp 
Log Message:
merge in branch "20041229-unify"
- some small cleanups
os x fixes
minor updates
improved buffer handling
simplify updates
Mac adaptations
- made xcode project
preparing xsample 0.3.0 release
updated for build system
some optimizations
- fixed loop record bug
Completion of attribute functionality, revisited and updated help files


Index: groove.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/xsample/source/groove.cpp,v
retrieving revision 1.28
retrieving revision 1.29
diff -C2 -d -r1.28 -r1.29
*** groove.cpp	16 Dec 2004 05:02:24 -0000	1.28
--- groove.cpp	8 Jan 2005 04:59:44 -0000	1.29
***************
*** 1,10 ****
  /*
- 
  xsample - extended sample objects for Max/MSP and pd (pure data)
  
! Copyright (c) 2001-2004 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
- 
  */
  
[...1312 lines suppressed...]
  	post("");
  }
- 
--- 755,770 ----
  } 
  
! void xgroove::m_print()
  {
! 	static const char *sclmode_txt[] = {"units","units in loop","buffer","loop"};
! 	static const char *interp_txt[] = {"off","4-point","linear"};
! 	static const char *loop_txt[] = {"once","looping","bidir"};
  
  	// print all current settings
  	post("%s - current settings:",thisName());
! 	post("bufname = '%s', length = %.3f, channels = %i",buf.Name(),(float)(buf.Frames()*s2u),buf.Channels()); 
! 	post("out channels = %i, frames/unit = %.3f, scale mode = %s",outchns,(float)(1./s2u),sclmode_txt[sclmode]); 
! 	post("loop = %s, interpolation = %s",loop_txt[(int)loopmode],interp_txt[interp >= xsi_none && interp <= xsi_lin?interp:xsi_none]); 
! 	post("loop crossfade zone = %.3f",(float)(xzone*s2u)); 
  	post("");
  }

Index: main.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/xsample/source/main.cpp,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -d -r1.18 -r1.19
*** main.cpp	21 Jun 2004 14:02:12 -0000	1.18
--- main.cpp	8 Jan 2005 04:59:44 -0000	1.19
***************
*** 1,10 ****
  /*
- 
  xsample - extended sample objects for Max/MSP and pd (pure data)
  
! Copyright (c) 2001-2004 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
- 
  */
  
--- 1,8 ----
  /*
  xsample - extended sample objects for Max/MSP and pd (pure data)
  
! Copyright (c) 2001-2005 Thomas Grill (gr at grrrr.org)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
  */
  
***************
*** 13,17 ****
  
  // Initialization function for xsample library
! static V xsample_main()
  {
  	flext::post("-------------------------------");
--- 11,15 ----
  
  // Initialization function for xsample library
! static void xsample_main()
  {
  	flext::post("-------------------------------");
***************
*** 19,25 ****
      flext::post("");
  	flext::post("  xrecord~, xplay~, xgroove~   ");
!     flext::post("  (C)2001-2004 Thomas Grill    ");
  #ifdef FLEXT_DEBUG
!     flext::post("          DEBUG BUILD          ");
  #endif
  	flext::post("-------------------------------");
--- 17,24 ----
      flext::post("");
  	flext::post("  xrecord~, xplay~, xgroove~   ");
!     flext::post("  (C)2001-2005 Thomas Grill    ");
  #ifdef FLEXT_DEBUG
!     flext::post("");
!     flext::post("DEBUG BUILD - " __DATE__ " " __TIME__);
  #endif
  	flext::post("-------------------------------");
***************
*** 38,45 ****
  void xsample::setup(t_classid c)
  {
- 	FLEXT_CADDBANG(c,0,m_start);
- 	FLEXT_CADDMETHOD_(c,0,"start",m_start);
- 	FLEXT_CADDMETHOD_(c,0,"stop",m_stop);
- 
  	FLEXT_CADDMETHOD_(c,0,"set",m_set);
  	FLEXT_CADDMETHOD_(c,0,"print",m_print);
--- 37,40 ----
***************
*** 54,58 ****
  
  xsample::xsample():
! 	buf(NULL),
  #if FLEXT_SYS == FLEXT_SYS_MAX
  	unitmode(xsu_ms),	   // Max/MSP defaults to milliseconds
--- 49,53 ----
  
  xsample::xsample():
!     update(xsc_all),
  #if FLEXT_SYS == FLEXT_SYS_MAX
  	unitmode(xsu_ms),	   // Max/MSP defaults to milliseconds
***************
*** 61,215 ****
  #endif
  	sclmode(xss_unitsinbuf),
! 	curmin(0),curmax(1<<31)
  {}
  	
! xsample::~xsample()
  {
! //	m_enable(false); // switch off DSP
  
! 	if(buf) delete buf; 
  }
  
! 
! BL xsample::bufchk() 
! { 
! 	if(buf->Valid()) {
! 		if(buf->Update()) {
! //			post("%s - buffer updated",thisName()); 
! 			m_refresh(); 
! 		}
! 		return true; 
! 	}
! 	else
! 		return false; 
  }
  
! I xsample::m_set(I argc,const t_atom *argv)
  {
! 	const t_symbol *sym = argc >= 1?GetASymbol(argv[0]):NULL;
! 	int r = buf->Set(sym);
! 	if(sym && r < 0) post("%s - can't find buffer %s",thisName(),GetString(sym));
! 	return r;
  }
  
! BL xsample::m_refresh()
  {
! 	BL ret;
! 	if(buf->Set()) { s_dsp(); ret = true; } // channel count may have changed
! 	else ret = false;
! 	
! 	m_units();
! 	m_sclmode();	
! 	// realize positions... 2 times bufchk()!!
! 	m_min((F)curmin*s2u); // also checks pos
! 	m_max((F)curmax*s2u); // also checks pos
! 
! 	return ret;
  }
  
! BL xsample::m_reset()
  {
! 	BL ret;
! 	if(buf->Set()) { s_dsp(); ret = true; } // channel count may have changed
! 	else ret = false;
! 	
! 	// now... 4 times bufchk()!! \todo get rid of that
! 	m_units();
! 	m_sclmode();	
! 	m_min(0);
!     m_max(buf->Frames()*s2u);
! 
! 	return ret;
! }
  
! V xsample::m_loadbang() 
! {
! 	m_reset();
! }
  
! V xsample::m_units(xs_unit mode)
! {
! 	if(mode != xsu__) unitmode = mode;
  
! 	switch(unitmode) {
! 		case xsu_sample: // samples
! 			s2u = 1;
! 			break;
! 		case xsu_buffer: // buffer size
! 			s2u = bufchk()?1.f/buf->Frames():0;
! 			break;
! 		case xsu_ms: // ms
! 			s2u = 1000.f/Samplerate();
! 			break;
! 		case xsu_s: // s
! 			s2u = 1.f/Samplerate();
! 			break;
! 		default:
! 			post("%s: Unknown unit mode",thisName());
  	}
  }
  
! V xsample::m_sclmode(xs_sclmd mode)
  {
! 	if(mode != xss__) sclmode = mode;
! 
! 	switch(sclmode) {
! 		case 0: // samples/units
! 			sclmin = 0; sclmul = s2u;
! 			break;
! 		case 1: // samples/units from recmin to recmax
! 			sclmin = curmin; sclmul = s2u;
! 			break;
! 		case 2: // unity between 0 and buffer size
! 			sclmin = 0; sclmul = (bufchk() && buf->Frames())?1.f/buf->Frames():0;
! 			break;
! 		case 3:	// unity between recmin and recmax
! 			sclmin = curmin; sclmul = curmin != curmax?1.f/(curmax-curmin):0;
! 			break;
! 		default:
! 			post("%s: Unknown scale mode",thisName());
! 	}
! }
  
! V xsample::m_min(F mn)
! {
! //	if(!bufchk()) return; // if invalid do nothing (actually, it should be delayed)
  
! 	if(s2u) {
! 		mn /= s2u;  // conversion to samples
! 		if(mn < 0) mn = 0;
! 		else if(mn > curmax) mn = (F)curmax;
! 		curmin = (I)(mn+.5);
  
! 		m_sclmode();
  	}
  }
  
! V xsample::m_max(F mx)
  {
! //	if(!bufchk()) return; // if invalid do nothing (actually, it should be delayed)
  
! 	if(s2u) {
! 		mx /= s2u;  // conversion to samples
! 		if(mx > buf->Frames()) mx = (F)buf->Frames();
! 		else if(mx < curmin) mx = (F)curmin;
! 		curmax = (I)(mx+.5);
  
! 		m_sclmode();
! 	}
  }
  
! V xsample::m_all()
  {
! 	if(!bufchk()) return; // if invalid do nothing (actually, it should be delayed)
! 
! 	curmin = 0; curmax = buf->Frames();
! 	m_sclmode();
  }
  
! V xsample::m_dsp(I /*n*/,S *const * /*insigs*/,S *const * /*outsigs*/)
  {
! 	// this is hopefully called at change of sample rate ?!
  
! 	if(!m_refresh()) s_dsp();
  }
--- 56,207 ----
  #endif
  	sclmode(xss_unitsinbuf),
! 	curmin(0),curmax(1<<(sizeof(curmax)*8-2))
  {}
  	
! xsample::~xsample() {}
! 
! bool xsample::Finalize()
  {
!     if(!flext_dsp::Finalize()) return false;
  
!     // flags have been set in constructor
!     Refresh();
!     return true;
  }
  
! int xsample::ChkBuffer(bool refresh) 
! {      
!     if(!buf.Ok()) return 0;
!     
!     if(buf.Update()) {
! #ifdef FLEXT_DEBUG
!         post("%s - buffer update!",thisName());
! #endif
!         Update(xsc_buffer);
!         if(refresh) { 
!             Refresh();
!             return buf.Ok() && buf.Valid()?1:0;
!         }
!         else 
!             return buf.Valid()?1:0;
!     }
!     else
!         return buf.Valid()?-1:0;
  }
  
! /* called after all buffer objects have been created in the patch */
! void xsample::m_loadbang() 
  {
!     ChkBuffer(true);
  }
  
! void xsample::m_set(int argc,const t_atom *argv)
  {
! 	const t_symbol *sym = argc >= 1?GetASymbol(argv[0]):NULL;
! 	int r = buf.Set(sym);
! 	if(sym && r < 0) 
!         post("%s - can't find buffer %s",thisName(),GetString(sym));
!     Update(xsc_buffer,true);
  }
  
! void xsample::m_min(float mn)
  {
!     int ret = ChkBuffer(true);
  
! 	if(ret && s2u) {
! 		long cmn = CASTINT<long>(mn/s2u+0.5f);  // conversion to samples
  
! 		if(cmn < 0) 
!             curmin = 0;
! 		else if(cmn > curmax) 
!             curmin = curmax;
! 		else
!             curmin = cmn;
  
!         Update(xsc_range,true);
  	}
  }
  
! void xsample::m_max(float mx)
  {
!     int ret = ChkBuffer(true);
  
! 	if(ret && s2u) {
! 		long cmx = CASTINT<long>(mx/s2u+0.5f);  // conversion to samples
  
! 		if(cmx > buf.Frames()) 
!             curmax = buf.Frames();
! 		else if(cmx < curmin) 
!             curmax = curmin;
!         else
! 		    curmax = cmx;
  
!         Update(xsc_range,true);
  	}
  }
  
! void xsample::m_dsp(int /*n*/,t_sample *const * /*insigs*/,t_sample *const * /*outsigs*/)
  {
! 	// this is hopefully called at change of sample rate ?!
  
! #ifdef FLEXT_DEBUG
!         post("%s - DSP reset!",thisName());
! #endif
  
!     // for PD at least this is also called if a table has been deleted...
!     // then we must reset the buffer
! 
!     Update(xsc_srate|xsc_buffer,true);
  }
  
! void xsample::DoReset() 
  {
!     ResetRange();
  }
  
! void xsample::DoUpdate(unsigned int flags)
  {
!     if(flags&xsc_buffer)
!         buf.Set();
  
!     if(flags&xsc_range && buf.Ok()) {
!         if(curmin < 0) curmin = 0;
!         if(curmax > buf.Frames()) curmax = buf.Frames();
!     }
! 
!     if(flags&xsc_units) {
! 	    switch(unitmode) {
! 		    case xsu_sample: // samples
! 			    s2u = 1;
! 			    break;
! 		    case xsu_buffer: // buffer size
! 			    s2u = buf.Ok() && buf.Frames()?1.f/buf.Frames():0;
! 			    break;
! 		    case xsu_ms: // ms
! 			    s2u = 1000.f/Samplerate();
! 			    break;
! 		    case xsu_s: // s
! 			    s2u = 1.f/Samplerate();
! 			    break;
! 		    default:
! 			    post("%s - Unknown unit mode",thisName());
! 	    }
! 
! 	    switch(sclmode) {
! 		    case xss_unitsinbuf: // samples/units
! 			    sclmin = 0; sclmul = s2u;
! 			    break;
! 		    case xss_unitsinloop: // samples/units from recmin to recmax
! 			    sclmin = curmin; sclmul = s2u;
! 			    break;
! 		    case xss_buffer: // unity between 0 and buffer size
! 			    sclmin = 0; sclmul = buf.Ok() && buf.Frames()?1.f/buf.Frames():0;
! 			    break;
! 		    case xss_loop:	// unity between recmin and recmax
! 			    sclmin = curmin; sclmul = curmin < curmax?1.f/(curmax-curmin):0;
! 			    break;
! 		    default:
! 			    post("%s - Unknown scale mode",thisName());
! 	    }
!     }
  }

Index: inter.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/xsample/source/inter.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** inter.h	8 Feb 2004 03:40:47 -0000	1.8
--- inter.h	8 Jan 2005 04:59:44 -0000	1.9
***************
*** 1,10 ****
  /* 
- 
  xsample - extended sample objects for Max/MSP and pd (pure data)
  
! Copyright (c) 2001-2004 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
- 
  */
  
--- 1,8 ----
  /* 
  xsample - extended sample objects for Max/MSP and pd (pure data)
  
! Copyright (c) 2001-2005 Thomas Grill (gr at grrrr.org)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
  */
  
***************
*** 12,64 ****
  #define __INTER_H
  
! TMPLDEF V xinter::st_play0(const S *,const I ,const I ,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs)
  {
  	// stopped/invalid buffer -> output zero
! 	for(I ci = 0; ci < outchns; ++ci) ZeroSamples(outvecs[ci],n);
  }
  
! TMPLDEF V xinter::st_play1(const S *bdt,const I smin,const I smax,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs)
  {
  	SIGCHNS(BCHNS,inchns,OCHNS,outchns);
  
  	// position info are frame units
! 	const S *pos = invecs[0]; 
! 	S *const *sig = outvecs;
! 	register I si = 0;
  	
  	// no interpolation
  	// ----------------
- 	
- 	for(I i = 0; i < n; ++i,++si) {	
- 		register const I oint = (I)(*(pos++));
- 		register const S *fp;
- 		
- 		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;
- 		}
- 		
- 		for(I ci = 0; ci < OCHNS; ++ci)
- 			sig[ci][si] = fp[ci];
- 	}
  
! 	// clear rest of output channels (if buffer has less channels)
! 	for(I ci = OCHNS; ci < outchns; ++ci) ZeroSamples(sig[ci],n);
  }
  
! TMPLDEF V xinter::st_play2(const S *bdt,const I smin,const I smax,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs)
  {
! 	const I plen = smax-smin; //curlen;
  	if(plen < 2) {
! 		st_play1 TMPLCALL (bdt,smin,smax,n,inchns,outchns,invecs,outvecs);
  		return;
  	}
--- 10,93 ----
  #define __INTER_H
  
! TMPLDEF void xinter::st_play0(const t_sample *,const int ,const int ,const int n,const int inchns,const int outchns,t_sample *const *invecs,t_sample *const *outvecs,bool looped)
  {
  	// stopped/invalid buffer -> output zero
! 	for(int ci = 0; ci < outchns; ++ci) ZeroSamples(outvecs[ci],n);
  }
  
! TMPLDEF void xinter::st_play1(const t_sample *bdt,const int smin,const int smax,const int n,const int inchns,const int outchns,t_sample *const *invecs,t_sample *const *outvecs,bool looped)
  {
  	SIGCHNS(BCHNS,inchns,OCHNS,outchns);
  
  	// position info are frame units
! 	const t_sample *pos = invecs[0];
! 	t_sample *const *sig = outvecs;
  	
  	// no interpolation
  	// ----------------
  
!     if(smin == smax) {
!         // zero loop length -> assume that smin is a valid sample position...
! 
!         int ci;
!         for(ci = 0; ci < OCHNS; ++ci) SetSamples(sig[ci],n,bdt[smin*BCHNS]);
! 	    // clear rest of output channels (if buffer has less channels)
! 	    for(; ci < outchns; ++ci) ZeroSamples(sig[ci],n);
!     }
!     else if(OCHNS == 1) {
!         t_sample *sig0 = sig[0];
! 	    for(int i = 0; i < n; ++i) {	
! 		    register long oint = CASTINT<long>(*(pos++));
! 
!             // for xplay oint can be out of bounds -> check
! 		    if(oint >= smin)
! 			    if(oint < smax) {
! 				    // normal
! 				    *(sig0++) = bdt[oint*BCHNS];
! 			    }
! 			    else {
! 				    // position > last sample ... take only last sample
! 				    *(sig0++) = bdt[(smax-1)*BCHNS];
! 			    }
! 		    else {
! 			    // position < 0 ... take only 0th sample
! 			    *(sig0++) = bdt[smin*BCHNS];
! 		    }
! 	    }
!     }
!     else {
! 	    for(int i = 0,si = 0; i < n; ++i,++si) {	
! 		    register long oint = CASTINT<long>(*(pos++));
! 		    register const t_sample *fp;
! 
!             // for xplay oint can be out of bounds -> check
! 		    if(oint >= smin)
! 			    if(oint < smax) {
! 				    // normal
! 				    fp = bdt+oint*BCHNS;
! 			    }
! 			    else {
! 				    // position > last sample ... take only last sample
! 				    fp = bdt+(smax-1)*BCHNS;
! 			    }
! 		    else {
! 			    // position < 0 ... take only 0th sample
! 			    fp = bdt+smin*BCHNS;
! 		    }
! 
!             for(int ci = 0; ci < OCHNS; ++ci)
! 			    sig[ci][si] = fp[ci];
!         }
! 
! 	    // clear rest of output channels (if buffer has less channels)
! 	    for(int ci = OCHNS; ci < outchns; ++ci) ZeroSamples(sig[ci],n);
!     }
  }
  
! TMPLDEF void xinter::st_play2(const t_sample *bdt,const int smin,const int smax,const int n,const int inchns,const int outchns,t_sample *const *invecs,t_sample *const *outvecs,bool looped)
  {
! 	const int plen = smax-smin;
  	if(plen < 2) {
! 		st_play1 TMPLCALL (bdt,smin,smax,n,inchns,outchns,invecs,outvecs,looped);
  		return;
  	}
***************
*** 67,116 ****
  
  	// position info are frame units
! 	const S *pos = invecs[0];
! 	S *const *sig = outvecs;
! 	register I si = 0;
  	
  	// linear interpolation
  	// --------------------
  
! 	const I maxo = smax-1;  // last sample in buffer
  
! 	for(I i = 0; i < n; ++i,++si) {	
! 		const F o = *(pos++);
! 		register const I oint = (I)o;
  
! 		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]; 
! 		}
! 	}
  
! 	// clear rest of output channels (if buffer has less channels)
! 	for(I ci = OCHNS; ci < outchns; ++ci) ZeroSamples(sig[ci],n);
  }
  
! TMPLDEF V xinter::st_play4(const S *bdt,const I smin,const I smax,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs)
  {
! 	const I plen = smax-smin; //curlen;
  	if(plen < 4) {
! 		if(plen < 2) st_play1 TMPLCALL (bdt,smin,smax,n,inchns,outchns,invecs,outvecs);
! 		else st_play2 TMPLCALL (bdt,smin,smax,n,inchns,outchns,invecs,outvecs);
  		return;
  	}
--- 96,194 ----
  
  	// position info are frame units
! 	const t_sample *pos = invecs[0];
! 	t_sample *const *sig = outvecs;
  	
  	// linear interpolation
  	// --------------------
  
! 	const int maxo = smax-1;  // last sample in buffer
  
!     if(OCHNS == 1) {
!         t_sample *sig0 = sig[0];
! 	    for(int i = 0; i < n; ++i) {	
! 		    const float o = *(pos++);
! 		    register long oint = CASTINT<long>(o);
! 			const float frac = o-oint;
! 			t_sample fp0,fp1;
  
! 		    if(oint >= smin)
! 			    if(oint < maxo) {
! 				    // normal interpolation
! 			        fp0 = bdt[oint*BCHNS];
! 			        fp1 = bdt[(oint+1)*BCHNS];
! 			    }
! 			    else {
! 				    // position is past last sample
!                     if(looped) {
!         				oint = smin+(oint-smin)%plen;
!                         fp0 = bdt[oint*BCHNS];
!                         fp1 = oint >= maxo?bdt[smin]:fp0;
!                     }
!                     else
!     	                fp0 = fp1 = bdt[maxo*BCHNS]; 
!                 }
! 		    else {
! 			    // position is before first sample
!                 if(looped) {
!         			oint = smax-(smin-oint)%plen;
!                     fp0 = bdt[oint*BCHNS]; 
!                     fp1 = oint >= maxo?bdt[smin]:fp0;
!                 }
!                 else
! 		            fp0 = fp1 = bdt[smin*BCHNS]; 
! 		    }
  
!             *(sig0++) = fp0+frac*(fp1-fp0);
! 	    }
!     }
!     else {
! 	    for(int i = 0,si = 0; i < n; ++i,++si) {	
! 		    const float o = *(pos++);
! 		    register long oint = CASTINT<long>(o);
! 			const t_sample *fp0,*fp1;
! 			const float frac = o-oint;
! 
! 		    if(oint >= smin)
! 			    if(oint < maxo) {
! 				    // normal interpolation
! 			        fp0 = bdt+oint*BCHNS;
! 			        fp1 = fp0+BCHNS;
! 			    }
! 			    else {
! 				    // position is past last sample
!                     if(looped) {
!         				oint = smin+(oint-smin)%plen;
!                         fp0 = bdt+oint*BCHNS;
!                         fp1 = oint >= maxo?bdt+smin:fp0;
!                     }
!                     else
! 		                fp0 = fp1 = bdt+maxo*BCHNS;
! 			    }
! 		    else {
! 			    // position is before first sample
!                 if(looped) {
!         			oint = smax-(smin-oint)%plen;
!                     fp0 = bdt+oint*BCHNS;
!                     fp1 = oint >= maxo?bdt+smin:fp0;
!                 }
!                 else
! 		            fp0 = fp1 = bdt+smin*BCHNS;
! 		    }
! 
! 			for(int 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)
! 	    for(int ci = OCHNS; ci < outchns; ++ci) ZeroSamples(sig[ci],n);
!     }
  }
  
! TMPLDEF void xinter::st_play4(const t_sample *bdt,const int smin,const int smax,const int n,const int inchns,const int outchns,t_sample *const *invecs,t_sample *const *outvecs,bool looped)
  {
! 	const int plen = smax-smin; //curlen;
  	if(plen < 4) {
! 		if(plen < 2) st_play1 TMPLCALL (bdt,smin,smax,n,inchns,outchns,invecs,outvecs,looped);
! 		else st_play2 TMPLCALL (bdt,smin,smax,n,inchns,outchns,invecs,outvecs,looped);
  		return;
  	}
***************
*** 119,224 ****
  
  	// position info are frame units
! 	const S *pos = invecs[0];
! 
! #ifdef __VEC__
! 	// prefetch cache
! 	vec_dst(pos,GetPrefetchConstant(1,n>>2,0),0);
! 	const int pf = GetPrefetchConstant(BCHNS,1,16*BCHNS);
! #endif
! 
! 	S *const *sig = outvecs;
! 	register I si = 0;
  	
  	// 4-point interpolation
  	// ---------------------
! 	const I maxo = smax-1; // last sample in play region
! 	const S *maxp = bdt+maxo*BCHNS;  // pointer to last sample
  
! 	for(I i = 0; i < n; ++i,++si) {	
! 		F o = *(pos++);
! 		register I oint = (I)o;
! 		register F frac;
! 		register const S *fa,*fb,*fc,*fd;
  
! 		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;
! 			
! 			// position is first sample
! 			fa = bdt+smin*BCHNS;  
  
! 			fb = bdt+oint*BCHNS;
! 			frac = o-oint;
! 			fc = fb+BCHNS;
! 			fd = fc+BCHNS;
! 		}
! 		
! 		register F f1 = 0.5f*(frac-1.0f);
! 		register F f3 = frac*3.0f-1.0f;
! 		
! 		for(I ci = 0; ci < OCHNS; ++ci) {
! 			const F amdf = (fa[ci]-fd[ci])*frac;
! 			const F cmb = fc[ci]-fb[ci];
! 			const F bma = fb[ci]-fa[ci];
! 			sig[ci][si] = fb[ci] + frac*( cmb - f1 * ( amdf+bma+cmb*f3 ) );
! 		}
! 	}
! 	
! #ifdef __VEC__
! 	vec_dss(0);
! #endif
  
! 	// clear rest of output channels (if buffer has less channels)
! 	for(I ci = OCHNS; ci < outchns; ++ci) ZeroSamples(sig[ci],n);
  }
  
  
! TMPLDEF inline V xinter::s_play0(I n,S *const *invecs,S *const *outvecs)
  {
! 	st_play0 TMPLCALL (buf->Data(),curmin,curmax,n,buf->Channels(),outchns,invecs,outvecs);
  }
  
! TMPLDEF inline V xinter::s_play1(I n,S *const *invecs,S *const *outvecs)
  {
! 	st_play1 TMPLCALL (buf->Data(),curmin,curmax,n,buf->Channels(),outchns,invecs,outvecs);
  }
  
! TMPLDEF inline V xinter::s_play2(I n,S *const *invecs,S *const *outvecs)
  {
! 	st_play2 TMPLCALL (buf->Data(),curmin,curmax,n,buf->Channels(),outchns,invecs,outvecs);
  }
  
! TMPLDEF inline V xinter::s_play4(I n,S *const *invecs,S *const *outvecs)
  {
! 	st_play4 TMPLCALL (buf->Data(),curmin,curmax,n,buf->Channels(),outchns,invecs,outvecs);
  }
  
--- 197,419 ----
  
  	// position info are frame units
! 	const t_sample *pos = invecs[0];
! 	t_sample *const *sig = outvecs;
  	
  	// 4-point interpolation
  	// ---------------------
! 	const int maxo = smax-1; // last sample in play region
  
!     if(OCHNS == 1) {
!         t_sample *sig0 = sig[0];
! 	    for(int i = 0; i < n; ++i) {	
! 		    float o = *(pos++);
! 		    register long oint = CASTINT<long>(o);
! 		    register t_sample fa,fb,fc,fd;
! 		    const float frac = o-oint;
!             register const t_sample *ptr = bdt+oint*BCHNS;
  
!             if(oint > smin) {
! 			    if(oint < maxo-2) {
! 				    // normal case
! 				    fa = ptr[-BCHNS];
! 				    fb = ptr[0];
! 				    fc = ptr[BCHNS];
! 				    fd = ptr[BCHNS*2];
!                 }
! 			    else {
! 				    // not enough space at the end
  
!                     if(looped) {
!                         // normalize position
!                         oint = smin+(oint-smin)%plen;
!                         goto looped1;
!                     }
!                     else {
!                         // last sample is outside in any case
!                         fd = bdt[maxo*BCHNS];
  
!                         if(oint-1 >= maxo)
!                             // if first is outside, all are outside
!                             fa = fb = fc = fd;
!                         else {
!                             fa = ptr[-BCHNS];
!                             if(oint >= maxo) 
!                                 fb = fc = fd;
!                             else {
!                                 fb = ptr[0];
!                                 fc = oint+1 < maxo?ptr[BCHNS]:fd;
!                             }
!                         }
!                     }
!                 }
!             }
! 		    else {
! 			    // not enough space at the beginning
  
!                 if(looped) {
!                     // normalize position
!                     oint = smax-(smin-oint)%plen;
! looped1:
!                     ptr = bdt+oint*BCHNS;
! 
!                     // inside in any case
!                     fb = ptr[0];
! 
!                     if(oint < maxo-1) {
!                         fa = oint > smin?ptr[-BCHNS]:bdt[maxo*BCHNS];
!                         fc = ptr[BCHNS];
!                         fd = ptr[BCHNS*2];
!                     }
!                     else {
!                         fa = ptr[-BCHNS];
!                         fc = oint < maxo?ptr[BCHNS]:ptr[(1-plen)*BCHNS];
!                         fd = ptr[(2-plen)*BCHNS];
!                     }
!                 }
!                 else {
!                     // first sample is outside in any case
!                     fa = bdt[smin*BCHNS];
! 
!                     if(oint+2 < smin)
!                         // if last is outside, all are outside
!                         fb = fc = fd = fa;
!                     else {
!                         fd = ptr[BCHNS*2];
!                         if(oint+1 < smin) 
!                             fb = fc = fa;
!                         else {
!                             fc = ptr[BCHNS];
!                             fb = oint < smin?fa:ptr[0];
!                         }
!                     }
!                 }
! 		    }
!     		
! 		    const float f1 = 0.5f*(frac-1.0f);
! 		    const float f3 = frac*3.0f-1.0f;
!     		
! 			const float amdf = (fa-fd)*frac;
! 			const float cmb = fc-fb;
! 			const float bma = fb-fa;
! 			*(sig0++) = fb + frac*( cmb - f1 * ( amdf+bma+cmb*f3 ) );
! 	    }
!     }
!     else {
! 	    for(int i = 0,si = 0; i < n; ++i,++si) {	
! 		    float o = *(pos++);
! 		    register long oint = CASTINT<long>(o);
! 		    const float frac = o-oint;
!             register const t_sample *ptr = bdt+oint*BCHNS;
! 		    register const t_sample *fa,*fb,*fc,*fd;
! 
! 		    if(oint > smin)
! 			    if(oint < maxo-2) {
! 				    // normal case
!     				fb = ptr;
! 				    fa = fb-BCHNS;
! 				    fc = fb+BCHNS;
! 				    fd = fc+BCHNS;
! 			    }
! 			    else {
! 				    // not enough space at the end
! 
!                     if(looped) {
!                         // normalize position
!                         oint = smin+(oint-smin)%plen;
!                         goto looped2;
!                     }
!                     else {
!                         // last sample is outside in any case
!                         fd = bdt+maxo*BCHNS;
! 
!                         if(oint-1 >= maxo)
!                             // if first is outside, all are outside
!                             fa = fb = fc = fd;
!                         else {
!                             fa = ptr-BCHNS;
!                             if(oint >= maxo) 
!                                 fb = fc = fd;
!                             else {
!                                 fb = ptr;
!                                 fc = oint+1 < maxo?ptr+BCHNS:fd;
!                             }
!                         }
!                     }
! 			    }
! 		    else {
! 			    // not enough space at the beginning
! 
!                 if(looped) {
!                     // normalize position
!                     oint = smax-(smin-oint)%plen;
! looped2:
!                     // inside in any case
!                     fb = bdt+oint*BCHNS;
! 
!                     if(oint < maxo-1) {
!                         fa = oint > smin?fb-BCHNS:bdt+maxo*BCHNS;
!                         fc = fb+BCHNS;
!                         fd = fc+BCHNS;
!                     }
!                     else {
!                         fa = fb-BCHNS;
!                         fc = oint < maxo?fb+BCHNS:bdt+(oint-plen+1)*BCHNS;
!                         fd = bdt+(oint-plen+2)*BCHNS;
!                     }
!                 }
!                 else {
!                     // first sample is outside in any case
!                     fa = bdt+smin*BCHNS;
! 
!                     if(oint+2 < smin)
!                         // if last is outside, all are outside
!                         fb = fc = fd = fa;
!                     else {
!                         fd = ptr+BCHNS*2;
!                         if(oint+1 < smin) 
!                             fb = fc = fa;
!                         else {
!                             fc = ptr+BCHNS;
!                             fb = oint < smin?fa:ptr;
!                         }
!                     }
!                 }
! 		    }
!     		
! 		    const float f1 = 0.5f*(frac-1.0f);
! 		    const float f3 = frac*3.0f-1.0f;
!     		
! 		    for(int ci = 0; ci < OCHNS; ++ci) {
! 			    const float amdf = (fa[ci]-fd[ci])*frac;
! 			    const float cmb = fc[ci]-fb[ci];
! 			    const float bma = fb[ci]-fa[ci];
! 			    sig[ci][si] = fb[ci] + frac*( cmb - f1 * ( amdf+bma+cmb*f3 ) );
! 		    }
! 	    }
! 
! 	    // clear rest of output channels (if buffer has less channels)
! 	    for(int ci = OCHNS; ci < outchns; ++ci) ZeroSamples(sig[ci],n);
!     }
  }
  
  
! TMPLDEF inline void xinter::s_play0(int n,t_sample *const *invecs,t_sample *const *outvecs)
  {
! 	st_play0 TMPLCALL (buf.Data(),curmin,curmax,n,buf.Channels(),outchns,invecs,outvecs,loopmode == xsl_loop);
  }
  
! TMPLDEF inline void xinter::s_play1(int n,t_sample *const *invecs,t_sample *const *outvecs)
  {
! 	st_play1 TMPLCALL (buf.Data(),curmin,curmax,n,buf.Channels(),outchns,invecs,outvecs,loopmode == xsl_loop);
  }
  
! TMPLDEF inline void xinter::s_play2(int n,t_sample *const *invecs,t_sample *const *outvecs)
  {
! 	st_play2 TMPLCALL (buf.Data(),curmin,curmax,n,buf.Channels(),outchns,invecs,outvecs,loopmode == xsl_loop);
  }
  
! TMPLDEF inline void xinter::s_play4(int n,t_sample *const *invecs,t_sample *const *outvecs)
  {
! 	st_play4 TMPLCALL (buf.Data(),curmin,curmax,n,buf.Channels(),outchns,invecs,outvecs,loopmode == xsl_loop);
  }
  

Index: prefix.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/xsample/source/prefix.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** prefix.h	16 Dec 2004 05:02:24 -0000	1.1
--- prefix.h	8 Jan 2005 04:59:44 -0000	1.2
***************
*** 13,14 ****
--- 13,15 ----
  #include <flext.h>
  
+ #include <math.h>

Index: main.h
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/xsample/source/main.h,v
retrieving revision 1.32
retrieving revision 1.33
diff -C2 -d -r1.32 -r1.33
*** main.h	16 Dec 2004 05:02:24 -0000	1.32
--- main.h	8 Jan 2005 04:59:44 -0000	1.33
***************
*** 1,10 ****
  /*
- 
  xsample - extended sample objects for Max/MSP and pd (pure data)
  
! Copyright (c) 2001-2004 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
- 
  */
  
--- 1,8 ----
  /*
  xsample - extended sample objects for Max/MSP and pd (pure data)
  
! Copyright (c) 2001-2005 Thomas Grill (gr at grrrr.org)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
  */
  
***************
*** 14,22 ****
  #include "prefix.h"
  
! #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 406)
! #error You need at least flext version 0.4.6
  #endif
  
! #define XSAMPLE_VERSION "0.3.1pre3"
  
  
--- 12,20 ----
  #include "prefix.h"
  
! #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 500)
! #error You need at least flext version 0.5.0
  #endif
  
! #define XSAMPLE_VERSION "0.3.1pre4"
  
  
***************
*** 25,29 ****
  #if defined(_MSC_VER)
  // MS VC 6.0 can't handle <int,int> templates?! -> no optimization
! 	#if _MSC_VER >= 1300
  		#define TMPLOPT
  	#endif
--- 23,28 ----
  #if defined(_MSC_VER)
  // MS VC 6.0 can't handle <int,int> templates?! -> no optimization
! // MS VC .NET 2002 just dies with template optimization switched on
! 	#if _MSC_VER >= 1310
  		#define TMPLOPT
  	#endif
***************
*** 52,66 ****
  
  
- // lazy me
- #define F float
- #define D double
- #define I int
- #define L long
- #define C char
- #define V void
- #define BL bool
- #define S t_sample
- 
- 
  #if defined(__MWERKS__) && !defined(__MACH__)
  	#define STD std
--- 51,54 ----
***************
*** 93,96 ****
--- 81,110 ----
  #endif
  
+ #if FLEXT_CPU == FLEXT_CPU_INTEL && defined(__GNUC__) 
+ template<typename I,typename F> inline I CASTINT(F o) { return lrintf(o); }
+ #elif FLEXT_CPU == FLEXT_CPU_INTEL && defined(_MSC_VER)
+ template<typename I,typename F>
+ inline I CASTINT(F x) {
+ //  by Laurent de Soras (http://ldesoras.free.fr)
+ //    assert (x > static_cast <double> (INT_MIN / 2) + 1.0);
+ //    assert (x < static_cast <double> (INT_MAX / 2) + 1.0);
+     const float round_towards_m_i = -0.5f;
+     I i;
+     __asm
+     {
+         fld x
+         fadd st,st
+         fabs
+         fadd round_towards_m_i
+         fistp i
+         sar i, 1
+     }
+     if(x < 0) i = -i;
+     return i;
+ }
+ #else
+ template<typename I,typename F> inline I CASTINT(F o) { return static_cast<I>(o); }
+ #endif
+ 
  
  class xsample:
***************
*** 102,172 ****
  	xsample();
  	~xsample();
  	
! 	enum xs_unit {
! 		xsu__ = -1,  // don't change
! 		xsu_sample = 0,xsu_buffer,xsu_ms,xsu_s
! 	};
  	
  	enum xs_intp {
- 		xsi__ = -1,  // don't change
  		xsi_none = 0,xsi_4p,xsi_lin
  	};
  	
  	enum xs_sclmd {
- 		xss__ = -1,  // don't change
  		xss_unitsinbuf = 0,xss_unitsinloop,xss_buffer,xss_loop
  	};
  	
  protected:
! 	buffer *buf;
  
! 	virtual V m_start() = 0;
! 	virtual V m_stop() = 0;
! 	virtual BL m_reset();
  
!   	virtual I m_set(I argc,const t_atom *argv);
! 	virtual V m_print() = 0;
! 	virtual BL m_refresh();
! 	virtual V m_loadbang();
  
! 	virtual V m_units(xs_unit u = xsu__);
! 	virtual V m_sclmode(xs_sclmd u = xss__);
  
! 	virtual V m_all();
! 	virtual V m_min(F mn);
! 	virtual V m_max(F mx);
  
! 	virtual V m_dsp(I n,S *const *insigs,S *const *outsigs);
! 	virtual V s_dsp() = 0;
  
! 	xs_unit unitmode; //iunitmode,ounitmode;
! 	xs_sclmd sclmode; //isclmode,osclmode;
  
! 	L curmin,curmax; //,curlen;  // in samples
! 	I sclmin; // in samples
! 	F sclmul;
! 	F s2u;  // sample to unit conversion factor
  
! 	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,-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)); }
  
! 	BL bufchk();
  
! 	V mg_buffer(AtomList &l) { if(buf && buf->Symbol()) { l(1); SetSymbol(l[0],buf->Symbol()); } else l(); }
! 	inline V ms_buffer(const AtomList &l) { m_set(l.Count(),l.Atoms()); }
  
! 	inline V mg_min(F &v) const { v = curmin*s2u; }
! 	inline V mg_max(F &v) const { v = curmax*s2u; }
  
  private:
- 	static V setup(t_classid c);
  
! 	FLEXT_CALLBACK(m_start)
! 	FLEXT_CALLBACK(m_stop)
  
  	FLEXT_CALLBACK_V(m_set)
--- 116,246 ----
  	xsample();
  	~xsample();
+     
+     enum xs_change {
+         xsc__ = 0,
+         xsc_units = 0x0001,
+         xsc_play = 0x0002,
+         xsc_pos = 0x0008,
+         xsc_range = 0x0010,
+         xsc_transport = 0x0020,
+         xsc_fade = 0x0040,
+         
+         xsc_intp = xsc_play,
+         xsc_srate = xsc_play|xsc_units,
+         xsc_chns = xsc_play,
+         xsc_loop = xsc_play,
+         xsc_startstop = xsc_play|xsc_transport,
+         xsc_buffer = xsc_units|xsc_pos|xsc_range|xsc_play,
+         xsc_reset = xsc_buffer,
+         xsc_all = 0xffff
+     };
  	
! 	enum xs_unit { 
!         xsu_sample = 0,xsu_buffer,xsu_ms,xsu_s 
!     };
  	
  	enum xs_intp {
  		xsi_none = 0,xsi_4p,xsi_lin
  	};
  	
  	enum xs_sclmd {
  		xss_unitsinbuf = 0,xss_unitsinloop,xss_buffer,xss_loop
  	};
  	
  protected:
!     virtual bool Finalize();
  
! 	buffer buf;
  
! 	void m_reset() 
!     { 
!         ChkBuffer(true);
!         DoReset(); 
!         Refresh(); 
!     }
  
!   	void m_set(int argc,const t_atom *argv);
  
!     void m_refresh() 
!     { 
!         Update(xsc_buffer,true);
!     }
  
!     void m_units(xs_unit mode)
!     {
!         unitmode = mode;
!         Update(xsc_units,true);
!     }
  
!     void m_sclmode(xs_sclmd mode)
!     {
!         sclmode = mode;
!         Update(xsc_units,true);
!     }
  
!     void m_all() 
!     { 
!         ChkBuffer(true); 
!         ResetRange(); 
!         Refresh(); 
!     }
  
! 	void m_min(float mn);
! 	void m_max(float mx);
! 
! 	xs_unit unitmode;
! 	xs_sclmd sclmode;
! 
! 	long curmin,curmax; //,curlen;  // in samples
! 	long sclmin; // in samples
! 	float sclmul;
! 	float s2u;  // sample to unit conversion factor
! 
! 	inline float scale(float smp) const { return (smp-sclmin)*sclmul; }
  	
!     static void arrscale(int n,const t_sample *in,t_sample *out,t_sample add,t_sample mul) { flext::ScaleSamples(out,in,mul,add,n); }
! 	inline void arrscale(int n,const t_sample *in,t_sample *out) const { arrscale(n,in,out,-sclmin*sclmul,sclmul); }
  	
! 	static void arrmul(int n,const t_sample *in,t_sample *out,t_sample mul) { flext::MulSamples(out,in,mul,n); }
! 	inline void arrmul(int n,const t_sample *in,t_sample *out) const { arrmul(n,in,out,(t_sample)(1.f/s2u)); }
  
! 	void mg_buffer(AtomList &l) { if(buf.Symbol()) { l(1); SetSymbol(l[0],buf.Symbol()); } }
! 	inline void ms_buffer(const AtomList &l) { m_set(l.Count(),l.Atoms()); }
  
! 	inline void mg_min(float &v) const { v = curmin*s2u; }
! 	inline void mg_max(float &v) const { v = curmax*s2u; }
!     
!     void Refresh() { if(update && !Initing()) { DoUpdate(update); update = xsc__; } }
!     void Update(unsigned int f,bool refr = false) { update |= f; if(refr) Refresh(); }
  
!     //! return 0...invalid, 1...changed, -1...unchanged
! 	int ChkBuffer(bool refr = false);
!     
!     typedef flext::buffer::lock_t lock_t;
! 
!     //! Lock buffer (buffer must be checked ok)
!     lock_t Lock() { return buf.Lock(); }
!     //! Unlock buffer (buffer must be checked ok)
!     void Unlock(lock_t l) { buf.Unlock(l); }
! 
!     void ResetRange() 
!     { 
! 	    curmin = 0; 
!         curmax = buf.Frames();
!         Update(xsc_range);
!     }
! 
!     virtual void DoReset();
!     virtual void DoUpdate(unsigned int flags);
! 
! 	virtual void m_loadbang();
! 	virtual void m_print() = 0;
! 	virtual void m_dsp(int n,t_sample *const *insigs,t_sample *const *outsigs);
  
  private:
  
!     unsigned int update;
! 
! 	static void setup(t_classid c);
  
  	FLEXT_CALLBACK_V(m_set)
***************
*** 207,218 ****
  
  	#define DEFSIGFUN(NAME) \
! 	static V st_##NAME(thisType *obj,I n,S *const *in,S *const *out)  { obj->NAME (n,in,out); } \
! 	V NAME(I n,S *const *in,S *const *out)
  
  	#define TMPLSIGFUN(NAME) \
! 	TMPLDEF static V st_##NAME(thisType *obj,I n,S *const *in,S *const *out)  { obj->NAME TMPLCALL (n,in,out); } \
! 	TMPLDEF V NAME(I n,S *const *in,S *const *out)
  
! 	#define TMPLSTFUN(NAME) TMPLDEF static V NAME(const S *bdt,const I smin,const I smax,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs)
  
  	#define SETSIGFUN(VAR,FUN) v_##VAR = FUN
--- 281,292 ----
  
  	#define DEFSIGFUN(NAME) \
! 	static void st_##NAME(thisType *obj,int n,t_sample *const *in,t_sample *const *out)  { obj->NAME (n,in,out); } \
! 	void NAME(int n,t_sample *const *in,t_sample *const *out)
  
  	#define TMPLSIGFUN(NAME) \
! 	TMPLDEF static void st_##NAME(thisType *obj,int n,t_sample *const *in,t_sample *const *out)  { obj->NAME TMPLCALL (n,in,out); } \
! 	TMPLDEF void NAME(int n,t_sample *const *in,t_sample *const *out)
  
! 	#define TMPLSTFUN(NAME) TMPLDEF static void NAME(const t_sample *bdt,const int smin,const int smax,const int n,const int inchns,const int outchns,t_sample *const *invecs,t_sample *const *outvecs)
  
  	#define SETSIGFUN(VAR,FUN) v_##VAR = FUN
***************
*** 221,229 ****
  
  	#define DEFSIGCALL(NAME) \
! 	inline V NAME(I n,S *const *in,S *const *out) { (*v_##NAME)(this,n,in,out); } \
! 	V (*v_##NAME)(thisType *obj,I n,S *const *in,S *const *out) 
  
  	#define DEFSTCALL(NAME) \
! 	V (*NAME)(const S *bdt,const I smin,const I smax,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs)
  
  #else
--- 295,303 ----
  
  	#define DEFSIGCALL(NAME) \
! 	inline void NAME(int n,t_sample *const *in,t_sample *const *out) { (*v_##NAME)(this,n,in,out); } \
! 	void (*v_##NAME)(thisType *obj,int n,t_sample *const *in,t_sample *const *out) 
  
  	#define DEFSTCALL(NAME) \
! 	void (*NAME)(const t_sample *bdt,const int smin,const int smax,const int n,const int inchns,const int outchns,t_sample *const *invecs,t_sample *const *outvecs)
  
  #else
***************
*** 242,259 ****
  	#define TMPLSTF(FUN,BCHNS,IOCHNS) TMPLFUN(FUN,BCHNS,IOCHNS) 
  
! 	#define DEFSIGFUN(NAME)	V NAME(I n,S *const *in,S *const *out)
! 	#define TMPLSIGFUN(NAME) TMPLDEF V NAME(I n,S *const *in,S *const *out)
! 	#define TMPLSTFUN(NAME) TMPLDEF static V NAME(const S *bdt,const I smin,const I smax,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs)
  
  	#define SETSIGFUN(VAR,FUN) v_##VAR = FUN
  
  	#define DEFSIGCALL(NAME) \
! 	inline V NAME(I n,S *const *in,S *const *out) { (this->*v_##NAME)(n,in,out); } \
! 	V (thisType::*v_##NAME)(I n,S *const *invecs,S *const *outvecs)
  
  	#define SETSTFUN(VAR,FUN) VAR = FUN
  
  	#define DEFSTCALL(NAME) \
! 	V (*NAME)(const S *bdt,const I smin,const I smax,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs)
  #endif
  
--- 316,333 ----
  	#define TMPLSTF(FUN,BCHNS,IOCHNS) TMPLFUN(FUN,BCHNS,IOCHNS) 
  
! 	#define DEFSIGFUN(NAME)	void NAME(int n,t_sample *const *in,t_sample *const *out)
! 	#define TMPLSIGFUN(NAME) TMPLDEF void NAME(int n,t_sample *const *in,t_sample *const *out)
! 	#define TMPLSTFUN(NAME) TMPLDEF static void NAME(const t_sample *bdt,const int smin,const int smax,const int n,const int inchns,const int outchns,t_sample *const *invecs,t_sample *const *outvecs,bool looped)
  
  	#define SETSIGFUN(VAR,FUN) v_##VAR = FUN
  
  	#define DEFSIGCALL(NAME) \
! 	inline void NAME(int n,t_sample *const *in,t_sample *const *out) { (this->*v_##NAME)(n,in,out); } \
! 	void (thisType::*v_##NAME)(int n,t_sample *const *invecs,t_sample *const *outvecs)
  
  	#define SETSTFUN(VAR,FUN) VAR = FUN
  
  	#define DEFSTCALL(NAME) \
! 	void (*NAME)(const t_sample *bdt,const int smin,const int smax,const int n,const int inchns,const int outchns,t_sample *const *invecs,t_sample *const *outvecs,bool looped)
  #endif
  
***************
*** 270,285 ****
  	// optimization by using constants for channel numbers
  	#define SIGCHNS(BCHNS,bchns,IOCHNS,iochns)  \
! 		const I BCHNS = _BCHNS_ < 0?(bchns):_BCHNS_;  \
! 		const I IOCHNS = _IOCHNS_ < 0?MIN(iochns,BCHNS):MIN(_IOCHNS_,BCHNS)
  #else 
  	// no template optimization
  	#if FLEXT_SYS == FLEXT_SYS_PD // only mono buffers
  		#define SIGCHNS(BCHNS,bchns,IOCHNS,iochns)   \
! 			const I BCHNS = 1;  \
! 			const I IOCHNS = MIN(iochns,BCHNS)
  	#else // MAXMSP
  		#define SIGCHNS(BCHNS,bchns,IOCHNS,iochns)   \
! 			const I BCHNS = bchns;  \
! 			const I IOCHNS = MIN(iochns,BCHNS)
  	#endif
  #endif
--- 344,359 ----
  	// optimization by using constants for channel numbers
  	#define SIGCHNS(BCHNS,bchns,IOCHNS,iochns)  \
! 		const int BCHNS = _BCHNS_ < 0?(bchns):_BCHNS_;  \
! 		const int IOCHNS = _IOCHNS_ < 0?MIN(iochns,BCHNS):MIN(_IOCHNS_,BCHNS)
  #else 
  	// no template optimization
  	#if FLEXT_SYS == FLEXT_SYS_PD // only mono buffers
  		#define SIGCHNS(BCHNS,bchns,IOCHNS,iochns)   \
! 			const int BCHNS = 1;  \
! 			const int IOCHNS = MIN(iochns,BCHNS)
  	#else // MAXMSP
  		#define SIGCHNS(BCHNS,bchns,IOCHNS,iochns)   \
! 			const int BCHNS = bchns;  \
! 			const int IOCHNS = MIN(iochns,BCHNS)
  	#endif
  #endif
***************
*** 292,308 ****
  	
  public:
! 	xinter(): outchns(1),doplay(false),interp(xsi_4p) {}
  	
! protected:
! 	virtual I m_set(I argc,const t_atom *argv);
  
! 	virtual V m_start();
! 	virtual V m_stop();
  
! 	inline V m_interp(xs_intp mode = xsi__) { interp = mode; s_dsp(); }
  
! 	I outchns;
! 	BL doplay;	
  	xs_intp interp;
  
  	TMPLSIGFUN(s_play0);
--- 366,405 ----
  	
  public:
! 
! 	enum xs_loop {
! 		xsl_once = 0,xsl_loop,xsl_bidir
! 	};
! 
!     xinter()
!         : outchns(1),doplay(false)
!         , interp(xsi_4p),loopmode(xsl_loop)
!     {}
  	
!     void m_start() 
!     { 
! 	    ChkBuffer();
!         doplay = true;
!         Update(xsc_startstop,true);
!     }
  
!     void m_stop() 
!     { 
! 	    ChkBuffer();
!         doplay = false;
!         Update(xsc_startstop,true);
!     }
  
! 	void m_interp(xs_intp mode)
!     { 
!         interp = mode; 
!         Update(xsc_intp,true);
!     }
  
! protected:
! 
! 	int outchns;
! 	bool doplay;	
  	xs_intp interp;
+ 	xs_loop loopmode;
  
  	TMPLSIGFUN(s_play0);
***************
*** 319,329 ****
  	DEFSIGCALL(zerofun);
  
! 	virtual V s_dsp();
  
! private:
! 	static V setup(t_classid c);
  
  	FLEXT_CALLSET_E(m_interp,xs_intp)
  	FLEXT_ATTRGET_E(interp,xs_intp)
  };
  
--- 416,431 ----
  	DEFSIGCALL(zerofun);
  
! 	virtual void DoUpdate(unsigned int flags);
  
! 	FLEXT_CALLBACK(m_start)
! 	FLEXT_CALLBACK(m_stop)
  
  	FLEXT_CALLSET_E(m_interp,xs_intp)
  	FLEXT_ATTRGET_E(interp,xs_intp)
+ 
+ 	FLEXT_ATTRGET_E(loopmode,xs_loop)
+ 
+ private:
+ 	static void setup(t_classid c);
  };
  
***************
*** 333,336 ****
  
  #endif
- 
- 
--- 435,436 ----

Index: record.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/xsample/source/record.cpp,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** record.cpp	16 Dec 2004 05:02:24 -0000	1.16
--- record.cpp	8 Jan 2005 04:59:44 -0000	1.17
***************
*** 1,10 ****
  /*
- 
  xsample - extended sample objects for Max/MSP and pd (pure data)
  
! Copyright (c) 2001-2004 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
- 
  */
  
--- 1,8 ----
  /*
  xsample - extended sample objects for Max/MSP and pd (pure data)
  
! Copyright (c) 2001-2005 Thomas Grill (gr at grrrr.org)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
  */
  
***************
*** 23,73 ****
  
  public:
! 	xrecord(I argc,const t_atom *argv);
! 	
! 	virtual BL Init();
! 		
! 	virtual V m_help();
! 	virtual V m_print();
  	
! 	virtual I m_set(I argc,const t_atom *argv);
! 
! 	virtual V m_pos(F pos);
! 	virtual V m_all();
! 	virtual V m_start();
! 	virtual V m_stop();
  
! 	virtual BL m_reset();
  
! 	virtual V m_units(xs_unit md = xsu__);
! 	virtual V m_min(F mn);
! 	virtual V m_max(F mx);
  
! 	inline V m_append(BL app) { if(!(appmode = app)) m_pos(0); }
  
! 	virtual V m_draw(I argc,const t_atom *argv);	
  
  protected:
! 	I inchns;
! 	BL sigmode,appmode;
! 	F drintv;
! 
! 	BL dorec,doloop;
!     I mixmode;
! 	L curpos;  // in samples
  
! 	inline V outputmin() { ToOutFloat(1,curmin*s2u); }
! 	inline V outputmax() { ToOutFloat(2,curmax*s2u); }
  
! 	inline V mg_pos(F &v) const { v = curpos*s2u; }
  	
  private:
! 	static V setup(t_classid c);
! 
! 	virtual V s_dsp();
  
  	TMPLSIGFUN(s_rec);
  
  	DEFSIGCALL(recfun);
! 	virtual V m_signal(I n,S *const *in,S *const *out);
  
  	FLEXT_CALLVAR_F(mg_pos,m_pos)
--- 21,72 ----
  
  public:
! 	xrecord(int argc,const t_atom *argv);
  	
! 	void m_pos(float pos)
!     {
! 	    curpos = pos?CASTINT<long>(pos/s2u+.5):0;
!         Update(xsc_pos);
!         Refresh();
!     }
  
! 	inline void mg_pos(float &v) const { v = curpos*s2u; }
  
!     void m_start();
! 	void m_stop();
  
! 	inline void m_append(bool app) 
!     { 
!         appmode = app;
!         Update(xsc_play);
!         if(!appmode) m_pos(0); 
!     }
  
! 	void m_draw(int argc,const t_atom *argv);	
  
  protected:
! 	int inchns;
! 	bool sigmode,appmode;
! 	float drintv;
  
! 	bool dorec,doloop;
!     int mixmode;
! 	long curpos;  // in samples
  
!     virtual void DoReset();
!     virtual void DoUpdate(unsigned int flags);
! 	
! 	virtual void m_help();
! 	virtual void m_print();
! 	virtual void m_signal(int n,t_sample *const *in,t_sample *const *out);
  	
  private:
! 	static void setup(t_classid c);
  
  	TMPLSIGFUN(s_rec);
  
  	DEFSIGCALL(recfun);
! 
! 	FLEXT_CALLBACK(m_start)
! 	FLEXT_CALLBACK(m_stop)
  
  	FLEXT_CALLVAR_F(mg_pos,m_pos)
***************
*** 91,98 ****
  
  
! V xrecord::setup(t_classid c)
  {
  	DefineHelp(c,"xrecord~");
  
  	FLEXT_CADDATTR_VAR(c,"pos",mg_pos,m_pos);
  	FLEXT_CADDATTR_VAR(c,"min",mg_min,m_min);
--- 90,101 ----
  
  
! void xrecord::setup(t_classid c)
  {
  	DefineHelp(c,"xrecord~");
  
+ 	FLEXT_CADDBANG(c,0,m_start);
+ 	FLEXT_CADDMETHOD_(c,0,"start",m_start);
+ 	FLEXT_CADDMETHOD_(c,0,"stop",m_stop);
+ 
  	FLEXT_CADDATTR_VAR(c,"pos",mg_pos,m_pos);
  	FLEXT_CADDATTR_VAR(c,"min",mg_min,m_min);
***************
*** 108,112 ****
  }
  
! xrecord::xrecord(I argc,const t_atom *argv):
  	inchns(1),
  	sigmode(false),appmode(true),
--- 111,115 ----
  }
  
! xrecord::xrecord(int argc,const t_atom *argv):
  	inchns(1),
  	sigmode(false),appmode(true),
***************
*** 115,119 ****
      mixmode(0)
  {
! 	I argi = 0;
  #if FLEXT_SYS == FLEXT_SYS_MAX
  	if(argc > argi && CanbeInt(argv[argi])) {
--- 118,122 ----
      mixmode(0)
  {
! 	int argi = 0;
  #if FLEXT_SYS == FLEXT_SYS_MAX
  	if(argc > argi && CanbeInt(argv[argi])) {
***************
*** 124,128 ****
  
  	if(argc > argi && IsSymbol(argv[argi])) {
! 		buf = new buffer(GetSymbol(argv[argi]),true);
  		argi++;
  
--- 127,131 ----
  
  	if(argc > argi && IsSymbol(argv[argi])) {
! 		buf.Set(GetSymbol(argv[argi]),true);
  		argi++;
  
***************
*** 136,144 ****
  #endif
  	}
- 	else
- 		buf = new buffer(NULL,true);
  
! 	for(I ci = 0; ci < inchns; ++ci) {
! 		C tmp[40];
  		STD::sprintf(tmp,ci == 0?"Messages/audio channel %i":"Audio channel %i",ci+1);
  		AddInSignal(tmp);  // audio signals
--- 139,145 ----
  #endif
  	}
  
!     for(int ci = 0; ci < inchns; ++ci) {
! 		char tmp[40];
  		STD::sprintf(tmp,ci == 0?"Messages/audio channel %i":"Audio channel %i",ci+1);
  		AddInSignal(tmp);  // audio signals
***************
*** 156,280 ****
  }
  
  
! BL xrecord::Init()
! {
! 	if(xsample::Init()) {
! 		m_reset();
! 		return true;
! 	}
! 	else
! 		return false;
! }
! 		
! V xrecord::m_units(xs_unit mode)
! {
! 	xsample::m_units(mode);
! 
! 	m_sclmode();
! 	outputmin();
! 	outputmax();
! }
! 
! V xrecord::m_min(F mn)
! {
! 	xsample::m_min(mn);
! 	m_pos(curpos*s2u);
! 	outputmin();
! }
! 
! V xrecord::m_max(F mx)
! {
! 	xsample::m_max(mx);
! 	m_pos(curpos*s2u);
! 	outputmax();
! }
! 
! V xrecord::m_all()
! {
! 	xsample::m_all();
! 	outputmin();
! 	outputmax();
! }
! 
! V xrecord::m_pos(F pos)
! {
! 	curpos = pos?(L)(pos/s2u+.5):0;
! 
! 	if(curpos < curmin) curpos = curmin;
! 	else if(curpos > curmax) curpos = curmax;
! }
! 
! 
! I xrecord::m_set(I argc,const t_atom *argv)
! {
! 	I r = xsample::m_set(argc,argv);
! 	if(r) 
!         // buffer parameters have changed, reset pos/min/max
!         m_reset(); 
! 	return r;
! }
  
! V xrecord::m_start() 
! { 
! 	if(!sigmode && !appmode) m_pos(0); 
! 	m_refresh(); 
! 	dorec = true; 
! 	buf->SetRefrIntv(drintv);
! 	s_dsp();
  }
  
! V xrecord::m_stop() 
  { 
! 	dorec = false; 
! 	buf->Dirty(true);
! 	buf->SetRefrIntv(0);
! 	s_dsp();
  }
  
! BL xrecord::m_reset()
  {
  	curpos = 0;
- 	return xsample::m_reset();
  }
  
! V xrecord::m_draw(I argc,const t_atom *argv)
  {
  	if(argc >= 1) {
! 		drintv = GetInt(argv[0]);
! 		if(dorec) buf->SetRefrIntv(drintv);
  	}
  	else
! 		buf->Dirty(true);
  }
  	
! 	
! TMPLDEF V xrecord::s_rec(I n,S *const *invecs,S *const *outvecs)
  {
! 	SIGCHNS(BCHNS,buf->Channels(),ICHNS,inchns);
  
! 	const S *const *sig = invecs;
! 	register I si = 0;
! 	const S *on = invecs[inchns];
! 	S *pos = outvecs[0];
  
! 	BL lpbang = false;
! 	register const F pf = sclmul;
! 	register L o = curpos;
  	
  	if(o < curmin) o = curmin;
  
! //	if(buf && dorec && curlen > 0) {
! 	if(buf && dorec && curmax > curmin) {
  		while(n) {
! 			L ncur = curmax-o; // at max to buffer or recording end
  
  			if(ncur <= 0) {	// end of buffer
  				if(doloop) { 
! 					o = curmin;
! //					ncur = curlen;
! 					ncur = curmax-o;
  				}
! 				else 
! 					m_stop(); // loop expired;
  					
  				lpbang = true;
--- 157,223 ----
  }
  
+ void xrecord::m_start() 
+ { 
+     ChkBuffer();
  
!     if(!sigmode && !appmode) { curpos = 0; Update(xsc_pos); }
  
!     dorec = true; 
!     Update(xsc_startstop);
!     Refresh();
  }
  
! void xrecord::m_stop() 
  { 
!     ChkBuffer();
!     dorec = false; 
!     Update(xsc_startstop);
!     Refresh();
  }
  
! void xrecord::DoReset()
  {
+     xsample::DoReset();
  	curpos = 0;
  }
  
! void xrecord::m_draw(int argc,const t_atom *argv)
  {
  	if(argc >= 1) {
! 		drintv = GetAInt(argv[0]);
! 		if(dorec) buf.SetRefrIntv(drintv);
  	}
  	else
! 		buf.Dirty(true);
  }
  	
! TMPLDEF void xrecord::s_rec(int n,t_sample *const *invecs,t_sample *const *outvecs)
  {
! 	SIGCHNS(BCHNS,buf.Channels(),ICHNS,inchns);
  
! 	const t_sample *const *sig = invecs;
! 	register int si = 0;
! 	const t_sample *on = invecs[inchns];
! 	t_sample *pos = outvecs[0];
  
! 	bool lpbang = false;
! 	register const float pf = sclmul;
! 	register long o = curpos;
  	
  	if(o < curmin) o = curmin;
  
! 	if(dorec && curmax > curmin) {
  		while(n) {
! 			long ncur = curmax-o; // at max to buffer or recording end
  
  			if(ncur <= 0) {	// end of buffer
  				if(doloop) { 
! 					ncur = curmax-(o = curmin);
  				}
!                 else {
! 					// loop expired;
!                     dorec = false; 
!                     Update(xsc_startstop);
!                 }
  					
  				lpbang = true;
***************
*** 285,291 ****
  			if(ncur > n) ncur = n;
  			
! 			register I i;
! 			register S *bf = buf->Data()+o*BCHNS;
! 			register F p = scale(o);
  
  			if(sigmode) {
--- 228,234 ----
  			if(ncur > n) ncur = n;
  			
! 			register int i;
! 			register t_sample *bf = buf.Data()+o*BCHNS;
! 			register float p = scale(o);
  
  			if(sigmode) {
***************
*** 296,300 ****
                      case 0:
  						for(i = 0; i < ncur; ++i,++si) {	
! 							if(*(on++) >= 0) {
  								for(int ci = 0; ci < ICHNS; ++ci)
  									bf[ci] = sig[ci][si];	
--- 239,243 ----
                      case 0:
  						for(i = 0; i < ncur; ++i,++si) {	
! 							if(!(*(on++) < 0)) {
  								for(int ci = 0; ci < ICHNS; ++ci)
  									bf[ci] = sig[ci][si];	
***************
*** 308,313 ****
                      case 1:
  						for(i = 0; i < ncur; ++i,++si) {	
! 							register const S g = *(on++);
! 							if(g >= 0) {
  								for(int ci = 0; ci < ICHNS; ++ci)
  									bf[ci] = bf[ci]*(1.-g)+sig[ci][si]*g;
--- 251,256 ----
                      case 1:
  						for(i = 0; i < ncur; ++i,++si) {	
! 							register const t_sample g = *(on++);
! 							if(!(g < 0)) {
  								for(int ci = 0; ci < ICHNS; ++ci)
  									bf[ci] = bf[ci]*(1.-g)+sig[ci][si]*g;
***************
*** 321,325 ****
                      case 2:
  						for(i = 0; i < ncur; ++i,++si) {	
! 							if(*(on++) >= 0) {
  								for(int ci = 0; ci < ICHNS; ++ci)
  									bf[ci] += sig[ci][si];	
--- 264,268 ----
                      case 2:
  						for(i = 0; i < ncur; ++i,++si) {	
! 							if(!(*(on++) < 0)) {
  								for(int ci = 0; ci < ICHNS; ++ci)
  									bf[ci] += sig[ci][si];	
***************
*** 338,342 ****
                          case 0: {
  						    for(i = 0; i < ncur; ++i,++si) {	
! 							    if(*(on++) >= 0)
  							    { 	
  								    for(int ci = 0; ci < ICHNS; ++ci)
--- 281,285 ----
                          case 0: {
  						    for(i = 0; i < ncur; ++i,++si) {	
! 							    if(!(*(on++) < 0))
  							    { 	
  								    for(int ci = 0; ci < ICHNS; ++ci)
***************
*** 347,351 ****
  							    else {
  								    *(pos++) = p = scale(o = 0);
! 								    bf = buf->Data();
  							    }
  						    }
--- 290,294 ----
  							    else {
  								    *(pos++) = p = scale(o = 0);
! 								    bf = buf.Data();
  							    }
  						    }
***************
*** 354,359 ****
                          case 1: {
  						    for(i = 0; i < ncur; ++i,++si) {	
! 							    register const S g = *(on++);
! 							    if(g >= 0) {
  								    for(int ci = 0; ci < ICHNS; ++ci)
  									    bf[ci] = bf[ci]*(1.-g)+sig[ci][si]*g;
--- 297,302 ----
                          case 1: {
  						    for(i = 0; i < ncur; ++i,++si) {	
! 							    register const t_sample g = *(on++);
! 							    if(!(g < 0)) {
  								    for(int ci = 0; ci < ICHNS; ++ci)
  									    bf[ci] = bf[ci]*(1.-g)+sig[ci][si]*g;
***************
*** 363,367 ****
  							    else {
  								    *(pos++) = p = scale(o = 0);
! 								    bf = buf->Data();
  							    }
  						    }
--- 306,310 ----
  							    else {
  								    *(pos++) = p = scale(o = 0);
! 								    bf = buf.Data();
  							    }
  						    }
***************
*** 370,374 ****
                          case 2: {
  						    for(i = 0; i < ncur; ++i,++si) {	
! 							    if(*(on++) >= 0)
  							    { 	
  								    for(int ci = 0; ci < ICHNS; ++ci)
--- 313,317 ----
                          case 2: {
  						    for(i = 0; i < ncur; ++i,++si) {	
! 							    if(!(*(on++) < 0))
  							    { 	
  								    for(int ci = 0; ci < ICHNS; ++ci)
***************
*** 379,383 ****
  							    else {
  								    *(pos++) = p = scale(o = 0);
! 								    bf = buf->Data();
  							    }
  						    }
--- 322,326 ----
  							    else {
  								    *(pos++) = p = scale(o = 0);
! 								    bf = buf.Data();
  							    }
  						    }
***************
*** 394,399 ****
                      case 0: {
  					    for(int ci = 0; ci < ICHNS; ++ci) {	
! 						    register S *b = bf+ci;
! 						    register const F *s = sig[ci]+si;
  						    for(i = 0; i < ncur; ++i,b += BCHNS,++s) 
                                  *b = *s;	
--- 337,342 ----
                      case 0: {
  					    for(int ci = 0; ci < ICHNS; ++ci) {	
! 						    register t_sample *b = bf+ci;
! 						    register const float *s = sig[ci]+si;
  						    for(i = 0; i < ncur; ++i,b += BCHNS,++s) 
                                  *b = *s;	
***************
*** 404,408 ****
                      case 1: {
  					    for(i = 0; i < ncur; ++i,++si) {	
! 						    register const S w = *(on++);
  						    for(int ci = 0; ci < ICHNS; ++ci)
  							    bf[ci] = bf[ci]*(1.-w)+sig[ci][si]*w;
--- 347,351 ----
                      case 1: {
  					    for(i = 0; i < ncur; ++i,++si) {	
! 						    register const t_sample w = *(on++);
  						    for(int ci = 0; ci < ICHNS; ++ci)
  							    bf[ci] = bf[ci]*(1.-w)+sig[ci][si]*w;
***************
*** 413,419 ****
                      case 2: {
  					    for(int ci = 0; ci < ICHNS; ++ci) {	
! 						    register S *b = bf+ci;
! 						    register const F *s = sig[ci]+si;
! 						    for(i = 0; i < ncur; ++i,b += BCHNS,++s) *b += *s;	
  					    }
  					    si += ncur;
--- 356,363 ----
                      case 2: {
  					    for(int ci = 0; ci < ICHNS; ++ci) {	
! 						    register t_sample *b = bf+ci;
! 						    register const float *s = sig[ci]+si;
! 						    for(i = 0; i < ncur; ++i,b += BCHNS,++s) 
!                                 *b += *s;	
  					    }
  					    si += ncur;
***************
*** 431,439 ****
  		curpos = o;
  		
! 		buf->Dirty(); 
  	}
  
  	if(n) {
! 		register F p = scale(o);
  		while(n--) *(pos++) = p;
  	}
--- 375,383 ----
  		curpos = o;
  		
! 		buf.Dirty(); 
  	}
  
  	if(n) {
! 		register float p = scale(o);
  		while(n--) *(pos++) = p;
  	}
***************
*** 442,450 ****
  }
  
! V xrecord::m_signal(I n,S *const *in,S *const *out) 
  { 
! 	if(bufchk()) 
  		// call the appropriate dsp function
! 		recfun(n,in,out); 
  	else
  		// set position signal to zero
--- 386,402 ----
  }
  
! void xrecord::m_signal(int n,t_sample *const *in,t_sample *const *out) 
  { 
!     int ret = ChkBuffer(true);
! 
!     if(ret) {
  		// call the appropriate dsp function
!         
!         const lock_t l = Lock();
! 		recfun(n,in,out);
!         Unlock(l);
!          
!         Refresh();
!     }
  	else
  		// set position signal to zero
***************
*** 452,474 ****
  }
  
! V xrecord::s_dsp()
  {
! 	switch(buf->Channels()*1000+inchns) {
! 	case 1001:	SETSIGFUN(recfun,TMPLFUN(s_rec,1,1));	break;
! 	case 1002:	SETSIGFUN(recfun,TMPLFUN(s_rec,1,2));	break;
! 	case 2001:	SETSIGFUN(recfun,TMPLFUN(s_rec,2,1));	break;
! 	case 2002:	SETSIGFUN(recfun,TMPLFUN(s_rec,2,2));	break;
! 	case 4001:
! 	case 4002:
! 	case 4003:	SETSIGFUN(recfun,TMPLFUN(s_rec,4,-1));	break;
! 	case 4004:	SETSIGFUN(recfun,TMPLFUN(s_rec,4,4));	break;
! 	default:	SETSIGFUN(recfun,TMPLFUN(s_rec,-1,-1));	break;
! 	}
! }
  
  
  
  
! V xrecord::m_help()
  {
  	post("%s - part of xsample objects, version " XSAMPLE_VERSION,thisName());
--- 404,447 ----
  }
  
! void xrecord::DoUpdate(unsigned int flags)
  {
!     xsample::DoUpdate(flags);
  
+     if(flags&(xsc_pos|xsc_range)) {
+ 	    if(curpos < curmin) curpos = curmin;
+ 	    else if(curpos > curmax) curpos = curmax;
+     }
  
+     if(flags&xsc_range) {
+ 	    ToOutFloat(1,curmin*s2u);
+ 	    ToOutFloat(2,curmax*s2u);
+     }
  
+     if(flags&xsc_transport && buf.Ok()) {
+         if(dorec)
+         	buf.SetRefrIntv(drintv);
+         else {
+ 	        buf.Dirty(true);
+ 	        buf.SetRefrIntv(0);
+         }
+     }
  
!     if(flags&xsc_play) {
! 	    switch(buf.Channels()*1000+inchns) {
! 	    case 1001:	SETSIGFUN(recfun,TMPLFUN(s_rec,1,1));	break;
! 	    case 1002:	SETSIGFUN(recfun,TMPLFUN(s_rec,1,2));	break;
! 	    case 2001:	SETSIGFUN(recfun,TMPLFUN(s_rec,2,1));	break;
! 	    case 2002:	SETSIGFUN(recfun,TMPLFUN(s_rec,2,2));	break;
! 	    case 4001:
! 	    case 4002:
! 	    case 4003:	SETSIGFUN(recfun,TMPLFUN(s_rec,4,-1));	break;
! 	    case 4004:	SETSIGFUN(recfun,TMPLFUN(s_rec,4,4));	break;
! 	    default:	SETSIGFUN(recfun,TMPLFUN(s_rec,-1,-1));	break;
! 	    }
!     }
! }
! 
! 
! void xrecord::m_help()
  {
  	post("%s - part of xsample objects, version " XSAMPLE_VERSION,thisName());
***************
*** 476,480 ****
  	post("compiled on " __DATE__ " " __TIME__);
  #endif
! 	post("(C) Thomas Grill, 2001-2004");
  #if FLEXT_SYS == FLEXT_SYS_MAX
  	post("Arguments: %s [channels=1] [buffer]",thisName());
--- 449,453 ----
  	post("compiled on " __DATE__ " " __TIME__);
  #endif
! 	post("(C) Thomas Grill, 2001-2005");
  #if FLEXT_SYS == FLEXT_SYS_MAX
  	post("Arguments: %s [channels=1] [buffer]",thisName());
***************
*** 507,520 ****
  }
  
! V xrecord::m_print()
  {
! 	static const C sclmode_txt[][20] = {"units","units in loop","buffer","loop"};
  
  	// print all current settings
  	post("%s - current settings:",thisName());
! 	post("bufname = '%s', length = %.3f, channels = %i",buf->Name(),(F)(buf->Frames()*s2u),buf->Channels()); 
! 	post("in channels = %i, frames/unit = %.3f, scale mode = %s",inchns,(F)(1./s2u),sclmode_txt[sclmode]); 
  	post("sigmode = %s, append = %s, loop = %s, mixmode = %i",sigmode?"yes":"no",appmode?"yes":"no",doloop?"yes":"no",mixmode); 
  	post("");
  }
- 
--- 480,492 ----
  }
  
! void xrecord::m_print()
  {
! 	static const char sclmode_txt[][20] = {"units","units in loop","buffer","loop"};
  
  	// print all current settings
  	post("%s - current settings:",thisName());
! 	post("bufname = '%s', length = %.3f, channels = %i",buf.Name(),(float)(buf.Frames()*s2u),buf.Channels()); 
! 	post("in channels = %i, frames/unit = %.3f, scale mode = %s",inchns,(float)(1./s2u),sclmode_txt[sclmode]); 
  	post("sigmode = %s, append = %s, loop = %s, mixmode = %i",sigmode?"yes":"no",appmode?"yes":"no",doloop?"yes":"no",mixmode); 
  	post("");
  }

Index: play.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/xsample/source/play.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** play.cpp	8 Feb 2004 03:40:47 -0000	1.9
--- play.cpp	8 Jan 2005 04:59:44 -0000	1.10
***************
*** 1,10 ****
  /*
- 
  xsample - extended sample objects for Max/MSP and pd (pure data)
  
! Copyright (c) 2001-2004 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
- 
  */
  
--- 1,8 ----
  /*
  xsample - extended sample objects for Max/MSP and pd (pure data)
  
! Copyright (c) 2001-2005 Thomas Grill (gr at grrrr.org)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
  */
  
***************
*** 23,49 ****
  
  public:
! 	xplay(I argc,const t_atom *argv);
  	
! 	virtual BL Init();
! 		
! 	virtual V m_help();
! 	virtual V m_print();
  	
  private:
! 	static V setup(t_classid c);
  
! 	virtual V m_signal(I n,S *const *in,S *const *out);
  };
  
  FLEXT_LIB_DSP_V("xplay~",xplay)
  
! V xplay::setup(t_classid c)
  {
  	DefineHelp(c,"xplay~");
  }
  
! xplay::xplay(I argc,const t_atom *argv)
  {
! 	I argi = 0;
  #if FLEXT_SYS == FLEXT_SYS_MAX
  	if(argc > argi && CanbeInt(argv[argi])) {
--- 21,58 ----
  
  public:
! 	xplay(int argc,const t_atom *argv);
! 
! 	void m_loop(xs_loop lp)
!     { 
! 	    loopmode = lp;
!         Update(xsc_loop,true);
!     }
  	
! protected:
! 	virtual void m_help();
! 	virtual void m_print();
! 	virtual void m_signal(int n,t_sample *const *in,t_sample *const *out);
  	
  private:
! 	static void setup(t_classid c);
  
!     FLEXT_CALLSET_E(m_loop,xs_loop)
  };
  
  FLEXT_LIB_DSP_V("xplay~",xplay)
  
! void xplay::setup(t_classid c)
  {
  	DefineHelp(c,"xplay~");
+ 
+ 	FLEXT_CADDATTR_VAR_E(c,"loop",loopmode,m_loop);
  }
  
! xplay::xplay(int argc,const t_atom *argv)
  {
!     // set the loopmode to non-wrapping (for sample interpolation)
!     loopmode = xsl_once;
! 
! 	int argi = 0;
  #if FLEXT_SYS == FLEXT_SYS_MAX
  	if(argc > argi && CanbeInt(argv[argi])) {
***************
*** 54,58 ****
  
  	if(argc > argi && IsSymbol(argv[argi])) {
! 		buf = new buffer(GetSymbol(argv[argi]),true);
  		argi++;
  		
--- 63,67 ----
  
  	if(argc > argi && IsSymbol(argv[argi])) {
! 		buf.Set(GetSymbol(argv[argi]),true);
  		argi++;
  		
***************
*** 66,100 ****
  #endif
  	}
- 	else
- 		buf = new buffer(NULL,true);
  
! 	AddInSignal("Messages and Signal of playing position");  // pos signal
! 	for(I ci = 0; ci < outchns; ++ci) {
! 		C tmp[30];
  		STD::sprintf(tmp,"Audio signal channel %i",ci+1); 
  		AddOutSignal(tmp);
  	}
- 	
- 	m_reset();
  }
  
! BL xplay::Init()
! {
! 	if(xinter::Init()) {
! 		m_reset();
! 		return true;
! 	}
! 	else
! 		return false;
! }
! 	
! V xplay::m_signal(I n,S *const *in,S *const *out) 
  { 
  	// check whether buffer is invalid or changed
! 	if(bufchk()) {
  		// convert position units to frames
  		arrmul(n,in[0],out[0]);
  		// call resample routine
  		playfun(n,out,out); 
  	}
  	else
--- 75,103 ----
  #endif
  	}
  
!     AddInSignal("Messages and Signal of playing position");  // pos signal
! 	for(int ci = 0; ci < outchns; ++ci) {
! 		char tmp[30];
  		STD::sprintf(tmp,"Audio signal channel %i",ci+1); 
  		AddOutSignal(tmp);
  	}
  }
  
! void xplay::m_signal(int n,t_sample *const *in,t_sample *const *out) 
  { 
+ 	int ret = ChkBuffer(true);
+ 
  	// check whether buffer is invalid or changed
! 	if(ret) {
!         const lock_t l = Lock();
!         
  		// convert position units to frames
  		arrmul(n,in[0],out[0]);
  		// call resample routine
  		playfun(n,out,out); 
+         
+         Unlock(l);
+ 
+         Refresh();
  	}
  	else
***************
*** 104,108 ****
  
  
! V xplay::m_help()
  {
  	post("%s - part of xsample objects, version " XSAMPLE_VERSION,thisName());
--- 107,111 ----
  
  
! void xplay::m_help()
  {
  	post("%s - part of xsample objects, version " XSAMPLE_VERSION,thisName());
***************
*** 110,114 ****
  	post("compiled on " __DATE__ " " __TIME__);
  #endif
! 	post("(C) Thomas Grill, 2001-2004");
  #if FLEXT_SYS == FLEXT_SYS_MAX
  	post("Arguments: %s [channels=1] [buffer]",thisName());
--- 113,117 ----
  	post("compiled on " __DATE__ " " __TIME__);
  #endif
! 	post("(C) Thomas Grill, 2001-2005");
  #if FLEXT_SYS == FLEXT_SYS_MAX
  	post("Arguments: %s [channels=1] [buffer]",thisName());
***************
*** 121,125 ****
  	post("\thelp: shows this help");
  	post("\tset name: set buffer");
! 	post("\tenable 0/1: turn dsp calculation off/on");	
  	post("\tprint: print current settings");
  	post("\tbang/start: begin playing");
--- 124,128 ----
  	post("\thelp: shows this help");
  	post("\tset name: set buffer");
! 	post("\tenable 0/1: turn dsp calculation off/on");
  	post("\tprint: print current settings");
  	post("\tbang/start: begin playing");
***************
*** 129,144 ****
  	post("\t at units 0/1/2/3: set units to samples/buffer size/ms/s");
  	post("\t at interp 0/1/2: set interpolation to off/4-point/linear");
  	post("");
  }
  
! V xplay::m_print()
  {
! 	const C *interp_txt[] = {"off","4-point","linear"};
  	// print all current settings
  	post("%s - current settings:",thisName());
! 	post("bufname = '%s', length = %.3f, channels = %i",buf->Name(),(F)(buf->Frames()*s2u),buf->Channels()); 
! 	post("out channels = %i, samples/unit = %.3f, interpolation = %s",outchns,(F)(1./s2u),interp_txt[interp >= xsi_none && interp <= xsi_lin?interp:xsi_none]); 
  	post("");
  }
- 
- 
--- 132,146 ----
  	post("\t at units 0/1/2/3: set units to samples/buffer size/ms/s");
  	post("\t at interp 0/1/2: set interpolation to off/4-point/linear");
+ 	post("\t at loop 0/1/2: sets looping (interpolation) to off/forward/bidirectional");
  	post("");
  }
  
! void xplay::m_print()
  {
! 	const char *interp_txt[] = {"off","4-point","linear"};
  	// print all current settings
  	post("%s - current settings:",thisName());
! 	post("bufname = '%s', length = %.3f, channels = %i",buf.Name(),(float)(buf.Frames()*s2u),buf.Channels()); 
! 	post("out channels = %i, samples/unit = %.3f, interpolation = %s",outchns,(float)(1./s2u),interp_txt[interp >= xsi_none && interp <= xsi_lin?interp:xsi_none]); 
  	post("");
  }

Index: inter.cpp
===================================================================
RCS file: /cvsroot/pure-data/externals/grill/xsample/source/inter.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** inter.cpp	16 Dec 2004 05:02:24 -0000	1.8
--- inter.cpp	8 Jan 2005 04:59:44 -0000	1.9
***************
*** 1,10 ****
  /* 
- 
  xsample - extended sample objects for Max/MSP and pd (pure data)
  
! Copyright (c) 2001-2004 Thomas Grill (xovo at gmx.net)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
- 
  */
  
--- 1,8 ----
  /* 
  xsample - extended sample objects for Max/MSP and pd (pure data)
  
! Copyright (c) 2001-2005 Thomas Grill (gr at grrrr.org)
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file, "license.txt," in this distribution.  
  */
  
***************
*** 22,100 ****
  void xinter::setup(t_classid c)
  {
  	FLEXT_CADDATTR_VAR_E(c,"interp",interp,m_interp);
  }
  
! I xinter::m_set(I argc,const t_atom *argv) 
  {
! 	I r = xsample::m_set(argc,argv);
! 	if(r) 
!         // buffer parameters have changed, reset pos/min/max
!         m_reset(); 
! 	return r;
! }
! 
! V xinter::m_start() 
! { 
! 	m_refresh(); 
! 	doplay = true; 
! 	s_dsp(); 
! }
! 
! V xinter::m_stop() 
! { 
! 	doplay = false; 
! 	s_dsp(); 
! }
  
! V xinter::s_dsp()
! {
! 	switch(outchns) {
! 		case 1:	SETSIGFUN(zerofun,TMPLFUN(s_play0,-1,1)); break;
! 		case 2:	SETSIGFUN(zerofun,TMPLFUN(s_play0,-1,2)); break;
! 		case 4:	SETSIGFUN(zerofun,TMPLFUN(s_play0,-1,4)); break;
! 		default:	SETSIGFUN(zerofun,TMPLFUN(s_play0,-1,-1));
! 	}
  
! 	if(doplay) {
! 		if(interp == xsi_4p) 
! 			switch(buf->Channels()*1000+outchns) {
! 				case 1001:	SETSIGFUN(playfun,TMPLFUN(s_play4,1,1)); break;
! 				case 1002:	SETSIGFUN(playfun,TMPLFUN(s_play4,1,2)); break;
! 				case 2001:	SETSIGFUN(playfun,TMPLFUN(s_play4,2,1)); break;
! 				case 2002:	SETSIGFUN(playfun,TMPLFUN(s_play4,2,2)); break;
! 				case 4001:
! 				case 4002:
! 				case 4003:	SETSIGFUN(playfun,TMPLFUN(s_play4,4,-1)); break;
! 				case 4004:	SETSIGFUN(playfun,TMPLFUN(s_play4,4,4)); break;
! 				default:	SETSIGFUN(playfun,TMPLFUN(s_play4,-1,-1));
! 			}
! 		else if(interp == xsi_lin) 
! 			switch(buf->Channels()*1000+outchns) {
! 				case 1001:	SETSIGFUN(playfun,TMPLFUN(s_play2,1,1)); break;
! 				case 1002:	SETSIGFUN(playfun,TMPLFUN(s_play2,1,2)); break;
! 				case 2001:	SETSIGFUN(playfun,TMPLFUN(s_play2,2,1)); break;
! 				case 2002:	SETSIGFUN(playfun,TMPLFUN(s_play2,2,2)); break;
! 				case 4001:
! 				case 4002:
! 				case 4003:	SETSIGFUN(playfun,TMPLFUN(s_play2,4,-1)); break;
! 				case 4004:	SETSIGFUN(playfun,TMPLFUN(s_play2,4,4)); break;
! 				default:	SETSIGFUN(playfun,TMPLFUN(s_play2,-1,-1));
! 			}
! 		else 
! 			switch(buf->Channels()*1000+outchns) {
! 				case 1001:	SETSIGFUN(playfun,TMPLFUN(s_play1,1,1)); break;
! 				case 1002:	SETSIGFUN(playfun,TMPLFUN(s_play1,1,2)); break;
! 				case 2001:	SETSIGFUN(playfun,TMPLFUN(s_play1,2,1)); break;
! 				case 2002:	SETSIGFUN(playfun,TMPLFUN(s_play1,2,2)); break;
! 				case 4001:
! 				case 4002:
! 				case 4003:	SETSIGFUN(playfun,TMPLFUN(s_play1,4,-1)); break;
! 				case 4004:	SETSIGFUN(playfun,TMPLFUN(s_play1,4,4)); break;
! 				default:	SETSIGFUN(playfun,TMPLFUN(s_play1,-1,-1));
! 			}
! 	}
! 	else
! 		SETSIGFUN(playfun,TMPLFUN(s_play0,-1,-1));
  }
- 
- 
--- 20,82 ----
  void xinter::setup(t_classid c)
  {
+ 	FLEXT_CADDBANG(c,0,m_start);
+ 	FLEXT_CADDMETHOD_(c,0,"start",m_start);
+ 	FLEXT_CADDMETHOD_(c,0,"stop",m_stop);
+ 
  	FLEXT_CADDATTR_VAR_E(c,"interp",interp,m_interp);
  }
  
! void xinter::DoUpdate(unsigned int flags)
  {
!     xsample::DoUpdate(flags);
  
!     if(flags&xsc_play) {
! 	    switch(outchns) {
! 		    case 1:	SETSIGFUN(zerofun,TMPLFUN(s_play0,-1,1)); break;
! 		    case 2:	SETSIGFUN(zerofun,TMPLFUN(s_play0,-1,2)); break;
! 		    case 4:	SETSIGFUN(zerofun,TMPLFUN(s_play0,-1,4)); break;
! 		    default:	SETSIGFUN(zerofun,TMPLFUN(s_play0,-1,-1));
! 	    }
  
! 	    if(doplay && buf.Ok()) {
! 		    if(interp == xsi_4p) 
! 			    switch(buf.Channels()*1000+outchns) {
! 				    case 1001:	SETSIGFUN(playfun,TMPLFUN(s_play4,1,1)); break;
! 				    case 1002:	SETSIGFUN(playfun,TMPLFUN(s_play4,1,2)); break;
! 				    case 2001:	SETSIGFUN(playfun,TMPLFUN(s_play4,2,1)); break;
! 				    case 2002:	SETSIGFUN(playfun,TMPLFUN(s_play4,2,2)); break;
! 				    case 4001:
! 				    case 4002:
! 				    case 4003:	SETSIGFUN(playfun,TMPLFUN(s_play4,4,-1)); break;
! 				    case 4004:	SETSIGFUN(playfun,TMPLFUN(s_play4,4,4)); break;
! 				    default:	SETSIGFUN(playfun,TMPLFUN(s_play4,-1,-1));
! 			    }
! 		    else if(interp == xsi_lin) 
! 			    switch(buf.Channels()*1000+outchns) {
! 				    case 1001:	SETSIGFUN(playfun,TMPLFUN(s_play2,1,1)); break;
! 				    case 1002:	SETSIGFUN(playfun,TMPLFUN(s_play2,1,2)); break;
! 				    case 2001:	SETSIGFUN(playfun,TMPLFUN(s_play2,2,1)); break;
! 				    case 2002:	SETSIGFUN(playfun,TMPLFUN(s_play2,2,2)); break;
! 				    case 4001:
! 				    case 4002:
! 				    case 4003:	SETSIGFUN(playfun,TMPLFUN(s_play2,4,-1)); break;
! 				    case 4004:	SETSIGFUN(playfun,TMPLFUN(s_play2,4,4)); break;
! 				    default:	SETSIGFUN(playfun,TMPLFUN(s_play2,-1,-1));
! 			    }
! 		    else 
! 			    switch(buf.Channels()*1000+outchns) {
! 				    case 1001:	SETSIGFUN(playfun,TMPLFUN(s_play1,1,1)); break;
! 				    case 1002:	SETSIGFUN(playfun,TMPLFUN(s_play1,1,2)); break;
! 				    case 2001:	SETSIGFUN(playfun,TMPLFUN(s_play1,2,1)); break;
! 				    case 2002:	SETSIGFUN(playfun,TMPLFUN(s_play1,2,2)); break;
! 				    case 4001:
! 				    case 4002:
! 				    case 4003:	SETSIGFUN(playfun,TMPLFUN(s_play1,4,-1)); break;
! 				    case 4004:	SETSIGFUN(playfun,TMPLFUN(s_play1,4,4)); break;
! 				    default:	SETSIGFUN(playfun,TMPLFUN(s_play1,-1,-1));
! 			    }
! 	    }
! 	    else
! 		    SETSIGFUN(playfun,TMPLFUN(s_play0,-1,-1));
!     }
  }





More information about the Pd-cvs mailing list