Gamma  0.9.5
Generic Synthesis Library
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
/Users/ljp/code/gamma/trunk/Gamma/Oscillator.h
00001 #ifndef GAMMA_OSCILLATOR_H_INC
00002 #define GAMMA_OSCILLATOR_H_INC
00003 
00004 /*  Gamma - Generic processing library
00005     See COPYRIGHT file for authors and license information */
00006 
00007 #include "Gamma/gen.h"
00008 #include "Gamma/scl.h"
00009 #include "Gamma/tbl.h"
00010 #include "Gamma/Strategy.h"
00011 #include "Gamma/Sync.h"
00012 #include "Gamma/Types.h"
00013 
00014 namespace gam{
00015 
00016 
00018 
00026 template <class Stap=tap::Wrap, class Ts=Synced>
00027 class Accum : public Ts {
00028 public:
00029 
00032     Accum(float frq=0, float phs=0);
00033 
00034 
00035     void freq(float v);             
00036     void phase(float v);            
00037     void phaseMax();                
00038     void phaseAdd(float v);         
00039     void period(float v);           
00040     void reset(){ mPhaseI=0; mTap.reset(); }    
00041     Stap& tap(){ return mTap; }
00042 
00044     bool done() const { return mTap.done(phaseI()); }
00045 
00046     float freq() const;             
00047     uint32_t freqI() const;         
00048     float freqUnit() const;         
00049     float phase() const;            
00050     uint32_t phaseI() const;        
00051 
00053     
00056     uint32_t cycle();
00057     uint32_t operator()();          
00058 
00059     uint32_t nextPhase();           
00060     uint32_t nextPhase(float freqOffset);
00061     uint32_t nextPhasePost();       
00062     uint32_t cycles();              
00063     uint32_t once();
00064 
00065     virtual void onResync(double r);
00066 
00067 protected:
00068     float mFreq;        // Current frequency
00069     uint32_t mPhaseI;   // Current fixed-point phase in [0, 2^32)
00070     uint32_t mFreqI;    // Current fixed-point frequency
00071     Stap mTap;
00072     
00073     uint32_t mapFI(float v) const;  // convert unit floating-point to fixed-point integer
00074     float mapIF(uint32_t v) const;  // convert fixed-point integer to unit floating-point
00075     uint32_t mapFreq(float v) const;
00076 };
00077 
00078 #define ACCUM_INHERIT\
00079     using Accum<Stap,Ts>::phaseI;\
00080     using Accum<Stap,Ts>::freqI;\
00081     using Accum<Stap,Ts>::nextPhase;\
00082     using Accum<Stap,Ts>::nextPhasePost;
00083 
00084 
00085 
00087 template <class Stap=tap::Wrap, class Ts=Synced>
00088 class Sweep : public Accum<Stap, Ts> {
00089 public:
00092     Sweep(float frq=440, float phs=0): Base(frq, phs){}
00093 
00094     float operator()(){ Base::cycle(); return Base::phase(); }
00095 
00096 private: typedef Accum<Stap,Ts> Base;
00097 };
00098 
00099 
00100 
00102 template <class Tv=gam::real, class Ts=Synced>
00103 class AccumPhase : public Ts{
00104 public:
00107     AccumPhase(Tv frq=440, Tv phs=0);
00108 
00109     
00111     Tv nextPhase();
00112     
00114     Tv nextPhase(Tv frqOffset);
00115 
00116     void freq(Tv v);        
00117     void period(Tv v);      
00118     void phase(Tv v);       
00119     void phaseAdd(Tv v);    
00120     
00121     Tv freq();              
00122     Tv period();            
00123     Tv phase();             
00124     
00125     virtual void onResync(double r);
00126     void print(const char * append = "\n", FILE * fp = stdout);
00127     
00128 protected:
00129     Tv mFreq, mPhase;
00130     Tv m2PiUPS;
00131     void recache();
00132     Tv mapFreq(Tv v) const;
00133     Tv mapPhase(Tv v) const;
00134     Tv nextPhaseUsing(Tv frq);
00135 };
00136 
00137 
00138 
00140 
00151 template <class Tv=gam::real, template<class> class Sipol=ipl::Linear, class Stap=tap::Wrap, class Ts=Synced>
00152 class Osc : public Accum<Stap,Ts>, public ArrayPow2<Tv>{
00153 public:
00154 
00156 
00160     Osc(float frq=440, float phs=0, uint32_t size=512)
00161     :   Base(frq, phs), ArrayPow2<Tv>(size)
00162     {}
00163 
00165 
00169     Osc(float frq, float phs, ArrayPow2<Tv>& src)
00170     :   Base(frq, phs), ArrayPow2<Tv>(src.elems(), src.size())
00171     {}
00172 
00173 
00175     Tv operator()(){
00176         Tv r = val(); this->nextPhasePost(); return r;
00177     }
00178 
00180     Tv val() const { return mIpol(*this, phaseI()); }
00181     
00183     
00187     Osc& addSine(double cycles, double amp=1, double phs=0){
00188         double f = cycles/this->size();
00189         for(unsigned i=0; i<this->size(); ++i){
00190             double p = (f*i + phs)*M_2PI;
00191             (*this)[i] += sin(p) * amp;
00192         }
00193         return *this;
00194     }
00195 
00197     void zero(){ for(unsigned i=0; i<this->size(); ++i) (*this)[i] = Tv(0); }
00198 
00199     ArrayPow2<Tv>& table(){ return *this; }
00200 
00201 //  using ArrayPow2<Tv>::elems; using ArrayPow2<Tv>::size;
00202 protected:
00203     Sipol<Tv> mIpol;
00204 private:
00205     ACCUM_INHERIT
00206     typedef Accum<Stap,Ts> Base;
00207 };
00208 
00209 
00210 
00212 
00222 template<class Tv=gam::real, class Ts=Synced>
00223 class CSine : public Ts{
00224 public:
00225 
00226     typedef Complex<Tv> complex;
00227 
00232     CSine(Tv frq=440, Tv amp=1, Tv dcy=-1, Tv phs=0);
00233 
00234 
00235     complex val;            
00236     
00237     void amp(Tv val);       
00238     void decay(Tv val);     
00239     void freq(Tv val);      
00240     void freq(const complex& val){ mInc=val; }
00241     void phase(Tv radians); 
00242     void reset();           
00243     void set(Tv frq, Tv phs, Tv amp, Tv dcy);
00244 
00245     complex operator()();   
00246     Tv freq();              
00247 
00248     virtual void onResync(double r);
00249 
00250 protected:
00251     Tv mAmp, mFreq, mDcy60;
00252     Tv mDcy;                // phasor amp
00253     complex mInc;       // rotation increment
00254 };
00255 
00256 
00257 
00259 
00264 template<class Tv=gam::real, class Ts=Synced>
00265 class Sine : public AccumPhase<Tv,Ts> {
00266 public:
00269     Sine(Tv frq=440, Tv phs=0) : AccumPhase<Tv,Ts>(frq, phs){}
00270     
00272     Tv operator()(Tv frqOffset = Tv(0)){
00273         return scl::sinP9(this->nextPhase(frqOffset) * M_1_PI);
00274     }
00275 };
00276 
00277 
00278 
00280 
00287 template <class Tv=double, class Ts=Synced>
00288 class SineR : public gen::RSin<Tv>, Ts{
00289 public:
00290 
00294     SineR(Tv frq=440, Tv amp=1, Tv phs=0){ set(frq, amp, phs); }
00295 
00297     Tv freq() const { return Base::freq() * Ts::spu(); }
00298 
00300     void ampPhase(Tv a=1, Tv p=0){ set(freq(), a, p); }
00301 
00302     void freq(const Tv& v){ Base::freq(v*Ts::ups()); }
00303 
00305     void set(Tv frq, Tv amp, Tv phs=0){ Base::set(frq*Ts::ups(), phs, amp); }
00306 
00307 
00308     virtual void onResync(double ratio){ Base::freq(Base::freq()/ratio); }
00309 
00310 private:
00311     typedef gen::RSin<Tv> Base;
00312 };
00313 
00314 
00315 
00317 
00321 template <class Tv=double, class Ts=Synced>
00322 class SineRs : public Array<SineR<Tv, Synced1> >, Ts{
00323 public:
00324 
00326     SineRs(uint32_t num): Base(num){ Ts::initSynced(); }
00327 
00329     Tv operator()(){
00330         Tv r= Tv(0);
00331         for(uint32_t j=0; j<this->size(); ++j) r+=(*this)[j]();
00332         return r;
00333     }
00334 
00336     Tv last(uint32_t i) const { return (*this)[i].val; }
00337 
00339     void set(uint32_t i, Tv frq, Tv amp=1, Tv phs=0){
00340         (*this)[i].set(frq*Ts::ups(), amp, phs); }
00341 
00342 private:
00343     typedef Array<SineR<Tv, Synced1> > Base;
00344 };
00345 
00346 
00347 
00349 
00352 template <class Tv=double, class Ts=Synced>
00353 class SineD : public gen::RSin2<Tv>, Ts{
00354 public:
00355 
00360     SineD(Tv frq=440, Tv amp=1, Tv dcy=-1, Tv phs=0){ set(frq, amp, dcy, phs); }
00361 
00363     Tv freq() const { return Base::freq() * Ts::spu(); }
00364 
00366     void ampPhase(Tv a=1, Tv p=0){ set(freq(), a, Base::decay(), p); }
00367     
00369     void set(Tv frq, Tv amp, Tv dcy, Tv phs=0){
00370         Base::set(frq*Ts::ups(), phs, dcy > Tv(0) ? (Tv)scl::radius60(dcy, Ts::ups()) : Tv(1), amp);
00371     }
00372 
00373     virtual void onResync(double ratio){
00374         Base::freq(Base::freq()/ratio);
00375         //printf("%g\n", Base::decay());
00376         //printf("%g %g %g\n", Base::decay(), ratio, ::pow(Base::decay(), 1./ratio));
00377         // double radius60(double dcy, double ups){ return ::exp(M_LN001/dcy * ups); }
00378         //      same as (0.001)^(ups/dcy)
00379         Base::decay(::pow(Base::decay(), 1./ratio));
00380     }
00381 
00382 private:
00383     typedef gen::RSin2<Tv> Base;
00384 };
00385 
00386 
00387 
00389 
00393 template <class Tv=double, class Ts=Synced>
00394 class SineDs : public Array<SineD<Tv, Synced1> >, Ts{
00395 public:
00396 
00398     SineDs(uint32_t num): Base(num){
00399         Ts::initSynced(); 
00400         for(uint32_t i=0; i<num; ++i) set(i, 0,0,0);
00401     }
00402 
00404     Tv operator()(){
00405         Tv r=Tv(0);
00406         for(uint32_t j=0; j<this->size(); ++j) r+=(*this)[j]();
00407         return r;
00408     }
00409 
00411     Tv last(uint32_t i) const { return (*this)[i].val; }
00412 
00414     void set(uint32_t i, Tv frq, Tv amp, Tv dcy, Tv phs=0){
00415         (*this)[i].set(frq*Ts::ups(), amp, dcy*Ts::spu(), phs); }
00416 
00417 private:
00418     typedef Array<SineD<Tv, Synced1> > Base;
00419 };
00420 
00421 
00422 
00424 
00431 template <class Stap=tap::Wrap, class Ts=Synced>
00432 class TableSine : public Accum<Stap,Ts> {
00433 public:
00434 
00437     TableSine(float frq=440, float phase=0);
00438 
00439     float operator()(float freqOffset=0);   
00440     float nextN(float freqOffset=0);        
00441     float nextL(float freqOffset=0);        
00442 
00444     
00451     static void resize(uint32_t bits);
00452 
00453 protected:
00454 //  static ArrayPow2<float> cTable; // can't use because need 2**N+1 table
00455     static float * cTable;      // Reference to my sample table. Must be 1<<bits.
00456     static uint32_t cTblBits;
00457     static uint32_t cFracBits;  // # of bits in fractional part of accumulator
00458     static uint32_t cOneIndex;
00459 private:
00460     typedef Accum<Stap,Ts> Base;
00461     ACCUM_INHERIT
00462 };
00463 
00464 
00465 
00466 
00468 
00471 template <class Stap=tap::Wrap, class Ts=Synced>
00472 class LFO : public Accum<Stap,Ts>{
00473 public:
00474 
00475     LFO();
00476     
00480     LFO(float frq, float phase=0, float mod=0.5);
00481 
00482     uint32_t modi;          
00483 
00485     LFO& set(float f, float p, float m);
00486 
00487     LFO& mod(double n); 
00488 
00489 
00490     float cos();        
00491     float down();       
00492     float even3();      
00493     float even5();      
00494     float imp();        
00495     float line2();      
00496     float para();       
00497     float pulse();      
00498     float sinPara();    
00499     float stair();      
00500     float sqr();        
00501     float tri();        
00502     float up();         
00503     float up2();        
00504 
00505     float cosU();       
00506     float downU();      
00507     float hann();       
00508     float line2U();     
00509     float paraU();      
00510     float pulseU();     
00511     float stairU();     
00512     float sqrU();       
00513     float triU();       
00514     float upU();        
00515     float up2U();       
00516 
00517     float patU();
00518     float patU(uint32_t mul);
00519     float sineT9();
00520     float sineP9();
00521 
00522     bool seq();         // Returns 'mod' as sequence of triggers
00523 
00524     ACCUM_INHERIT
00525 private:
00526     typedef Accum<Stap,Ts> Base;
00527 };
00528 
00529 
00530 
00532 
00538 template<class Tv=gam::real, class Ts=Synced>
00539 class Buzz : public AccumPhase<Tv,Ts> {
00540 public:
00541 
00545     Buzz(Tv frq=440, Tv phase=0, Tv harmonics=8);
00546     virtual ~Buzz(){}
00547 
00548     void antialias();           
00549     void harmonics(Tv num);     
00550     void harmonicsMax();        
00551 
00552     Tv operator()();            
00553     Tv odd();                   
00554     Tv saw(Tv intg=0.997);      
00555     Tv square(Tv intg=0.997);   
00556     
00557     Tv maxHarmonics();          
00558 
00559     virtual void onResync(double r);
00560 
00561 protected:
00562     Tv mAmp;            // amplitude normalization factor
00563     Tv mN;              // # harmonics
00564     Tv mNDesired;       // desired number of harmonics
00565     Tv mNFrac;      
00566     Tv mSPU_2;          // cached locals
00567     Tv mPrev;           // previous output for integration
00568     void setAmp();
00569 private: typedef AccumPhase<Tv,Ts> Base;
00570 };
00571 
00572 
00573 
00575 
00581 template <class Tv=gam::real, class Ts=Synced>
00582 struct Impulse : public Buzz<Tv,Ts>{
00583 
00584 private: typedef Buzz<Tv,Ts> Base;
00585 
00586 public:
00587     using Base::freq;
00588 
00591     Impulse(Tv frq=440, Tv phs=0): Base(frq, phs){ onResync(1); }
00592 
00594     void freq(Tv v){ Base::freq(v); Base::harmonicsMax(); }
00595 
00596     virtual void onResync(double r){ Base::onResync(r); freq(AccumPhase<Tv, Ts>::freq()); }
00597 };
00598 
00599 
00600 
00602 
00608 template <class Tv=gam::real, class Ts=Synced>
00609 struct Saw : public Impulse<Tv,Ts> {
00610 
00613     Saw(Tv frq=440, Tv phs=0): Impulse<Tv, Ts>(frq, phs){}
00614 
00616     
00619     Tv operator()(Tv intg=0.997){ return Impulse<Tv,Ts>::saw(intg); }
00620 };
00621 
00622 
00623 
00625 
00631 template <class Tv=gam::real, class Ts=Synced>
00632 struct Square : public Impulse<Tv,Ts> {
00633 
00636     Square(Tv frq=440, Tv phs=0) : Impulse<Tv,Ts>(frq, phs){}
00637 
00639     
00642     Tv operator()(Tv intg=0.997){ return Impulse<Tv,Ts>::square(intg); }
00643 };
00644 
00645 
00646 
00648 
00654 template<class Tv=gam::real, class Ts=Synced>
00655 class DSF : public AccumPhase<Tv,Ts> {
00656 public:
00657 
00662     DSF(Tv frq=440, Tv freqRatio=1, Tv ampRatio=0.5, Tv harmonics=8);
00663     
00664     Tv operator()();            
00665     
00666     void ampRatio(Tv v);        
00667     void antialias();           
00668     void freq(Tv v);            
00669     void freqRatio(Tv v);       
00670     void harmonics(Tv v);       
00671     void harmonicsMax();        
00672 
00673     Tv ampRatio();              
00674     Tv freqRatio();             
00675     Tv harmonics();             
00676     Tv maxHarmonics();          
00677     
00678     virtual void onResync(double r);
00679 
00680 protected:
00681     typedef AccumPhase<Tv,Ts> Base;
00682 
00683     Tv mN, mNDesired;       // actual and desired # harmonics
00684     Tv mFreqRatio;          // frequency ratio
00685     Tv mA;                  // Partial amplitude ratio
00686     Tv mBeta, mBetaInc;     // "detune" accumulator
00687     Tv mAPow, mASqP1;       // cached vars
00688     
00689     void updateAPow();
00690     void updateBetaInc();
00691 };
00692 
00693 
00694 
00695 // Simple band-limited impulse generator
00696 
00697 // This uses a fast, simplified formula for generating a band-limited impulse,
00698 // but only operates at integer divisions of the Nyquist frequency.
00699 class ImpulseFast : public Synced {
00700 public:
00701     ImpulseFast(): mPhase(0), mOffset(0){ freq(0); }
00702 
00703 
00705     void freq(double v){
00706         double samples = spu() / v;
00707         
00708         uint32_t period = (uint32_t)(samples);
00709         //period &= 0xfffffffe;     // force period to be even
00710                                     // odd periods introduce DC
00711 
00712         mPeriod = (double)period;
00713         
00714         if(scl::even(period))   mOffset = 0.;
00715         //else                  mOffset = 0.5f / mPeriod;
00716     }
00717 
00718 
00720     float operator()(){
00721         float v = 0.f;
00722 
00723         if(mPhase >= mPeriod){
00724             mPhase -= mPeriod;
00725             v = 1.f;
00726         }
00727         else if(scl::even((uint32_t)mPhase)){
00728             v = -1.f/(mPeriod * 0.5f - 1.f);
00729         }
00730         
00731         ++mPhase;
00732         return v + mOffset;
00733     }
00734     
00735 protected:
00736     double mPhase;      // phase in samples
00737     double mPeriod;     // period in samples;
00738     float mOffset;      // DC compensation
00739 };
00740 
00741 
00742 
00743 // Implementation_______________________________________________________________
00744 
00745 #define TEM template<class Tv, class Ts>
00746 #define TEMS template<class Ts>
00747 #define TEMTS template<class St, class Ts>
00748 
00749 //---- Accum
00750 #define TACCUM  Accum<St,Ts>
00751 
00752 TEMTS TACCUM::Accum(float f, float p): mFreq(f){
00753     Ts::initSynced();
00754     (p >= 1.f) ? phaseMax() : this->phase(p);
00755     //printf("%u\n", mPhaseI);
00756 }
00757 
00758 TEMTS inline uint32_t TACCUM::mapFI(float v) const {
00759     //return scl::unitToUInt(v);
00760     //return (uint32_t)(v * 4294967296.);
00761     return castIntRound(v * 4294967296.);
00762 }
00763 
00764 TEMTS inline float TACCUM::mapIF(uint32_t v) const {
00765     //return v/4294967296.;
00766     return uintToUnit<float>(v);
00767 }
00768 
00769 TEMTS inline uint32_t TACCUM::mapFreq(float v) const {
00770     return mapFI(v * Ts::ups());
00771 }
00772 
00773 TEMTS void TACCUM::onResync(double r){ //printf("Accum: onSyncChange (%p)\n", this);
00774     freq(mFreq);
00775 }
00776 
00777 TEMTS inline void TACCUM::freq(float v){
00778     mFreq  = v;
00779     mFreqI = mapFreq(v);
00780 }
00781 
00782 TEMTS inline void TACCUM::period(float v){ freq(1.f/v); }
00783 TEMTS inline void TACCUM::phase(float v){ mPhaseI = mapFI(v); }
00784 TEMTS inline void TACCUM::phaseAdd(float v){ mTap(mPhaseI, mapFI(v)); }
00785 TEMTS inline void TACCUM::phaseMax(){ mPhaseI = 0xffffffff; }
00786 
00787 TEMTS inline float TACCUM::freq() const { return mFreq; }
00788 TEMTS inline uint32_t TACCUM::freqI() const { return mFreqI; }
00789 TEMTS inline float TACCUM::freqUnit() const { return mapIF(mFreqI); }
00790 TEMTS inline float TACCUM::phase() const { return mapIF(mPhaseI); }
00791 TEMTS inline uint32_t TACCUM::phaseI() const { return mPhaseI; }
00792 
00793 TEMTS inline uint32_t TACCUM::nextPhase(float frqOffset){
00794     uint32_t r=mPhaseI;
00795     mTap(mPhaseI, mFreqI + mapFreq(frqOffset));
00796     return r;
00797 }
00798 
00799 TEMTS inline uint32_t TACCUM::nextPhase(){ uint32_t r=mPhaseI; nextPhasePost(); return r; }
00800 TEMTS inline uint32_t TACCUM::nextPhasePost(){ return mTap(mPhaseI, mFreqI); }
00801 
00802 
00803 
00804 TEMTS inline uint32_t TACCUM::operator()(){ return cycle(); }
00805 
00806 TEMTS inline uint32_t TACCUM::cycle(){ return cycles() & 0x80000000; }
00807 
00808 //TEMTS inline uint32_t TACCUM::cycle(uint32_t mask){
00809 //  return cycles() & mask;
00810 //}
00811 
00812 TEMTS inline uint32_t TACCUM::cycles(){
00813     uint32_t prev = phaseI();
00814     nextPhasePost();    
00815     return ~phaseI() & prev;
00816 }
00817 
00818 TEMTS inline uint32_t TACCUM::once(){
00819     uint32_t prev = phaseI();
00820     uint32_t c = cycle();
00821     if(c) mPhaseI = prev;
00822     return c;
00823 }
00824 
00825 #undef TACCUM
00826 
00827 
00828 
00829 //---- AccumPhase
00830 
00831 TEM AccumPhase<Tv, Ts>::AccumPhase(Tv f, Tv p)
00832 :   mFreq(f), m2PiUPS(1)
00833 {
00834     Ts::initSynced();
00835     this->phase(p);
00836 }
00837 
00838 TEM inline Tv AccumPhase<Tv, Ts>::mapFreq(Tv v) const { return v*m2PiUPS; }
00839 TEM inline Tv AccumPhase<Tv, Ts>::mapPhase(Tv v) const { return v*Tv(M_2PI); }
00840 
00841 TEM inline Tv AccumPhase<Tv, Ts>::nextPhaseUsing(Tv frq){
00842     mPhase = scl::wrapPhase(mPhase); // guarantees that result is in [-pi, pi)
00843     Tv r = mPhase;
00844     mPhase += frq;
00845     return r;
00846 }
00847 
00848 TEM inline Tv AccumPhase<Tv, Ts>::nextPhase(){
00849     return nextPhaseUsing(mFreq);
00850 }
00851 
00852 TEM inline Tv AccumPhase<Tv, Ts>::nextPhase(Tv frqMod){
00853     return nextPhaseUsing(mFreq + mapFreq(frqMod));
00854 }
00855 
00856 TEM inline void AccumPhase<Tv, Ts>::freq(Tv v){ mFreq = mapFreq(v); }
00857 TEM inline void AccumPhase<Tv, Ts>::period(Tv v){ freq(Tv(1)/v); }
00858 TEM inline void AccumPhase<Tv, Ts>::phase(Tv v){ mPhase = mapPhase(v); }
00859 TEM inline void AccumPhase<Tv, Ts>::phaseAdd(Tv v){ mPhase += mapPhase(v); }
00860 
00861 TEM inline Tv AccumPhase<Tv, Ts>::freq(){ return mFreq/m2PiUPS; } //mFreq; }
00862 TEM inline Tv AccumPhase<Tv, Ts>::period(){ return Tv(1) / freq(); }
00863 TEM inline Tv AccumPhase<Tv, Ts>::phase(){ return mPhase * Tv(M_1_2PI); }
00864 
00865 TEM void AccumPhase<Tv, Ts>::onResync(double r){ Tv f=freq(); recache(); freq(f); }
00866 TEM void AccumPhase<Tv, Ts>::recache(){ m2PiUPS = Tv(Ts::ups() * M_2PI); }
00867 
00868 TEM void AccumPhase<Tv, Ts>::print(const char * append, FILE * fp){
00869 //  fprintf(fp, "%f %f %f%s", freq(), phase(), mFreqI, append);
00870     fprintf(fp, "%f %f %f%s", freq(), phase(), mFreq, append);
00871 }
00872 
00873 
00874 //---- CSine
00875 
00876 TEM CSine<Tv, Ts>::CSine(Tv f, Tv a, Tv dcy60, Tv p)
00877     : val(a, 0), mAmp(a), mFreq(f), mDcy60(dcy60)
00878 {
00879     Ts::initSynced();
00880     this->phase(p);
00881 }
00882 
00883 TEM void CSine<Tv, Ts>::amp(Tv v){
00884     if(scl::abs(mAmp) > Tv(0.000001)){
00885         Tv factor = v / mAmp;
00886         val *= factor;
00887     } else {
00888         val(v, Tv(0));
00889     }
00890     mAmp = v;
00891 }
00892 
00893 TEM void CSine<Tv, Ts>::decay(Tv v){
00894     mDcy60 = v;
00895     mDcy = v > Tv(0) ? Tv(scl::t60(v * Ts::spu())) : Tv(1);
00896     freq(mFreq);
00897 }
00898 
00899 TEM void CSine<Tv, Ts>::freq(Tv v){
00900     mFreq = v;
00901     Tv phaseInc = v * Ts::ups() * Tv(M_2PI);
00902     mInc.fromPolar(mDcy, phaseInc);
00903     //printf("%f %f %f %f\n", phaseInc, mDcy, c1, s1);
00904 }
00905 
00906 TEM void CSine<Tv, Ts>::phase(Tv v){
00907     // set phase without changing current magnitude
00908     val.fromPolar(val.norm(), v*Tv(M_2PI));
00909 }
00910 
00911 TEM void CSine<Tv, Ts>::reset(){ val(mAmp, Tv(0)); }
00912 
00913 TEM void CSine<Tv, Ts>::set(Tv frq, Tv phase, Tv amp, Tv dcy60){
00914     mFreq = frq;
00915     decay(dcy60);
00916     this->amp(amp);
00917     this->phase(phase);
00918 }
00919 
00920 TEM inline Complex<Tv> CSine<Tv, Ts>::operator()(){
00921     complex c = val;
00922     val *= mInc;
00923     return c;
00924 }
00925 
00926 TEM inline Tv CSine<Tv, Ts>::freq(){ return mFreq; }
00927 
00928 TEM void CSine<Tv, Ts>::onResync(double r){
00929     decay(mDcy60); // this sets frequency as well
00930 }
00931 
00932 
00933 //---- TableSine
00934 
00935 #define TTABLESINE TableSine<St,Ts>
00936 TEMTS uint32_t TTABLESINE::cTblBits  = 0;   
00937 TEMTS uint32_t TTABLESINE::cFracBits = 0;
00938 TEMTS uint32_t TTABLESINE::cOneIndex = 0;
00939 TEMTS float * TTABLESINE::cTable = 0;
00940 
00941 TEMTS TTABLESINE::TableSine(float f, float p): Base(f, p){
00942     // initialize global table ONCE
00943     if(0 == cTable){ resize(11); }
00944 }
00945 
00946 TEMTS void TTABLESINE::resize(uint32_t bits){
00947     if(bits != cTblBits){
00948         if(cTable) delete[] cTable;
00949 
00950         cTblBits = bits;
00951         cFracBits = 32UL - cTblBits;
00952         cOneIndex = 1<<cFracBits;
00953         uint32_t size = 1<<(cTblBits-2);
00954         cTable = new float[size + 1];
00955         tbl::sinusoid(cTable, size, 0, 0.25);
00956         cTable[size] = 1;       
00957     }
00958 }
00959 
00960 TEMTS inline float TTABLESINE::operator()(float df){ return nextL(df); }
00961 
00962 TEMTS inline float TTABLESINE::nextN(float df){ 
00963     return tbl::atQ(cTable, cFracBits, nextPhase(df));
00964 }
00965 
00966 TEMTS inline float TTABLESINE::nextL(float df){
00967     uint32_t P = nextPhase(df);
00968 
00969     return ipl::linear(
00970         gam::fraction(cTblBits, P),
00971         tbl::atQ(cTable, cFracBits, P),
00972         tbl::atQ(cTable, cFracBits, P + cOneIndex)
00973     );
00974 }
00975 
00976 #undef TTABLESINE
00977 
00978 
00979 
00980 //---- LFO
00981 #define TLFO LFO<St,Ts>
00982 TEMTS TLFO::LFO(): Base(){ mod(0.5); }
00983 TEMTS TLFO::LFO(float f, float p, float m): Base(f, p){ mod(m); }
00984 
00985 TEMTS inline TLFO& TLFO::set(float f, float p, float m){ this->freq(f); this->phase(p); return mod(m); }
00986 TEMTS inline TLFO& TLFO::mod(double v){ modi = castIntRound(v*4294967296.); return *this; }
00987 
00988 TEMTS inline float TLFO::line2(){
00989     using namespace gam::scl;
00990     
00991 //  // Starts at 1
00992 //  float r1 = rampDown(phaseI());
00993 //  float r2 = rampDown(phaseI() + modi);
00994 
00995     // Starts at -1 (better for creating attack/decay like envelopes)
00996     uint32_t m = scl::clip<uint32_t>(modi, 0xffefffff, 512); // avoid div by zero
00997     float r1 = rampDown(phaseI() - m);
00998     float r2 = rampDown(phaseI());
00999     float p  = rampUpU(m);
01000 
01001     float r = (r1*r1 - r2*r2)/(4.f*p*(1.f - p));
01002     nextPhasePost();
01003     return r;
01004 }
01005 
01006 TEMTS inline float TLFO::line2U(){ return line2()*0.5f+0.5f; }
01007 
01008 #define DEF(name, exp) TEMTS inline float TLFO::name{ float r = exp; return r; }
01009 //DEF(cos(),        tri(); r *= 0.5f * r*r - 1.5f)
01010 //DEF(cos(),        up(); r=scl::abs(r*r) )//r = -1.f - scl::pow2(2.f*r)*(scl::abs(r)-1.5f) )
01011 DEF(cos(),      up(); r = -1.f - r*r*(4.f*scl::abs(r)-6.f) )
01012 DEF(down(),     scl::rampDown(nextPhase()))
01013 DEF(even3(),    up(); static const float c=-1.50f*sqrtf(3.f); r *= (1.f-r*r)*c;)
01014 DEF(even5(),    up(); static const float c=-1.25f*::powf(5.f,0.25f); r *= (1.f-scl::pow4(r))*c;)
01015 DEF(imp(),      scl::pulseU(nextPhase(), this->freqI()) )
01016 DEF(para(),     paraU()*1.5f - 0.5f)
01017 DEF(pulse(),    scl::pulse(nextPhase(), modi))
01018 DEF(sinPara(),  scl::sinPara(nextPhase()))
01019 DEF(stair(),    scl::stair(nextPhase(), modi))
01020 DEF(sqr(),      scl::square(nextPhase()))
01021 DEF(tri(),      scl::triangle(nextPhase()))
01022 DEF(up(),       scl::rampUp(nextPhase()))
01023 DEF(up2(),      scl::rampUp2(nextPhase(), modi))
01024 DEF(cosU(),     tri(); r = scl::mapSinSU(r))
01025 DEF(downU(),    scl::rampDownU(nextPhase()))
01026 DEF(hann(),     tri(); r = r * (0.25f * r*r - 0.75f) + 0.5f)
01027 DEF(paraU(),    up(); r*=r;)
01028 DEF(pulseU(),   scl::pulseU(nextPhase(), modi))
01029 DEF(sqrU(),     scl::squareU(nextPhase()))
01030 DEF(stairU(),   scl::stairU(nextPhase(), modi))
01031 DEF(triU(),     scl::triangleU(nextPhase()))
01032 DEF(upU(),      scl::rampUpU(nextPhase()))
01033 DEF(up2U(),     scl::rampUp2U(nextPhase(), modi))
01034 DEF(patU(),     scl::rampUpU(nextPhase() & modi))
01035 
01036 DEF(patU(uint32_t mul), scl::rampUpU((nextPhase() & modi) * mul))
01037 
01038 DEF(sineT9(),   up(); r = scl::sinT9(r * M_PI))
01039 DEF(sineP9(),   up(); r = scl::sinP9(r))
01040 
01041 #undef DEF
01042 
01043 TEMTS inline bool TLFO::seq(){
01044     uint32_t prev = nextPhase();
01045     if( (phaseI() ^ prev) & 0xf8000000 ){
01046         if( (modi >> (phaseI()>>27)) & 0x1 ) return true;
01047     }
01048     return false;
01049 }
01050 
01051 #undef TLFO
01052 
01053 
01054 //---- Buzz
01055 
01056 TEM Buzz<Tv,Ts>::Buzz(Tv f, Tv p, Tv harmonics)
01057 :   Base(f, p), mAmp(0), mPrev(Tv(0))
01058 {
01059     onResync(1);
01060     this->harmonics(harmonics);
01061 }
01062 
01063 TEM inline void Buzz<Tv,Ts>::harmonics(Tv v){
01064     mN = mNDesired = scl::floor(v);
01065     setAmp();
01066     mNFrac = v - mN;
01067 }
01068 
01069 TEM inline void Buzz<Tv,Ts>::harmonicsMax(){ harmonics(maxHarmonics()); }
01070 
01071 TEM inline void Buzz<Tv,Ts>::antialias(){
01072     float maxN = scl::floor(maxHarmonics());
01073     mN = mNDesired > maxN ? maxN : mNDesired;
01074     setAmp();
01075 }
01076 
01077 TEM inline Tv Buzz<Tv,Ts>::maxHarmonics(){ return mSPU_2 / this->freq(); }
01078 
01079 TEM inline void Buzz<Tv,Ts>::setAmp(){
01080     // Normally, the amplitude is 1/(2N), but we will linearly interpolate
01081     // based on fractional harmonics to avoid sudden changes in amplitude to
01082     // the lower harmonics which is very noticeable.
01083     mAmp = (mN != Tv(0)) ? (Tv(0.5) / (mN+mNFrac)) : 0;
01084     //mAmp = (mN != Tv(0)) ? (Tv(0.5) / (mN)) : 0;
01085 }
01086 
01087 #define EPS 0.000001
01088 TEM inline Tv Buzz<Tv, Ts>::operator()(){
01089     /*        1   / sin((N+0.5)x)    \
01090        f(x) = -- |  ------------- - 1 |
01091               2N  \   sin(0.5x)      /
01092     */
01093     Tv theta = this->nextPhase();
01094     Tv result;
01095     Tv denom = scl::sinT9(theta * Tv(0.5));
01096 
01097     // denominator goes to zero when theta is an integer multiple of 2 pi
01098     if(scl::abs(denom) < Tv(EPS)){
01099         result = Tv(2) * mN * mAmp;
01100         //printf("Impulse::(): oops\n");
01101     }
01102     else{
01103         Tv nphase = scl::wrapPhase(theta * (mN + Tv(0.5)));
01104         //result = (scl::sinT7(nphase) / denom - Tv(1)) * mAmp;
01105         result = ((scl::sinT7(nphase) - denom) / denom) * mAmp;
01106     }
01107 
01108     //Tv fund = ((denom*denom)-0.5)*-4*mAmp;
01109     //result -= fund; // drop first harmonic
01110 
01111     // Mitigate pops when number of harmonics is changed by a small amount
01112     //result -= 2.f * mAmp * cos(theta * mN) * (1.f - scl::pow2(mNFrac));
01113 
01114     return result;
01115 }
01116 
01117 TEM inline Tv Buzz<Tv,Ts>::odd(){
01118     /*        1   / sin(2N x) \
01119        f(x) = -- |  ---------  |
01120               2N  \   sin(x)  /
01121     */
01122     Tv theta = this->nextPhase();
01123     Tv result;
01124 
01125     Tv n2 = scl::roundAway(mN*0.5) * 2; 
01126     Tv n2frac = ((mN + mNFrac) - (n2-1)); // fraction, in [0,2), btw odd harmonics
01127 
01128     // cos is more precise near zero-crossings
01129     Tv denom = scl::cosT8(scl::wrapPhaseOnce(theta - M_PI_2));
01130     //Tv denom = scl::sinT9(theta);
01131     if( scl::abs(denom) < Tv(EPS) ){
01132         if( theta > M_PI ) theta -= M_2PI;
01133         Tv A = n2 / (n2 + n2frac);
01134         result = (theta > -M_PI_2 && theta < M_PI_2) ? A : -A;
01135         //printf("Impulse::odd(): oops\n");
01136     }
01137     else result = scl::sinT7(scl::wrapPhase(n2 * theta)) / (denom * (n2 + n2frac));
01138     
01139     return result;
01140 }
01141 #undef EPS
01142 
01143 TEM inline Tv Buzz<Tv,Ts>::saw(Tv i){ return mPrev=(*this)()*0.125 + i*mPrev; }
01144 TEM inline Tv Buzz<Tv,Ts>::square(Tv i){ return mPrev=odd()*0.125 + i*mPrev; }
01145 
01146 TEM void Buzz<Tv,Ts>::onResync(double r){
01147     Base::onResync(r);
01148     mSPU_2 = Tv(Synced::spu() * 0.5);
01149 }
01150 
01151 
01152 
01153 //---- DSF
01154 
01155 TEM DSF<Tv,Ts>::DSF(Tv frq, Tv freqRatioA, Tv ampRatioA, Tv harmonicsA)
01156     : Base(frq)
01157 {
01158     freq(frq);
01159     freqRatio(freqRatioA);
01160     harmonics(harmonicsA);
01161     ampRatio(ampRatioA);
01162 
01163     mBeta = 0.f;
01164 }
01165 
01166 TEM inline void DSF<Tv,Ts>::freq(Tv v){
01167     Base::freq(v);
01168     updateBetaInc();    
01169 }
01170 
01171 TEM inline void DSF<Tv,Ts>::freqRatio(Tv v){
01172     mFreqRatio = v;
01173     updateBetaInc();
01174 }
01175 
01176 TEM inline void DSF<Tv,Ts>::ampRatio(Tv v){
01177     if(v != mA){
01178         // if near 1, nudge away
01179         static const Tv epslt = 0.9997;
01180         static const Tv epsgt = 1/epslt;
01181                 if(v >= 1 && v < epsgt) v = epsgt;
01182         else    if(v <= 1 && v > epslt) v = epslt;
01183         mA = v;
01184         mASqP1 = mA * mA + 1.f;
01185         updateAPow();
01186     }
01187 }
01188 
01189 TEM inline void DSF<Tv,Ts>::harmonics(Tv v){
01190     if(v != mN){
01191         mN = mNDesired = v;
01192         updateAPow();
01193     }
01194 }
01195 
01196 TEM inline void DSF<Tv,Ts>::harmonicsMax(){ harmonics(maxHarmonics()); }
01197 
01198 TEM inline void DSF<Tv,Ts>::antialias(){
01199     Tv maxN = maxHarmonics();
01200     if(mNDesired > maxN)    mN = maxN;
01201     else                    mN = mNDesired;
01202     updateAPow();
01203 }
01204 
01205 TEM inline Tv DSF<Tv,Ts>::ampRatio(){ return mA; }
01206 TEM inline Tv DSF<Tv,Ts>::freqRatio(){ return mFreqRatio; }
01207 TEM inline Tv DSF<Tv,Ts>::harmonics(){ return mN; }
01208 
01209 TEM inline Tv DSF<Tv,Ts>::maxHarmonics(){
01210     return scl::floor((Tv(this->spu()) * Tv(0.5)/this->freq() - Tv(1))/freqRatio() + Tv(1));
01211 }
01212 
01213 TEM inline void DSF<Tv,Ts>::updateAPow(){ mAPow = ::pow(mA, mN); }
01214 TEM inline void DSF<Tv,Ts>::updateBetaInc(){ mBetaInc = this->mFreq * mFreqRatio; }
01215 
01216 // Generalized DSF formula:
01217 // sum{k=0, N}( a^k sin(T + k B) )
01218 //      =  sin(T) - a sin(T - B) - a^(N+1) [sin(T + (N+1) B) - a sin(T + N B))]
01219 //          / 1 + a^2 - 2a cos(B)
01220 
01221 #define SIN scl::sinT7
01222 #define COS scl::cosT8
01223 //#define SIN sin
01224 //#define COS cos
01225 TEM inline Tv DSF<Tv,Ts>::operator()(){
01226     Tv theta = Base::nextPhase();
01227     mBeta = scl::wrapPhase(mBeta);
01228 
01229     Tv phs2 = scl::wrapPhaseOnce(theta - mBeta);
01230     Tv phs3 = scl::wrapPhase(theta + mN * mBeta);
01231     Tv phs4 = scl::wrapPhaseOnce(phs3 - mBeta);
01232 
01233     Tv result = SIN(theta) - mA * SIN(phs2) - mAPow * (SIN(phs3) - mA * SIN(phs4)); 
01234     result /= mASqP1 - Tv(2) * mA * COS(mBeta);
01235     //result /= mA * (mA - Tv(2) * COS(mBeta)) + Tv(1);
01236 
01237     mBeta += mBetaInc;
01238     return result;
01239 }
01240 #undef SIN
01241 #undef COS
01242 
01243 TEM void DSF<Tv,Ts>::onResync(double r){
01244     Base::onResync(r);
01245     freq(Base::freq());
01246     harmonics(mNDesired);
01247 }
01248 
01249 #undef TEM
01250 #undef TEMS
01251 #undef TEMTS
01252 
01253 } // gam::
01254 #endif