TOBI SignalServer
0.1
|
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