Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2011 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 "AdditiveOsc.h" 00020 #include "math.h" 00021 00022 using namespace Marsyas; 00023 00024 AdditiveOsc::AdditiveOsc(mrs_string name):MarSystem("AdditiveOsc", name) 00025 { 00026 harmonics_ = 0; // How many harmonics our signal will have 00027 00028 israte_ = 0; // Sampling rate of the system 00029 00030 00031 addControls(); 00032 } 00033 00034 AdditiveOsc::AdditiveOsc(const AdditiveOsc& a) : MarSystem(a) 00035 { 00036 // For any MarControlPtr in a MarSystem 00037 // it is necessary to perform this getctrl 00038 // in the copy constructor in order for cloning to work 00039 } 00040 00041 AdditiveOsc::~AdditiveOsc() 00042 { 00043 } 00044 00045 MarSystem* AdditiveOsc::clone() const 00046 { 00047 return new AdditiveOsc(*this); 00048 } 00049 00050 void AdditiveOsc::addControls() 00051 { 00052 addctrl("mrs_real/frequency", 440.0); 00053 addctrl("mrs_bool/noteon", false); 00054 00055 setctrlState("mrs_real/frequency", true); 00056 setctrlState("mrs_bool/noteon", true); 00057 } 00058 00059 00060 void AdditiveOsc::myUpdate(MarControlPtr sender) 00061 { 00062 mrs_real frequency = (getctrl("mrs_real/frequency")->to<mrs_real>()); 00063 israte_ = (getctrl("mrs_real/israte")->to<mrs_real>()); 00064 00065 00066 // How many harmonics do we have before crossing the Nyquist threshold? 00067 for (harmonics_ = 1; harmonics_ * frequency * 2 <= israte_/2; harmonics_++) {}; 00068 00069 // Initialize our lists of coefficients and past values 00070 x1n1_.create((mrs_natural)harmonics_ + 1); 00071 x2n1_.create((mrs_natural)harmonics_ + 1); 00072 k_.create((mrs_natural)harmonics_ + 1); 00073 00074 // Initialize our lists 00075 for (mrs_natural t = 1; t <= harmonics_; t++) 00076 { 00077 // The initial impulse of each wave guide 00078 x1n1_(t) = 0.95 * pow((mrs_real)(-1.0),t + 1); 00079 // Our last waveguide value is zero 00080 x2n1_(t) = 0; 00081 // The coefficient for the waveguide at a given harmonic 00082 k_(t) = cos((TWOPI * frequency * t)/israte_); 00083 } 00084 00085 MarSystem::myUpdate(sender); 00086 } 00087 00088 void AdditiveOsc::myProcess(realvec& in, realvec& out) 00089 { 00090 (void) in; 00091 mrs_real y, x1, x2; 00092 00093 for (mrs_natural t = 0; t < inSamples_; t++) 00094 { 00095 y = 0; 00096 for (mrs_natural har = 1; har <= harmonics_; har++) 00097 { 00098 x1 = (2 * k_(har) * x1n1_(har)) - x2n1_(har); 00099 x2 = x1n1_(har); 00100 00101 x1n1_(har) = x1; 00102 x2n1_(har) = x2; 00103 00104 y += (x1 - x2); 00105 out(t) = (y * 0.9)/har; 00106 } 00107 } 00108 }