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@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@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@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@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@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@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@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@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@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@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@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@units 0/1/2/3: set units to samples/buffer size/ms/s"); post("\t@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@units 0/1/2/3: set units to samples/buffer size/ms/s"); post("\t@interp 0/1/2: set interpolation to off/4-point/linear"); + post("\t@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@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@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)); ! } }