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 #include "SoundFileSource2.h" 00020 #include "../common_source.h" 00021 00022 using namespace std; 00023 using namespace Marsyas; 00024 00025 SoundFileSource2::SoundFileSource2(mrs_string name):MarSystem("SoundFileSource2",name) 00026 { 00027 src_ = NULL; 00028 00029 addControls(); 00030 00031 //create a default file source object 00032 fileReady(false); 00033 } 00034 00035 SoundFileSource2::~SoundFileSource2() 00036 { 00037 delete src_; 00038 } 00039 00040 SoundFileSource2::SoundFileSource2(const SoundFileSource2& a):MarSystem(a)//[!] 00041 { 00042 src_ = new AbsSoundFileSource2("AbsSoundFileSource2", name_); 00043 filename_ = "defaultfile"; 00044 } 00045 00046 MarSystem* 00047 SoundFileSource2::clone() const 00048 { 00049 return new SoundFileSource2(*this); 00050 } 00051 00052 void 00053 SoundFileSource2::fileReady(bool ready) 00054 { 00055 if(ready) 00056 { 00057 //...read and setup audio file at src_ level 00058 src_->updControl("mrs_string/filename", getctrl("mrs_string/filename")); 00059 00060 //check if audio file header was read without errors 00061 //(if an error occurred, the filename is set to "defaultfile" by src_ ) 00062 mrs_string filename = src_->getctrl("mrs_string/filename")->to<mrs_string>(); 00063 if (filename == "defaultfile") 00064 { 00065 fileReady(false); 00066 return; 00067 } 00068 setctrl("mrs_string/filename", filename); 00069 filename_ = filename; 00070 00071 setctrl("mrs_bool/hasData", src_->getctrl("mrs_bool/hasData")); 00072 00073 //rewind 00074 setctrl("mrs_natural/pos", 0); 00075 } 00076 else 00077 { 00078 //set audio file object to a dummy audio file reader 00079 delete src_; 00080 src_ = new AbsSoundFileSource2("AbsSoundFileSource2", name_); 00081 00082 //...set controls to a default state 00083 setctrl("mrs_string/filename", "defaultfile"); 00084 filename_ = "defaultfile"; 00085 00086 setctrl("mrs_natural/nChannels", (mrs_natural)1); 00087 setctrl("mrs_real/israte", MRS_DEFAULT_SLICE_SRATE); 00088 setctrl("mrs_bool/hasData", false); 00089 00090 //rewind 00091 setctrl("mrs_natural/pos", 0); 00092 } 00093 } 00094 00095 void 00096 SoundFileSource2::addControls() 00097 { 00098 //read/write controls (controls with state) 00099 addctrl("mrs_string/filename", "defaultfile"); 00100 setctrlState("mrs_string/filename", true); 00101 addctrl("mrs_natural/pos", (mrs_natural)0); 00102 setctrlState("mrs_natural/pos", true); 00103 00104 //read-only controls (stateless) 00105 addctrl("mrs_bool/hasData", true); 00106 addctrl("mrs_natural/nChannels",(mrs_natural)1); 00107 addctrl("mrs_natural/size", (mrs_natural)0); 00108 } 00109 00110 void 00111 SoundFileSource2::myUpdate(MarControlPtr sender) 00112 { 00113 (void) sender; //suppress warning of unused parameter(s) 00114 MRSDIAG("SoundFileSource2::localUpdate"); 00115 00116 //if file name changed, open new audio file 00117 mrs_string filename = getctrl("mrs_string/filename")->to<mrs_string>(); 00118 if (filename_ != filename) 00119 { 00120 //if valid audio file format, create corresponding file object (src_)... 00121 if (checkType() == true) 00122 { 00123 //read audio file header and configure objects accordingly 00124 fileReady(true); 00125 } 00126 else //if empty or invalid filename... 00127 { 00128 //...go to a default (dummy) state 00129 fileReady(false); 00130 } 00131 } 00132 00133 //pass configuration to file source object (src_) and update it 00134 src_->setctrl("mrs_natural/pos", getctrl("mrs_natural/pos")); 00135 src_->setctrl("mrs_bool/hasData", getctrl("mrs_bool/hasData")); 00136 //avoid calling src_->update unless it's really necessary 00137 if(getctrl("mrs_natural/inSamples") != src_->getctrl("mrs_natural/inSamples") || 00138 getctrl("mrs_natural/inObservations") != src_->getctrl("mrs_natural/inObservations")) 00139 { 00140 src_->setctrl("mrs_natural/inSamples", getctrl("mrs_natural/inSamples")); 00141 src_->setctrl("mrs_natural/inObservations", getctrl("mrs_natural/inObservations")); 00142 src_->update(); 00143 } 00144 00145 //sync controls with file source object 00146 setctrl("mrs_natural/onSamples", src_->getctrl("mrs_natural/onSamples")); 00147 setctrl("mrs_natural/onObservations", src_->getctrl("mrs_natural/onObservations")); 00148 //setctrl("mrs_real/israte", src_->getctrl("mrs_real/israte")); 00149 setctrl("mrs_real/osrate", src_->getctrl("mrs_real/osrate")); 00150 setctrl("mrs_string/onObsNames", src_->getctrl("mrs_string/onObsNames")); 00151 00152 setctrl("mrs_natural/nChannels", src_->getctrl("mrs_natural/nChannels")); 00153 setctrl("mrs_bool/hasData", src_->getctrl("mrs_bool/hasData")); 00154 setctrl("mrs_natural/size", src_->getctrl("mrs_natural/size")); 00155 setctrl("mrs_natural/pos", src_->getctrl("mrs_natural/pos")); 00156 } 00157 00158 bool 00159 SoundFileSource2::checkType() 00160 { 00161 mrs_string filename = getctrl("mrs_string/filename")->to<mrs_string>(); 00162 00163 if (filename == "defaultfile") 00164 { 00165 MRSWARN("SoundFileSource2::checkType: empty filename"); 00166 return false; 00167 } 00168 00169 //check if file exists 00170 FILE * sfp = fopen(filename.c_str(), "r"); 00171 if (sfp == NULL) 00172 { 00173 mrs_string wrn = "SoundFileSource2::checkType: Problem opening file "; 00174 wrn += filename; 00175 MRSWARN(wrn); 00176 return false; 00177 } 00178 fclose(sfp); 00179 00180 // try to open file with appropriate format 00181 mrs_string::size_type pos = filename.rfind(".", filename.length()); 00182 mrs_string ext; 00183 00184 if (pos == mrs_string::npos) 00185 ext = ""; 00186 else 00187 ext = filename.substr(pos, filename.length()); 00188 /*if (ext == ".au") 00189 { 00190 delete src_; 00191 src_ = new AuFileSource(name_); 00192 } 00193 else 00194 */ 00195 if (ext == ".wav") 00196 { 00197 delete src_; 00198 src_ = new WavFileSource2(name_); 00199 } 00200 /* 00201 else if (ext == ".raw") 00202 { 00203 delete src_; 00204 src_ = new RawFileSource(name_); 00205 } 00206 else if (ext == ".mf") 00207 { 00208 delete src_; 00209 src_ = new CollectionFileSource(name_); 00210 } 00211 #ifdef MAD_MP3 00212 else if (ext == ".mp3") 00213 { 00214 delete src_; 00215 src_ = new MP3FileSource(name_); 00216 } 00217 #endif 00218 #ifdef OGG_VORBIS 00219 else if (ext == ".ogg") 00220 { 00221 cout << "OGG" << endl; 00222 delete src_; 00223 src_ = new OggFileSource(name_); 00224 } 00225 #endif 00226 */ 00227 else 00228 { 00229 if (filename != "defaultfile") 00230 { 00231 mrs_string wrn = "Unsupported format for file "; 00232 wrn += filename; 00233 MRSWARN(wrn); 00234 return false; 00235 } 00236 else 00237 return false; 00238 } 00239 return true; 00240 } 00241 00242 00243 realvec& 00244 SoundFileSource2::getAudioRegion(mrs_natural startSample, mrs_natural endSample) 00245 { 00246 return src_->getAudioRegion(startSample, endSample); 00247 } 00248 00249 void 00250 SoundFileSource2::myProcess(realvec& in, realvec &out) 00251 { 00252 //read audio data from audio file 00253 src_->process(in,out); 00254 00255 //sync play controls (no update needed!) 00256 setctrl("mrs_natural/pos", src_->getctrl("mrs_natural/pos")); 00257 setctrl("mrs_bool/hasData", src_->getctrl("mrs_bool/hasData")); 00258 00259 //if muted, replace output data with silence 00260 if(getctrl("mrs_bool/mute")->to<mrs_bool>()) 00261 out.setval(0.0); 00262 }