00001 #ifndef GAMMA_PLAYER_H_INC
00002 #define GAMMA_PLAYER_H_INC
00003
00004
00005
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());
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;
00132 double mSampleRate;
00133 int mChans;
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);
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 }
00214
00215 #endif
00216