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