Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2007 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 00020 #include "Vibrato.h" 00021 #include "../common_source.h" 00022 00023 using namespace std; 00024 using namespace Marsyas; 00025 00026 Vibrato::Vibrato(mrs_string name):MarSystem("Vibrato",name) 00027 { 00028 addControls(); 00029 } 00030 00031 Vibrato::~Vibrato() 00032 { 00033 } 00034 00035 MarSystem* 00036 Vibrato::clone() const 00037 { 00038 return new Vibrato(*this); 00039 } 00040 00041 void 00042 Vibrato::addControls() 00043 { 00044 addctrl("mrs_real/mod_freq", 5.0); // 5 Hz 00045 addctrl("mrs_real/width", 0.005); // 5 ms 00046 setctrlState("mrs_real/mod_freq", true); 00047 setctrlState("mrs_real/width", true); 00048 } 00049 00050 void 00051 Vibrato::myUpdate(MarControlPtr sender) 00052 { 00053 MRSDIAG("Vibrato.cpp - Vibrato:localuUpdate"); 00054 00055 MarSystem::myUpdate(sender); 00056 00057 mrs_real mod_freq; 00058 mod_freq = getctrl("mrs_real/mod_freq")->to<mrs_real>(); 00059 width_ = getctrl("mrs_real/width")->to<mrs_real>(); 00060 00061 delay_ = floor(width_ * israte_); 00062 width_ = floor(width_ * israte_); 00063 mod_freq = mod_freq / israte_; // mod_freq in samples 00064 00065 mrs_natural L = mrs_natural(2 + delay_ + width_ * 2); 00066 // cout << "L = " << L << endl; 00067 00068 if (delaylineSize_ == 0) 00069 { 00070 delaylineSize_ = L; 00071 delayline_.create((mrs_natural)delaylineSize_); 00072 wp_ = 0; // write pointer for delay line 00073 rp_ = 0; // read pointer for fractional delay 00074 rpp_ = 0; // read pointer for fractional delay 00075 } 00076 00077 tmod_ = 0; 00078 00079 } 00080 00081 00082 void 00083 Vibrato::myProcess(realvec &in, realvec &out) 00084 { 00085 for (mrs_natural t = 0; t < inSamples_; t++) 00086 { 00087 mrs_real M = getctrl("mrs_real/mod_freq")->to<mrs_real>(); 00088 M = M / israte_; 00089 mrs_real MOD = sin(M* 2 * PI * tmod_); 00090 tmod_ ++ ; 00091 00092 mrs_real Z = 1 + delay_ + width_ * MOD; 00093 mrs_natural i = (mrs_natural)floor(Z); 00094 mrs_real frac = Z - i; 00095 00096 // put samples in delay line 00097 delayline_(wp_) = in(0,t); 00098 00099 // advance read/write pointers in circular buffer 00100 wp_ = (wp_+1) % delaylineSize_; 00101 rp_ = (wp_ + i + 1) % delaylineSize_; 00102 rpp_ = (wp_ + i) % delaylineSize_; 00103 00104 // write to output 00105 out(0,t) = delayline_(rp_)* frac + delayline_(rpp_) * (1 -frac); 00106 00107 } 00108 00109 } 00110 00111 00112 00113 00114 00115 00116 00117