Arduino STK  4.6.2
Chorus.h
1 #ifndef STK_CHORUS_H
2 #define STK_CHORUS_H
3 
4 #include "Effect.h"
5 #include "DelayL.h"
6 #include "SineWave.h"
7 
8 namespace stk {
9 
10 /***************************************************/
19 /***************************************************/
20 
21 class Chorus : public Effect
22 {
23  public:
25 
28  Chorus( StkFloat baseDelay = 6000 );
29 
31  void clear( void );
32 
34  void setModDepth( StkFloat depth );
35 
37  void setModFrequency( StkFloat frequency );
38 
40 
48  StkFloat lastOut( unsigned int channel = 0 );
49 
51 
58  StkFloat tick( StkFloat input, unsigned int channel = 0 );
59 
61 
70  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
71 
73 
82  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
83 
84  protected:
85 
86  DelayL delayLine_[2];
87  SineWave mods_[2];
88  StkFloat baseLength_;
89  StkFloat modDepth_;
90 
91 };
92 
93 inline StkFloat Chorus :: lastOut( unsigned int channel )
94 {
95 #if defined(_STK_DEBUG_)
96  if ( channel > 1 ) {
97  oStream_ << "Chorus::lastOut(): channel argument must be less than 2!";
98  handleError( StkError::FUNCTION_ARGUMENT );
99  }
100 #endif
101 
102  return lastFrame_[channel];
103 }
104 
105 inline StkFloat Chorus :: tick( StkFloat input, unsigned int channel )
106 {
107 #if defined(_STK_DEBUG_)
108  if ( channel > 1 ) {
109  oStream_ << "Chorus::tick(): channel argument must be less than 2!";
110  handleError( StkError::FUNCTION_ARGUMENT );
111  }
112 #endif
113 
114  delayLine_[0].setDelay( baseLength_ * 0.707 * ( 1.0 + modDepth_ * mods_[0].tick() ) );
115  delayLine_[1].setDelay( baseLength_ * 0.5 * ( 1.0 - modDepth_ * mods_[1].tick() ) );
116  lastFrame_[0] = effectMix_ * ( delayLine_[0].tick( input ) - input ) + input;
117  lastFrame_[1] = effectMix_ * ( delayLine_[1].tick( input ) - input ) + input;
118  return lastFrame_[channel];
119 }
120 
121 inline StkFrames& Chorus :: tick( StkFrames& frames, unsigned int channel )
122 {
123 #if defined(_STK_DEBUG_)
124  if ( channel >= frames.channels() - 1 ) {
125  oStream_ << "Chorus::tick(): channel and StkFrames arguments are incompatible!";
126  handleError( StkError::FUNCTION_ARGUMENT );
127  }
128 #endif
129 
130  StkFloat *samples = &frames[channel];
131  unsigned int hop = frames.channels() - 1;
132  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
133  delayLine_[0].setDelay( baseLength_ * 0.707 * ( 1.0 + modDepth_ * mods_[0].tick() ) );
134  delayLine_[1].setDelay( baseLength_ * 0.5 * ( 1.0 - modDepth_ * mods_[1].tick() ) );
135  *samples = effectMix_ * ( delayLine_[0].tick( *samples ) - *samples ) + *samples;
136  samples++;
137  *samples = effectMix_ * ( delayLine_[1].tick( *samples ) - *samples ) + *samples;
138  }
139 
140  lastFrame_[0] = *(samples-hop);
141  lastFrame_[1] = *(samples-hop+1);
142  return frames;
143 }
144 
145 inline StkFrames& Chorus :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
146 {
147 #if defined(_STK_DEBUG_)
148  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() - 1 ) {
149  oStream_ << "Chorus::tick(): channel and StkFrames arguments are incompatible!";
150  handleError( StkError::FUNCTION_ARGUMENT );
151  }
152 #endif
153 
154  StkFloat *iSamples = &iFrames[iChannel];
155  StkFloat *oSamples = &oFrames[oChannel];
156  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
157  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
158  delayLine_[0].setDelay( baseLength_ * 0.707 * ( 1.0 + modDepth_ * mods_[0].tick() ) );
159  delayLine_[1].setDelay( baseLength_ * 0.5 * ( 1.0 - modDepth_ * mods_[1].tick() ) );
160  *oSamples = effectMix_ * ( delayLine_[0].tick( *iSamples ) - *iSamples ) + *iSamples;
161  *(oSamples+1) = effectMix_ * ( delayLine_[1].tick( *iSamples ) - *iSamples ) + *iSamples;
162  }
163 
164  lastFrame_[0] = *(oSamples-oHop);
165  lastFrame_[1] = *(oSamples-oHop+1);
166  return iFrames;
167 }
168 
169 } // stk namespace
170 
171 #endif
172 
STK chorus effect class.
Definition: Chorus.h:22
StkFloat tick(StkFloat input, unsigned int channel=0)
Input one sample to the effect and return the specified channel value of the computed stereo frame.
Definition: Chorus.h:105
Chorus(StkFloat baseDelay=6000)
Class constructor, taking the median desired delay length.
void clear(void)
Reset and clear all internal state.
void setModFrequency(StkFloat frequency)
Set modulation frequency.
StkFloat lastOut(unsigned int channel=0)
Return the specified channel value of the last computed stereo frame.
Definition: Chorus.h:93
void setModDepth(StkFloat depth)
Set modulation depth in range 0.0 - 1.0.
STK linear interpolating delay line class.
Definition: DelayL.h:28
StkFloat tick(StkFloat input)
Input one sample to the filter and return one output.
Definition: DelayL.h:163
void setDelay(StkFloat delay)
Set the delay-line length.
Definition: DelayL.h:136
STK abstract effects parent class.
Definition: Effect.h:22
STK sinusoid oscillator class.
Definition: SineWave.h:26
An STK class to handle vectorized audio data.
Definition: Stk.h:287
unsigned int channels(void) const
Return the number of channels represented by the data.
Definition: Stk.h:415
unsigned int frames(void) const
Return the number of sample frames represented by the data.
Definition: Stk.h:418
static void handleError(const char *message, StkError::Type type)
Static function for error reporting and handling using c-strings.
The STK namespace.
Definition: ADSR.h:8