Marsyas  0.5.0-beta1
/Users/jleben/code/marsyas/src/marsyas/marsystems/DPWOsc.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 "DPWOsc.h"
00021 #include "math.h"
00022 
00023 using std::ostringstream;
00024 using namespace Marsyas;
00025 
00026 DPWOsc::DPWOsc(mrs_string name) : MarSystem("DPWOsc", name)
00027 {
00028   currentValue_ = 0;
00029   incr_  = 0;
00030   cyclicRate_ = 0;
00031   israte_ = 0;
00032   frequency_ = 0;
00033   type_ = 0;
00034 
00035   addControls();
00036 }
00037 
00038 DPWOsc::DPWOsc(const DPWOsc& a) : MarSystem(a)
00039 {
00040   // IMPORTANT!
00041   // All member MarControlPtr have to be explicitly reassigned in
00042   // the copy constructor.
00043   // Otherwise this would result in trying to deallocate them twice!
00044 }
00045 
00046 
00047 DPWOsc::~DPWOsc()
00048 {
00049 }
00050 
00051 MarSystem* DPWOsc::clone() const
00052 {
00053   // Every MarSystem should do this.
00054   return new DPWOsc(*this);
00055 }
00056 
00057 void DPWOsc::addControls()
00058 {
00059   addctrl("mrs_real/frequency", 440.0);
00060   addctrl("mrs_natural/type", 0);
00061   addctrl("mrs_real/cyclicrate", 0.0);
00062   addctrl("mrs_bool/cyclicin", false);
00063 
00064   setctrlState("mrs_real/frequency", true);
00065   setctrlState("mrs_natural/type", true);
00066   setctrlState("mrs_real/cyclicrate", true);
00067 }
00068 
00069 void DPWOsc::myUpdate(MarControlPtr sender)
00070 {
00071   MRSDIAG("DPWOsc.cpp - DPWOsc:myUpdate");
00072 
00073   // Start the default MarSystem setup with equal input/output stream format.
00074   MarSystem::myUpdate(sender);
00075 
00076   // This sets the ouput channels to 1, as this is a mono oscillator
00077   ctrl_onObservations_->setValue(1, NOUPDATE);
00078 
00079   // Because our range is from -1 to 1, and frequency / israte is
00080   // for the range 0 to 1. We need to double the frequency to
00081   // accomedate the larger range.
00082   frequency_ = 2 * (getctrl("mrs_real/frequency")->to<mrs_real>());
00083   israte_ = (getctrl("mrs_real/israte")->to<mrs_real>());
00084   cyclicIn_ = (getctrl("mrs_bool/cyclicin")->to<mrs_bool>());
00085   c_ = israte_/(4 * frequency_ * (1 - (frequency_/israte_)));
00086 
00087   incr_ = (frequency_ ) / israte_;
00088   type_ =  (getctrl("mrs_natural/type")->to<mrs_natural>());
00089   cyclicRate_ = (getctrl("mrs_real/cyclicrate")->to<mrs_real>());
00090 }
00091 
00092 void DPWOsc::myProcess(realvec& in, realvec& out)
00093 {
00094   for (mrs_natural t = 0; t < inSamples_; t++)
00095   {
00096     incr_ = (frequency_ * (in(0,t) + 1) ) / israte_;
00097 
00098     currentValue_ += incr_;
00099     if (currentValue_ >= 1)
00100     {
00101       currentValue_ -= 2;
00102     }
00103 
00104     out(0,t) = c_ * df(currentValue_ * currentValue_);
00105   }
00106 }