Cubic.h
1 #ifndef STK_CUBIC_H
2 #define STK_CUBIC_H
3
4 #include "Function.h"
5 #include <cmath>
6
7 namespace stk {
8
9 /***************************************************/
27 /***************************************************/
28
29 class Cubic : public Function
30 {
31 public:
33  Cubic( void ) : a1_(0.5), a2_(0.5), a3_(0.5), gain_(1.0), threshold_(1.0) {};
34
36  void setA1( StkFloat a1 ) { a1_ = a1; };
37
39  void setA2( StkFloat a2 ) { a2_ = a2; };
40
42  void setA3( StkFloat a3 ) { a3_ = a3; };
43
45  void setGain( StkFloat gain ) { gain_ = gain; };
46
48  void setThreshold( StkFloat threshold ) { threshold_ = threshold; };
49
51  StkFloat tick( StkFloat input );
52
54
62  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
63
65
73  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
74
75 protected:
76
77  StkFloat a1_;
78  StkFloat a2_;
79  StkFloat a3_;
80  StkFloat gain_;
81  StkFloat threshold_;
82 };
83
84 inline StkFloat Cubic :: tick( StkFloat input )
85 {
86  StkFloat inSquared = input * input;
87  StkFloat inCubed = inSquared * input;
88
89  lastFrame_[0] = gain_ * (a1_ * input + a2_ * inSquared + a3_ * inCubed);
90
91  // Apply threshold if we are out of range.
92  if ( fabs( lastFrame_[0] ) > threshold_ ) {
93  lastFrame_[0] = ( lastFrame_[0] < 0 ? -threshold_ : threshold_ );
94  }
95
96  return lastFrame_[0];
97 }
98
99 inline StkFrames& Cubic :: tick( StkFrames& frames, unsigned int channel )
100 {
101 #if defined(_STK_DEBUG_)
102  if ( channel >= frames.channels() ) {
103  oStream_ << "Cubic::tick(): channel and StkFrames arguments are incompatible!";
104  handleError( StkError::FUNCTION_ARGUMENT );
105  }
106 #endif
107
108  StkFloat *samples = &frames[channel];
109  unsigned int hop = frames.channels();
110  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
111  *samples = tick( *samples );
112
113  lastFrame_[0] = *(samples-hop);
114  return frames;
115 }
116
117 inline StkFrames& Cubic :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
118 {
119 #if defined(_STK_DEBUG_)
120  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
121  oStream_ << "Cubic::tick(): channel and StkFrames arguments are incompatible!";
122  handleError( StkError::FUNCTION_ARGUMENT );
123  }
124 #endif
125
126  StkFloat *iSamples = &iFrames[iChannel];
127  StkFloat *oSamples = &oFrames[oChannel];
128  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
129  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop )
130  *oSamples = tick( *iSamples );
131
132  lastFrame_[0] = *(oSamples-oHop);
133  return iFrames;
134 }
135
136 } // stk namespace
137
138 #endif