Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/AudioSourceBlocking.cpp
Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 1998-2010 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 
00020 
00021 #include "../common_source.h"
00022 #include "AudioSourceBlocking.h"
00023 
00024 
00025 #include "RtAudio3.h"
00026 
00027 
00028 using std::ostringstream;
00029 using namespace Marsyas;
00030 
00031 AudioSourceBlocking::AudioSourceBlocking(mrs_string name):MarSystem("AudioSourceBlocking", name)
00032 {
00033   data_ = NULL;
00034   audio_ = NULL;
00035 
00036   ri_ = 0;
00037   preservoirSize_ = 0;
00038 
00039   isInitialized_ = false;
00040   stopped_ = true;
00041 
00042   rtSrate_ = 0;
00043   bufferSize_ = 0;
00044   rtChannels_ = 0;
00045   rtDevice_ = 0;
00046   nChannels_ = 0;
00047 
00048   addControls();
00049 }
00050 
00051 AudioSourceBlocking::~AudioSourceBlocking()
00052 {
00053   delete audio_;
00054   data_ = NULL; // RtAudio deletes the buffer itself.
00055 }
00056 
00057 
00058 MarSystem*
00059 AudioSourceBlocking::clone() const
00060 {
00061   return new AudioSourceBlocking(*this);
00062 }
00063 
00064 void
00065 AudioSourceBlocking::addControls()
00066 {
00067   addctrl("mrs_natural/nChannels", 1);
00068 
00069 
00070 #ifdef MARSYAS_MACOSX
00071   addctrl("mrs_natural/bufferSize", 512);
00072 #else
00073   addctrl("mrs_natural/bufferSize", 256);
00074 #endif
00075 
00076   addctrl("mrs_natural/nBuffers", 4);
00077 
00078   addctrl("mrs_bool/initAudio", false);
00079   setctrlState("mrs_bool/initAudio", true);
00080 
00081   addctrl("mrs_bool/hasData", true);
00082   addctrl("mrs_real/gain", 1.0);
00083 
00084   addctrl("mrs_natural/device", 0);
00085 }
00086 
00087 void
00088 AudioSourceBlocking::myUpdate(MarControlPtr sender)
00089 {
00090   (void) sender;  //suppress warning of unused parameter(s)
00091   MRSDIAG("AudioSourceBlocking::myUpdate");
00092 
00093 
00094   if (getctrl("mrs_bool/initAudio")->to<mrs_bool>())
00095     initRtAudio();
00096 
00097 
00098 
00099 
00100   //set output controls
00101   setctrl("mrs_natural/onSamples", getctrl("mrs_natural/inSamples"));
00102   setctrl("mrs_real/osrate", getctrl("mrs_real/israte"));
00103   setctrl("mrs_natural/onObservations", getctrl("mrs_natural/nChannels"));
00104 
00105 
00106   inObservations_ = ctrl_inObservations_->to<mrs_natural>();
00107   onObservations_ = ctrl_onObservations_->to<mrs_natural>();
00108   gain_ = getctrl("mrs_real/gain")->to<mrs_real>();
00109 
00110   //resize reservoir if necessary
00111 
00112 
00113   if (inSamples_ * onObservations_ < bufferSize_)
00114     reservoirSize_ = 2 * onObservations_ * bufferSize_;
00115   else
00116     reservoirSize_ = 2 * inSamples_ * onObservations_;
00117 
00118   if (reservoirSize_ > preservoirSize_)
00119   {
00120     reservoir_.stretch(reservoirSize_);
00121   }
00122   preservoirSize_ = reservoirSize_;
00123 }
00124 
00125 
00126 void
00127 AudioSourceBlocking::initRtAudio()
00128 {
00129 
00130   bufferSize_ = (int)getctrl("mrs_natural/bufferSize")->to<mrs_natural>();
00131   nChannels_ = getctrl("mrs_natural/nChannels")->to<mrs_natural>();
00132   rtSrate_ = (int)getctrl("mrs_real/israte")->to<mrs_real>();
00133   rtChannels_ = (int)getctrl("mrs_natural/nChannels")->to<mrs_natural>();
00134   nBuffers_ = (int)getctrl("mrs_natural/nBuffers")->to<mrs_natural>();
00135   rtDevice_ = (int)getctrl("mrs_natural/device")->to<mrs_natural>();
00136 
00137 
00138 
00139 //marsyas represents audio data as float numbers
00140   RtAudio3Format rtFormat = (sizeof(mrs_real) == 8) ? RTAUDIO3_FLOAT64 : RTAUDIO3_FLOAT32;
00141 
00142 
00143 
00144   //Create new RtAudio object (delete any existing one)
00145 
00146   if (audio_ != NULL)
00147   {
00148     audio_->stopStream();
00149     delete audio_;
00150   }
00151   try
00152   {
00153     audio_ = new RtAudio3(0, 0, rtDevice_, rtChannels_, rtFormat,
00154                           rtSrate_, &bufferSize_, nBuffers_);
00155     data_ = (mrs_real *) audio_->getStreamBuffer();
00156   }
00157   catch (RtError3 &error)
00158   {
00159     error.printMessage();
00160   }
00161 
00162   //update bufferSize control which may have been changed
00163   //by RtAudio (see RtAudio documentation)
00164   setctrl("mrs_natural/bufferSize", (mrs_natural)bufferSize_);
00165 
00166   if (audio_ != NULL)
00167     audio_->stopStream();
00168 
00169 
00170   if (rtDevice_ !=0) {
00171     RtAudio3DeviceInfo info;
00172     info = audio_->getDeviceInfo(rtDevice_);
00173   }
00174 
00175   isInitialized_ = true;
00176   setctrl("mrs_bool/initAudio", false);
00177 }
00178 
00179 void
00180 AudioSourceBlocking::start()
00181 {
00182   if ( stopped_ && audio_) {
00183     audio_->startStream();
00184     stopped_ = false;
00185   }
00186 }
00187 
00188 void
00189 AudioSourceBlocking::stop()
00190 {
00191   if ( !stopped_ && audio_) {
00192     audio_->stopStream();
00193     stopped_ = true;
00194   }
00195 }
00196 
00197 void
00198 AudioSourceBlocking::localActivate(bool state)
00199 {
00200   if(state)
00201     start();
00202   else
00203     stop();
00204 }
00205 
00206 void
00207 AudioSourceBlocking::myProcess(realvec& in, realvec& out)
00208 {
00209   (void) in;
00210 
00211   mrs_natural t,o;
00212 
00213   //check if RtAudio is initialized
00214   if (!isInitialized_)
00215     return;
00216 
00217   //check MUTE
00218   if(ctrl_mute_->isTrue()) return;
00219 
00220   //assure that RtAudio thread is running
00221   //(this may be needed by if an explicit call to start()
00222   //is not done before ticking or calling process() )
00223   if ( stopped_ )
00224     start();
00225 
00226   int ssize = onSamples_ * onObservations_;
00227 
00228   //send audio to output
00229   while (ri_ < ssize)
00230   {
00231     try
00232     {
00233 
00234       audio_->tickStream();
00235 
00236     }
00237     catch (RtError3 &error)
00238     {
00239       error.printMessage();
00240     }
00241 
00242     for (t=0; t < onObservations_ * bufferSize_; t++)
00243     {
00244       reservoir_(ri_) = data_[t];
00245       ri_++;
00246     }
00247   }
00248 
00249   for (o=0; o < onObservations_; o++)
00250     for (t=0; t < onSamples_; t++)
00251     {
00252       out(o,t) = gain_ * reservoir_(onObservations_ * t + o);
00253     }
00254 
00255   for (t=ssize; t < ri_; t++)
00256     reservoir_(t-ssize) = reservoir_(t);
00257 
00258   ri_ = ri_ - ssize;
00259 
00260   /* MATLAB_PUT(out, "AudioSourceBlocking_out");
00261    MATLAB_EVAL("plot(AudioSourceBlocking_out)");*/
00262 }