TOBI SignalServer  0.1
/home/breidi/Dropbox/signalserver/src/hardware/sine_generator_no_artificial_base.cpp
00001 /*
00002     This file is part of the TOBI signal server.
00003 
00004     The TOBI signal server 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 3 of the License, or
00007     (at your option) any later version.
00008 
00009     The TOBI signal server 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017     Copyright 2010 Christian Breitwieser
00018     Contact: c.breitwieser@tugraz.at
00019 */
00020 
00021 #include "hardware/sine_generator.h"
00022 
00023 #include <math.h>
00024 
00025 #include <boost/lexical_cast.hpp>
00026 #include <boost/bind.hpp>
00027 
00028 namespace tobiss
00029 {
00030 using boost::uint8_t;
00031 using boost::uint16_t;
00032 using boost::uint32_t;
00033 
00034 using boost::lexical_cast;
00035 using boost::bad_lexical_cast;
00036 
00037 using std::map;
00038 using std::vector;
00039 using std::string;
00040 using std::cout;
00041 using std::endl;
00042 
00043 
00044 const HWThreadBuilderTemplateRegistrator<SineGenerator> SineGenerator::factory_registrator_ ("sinegen", "sinegenerator");
00045 
00046 //-----------------------------------------------------------------------------
00047 
00048 SineGenerator::SineGenerator(boost::asio::io_service& io, ticpp::Iterator<ticpp::Element> hw)
00049 : HWThread(), acquiring_(0), current_block_(0), td_(0)
00050 {
00051   #ifdef DEBUG
00052     cout << "SineGenerator: Constructor" << endl;
00053   #endif
00054 
00055   setType("Sine Generator");
00056   setHardware(hw);
00057 
00058   step_ = 1/static_cast<float>(fs_);
00059   cycle_dur_ = 1/static_cast<float>(fs_);
00060   boost::posix_time::microseconds period(1000000/fs_);
00061   td_ += period;
00062 
00063   buffer_.init(blocks_ , nr_ch_ , channel_types_);
00064   data_.init(blocks_ , nr_ch_ , channel_types_);
00065 
00066   samples_.resize(nr_ch_ ,0);
00067   t_ = new boost::asio::deadline_timer(io, td_);
00068 
00069   cout << " * SineGenerator sucessfully initialized" << endl;
00070   cout << "    fs: " << fs_ << "Hz, nr of channels: " << nr_ch_  << ", blocksize: " << blocks_  << endl;
00071 
00072 }
00073 
00074 //-----------------------------------------------------------------------------
00075 
00076 void SineGenerator::run()
00077 {
00078   #ifdef DEBUG
00079     cout << "SineGenerator: run" << endl;
00080   #endif
00081 
00082   running_ = 1;
00083   genSine();
00084   cout << " * SineGenerator sucessfully started" << endl;
00085 }
00086 
00087 
00088 //-----------------------------------------------------------------------------
00089 
00090 void SineGenerator::stop()
00091 {
00092   #ifdef DEBUG
00093     cout << "SineGenerator: stop" << endl;
00094   #endif
00095 
00096   running_ = 0;
00097   cond_.notify_all();
00098   cout << " * SineGenerator sucessfully stopped" << endl;
00099 }
00100 
00101 //-----------------------------------------------------------------------------
00102 
00103 SampleBlock<double> SineGenerator::getSyncData()
00104 {
00105   #ifdef DEBUG
00106     cout << "SineGenerator: getSyncData" << endl;
00107   #endif
00108 
00109   if(!acquiring_)
00110     acquiring_ = 1;
00111 
00112   boost::unique_lock<boost::mutex> syn(sync_mut_);
00113   while(!samples_available_ && running_)
00114     cond_.wait(syn);
00115   boost::shared_lock<boost::shared_mutex> lock(rw_);
00116   samples_available_ = false;
00117   lock.unlock();
00118   cond_.notify_all();
00119   syn.unlock();
00120   return(data_);
00121 }
00122 
00123 //-----------------------------------------------------------------------------
00124 
00125 SampleBlock<double> SineGenerator::getAsyncData()
00126 {
00127   #ifdef DEBUG
00128     cout << "SineGenerator: getAsyncData" << endl;
00129   #endif
00130   boost::shared_lock<boost::shared_mutex> lock(rw_);
00131   samples_available_ = false;
00132   lock.unlock();
00133   return(data_);
00134 }
00135 
00136 //-----------------------------------------------------------------------------
00137 
00138 void SineGenerator::genSine()
00139 {
00140   #ifdef DEBUG
00141     cout << "SineGenerator: genSine" << endl;
00142   #endif
00143 
00144   for(uint16_t n = 0; n < nr_ch_ ; n++)
00145     samples_[n] = sin(step_ * 2 * PI + n/4);
00146 
00147   (step_ < 1-cycle_dur_ ? step_ += cycle_dur_ : step_ = 0);
00148   t_->expires_at(t_->expires_at() + td_);
00149 
00150   if(blocks_  == 1)
00151   {
00152     boost::unique_lock<boost::shared_mutex> lock(rw_);
00153     boost::unique_lock<boost::mutex> syn(sync_mut_);
00154     samples_available_ = true;
00155     data_.setSamples(samples_);
00156     lock.unlock();
00157     cond_.notify_all();
00158     if(isMaster() && acquiring_)
00159     {
00160       cond_.wait(sync_mut_);
00161       // if( !cond_.timed_wait(sync_mut_, td_))
00162       //   cerr << "Warning: New data was not fetched fast enough!" << endl;
00163       //   throw std::runtime_error("SineGenerator::genSine() -- Timeout; New data was not fetched fast enough!");
00164     }
00165     syn.unlock();
00166   }
00167   else
00168   {
00169     buffer_.appendBlock(samples_);
00170     current_block_++;
00171 
00172     if(current_block_ == blocks_ )
00173     {
00174       boost::unique_lock<boost::shared_mutex> lock(rw_);
00175       boost::unique_lock<boost::mutex> syn(sync_mut_);
00176       samples_available_ = true;
00177       data_ = buffer_;
00178       lock.unlock();
00179       cond_.notify_all();
00180       buffer_.reset();
00181       current_block_ = 0;
00182       if(isMaster() && acquiring_)
00183       {
00184         cond_.wait(sync_mut_);
00185         // if( !cond_.timed_wait(sync_mut_, td_))
00186         //   cerr << "Warning: New data was not fetched fast enough!" << endl;
00187         //   throw std::runtime_error("SineGenerator::genSine() -- Timeout; New data was not fetched fast enough!");
00188       }
00189       syn.unlock();
00190     }
00191   }
00192   if(running_)
00193     t_->async_wait(boost::bind(&SineGenerator::genSine, this));
00194 }
00195 
00196 //-----------------------------------------------------------------------------
00197 
00198 void SineGenerator::setHardware(ticpp::Iterator<ticpp::Element>const &hw)
00199 {
00200   #ifdef DEBUG
00201     cout << "SineGenerator: setHardware" << endl;
00202   #endif
00203 
00204   checkMandatoryHardwareTags(hw);
00205   ticpp::Iterator<ticpp::Element> ds(hw->FirstChildElement(hw_devset_, true));
00206 
00207   setDeviceSettings(ds);
00208 
00209   ticpp::Iterator<ticpp::Element> cs(hw->FirstChildElement(hw_chset_, false));
00210   if (cs != cs.end())
00211   {
00212     for(ticpp::Iterator<ticpp::Element> it(cs); ++it != it.end(); )
00213       if(it->Value() == hw_chset_)
00214       {
00215         string ex_str(type_ + " -- ");
00216         ex_str += "Multiple channel_settings found!";
00217         throw(std::invalid_argument(ex_str));
00218       }
00219       setChannelSettings(cs);
00220   }
00221 }
00222 
00223 //-----------------------------------------------------------------------------
00224 
00225 void SineGenerator::setDeviceSettings(ticpp::Iterator<ticpp::Element>const &father)
00226 {
00227   #ifdef DEBUG
00228     cout << "SineGenerator: setDeviceSettings" << endl;
00229   #endif
00230 
00231   ticpp::Iterator<ticpp::Element> elem(father->FirstChildElement(hw_fs_,true));
00232   setSamplingRate(elem);
00233 
00234   elem = father->FirstChildElement(hw_channels_,false);
00235   if(elem != elem.end())
00236     setDeviceChannels(elem);
00237 
00238   elem = father->FirstChildElement(hw_blocksize_,false);
00239   if(elem != elem.end())
00240     setBlocks(elem);
00241 }
00242 
00243 //---------------------------------------------------------------------------------------
00244 
00245 void SineGenerator::setChannelSettings(ticpp::Iterator<ticpp::Element>const &father)
00246 {
00247   #ifdef DEBUG
00248     cout << "SineGenerator: setChannelSettings" << endl;
00249   #endif
00250 
00251   ticpp::Iterator<ticpp::Element> elem(father->FirstChildElement(hw_chset_sel_,false));
00252   if (elem != elem.end())
00253     setChannelSelection(elem);
00254 }
00255 
00256 //---------------------------------------------------------------------------------------
00257 
00258 } // Namespace tobiss
 All Data Structures Files Functions Variables