Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/PhiSEMSource.cpp
Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 1998-2006 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 
00029 #include "../common_source.h"
00030 #include "PhiSEMSource.h"
00031 
00032 using std::ostringstream;
00033 using namespace Marsyas;
00034 
00035 const mrs_real PhiSEMSource::MIN_ENERGY = 0.3;
00036 const mrs_real PhiSEMSource::MAX_ENERGY = 2000;
00037 
00038 PhiSEMSource::PhiSEMSource(mrs_string name)
00039   : MarSystem("PhiSEMSource", name) {
00040   addControls();
00041   temp_ = 0.0;
00042   shakeEnergy_ = 0.0;
00043   soundLevel_ = 0.0;
00044   sample_ = 0;
00045 }
00046 
00047 PhiSEMSource::PhiSEMSource(const PhiSEMSource& source)
00048   : MarSystem(source) {
00049   numObjects_   = getctrl("mrs_natural/numObjects");
00050   systemDecay_  = getctrl("mrs_real/systemDecay");
00051   soundDecay_   = getctrl("mrs_real/soundDecay");
00052   baseGain_ = getctrl("mrs_real/baseGain");
00053 }
00054 
00055 PhiSEMSource::~PhiSEMSource() {}
00056 
00057 MarSystem*
00058 PhiSEMSource::clone() const {
00059   return new PhiSEMSource(*this);
00060 }
00061 
00062 void PhiSEMSource::addControls() {
00063   //Add specific controls needed by this MarSystem.
00064   addctrl("mrs_natural/numObjects", 25, numObjects_);
00065   setctrlState("mrs_natural/numObjects", true);
00066   addctrl("mrs_real/systemDecay", 0.999, systemDecay_);
00067   setctrlState("mrs_real/systemDecay", true);
00068   addctrl("mrs_real/soundDecay", 0.95, soundDecay_);
00069   setctrlState("mrs_real/soundDecay", true);
00070   addctrl("mrs_real/baseGain", 20.0, baseGain_);
00071   setctrlState("mrs_real/baseGain", true);
00072 }
00073 
00074 void PhiSEMSource::myUpdate(MarControlPtr sender) {
00075   setctrl("mrs_natural/numObjects",     getctrl("mrs_natural/numObjects"));
00076   setctrl("mrs_real/systemDecay",       getctrl("mrs_real/systemDecay"));
00077   setctrl("mrs_real/soundDecay",        getctrl("mrs_real/soundDecay"));
00078   setctrl("mrs_real/baseGain",      getctrl("mrs_real/baseGain"));
00079   MarSystem::myUpdate(sender);
00080 
00081   mrs_natural num = numObjects_->to<mrs_natural>();
00082   //gain_ = log(num) * baseGain_->to<mrs_real>() / (mrs_natural)num;
00083   gain_ = log(num+.0) / log(4.0) * 40.0 / (mrs_natural)num;
00084 }
00085 
00086 void PhiSEMSource::myProcess(realvec& /* in */, realvec& out) {
00087   mrs_natural t,o;
00088   for (o=0; o < inObservations_; o++ ) {
00089     for ( t=0; t < inSamples_; t++ ) {
00090       out(o,t) = computeSample();
00091     }
00092   }
00093 }
00094 
00095 mrs_real PhiSEMSource::computeSample() {
00096   mrs_real out = 0.0;
00097   mrs_natural numObjects    = numObjects_->to<mrs_natural>();
00098   mrs_natural samplePeriod = (mrs_natural) israte_ ;
00099   mrs_real systemDecay  = systemDecay_->to<mrs_real>();
00100   mrs_real soundDecay   = soundDecay_->to<mrs_real>();
00101 
00102   if ( temp_ < TWOPI ) {
00103     temp_ += (TWOPI / israte_ / 0.05);
00104     shakeEnergy_ += (1.0 - cos(temp_));
00105   }
00106   if ( (++sample_)%(samplePeriod / 4) == 0 ) {
00107     temp_ = 0;
00108     sample_ = 0;
00109   }
00110 
00111   //exponential system decay
00112   shakeEnergy_ *= systemDecay;
00113 
00114   if ( randomFloat(1024.0) < numObjects ) {
00115     soundLevel_ += gain_ * shakeEnergy_;
00116   }
00117   //output sound is just noise
00118   out = soundLevel_ * noiseTick();
00119 
00120   //expontential sound decay
00121   soundLevel_ *= soundDecay;
00122 
00123   return out;
00124 }
00125 /*
00126     if ( shakeEnergy_ > MIN_ENERGY ) {
00127         if ( temp < TWO_PI ) {
00128             temp += (TWO_PI / israte_ / 0.05);
00129             shakeEnergy += (1.0 - cos(temp));
00130         }
00131         if ( i%5050 == 0 ) {
00132             temp = 0;
00133         }
00134 
00135         //exponential system decay
00136         shakeEnergy *= systemDecay;
00137 
00138         if ( randomFloat(1024.0) < numObjects ) {
00139             soundLevel_ += gain_ * shakeEnergy;
00140         }
00141         //output sound is just noise
00142         out = soundLevel_ * noiseTick();
00143 
00144         //expontential sound decay
00145         soundLevel_ *= soundDecay;
00146     }
00147     return out;
00148 }
00149 */
00150 
00151 mrs_real
00152 PhiSEMSource::noiseTick() {
00153   mrs_real temp = (mrs_real)(2.0 * rand() / (RAND_MAX + 1.0));
00154   temp -= 1.0;
00155   return temp;
00156 }
00157 
00158 int
00159 PhiSEMSource::randomInt(int max) {
00160   int temp = (int)((float)max * (float)rand() / (RAND_MAX + 1.0));
00161   return temp;
00162 }
00163 
00164 mrs_real
00165 PhiSEMSource::randomFloat(mrs_real max) {
00166   mrs_real temp = (mrs_real)(max * rand() / (RAND_MAX + 1.0));
00167   return temp;
00168 }