Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/MidiFileSynthSource.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 #include "../common_source.h"
00020 #include "MidiFileSynthSource.h"
00021 
00022 using std::ostringstream;
00023 using namespace Marsyas;
00024 
00025 MidiFileSynthSource::MidiFileSynthSource(mrs_string name):MarSystem("MidiFileSynthSource",name)
00026 {
00027   addControls();
00028   nChannels_ = 0;
00029   size_ = 0;
00030 }
00031 
00032 MidiFileSynthSource::~MidiFileSynthSource()
00033 {
00034 
00035 }
00036 
00037 MarSystem*
00038 MidiFileSynthSource::clone() const
00039 {
00040   return new MidiFileSynthSource(*this);
00041 }
00042 
00043 MidiFileSynthSource::MidiFileSynthSource(const MidiFileSynthSource& a):MarSystem(a)
00044 {
00045   filename_ = a.filename_;
00046   nChannels_ = a.nChannels_;
00047   size_ = a.size_;
00048 
00049   ctrl_filename_ = getctrl("mrs_string/filename");
00050   ctrl_numActiveNotes_ = getctrl("mrs_natural/numActiveNotes");
00051   ctrl_nChannels_ = getctrl("mrs_natural/nChannels");
00052   ctrl_pos_ = getctrl("mrs_natural/pos");
00053   ctrl_hasData_ = getctrl("mrs_bool/hasData");
00054 
00055   ctrl_start_ = getctrl("mrs_real/start");
00056   ctrl_end_ = getctrl("mrs_real/end");
00057 
00058   ctrl_winSize_ = getctrl("mrs_natural/winSize");
00059 
00060   ctrl_sigNewTextWin_ = getctrl("mrs_bool/sigNewTextWin");
00061   ctrl_newTextWin_ = getctrl("mrs_bool/newTextWin");
00062 
00063   ctrl_size_ = getctrl("mrs_natural/size");
00064 }
00065 
00066 void
00067 MidiFileSynthSource::addControls()
00068 {
00069   addctrl("mrs_string/filename", "", ctrl_filename_);
00070   setctrlState("mrs_string/filename", true);
00071 
00072   addctrl("mrs_natural/numActiveNotes", 0, ctrl_numActiveNotes_);
00073 
00074   addctrl("mrs_natural/nChannels", 0, ctrl_nChannels_);
00075 
00076   addctrl("mrs_natural/pos", 0, ctrl_pos_);
00077 
00078   addctrl("mrs_bool/hasData", true, ctrl_hasData_);
00079 
00080   addctrl("mrs_real/start", 0.0, ctrl_start_);
00081   addctrl("mrs_real/end", 0.0, ctrl_end_);
00082 
00083   addctrl("mrs_natural/winSize", MRS_DEFAULT_SLICE_NSAMPLES, ctrl_winSize_);
00084   ctrl_winSize_->setState(true);
00085 
00086   addctrl("mrs_bool/sigNewTextWin", true, ctrl_sigNewTextWin_);
00087   ctrl_sigNewTextWin_->setState(true);
00088 
00089   addctrl("mrs_bool/newTextWin", false, ctrl_newTextWin_);
00090   ctrl_newTextWin_->setState(true);
00091 
00092   addctrl("mrs_natural/size", 0, ctrl_size_);
00093 }
00094 
00095 void
00096 MidiFileSynthSource::myUpdate(MarControlPtr sender)
00097 {
00098   (void) sender;  //suppress warning of unused parameter(s)
00099   MRSDIAG("MidiFileSynthSource::myUpdate");
00100 
00101   MATLAB_PUT(ctrl_winSize_->to<mrs_natural>(), "winSize");
00102   MATLAB_PUT(inSamples_, "hopSize");
00103 
00104   mrs_bool sigNewTextWin = ctrl_sigNewTextWin_->to<mrs_bool>();
00105   MATLAB_PUT((mrs_natural)sigNewTextWin, "sigNewTextWin");
00106   //in case texture windows are set from the outside...
00107   if(!sigNewTextWin)
00108   {
00109     if(ctrl_newTextWin_->isTrue())
00110     {
00111       //get number of playing notes in texture window
00112       mrs_natural numActiveNotes;
00113       MATLAB_GET("numActiveNotes", numActiveNotes);
00114       ctrl_numActiveNotes_->setValue(numActiveNotes);
00115 
00116       MATLAB_EVAL("textWinStart = textWinEnd+1;textWinEnd = endPos2;");
00117 
00118       //reset MATLAB
00119       //MATLAB_EVAL("numActiveNotes = 0;");
00120 
00121       //reset control
00122       ctrl_newTextWin_->setValue(false, NOUPDATE);
00123     }
00124   }
00125 
00126   if(filename_ != ctrl_filename_->to<mrs_string>())
00127   {
00128     filename_ = ctrl_filename_->to<mrs_string>();
00129     MATLAB_PUT(filename_, "filename");
00130     MATLAB_PUT(israte_, "fs");
00131     MATLAB_PUT(ctrl_start_->to<mrs_real>(), "startSeg");
00132     MATLAB_PUT(ctrl_end_->to<mrs_real>(), "endSeg");
00133 
00134     //Synthesize MIDI file to audio
00135     MATLAB_EVAL("synthetizeMIDI;");
00136 
00137     MATLAB_GET("numChannels", nChannels_);
00138     ctrl_nChannels_->setValue(nChannels_, NOUPDATE);
00139 
00140     MATLAB_GET("audioLength", size_); //in samples
00141     ctrl_size_->setValue(size_, NOUPDATE);
00142 
00143     ctrl_pos_->setValue(0, NOUPDATE);
00144     if(size_>0)
00145       ctrl_hasData_->setValue(true, NOUPDATE);
00146     else
00147       ctrl_hasData_->setValue(false, NOUPDATE);
00148   }
00149 
00150   ctrl_onSamples_->setValue(ctrl_inSamples_, NOUPDATE);
00151   ctrl_onObservations_->setValue(1, NOUPDATE);
00152   ctrl_osrate_->setValue(ctrl_israte_, NOUPDATE);
00153   ctrl_onObsNames_->setValue("MIDIaudio", NOUPDATE);
00154 }
00155 
00156 void
00157 MidiFileSynthSource::myProcess(realvec& in, realvec &out)
00158 {
00159   (void) in;
00160   if(size_ == 0)
00161     return;
00162 
00163   mrs_natural pos = ctrl_pos_->to<mrs_natural>();
00164 
00165   //detect end of file
00166   if(pos > size_)
00167   {
00168     out.setval(0.0);//fill with silence
00169 
00170     if(!ctrl_hasData_->isTrue())
00171       return;
00172 
00173     ctrl_hasData_->setValue(false);
00174 
00175     //flush last texture window
00176     if(ctrl_sigNewTextWin_->isTrue())
00177     {
00178       mrs_natural numActiveNotes;
00179       MATLAB_GET("numActiveNotes", numActiveNotes);
00180       ctrl_numActiveNotes_->setValue(numActiveNotes);
00181       ctrl_newTextWin_->setValue(true, NOUPDATE);
00182     }
00183 
00184     return;
00185   }
00186 
00187   MATLAB_PUT(pos+1, "pos");//MATLAB uses indexes in the range [1,...]
00188   MATLAB_EVAL("computeAudioFrame;");
00189   MATLAB_GET("audioFrame", out);
00190 
00191   ctrl_pos_->setValue(pos+onSamples_);
00192 
00193   //check if this audio frame is the last one in the current texture window:
00194   //if it is, then signal a new texture window
00195   if(ctrl_sigNewTextWin_->isTrue())
00196   {
00197     mrs_natural newTextWin = 0;
00198     MATLAB_GET("newTextWin", newTextWin);
00199     if(newTextWin!=0)//if true...
00200     {
00201       mrs_natural numActiveNotes;
00202       MATLAB_GET("numActiveNotes", numActiveNotes);
00203       ctrl_numActiveNotes_->setValue(numActiveNotes);
00204       //MATLAB_EVAL("numActiveNotes = 0;"); //reset
00205     }
00206     ctrl_newTextWin_->setValue(newTextWin!=0, NOUPDATE);
00207   }
00208 }