TOBI SignalServer  0.1
/home/breidi/Dropbox/signalserver/include/sampleblock/sample_block.h
Go to the documentation of this file.
00001 /*
00002     This file is part of the TOBI SignalServer.
00003 
00004     Commercial Usage
00005     Licensees holding valid Graz University of Technology Commercial
00006     licenses may use this file in accordance with the Graz University
00007     of Technology Commercial License Agreement provided with the
00008     Software or, alternatively, in accordance with the terms contained in
00009     a written agreement between you and Graz University of Technology.
00010 
00011     --------------------------------------------------
00012 
00013     GNU General Public License Usage
00014     Alternatively, this file may be used under the terms of the GNU
00015     General Public License version 3.0 as published by the Free Software
00016     Foundation and appearing in the file gpl.txt included in the
00017     packaging of this file.  Please review the following information to
00018     ensure the GNU General Public License version 3.0 requirements will be
00019     met: http://www.gnu.org/copyleft/gpl.html.
00020 
00021     In case of GNU General Public License Usage ,the TOBI SignalServer
00022     is distributed in the hope that it will be useful,
00023     but WITHOUT ANY WARRANTY; without even the implied warranty of
00024     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025     GNU General Public License for more details.
00026 
00027     You should have received a copy of the GNU General Public License
00028     along with the TOBI SignalServer. If not, see <http://www.gnu.org/licenses/>.
00029 
00030     Copyright 2010 Graz University of Technology
00031     Contact: SignalServer@tobi-project.org
00032 */
00033 
00045 #ifndef SAMPLEBLOCK_H
00046 #define SAMPLEBLOCK_H
00047 
00048 #include <map>
00049 #include <string>
00050 #include <vector>
00051 #include <stdexcept>
00052 
00053 #include <boost/cstdint.hpp>
00054 #include <boost/lexical_cast.hpp>
00055 
00056 #ifdef DEBUG
00057   #include <iostream>
00058 #endif
00059 
00060 namespace tobiss
00061 {
00062 
00063 //-----------------------------------------------------------------------------
00090 template<class T> class SampleBlock
00091 {
00092   public:
00096     SampleBlock()
00097       : blocks_ (0), channels_(0), homogenous_(1),curr_block_(0) { }
00098 
00102     virtual ~SampleBlock()    {  }
00103 
00107     boost::uint16_t getNrOfBlocks()    {  return(blocks_ );  }
00111     boost::uint16_t getNrOfChannels()    {  return(channels_);  }
00115     boost::uint16_t getNrOfSamples()    {  return(samples_.size());  }
00119     boost::uint16_t getNrOfSignalTypes()     { return(block_info_.size());  }
00123     void deleteSamples()    {  samples_.clear();  }
00127     void reset()     { curr_block_ = 0;  }
00128 
00133     T at(boost::uint32_t n)    {  return(samples_.at(n));  }
00137     T operator[](boost::uint32_t n)    {  return(samples_[n]);  }
00138 
00139     //-------------------------------------------
00140 
00152     void init(boost::uint16_t blocksize, boost::uint16_t nr_ch, std::vector<boost::uint32_t> sig_types);
00153 
00154 
00156 
00157 
00162     std::vector<boost::uint32_t> getTypes();
00163 
00169     std::vector<T> getSamples();
00170 
00176     boost::uint32_t getFlagByNr(boost::uint32_t nr);
00177 
00184     std::vector<T> getSignalByFlag(boost::uint32_t flag);
00185 
00192     void getSignalByFlag(boost::uint32_t flag, std::vector<T>& v);
00193 
00200     std::vector<T> getSignalByNr(boost::uint32_t nr);
00201 
00208     void getSignalByNr(boost::uint32_t nr, std::vector<T>& v);
00209 
00216     void appendBlock(std::vector<T> v, boost::uint16_t nr_blocks);
00217 
00224     void setSamples(std::vector<T> v);
00225 
00226 //-----------------------------------------------------------------------------
00227 
00228   private:
00239     void sort(std::vector<T>& v, std::vector<boost::uint32_t> order, boost::uint32_t nr_blocks);
00240 
00245     void checkBlockIntegrity();
00246 
00247 //-----------------------------------------------
00248 
00249   private:
00250     boost::uint16_t blocks_ ;    
00251     boost::uint16_t channels_;  
00252     bool homogenous_;    
00253     boost::uint16_t curr_block_;    
00254 
00255     //vector<uint32_t> types_ordered_;   //< Signal types in an ordered manner (and how samples are stored)
00256     std::vector<boost::uint32_t> types_input_;   
00257 
00264     std::map<boost::uint32_t, std::pair<boost::uint16_t, boost::uint16_t> > block_info_;  // flag ... identifier, offset & nr_values as data
00265     std::vector<T> samples_;    
00266 };
00267 
00268 //-----------------------------------------------------------------------------
00269 //-----------------------------------------------------------------------------
00270 
00271 template<class T> void SampleBlock<T>::init(boost::uint16_t blocksize, boost::uint16_t nr_ch, std::vector<boost::uint32_t> sig_types)
00272 {
00273   #ifdef DEBUG
00274     //std::cout << "SampleBlock: init" << std::endl;
00275   #endif
00276 
00277   using boost::uint16_t;
00278   using boost::uint32_t;
00279 
00280   if(nr_ch != sig_types.size())
00281     throw(std::logic_error("SampleBlock::init -- sig_types.size() differs from number of channels given!"));
00282 
00283   blocks_  = blocksize;
00284   channels_ = nr_ch;
00285   types_input_ = sig_types;
00286 
00287   if(nr_ch == 0)
00288     return;
00289 
00290   if(!samples_.size() )
00291     samples_.reserve( 4 * samples_.size() );
00292 
00293   samples_.resize(blocks_ *channels_);
00294 
00295   uint32_t o_tmp;
00296   for(unsigned int i=0; i < sig_types.size(); i++)
00297     for(unsigned int x=0; x < sig_types.size()-1-i; x++)
00298       if(sig_types[x] > sig_types[x+1])
00299       {
00300         o_tmp = sig_types[x];
00301         sig_types[x] =sig_types[x+1];
00302         sig_types[x+1] = o_tmp;
00303       }
00304   //       types_ordered_ = sig_types;
00305 
00306   std::pair<uint16_t, uint16_t> pi;   //  ... pos. information (offset, nr_values)
00307   std::pair<uint32_t, std::pair<uint16_t, uint16_t> > si; // samples info (flag)
00308   uint16_t pos = 0;
00309   for(unsigned int n = 1; n < sig_types.size(); n++)
00310     if(sig_types[n-1] != sig_types[n])
00311     {
00312       homogenous_ = 0;
00313       pi = std::make_pair(pos*blocks_ ,(n-pos)*blocks_ );   // (n - pos)
00314       si = std::make_pair(sig_types[n-1], pi);
00315       block_info_.insert(si);
00316       pos = n;
00317     }
00318   pi = std::make_pair(pos*blocks_ , (channels_-pos)*blocks_ );
00319   si = std::make_pair(sig_types[pos], pi);
00320   block_info_.insert(si);
00321 }
00322 
00323 //-----------------------------------------------------------------------------
00324 
00325 template<class T> std::vector<boost::uint32_t> SampleBlock<T>::getTypes()
00326 {
00327   #ifdef DEBUG
00328     std::cout << "SampleBlock: getTypes" << std::endl;
00329   #endif
00330 
00331   using boost::uint16_t;
00332   using boost::uint32_t;
00333 
00334   std::vector<uint32_t> v;
00335   for(std::map<uint32_t, std::pair<uint16_t, uint16_t> >::iterator it = block_info_.begin();
00336       it != block_info_.end(); it++)
00337     v.push_back(it->first);
00338   return(v);
00339 }
00340 
00341 //-----------------------------------------------------------------------------
00342 
00343 template<class T> std::vector<T> SampleBlock<T>::getSamples()
00344 {
00345   #ifdef DEBUG
00346     std::cout << "SampleBlock: getSamples" << std::endl;
00347   #endif
00348 
00349   checkBlockIntegrity();
00350   return(samples_);
00351 }
00352 
00353 //-----------------------------------------------------------------------------
00354 
00355 template<class T> boost::uint32_t SampleBlock<T>::getFlagByNr(boost::uint32_t nr)
00356 {
00357   #ifdef DEBUG
00358     //std::cout << "SampleBlock: getFlagByNr" << std::endl;
00359   #endif
00360 
00361   using boost::uint16_t;
00362   using boost::uint32_t;
00363 
00364   if(nr > block_info_.size())
00365     throw(std::invalid_argument("getFlagByNr -- Signal number higher than nr. of different signals available!"));
00366 
00367   std::map<uint32_t, std::pair<uint16_t, uint16_t> >::iterator m_it(block_info_.begin());
00368   for(uint32_t n = 0; n < nr; n++)
00369     m_it++;
00370 
00371   return(m_it->first);
00372 }
00373 
00374 //-----------------------------------------------------------------------------
00375 
00376 template<class T> std::vector<T> SampleBlock<T>::getSignalByFlag(boost::uint32_t flag)
00377 {
00378   #ifdef DEBUG
00379     std::cout << "SampleBlock: getSignalByFlag" << std::endl;
00380   #endif
00381 
00382   using boost::uint16_t;
00383   using boost::uint32_t;
00384 
00385   std::map<uint32_t, std::pair<uint16_t, uint16_t> >::iterator m_it(block_info_.find(flag));
00386   if(m_it != block_info_.end())
00387   {
00388     checkBlockIntegrity();
00389     typename std::vector<T>::iterator v_it(samples_.begin() + m_it->second.first);
00390     std::vector<T> v(v_it, v_it + m_it->second.second);
00391     return(v);
00392   }
00393   else
00394     throw(std::invalid_argument("getSinalByFlag -- FLAG not set in SampleBlock!"));
00395 }
00396 
00397 //-----------------------------------------------------------------------------
00398 
00399 template<class T> void SampleBlock<T>::getSignalByFlag(boost::uint32_t flag, std::vector<T>& v)
00400 {
00401   #ifdef DEBUG
00402     std::cout << "SampleBlock: getSignalByFlag" << std::endl;
00403   #endif
00404 
00405   using boost::uint16_t;
00406   using boost::uint32_t;
00407 
00408   std::map<uint32_t, std::pair<uint16_t, uint16_t> >::iterator m_it(block_info_.find(flag));
00409   if(m_it != block_info_.end())
00410   {
00411     checkBlockIntegrity();
00412     typename std::vector<T>::iterator v_it(samples_.begin() + m_it->second.first);
00413 
00414     v.assign(v_it, v_it + m_it->second.second);
00415   }
00416   else
00417     throw(std::invalid_argument("getSinalByFlag -- FLAG not set in SampleBlock!"));
00418 }
00419 
00420 //-----------------------------------------------------------------------------
00421 
00422 template<class T> std::vector<T> SampleBlock<T>::getSignalByNr(boost::uint32_t nr)
00423 {
00424   #ifdef DEBUG
00425    // std::cout << "SampleBlock: getSignalByNr" << std::endl;
00426   #endif
00427 
00428   using boost::uint16_t;
00429   using boost::uint32_t;
00430 
00431   if(nr > block_info_.size())
00432     throw(std::invalid_argument("getSinalByNr -- Signal number higher than nr. \
00433       of different signals available!"));
00434   checkBlockIntegrity();
00435 
00436   std::map<uint32_t, std::pair<uint16_t, uint16_t> >::iterator m_it(block_info_.begin());
00437   for(uint32_t n = 0; n < nr; n++)
00438     m_it++;
00439   typename std::vector<T>::iterator v_it(samples_.begin() + m_it->second.first);
00440   std::vector<T> v(v_it, v_it + m_it->second.second);
00441   return(v);
00442 }
00443 
00444 //-----------------------------------------------------------------------------
00445 
00446 template<class T> void SampleBlock<T>::getSignalByNr(boost::uint32_t nr, std::vector<T>& v)
00447 {
00448   #ifdef DEBUG
00449     //std::cout << "SampleBlock: getSignalByNr" << std::endl;
00450   #endif
00451 
00452   using boost::uint16_t;
00453   using boost::uint32_t;
00454 
00455   if(nr > block_info_.size())
00456     throw(std::invalid_argument("getSinalByNr -- Signal number higher than nr. \
00457     of different signals available!"));
00458   checkBlockIntegrity();
00459 
00460   std::map<uint32_t, std::pair<uint16_t, uint16_t> >::iterator m_it(block_info_.begin());
00461   for(uint32_t n = 0; n < nr; n++)
00462     m_it++;
00463   typename std::vector<T>::iterator v_it(samples_.begin() + m_it->second.first);
00464 
00465   v.assign(v_it, v_it + m_it->second.second);
00466 }
00467 
00468 //-----------------------------------------------------------------------------
00469 
00470 template<class T> void SampleBlock<T>::appendBlock(std::vector<T> v, boost::uint16_t nr_blocks)
00471 {
00472   #ifdef DEBUG
00473     //std::cout << "SampleBlock: appendBlock" << std::endl;
00474   #endif
00475 
00476   if(v.size() != channels_)
00477     throw(std::length_error("appendBlock: Appended Block contains more values than sampled channels!"));
00478 
00479   if(nr_blocks == 1)
00480   {
00481     if(blocks_  < curr_block_)
00482       throw(std::length_error("SampleBlock<T>::appendBlock: Tried to append more blocks than specified!"));
00483 
00484     sort(v,types_input_,nr_blocks);
00485 
00486     for(unsigned int n = 0; n < channels_; n++)
00487       samples_[ (n*blocks_ ) + curr_block_ ] = v[n];
00488 
00489     curr_block_++;
00490   }
00491   else
00492   {
00493 
00494      throw(std::length_error("SampleBlock<T>::appendBlock: Operation not supported yet"));
00495 
00496     if(blocks_  < curr_block_ + nr_blocks -1)
00497       throw(std::length_error("SampleBlock<T>::appendBlock: Tried to append more blocks than specified!"));
00498 
00499     sort(v,types_input_, nr_blocks);
00500 
00501 //    for(unsigned int n = 0; n < channels_; n++)
00502 //      for(unsigned int m = 0; n < nr_blocks; m++)
00503         //samples_[ (n*blocks_ ) + curr_block_ ] = v[n];
00504 
00505     curr_block_+= nr_blocks;
00506   }
00507 }
00508 
00509 //-----------------------------------------------------------------------------
00510 
00511 template<class T> void SampleBlock<T>::setSamples(std::vector<T> v)
00512 {
00513   #ifdef DEBUG
00514     //std::cout << "SampleBlock: setSamples" << std::endl;
00515   #endif
00516 
00517   if(v.size() != static_cast<boost::uint32_t>(blocks_ *channels_))
00518   {
00519     std::string ex_str;
00520     std::string nr_samples(boost::lexical_cast<std::string>(v.size()));
00521     std::string available(boost::lexical_cast<std::string>(blocks_ *channels_));
00522     ex_str = "Values in vector: " + nr_samples + " -- awaiting: " + available;
00523       throw(std::length_error("Sample Block contains a different amount of values than sampled channels! -- " +ex_str ));
00524   }
00525   if(homogenous_)
00526     samples_.assign(v.begin(),v.end());
00527   else
00528   {
00529     sort(v,types_input_, blocks_);
00530     samples_.assign(v.begin(),v.end());
00531   }
00532 }
00533 //-----------------------------------------------------------------------------
00534 //-----------------------------------------------------------------------------
00535 
00536 template<class T> void SampleBlock<T>::sort(std::vector<T>& v,
00537     std::vector<boost::uint32_t> order, boost::uint32_t nr_blocks)
00538 {
00539   //#ifdef DEBUG
00540   //  std::cout << "SampleBlock: sort" << std::endl;
00541   //#endif
00542 
00543   double v_tmp;
00544   boost::uint32_t o_tmp;
00545 
00546   for(unsigned int i=0; i < order.size(); i++)
00547     for(unsigned int x=0; x < order.size()-1-i; x++)
00548       if(order[x] > order[x+1])
00549       {
00550         o_tmp = order[x];
00551         order[x] =order[x+1];
00552         order[x+1] = o_tmp;
00553 
00554         for(unsigned int n = 0; n < nr_blocks; n++)
00555         {
00556           v_tmp = v[nr_blocks * x +n];
00557           v[(nr_blocks * x) +n] = v[nr_blocks * x +n +nr_blocks];
00558           v[(nr_blocks * x) +n +nr_blocks] = v_tmp;
00559         }
00560       }
00561 }
00562 
00563 //-----------------------------------------------------------------------------
00564 
00565 template<class T> void SampleBlock<T>::checkBlockIntegrity()
00566 {
00567   #ifdef DEBUG
00568     //std::cout << "SampleBlock: checkBlockIntegrity" << std::endl;
00569   #endif
00570 
00571   if(samples_.size() != static_cast<boost::uint32_t>(channels_*blocks_ ))
00572   {
00573     std::string ex_str;
00574     std::string n(boost::lexical_cast<std::string>(samples_.size()));
00575     std::string c(boost::lexical_cast<std::string>(channels_));
00576     std::string b(boost::lexical_cast<std::string>(blocks_ ));
00577     ex_str = "("+n+ ") different to channels_ ("+c+ ") * blocks_  ("+b+ ")!";
00578     throw(std::length_error("Inconsistent sample block -- nr of samples" + ex_str));
00579   }
00580 }
00581 
00582 //-----------------------------------------------------------------------------
00583 
00584 } // Namespace tobiss
00585 
00586 #endif // SAMPLEBLOCK_H
 All Data Structures Files Functions Variables