Home Information Classes Download Usage Mail List Requirements Links FAQ Tutorial

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::tick
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
stk::Chorus::Chorus
Chorus(StkFloat baseDelay=6000)
Class constructor, taking the median desired delay length.
stk::Chorus::clear
void clear(void)
Reset and clear all internal state.
stk::Chorus::setModFrequency
void setModFrequency(StkFloat frequency)
Set modulation frequency.
stk::Chorus::lastOut
StkFloat lastOut(unsigned int channel=0)
Return the specified channel value of the last computed stereo frame.
Definition Chorus.h:93
stk::Chorus::setModDepth
void setModDepth(StkFloat depth)
Set modulation depth in range 0.0 - 1.0.
stk::DelayL
STK linear interpolating delay line class.
Definition DelayL.h:28
stk::Effect::Effect
Effect(void)
Class constructor.
Definition Effect.h:25
stk::SineWave
STK sinusoid oscillator class.
Definition SineWave.h:26
stk::StkFrames
An STK class to handle vectorized audio data.
Definition Stk.h:279
stk::StkFrames::channels
unsigned int channels(void) const
Return the number of channels represented by the data.
Definition Stk.h:416
stk::StkFrames::frames
unsigned int frames(void) const
Return the number of sample frames represented by the data.
Definition Stk.h:419
stk::Stk::handleError
static void handleError(const char *message, StkError::Type type)
Static function for error reporting and handling using c-strings.
stk
The STK namespace.
Definition ADSR.h:6

The Synthesis ToolKit in C++ (STK)
©1995--2023 Perry R. Cook and Gary P. Scavone. All Rights Reserved.