/* xsample - extended sample objects for Max/MSP and pd (pure data) Copyright (c) 2001-2007 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. */ #include "main.h" #include #ifdef _MSC_VER #pragma warning (disable:4244) #endif class xplay: public xinter { FLEXT_HEADER_S(xplay,xinter,setup) public: xplay(int argc,const t_atom *argv); void m_loop(xs_loop lp) { loopmode = lp; Update(xsc_loop,true); } protected: virtual void CbSignal(); virtual void m_help(); virtual void m_print(); 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])) { outchns = GetAInt(argv[argi]); argi++; } #endif if(argc > argi && IsSymbol(argv[argi])) { buf.Set(GetSymbol(argv[argi]),true); argi++; #if FLEXT_SYS == FLEXT_SYS_MAX // oldstyle command line? if(argi == 1 && argc == 2 && CanbeInt(argv[argi])) { outchns = GetAInt(argv[argi]); argi++; post("%s: old style command line detected - please change to '%s [channels] [buffer]'",thisName(),thisName()); } #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::CbSignal() { int ret = ChkBuffer(true); int n = Blocksize(); const t_sample *const *in = InSig(); t_sample *const *out = OutSig(); // 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 zerofun(n,out,out); } void xplay::m_help() { post("%s - part of xsample objects, version " XSAMPLE_VERSION,thisName()); #ifdef FLEXT_DEBUG post("compiled on " __DATE__ " " __TIME__); #endif post("(C) Thomas Grill, 2001-2007"); #if FLEXT_SYS == FLEXT_SYS_MAX post("Arguments: %s [channels=1] [buffer]",thisName()); #else post("Arguments: %s [buffer]",thisName()); #endif post("Inlets: 1:Messages/Position signal"); post("Outlets: 1:Audio signal"); post("Methods:"); 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"); post("\tstop: stop playing"); post("\treset: checks buffer"); post("\trefresh: checks buffer and refreshes outlets"); 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(""); }