Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/CollectionFileSource.cpp
Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 1998-2011 George Tzanetakis <gtzan@cs.uvic.ca>
00003 **
00004 ** This program is free software; you can redistribute it and/or modify
00005 ** it under the terms of the GNU General Public License as published by
00006 ** the Free Software Foundation; either version 2 of the License, or
00007 ** (at your option) any later version.
00008 **
00009 ** This program is distributed in the hope that it will be useful,
00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 ** GNU General Public License for more details.
00013 **
00014 ** You should have received a copy of the GNU General Public License
00015 ** along with this program; if not, write to the Free Software
00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017 */
00018 
00019 #include "CollectionFileSource.h"
00020 
00021 using std::ostringstream;
00022 using namespace Marsyas;
00023 
00024 CollectionFileSource::CollectionFileSource(mrs_string name):AbsSoundFileSource("CollectionFileSource", name)
00025 {
00026   addControls();
00027   iHasData_ = false;
00028   iLastTickWithData_ = true;
00029   iNewFile_ = true;
00030 }
00031 
00032 CollectionFileSource::CollectionFileSource(const CollectionFileSource& a):AbsSoundFileSource(a)
00033 {
00034   ctrl_currentlyPlaying_ = getctrl("mrs_string/currentlyPlaying");
00035   ctrl_previouslyPlaying_ = getctrl("mrs_string/previouslyPlaying");
00036   ctrl_regression_ = getctrl("mrs_bool/regression");
00037   ctrl_currentLabel_ = getctrl("mrs_real/currentLabel");
00038   ctrl_previousLabel_ = getctrl("mrs_real/previousLabel");
00039   ctrl_labelNames_ = getctrl("mrs_string/labelNames");
00040   ctrl_nLabels_ = getctrl("mrs_natural/nLabels");
00041   iHasData_ = false;
00042   iLastTickWithData_ = true;
00043   iNewFile_ = true;
00044 }
00045 
00046 CollectionFileSource::~CollectionFileSource()
00047 {
00048   delete isrc_;
00049   delete downsampler_;
00050 }
00051 
00052 MarSystem*
00053 CollectionFileSource::clone() const
00054 {
00055   return new CollectionFileSource(*this);
00056 }
00057 
00058 void
00059 CollectionFileSource::addControls()
00060 {
00061   addctrl("mrs_bool/hasData", true);
00062   hasData_ = true;
00063 
00064   addctrl("mrs_bool/lastTickWithData", false);
00065   lastTickWithData_ = false;
00066 
00067 
00068   addctrl("mrs_natural/pos", (mrs_natural)0);
00069   setctrlState("mrs_natural/pos", true);
00070 
00071   addctrl("mrs_natural/loopPos", (mrs_natural)0);
00072   setctrlState("mrs_natural/pos", true);
00073 
00074   addctrl("mrs_natural/size", (mrs_natural)0);
00075   addctrl("mrs_string/filetype", "mf");
00076   addctrl("mrs_natural/cindex", 0);
00077   setctrlState("mrs_natural/cindex", true);
00078 
00079   addctrl("mrs_string/allfilenames", "collectionFileSource");
00080   setctrlState("mrs_string/allfilenames", true);
00081   addctrl("mrs_natural/numFiles", 0);
00082 
00083   addctrl("mrs_real/repetitions", 1.0);
00084   setctrlState("mrs_real/repetitions", true);
00085   addctrl("mrs_real/duration", -1.0);
00086   setctrlState("mrs_real/duration", true);
00087 
00088   addctrl("mrs_natural/advance", 0);
00089   setctrlState("mrs_natural/advance", true);
00090 
00091   addctrl("mrs_bool/shuffle", false);
00092   setctrlState("mrs_bool/shuffle", true);
00093 
00094   addctrl("mrs_natural/cindex", 0);
00095   setctrlState("mrs_natural/cindex", true);
00096 
00097   addctrl("mrs_string/currentlyPlaying", "daufile", ctrl_currentlyPlaying_);
00098   addctrl("mrs_string/previouslyPlaying", "daufile", ctrl_previouslyPlaying_);
00099   addctrl("mrs_bool/regression", false, ctrl_regression_);
00100   addctrl("mrs_real/currentLabel", 0.0, ctrl_currentLabel_);
00101   addctrl("mrs_real/previousLabel", 0.0, ctrl_previousLabel_);
00102   addctrl("mrs_string/labelNames", ",", ctrl_labelNames_);
00103   addctrl("mrs_natural/nLabels", 0, ctrl_nLabels_);
00104   mngCreated_ = false;
00105 }
00106 
00107 void
00108 CollectionFileSource::getHeader(mrs_string filename)
00109 {
00110   col_.clear();
00111   col_.store_labels(!ctrl_regression_->isTrue());
00112   col_.read(filename);
00113   updControl("mrs_string/allfilenames", col_.toLongString());
00114   updControl("mrs_natural/numFiles", (mrs_natural)col_.getSize());
00115 
00116   cindex_ = 0;
00117   setctrl("mrs_natural/cindex", 0);
00118   setctrl("mrs_bool/hasData", true);
00119   setctrl("mrs_bool/lastTickWithData", false);
00120   ctrl_currentlyPlaying_->setValue(col_.entry(0), NOUPDATE);
00121 
00122 
00123 
00124   if (col_.hasLabels())
00125   {
00126     if (ctrl_regression_->isTrue()) {
00127       ctrl_currentLabel_->setValue(col_.regression_label(0), NOUPDATE);
00128       ctrl_previousLabel_->setValue(col_.regression_label(0), NOUPDATE);
00129       ctrl_labelNames_->setValue("", NOUPDATE);
00130       ctrl_nLabels_->setValue(0, NOUPDATE);
00131     } else {
00132       ctrl_currentLabel_->setValue((mrs_real)col_.labelNum(col_.labelEntry(0)), NOUPDATE);
00133       ctrl_previousLabel_->setValue((mrs_real)col_.labelNum(col_.labelEntry(0)), NOUPDATE);
00134       ctrl_labelNames_->setValue(col_.getLabelNames(), NOUPDATE);
00135       ctrl_nLabels_->setValue(col_.getNumLabels(), NOUPDATE);
00136     }
00137   }
00138 
00139 
00140 
00141   addctrl("mrs_natural/size", 1); // just so it's not zero
00142   setctrl("mrs_natural/pos", 0);
00143   pos_ = 0;
00144 }
00145 
00146 void
00147 CollectionFileSource::myUpdate(MarControlPtr sender)
00148 {
00149   (void) sender;  //suppress warning of unused parameter(s)
00150 
00151 
00152   inSamples_ = getctrl("mrs_natural/inSamples")->to<mrs_natural>();
00153   inObservations_ = getctrl("mrs_natural/inObservations")->to<mrs_natural>();
00154 
00155   pos_ = getctrl("mrs_natural/pos")->to<mrs_natural>();
00156 
00157   if (mngCreated_ == false)
00158   {
00159     isrc_ = new SoundFileSource("isrc");
00160     mngCreated_ = true;
00161     downsampler_ = new DownSampler("downsampler_");
00162   }
00163 
00164   repetitions_ = getctrl("mrs_real/repetitions")->to<mrs_real>();
00165   duration_ = getctrl("mrs_real/duration")->to<mrs_real>();
00166 
00167   advance_ = getctrl("mrs_natural/advance")->to<mrs_natural>();
00168   setctrl("mrs_natural/advance", 0);
00169   cindex_ = getctrl("mrs_natural/cindex")->to<mrs_natural>();
00170   if (getctrl("mrs_bool/shuffle")->isTrue())
00171   {
00172     col_.shuffle();
00173     setctrl("mrs_bool/shuffle", false);
00174   }
00175 
00176   if (cindex_ < (mrs_natural)col_.size())
00177   {
00178     isrc_->updControl("mrs_string/filename", col_.entry(cindex_));
00179     isrc_->updControl("mrs_natural/pos", 0);
00180     ctrl_currentlyPlaying_->setValue(col_.entry(cindex_), NOUPDATE);
00181     ctrl_previouslyPlaying_->setValue(col_.entry((cindex_-1)%col_.size()), NOUPDATE);
00182 
00183 
00184     if (col_.hasLabels())
00185     {
00186       if (ctrl_regression_->isTrue()) {
00187         ctrl_currentLabel_->setValue( col_.regression_label(cindex_), NOUPDATE);
00188         ctrl_previousLabel_->setValue( col_.regression_label((cindex_-1) % col_.size()), NOUPDATE);
00189       } else {
00190         ctrl_currentLabel_->setValue((mrs_real)col_.labelNum(col_.labelEntry(cindex_)), NOUPDATE);
00191         ctrl_previousLabel_->setValue((mrs_real)col_.labelNum(col_.labelEntry((cindex_-1)%col_.size())), NOUPDATE);
00192       }
00193     }
00194     ctrl_labelNames_->setValue(col_.getLabelNames(), NOUPDATE);
00195     ctrl_nLabels_->setValue(col_.getNumLabels(), NOUPDATE);
00196   }
00197 
00198   myIsrate_ = isrc_->getctrl("mrs_real/israte")->to<mrs_real>();//[!] why get an INPUT flow control?!
00199   onObservations_ = isrc_->getctrl("mrs_natural/onObservations")->to<mrs_natural>();
00200 
00201   setctrl("mrs_real/israte", myIsrate_);//[!] why set an INPUT flow control?!?
00202   setctrl("mrs_real/osrate", myIsrate_);
00203   setctrl("mrs_natural/onObservations", onObservations_);
00204 
00205   isrc_->updControl("mrs_natural/inSamples", inSamples_);
00206   setctrl("mrs_natural/onSamples", inSamples_);
00207   setctrl("mrs_real/israte", myIsrate_);//[!] why set an INPUT flow control?!?
00208   setctrl("mrs_real/osrate", myIsrate_);
00209   setctrl("mrs_natural/onObservations", onObservations_);
00210   temp_.create(inObservations_, inSamples_);
00211 
00212   isrc_->updControl("mrs_real/repetitions", repetitions_);
00213   isrc_->updControl("mrs_natural/pos", pos_);
00214   isrc_->updControl("mrs_real/duration", duration_);
00215   isrc_->updControl("mrs_natural/advance", advance_);
00216   isrc_->updControl("mrs_natural/cindex", cindex_);
00217 
00218   cindex_ = getctrl("mrs_natural/cindex")->to<mrs_natural>();
00219 
00220 
00221   if (advance_)
00222   {
00223 
00224 
00225     setctrl("mrs_string/currentlyPlaying", col_.entry((cindex_+advance_) % col_.size()));
00226     setctrl("mrs_string/previouslyPlaying", col_.entry((cindex_+advance_-1) % col_.size()));
00227 
00228     if (col_.hasLabels())
00229     {
00230       if (ctrl_regression_->isTrue()) {
00231         setctrl("mrs_real/currentLabel", col_.regression_label((cindex_+advance_) % col_.size()));
00232         ctrl_currentLabel_->setValue( col_.regression_label((cindex_+advance_) % col_.size()), NOUPDATE);
00233         setctrl("mrs_real/previousLabel", col_.regression_label((cindex_-1+advance_) % col_.size()));
00234         ctrl_previousLabel_->setValue( col_.regression_label((cindex_-1+advance_) % col_.size()), NOUPDATE);
00235       } else {
00236         setctrl("mrs_real/currentLabel", (mrs_real) (col_.labelNum(col_.labelEntry((cindex_+advance_) % col_.size()))));
00237         ctrl_currentLabel_->setValue( (mrs_real) (col_.labelNum(col_.labelEntry((cindex_+advance_) % col_.size()))), NOUPDATE);
00238 
00239         setctrl("mrs_real/previousLabel", (mrs_real) (col_.labelNum(col_.labelEntry((cindex_-1+advance_) % col_.size()))));
00240         ctrl_previousLabel_->setValue( (mrs_real) (col_.labelNum(col_.labelEntry((cindex_-1+advance_) % col_.size()))), NOUPDATE);
00241       }
00242 
00243     }
00244 
00245     if (cindex_ + advance_ >= (mrs_natural)col_.size())
00246     {
00247       setctrl("mrs_bool/hasData", false);
00248       hasData_ = false;
00249       setctrl("mrs_bool/lastTickWithData", true);
00250       lastTickWithData_ = true;
00251       advance_ = 0;
00252       cindex_ = 0;
00253 
00254     }
00255   }
00256 
00257 
00258 }
00259 
00260 void
00261 CollectionFileSource::myProcess(realvec& in, realvec &out)
00262 {
00263 
00264   if (advance_)
00265   {
00266 
00267     cindex_ = (cindex_ + advance_) % col_.size();
00268     setctrl("mrs_natural/cindex", cindex_);
00269     isrc_->updControl("mrs_string/filename", col_.entry(cindex_));
00270     isrc_->updControl("mrs_natural/pos", 0);
00271 
00272 
00273     myIsrate_ = isrc_->getctrl("mrs_real/israte")->to<mrs_real>();
00274     onObservations_ = isrc_->getctrl("mrs_natural/onObservations")->to<mrs_natural>();
00275 
00276     setctrl("mrs_real/israte", myIsrate_);
00277     setctrl("mrs_real/osrate", myIsrate_);
00278     setctrl("mrs_natural/onObservations", onObservations_);
00279     setctrl("mrs_string/currentlyPlaying", col_.entry(cindex_));
00280     setctrl("mrs_string/previouslyPlaying", col_.entry((cindex_-1) % col_.size()));
00281 
00282 
00283     ctrl_currentlyPlaying_->setValue(col_.entry(cindex_), NOUPDATE);
00284     ctrl_previouslyPlaying_->setValue(col_.entry((cindex_-1) % col_.size()));
00285     if (col_.hasLabels())
00286     {
00287       if (ctrl_regression_->isTrue()) {
00288         setctrl("mrs_real/currentLabel", col_.regression_label(cindex_));
00289         ctrl_currentLabel_->setValue( col_.regression_label(cindex_), NOUPDATE);
00290 
00291         setctrl("mrs_real/previousLabel", col_.regression_label((cindex_-1)% col_.size()));
00292         ctrl_previousLabel_->setValue( col_.regression_label((cindex_-1)%col_.size()), NOUPDATE);
00293       } else {
00294         setctrl("mrs_real/currentLabel", (mrs_real) (col_.labelNum(col_.labelEntry(cindex_))));
00295         ctrl_currentLabel_->setValue( (mrs_real) (col_.labelNum(col_.labelEntry(cindex_))), NOUPDATE);
00296 
00297         setctrl("mrs_real/previousLabel", (mrs_real) (col_.labelNum(col_.labelEntry((cindex_-1)% col_.size()))));
00298         ctrl_previousLabel_->setValue( (mrs_real) (col_.labelNum(col_.labelEntry((cindex_-1)%col_.size()))), NOUPDATE);
00299       }
00300     }
00301 
00302     ctrl_labelNames_->setValue(col_.getLabelNames(), NOUPDATE);
00303     ctrl_nLabels_->setValue(col_.getNumLabels(), NOUPDATE);
00304 
00305     // update();
00306 
00307     isrc_->process(in,out);
00308 
00309 
00310 
00311     setctrl("mrs_natural/pos", isrc_->getctrl("mrs_natural/pos"));
00312     setctrl("mrs_bool/hasData", isrc_->getctrl("mrs_bool/hasData"));
00313     setctrl("mrs_bool/lastTickWithData", isrc_->getctrl("mrs_bool/lastTickWithData"));
00314     iNewFile_ = true;
00315 
00316     if (cindex_ > (mrs_natural)col_.size()-1)
00317     {
00318       setctrl("mrs_bool/hasData", false);
00319       hasData_ = false;
00320       setctrl("mrs_bool/lastTickWithData", true);
00321       lastTickWithData_ = true;
00322       advance_ = 0;
00323       setctrl("mrs_natural/advance", 0);
00324       return;
00325     }
00326 
00327 
00328     setctrl("mrs_natural/advance", 0);
00329     advance_ = 0;
00330 
00331 
00332 
00333 
00334   }
00335   else
00336   {
00337 
00338 
00339     //finished current file. Advance to next one in collection (if any)
00340     if (!isrc_->getctrl("mrs_bool/hasData")->isTrue())
00341     {
00342 
00343       //check if there a following file in the collection
00344       if (cindex_ < (mrs_natural)col_.size() -1)
00345       {
00346         cindex_ = cindex_ + 1;
00347         setctrl("mrs_natural/cindex", cindex_);
00348 
00349         // encforce re-reading of filename
00350         isrc_->updControl("mrs_string/filename", "");
00351         isrc_->updControl("mrs_string/filename", col_.entry(cindex_));
00352         isrc_->updControl("mrs_natural/pos", 0);
00353 
00354 
00355         pos_ = 0;
00356         myIsrate_ = isrc_->getctrl("mrs_real/israte")->to<mrs_real>();
00357         onObservations_ = isrc_->getctrl("mrs_natural/onObservations")->to<mrs_natural>();
00358 
00359         setctrl("mrs_real/israte", myIsrate_);
00360         setctrl("mrs_real/osrate", myIsrate_);
00361         setctrl("mrs_natural/onObservations", onObservations_);
00362         setctrl("mrs_string/currentlyPlaying", col_.entry(cindex_));
00363         setctrl("mrs_string/previouslyPlaying", col_.entry((cindex_-1)%col_.size()));
00364 
00365 
00366         ctrl_currentlyPlaying_->setValue(col_.entry(cindex_), NOUPDATE);
00367         ctrl_previouslyPlaying_->setValue(col_.entry((cindex_-1) % col_.size()), NOUPDATE);
00368 
00369 
00370         if (col_.hasLabels())
00371         {
00372           if (ctrl_regression_->isTrue()) {
00373             setctrl("mrs_real/currentLabel", col_.regression_label(cindex_));
00374             ctrl_currentLabel_->setValue( col_.regression_label(cindex_), NOUPDATE);
00375             setctrl("mrs_real/previousLabel", col_.regression_label((cindex_-1)%col_.size()));
00376             ctrl_previousLabel_->setValue( col_.regression_label((cindex_-1) % col_.size()), NOUPDATE);
00377           } else {
00378 
00379 
00380             setctrl("mrs_real/currentLabel", (mrs_real) col_.labelNum(col_.labelEntry((cindex_-1) % col_.size())));
00381             ctrl_currentLabel_->setValue( (mrs_real) col_.labelNum(col_.labelEntry((cindex_-1) % col_.size() )), NOUPDATE);
00382 
00383 
00384             setctrl("mrs_real/previousLabel", (mrs_real) (col_.labelNum(col_.labelEntry((cindex_-1)%col_.size()))));
00385             ctrl_previousLabel_->setValue( (mrs_real) (col_.labelNum(col_.labelEntry((cindex_-1) % col_.size()))), NOUPDATE);
00386           }
00387         }
00388 
00389         ctrl_labelNames_->setValue(col_.getLabelNames(), NOUPDATE);
00390         ctrl_nLabels_->setValue(col_.getNumLabels(), NOUPDATE);
00391         iNewFile_ = true;
00392       }
00393       else //no more files in collection
00394       {
00395 
00396         cindex_ = cindex_ + 1;
00397         setctrl("mrs_natural/cindex", cindex_);
00398         ctrl_previouslyPlaying_->setValue(col_.entry((cindex_-1) % col_.size()), NOUPDATE);
00399         setctrl("mrs_string/previouslyPlaying", col_.entry((cindex_-1)%col_.size()));
00400 
00401         setctrl("mrs_real/previousLabel", (mrs_real) (col_.labelNum(col_.labelEntry((cindex_-1)%col_.size()))));
00402         ctrl_previousLabel_->setValue( (mrs_real) (col_.labelNum(col_.labelEntry((cindex_-1) % col_.size()))), NOUPDATE);
00403 
00404 
00405         setctrl("mrs_bool/hasData", false);
00406         hasData_ = false;
00407 
00408         setctrl("mrs_bool/lastTickWithData", true);
00409         lastTickWithData_ = true;
00410 
00411         iNewFile_ = true;
00412       }
00413     } else
00414     {
00415       if (isrc_->getctrl("mrs_natural/pos")->to<mrs_natural>() > 0)
00416         iNewFile_ = false;
00417 
00418     }
00419 
00420 
00421     isrc_->process(in,out);
00422 
00423     setctrl("mrs_natural/pos", isrc_->getctrl("mrs_natural/pos"));
00424     setctrl("mrs_bool/hasData", isrc_->getctrl("mrs_bool/hasData"));
00425     setctrl("mrs_bool/lastTickWithData", isrc_->getctrl("mrs_bool/lastTickWithData"));
00426 
00427 
00428 
00429     setctrl("mrs_real/currentLabel", (mrs_real) col_.labelNum(col_.labelEntry((cindex_) % col_.size())));
00430     ctrl_currentLabel_->setValue( (mrs_real) col_.labelNum(col_.labelEntry((cindex_) % col_.size())), NOUPDATE);
00431 
00432     // check internal data *after* process()
00433     iHasData_ = isrc_->getctrl("mrs_bool/hasData")->to<mrs_bool>();
00434     iLastTickWithData_ = isrc_->getctrl("mrs_bool/lastTickWithData")->to<mrs_bool>();
00435     if (! iHasData_ ) {
00436       // check if we're at the end
00437       // if we're not at the end, the above code
00438       // will handle it in the next tick()
00439       if (cindex_ == (mrs_natural)col_.size() - 1) {
00440         setctrl("mrs_bool/hasData", false);
00441         hasData_ = false;
00442       }
00443     }
00444 
00445 
00446     if (iLastTickWithData_ ) {
00447       // check if we're at the end
00448       // if we're not at the end, the above code
00449       // will handle it in the next tick()
00450       if (cindex_ == (mrs_natural)col_.size() - 1) {
00451         setctrl("mrs_bool/lastTickWithData", true);
00452         lastTickWithData_ = true;
00453       }
00454     }
00455 
00456 
00457 
00458 
00459 
00460 
00461   }
00462 
00463 
00464 
00465 
00466 }