Gamma  0.9.5
Generic Synthesis Library
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
/Users/ljp/code/gamma/trunk/Gamma/gen.h
00001 #ifndef GAMMA_GEN_H_INC
00002 #define GAMMA_GEN_H_INC
00003 
00004 /*  Gamma - Generic processing library
00005     See COPYRIGHT file for authors and license information
00006 
00007     File Description:
00008 
00009     Generator function objects
00010 
00011     A generator is a lightweight object that generates a sequence of elements.
00012     Generators have a standard interface specified by the Val class. The array
00013     access operator, [], is overloaded so generators can be treated like
00014     arrays. A const qualified generator only means that its generating function 
00015     parameters are held constant; its current value can change.
00016     A convention used is that generators' current value is the one most recently
00017     generated. This means one must be careful when initializing a generator so 
00018     that it generates the first element properly. Usually this means setting its
00019     value to what would have been the previously generated value. For instance, 
00020     to get the sequence 0,1,2,... from RAdd1, its value must be initialized to 
00021     -1. Constructors 'rewind' the generator, so that the initial value argument
00022     is returned on the next generate call.
00023 */
00024 
00025 #include "Gamma/scl.h"
00026 #include "Gamma/Constants.h"
00027 #include "Gamma/Types.h"
00028 
00029 namespace gam{
00030 
00032 namespace gen{
00033 
00035 template <class T=gam::real>
00036 struct Val{
00037     Val(): val(T(0)){}                                      
00038     Val(const T& v): val(v){}                               
00039     Val& operator = (const T& v){ val=v; return *this; }    
00040     T operator()() const { return val; }                    
00041     T& operator[](uint32_t i)      { return val; }          
00042     T  operator[](uint32_t i) const{ return (*this)(); }    
00043 
00044     template<class U> bool operator> (const U& v) const { return val> v; }
00045     template<class U> bool operator>=(const U& v) const { return val>=v; }
00046     template<class U> bool operator< (const U& v) const { return val< v; }
00047     template<class U> bool operator<=(const U& v) const { return val<=v; }
00048     
00049     mutable T val;                                          
00050     // Since this is a generator, we will allow its value to be modified if 
00051     // it's a const.
00052 };
00053 
00054 
00055 // This is needed since templates are not always smart about inheriting super members.
00056 #define INHERIT\
00057     using Val<T>::val; using Val<T>::operator=;\
00058     T   operator[](uint32_t i) const { return (*this)(); }
00059 
00060 template<class T=gam::real>
00061 struct Impulse : public Val<T>{ INHERIT;
00062     Impulse(const T& val=T(1)): Val<T>(val){}           
00063     T operator()() const {T t=val; val=0; return t;}    
00064 };
00065 
00067 template<class T=gam::real>
00068 struct Nyquist : public Val<T>{ INHERIT;
00069     Nyquist(const T& val=T(1)): Val<T>(-val){}          
00070     T operator()() const { return val = -val; }         
00071 };
00072 
00074 template <class T=gam::real>
00075 struct Recip : public Val<T>{ INHERIT;
00076     Recip(const T& val=T(1)): Val<T>(val){}             
00077     T operator()() const { return T(1)/val++; }         
00078 };
00079 
00080 
00082 template <class T=double>
00083 struct RCos : public Val<T>{ INHERIT;
00084 
00086     RCos(const T& frq=T(0), const T& amp=T(1))
00087     :   val2(0), c1(0){ set(frq,amp); }
00088 
00090     T operator()() const {
00091         T v0 = val*c1 - val2;
00092         val2 = val; val = v0;
00093         return val2;
00094     }
00095     
00096     T freq() const { return acos(c1*0.5) * M_1_2PI; }
00097     
00099     RCos& set(const T& frq, const T& amp=T(1)){
00100         c1  = T(cos(frq*M_2PI));
00101         val2= c1*amp;
00102         val = amp;
00103         c1 *= T(2);
00104         return *this;
00105     }
00106 
00107     mutable T val2;     
00108     T c1;               
00109 };
00110 
00111 
00112 // TODO: zero-overhead version of this with only delays and coef
00113 
00115 template <class T=double>
00116 struct RSin : public Val<T>{ INHERIT;
00117 
00119     RSin(const T& frq=T(0), const T& phs=T(0), const T& amp=T(1))
00120     :   val2(0), mul(0){ set(frq,phs,amp); }
00121 
00123     T operator()() const {
00124         T v0 = mul * val - val2;
00125         val2 = val;
00126         return val = v0;
00127     }
00128 
00130     T amp() const { return mAmp; }
00131 
00133     T freq() const { return mFreq; }
00134 
00136     T phase() const { return mPhase; }
00137 
00139     RSin& amp(const T& v){ return set(freq(), phase(), v); }
00140     
00142     RSin& freq(const T& v){ return set(v, phase(), amp()); }
00143 
00145     RSin& phase(const T& v){ return set(freq(), v, amp()); }
00146 
00148     RSin& reset(){ set(freq(), phase(), amp()); return *this; }
00149 
00151     RSin& set(const T& frq, const T& phs, const T& amp=T(1)){
00152 //      printf("%g %g %g\n", frq, phs, amp);
00153         mFreq = frq;
00154         mAmp = amp;
00155         mPhase = phs;
00156 
00157         T f=frq*M_2PI, p=phs*M_2PI;
00158         mul  = 2 * cos(f);
00159         val2 = sin(p - f * T(2))*amp;
00160         val  = sin(p - f       )*amp;
00161 //      printf("%g %g %g\n", freq(), phase(), this->amp());
00162         return *this;
00163     }
00164 
00165 // Note: these methods compute parameters directly from coefficients, but is buggy...
00166 //  /// Get amplitude
00167 //  T amp() const { T a,p; ampPhase(a,p); return a; }
00168 //  
00169 //  /// Get amplitude and unit phase
00170 //  void ampPhase(T& a, T& p) const {
00171 //      p = phase();
00172 //
00173 //      const T eps = 1e-8;
00174 //      if(p > eps && p < (1-eps) && scl::abs(p-0.5) > eps)
00175 //          a = val /sin(p * M_2PI);
00176 //      else
00177 //          a = val2/sin((p - freq())*M_2PI);
00178 //      return;
00179 //  }
00180 //
00181 //  /// Get unit frequency
00182 //  T freq() const { return acos(mul*0.5) * M_1_2PI; }
00183 //
00184 //  /// Get unit phase
00185 //  T phase() const {
00186 //      if(val == val2) return 0;
00187 //      T f = freq()*M_2PI;
00188 //      T y = val * sin(f);
00189 //      T x = val * cos(f) - val2;
00190 //      T r = atan2(y, x) * M_1_2PI;
00191 //      if(r < 0) r += 1;
00192 //      return r;
00193 //  }
00194 //
00195 //  /// Set amplitude
00196 //  RSin& amp(const T& v){ return set(freq(), phase(), v); }
00197 //  
00198 //  /// Set unit frequency
00199 //  RSin& freq(const T& v){ T a,p; ampPhase(a,p); return set(v,a,p); }
00200 //
00201 //  /// Set unit phase
00202 //  RSin& phase(const T& v){ return set(freq(), v, amp()); }
00203 
00204     mutable T val2;
00205     T mul;          
00206 
00207 protected:
00208     T mFreq, mAmp, mPhase;
00209 };
00210 
00211 
00212 template <class T=double>
00213 struct RSin2 : public Val<T>{ INHERIT;
00214 
00216     RSin2(const T& frq=T(0), const T& phs=T(0), const T& dcy=T(1), const T& amp=T(1))
00217     { set(frq,phs,dcy,amp); }
00218 
00220     T operator()() const {
00221         T v0 = mul1 * val + mul2 * val2;
00222         val2 = val;
00223         return val = v0;
00224     }
00225     
00227     T operator()(const T& v) const {
00228         T v0 = mul1 * val + mul2 * val2 + v;
00229         val2 = val;
00230         return val = v0;
00231     }
00232 
00234     T amp() const { return mAmp; }
00235 
00237     //T decay() const{ return mDecay; }
00238     T decay() const{ return sqrt(-mul2); }
00239 
00241     T freq() const { return mFreq; }
00242     //T freq() const { return acos(mul1*0.5/decay()) * M_1_2PI; }
00243 
00245     T phase() const { return mPhase; }
00246 
00247 
00249     RSin2& amp(const T& v){ return set(freq(), phase(), decay(), v); }
00250 
00252     RSin2& decay(const T& v){ return set(freq(), phase(), v, amp()); }
00253     
00255     RSin2& freq(const T& v){ return set(v, phase(), decay(), amp()); }
00256 
00258     RSin2& phase(const T& v){ return set(freq(), v, decay(), amp()); }
00259 
00261     RSin2& reset(){ set(freq(), phase(), decay(), amp()); return *this; }
00262 
00264     RSin2& set(T frq, T phs, T dcy, T amp=T(1)){
00265 //      printf("%g %g %g %g\n", frq, phs, dcy, amp);
00266         mFreq = frq;
00267         mAmp = amp;
00268         mPhase = phs;
00269         mDecay = dcy;
00270 
00271         frq *= M_2PI; phs *= M_2PI;
00272         //dcy = scl::atLeast(dcy, (T)0.00000001);
00273         
00274         mul1 = (T)2 * dcy * cos(frq);
00275         mul2 = -dcy*dcy;
00276         T rdcy = 1./dcy;
00277         val2 = (T)sin(phs - frq * (T)2) * amp * rdcy * rdcy;
00278         val  = (T)sin(phs - frq       ) * amp * rdcy;
00279 //      printf("%g %g %g %g\n", freq(), phase(), decay(), this->amp());
00280         return *this;
00281     }
00282 
00283     mutable T val2;
00284     T mul2, mul1;           
00285 
00286 protected:
00287     T mFreq, mAmp, mPhase, mDecay;
00288 };
00289 
00290 
00292 template <class T=gam::real>
00293 struct RAdd: public Val<T>{ INHERIT;
00294 
00297     RAdd(const T& add=T(1), const T& val=T(0))
00298     : Val<T>(val-add), add(add){}
00299     
00301     const T& operator()() const { return val += add; }
00302 
00304     const T& recede() const { return val -= add; }
00305 
00307     void line(T begin, T end, T length){
00308         val = begin;
00309         add = (end - begin)/length;
00310         recede();
00311     }
00312 
00314     void line(T end, T length){ line(val, end, length); }
00315 
00317     void constant(T v){ val=v; add=T(0); }
00318 
00319     T add;                                              
00320 };
00321 
00323 template <class T=gam::real>
00324 struct RAdd1: public Val<T>{ INHERIT;
00325     RAdd1(const T& val=T(0)): Val<T>(val-1){}           
00326     T operator()() const { return ++val; }              
00327 };
00328 
00330 template <int N=1, class T=gam::real>
00331 struct RAddN: public Val<T>{ INHERIT;
00332     RAddN(const T& val=T(0)): Val<T>(val-N){}           
00333     T operator()() const { return val+=N; }             
00334 };
00335 
00337 template <class T=gam::real>
00338 struct RAddWrap: public RAdd<T>{ INHERIT;
00339     RAddWrap(const T& add, const T& val=T(0), const T& max=T(1), const T& min=T(0))
00340     :   RAdd<T>(add, val), max(max), min(min){}         
00341     T operator()() const {                              
00342         RAdd<T>::operator()();
00343         return val=scl::wrap(val,max,min);
00344     } 
00345     T max, min;
00346 };
00347 
00349 template <class T=gam::real>
00350 struct RMul: public Val<T>{ INHERIT;
00351     RMul(const T& mul=T(1), const T& val=T(1))
00352     :   Val<T>(val/mul), mul(mul){}                     
00353     T operator()() const { return val *= mul; }         
00354     T mul;                                              
00355 };
00356 
00358 template <class T=gam::real>
00359 struct RMulAdd: public Val<T>{ INHERIT;
00361     RMulAdd(const T& mul=T(1), const T& add=T(0), const T& val=T(0))
00362     :   Val<T>((val-add)/mul), mul(mul), add(add){}     
00363     T operator()() const { return val=val*mul+add; }    
00364     T mul;                                              
00365     T add;                                              
00366 };
00367 
00369 template <class T=gam::real>
00370 struct Sin: public RAdd<T>{ INHERIT;
00371     Sin(const T& frq, const T& phs=T(0), const T& amp=T(1))
00372     :   RAdd<T>(frq, phs), amp(amp){}                   
00373 
00374     T operator()() const
00375     { return (T)sin(RAdd<T>::operator()()) * amp; }     
00376     T amp;
00377 };
00378 
00379 
00380 // Temp object functions
00381 // Note: we cannot use default arguments with two different template types
00382 //
00383 #define OF1(Ob, fu, a)\
00384 template<class T> inline Ob<T> fu(T v1=a){ return Ob<T>(v1); }
00385 
00386 //#define OF2(Ob, fu, a, b)
00387 //template<class T, class U> inline Ob<T> fu(T v1=a,U v2=b){ return Ob<T>(v1,v2); }
00388 
00389 #define OF2(Ob, fu, a, b)\
00390 template<class T> inline Ob<T> fu(T v1=a,T v2=b){ return Ob<T>(v1,v2); }
00391 
00392 #define OF3(Ob, fu, a, b, c)\
00393 template<class T> inline Ob<T> fu(T v1=a,T v2=b,T v3=c){ return Ob<T>(v1,v2,v3); }
00394 
00395 OF1(Val,        val,        0)
00396 OF1(Nyquist,    nyquist,    0)
00397 OF1(RAdd1,      rAdd1,      0)
00398 OF1(Recip,      recip,      1)
00399 
00400 OF2(RAdd,       rAdd,       1,0)
00401 OF2(RCos,       rCos,       0,1)
00402 OF2(RMul,       rMul,       1,1)
00403 
00404 OF3(RMulAdd,    rMulAdd,    1,0,0)
00405 OF3(RSin,       rSin,       0,0,1)
00406 
00407 #undef OF1
00408 #undef OF2
00409 #undef OF3
00410 #undef INHERIT
00411 
00412 
00413 
00415 
00419 template <class T=double>
00420 class CReson : public Complex<T>{
00421 public:
00422     typedef Complex<T> C;
00423     using C::operator();
00424     using C::operator=;
00425 
00430     CReson(const T& frq=T(0), const T& amp=T(1), const T& phs=T(0), const T& dec=T(1)){
00431         set(frq, amp, phs);
00432     }
00433 
00435     const C& operator()(){ return (*this)*=mFactor; }
00436 
00438     const C& operator()(const C& v){ return (*this) = (*this)*mFactor + v; }
00439     const C& operator()(const T& v){ return (*this) = (*this)*mFactor + v; }
00440     
00442     const C& recede(){ return (*this)/=mFactor; }
00443 
00445     void amp(const T& v){ (*this).fromPolar(v, this->arg()); }
00446     
00448     void decay(const T& target, const T& N=T(1)){
00449         // NOTE: this handles negative decays, thought better to leave this to frequency component
00450         //factor(freq(), (1==N) ? target : (::pow(scl::abs(target), 1./N)*scl::sgn(target)));
00451         factor(freq(), (1==N) ? target : (::pow(scl::abs(target), 1./N)));
00452     }
00453 
00455     void factor(const T& frq, const T& dec=T(1)){
00456         mFactor.fromPolar(dec, frq*M_2PI);
00457     }
00458     
00459     void factor(const Complex<T>& v){ mFactor=v; }
00460 
00462     void freq(const T& v){ factor(v, decay()); }
00463 
00465     
00468     void set(const T& frq, const T& amp, const T& phs, const T& dec=T(1)){
00469         this->fromPolar(amp, phs*M_2PI);
00470         factor(frq, dec);
00471         recede();
00472     }
00473 
00474     void set(const T& frq, const Complex<T>& phs){
00475         (*this)(phs.r, phs.i); freq(frq);
00476     }
00477 
00479     C ahead() const { return (*this)*mFactor; }
00480     
00482     C behind() const { return (*this)/mFactor; }
00483 
00485     T decay() const { return mFactor.mag(); }
00486     
00488     T freq() const { return mFactor.phase()*M_1_2PI; }
00489 
00490     const C& factor() const { return mFactor; }
00491     C& factor(){ return mFactor; }
00492 
00493 protected:
00494     C mFactor;
00495     
00496     // Set 60 dB decay interval
00497     //void decay(const Tv& v){ width(T(2.198806796637603 /* -ln(0.001)/pi */)/v); }
00498     
00499     // Set unit bandwidth
00500     //void width(const Tv& v){ mDecay=::exp(-M_PI*v); freq(freq()); }
00501 };
00502 
00503 typedef CReson<float>   CResonf;
00504 typedef CReson<double>  CResond;
00505 
00506 
00507 
00508 struct OnOff{
00509     OnOff(uint32_t max, uint32_t ons) : max(max), ons(ons), cnt(0){}
00510     
00511     bool operator()(){
00512         cnt++;
00513         if(cnt <= ons) return true;
00514         if(cnt >= max) cnt = 0;
00515         return ons >= max;
00516     }
00517     
00518     void set(uint32_t max, uint32_t ons, uint32_t cnt){
00519         this->max = max; this->ons = ons; this->cnt = cnt;
00520     }
00521     
00522     uint32_t max, ons, cnt;
00523 };
00524 
00525 
00526 struct OneOff{
00527     OneOff(bool v=true): mVal(v) {}
00528     bool operator()(){ bool r=mVal; mVal=false; return r; }
00529     void set(){ mVal=true; }
00530     
00531 private:
00532     bool mVal;
00533 };
00534 
00535 
00537 template <uint32_t N, class T=gam::real, class G=gen::RAdd1<uint32_t> >
00538 class Seq: public Multi<N,T>{
00539 public:
00540 
00541     Seq(const T& val){ for(int i=0; i<N; ++i){ this->elems[i]=val; } }
00542     Seq(const T * vals){ for(int i=0; i<N; ++i){ this->elems[i]=vals[i]; } }
00543 
00545     T operator()(){ return (*this)[((uint32_t)mTap())%N]; }
00546 
00548     G& tap(){ return mTap; }
00549     
00550 private:
00551     G mTap;
00552 };
00553 
00554 
00556 struct Trigger{
00557     Trigger(uint32_t num, uint32_t val=0) : val(val), num(num){}
00558     
00560     bool operator()(){
00561         if(++val >= num){ val = 0; return true; }
00562         return false;
00563     }
00564     uint32_t val;       
00565     uint32_t num;       
00566 };
00567 
00568 
00569 } // gen::
00570 } // gam::
00571 
00572 #endif