aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/xsample/source
diff options
context:
space:
mode:
Diffstat (limited to 'externals/grill/xsample/source')
-rw-r--r--externals/grill/xsample/source/groove.cpp39
-rw-r--r--externals/grill/xsample/source/inter.cpp9
-rwxr-xr-x[-rw-r--r--]externals/grill/xsample/source/inter.h (renamed from externals/grill/xsample/source/inter.ci)54
-rw-r--r--externals/grill/xsample/source/main.cpp61
-rw-r--r--externals/grill/xsample/source/main.h28
-rw-r--r--externals/grill/xsample/source/play.cpp25
-rw-r--r--externals/grill/xsample/source/record.cpp3
7 files changed, 144 insertions, 75 deletions
diff --git a/externals/grill/xsample/source/groove.cpp b/externals/grill/xsample/source/groove.cpp
index 62f0c291..60bf617b 100644
--- a/externals/grill/xsample/source/groove.cpp
+++ b/externals/grill/xsample/source/groove.cpp
@@ -103,8 +103,10 @@ private:
virtual V m_signal(I n,S *const *in,S *const *out)
{
- bufchk();
- posfun(n,in,out);
+ if(bufchk())
+ posfun(n,in,out);
+ else
+ zerofun(n,in,out);
}
FLEXT_CALLBACK_F(m_pos)
@@ -195,11 +197,11 @@ xgroove::xgroove(I argc,const t_atom *argv):
AddOutFloat("Ending point (rounded to frame)"); // play max
AddOutBang("Bang on loop end/rollover"); // loop bang
-
znbuf = new S *[outchns];
for(I i = 0; i < outchns; ++i) znbuf[i] = new S[0];
- znpos = new S[0];
+ znpos = new S[0]; // don't know vector size yet -> m_dsp
znidx = new S[0];
+ znmul = new S[XZONE_TABLE+1];
m_xshape();
}
@@ -304,9 +306,6 @@ V xgroove::m_xshape(I argc,const t_atom *argv)
else if(xshparam > 1) xshparam = 1;
}
- if(znmul) delete[] znmul;
- znmul = new S[XZONE_TABLE+1];
-
I i;
switch(xshape) {
case 1:
@@ -393,13 +392,11 @@ V xgroove::s_pos_off(I n,S *const *invecs,S *const *outvecs)
{
S *pos = outvecs[outchns];
- I si;
- for(si = 0; si < n; ++si) pos[si] = curpos;
+ SetSamples(pos,n,curpos);
playfun(n,&pos,outvecs);
- const F oscl = scale(curpos);
- for(si = 0; si < n; ++si) pos[si] = oscl;
+ SetSamples(pos,n,scale(curpos));
}
V xgroove::s_pos_once(I n,S *const *invecs,S *const *outvecs)
@@ -427,7 +424,7 @@ V xgroove::s_pos_once(I n,S *const *invecs,S *const *outvecs)
playfun(n,&pos,outvecs);
- for(I i = 0; i < n; ++i) pos[i] = scale(pos[i]);
+ arrscale(n,pos,pos);
}
else
s_pos_off(n,invecs,outvecs);
@@ -467,7 +464,7 @@ V xgroove::s_pos_loop(I n,S *const *invecs,S *const *outvecs)
playfun(n,&pos,outvecs);
- for(I i = 0; i < n; ++i) pos[i] = scale(pos[i]);
+ arrscale(n,pos,pos);
}
else
s_pos_off(n,invecs,outvecs);
@@ -523,15 +520,16 @@ V xgroove::s_pos_loopzn(I n,S *const *invecs,S *const *outvecs)
playfun(n,&pos,outvecs);
- for(I i = 0; i < n; ++i) pos[i] = scale(pos[i]);
+ arrscale(n,pos,pos);
if(inzn) {
// only if we were in cross-fade zone
playfun(n,&znpos,znbuf);
- for(I i = 0; i < n; ++i) znpos[i] = XZONE_TABLE-znidx[i];
- zonefun(znmul,0,XZONE_TABLE+1,1,n,1,1,&znidx,&znidx);
- zonefun(znmul,0,XZONE_TABLE+1,1,n,1,1,&znpos,&znpos);
+ arrscale(n,znidx,znpos,-XZONE_TABLE,-1);
+
+ zonefun(znmul,0,XZONE_TABLE+1,n,1,1,&znidx,&znidx);
+ zonefun(znmul,0,XZONE_TABLE+1,n,1,1,&znpos,&znpos);
for(I o = 0; o < outchns; ++o) {
F *ov = outvecs[o],*ob = znbuf[o];
@@ -582,7 +580,7 @@ V xgroove::s_pos_bidir(I n,S *const *invecs,S *const *outvecs)
bidir = (I)bd;
playfun(n,&pos,outvecs);
- for(I i = 0; i < n; ++i) pos[i] = scale(pos[i]);
+ arrscale(n,pos,pos);
}
else
s_pos_off(n,invecs,outvecs);
@@ -614,6 +612,8 @@ V xgroove::s_dsp()
SETSIGFUN(posfun,SIGFUN(s_pos_loopzn));
+ // linear interpolation should be just ok for fade zone, no?
+/*
if(interp == xsi_4p)
switch(outchns) {
case 1: SETSTFUN(zonefun,TMPLSTF(st_play4,1,1)); break;
@@ -622,12 +622,14 @@ V xgroove::s_dsp()
default: SETSTFUN(zonefun,TMPLSTF(st_play4,1,-1));
}
else if(interp == xsi_lin)
+*/
switch(outchns) {
case 1: SETSTFUN(zonefun,TMPLSTF(st_play2,1,1)); break;
case 2: SETSTFUN(zonefun,TMPLSTF(st_play2,1,2)); break;
case 4: SETSTFUN(zonefun,TMPLSTF(st_play2,1,4)); break;
default: SETSTFUN(zonefun,TMPLSTF(st_play2,1,-1));
}
+/*
else
switch(outchns) {
case 1: SETSTFUN(zonefun,TMPLSTF(st_play1,1,1)); break;
@@ -635,6 +637,7 @@ V xgroove::s_dsp()
case 4: SETSTFUN(zonefun,TMPLSTF(st_play1,1,4)); break;
default: SETSTFUN(zonefun,TMPLSTF(st_play1,1,-1));
}
+*/
}
else
SETSIGFUN(posfun,SIGFUN(s_pos_loop));
diff --git a/externals/grill/xsample/source/inter.cpp b/externals/grill/xsample/source/inter.cpp
index 42221e1c..f3fba86c 100644
--- a/externals/grill/xsample/source/inter.cpp
+++ b/externals/grill/xsample/source/inter.cpp
@@ -16,7 +16,7 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#endif
#ifndef TMPLOPT
-#include "inter.ci"
+#include "inter.h"
#endif
void xinter::setup(t_classid c)
@@ -53,6 +53,13 @@ V xinter::m_stop()
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) {
diff --git a/externals/grill/xsample/source/inter.ci b/externals/grill/xsample/source/inter.h
index 1ce98f61..697c66df 100644..100755
--- a/externals/grill/xsample/source/inter.ci
+++ b/externals/grill/xsample/source/inter.h
@@ -11,23 +11,18 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#ifndef __INTER_H
#define __INTER_H
-TMPLDEF V xinter::st_play0(const S *bdt,const I smin,const I smax,const F s2u,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs)
+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
- SIGCHNS(BCHNS,inchns,OCHNS,outchns);
-
-// const S *pos = invecs[0];
- S *const *sig = outvecs;
-
- for(I ci = 0; ci < outchns; ++ci)
- for(I si = 0; si < n; ++si) sig[ci][si] = 0;
+ // 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 F s2u,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs)
+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);
- const S *pos = invecs[0];
+ // position info are frame units
+ const S *pos = invecs[0];
S *const *sig = outvecs;
register I si = 0;
@@ -55,20 +50,20 @@ TMPLDEF V xinter::st_play1(const S *bdt,const I smin,const I smax,const F s2u,co
}
// clear rest of output channels (if buffer has less channels)
- for(I ci = OCHNS; ci < outchns; ++ci)
- for(si = 0; si < n; ++si) sig[ci][si] = 0;
+ 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 F s2u,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs)
+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,s2u,n,inchns,outchns,invecs,outvecs);
+ st_play1 TMPLCALL (bdt,smin,smax,n,inchns,outchns,invecs,outvecs);
return;
}
SIGCHNS(BCHNS,inchns,OCHNS,outchns);
+ // position info are frame units
const S *pos = invecs[0];
S *const *sig = outvecs;
register I si = 0;
@@ -105,21 +100,21 @@ TMPLDEF V xinter::st_play2(const S *bdt,const I smin,const I smax,const F s2u,co
}
// clear rest of output channels (if buffer has less channels)
- for(I ci = OCHNS; ci < outchns; ++ci)
- for(si = 0; si < n; ++si) sig[ci][si] = 0;
+ 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 F s2u,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs)
+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,s2u,n,inchns,outchns,invecs,outvecs);
- else st_play2 TMPLCALL (bdt,smin,smax,s2u,n,inchns,outchns,invecs,outvecs);
+ 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;
}
SIGCHNS(BCHNS,inchns,OCHNS,outchns);
+ // position info are frame units
const S *pos = invecs[0];
S *const *sig = outvecs;
register I si = 0;
@@ -167,29 +162,28 @@ TMPLDEF V xinter::st_play4(const S *bdt,const I smin,const I smax,const F s2u,co
}
// clear rest of output channels (if buffer has less channels)
- for(I ci = OCHNS; ci < outchns; ++ci)
- for(si = 0; si < n; ++si) sig[ci][si] = 0;
+ for(I ci = OCHNS; ci < outchns; ++ci) ZeroSamples(sig[ci],n);
}
-TMPLDEF V xinter::s_play0(I n,S *const *invecs,S *const *outvecs)
+TMPLDEF inline V xinter::s_play0(I n,S *const *invecs,S *const *outvecs)
{
- st_play0 TMPLCALL (buf->Data(),curmin,curmax,s2u,n,buf->Channels(),outchns,invecs,outvecs);
+ st_play0 TMPLCALL (buf->Data(),curmin,curmax,n,buf->Channels(),outchns,invecs,outvecs);
}
-TMPLDEF V xinter::s_play1(I n,S *const *invecs,S *const *outvecs)
+TMPLDEF inline V xinter::s_play1(I n,S *const *invecs,S *const *outvecs)
{
- st_play1 TMPLCALL (buf->Data(),curmin,curmax,s2u,n,buf->Channels(),outchns,invecs,outvecs);
+ st_play1 TMPLCALL (buf->Data(),curmin,curmax,n,buf->Channels(),outchns,invecs,outvecs);
}
-TMPLDEF V xinter::s_play2(I n,S *const *invecs,S *const *outvecs)
+TMPLDEF inline V xinter::s_play2(I n,S *const *invecs,S *const *outvecs)
{
- st_play2 TMPLCALL (buf->Data(),curmin,curmax,s2u,n,buf->Channels(),outchns,invecs,outvecs);
+ st_play2 TMPLCALL (buf->Data(),curmin,curmax,n,buf->Channels(),outchns,invecs,outvecs);
}
-TMPLDEF V xinter::s_play4(I n,S *const *invecs,S *const *outvecs)
+TMPLDEF inline V xinter::s_play4(I n,S *const *invecs,S *const *outvecs)
{
- st_play4 TMPLCALL (buf->Data(),curmin,curmax,s2u,n,buf->Channels(),outchns,invecs,outvecs);
+ st_play4 TMPLCALL (buf->Data(),curmin,curmax,n,buf->Channels(),outchns,invecs,outvecs);
}
diff --git a/externals/grill/xsample/source/main.cpp b/externals/grill/xsample/source/main.cpp
index 2a39950d..2392bdb1 100644
--- a/externals/grill/xsample/source/main.cpp
+++ b/externals/grill/xsample/source/main.cpp
@@ -72,6 +72,18 @@ xsample::~xsample()
}
+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)
{
@@ -115,7 +127,7 @@ V xsample::m_loadbang()
V xsample::m_units(xs_unit mode)
{
- bufchk();
+ if(!bufchk()) return; // if invalid do nothing (actually, it should be delayed)
if(mode != xsu__) unitmode = mode;
switch(unitmode) {
@@ -138,7 +150,7 @@ V xsample::m_units(xs_unit mode)
V xsample::m_sclmode(xs_sclmd mode)
{
- bufchk();
+ if(!bufchk()) return; // if invalid do nothing (actually, it should be delayed)
if(mode != xss__) sclmode = mode;
switch(sclmode) {
@@ -162,7 +174,7 @@ V xsample::m_sclmode(xs_sclmd mode)
V xsample::m_min(F mn)
{
- bufchk();
+ if(!bufchk()) return; // if invalid do nothing (actually, it should be delayed)
mn /= s2u; // conversion to samples
if(mn < 0) mn = 0;
@@ -175,7 +187,7 @@ V xsample::m_min(F mn)
V xsample::m_max(F mx)
{
- bufchk();
+ if(!bufchk()) return; // if invalid do nothing (actually, it should be delayed)
mx /= s2u; // conversion to samples
if(mx > buf->Frames()) mx = (F)buf->Frames();
@@ -188,7 +200,7 @@ V xsample::m_max(F mx)
V xsample::m_all()
{
- bufchk();
+ if(!bufchk()) return; // if invalid do nothing (actually, it should be delayed)
// curlen = (curmax = buf->Frames())-(curmin = 0);
curmin = 0; curmax = buf->Frames();
@@ -203,5 +215,44 @@ V xsample::m_dsp(I /*n*/,S *const * /*insigs*/,S *const * /*outsigs*/)
}
+V xsample::arrscale(I n,const S *src,S *dst,S add,S mul)
+{
+ int n8 = n>>3;
+ n -= n8<<3;
+ while(n8--) {
+ dst[0] = (src[0]+add)*mul;
+ dst[1] = (src[1]+add)*mul;
+ dst[2] = (src[2]+add)*mul;
+ dst[3] = (src[3]+add)*mul;
+ dst[4] = (src[4]+add)*mul;
+ dst[5] = (src[5]+add)*mul;
+ dst[6] = (src[6]+add)*mul;
+ dst[7] = (src[7]+add)*mul;
+ src += 8,dst += 8;
+ }
+
+ while(n--) *(dst++) = (*(src++)+add)*mul;
+}
+
+V xsample::arrmul(I n,const S *src,S *dst,S mul)
+{
+ int n8 = n>>3;
+ n -= n8<<3;
+ while(n8--) {
+ dst[0] = src[0]*mul;
+ dst[1] = src[1]*mul;
+ dst[2] = src[2]*mul;
+ dst[3] = src[3]*mul;
+ dst[4] = src[4]*mul;
+ dst[5] = src[5]*mul;
+ dst[6] = src[6]*mul;
+ dst[7] = src[7]*mul;
+ src += 8,dst += 8;
+ }
+
+ while(n--) *(dst++) = *(src++)*mul;
+}
+
+
diff --git a/externals/grill/xsample/source/main.h b/externals/grill/xsample/source/main.h
index 94f8885f..03d5d261 100644
--- a/externals/grill/xsample/source/main.h
+++ b/externals/grill/xsample/source/main.h
@@ -11,19 +11,18 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#ifndef __XSAMPLE_H
#define __XSAMPLE_H
-#define XSAMPLE_VERSION "0.2.5pre3"
+#define XSAMPLE_VERSION "0.3.0pre4"
#define FLEXT_ATTRIBUTES 1
#include <flext.h>
-#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 401)
-#error You need at least flext version 0.4.1
+#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 402)
+#error You need at least flext version 0.4.2
#endif
-// most compilers are somehow broken.....
-// in other words: can't handle all C++ features
+// most compilers are somehow broken - in other words - can't handle all C++ features
#if defined(_MSC_VER)
// MS VC 6.0 can't handle <int,int> templates?! -> no optimization
@@ -123,8 +122,14 @@ protected:
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);
+ inline V arrscale(I n,const S *in,S *out) const { arrscale(n,in,out,(S)-sclmin,sclmul); }
+
+ static V arrmul(I n,const S *in,S *out,S mul);
+ inline V arrmul(I n,const S *in,S *out) const { arrmul(n,in,out,(S)(1./s2u)); }
- BL bufchk() { if(buf->Update()) { m_refresh(); return true; } return false; }
+ BL bufchk();
V mg_buffer(AtomList &l) { if(buf) { l(1); SetSymbol(l[0],buf->Symbol()); } else l(); }
inline V ms_buffer(const AtomList &l) { m_set(l.Count(),l.Atoms()); }
@@ -182,7 +187,7 @@ protected:
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 F s2u,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs)
+ #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
@@ -193,7 +198,7 @@ protected:
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 F s2u,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs)
+ 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
#ifdef TMPLOPT
@@ -212,7 +217,7 @@ protected:
#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 F s2u,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs)
+ #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
@@ -223,7 +228,7 @@ protected:
#define SETSTFUN(VAR,FUN) VAR = FUN
#define DEFSTCALL(NAME) \
- V (*NAME)(const S *bdt,const I smin,const I smax,const F s2u,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs)
+ 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
@@ -285,6 +290,7 @@ protected:
TMPLSTFUN(st_play4);
DEFSIGCALL(playfun);
+ DEFSIGCALL(zerofun);
virtual V s_dsp();
@@ -296,7 +302,7 @@ private:
};
#ifdef TMPLOPT
-#include "inter.ci"
+#include "inter.h"
#endif
#endif
diff --git a/externals/grill/xsample/source/play.cpp b/externals/grill/xsample/source/play.cpp
index 50f32e75..037bc1bb 100644
--- a/externals/grill/xsample/source/play.cpp
+++ b/externals/grill/xsample/source/play.cpp
@@ -32,11 +32,7 @@ public:
private:
static V setup(t_classid c);
- virtual V m_signal(I n,S *const *in,S *const *out)
- {
- bufchk();
- playfun(n,in,out);
- }
+ virtual V m_signal(I n,S *const *in,S *const *out);
};
FLEXT_LIB_DSP_V("xplay~",xplay)
@@ -91,7 +87,20 @@ BL xplay::Init()
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
+ zerofun(n,out,out);
+}
+
V xplay::m_help()
@@ -117,8 +126,8 @@ V xplay::m_help()
post("\tstop: stop playing");
post("\treset: checks buffer");
post("\trefresh: checks buffer and refreshes outlets");
- post("\tunits 0/1/2/3: set units to samples/buffer size/ms/s");
- post("\tinterp 0/1/2: set interpolation to off/4-point/linear");
+ 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("");
}
diff --git a/externals/grill/xsample/source/record.cpp b/externals/grill/xsample/source/record.cpp
index ce169e9a..d6b9e70e 100644
--- a/externals/grill/xsample/source/record.cpp
+++ b/externals/grill/xsample/source/record.cpp
@@ -69,8 +69,7 @@ private:
DEFSIGCALL(recfun);
virtual V m_signal(I n,S *const *in,S *const *out)
{
- bufchk();
- recfun(n,in,out);
+ if(bufchk()) recfun(n,in,out);
}
FLEXT_CALLVAR_F(mg_pos,m_pos)