00001 #ifndef GAMMA_DELAY_H_INC
00002 #define GAMMA_DELAY_H_INC
00003
00004
00005
00006
00007
00008 #include "Gamma/ipl.h"
00009 #include "Gamma/mem.h"
00010 #include "Gamma/scl.h"
00011
00012
00013 #include "Gamma/Containers.h"
00014 #include "Gamma/Strategy.h"
00015 #include "Gamma/Sync.h"
00016 #include "Gamma/Types.h"
00017
00018 namespace gam{
00019
00020
00022
00027 template <class Tv=gam::real, template<class> class Si=ipl::Linear, class Ts=Synced>
00028 class Delay : public ArrayPow2<Tv>, Ts{
00029 public:
00030
00032 Delay();
00033
00036 Delay(float delay);
00037
00041 Delay(float maxDelay, float delay);
00042
00043
00044 void delay(float v);
00045 void delayUnit(float u);
00046 void freq(float v);
00047 void ipolType(ipl::Type v){ mIpol.type(v); }
00048 void maxDelay(float v);
00049 void zero();
00050
00051 Tv operator()(const Tv& v);
00052 Tv operator()() const;
00053 Tv read(float ago);
00054 void write(const Tv& v);
00055 void writePre(const Tv& v);
00056
00057 float delay() const;
00058 uint32_t delayIndex(uint32_t delay) const;
00059 float delayUnit() const;
00060 float freq() const { return 1.f/delay(); }
00061 uint32_t indexBack() const;
00062 float maxDelay() const;
00063
00064 virtual void onResize();
00065 virtual void onResync(double r);
00066
00067 void print();
00068
00069 protected:
00070 Si<Tv> mIpol;
00071
00072 float mMaxDelay;
00073 float mDelayFactor;
00074 float mDelayLength;
00075 uint32_t mPhase;
00076 uint32_t mPhaseInc;
00077 uint32_t mDelay;
00078
00079 void incPhase();
00080 void refreshDelayFactor();
00081 uint32_t delayFToI(float v);
00082 };
00083
00084
00085
00087 template <class Tv=gam::real, template <class> class Si=ipl::Linear, class Ts=Synced>
00088 class Delays : public Delay<Tv,Si,Ts> {
00089 public:
00090
00094 Delays(float delay, uint32_t numTaps)
00095 : Delay<Tv,Si,Ts>(delay)
00096 { taps(numTaps); }
00097
00099 uint32_t taps() const { return mDelays.size(); }
00100
00102 Tv read(uint32_t tap) const {
00103 return mIpol(*this, this->mPhase - mDelays[tap]);
00104 }
00105
00107 void delay(float length, uint32_t tap){
00108 mDelays[tap] = this->delayFToI(length);
00109 }
00110
00112 void taps(uint32_t numTaps){ mDelays.resize(numTaps); }
00113
00114 protected:
00115 std::vector<uint32_t> mDelays;
00116 };
00117
00118
00119
00121
00124 template <uint32_t N, class T>
00125 class DelayShift{
00126 public:
00127 #define IT for(uint32_t i=0; i<N; ++i)
00128
00130 DelayShift(const T& v=T()){ IT mElems[i]=v; }
00131
00133 T& operator[](uint32_t i){ return mElems[i]; }
00134
00136 const T& operator[](uint32_t i) const { return mElems[i]; }
00137
00139 T * elems(){ return mElems; }
00140 const T * elems() const { return mElems; }
00141
00142
00144 T operator()(const T& v) const {
00145 const T r = mElems[N-1];
00146 for(uint32_t i=N-1; i>0; --i) mElems[i] = mElems[i-1];
00147 mElems[0]=v;
00148 return r;
00149 }
00150
00152 static uint32_t size(){ return N; }
00153
00154 #undef IT
00155
00156 protected:
00157 mutable T mElems[N];
00158 };
00159
00160
00162 template<class T=gam::real>
00163 class Delay1 : public DelayShift<1,T>{
00164 public:
00165
00167 Delay1(const T& v=T()): DelayShift<1,T>(v){}
00168 };
00169
00170
00172 template<class T=gam::real>
00173 class Delay2 : public DelayShift<2,T>{
00174 public:
00175
00177 Delay2(const T& v=T()): DelayShift<2,T>(v){}
00178
00181 Delay2(const T& v2, const T& v1){ (*this)[1]=v2; (*this)[0]=v1; }
00182 };
00183
00184
00185
00187
00199
00200
00201 template<
00202 class Tv=gam::real,
00203 template <class> class Si=ipl::Linear,
00204 class Tp=gam::real,
00205 class Ts=Synced
00206 >
00207 class Comb : public Delay<Tv,Si,Ts> {
00208
00209 private:
00210 typedef Delay<Tv,Si,Ts> Base;
00211
00212 public:
00213 using Base::operator();
00214
00216 Comb();
00217
00222 Comb(float delay, const Tp& ffd = Tp(0), const Tp& fbk = Tp(0));
00223
00229 Comb(float maxDelay, float delay, const Tp& ffd, const Tp& fbk);
00230
00231
00233
00238 void decay(float units, float end = 0.001f);
00239
00241 void allPass(const Tp& v);
00242
00243 void fbk(const Tp& v);
00244 void ffd(const Tp& v);
00245 void feeds(const Tp& fwd, const Tp& bwd){ ffd(fwd); fbk(bwd); }
00246
00247 void set(float delay, const Tp& ffd, const Tp& fbk);
00248
00249 Tv operator()(const Tv& i0);
00250 Tv operator()(const Tv& i0, const Tv& oN);
00251 Tv circulateFbk(const Tv& i0, const Tv& oN);
00252
00254 Tv nextFbk(const Tv& i0);
00255
00256 float norm() const;
00257 float normFbk() const;
00258 float normFfd() const;
00259 Tp ffd() const;
00260 Tp fbk() const;
00261
00262 protected:
00263 Tp mFFD, mFBK;
00264 };
00265
00266
00267
00268
00269
00270
00271 #define TM1 template <class Tv, template <class> class Ti, class Ts>
00272 #define TM2 Tv,Ti,Ts
00273
00274 #define DELAY_INIT mMaxDelay(0), mDelayFactor(0), mDelayLength(0), mPhase(0), mPhaseInc(0), mDelay(0)
00275
00276 TM1 Delay<TM2>::Delay()
00277 : ArrayPow2<Tv>(), DELAY_INIT
00278 { Ts::initSynced(); }
00279
00280 TM1 Delay<TM2>::Delay(float maxDelay, float delay)
00281 : ArrayPow2<Tv>(), DELAY_INIT
00282 {
00283 Ts::initSynced();
00284 this->maxDelay(maxDelay);
00285 this->delay(delay);
00286 }
00287
00288 TM1 Delay<TM2>::Delay(float delay)
00289 : ArrayPow2<Tv>(), DELAY_INIT
00290 {
00291 Ts::initSynced();
00292 this->maxDelay(delay);
00293 this->delay(delay);
00294 }
00295
00296 #undef DELAY_INIT
00297
00298 TM1 void Delay<TM2>::maxDelay(float length){
00299 mMaxDelay = length;
00300 if(Ts::sync() && Ts::sync()->hasBeenSet()){
00301
00302
00303
00304
00305 this->resize((uint32_t)(mMaxDelay * Ts::spu()));
00306 }
00307 }
00308
00309 TM1 void Delay<TM2>::zero(){ this->assign(Tv(0)); }
00310
00311 TM1 inline Tv Delay<TM2>::operator()() const{ return mIpol(*this, mPhase - mDelay); }
00312
00313 TM1 inline Tv Delay<TM2>::operator()(const Tv& i0){
00314
00315
00316 Tv o0 = (*this)();
00317 write(i0);
00318 return o0;
00319 }
00320
00321 TM1 inline uint32_t Delay<TM2>::delayFToI(float v){
00322 return castIntRound((v * mDelayFactor) * 4294967296.);
00323
00324 }
00325
00326 TM1 inline void Delay<TM2>::incPhase(){ mPhase += mPhaseInc; }
00327
00328 TM1 void Delay<TM2>::onResize(){
00329 mPhaseInc = this->oneIndex();
00330
00331 if(this->isSoleOwner()) zero();
00332 onResync(1);
00333 }
00334
00335 TM1 void Delay<TM2>::onResync(double r){
00336 if(this->usingExternalSource()){
00337 mMaxDelay = this->size() * Ts::ups();
00338 }
00339 else{
00340 maxDelay(mMaxDelay);
00341 }
00342 refreshDelayFactor();
00343 delay(mDelayLength);
00344 }
00345
00346 TM1 inline Tv Delay<TM2>::read(float ago){ return mIpol(*this, mPhase - delayFToI(ago)); }
00347
00348 TM1 void Delay<TM2>::refreshDelayFactor(){ mDelayFactor = 1. / maxDelay(); }
00349
00350 TM1 inline void Delay<TM2>::write(const Tv& v){
00351 mem::put(this->elems(), this->fracBits(), mPhase, v);
00352 incPhase();
00353 }
00354
00355 TM1 inline void Delay<TM2>::writePre(const Tv& v){
00356 incPhase();
00357 mem::put(this->elems(), this->fracBits(), mPhase, v);
00358 }
00359
00360 TM1 inline void Delay<TM2>::delay(float v){
00361 mDelayLength = v;
00362 mDelay = delayFToI(v);
00363 }
00364
00365 TM1 inline float Delay<TM2>::delay() const { return mDelayLength; }
00366
00367 TM1 inline float Delay<TM2>::delayUnit() const {
00368 return uintToUnit<float>(mDelay);
00369 }
00370
00371 TM1 inline void Delay<TM2>::delayUnit(float n){ mDelay = unitToUInt(n); }
00372
00373 TM1 inline uint32_t Delay<TM2>::delayIndex(uint32_t delay) const {
00374 return this->index(mPhase - (delay << this->fracBits()));
00375 }
00376
00377 TM1 inline void Delay<TM2>::freq(float v){ delay(1.f/v); }
00378
00379 TM1 inline uint32_t Delay<TM2>::indexBack() const {
00380 return this->index(mPhase + this->oneIndex());
00381 }
00382
00383 TM1 inline float Delay<TM2>::maxDelay() const { return this->size() * Ts::ups(); }
00384
00385 TM1 void Delay<TM2>::print(){
00386 printf("SPU: %f\n", Ts::spu());
00387 printf("Buffer: %p\n", this->elems());
00388 printf("BufBits: %d\n", this->log2Size());
00389 printf("FracBits: %d\n", this->fracBits());
00390 printf("Phase: %d\n", mPhase);
00391 printf("PhaseInc: %d\n", mPhaseInc);
00392 printf("Delay: %d, %f\n", mDelay, mDelayLength);
00393 printf("Max Delay: %f\n", mMaxDelay);
00394 printf("DlyFactor: %f\n", mDelayFactor);
00395 }
00396
00397 #undef TM1
00398 #undef TM2
00399
00400
00401
00402
00403 #define TM1 template<class Tv, template<class> class Si, class Tp, class Ts>
00404 #define TM2 Tv,Si,Tp,Ts
00405 TM1 Comb<TM2>::Comb(): Delay<Tv,Si,Ts>(), mFFD(0), mFBK(0){}
00406
00407 TM1 Comb<TM2>::Comb(float delay, const Tp& ffd, const Tp& fbk)
00408 : Delay<Tv,Si,Ts>(delay), mFFD(ffd), mFBK(fbk)
00409 {}
00410
00411 TM1 Comb<TM2>::Comb(float delayMax, float delay, const Tp& ffd, const Tp& fbk)
00412 : Delay<Tv,Si,Ts>(delayMax, delay), mFFD(ffd), mFBK(fbk)
00413 {}
00414
00415 TM1 inline Tv Comb<TM2>::operator()(const Tv& i0){
00416 return (*this)(i0, (*this)()); }
00417
00418 TM1 inline Tv Comb<TM2>::operator()(const Tv& i0, const Tv& oN){
00419 Tv t = i0 + oN * mFBK;
00420 this->write(t);
00421 return oN + t * mFFD;
00422 }
00423
00424 TM1 inline Tv Comb<TM2>::circulateFbk(const Tv& i0, const Tv& oN){
00425 this->write(i0 + oN * mFBK);
00426 return oN;
00427 }
00428
00429 TM1 inline Tv Comb<TM2>::nextFbk(const Tv& i0){
00430 return circulateFbk(i0, (*this)()); }
00431
00432 TM1 inline void Comb<TM2>::decay(float units, float end){
00433 mFBK = ::pow(end, this->delay() / scl::abs(units));
00434 if(units < 0.f) mFBK = -mFBK;
00435 }
00436
00437 TM1 inline void Comb<TM2>::allPass(const Tp& v){ fbk(v); ffd(-v); }
00438 TM1 inline void Comb<TM2>::fbk(const Tp& v){ mFBK=v; }
00439 TM1 inline void Comb<TM2>::ffd(const Tp& v){ mFFD=v; }
00440 TM1 inline void Comb<TM2>::set(float d, const Tp& ff, const Tp& fb){ this->delay(d); ffd(ff); fbk(fb); }
00441
00442 TM1 inline Tp Comb<TM2>::fbk() const { return mFBK; }
00443 TM1 inline Tp Comb<TM2>::ffd() const { return mFFD; }
00444 TM1 inline float Comb<TM2>::norm() const { return (1.f - scl::abs(fbk()))/(1.f + scl::abs(ffd())); }
00445 TM1 inline float Comb<TM2>::normFbk() const { return 1.f - scl::abs(fbk()); }
00446 TM1 inline float Comb<TM2>::normFfd() const { return 1.f/(1.f + scl::abs(ffd())); }
00447
00448 #undef TM1
00449 #undef TM2
00450
00451 }
00452 #endif