Home   Information   Classes   Download   Usage   Mail List   Requirements   Links   FAQ   Tutorial


DelayL.h
1 #ifndef STK_DELAYL_H
2 #define STK_DELAYL_H
3 
4 #include "Filter.h"
5 
6 namespace stk {
7 
8 /***************************************************/
25 /***************************************************/
26 
27 class DelayL : public Filter
28 {
29 public:
30 
32 
37  DelayL( StkFloat delay = 0.0, unsigned long maxDelay = 4095 );
38 
40  ~DelayL();
41 
43  unsigned long getMaximumDelay( void ) { return inputs_.size() - 1; };
44 
46 
53  void setMaximumDelay( unsigned long delay );
54 
56 
59  void setDelay( StkFloat delay );
60 
62  StkFloat getDelay( void ) const { return delay_; };
63 
65 
70  StkFloat tapOut( unsigned long tapDelay );
71 
73  void tapIn( StkFloat value, unsigned long tapDelay );
74 
76  StkFloat lastOut( void ) const { return lastFrame_[0]; };
77 
79 
82  StkFloat nextOut( void );
83 
85  StkFloat tick( StkFloat input );
86 
88 
96  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
97 
99 
107  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
108 
109  protected:
110 
111  unsigned long inPoint_;
112  unsigned long outPoint_;
113  StkFloat delay_;
114  StkFloat alpha_;
115  StkFloat omAlpha_;
116  StkFloat nextOutput_;
117  bool doNextOut_;
118 };
119 
120 inline StkFloat DelayL :: nextOut( void )
121 {
122  if ( doNextOut_ ) {
123  // First 1/2 of interpolation
124  nextOutput_ = inputs_[outPoint_] * omAlpha_;
125  // Second 1/2 of interpolation
126  if (outPoint_+1 < inputs_.size())
127  nextOutput_ += inputs_[outPoint_+1] * alpha_;
128  else
129  nextOutput_ += inputs_[0] * alpha_;
130  doNextOut_ = false;
131  }
132 
133  return nextOutput_;
134 }
135 
136 inline void DelayL :: setDelay( StkFloat delay )
137 {
138  if ( delay + 1 > inputs_.size() ) { // The value is too big.
139  oStream_ << "DelayL::setDelay: argument (" << delay << ") greater than maximum!";
140  handleError( StkError::WARNING ); return;
141  }
142 
143  if (delay < 0 ) {
144  oStream_ << "DelayL::setDelay: argument (" << delay << ") less than zero!";
145  handleError( StkError::WARNING ); return;
146  }
147 
148  StkFloat outPointer = inPoint_ - delay; // read chases write
149  delay_ = delay;
150 
151  while ( outPointer < 0 )
152  outPointer += inputs_.size(); // modulo maximum length
153 
154  outPoint_ = (long) outPointer; // integer part
155 
156  alpha_ = outPointer - outPoint_; // fractional part
157  omAlpha_ = (StkFloat) 1.0 - alpha_;
158 
159  if ( outPoint_ == inputs_.size() ) outPoint_ = 0;
160  doNextOut_ = true;
161 }
162 
163 inline StkFloat DelayL :: tick( StkFloat input )
164 {
165  inputs_[inPoint_++] = input * gain_;
166 
167  // Increment input pointer modulo length.
168  if ( inPoint_ == inputs_.size() )
169  inPoint_ = 0;
170 
171  lastFrame_[0] = nextOut();
172  doNextOut_ = true;
173 
174  // Increment output pointer modulo length.
175  if ( ++outPoint_ == inputs_.size() )
176  outPoint_ = 0;
177 
178  return lastFrame_[0];
179 }
180 
181 inline StkFrames& DelayL :: tick( StkFrames& frames, unsigned int channel )
182 {
183 #if defined(_STK_DEBUG_)
184  if ( channel >= frames.channels() ) {
185  oStream_ << "DelayL::tick(): channel and StkFrames arguments are incompatible!";
186  handleError( StkError::FUNCTION_ARGUMENT );
187  }
188 #endif
189 
190  StkFloat *samples = &frames[channel];
191  unsigned int hop = frames.channels();
192  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
193  inputs_[inPoint_++] = *samples * gain_;
194  if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
195  *samples = nextOut();
196  doNextOut_ = true;
197  if ( ++outPoint_ == inputs_.size() ) outPoint_ = 0;
198  }
199 
200  lastFrame_[0] = *(samples-hop);
201  return frames;
202 }
203 
204 inline StkFrames& DelayL :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
205 {
206 #if defined(_STK_DEBUG_)
207  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
208  oStream_ << "DelayL::tick(): channel and StkFrames arguments are incompatible!";
209  handleError( StkError::FUNCTION_ARGUMENT );
210  }
211 #endif
212 
213  StkFloat *iSamples = &iFrames[iChannel];
214  StkFloat *oSamples = &oFrames[oChannel];
215  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
216  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
217  inputs_[inPoint_++] = *iSamples * gain_;
218  if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
219  *oSamples = nextOut();
220  doNextOut_ = true;
221  if ( ++outPoint_ == inputs_.size() ) outPoint_ = 0;
222  }
223 
224  lastFrame_[0] = *(oSamples-oHop);
225  return iFrames;
226 }
227 
228 } // stk namespace
229 
230 #endif

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