Gamma  0.9.5
Generic Synthesis Library
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
/Users/ljp/code/gamma/trunk/Gamma/Player.h
00001 #ifndef GAMMA_PLAYER_H_INC
00002 #define GAMMA_PLAYER_H_INC
00003 
00004 /*  Gamma - Generic processing library
00005     See COPYRIGHT file for authors and license information */
00006 
00007 #include "Gamma/Containers.h"
00008 #include "Gamma/ipl.h"
00009 #include "Gamma/scl.h"
00010 #include "Gamma/SoundFile.h"
00011 #include "Gamma/Strategy.h"
00012 #include "Gamma/Sync.h"
00013 #include "Gamma/Types.h"
00014 
00015 namespace gam{
00016 
00017 
00019 
00026 template<
00027     class T = real,
00028     template<class> class Si = ipl::Trunc,
00029     class St = tap::Clip
00030 >
00031 class Player: public Synced, public Array<T>{
00032 public:
00033     using Array<T>::size; using Array<T>::elems;
00034 
00035     Player()
00036     :   Array<T>(defaultBuffer(), 1),
00037         mPos(0), mInc(0),
00038         mSampleRate(1), mChans(1),
00039         mRate(1), mMin(0), mMax(1)
00040     {}
00041 
00042 
00045     explicit Player(Player<T>& src, double rate=1)
00046     :   Array<T>(src), 
00047         mPos(0), mInc(1), 
00048         mSampleRate(src.sampleRate()), mChans(src.channels()), 
00049         mRate(rate), mMin(0), mMax(src.size())
00050     { initSynced(); }
00051 
00052 
00056     Player(Array<T>& src, double smpRate, double rate=1)
00057     :   Array<T>(src),
00058         mPos(0), mInc(1),
00059         mSampleRate(smpRate), mChans(1),
00060         mRate(rate), mMin(0), mMax(src.size())
00061     {
00062         initSynced();
00063         sampleRate(smpRate);
00064     }
00065 
00066 
00069     template<class Char>
00070     explicit Player(const Char * pathToSoundFile, double rate=1);
00071 
00072 
00074     template<class Char>
00075     bool load(const Char * pathToSoundFile);
00076 
00077 
00079     void advance(){
00080         mPos = mTap(pos(), mInc, max(), min()); // update read tap, in frames
00081     }
00082 
00084     T operator()(int channel=0){ T r = read(channel); advance(); return r; }
00085 
00087     T read(int channel) const {
00088         uint32_t posi = uint32_t(pos());
00089         int Nframes= frames();
00090         int offset = channel*Nframes;
00091         return mIpol(*this, posi+offset, pos()-posi, offset+Nframes-1, offset);
00092     }
00093 
00095     
00099     void buffer(Array<T>& src, double smpRate, int channels);
00100 
00101     void free();                            
00102     void max(double v);                     
00103     void min(double v);                     
00104     void pos(double v);                     
00105     void phase(double v);                   
00106     void rate(double v);                    
00107     void range(double phs, double period);  
00108     void reset();                           
00109 
00110     double max() const { return mMax; }     
00111     double min() const { return mMin; }     
00112     double period() const;                  
00113     double pos() const { return mPos; }     
00114     double posInInterval(double frac) const;
00115     double rate() const { return mRate; }   
00116     double sampleRate() const { return mSampleRate; } 
00117 
00118     int channels() const { return mChans; } 
00119 
00120     virtual void onResync(double r){ sampleRate(mSampleRate); }
00121 
00122 protected:  
00123     static T * defaultBuffer(){
00124         static T v(0);
00125         return &v;
00126     }
00127 
00128     Si<T> mIpol;
00129     St mTap;
00130 
00131     double mPos, mInc;          // real index position and increment
00132     double mSampleRate;         // sample rate of array data
00133     int mChans;                 // number of channels
00134     double mRate, mMin, mMax;
00135     
00136     void sampleRate(double v){
00137         mSampleRate = v;
00138         rate(mRate);
00139     }
00140 
00141     int frames() const { return size()/channels(); }
00142 };
00143 
00144 #define PRE template <class T, template<class> class Si, class St>
00145 #define CLS Player<T,Si,St>
00146 
00147 PRE
00148 template<class Char>
00149 CLS::Player(const Char * path, double rate)
00150 :   Array<T>(), mPos(0), mInc(1), mChans(1), mRate(rate), mMin(0), mMax(1)
00151 {   
00152     if(!load(path)){
00153         this->source(defaultBuffer(), 1);
00154     }
00155 }
00156 
00157 PRE
00158 template<class Char>
00159 bool CLS::load(const Char * pathToSoundFile){
00160     SoundFile sf(pathToSoundFile);
00161     
00162     if(sf.openRead()){
00163         Array<T>::resize(sf.samples());
00164         sf.readAllD(elems());
00165         sampleRate(sf.frameRate());
00166         mChans = sf.channels();
00167         mMin = 0;
00168         mMax = frames();
00169         mPos = 0;
00170         sf.close();
00171         return true;
00172     }
00173     
00174     return false;
00175 }
00176 
00177 PRE void CLS::buffer(Array<T>& src, double smpRate, int channels){
00178     this->source(src);
00179     sampleRate(smpRate);    // sets mSampleRate, mRate, and mInc
00180     mChans = channels;
00181     mMin = 0;
00182     mMax = frames();
00183     mPos = 0;
00184 }
00185 
00186 PRE inline void CLS::pos(double v){ mPos = v; }
00187 PRE inline void CLS::phase(double v){ pos(v * frames()); }
00188 PRE inline void CLS::min(double v){ mMin = scl::clip<double>(v, frames()); }    
00189 PRE inline void CLS::max(double v){ mMax = scl::clip<double>(v, frames()); }
00190 
00191 PRE void CLS::free(){ this->freeElements(); }
00192 PRE inline void CLS::rate(double v){
00193     mRate = v;
00194     mInc = v * mSampleRate * ups();
00195 }
00196 PRE inline void CLS::range(double posn, double period){
00197     phase(posn);
00198     min(pos());
00199     max(pos() + period * spu());    
00200 }
00201 
00202 PRE inline void CLS::reset(){
00203     pos(rate()<0 ? max() : min());
00204     mTap.reset();
00205 }
00206 
00207 PRE inline double CLS::period() const { return frames() * ups(); }
00208 PRE inline double CLS::posInInterval(double frac) const { return min() + (max() - min()) * frac; }
00209 
00210 #undef PRE
00211 #undef CLS
00212 
00213 } // gam::
00214 
00215 #endif
00216