00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "FM.h"
00020
00021 using std::ostringstream;
00022 using namespace Marsyas;
00023
00024 #define WAVETABLE_SIZE 8192
00025
00026
00027 FM::FM(mrs_string name)
00028 : MarSystem("FM",name),
00029 wavetable_(WAVETABLE_SIZE),
00030 wavetableSize_(WAVETABLE_SIZE)
00031 {
00032 mrs_real incr = TWOPI / wavetableSize_;
00033
00034 for (mrs_natural t=0; t < wavetableSize_; ++t) {
00035 wavetable_(t) = (mrs_real)(0.5 * sin(incr * t));
00036 }
00037
00038 mIndex_ = 0;
00039 oIndex_ = 0;
00040 addControls();
00041 }
00042
00043
00044 FM :: ~FM() {}
00045
00046
00047 MarSystem* FM::clone() const
00048 {
00049 return new FM(*this);
00050 }
00051
00052
00053 void
00054 FM::addControls()
00055 {
00056 addctrl("mrs_natural/nChannels",1);
00057
00058 addctrl("mrs_real/mDepth", 15.0);
00059 setctrlState("mrs_real/mDepth",true);
00060
00061 addctrl("mrs_real/mSpeed", 6.0);
00062 setctrlState("mrs_real/mSpeed", true);
00063
00064 addctrl("mrs_real/cFrequency", 1000.0);
00065 setctrlState("mrs_real/cFrequency", true);
00066
00067 addctrl("mrs_bool/noteon", false);
00068 setctrlState("mrs_bool/noteon", true);
00069 }
00070
00071
00072 void FM::myUpdate(MarControlPtr sender)
00073 {
00074 (void) sender;
00075 MRSDIAG("FM.cpp - FM:myUpdate");
00076
00077 setctrl("mrs_natural/onSamples", getctrl("mrs_natural/inSamples"));
00078 setctrl("mrs_natural/onObservations", getctrl("mrs_natural/inObservations"));
00079 setctrl("mrs_real/osrate", getctrl("mrs_real/israte"));
00080
00081
00082 cFrequency_ = getctrl("mrs_real/cFrequency")->to<mrs_real>();
00083 isRate_ = getctrl("mrs_real/israte")->to<mrs_real>();
00084 mSpeed_ = getctrl("mrs_real/mSpeed")->to<mrs_real>();
00085 mDepth_ = getctrl("mrs_real/mDepth")->to<mrs_real>();
00086 mRate_ = (mSpeed_ * wavetableSize_) / getctrl("mrs_real/israte")->to<mrs_real>();
00087 inSamples_ = getctrl("mrs_natural/inSamples")->to<mrs_natural>();
00088 }
00089
00090 void FM::myProcess( realvec& in, realvec& out )
00091 {
00092 (void) in;
00093 mrs_natural t;
00094
00095
00096
00097 register mrs_real mSample_;
00098 register mrs_real oFrequency_;
00099
00100 if (getctrl("mrs_bool/noteon")->to<mrs_bool>() == false) {
00101 return;
00102 }
00103
00104 for (t=0; t < inSamples_; t++)
00105 {
00106
00107
00108 mSample_ = wavetable_((mrs_natural)mIndex_);
00109 mIndex_ += mRate_;
00110 mSample_ *= mDepth_;
00111
00112
00113 oFrequency_ = cFrequency_ + mSample_;
00114 oRate_ = (oFrequency_ * wavetableSize_) / isRate_;
00115
00116 out(0,t) = wavetable_((mrs_natural)oIndex_);
00117
00118
00119 oIndex_ += oRate_;
00120
00121 while (mIndex_ >= wavetableSize_)
00122 mIndex_ -= wavetableSize_;
00123
00124 while (oIndex_ >= wavetableSize_)
00125 oIndex_ -= wavetableSize_;
00126 }
00127
00128 }