00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "PvConvert.h"
00021 #include <algorithm>
00022
00023
00024
00025 using std::ostringstream;
00026 using std::greater;
00027 using std::sort;
00028
00029 using namespace Marsyas;
00030
00031 PvConvert::PvConvert(mrs_string name):MarSystem("PvConvert",name)
00032 {
00033
00034
00035
00036 psize_ = 0;
00037 size_ = 0;
00038
00039 addControls();
00040 }
00041
00042 PvConvert::PvConvert(const PvConvert& a):MarSystem(a)
00043 {
00044 ctrl_mode_ = getctrl("mrs_string/mode");
00045 ctrl_phases_ = getctrl("mrs_realvec/phases");
00046 ctrl_regions_ = getctrl("mrs_realvec/regions");
00047
00048 psize_ = 0;
00049 }
00050
00051
00052
00053 PvConvert::~PvConvert()
00054 {
00055 }
00056
00057 MarSystem*
00058 PvConvert::clone() const
00059 {
00060 return new PvConvert(*this);
00061 }
00062
00063
00064 void
00065 PvConvert::addControls()
00066 {
00067 addctrl("mrs_natural/Decimation",MRS_DEFAULT_SLICE_NSAMPLES/4);
00068 addctrl("mrs_natural/Sinusoids", 1);
00069 setctrlState("mrs_natural/Sinusoids", true);
00070 addctrl("mrs_string/mode", "sorted", ctrl_mode_);
00071 addctrl("mrs_realvec/phases", realvec(), ctrl_phases_);
00072 addctrl("mrs_realvec/regions", realvec(), ctrl_regions_);
00073
00074
00075 }
00076
00077 void
00078 PvConvert::myUpdate(MarControlPtr sender)
00079 {
00080
00081 (void) sender;
00082 setctrl("mrs_natural/onSamples", getctrl("mrs_natural/inSamples"));
00083 setctrl("mrs_natural/onObservations", getctrl("mrs_natural/inObservations")->to<mrs_natural>() + 2);
00084 setctrl("mrs_real/osrate", getctrl("mrs_real/israte")->to<mrs_real>() * getctrl("mrs_natural/inObservations")->to<mrs_natural>());
00085
00086
00087 onObservations_ = getctrl("mrs_natural/onObservations")->to<mrs_natural>();
00088
00089 size_ = onObservations_ /2 +1;
00090
00091 if (size_ != psize_)
00092 {
00093 lastphase_.stretch(size_);
00094
00095 MarControlAccessor acc(ctrl_phases_);
00096 realvec& phase = acc.to<mrs_realvec>();
00097 MarControlAccessor acc1(ctrl_regions_);
00098 realvec& regions = acc1.to<mrs_realvec>();
00099
00100 phase.stretch(size_);
00101 regions.stretch(size_);
00102 mag_.stretch(size_);
00103 sortedmags_.stretch(size_);
00104 sortedpos_.stretch(size_);
00105 }
00106
00107 psize_ = size_;
00108
00109 factor_ = ((getctrl("mrs_real/osrate")->to<mrs_real>()) /
00110 (mrs_real)( getctrl("mrs_natural/Decimation")->to<mrs_natural>()* TWOPI));
00111
00112
00113
00114 fundamental_ = (mrs_real) (getctrl("mrs_real/osrate")->to<mrs_real>() / (mrs_real)getctrl("mrs_natural/inObservations")->to<mrs_natural>());
00115
00116
00117
00118
00119 kmax_ = getctrl("mrs_natural/Sinusoids")->to<mrs_natural>();
00120 }
00121
00122 void
00123 PvConvert::myProcessFull(realvec& in, realvec& out)
00124 {
00125 mrs_natural t;
00126 mrs_natural N2 = inObservations_/2;
00127
00128 mrs_real a;
00129 mrs_real b;
00130 mrs_real phasediff;
00131
00132 MarControlAccessor acc(ctrl_phases_);
00133 mrs_realvec& phases = acc.to<mrs_realvec>();
00134
00135 MarControlAccessor acc1(ctrl_regions_);
00136 mrs_realvec& regions = acc1.to<mrs_realvec>();
00137
00138
00139 mrs_real decimation = getctrl("mrs_natural/Decimation")->to<mrs_natural>() * 1.0;
00140 mrs_real one_over_decimation = 1.0 / decimation;
00141
00142 mrs_real omega_k;
00143
00144 const mrs_string& mode = ctrl_mode_->to<mrs_string>();
00145
00146
00147
00148
00149 for (t=0; t <= N2; t++)
00150 {
00151 if (t==0)
00152 {
00153 a = in(0,0);
00154 b = 0.0;
00155 }
00156 else if (t == N2)
00157 {
00158 a = in(1, 0);
00159 b = 0.0;
00160 }
00161 else
00162 {
00163 a = in(2*t, 0);
00164 b = in(2*t+1, 0);
00165 }
00166
00167 omega_k = (TWOPI * t) / (N2*2) ;
00168
00169
00170 out(2*t,0) = sqrt(a*a + b*b);
00171
00172 if (out(2*t,0) == 0.0)
00173 phasediff = 0.0;
00174 else
00175 {
00176 phases(t) = -atan2(b,a);
00177
00178 if (mode == "analysis_scaled_phaselock")
00179 {
00180
00181 phasediff = phases(t) - lastphase_((mrs_natural)regions(t)) - decimation * omega_k;
00182 }
00183 else
00184 {
00185
00186 phasediff = phases(t) - lastphase_(t) - decimation * omega_k;
00187 }
00188
00189 lastphase_(t) = phases(t);
00190
00191 while (phasediff > PI)
00192 phasediff -= TWOPI;
00193 while (phasediff < -PI)
00194 phasediff += TWOPI;
00195 }
00196
00197
00198 out(2*t+1, 0) = omega_k + one_over_decimation * phasediff;
00199 }
00200 }
00201
00202
00203
00204 void
00205 PvConvert::myProcess(realvec& in, realvec& out)
00206 {
00207
00208
00209 const mrs_string& mode = ctrl_mode_->to<mrs_string>();
00210 if ((mode == "full")||(mode == "analysis_scaled_phaselock"))
00211 myProcessFull(in,out);
00212 else if (mode == "sorted")
00213 myProcessSorted(in,out);
00214 else if (mode == "neighbors")
00215 myProcessNeighbors(in,out);
00216
00217 }
00218
00219
00220
00221
00222 void
00223 PvConvert::myProcessSorted(realvec& in, realvec& out)
00224 {
00225 mrs_natural c,t;
00226
00227 MarControlAccessor acc(ctrl_phases_);
00228 mrs_realvec& phases = acc.to<mrs_realvec>();
00229
00230 mrs_real decimation = getctrl("mrs_natural/Decimation")->to<mrs_natural>() * 1.0;
00231
00232 mrs_real one_over_decimation = 1.0 / decimation;
00233
00234
00235 mrs_natural N2 = inObservations_/2;
00236 mrs_real a;
00237 mrs_real b;
00238 mrs_real phasediff;
00239
00240 mrs_real omega_k;
00241
00242
00243 for (t=0; t <= N2; t++)
00244 {
00245 if (t==0)
00246 {
00247 a = in(2*t,0);
00248 b = 0.0;
00249 }
00250 else if (t == N2)
00251 {
00252 a = in(1, 0);
00253 b = 0.0;
00254 }
00255 else
00256 {
00257 a = in(2*t, 0);
00258 b = in(2*t+1, 0);
00259 }
00260
00261
00262 mag_(t) = sqrt(a*a + b*b);
00263 sortedmags_(t) = mag_(t);
00264
00265 phases(t) = -atan2(b,a);
00266
00267 }
00268
00269 mrs_real* data = sortedmags_.getData();
00270 sort(data, data+(N2+1), greater<mrs_real>());
00271
00272 bool found;
00273 mrs_real val;
00274
00275
00276 mrs_real sum = 0;
00277 mrs_real sorted_sum = 0;
00278
00279 for (t=0; t <= N2; t++)
00280 sum += mag_(t);
00281
00282
00283 int k = 0;
00284
00285 for (t=0; t <= N2; t++)
00286 {
00287 found = false;
00288 val = mag_(t);
00289
00290
00291 for (c=0; c < kmax_; ++c)
00292 {
00293
00294 if (val == sortedmags_(c))
00295 {
00296 sorted_sum += val;
00297 found = true;
00298 k++;
00299 break;
00300 }
00301 }
00302
00303
00304
00305 out(2*t,0) = 0.0;
00306 out(2*t+1,0) = t * fundamental_;
00307
00308 omega_k = (TWOPI * t) / (N2*2) ;
00309
00310 phasediff = phases(t) - lastphase_(t) - decimation * omega_k;
00311
00312 lastphase_(t) = phases(t);
00313
00314
00315 while (phasediff > PI)
00316 phasediff -= TWOPI;
00317 while (phasediff < -PI)
00318 phasediff += TWOPI;
00319
00320 if (found)
00321 {
00322 if (val == 0.0)
00323 phasediff = 0.0;
00324 else
00325 {
00326 out(2*t,0) = val;
00327 }
00328 out(2*t+1, 0) = omega_k + one_over_decimation * phasediff;
00329 }
00330 else
00331 {
00332 out(2*t+1, 0) = omega_k + one_over_decimation * phasediff;
00333 }
00334 }
00335
00336
00337
00338
00339 }
00340
00341 void
00342 PvConvert::myProcessNeighbors(realvec& in, realvec& out)
00343 {
00344
00345
00346 MarControlAccessor acc(ctrl_phases_);
00347 mrs_realvec& phases = acc.to<mrs_realvec>();
00348
00349 mrs_natural t;
00350 mrs_natural N2 = inObservations_/2;
00351 mrs_real a;
00352 mrs_real b;
00353 mrs_real phasediff;
00354
00355
00356 for (t=0; t <= N2; t++)
00357 {
00358 if (t==0)
00359 {
00360 a = in(2*t,0);
00361 b = 0.0;
00362 }
00363 else if (t == N2)
00364 {
00365 a = in(1, 0);
00366 b = 0.0;
00367 }
00368 else
00369 {
00370 a = in(2*t, 0);
00371 b = in(2*t+1, 0);
00372 }
00373
00374
00375 mag_(t) = sqrt(a*a + b*b);
00376 sortedmags_(t) = mag_(t);
00377
00378 phases(t) = -atan2(b,a);
00379
00380
00381 }
00382
00383 mrs_real* data = sortedmags_.getData();
00384 sort(data, data+(N2+1), greater<mrs_real>());
00385
00386 mrs_real val;
00387 val = 0.0;
00388
00389 for (t=0; t <= N2; t++)
00390 {
00391
00392 phasediff = phases(t) - lastphase_(t);
00393 lastphase_(t) = phases(t);
00394
00395
00396 while (phasediff > PI)
00397 phasediff -= TWOPI;
00398 while (phasediff < -PI)
00399 phasediff += TWOPI;
00400
00401 if ((t > 3) && (t <= N2-2))
00402 {
00403 if (
00404 (mag_(t) > mag_(t-1)) &&
00405
00406
00407 (mag_(t) > mag_(t+1))
00408 )
00409
00410 {
00411 val = mag_(t);
00412 }
00413 else
00414 val = 0.0;
00415 }
00416
00417 if (val == 0.0)
00418 phasediff = 0.0;
00419
00420 out(2*t,0) = val;
00421 out(2*t+1, 0) = phasediff * factor_ + t * fundamental_;
00422 }
00423 }
00424
00425