14 #include "CrossFade.h"
15 #include "CrossFadeQueue.h"
16 #include "Properties.h"
17 #if defined(TT_PLATFORM_MAC)
19 #include <CoreServices/CoreServices.h>
21 #include "ext_critical.h"
28 extern bool globReportFlag;
29 extern bool globWarningFlag;
33 fadeThreshold_(newFadeThreshold),
34 fadeLength_(newFadeLength),
36 sampleRate_(sampleRate),
44 post (
"Invalid fadelength, set to default of %d samps", fadeLength_);
54 while (!fadeQueue_.empty())
56 delete fadeQueue_.front();
57 fadeQueue_.pop_front();
63 return fadeTbl_[index];
73 if (newFadeLength > 0)
75 fadeLength_ = newFadeLength;
82 else if (globWarningFlag)
83 error(
"Invalid fadelength %d, no action taken", newFadeLength);
86 post(
"FadeLength: %d", fadeLength_);
97 case Properties::COS_SQUARED:
98 post(
"x-fade fade-function: cosine squared");
101 case Properties::COS:
102 post(
"x-fade fade-function: cosine");
105 case Properties::LINEAR:
106 post(
"x-fade fade-function: linear");
109 case Properties::TANH:
110 post(
"x-fade fade-function: tangens hyperbolicus");
113 case Properties::SQRT:
114 post(
"x-fade fade-function: square root");
117 case Properties::LOG:
118 post(
"x-fade fade-function: logarithm");
121 case Properties::SIGMOID:
122 post(
"x-fade fade-function: Sigmoid");
130 void CrossFadeQueue::computeFadeTbl()
132 fadeTbl_.resize(fadeLength_);
142 double a = log(7.)/width;
143 double f0=tanh(a*(-b));
144 double f1=tanh(a*(1-b));
146 double alpha = 1/(f1-f0);
152 case Properties::COS:
155 for (i = 0.0, tableIdx = 0; tableIdx < fadeLength_; i += (double) (
kTTPi / (fadeLength_ - 1)), tableIdx++)
157 fadeTbl_[tableIdx] = (double) 0.5*(1.0 + cos(i));
161 case Properties::COS_SQUARED:
164 for (i = 0.0, tableIdx = 0; tableIdx < fadeLength_; i += (double) (1.0 / (fadeLength_ -1)), tableIdx++)
166 fadeTbl_[tableIdx] = (double) (1.0 + cos(i*i*
kTTPi))*0.5;
170 case Properties::LINEAR:
171 for (i = 1.0, tableIdx = 0; tableIdx < fadeLength_; i -= (double) (1.0 / (fadeLength_ -1)), tableIdx++)
173 fadeTbl_[tableIdx] = (double) i;
177 case Properties::TANH:
178 for (i = 1.0, tableIdx = 0; tableIdx < fadeLength_; i -= (double) (1.0 / (fadeLength_ -1)), tableIdx++)
180 fadeTbl_[tableIdx] = (double) alpha*(tanh(a*(i-b)) - beta);
184 case Properties::LOG:
186 for (i = 1.0, tableIdx = 0; tableIdx < fadeLength_; i -= (double) (1.0 / (fadeLength_ )), tableIdx++)
188 fadeTbl_[tableIdx] = (double) 20*log10((i)*pow(10.0,((1-i)*0.05)));
190 double temp = -1.0 * fadeTbl_[fadeLength_ -1];
191 for (tableIdx = 0; tableIdx < fadeLength_; tableIdx++)
192 fadeTbl_[tableIdx] = (fadeTbl_[tableIdx]+temp)/(temp);
196 case Properties::SIGMOID:
199 for (i = -8.0, tableIdx = 0; tableIdx < fadeLength_; i += (double) (16.0 / (fadeLength_- 1)), tableIdx++)
201 fadeTbl_[tableIdx] = (double) 1.0 / (1.0 + exp(i));
216 case Properties::SQRT:
217 for (i = 1.0, tableIdx = 0; tableIdx < fadeLength_; i -= (double) (1.0 / (fadeLength_ - 1)), tableIdx++)
219 fadeTbl_[tableIdx] = sqrt(i);
225 if (fadeType_ != Properties::SIGMOID)
226 fadeTbl_[fadeLength_ - 1] = 0.0;
230 for (tableIdx = 0; tableIdx < fadeLength_; tableIdx++)
231 post(
"Fade[%d]: %f", tableIdx, fadeTbl_[tableIdx]);
236 void CrossFadeQueue::notifyCrossFades()
240 for (std::deque< CrossFade *>::iterator iter = fadeQueue_.begin(); iter != fadeQueue_.end(); ++iter)
241 (*iter)->update(fadeLength_);
259 fadeQueue_.push_back(
new CrossFade(*
this));
271 post(
"new crossfade added, total crossfades = %d", fadeQueue_.size());
280 return fadeQueue_.size();
285 return fadeThreshold_;
290 if (newThreshold >= 1)
291 fadeThreshold_ = newThreshold;
292 else if (globWarningFlag)
293 error(
"Invalid crossfade threshold %ld, must be >= 1", newThreshold);
296 post(
"Crossfade threshold in samples: %d", fadeThreshold_);
302 delete fadeQueue_.front();
303 fadeQueue_.pop_front();
308 fadeQueue_.front()->increment();
313 return !fadeQueue_.empty();
318 return fadeQueue_.front()->tick(fadeInInput, fadeOutInput);
326 return fadeQueue_.front()->atStart();
long fadeThreshold() const
Get fade threshold in samples.
bool atStart() const
True if at beginning of crossfade.
~CrossFadeQueue()
Class destructor.
bool isActive() const
True if a crossfade is underway, false othewise.
void fadeFunction(Properties::fadeMode fadeType)
Set fade type (LINEAR, COS, COS_SQUARED, TANH, SQRT, LOG, SIGMOID)
CrossFadeQueue(long fadeThreshold, long fadeLength, Properties::fadeMode fadeType, double sampleRate)
Jamoma's lowest-level base class and related infrastructure.
double fadeLength() const
Get fade time in samples.
bool startFade()
Triggers a crossfade, returns true if fade has started.
double getTblValAt(int index) const
Returns crossfade table value at given index.
void increment()
Increment top level crossfade.
void finishFade()
Manages cleanup and end of crossfade.
TTFOUNDATION_EXPORT const TTFloat64 kTTPi
[doxygenAppendixC_constExample]
int size()
Return number of crossfades being queued.
double tick(double fadeInInput, double fadeOutInput)
Out value of crossfade.