aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/xsample/source/record.cpp
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2009-04-01 21:13:09 +0000
committerThomas Grill <xovo@users.sourceforge.net>2009-04-01 21:13:09 +0000
commit0ed7a8b68dd73e2b0473b8127aeca99f3bac9061 (patch)
tree5c67818b38a5cc2f9caa5ca7f8640ca356adf02b /externals/grill/xsample/source/record.cpp
parentbb4c7f6a245394d09dac9adfb2efb093d3d98452 (diff)
cleaned up grill externals - replaced with svn:externals to svn.grrrr.org/ext/trunk/
svn path=/trunk/; revision=10951
Diffstat (limited to 'externals/grill/xsample/source/record.cpp')
-rw-r--r--externals/grill/xsample/source/record.cpp497
1 files changed, 0 insertions, 497 deletions
diff --git a/externals/grill/xsample/source/record.cpp b/externals/grill/xsample/source/record.cpp
deleted file mode 100644
index 07c94b45..00000000
--- a/externals/grill/xsample/source/record.cpp
+++ /dev/null
@@ -1,497 +0,0 @@
-/*
-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 <stdio.h>
-
-#ifdef _MSC_VER
-#pragma warning (disable:4244)
-#endif
-
-extern "C++" {
-
-class xrecord:
- public xsample
-{
- FLEXT_HEADER_S(xrecord,xsample,setup)
-
-public:
- xrecord(int argc,const t_atom *argv);
-
- void m_pos(float pos)
- {
- curpos = LIKELY(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 CbSignal();
-
- virtual void m_help();
- virtual void m_print();
-
-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)
- FLEXT_CALLBACK(m_all)
- FLEXT_CALLSET_F(m_min)
- FLEXT_CALLSET_F(m_max)
- FLEXT_CALLBACK_F(m_min)
- FLEXT_CALLBACK_F(m_max)
-
- FLEXT_ATTRVAR_B(doloop)
- FLEXT_ATTRVAR_I(mixmode)
- FLEXT_ATTRVAR_B(sigmode)
- FLEXT_CALLSET_B(m_append)
- FLEXT_ATTRGET_B(appmode)
-
- FLEXT_CALLBACK_V(m_draw)
-};
-
-}
-
-
-FLEXT_LIB_DSP_V("xrecord~",xrecord)
-
-
-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);
- FLEXT_CADDATTR_VAR(c,"max",mg_max,m_max);
- FLEXT_CADDMETHOD_(c,0,"all",m_all);
-
- FLEXT_CADDMETHOD_(c,0,"draw",m_draw);
-
- FLEXT_CADDATTR_VAR1(c,"loop",doloop);
- FLEXT_CADDATTR_VAR1(c,"mixmode",mixmode);
- FLEXT_CADDATTR_VAR1(c,"sigmode",sigmode);
- FLEXT_CADDATTR_VAR(c,"append",appmode,m_append);
-}
-
-xrecord::xrecord(int argc,const t_atom *argv):
- inchns(1),
- sigmode(false),appmode(true),
- drintv(0),
- dorec(false),doloop(false),
- mixmode(0)
-{
- int argi = 0;
-#if FLEXT_SYS == FLEXT_SYS_MAX
- if(argc > argi && CanbeInt(argv[argi])) {
- inchns = 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])) {
- inchns = GetAInt(argv[argi]);
- argi++;
- post("%s: old style command line detected - please change to '%s [channels] [buffer]'",thisName(),thisName());
- }
-#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
- }
- AddInSignal("On/Off/Fade/Mix signal (0..1)"); // on/off signal
- AddInFloat("Starting point of recording"); // min
- AddInFloat("Ending point of recording"); // max
- AddOutSignal("Current position of recording"); // pos signal
- AddOutFloat("Starting point (rounded to frame)"); // min
- AddOutFloat("Ending point (rounded to frame)"); // max
- AddOutBang("Bang on loop end/rollover"); // loop bang
-
- FLEXT_ADDMETHOD(inchns+1,m_min);
- FLEXT_ADDMETHOD(inchns+2,m_max);
-}
-
-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 && LIKELY(curmax > curmin)) {
- while(n) {
- long ncur = curmax-o; // at max to buffer or recording end
-
- if(UNLIKELY(ncur <= 0)) { // end of buffer
- if(doloop) {
- ncur = curmax-(o = curmin);
- }
- else {
- // loop expired;
- dorec = false;
- Update(xsc_startstop);
- }
-
- lpbang = true;
- }
-
- if(UNLIKELY(!dorec)) break;
-
- if(UNLIKELY(ncur > n)) ncur = n;
-
- register int i;
- register t_sample *bf = buf.Data()+o*BCHNS;
- register float p = scale(o);
-
- if(sigmode) {
- if(appmode) {
- // append to current position
-
- switch(mixmode) {
- case 0:
- for(i = 0; i < ncur; ++i,++si) {
- if(!(*(on++) < 0)) {
- for(int ci = 0; ci < ICHNS; ++ci)
- bf[ci] = sig[ci][si];
- bf += BCHNS;
- *(pos++) = p,p += pf,++o;
- }
- else
- *(pos++) = p;
- }
- break;
- 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;
- bf += BCHNS;
- *(pos++) = p,p += pf,++o;
- }
- else
- *(pos++) = p;
- }
- break;
- case 2:
- for(i = 0; i < ncur; ++i,++si) {
- if(!(*(on++) < 0)) {
- for(int ci = 0; ci < ICHNS; ++ci)
- bf[ci] += sig[ci][si];
- bf += BCHNS;
- *(pos++) = p,p += pf,++o;
- }
- else
- *(pos++) = p;
- }
- break;
- }
- }
- else {
- // don't append
- switch(mixmode) {
- case 0: {
- for(i = 0; i < ncur; ++i,++si) {
- if(!(*(on++) < 0))
- {
- for(int ci = 0; ci < ICHNS; ++ci)
- bf[ci] = sig[ci][si];
- bf += BCHNS;
- *(pos++) = p,p += pf,++o;
- }
- else {
- *(pos++) = p = scale(o = 0);
- bf = buf.Data();
- }
- }
- break;
- }
- 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;
- bf += BCHNS;
- *(pos++) = p,p += pf,++o;
- }
- else {
- *(pos++) = p = scale(o = 0);
- bf = buf.Data();
- }
- }
- break;
- }
- case 2: {
- for(i = 0; i < ncur; ++i,++si) {
- if(!(*(on++) < 0))
- {
- for(int ci = 0; ci < ICHNS; ++ci)
- bf[ci] += sig[ci][si];
- bf += BCHNS;
- *(pos++) = p,p += pf,++o;
- }
- else {
- *(pos++) = p = scale(o = 0);
- bf = buf.Data();
- }
- }
- break;
- }
- }
- }
- }
- else {
- // message mode
-
- // Altivec optimization for that!
- switch(mixmode) {
- 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;
- }
- si += ncur;
- break;
- }
- 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;
- bf += BCHNS;
- }
- break;
- }
- 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;
- break;
- }
- }
-
- for(i = 0; i < ncur; ++i) {
- *(pos++) = p,p += pf,++o;
- }
- }
-
- n -= ncur;
- }
- curpos = o;
-
- buf.Dirty();
- }
-
- if(n) {
- register float p = scale(o);
- while(n--) *(pos++) = p;
- }
-
- if(lpbang) ToOutBang(3);
-}
-
-void xrecord::CbSignal()
-{
- int ret = ChkBuffer(true);
-
- if(ret) {
- // call the appropriate dsp function
-
- const lock_t l = Lock();
- recfun(Blocksize(),InSig(),OutSig());
- Unlock(l);
-
- Refresh();
- }
- else
- // set position signal to zero
- ZeroSamples(OutSig()[0],Blocksize());
-}
-
-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());
-#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/Audio signal, 2:Trigger signal, 3:Min point, 4: Max point");
- post("Outlets: 1:Position signal, 2:Min point, 3:Max point");
- post("Methods:");
- post("\thelp: shows this help");
- post("\tset [name]: set buffer or reinit");
- post("\tenable 0/1: turn dsp calculation off/on");
- post("\treset: reset min/max recording points and recording offset");
- post("\tprint: print current settings");
- post("\t@sigmode 0/1: specify message or signal triggered recording");
- post("\t@append 0/1: reset recording position or append to current position");
- post("\t@loop 0/1: switches looping off/on");
- post("\t@mixmode 0/1/2: specify how audio signal should be mixed in (none,mixed,added)");
- post("\tmin {unit}: set minimum recording point");
- post("\tmax {unit}: set maximum recording point");
- post("\tall: select entire buffer length");
- post("\tpos {unit}: set recording position (obeying the current scale mode)");
- post("\tbang/start: start recording");
- post("\tstop: stop recording");
- post("\trefresh: checks buffer and refreshes outlets");
- post("\t@units 0/1/2/3: set units to frames/buffer size/ms/s");
- post("\t@sclmode 0/1/2/3: set range of position to units/units in loop/buffer/loop");
- post("\tdraw [{float}]: redraw buffer immediately (arg omitted) or periodic (in ms)");
- post("");
-}
-
-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("");
-}
-