00001 #ifndef GAMMA_STRATEGY_H_INC
00002 #define GAMMA_STRATEGY_H_INC
00003
00004
00005
00006
00007 #include "Gamma/Access.h"
00008 #include "Gamma/Containers.h"
00009 #include "Gamma/ipl.h"
00010 #include "Gamma/scl.h"
00011
00012 namespace gam{
00013 namespace ipl{
00014
00016 template <class T>
00017 struct Trunc{
00018
00019 ipl::Type type() const { return TRUNC; }
00020 void type(ipl::Type v){}
00021
00023 T operator()(const ArrayPow2<T>& a, uint32_t phase) const{
00024 return a.atPhase(phase);
00025 }
00026
00027 template <class AccessStrategy>
00028 T operator()(const AccessStrategy& s, const Array<T>& a, index_t iInt, double iFrac, index_t max, index_t min=0) const{
00029 return a[iInt];
00030 }
00031
00032 T operator()(const Array<T>& a, index_t iInt, double iFrac, index_t max, index_t min=0) const{
00033 return (*this)(acc::Wrap(), a,iInt,iFrac, max,min);
00034 }
00035 };
00036
00037
00039 template <class T>
00040 struct Round{
00041
00042 ipl::Type type() const { return ROUND; }
00043 void type(ipl::Type v){}
00044
00046 T operator()(const ArrayPow2<T>& a, uint32_t phase) const{
00047
00048
00049 return a.atPhase(phase + (a.oneIndex()>>1));
00050 }
00051
00052 template <class AccessStrategy>
00053 T operator()(const AccessStrategy& s, const Array<T>& a, index_t iInt, double iFrac, index_t max, index_t min=0) const{
00054 return ipl::nearest(
00055 iFrac,
00056 a[iInt],
00057 a[s.mapP1(iInt+1, max, min)]
00058 );
00059 }
00060
00061 T operator()(const Array<T>& a, index_t iInt, double iFrac, index_t max, index_t min=0) const{
00062 return (*this)(acc::Wrap(), a, iInt, iFrac, max, min);
00063 }
00064 };
00065
00066
00068 template <class T>
00069 struct Linear{
00070
00071 ipl::Type type() const { return LINEAR; }
00072 void type(ipl::Type v){}
00073
00075 T operator()(const ArrayPow2<T>& a, uint32_t phase) const{
00076 return ipl::linear(
00077 a.fraction(phase),
00078 a.atPhase(phase),
00079 a.atPhase(phase + a.oneIndex())
00080 );
00081 }
00082
00083 template <class AccessStrategy>
00084 T operator()(const AccessStrategy& s, const Array<T>& a, index_t iInt, double iFrac, index_t max, index_t min=0) const{
00085 return ipl::linear(
00086 iFrac,
00087 a[iInt],
00088 a[s.mapP1(iInt+1, max, min)]
00089 );
00090 }
00091
00092 T operator()(const Array<T>& a, index_t iInt, double iFrac, index_t max, index_t min=0) const{
00093 return (*this)(acc::Wrap(), a, iInt, iFrac, max, min);
00094 }
00095
00096 };
00097
00098
00100 template <class T>
00101 struct Cubic{
00102
00103 ipl::Type type() const { return CUBIC; }
00104 void type(ipl::Type v){}
00105
00107 T operator()(const ArrayPow2<T>& a, uint32_t phase) const{
00108 uint32_t one = a.oneIndex();
00109 return ipl::cubic(
00110 a.fraction(phase),
00111 a.atPhase(phase - one),
00112 a.atPhase(phase),
00113 a.atPhase(phase + one),
00114 a.atPhase(phase + (one<<1))
00115 );
00116 }
00117
00118 template <class AccessStrategy>
00119 T operator()(const AccessStrategy& s, const Array<T>& a, index_t iInt, double iFrac, index_t max, index_t min=0) const{
00120 return ipl::cubic(
00121 iFrac,
00122 a[s.mapM1(iInt-1, max, min)],
00123 a[iInt],
00124 a[s.mapP1(iInt+1, max, min)],
00125 a[s.map (iInt+2, max, min)]
00126 );
00127 }
00128
00129 T operator()(const Array<T>& a, index_t iInt, double iFrac, index_t max, index_t min=0) const{
00130 return (*this)(acc::Wrap(), a, iInt,iFrac, max,min);
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 };
00151
00152
00154 template <class T>
00155 struct AllPass{
00156
00157 AllPass(T prev=0): prev(prev){}
00158
00159 ipl::Type type() const { return ALLPASS; }
00160 void type(ipl::Type v){}
00161
00163 T operator()(const ArrayPow2<T>& a, uint32_t phase) const{
00164 return ipl::allpass(
00165 a.fraction(phase),
00166 a.atPhase(phase),
00167 a.atPhase(phase + a.oneIndex()),
00168 prev
00169 );
00170 }
00171
00172 template <class AccessStrategy>
00173 T operator()(const AccessStrategy& s, const Array<T>& a, index_t iInt, double iFrac, index_t max, index_t min=0) const{
00174 return ipl::allpass(
00175 iFrac,
00176 a[iInt],
00177 a[s.mapP1(iInt+1, max, min)],
00178 prev
00179 );
00180 }
00181
00182 T operator()(const Array<T>& a, index_t iInt, double iFrac, index_t max, index_t min=0) const{
00183 return (*this)(acc::Wrap(), a, iInt,iFrac, max,min);
00184 }
00185
00186 mutable T prev;
00187 };
00188
00189
00191 template <class T>
00192 struct Any{
00193
00194 Any(): mType(TRUNC){}
00195
00196 ipl::Type type() const { return mType; }
00197 void type(ipl::Type v){ mType=v; }
00198
00200 T operator()(const ArrayPow2<T>& a, uint32_t phase) const{
00201 switch(mType){
00202 case ROUND: return round (a, phase);
00203 case LINEAR: return linear (a, phase);
00204 case CUBIC: return cubic (a, phase);
00205 case ALLPASS: return allpass (a, phase);
00206 default: return trunc (a, phase);
00207 }
00208 }
00209
00210 template <class AccessStrategy>
00211 T operator()(const AccessStrategy& s, const Array<T>& a, index_t iInt, double iFrac, index_t max, index_t min=0) const{
00212 switch(mType){
00213 case ROUND: return round (s,a,iInt,iFrac,max,min);
00214 case LINEAR: return linear (s,a,iInt,iFrac,max,min);
00215 case CUBIC: return cubic (s,a,iInt,iFrac,max,min);
00216 case ALLPASS: return allpass (s,a,iInt,iFrac,max,min);
00217 default: return trunc (s,a,iInt,iFrac,max,min);
00218 }
00219 }
00220
00221 T operator()(const Array<T>& a, index_t iInt, double iFrac, index_t max, index_t min=0) const{
00222 switch(mType){
00223 case ROUND: return round (a,iInt,iFrac,max,min);
00224 case LINEAR: return linear (a,iInt,iFrac,max,min);
00225 case CUBIC: return cubic (a,iInt,iFrac,max,min);
00226 case ALLPASS: return allpass (a,iInt,iFrac,max,min);
00227 default: return trunc (a,iInt,iFrac,max,min);
00228 }
00229 }
00230
00231 protected:
00232 ipl::Type mType;
00233 Trunc<T> trunc;
00234 Round<T> round;
00235 Linear<T> linear;
00236 Cubic<T> cubic;
00237 AllPass<T> allpass;
00238 };
00239
00240 }
00241
00242
00243
00245
00246
00247
00248
00249
00250
00251 namespace iplSeq{
00252
00254 template <uint32_t N, class T>
00255 struct Base{
00256 Base(const T& v=0){ set(v); }
00257
00259 void push(T va){ for(uint32_t i=N-1; i>0; --i) v[i]=v[i-1]; v[0]=va; }
00260
00262 void set(T va){ for(uint32_t i=0; i<N; ++i) v[i]=va; }
00263
00265 T val() const { return v[0]; }
00266
00268 void val(const T& va){ v[0]=va; }
00269
00270 T v[N];
00271 };
00272
00274 template <class T>
00275 struct Trunc : public Base<1,T>{
00276 using Base<1,T>::v;
00277 Trunc(const T& v=0): Base<1,T>(v){}
00278 T operator()(float f) const { return v[0]; }
00279 };
00280
00282 template <class T>
00283 struct Linear : public Base<2,T>{
00284 using Base<2,T>::v;
00285 Linear(const T& v=0): Base<2,T>(v){}
00286 T operator()(float f) const { return ipl::linear(f, v[1], v[0]); }
00287 };
00288
00290 template <class T>
00291 struct Cubic : public Base<4,T>{
00292 using Base<4,T>::v;
00293 Cubic(const T& v=0): Base<4,T>(v){}
00294 T operator()(float f) const { return ipl::cubic(f, v[3], v[2], v[1], v[0]); }
00295 T val() const { return v[1]; }
00296 void val(const T& va){ v[1]=va; }
00297 };
00298
00300 template <class T>
00301 struct Cosine : public Base<2,T>{
00302 using Base<2,T>::v;
00303 Cosine(const T& v=0): Base<2,T>(v){}
00304 T operator()(float f) const { return ipl::linear(scl::mapSinUU(f), v[1], v[0]); }
00305 };
00306
00307 }
00308
00309
00310
00312
00313
00314
00315
00316
00317
00318 namespace tap{
00319
00321 struct Clip{
00322 void reset(){}
00323
00324 uint32_t& operator()(uint32_t& pos, uint32_t inc){
00325 uint32_t prev = pos;
00326 pos += inc;
00327 if(~pos & prev & 0x80000000) pos = 0xffffffff;
00328
00329
00330
00331
00332 return pos;
00333 }
00334 bool done(uint32_t pos) const { return pos == 0xffffffff; }
00335
00336 template <class T>
00337 T operator()(T v, T inc, T max, T min){ return scl::clip(v+inc, max, min); }
00338 };
00339
00341 struct Fold{
00342 Fold(): dir(0){}
00343
00344 void reset(){ dir=0; }
00345
00346 uint32_t& operator()(uint32_t& pos, uint32_t inc){
00347 uint32_t prev = pos;
00348 pos += dir ? -inc : inc;
00349 if(~pos & prev & 0x80000000) dir^=1;
00350 return pos;
00351 }
00352
00353 bool done(uint32_t pos) const { return false; }
00354
00355 template <class T>
00356 T operator()(T v, T inc, T max, T min){
00357 v += dir ? -inc : inc;
00358 long n;
00359 v = scl::fold(v, n, max, min);
00360 dir ^= n!=0;
00361 return v;
00362 }
00363
00364 uint32_t dir;
00365 };
00366
00367
00369 struct Pat{
00370
00371 Pat(){
00372 pattern(0,0);
00373 reset();
00374 }
00375
00376 void reset(){ mPhase=0; mIndex=0; }
00377
00378 uint32_t& operator()(uint32_t& pos, uint32_t inc){
00379 uint32_t prev = mPhase;
00380 mPhase += inc;
00381
00382
00383
00384 if((~mPhase & prev) & 0x80000000){
00385 if(++mIndex >= mSize) mIndex=0;
00386 }
00387
00388 uint32_t bit = (mPattern >> (mSize-1 - mIndex)) & 1UL;
00389 if(bit){
00390 pos = mPhase;
00391 }
00392 return pos;
00393 }
00394
00395 Pat& pattern(uint32_t bits, uint16_t size){
00396 mPattern=bits;
00397 mSize=size;
00398 return *this;
00399 }
00400
00401 Pat& pattern(const char* bits){
00402 mSize = strlen(bits);
00403 mPattern = 0;
00404 for(int i=0; i<mSize; ++i){
00405 mPattern |= (bits[i]!='.') << (mSize-1-i);
00406 }
00407 return *this;
00408 }
00409
00410 private:
00411 uint32_t mPhase;
00412 uint32_t mPattern;
00413 uint16_t mIndex;
00414 uint16_t mSize;
00415 };
00416
00417
00419 struct Rep{
00420 Rep(){ number(1); reset(); }
00421
00422 void reset(){ mCount=0; }
00423
00424 uint32_t& operator()(uint32_t& pos, uint32_t inc){
00425 uint32_t prev = pos;
00426 pos += inc;
00427
00428
00429
00430 if((~pos & prev) & 0x80000000){
00431 if(++mCount >= mNumber) pos = 0xffffffff;
00432 }
00433 return pos;
00434 }
00435
00436 bool done(uint32_t pos) const { return (mCount >= mNumber) && (pos == 0xffffffff); }
00437
00438 template <class T>
00439 T operator()(T v, T inc, T max, T min){
00440 v += inc;
00441 if(v >= max || v < min) ++mCount;
00442 return mCount < mNumber ? scl::wrap(v, max, min) : scl::clip(v, max, min);
00443 }
00444
00445
00446 Rep& number(uint32_t v){ mNumber=v; return *this; }
00447
00448 private:
00449 uint32_t mNumber;
00450 uint32_t mCount;
00451 };
00452
00453
00455 struct Wrap{
00456 void reset(){}
00457
00458 uint32_t& operator()(uint32_t& pos, uint32_t inc){ return pos+=inc; }
00459 bool done(uint32_t pos) const { return false; }
00460
00461 template <class T>
00462 T operator()(T v, T inc, T max, T min){ return scl::wrap(v+inc, max, min); }
00463 };
00464
00465 }
00466
00467 }
00468 #endif