Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/WavFileSource.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 "../common_source.h"
00020 #include "WavFileSource.h"
00021 
00022 
00023 using namespace std;
00024 using namespace Marsyas;
00025 
00026 WavFileSource::WavFileSource(mrs_string name):AbsSoundFileSource("WavFileSource",name)
00027 {
00028   idata_ = 0;
00029   sdata_ = 0;
00030   cdata_ = 0;
00031   sfp_ = 0;
00032   pos_ = 0;
00033 
00034   addControls();
00035 }
00036 
00037 
00038 WavFileSource::WavFileSource(const WavFileSource& a): AbsSoundFileSource(a)
00039 {
00040   ctrl_pos_ = getctrl("mrs_natural/pos");
00041   ctrl_currentlyPlaying_ = getctrl("mrs_string/currentlyPlaying");
00042   ctrl_previouslyPlaying_ = getctrl("mrs_string/previouslyPlaying");
00043   ctrl_regression_ = getctrl("mrs_bool/regression");
00044   ctrl_currentLabel_ = getctrl("mrs_real/currentLabel");
00045   ctrl_previousLabel_ = getctrl("mrs_real/previousLabel");
00046   ctrl_labelNames_ = getctrl("mrs_string/labelNames");
00047   ctrl_nLabels_ = getctrl("mrs_natural/nLabels");
00048   ctrl_currentHasData_ = getctrl("mrs_bool/currentHasData");
00049   ctrl_currentLastTickWithData_ = getctrl("mrs_bool/currentLastTickWithData");
00050 }
00051 
00052 
00053 
00054 WavFileSource::~WavFileSource()
00055 {
00056   delete [] idata_;
00057   delete [] sdata_;
00058   delete [] cdata_;
00059   if (sfp_ != NULL)
00060     fclose(sfp_);
00061 }
00062 
00063 MarSystem*
00064 WavFileSource::clone() const
00065 {
00066   return new WavFileSource(*this);
00067 }
00068 
00069 void
00070 WavFileSource::addControls()
00071 {
00072   addctrl("mrs_bool/hasData", true);
00073   addctrl("mrs_bool/lastTickWithData", false);
00074 
00075   addctrl("mrs_natural/pos", (mrs_natural)0, ctrl_pos_);
00076   setctrlState("mrs_natural/pos", true);
00077 
00078   addctrl("mrs_natural/loopPos", (mrs_natural)0);
00079   setctrlState("mrs_natural/pos", true);
00080 
00081   addctrl("mrs_natural/size", (mrs_natural)0);
00082 
00083   addctrl("mrs_string/filename", "dwavfile");
00084   setctrlState("mrs_string/filename", true);
00085 
00086   addctrl("mrs_string/filetype", "wav");
00087 
00088   addctrl("mrs_real/repetitions", 1.0);
00089   setctrlState("mrs_real/repetitions", true);
00090 
00091   addctrl("mrs_real/duration", -1.0);
00092   setctrlState("mrs_real/duration", true);
00093 
00094   addctrl("mrs_natural/advance", 0);
00095   setctrlState("mrs_natural/advance", true);
00096 
00097   addctrl("mrs_bool/shuffle", false);
00098   setctrlState("mrs_bool/shuffle", true);
00099 
00100   addctrl("mrs_natural/cindex", 0);
00101   setctrlState("mrs_natural/cindex", true);
00102 
00103   addctrl("mrs_string/allfilenames", ",");
00104   setctrlState("mrs_string/allfilenames", true);
00105 
00106   addctrl("mrs_natural/numFiles", 1);
00107   addctrl("mrs_string/currentlyPlaying", "daufile", ctrl_currentlyPlaying_); //"dwavfile" [?]
00108   addctrl("mrs_string/previouslyPlaying", "daufile", ctrl_previouslyPlaying_); //"dwavfile" [?]
00109 
00110   addctrl("mrs_bool/regression", false, ctrl_regression_);
00111   addctrl("mrs_real/currentLabel", 0.0, ctrl_currentLabel_);
00112   addctrl("mrs_real/previousLabel", 0.0, ctrl_previousLabel_);
00113   addctrl("mrs_natural/nLabels", 0, ctrl_nLabels_);
00114   addctrl("mrs_string/labelNames", ",", ctrl_labelNames_);
00115 
00116   addctrl("mrs_bool/currentHasData", true, ctrl_currentHasData_);
00117 
00118   addctrl("mrs_bool/currentLastTickWithData", false, ctrl_currentLastTickWithData_);
00119 
00120 }
00121 
00122 void
00123 WavFileSource::getHeader(mrs_string filename)
00124 {
00125 
00126   if (sfp_ != NULL)
00127     fclose(sfp_);
00128 
00129   sfp_ = fopen(filename.c_str(), "rb");
00130   if (sfp_)
00131   {
00132     char magic[5];
00133 
00134     fseek(sfp_, 8, SEEK_SET); // Locate wave id
00135     if (fread(magic, 4, 1, sfp_) == 0)
00136     {
00137       MRSERR("WavFileSource: File " + filename + " is empty ");
00138     }
00139     magic[4] = '\0';
00140 
00141     if (strcmp(magic, "WAVE"))
00142     {
00143       MRSWARN("Filename " + filename + " is not correct .wav file \n or has settings that are not supported in Marsyas");
00144       // setctrl("mrs_natural/nChannels", 1);
00145       setctrl("mrs_real/israte", (mrs_real)22050.0);
00146       setctrl("mrs_natural/size", 0);
00147       hasData_ = false;
00148       lastTickWithData_ = true;
00149       setctrl("mrs_bool/hasData", false);
00150       setctrl("mrs_bool/lastTickWithData", true);
00151 
00152     }
00153     else
00154     {
00155       char id[5];
00156       int chunkSize;
00157       if (fread(id, 4, 1, sfp_) != 1) {
00158         MRSERR("Error reading wav file");
00159       }
00160       id[4] = '\0';
00161 
00162       while (strcmp(id, "fmt "))
00163       {
00164         if (fread(&chunkSize, 4, 1, sfp_) != 1) {
00165           MRSERR("Error reading wav file");
00166         }
00167 #if defined(MARSYAS_BIGENDIAN)
00168         chunkSize = ByteSwapLong(chunkSize);
00169 #else
00170         //chunkSize = chunkSize;
00171 #endif
00172         fseek(sfp_, chunkSize, SEEK_CUR);
00173         if (fread(id, 4, 1, sfp_) != 1) {
00174           MRSERR("Error reading wav file");
00175         }
00176       }
00177 
00178       if (fread(&chunkSize, 4, 1, sfp_) != 1) {
00179         MRSERR("Error reading wav file");
00180       }
00181 #if defined(MARSYAS_BIGENDIAN)
00182       chunkSize = ByteSwapLong(chunkSize);
00183 #else
00184       //chunkSize = chunkSize;
00185 #endif
00186 
00187       unsigned short format_tag;
00188       if (fread(&format_tag, 2, 1, sfp_) != 1) {
00189         MRSERR("Error reading wav file");
00190       }
00191 
00192 #if defined(MARSYAS_BIGENDIAN)
00193       format_tag = ByteSwapShort(format_tag);
00194 #else
00195       //format_tag = format_tag;
00196 #endif
00197 
00198       if (format_tag != 1)
00199       {
00200         fclose(sfp_);
00201         MRSWARN("Non pcm(compressed) wave files are not supported");
00202         exit(1);
00203       }
00204 
00205       // Get number of channels
00206       unsigned short channels;
00207       if (fread(&channels, 2,1, sfp_) != 1) {
00208         MRSERR("Error reading wav file");
00209       }
00210 
00211 #if defined(MARSYAS_BIGENDIAN)
00212       channels = ByteSwapShort(channels);
00213 #else
00214       //channels = channels;
00215 #endif
00216 
00217       setctrl("mrs_natural/onObservations", (mrs_natural)channels);
00218 
00219       unsigned int srate;
00220       if (fread(&srate, 4,1,sfp_) != 1) {
00221         MRSERR("Error reading wav file");
00222       }
00223 
00224 #if defined(MARSYAS_BIGENDIAN)
00225       srate = ByteSwapLong(srate);
00226 #else
00227       //srate = srate;
00228 #endif
00229 
00230 
00231       setctrl("mrs_real/israte", (mrs_real)srate);
00232       setctrl("mrs_real/osrate", (mrs_real)srate);
00233 
00234       fseek(sfp_,6,SEEK_CUR);
00235       if (fread(&bits_, 2, 1, sfp_) != 1) {
00236         MRSERR("Error reading wav file");
00237       }
00238 
00239 #if defined(MARSYAS_BIGENDIAN)
00240       bits_ = ByteSwapShort(bits_);
00241 #else
00242       //bits_ = bits_;
00243 #endif
00244 
00245       if ((bits_ != 16)&&(bits_ != 8)&&(bits_!=32))
00246       {
00247         MRSWARN("WavFileSource::Only linear 8-bit, 16-bit, and 32-bit samples are supported ");
00248       }
00249       fseek(sfp_, chunkSize - 16, SEEK_CUR);
00250 
00251       if (fread(id, 4, 1, sfp_) != 1) {
00252         MRSERR("Error reading wav file");
00253       }
00254       id[4] = '\0';
00255       while (strcmp(id, "data"))
00256       {
00257         if (fread(&chunkSize, 4, 1, sfp_) != 1) {
00258           MRSERR("Error reading wav file");
00259         }
00260 #if defined(MARSYAS_BIGENDIAN)
00261         chunkSize = ByteSwapLong(chunkSize);
00262 #else
00263         //chunkSize = chunkSize;
00264 #endif
00265 
00266         fseek(sfp_,chunkSize,SEEK_CUR);
00267         if (fread(&id,4,1,sfp_) != 1) {
00268           MRSERR("Error reading wav file");
00269         }
00270       }
00271 
00272       int bytes;
00273       if (fread(&bytes, 4, 1, sfp_) != 1) {
00274         MRSERR("Error reading wav file");
00275       }
00276 
00277 #if defined(MARSYAS_BIGENDIAN)
00278       bytes = ByteSwapLong(bytes);
00279 #else
00280       //bytes = bytes;
00281 #endif
00282 
00283       //size in number of samples per channel
00284       size_ = bytes / (bits_ / 8)/ (getctrl("mrs_natural/onObservations")->to<mrs_natural>());
00285       csize_ = size_;
00286 
00287       setctrl("mrs_natural/size", size_);
00288       ctrl_currentlyPlaying_->setValue(filename, NOUPDATE);
00289       ctrl_previouslyPlaying_->setValue(filename, NOUPDATE);
00290       ctrl_currentLabel_->setValue((mrs_real)0.0, NOUPDATE);
00291       ctrl_previousLabel_->setValue((mrs_real)0.0, NOUPDATE);
00292 
00293       ctrl_labelNames_->setValue(",", NOUPDATE);
00294       ctrl_nLabels_->setValue(0, NOUPDATE);
00295       sfp_begin_ = ftell(sfp_);
00296       hasData_ = true;
00297       lastTickWithData_ = false;
00298       pos_ = 0;
00299       samplesOut_ = 0;
00300       MRSDIAG("WavFileSource: "
00301               << filename
00302               << " has the following properties: ");
00303       mrs_real temprate = getControl("mrs_real/israte")->to<mrs_real>();
00304       mrs_natural numInSamples = getControl("mrs_natural/inSamples")->to<mrs_natural>();
00305       MRSDIAG("israte == " << temprate);
00306       MRSDIAG("inSamples == " << numInSamples);
00307       (void) temprate;
00308       (void) numInSamples; // in case the macro is not expanded
00309 
00310     }
00311   }
00312   else
00313   {
00314     MRSWARN("couldn't open file: " << filename);
00315     // setctrl("mrs_natural/nChannels", 1);
00316     setctrl("mrs_real/israte", (mrs_real)22050.0);
00317     setctrl("mrs_natural/onObservations", 1);
00318     setctrl("mrs_natural/size", 0);
00319     hasData_ = false;
00320     lastTickWithData_ = true;
00321     setctrl("mrs_bool/hasData", false);
00322     setctrl("mrs_bool/lastTickWithData", true);
00323     pos_ = 0;
00324   }
00325 
00326   nChannels_ = getctrl("mrs_natural/onObservations")->to<mrs_natural>();
00327 }
00328 
00329 void
00330 WavFileSource::myUpdate(MarControlPtr sender)
00331 {
00332   (void) sender;  //suppress warning of unused parameter(s)
00333   inSamples_ = getctrl("mrs_natural/inSamples")->to<mrs_natural>();
00334   inObservations_ = getctrl("mrs_natural/inObservations")->to<mrs_natural>();
00335   israte_ = getctrl("mrs_real/israte")->to<mrs_real>();
00336   osrate_ = getctrl("mrs_real/osrate")->to<mrs_real>();
00337 
00338   nChannels_ = getctrl("mrs_natural/onObservations")->to<mrs_natural>();
00339 
00340   setctrl("mrs_natural/onSamples", inSamples_);
00341   setctrl("mrs_natural/onObservations", nChannels_);
00342   //setctrl("mrs_real/osrate", osrate_);
00343   //osrate_ = getctrl("mrs_real/osrate")->to<mrs_real>();
00344   pos_ = getctrl("mrs_natural/pos")->to<mrs_natural>();
00345   rewindpos_ = getctrl("mrs_natural/loopPos")->to<mrs_natural>();
00346 
00347   delete [] idata_;
00348   delete [] sdata_;
00349   delete [] cdata_;
00350 
00351   idata_ = new int[inSamples_ * nChannels_];
00352   sdata_ = new short[inSamples_ * nChannels_];
00353   cdata_ = new unsigned char[inSamples_ * nChannels_];
00354 
00355   repetitions_ = getctrl("mrs_real/repetitions")->to<mrs_real>();
00356   duration_ = getctrl("mrs_real/duration")->to<mrs_real>();
00357 
00358   if (duration_ != -1.0)
00359   {
00360     csize_ = (mrs_natural)(duration_ * israte_);
00361   }
00362 
00363   samplesToRead_ = inSamples_ * nChannels_;
00364   MRSDIAG("WavFileSource::myUpdate "
00365           << " has the following properties: ");
00366   mrs_real temprate = getControl("mrs_real/israte")->to<mrs_real>();
00367   mrs_natural numInSamples = getControl("mrs_natural/inSamples")->to<mrs_natural>();
00368   MRSDIAG("israte == " << temprate);
00369   MRSDIAG("inSamples == " << numInSamples);
00370   (void) temprate;
00371   (void) numInSamples; // in case the macro is not expanded
00372 
00373 }
00374 
00375 mrs_natural
00376 WavFileSource::getLinear8(realvec& slice)
00377 {
00378   mrs_natural t;
00379   mrs_natural c = 0;
00380   fseek(sfp_, pos_ * nChannels_ + sfp_begin_, SEEK_SET);
00381 
00382   samplesToRead_ = inSamples_ * nChannels_;
00383   samplesRead_ = (mrs_natural)fread(cdata_, sizeof(unsigned char), samplesToRead_, sfp_);
00384 
00385 
00386   if (samplesRead_ != samplesToRead_)
00387   {
00388     for (c=0; c < nChannels_; ++c)
00389       for (t=0; t < inSamples_; t++)
00390       {
00391         slice(c,t) = 0.0;
00392       }
00393     samplesToWrite_ = samplesRead_ / nChannels_;
00394   }
00395   else
00396     samplesToWrite_ = inSamples_;
00397 
00398   for (t=0; t < samplesToWrite_; t++)
00399   {
00400     for (c=0; c < nChannels_; ++c)
00401     {
00402       slice(c, t) = (mrs_real)-1.0 + (mrs_real) cdata_[nChannels_ * t + c] / 127;
00403     }
00404   }
00405 
00406   pos_ += samplesToWrite_;
00407   return pos_;
00408 }
00409 
00410 // oh dear.  "long" here means 32 bits
00411 unsigned long
00412 WavFileSource::ByteSwapLong(unsigned long nLongNumber)
00413 {
00414   return (((nLongNumber&0x000000FF)<<24)+((nLongNumber&0x0000FF00)<<8)+
00415           ((nLongNumber&0x00FF0000)>>8)+((nLongNumber&0xFF000000)>>24));
00416 }
00417 
00418 unsigned int
00419 WavFileSource::ByteSwapInt(unsigned int nInt)
00420 {
00421   return (((nInt&0x000000FF)<<24)+((nInt&0x0000FF00)<<8)+
00422           ((nInt&0x00FF0000)>>8)+((nInt&0xFF000000)>>24));
00423 }
00424 
00425 
00426 unsigned short
00427 WavFileSource::ByteSwapShort (unsigned short nValue)
00428 {
00429   return (static_cast<unsigned short>((nValue & 0xff00) >> 8) |
00430           static_cast<unsigned short>((nValue & 0xff) << 8));
00431 }
00432 
00433 mrs_natural
00434 WavFileSource::getLinear32(realvec& slice)
00435 {
00436   mrs_natural c,t;
00437 
00438   fseek(sfp_, 4 * pos_ * nChannels_ + sfp_begin_, SEEK_SET);
00439   samplesRead_ = (mrs_natural)fread(idata_, sizeof(int), samplesToRead_, sfp_);
00440 
00441   // pad with zeros if necessary
00442   if ((samplesRead_ != samplesToRead_)&&(samplesRead_ != 0))
00443   {
00444     for (c=0; c < nChannels_; ++c)
00445       for (t=0; t < inSamples_; t++)
00446         slice(c, t) = 0.0;
00447     samplesToWrite_ = samplesRead_ / nChannels_;
00448   }
00449   else // default case - read enough samples or no samples in which case zero output
00450   {
00451     samplesToWrite_ = inSamples_;
00452 
00453     // if there are no more samples output zeros
00454     if (samplesRead_ == 0)
00455       for (t=0; t < inSamples_; t++)
00456       {
00457         nt_ = nChannels_ * t;
00458         for (c=0; c < nChannels_; ++c)
00459         {
00460           idata_[nt_ + c] = 0;
00461         }
00462       }
00463   }
00464 
00465   // write the read samples to output slice once for each channel
00466   for (t=0; t < samplesToWrite_; t++)
00467   {
00468     ival_ = 0;
00469     nt_ = nChannels_ * t;
00470 #if defined(MARSYAS_BIGENDIAN)
00471     for (c=0; c < nChannels_; ++c)
00472     {
00473       // oh dear.  "long" here means 32 bits
00474       ival_ = ByteSwapInt(idata_[nt_ + c]);
00475       slice(c, t) = (mrs_real) ival_ / (PCM_FMAXINT + 1);
00476     }
00477 #else
00478     for (c=0; c < nChannels_; ++c)
00479     {
00480       ival_ = idata_[nt_ + c];
00481       slice(c, t) = ((mrs_real) ival_ / (PCM_FMAXINT + 1));
00482     }
00483 #endif
00484   }
00485 
00486   pos_ += samplesToWrite_;
00487   return pos_;
00488 }
00489 
00490 
00491 mrs_natural
00492 WavFileSource::getLinear16(realvec& slice)
00493 {
00494   mrs_natural c,t;
00495 
00496   fseek(sfp_, 2 * pos_ * nChannels_ + sfp_begin_, SEEK_SET);
00497   samplesRead_ = (mrs_natural)fread(sdata_, sizeof(short), samplesToRead_, sfp_);
00498 
00499   // pad with zeros if necessary
00500   if ((samplesRead_ != samplesToRead_)&&(samplesRead_ != 0))
00501   {
00502     for (c=0; c < nChannels_; ++c)
00503       for (t=0; t < inSamples_; t++)
00504         slice(c, t) = 0.0;
00505     samplesToWrite_ = samplesRead_ / nChannels_;
00506   }
00507   else // default case - read enough samples or no samples in which case zero output
00508   {
00509     samplesToWrite_ = inSamples_;
00510 
00511     // if there are no more samples output zeros
00512     if (samplesRead_ == 0)
00513       for (t=0; t < inSamples_; t++)
00514       {
00515         nt_ = nChannels_ * t;
00516         for (c=0; c < nChannels_; ++c)
00517         {
00518           sdata_[nt_ + c] = 0;
00519         }
00520       }
00521   }
00522 
00523   // write the read samples to output slice once for each channel
00524   for (t=0; t < samplesToWrite_; t++)
00525   {
00526     sval_ = 0;
00527     nt_ = nChannels_ * t;
00528 #if defined(MARSYAS_BIGENDIAN)
00529     for (c=0; c < nChannels_; ++c)
00530     {
00531       sval_ = ByteSwapShort(sdata_[nt_ + c]);
00532       slice(c, t) = (mrs_real) sval_ / (PCM_FMAXSHRT + 1);
00533     }
00534 #else
00535     for (c=0; c < nChannels_; ++c)
00536     {
00537       sval_ = sdata_[nt_ + c];
00538       slice(c, t) = ((mrs_real) sval_ / (PCM_FMAXSHRT + 1));
00539     }
00540 #endif
00541   }
00542 
00543   pos_ += samplesToWrite_;
00544   return pos_;
00545 }
00546 
00547 void
00548 WavFileSource::myProcess(realvec& in, realvec& out)
00549 {
00550   (void) in;
00551   switch(bits_)
00552   {
00553   case 32:
00554   {
00555     getLinear32(out);
00556     ctrl_pos_->setValue(pos_, NOUPDATE);
00557 
00558     if (pos_ >= rewindpos_ + csize_)
00559     {
00560       if (repetitions_ != 1)
00561         pos_ = rewindpos_;
00562     }
00563     samplesOut_ += onSamples_;
00564 
00565     if (repetitions_ != 1)
00566     {
00567       hasData_ = (samplesOut_ < repetitions_ * csize_);
00568 
00569       lastTickWithData_ = ((samplesOut_  + onSamples_>= repetitions_ * csize_) && hasData_);
00570     }
00571 
00572     else
00573     {
00574       hasData_ = pos_ < rewindpos_ + csize_;
00575       lastTickWithData_ = ((pos_ + onSamples_ >= rewindpos_ + csize_) && hasData_);
00576     }
00577 
00578     if (repetitions_ == -1)
00579     {
00580       hasData_ = true;
00581       lastTickWithData_ = false;
00582     }
00583     break;
00584   }
00585   case 16:
00586   {
00587     getLinear16(out);
00588     ctrl_pos_->setValue(pos_, NOUPDATE);
00589 
00590     if (pos_ >= rewindpos_ + csize_)
00591     {
00592       if (repetitions_ != 1)
00593         pos_ = rewindpos_;
00594     }
00595     samplesOut_ += onSamples_;
00596 
00597     if (repetitions_ != 1)
00598     {
00599       hasData_ = (samplesOut_ < repetitions_ * csize_);
00600 
00601       lastTickWithData_ = ((samplesOut_  + onSamples_>= repetitions_ * csize_) && hasData_);
00602     }
00603 
00604     else
00605     {
00606       hasData_ = pos_ < rewindpos_ + csize_;
00607       lastTickWithData_ = ((pos_ + onSamples_ >= rewindpos_ + csize_) && hasData_);
00608     }
00609 
00610     if (repetitions_ == -1)
00611     {
00612       hasData_ = true;
00613       lastTickWithData_ = false;
00614     }
00615     break;
00616   }
00617   case 8:
00618   {
00619     getLinear8(out);
00620     ctrl_pos_->setValue(pos_, NOUPDATE);
00621 
00622     if (pos_ >= rewindpos_ + csize_)
00623     {
00624       if (repetitions_ != 1)
00625         pos_ = rewindpos_;
00626     }
00627     samplesOut_ += onSamples_;
00628 
00629     if (repetitions_ != 1)
00630     {
00631       hasData_ = (samplesOut_ < repetitions_ * csize_);
00632       lastTickWithData_ = ((samplesOut_ + onSamples_ >= repetitions_ * csize_) && hasData_);
00633     }
00634     else
00635     {
00636       hasData_ = pos_ < rewindpos_ + csize_;
00637       lastTickWithData_ = ((pos_ + onSamples_ >= rewindpos_ + csize_) && hasData_);
00638     }
00639 
00640     if (repetitions_ == -1)
00641     {
00642       hasData_ = true;
00643       lastTickWithData_ = false;
00644     }
00645     break;
00646 
00647 
00648   }
00649   }
00650   ctrl_currentHasData_->setValue(hasData_);
00651 
00652   ctrl_currentLastTickWithData_->setValue(lastTickWithData_);
00653 }