00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00029 #include "common.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
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
00083 gain_ = log(num+.0) / log(4.0) * 40.0 / (mrs_natural)num;
00084 }
00085
00086 void PhiSEMSource::myProcess(realvec& , 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
00112 shakeEnergy_ *= systemDecay;
00113
00114 if ( randomFloat(1024.0) < numObjects ) {
00115 soundLevel_ += gain_ * shakeEnergy_;
00116 }
00117
00118 out = soundLevel_ * noiseTick();
00119
00120
00121 soundLevel_ *= soundDecay;
00122
00123 return out;
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
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 * 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 }