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