Marsyas
0.6.0-alpha
|
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 }