aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/vasp/source/ops_gen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'externals/grill/vasp/source/ops_gen.cpp')
-rw-r--r--externals/grill/vasp/source/ops_gen.cpp265
1 files changed, 265 insertions, 0 deletions
diff --git a/externals/grill/vasp/source/ops_gen.cpp b/externals/grill/vasp/source/ops_gen.cpp
new file mode 100644
index 00000000..eec81701
--- /dev/null
+++ b/externals/grill/vasp/source/ops_gen.cpp
@@ -0,0 +1,265 @@
+/*
+
+VASP modular - vector assembling signal processor / objects for Max/MSP and PD
+
+Copyright (c) 2002 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.
+
+*/
+
+#include "ops_gen.h"
+#include "util.h"
+#include <math.h>
+
+// --- osc ---------------------------------------
+
+/*! \brief Generator for real (cos) oscillations
+*/
+BL VecOp::d_osc(OpParam &p)
+{
+ register R ph = p.gen.ph,phinc = p.gen.phinc;
+ if(p.revdir) ph -= (p.frames-1)*(phinc = -phinc);
+
+ for(I i = 0; i < p.frames; ++i,ph += phinc,p.rddt += p.rds) *p.rddt = cos(ph);
+ return true;
+}
+
+/*! \brief multiplicative generator for real (cos) oscillations
+*/
+BL VecOp::d_mosc(OpParam &p)
+{
+ register R ph = p.gen.ph,phinc = p.gen.phinc;
+ if(p.revdir) ph -= (p.frames-1)*(phinc = -phinc);
+
+ for(I i = 0; i < p.frames; ++i,ph += phinc,p.rsdt += p.rss,p.rddt += p.rds)
+ *p.rddt = *p.rsdt * cos(ph);
+ return true;
+}
+
+/*! \brief Generator for real (cos) oscillations.
+
+ \param arg argument list
+ \param arg.perlen Period length (in samples)
+ \param arg.stph Starting phase
+ \param mul true for multiplication to exisiting date
+ \return normalized destination vasp
+
+ \todo Replace period length by frequency specification
+*/
+Vasp *VaspOp::m_osc(OpParam &p,Vasp &src,const Argument &arg,Vasp *dst,BL mul)
+{
+ Vasp *ret = NULL;
+ if(arg.IsList() && arg.GetList().Count() >= 1) {
+ RVecBlock *vecs = GetRVecs(p.opname,src,dst);
+ if(vecs) {
+ // period length
+ p.gen.phinc = 2*PI/flext::GetAFloat(arg.GetList()[0]);
+ // starting phase
+ p.gen.ph = arg.GetList().Count() >= 2?flext::GetAFloat(arg.GetList()[1]):0;
+
+ ret = DoOp(vecs,mul?VecOp::d_mosc:VecOp::d_osc,p);
+ delete vecs;
+ }
+ }
+ else
+ post("%s - no arguments: no operation",p.opName());
+
+ return ret;
+}
+
+
+/*! \brief Generator for complex oscillations.
+*/
+BL VecOp::d_cosc(OpParam &p)
+{
+ register R ph = p.gen.ph,phinc = p.gen.phinc;
+ if(p.revdir) ph -= (p.frames-1)*(phinc = -phinc);
+
+ for(; p.frames--; ph += phinc,p.rddt += p.rds,p.iddt += p.ids)
+ *p.rddt = cos(ph),*p.iddt = sin(ph);
+ return true;
+}
+
+/*! \brief Multiplicative generator for complex oscillations.
+*/
+BL VecOp::d_mcosc(OpParam &p)
+{
+ register R ph = p.gen.ph,phinc = p.gen.phinc;
+ if(p.revdir) ph -= (p.frames-1)*(phinc = -phinc);
+
+ for(; p.frames--; ph += phinc,p.rsdt += p.rss,p.isdt += p.iss,p.rddt += p.rds,p.iddt += p.ids) {
+ R zre = cos(ph),zim = sin(ph);
+
+ register const R r = *p.rsdt * zre - *p.isdt * zim;
+ *p.iddt = *p.isdt * zre + *p.rsdt * zim;
+ *p.rddt = r;
+ }
+ return true;
+}
+
+/*! \brief Generator for complex (cos+i sin) oscillations.
+
+ \param arg argument list
+ \param arg.perlen Period length (in samples)
+ \param arg.stph Starting phase
+ \param mul true for multiplication to exisiting date
+ \return normalized destination vasp
+
+ \todo Replace period length by frequency specification
+*/
+Vasp *VaspOp::m_cosc(OpParam &p,Vasp &src,const Argument &arg,Vasp *dst,BL mul)
+{
+ Vasp *ret = NULL;
+ if(arg.IsList() && arg.GetList().Count() >= 1) {
+ CVecBlock *vecs = GetCVecs(p.opname,src,dst);
+ if(vecs) {
+ // period length
+ p.gen.phinc = 2*PI/flext::GetAFloat(arg.GetList()[0]);
+ // starting phase
+ p.gen.ph = arg.GetList().Count() >= 2?flext::GetAFloat(arg.GetList()[1]):0;
+
+ ret = DoOp(vecs,mul?VecOp::d_mcosc:VecOp::d_cosc,p);
+ delete vecs;
+ }
+ }
+ else
+ post("%s - no arguments: no operation",p.opName());
+
+ return ret;
+}
+
+
+VASP_ANYOP("vasp.osc",osc,1,false,VASP_ARG(),"Calculates a cosine wave")
+VASP_ANYOP("vasp.*osc",mosc,1,true,VASP_ARG(),"Multiplies with a cosine wave")
+VASP_ANYOP("vasp.cosc",cosc,1,false,VASP_ARG(),"Calculates a complex oscillation (cos + i sin)")
+VASP_ANYOP("vasp.*cosc",mcosc,1,true,VASP_ARG(),"Multiplies with a complex oscillation (cos + i sin)")
+
+// --- phasor ---------------------------------------
+
+// ! look up Höldrich's pd phasor code
+
+/*! \brief Generator for saw wave oscillations.
+*/
+BL VecOp::d_phasor(OpParam &p)
+{
+ register R ph = p.gen.ph,phinc = p.gen.phinc;
+ if(p.revdir) ph -= (p.frames-1)*(phinc = -phinc);
+
+ for(; p.frames--; ph += phinc,p.rddt += p.rds) *p.rddt = fmod(ph,1.F);
+ return true;
+}
+
+/*! \brief Multiplicative generator for saw wave oscillations.
+*/
+BL VecOp::d_mphasor(OpParam &p)
+{
+ register R ph = p.gen.ph,phinc = p.gen.phinc;
+ if(p.revdir) ph -= (p.frames-1)*(phinc = -phinc);
+
+ for(; p.frames--; ph += phinc,p.rddt += p.rds,p.rsdt += p.rss) *p.rddt = *p.rsdt * fmod(ph,1.F);
+ return true;
+}
+
+/*! \brief Generator for sawtooth oscillations.
+
+ \param arg argument list
+ \param arg.perlen Period length (in samples)
+ \param arg.stph Starting phase
+ \param mul true for multiplication to exisiting date
+ \return normalized destination vasp
+
+ \todo Replace period length by frequency specification
+*/
+Vasp *VaspOp::m_phasor(OpParam &p,Vasp &src,const Argument &arg,Vasp *dst,BL mul)
+{
+ Vasp *ret = NULL;
+ if(arg.IsList() && arg.GetList().Count() >= 1) {
+ RVecBlock *vecs = GetRVecs(p.opname,src,dst);
+ if(vecs) {
+ // period length
+ p.gen.phinc = 1./flext::GetAFloat(arg.GetList()[0]);
+ // starting phase
+ p.gen.ph = arg.GetList().Count() >= 2?flext::GetAFloat(arg.GetList()[1]):0;
+
+ ret = DoOp(vecs,mul?VecOp::d_mphasor:VecOp::d_phasor,p);
+ delete vecs;
+ }
+ }
+ else
+ post("%s - no arguments: no operation",p.opName());
+
+ return ret;
+}
+
+
+VASP_ANYOP("vasp.phasor",phasor,1,false,VASP_ARG(),"Calculates a sawtooth wave")
+VASP_ANYOP("vasp.*phasor",mphasor,1,true,VASP_ARG(),"Multiplies with a sawtooth wave")
+
+// --- noise --------------------------------
+
+static F rnd()
+{
+ static I val = 307*1319;
+ F ret = ((F)((val&0x7fffffff)-0x40000000))*(F)(1.0/0x40000000);
+ val = val * 435898247 + 382842987;
+ return ret;
+}
+
+/*! \brief Vector function for pseudorandom noise.
+*/
+BL VecOp::d_noise(OpParam &p)
+{
+ for(; p.frames--; p.rddt += p.rds) *p.rddt = rnd();
+ return true;
+}
+
+
+/*! \brief Generator for real valued noise.
+
+ \return normalized destination vasp
+*/
+Vasp *VaspOp::m_noise(OpParam &p,Vasp &src,Vasp *dst)
+{
+ Vasp *ret = NULL;
+ RVecBlock *vecs = GetRVecs(p.opname,src,dst);
+ if(vecs) {
+ ret = DoOp(vecs,VecOp::d_noise,p);
+ delete vecs;
+ }
+ return ret;
+}
+
+/*! \brief Vector function for pseudorandom complex noise.
+*/
+BL VecOp::d_cnoise(OpParam &p)
+{
+ for(; p.frames--; p.rddt += p.rds,p.iddt += p.ids) {
+ R amp = rnd();
+ R arg = rnd()*(2.*PI);
+ *p.rddt = amp*cos(arg);
+ *p.iddt = amp*sin(arg);
+ }
+ return true;
+}
+
+/*! \brief Generator for complex noise (complex abs, complex arg).
+
+ \return normalized destination vasp
+
+ \todo Replace period length by frequency specification
+*/
+Vasp *VaspOp::m_cnoise(OpParam &p,Vasp &src,Vasp *dst)
+{
+ Vasp *ret = NULL;
+ CVecBlock *vecs = GetCVecs(p.opname,src,dst);
+ if(vecs) {
+ ret = DoOp(vecs,VecOp::d_cnoise,p);
+ delete vecs;
+ }
+ return ret;
+}
+
+VASP_UNARY("vasp.noise",noise,false,"Fills the vectors with white noise")
+VASP_UNARY("vasp.cnoise",cnoise,false,"Fills the vectors with complex white noise (radius and angle are random)")
+