00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "common.h"
00020 #include "Delay.h"
00021
00022 using std::ostringstream;
00023 using std::vector;
00024
00025 using namespace Marsyas;
00026
00027
00028
00029 static inline mrs_natural wrapCursor (mrs_natural unwrappedCursor, mrs_natural cursorMask)
00030 {
00031
00032 return (unwrappedCursor + (cursorMask+1)) & cursorMask;
00033 }
00034
00035 static inline mrs_real getValue (mrs_natural obs, mrs_real index, mrs_realvec& buffer, mrs_natural cursorMask)
00036 {
00037 mrs_natural integer = (mrs_natural)index + ((index < 0)? -1 : 0);
00038 mrs_real frac = index - integer;
00039 mrs_real retVal = buffer(obs, wrapCursor (integer, cursorMask));
00040
00041 return retVal + frac * (buffer(obs, wrapCursor (integer+1, cursorMask))-retVal);
00042 }
00043
00044 Delay::Delay(mrs_string name):MarSystem("Delay",name)
00045 {
00046
00047 delayInSamples_.create(0);
00048 writeCursor_ = 0;
00049
00050 cursorMask_ = 1;
00051
00052 addControls();
00053 }
00054
00055
00056 Delay::~Delay()
00057 {
00058 }
00059
00060
00061 MarSystem*
00062 Delay::clone() const
00063 {
00064 return new Delay(*this);
00065 }
00066
00067 Delay::Delay(const Delay& a) : MarSystem(a)
00068 {
00069 addControls();
00070 maxDelayLengthInSamples_ = getctrl("mrs_real/maxDelaySamples")->to<mrs_real>();
00071 delayInSamples_ = getctrl("mrs_realvec/delaySamples")->to<mrs_realvec>();
00072 }
00073
00074 void
00075 Delay::addControls()
00076 {
00077 mrs_realvec tmp(1);
00078 tmp(0) = 0;
00079 addctrl("mrs_real/maxDelaySamples", 32.0);
00080 addctrl("mrs_real/maxDelaySeconds", 0.0);
00081 addctrl("mrs_real/delaySamples", 0.0);
00082 addctrl("mrs_real/delaySeconds", 0.0);
00083 addctrl("mrs_realvec/delaySamples", tmp);
00084 addctrl("mrs_realvec/delaySeconds", tmp);
00085 setctrlState("mrs_real/maxDelaySamples", true);
00086 setctrlState("mrs_real/maxDelaySeconds", true);
00087 setctrlState("mrs_real/delaySeconds", true);
00088 setctrlState("mrs_real/delaySamples", true);
00089 setctrlState("mrs_realvec/delaySeconds", true);
00090 setctrlState("mrs_realvec/delaySamples", true);
00091 }
00092
00093
00094 void
00095 Delay::myUpdate(MarControlPtr sender)
00096 {
00097 (void) sender;
00098 MRSDIAG("Delay.cpp - Delay:myUpdate");
00099
00100
00101 if (samples2Seconds (maxDelayLengthInSamples_) != getctrl ("mrs_real/maxDelaySeconds")->to<mrs_real>())
00102 {
00103 maxDelayLengthInSamples_ = seconds2Samples (getctrl ("mrs_real/maxDelaySeconds")->to<mrs_real>());
00104 setctrl("mrs_real/maxDelaySamples", maxDelayLengthInSamples_);
00105 buffer_.stretch (getctrl("mrs_natural/inObservations")->to<mrs_natural>(), nextPowOfTwo((mrs_natural(.1+ceil(maxDelayLengthInSamples_))+1)));
00106 buffer_.setval(0);
00107 }
00108 if (maxDelayLengthInSamples_ != getctrl ("mrs_real/maxDelaySamples")->to<mrs_real>())
00109 {
00110 maxDelayLengthInSamples_ = getctrl ("mrs_real/maxDelaySamples")->to<mrs_real>();
00111 setctrl("mrs_real/maxDelaySeconds", samples2Seconds (maxDelayLengthInSamples_));
00112 buffer_.stretch (getctrl("mrs_natural/inObservations")->to<mrs_natural>(), nextPowOfTwo((mrs_natural(.1+ceil(maxDelayLengthInSamples_))+1)));
00113 buffer_.setval(0);
00114 }
00115
00116 if (samples2Seconds (singleDelayInSamples_) != getctrl ("mrs_real/delaySeconds")->to<mrs_real>())
00117 {
00118 mrs_realvec tmp(1);
00119 singleDelayInSamples_ = seconds2Samples (getctrl ("mrs_real/delaySeconds")->to<mrs_real>());
00120 MRSASSERT(singleDelayInSamples_ >= 0);
00121 MRSASSERT(singleDelayInSamples_ <= maxDelayLengthInSamples_);
00122
00123 setctrl("mrs_real/delaySamples", singleDelayInSamples_);
00124
00125
00126 tmp(0) = singleDelayInSamples_;
00127 setctrl("mrs_realvec/delaySamples", tmp);
00128 }
00129 if (singleDelayInSamples_ != getctrl ("mrs_real/delaySamples")->to<mrs_real>())
00130 {
00131 mrs_realvec tmp(1);
00132 singleDelayInSamples_ = getctrl ("mrs_real/delaySamples")->to<mrs_real>();
00133 MRSASSERT(singleDelayInSamples_ >= 0);
00134 MRSASSERT(singleDelayInSamples_ <= maxDelayLengthInSamples_);
00135
00136 setctrl("mrs_real/delaySeconds", samples2Seconds (singleDelayInSamples_));
00137
00138
00139 tmp(0) = singleDelayInSamples_;
00140 setctrl("mrs_realvec/delaySamples", tmp);
00141 }
00142
00143 if (delayInSamples_ != getctrl ("mrs_realvec/delaySamples")->to<mrs_realvec>())
00144 {
00145 delayInSamples_ = getctrl ("mrs_realvec/delaySamples")->to<mrs_realvec>();
00146 setctrl("mrs_realvec/delaySeconds", samples2Seconds (delayInSamples_));
00147 }
00148 if (samples2Seconds (delayInSamples_) != getctrl ("mrs_realvec/delaySeconds")->to<mrs_realvec>())
00149 {
00150 delayInSamples_ = seconds2Samples (getctrl ("mrs_realvec/delaySeconds")->to<mrs_realvec>());
00151 setctrl("mrs_realvec/delaySamples", delayInSamples_);
00152 }
00153
00154
00155 buffer_.stretch (getctrl("mrs_natural/inObservations")->to<mrs_natural>(), nextPowOfTwo((mrs_natural(.1+ceil(maxDelayLengthInSamples_))+1)));
00156 cursorMask_ = buffer_.getCols () - 1;
00157 if (prevDelayInSamples_.getSize () != delayInSamples_.getSize ())
00158 {
00159
00160 ctrlIncrement_.stretch (delayInSamples_.getSize (), delayInSamples_.getCols ());
00161 prevDelayInSamples_ = delayInSamples_;
00162
00163
00164 buffer_.stretch (getctrl("mrs_natural/inObservations")->to<mrs_natural>(), nextPowOfTwo((mrs_natural(.1+ceil(maxDelayLengthInSamples_))+1)));
00165 buffer_.setval(0);
00166 writeCursor_ = 0;
00167
00168
00169 vector<mrs_string> indiChannels = stringSplit (getctrl("mrs_string/inObsNames")->to<mrs_string>(), ",");
00170 ostringstream outNames;
00171 for (mrs_natural c = 0; c < getctrl("mrs_natural/inObservations")->to<mrs_natural>(); ++c)
00172 for (mrs_natural i = 0; i < delayInSamples_.getSize (); ++i)
00173 {
00174 outNames << indiChannels.at(c) << "-delay_" << i << ",";
00175 }
00176 setctrl("mrs_string/onObsNames", outNames.str());
00177 }
00178
00179
00180 setctrl("mrs_natural/onSamples", getctrl("mrs_natural/inSamples"));
00181 setctrl("mrs_real/osrate", getctrl("mrs_real/israte"));
00182 setctrl("mrs_natural/onObservations", (mrs_natural) delayInSamples_.getSize () * getctrl("mrs_natural/inObservations")->to<mrs_natural>());
00183
00184 }
00185
00186
00187 void
00188 Delay::myProcess(realvec& in, realvec& out)
00189 {
00190 mrs_natural k, numDelayLines = delayInSamples_.getSize ();
00191 mrs_natural o,t;
00192
00193 getLinearInterPInc (prevDelayInSamples_, delayInSamples_, ctrlIncrement_, inSamples_);
00194
00195 #ifdef MARSYAS_MATLAB
00196 #ifdef MTLB_DBG_LOG
00197 MATLAB_PUT(in, "in");
00198 MATLAB_EVAL("figure(41),subplot(211),plot(in'),axis('tight'),grid on, title('in')");
00199 #endif
00200 #endif
00201
00202 for (t = 0; t < inSamples_; t++)
00203 {
00204 for (o=0; o < inObservations_; o++)
00205 {
00206
00207 buffer_(o, writeCursor_) = in(o,t);
00208 for (k = 0; k < numDelayLines; k++)
00209 {
00210
00211 out(k+o*numDelayLines,t) = getValue (o, writeCursor_ - (prevDelayInSamples_(k) + t*ctrlIncrement_(k)), buffer_, cursorMask_);
00212 }
00213
00214 }
00215 writeCursor_ = wrapCursor (++writeCursor_, cursorMask_);
00216 }
00217
00218 prevDelayInSamples_ = delayInSamples_;
00219
00220
00221 #ifdef MARSYAS_MATLAB
00222 #ifdef MTLB_DBG_LOG
00223 MATLAB_PUT(out, "out");
00224 MATLAB_EVAL("figure(41),subplot(212),plot(out'),axis('tight'),grid on, title('out')");
00225 #endif
00226 #endif
00227 }
00228
00229 void Delay::getLinearInterPInc (const mrs_realvec startVal, const mrs_realvec stopVal, mrs_realvec &incVal, const mrs_natural numSamples)
00230 {
00231 incVal = (stopVal - startVal);
00232 incVal /= (1.0*numSamples);
00233 }
00234
00235 mrs_natural Delay::nextPowOfTwo (mrs_natural value)
00236 {
00237 mrs_natural order = 0;
00238
00239 while (value>>order)
00240 order++;
00241
00242 if (!order)
00243 return value;
00244
00245 if (!(value%(1<<(order-1))))
00246 order--;
00247
00248 order = (order < 1)? 1 : order;
00249
00250 return (1<<(order));
00251 }
00252
00253 mrs_real Delay::samples2Seconds (mrs_real samples)
00254 {
00255 if (israte_ > 0)
00256 return samples / israte_;
00257 else
00258 return 0;
00259 }
00260 mrs_real Delay::seconds2Samples (mrs_real seconds)
00261 {
00262 return seconds * israte_;
00263 }
00264 mrs_realvec Delay::samples2Seconds (mrs_realvec samples)
00265 {
00266 for (mrs_natural i = 0; i < samples.getSize (); ++i)
00267 samples(i) = samples(i)/ israte_;
00268
00269 return samples;
00270 }
00271 mrs_realvec Delay::seconds2Samples (mrs_realvec seconds)
00272 {
00273 for (mrs_natural i = 0; i < seconds.getSize (); ++i)
00274 seconds(i) = seconds(i) * israte_;
00275
00276 return seconds;
00277 }