Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2006 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 "PvOscBank.h" 00020 00021 using std::ostringstream; 00022 using namespace Marsyas; 00023 00024 PvOscBank::PvOscBank(mrs_string name):MarSystem("PvOscBank",name) 00025 { 00026 //type_ = "PvOscBank"; 00027 //name_ = name; 00028 00029 psize_ = 0; 00030 size_ = 0; 00031 PS_ = 0; 00032 00033 addControls(); 00034 } 00035 00036 00037 PvOscBank::PvOscBank(const PvOscBank& a):MarSystem(a) 00038 { 00039 ctrl_analysisphases_ = getctrl("mrs_realvec/analysisphases"); 00040 ctrl_frequencies_ = getctrl("mrs_realvec/frequencies"); 00041 ctrl_regions_ = getctrl("mrs_realvec/regions"); 00042 ctrl_peaks_ = getctrl("mrs_realvec/peaks"); 00043 00044 ctrl_phaselock_ = getctrl("mrs_bool/phaselock"); 00045 ctrl_onsetsAudible_ = getctrl("mrs_bool/onsetsAudible"); 00046 ctrl_rmsIn_ = getctrl("mrs_real/rmsIn"); 00047 00048 psize_ = 0; 00049 PS_ = 0; 00050 } 00051 00052 00053 PvOscBank::~PvOscBank() 00054 { 00055 } 00056 00057 MarSystem* 00058 PvOscBank::clone() const 00059 { 00060 return new PvOscBank(*this); 00061 } 00062 00063 void 00064 PvOscBank::addControls() 00065 { 00066 addctrl("mrs_natural/Interpolation", MRS_DEFAULT_SLICE_NSAMPLES/4); 00067 setctrlState("mrs_natural/Interpolation", true); 00068 addctrl("mrs_real/PitchShift", 1.0); 00069 setctrlState("mrs_real/PitchShift", true); 00070 addctrl("mrs_real/SynthesisThreshold", 0.0); 00071 setctrlState("mrs_real/SynthesisThreshold", true); 00072 addctrl("mrs_natural/winSize", MRS_DEFAULT_SLICE_NSAMPLES); 00073 setctrlState("mrs_natural/winSize", true); 00074 00075 00076 addctrl("mrs_realvec/analysisphases", realvec(), ctrl_analysisphases_); 00077 addctrl("mrs_realvec/frequencies", realvec(), ctrl_frequencies_); 00078 addctrl("mrs_realvec/regions", realvec(), ctrl_regions_); 00079 addctrl("mrs_realvec/peaks", realvec(), ctrl_peaks_); 00080 addctrl("mrs_bool/phaselock", false, ctrl_phaselock_); 00081 addctrl("mrs_bool/onsetsAudible", true, ctrl_onsetsAudible_); 00082 addctrl("mrs_real/rmsIn", 0.0, ctrl_rmsIn_); 00083 } 00084 00085 void 00086 PvOscBank::myUpdate(MarControlPtr sender) 00087 { 00088 mrs_natural t; 00089 (void) sender; //suppress warning of unused parameter(s) 00090 setctrl("mrs_natural/onSamples", getctrl("mrs_natural/winSize")); 00091 setctrl("mrs_natural/onObservations", (mrs_natural)1); 00092 setctrl("mrs_real/osrate", getctrl("mrs_real/israte")); 00093 00094 inObservations_ = getctrl("mrs_natural/inObservations")->to<mrs_natural>(); 00095 inSamples_ = getctrl("mrs_natural/inSamples")->to<mrs_natural>(); 00096 00097 size_ = inObservations_/2; 00098 temp_.create(getctrl("mrs_natural/winSize")->to<mrs_natural>()); 00099 00100 00101 00102 if (size_ != psize_) 00103 { 00104 { 00105 MarControlAccessor acc(ctrl_analysisphases_); 00106 mrs_realvec& analysisphases = acc.to<mrs_realvec>(); 00107 analysisphases.create(size_); 00108 } 00109 00110 { 00111 MarControlAccessor acc(ctrl_frequencies_); 00112 mrs_realvec& frequencies = acc.to<mrs_realvec>(); 00113 frequencies.create(size_); 00114 } 00115 00116 { 00117 MarControlAccessor acc(ctrl_regions_); 00118 mrs_realvec& regions = acc.to<mrs_realvec>(); 00119 regions.create(size_); 00120 } 00121 00122 { 00123 MarControlAccessor acc(ctrl_peaks_); 00124 mrs_realvec& peaks = acc.to<mrs_realvec>(); 00125 peaks.create(size_); 00126 } 00127 00128 00129 00130 00131 lastamp_.stretch(size_); 00132 magnitudes_.stretch(size_); 00133 00134 00135 00136 lastfreq_.stretch(size_); 00137 index_.stretch(size_); 00138 N_ = size_; 00139 L_ = 8192; 00140 table_.stretch(L_+2); // leave some head-room for numerical errors 00141 00142 for (t=0; t < L_; t++) 00143 { 00144 table_(t) = N_ * cos(TWOPI * t/L_); 00145 } 00146 } 00147 00148 psize_ = size_; 00149 00150 00151 P_ = getctrl("mrs_real/PitchShift")->to<mrs_real>(); 00152 I_ = getctrl("mrs_natural/Interpolation")->to<mrs_natural>(); 00153 S_ = getctrl("mrs_real/SynthesisThreshold")->to<mrs_real>(); 00154 R_ = getctrl("mrs_real/osrate")->to<mrs_real>(); 00155 } 00156 00157 00158 00159 int 00160 PvOscBank::subband(int bin) 00161 { 00162 int si = 0; 00163 00164 if (bin < 16) 00165 si = 0; 00166 else if ((bin >= 16) && (bin < 32)) 00167 si = 1; 00168 else if (bin < 512) 00169 si = (int)(log(bin*1.0) / log(2.0))-3; 00170 else if (bin > 512) 00171 si = 6; 00172 return si; 00173 } 00174 00175 00176 bool 00177 PvOscBank::isPeak(int bin, mrs_realvec& magnitudes, mrs_real maxAmp) 00178 { 00179 bool res = true; 00180 00181 int h = subband(bin); 00182 h = 2; 00183 if ((bin > 2) && (bin <= size_-2)) 00184 for (int i = bin-h; i < bin+h; ++i) 00185 { 00186 if (magnitudes(bin) < magnitudes(i)) 00187 res = false; 00188 } 00189 if (magnitudes(bin) < 0.005 * maxAmp) 00190 res = false; 00191 if (bin == 0) 00192 res = true; 00193 return res; 00194 } 00195 00196 00197 void 00198 PvOscBank::myProcess(realvec& in, realvec& out) 00199 { 00200 00201 00202 mrs_natural c,t; 00203 MarControlAccessor acc(ctrl_frequencies_); 00204 mrs_realvec& frequencies = acc.to<mrs_realvec>(); 00205 00206 MarControlAccessor acc1(ctrl_analysisphases_); 00207 mrs_realvec& analysisphases = acc1.to<mrs_realvec>(); 00208 00209 00210 MarControlAccessor acc2(ctrl_regions_); 00211 mrs_realvec& regions = acc2.to<mrs_realvec>(); 00212 00213 00214 MarControlAccessor acc3(ctrl_peaks_); 00215 mrs_realvec& peaks = acc3.to<mrs_realvec>(); 00216 00217 if (PS_ > 1.0) 00218 NP_ = (mrs_natural)(N_/PS_); 00219 else 00220 NP_ = N_; 00221 00222 00223 00224 peaks.setval(0.0); 00225 00226 00227 for (t=0; t < NP_; t++) 00228 { 00229 frequencies(t) = in(2*t+1,0); 00230 } 00231 PS_ = P_; 00232 Iinv_ = (mrs_real)(1.0 / I_); 00233 Pinc_ = PS_ * L_ / TWOPI; 00234 Nw_ = getctrl("mrs_natural/winSize")->to<mrs_natural>(); 00235 mrs_real maxAmp =0.0; 00236 00237 for (t=0; t < NP_; t++) 00238 { 00239 magnitudes_(t) = in(2*t,0); 00240 if (magnitudes_(t) > maxAmp) 00241 maxAmp = magnitudes_(t); 00242 if (t==0) 00243 magnitudes_(t) = 0.0; 00244 if (t==size_) 00245 magnitudes_(t) = 0.0; 00246 00247 00248 while (analysisphases(t) > PI) 00249 analysisphases(t) -= TWOPI; 00250 while (analysisphases(t) < -PI) 00251 analysisphases(t) += TWOPI; 00252 00253 } 00254 00255 for (int i=0; i < size_; ++i) 00256 { 00257 regions(i) = i; 00258 } 00259 00260 00261 00262 // calculate regions of influence 00263 int previous_peak=0; 00264 int peak = 0; 00265 for (t=0; t < NP_; t++) 00266 { 00267 if (isPeak(t, magnitudes_, maxAmp)) 00268 { 00269 00270 // calculate significant peaks and corresponding 00271 // non-overlapping intervals 00272 peak = t; 00273 00274 if (peak-previous_peak == 1) 00275 regions(peak) = peak; 00276 else 00277 { 00278 for (int j=previous_peak; j< previous_peak + (int)((peak-previous_peak)/2.0); j++) 00279 { 00280 regions(j) = previous_peak; 00281 } 00282 00283 for (int j= previous_peak + (int)((peak-previous_peak)/2.0); j < peak; j++) 00284 { 00285 regions(j) = peak; 00286 } 00287 } 00288 previous_peak = peak; 00289 } 00290 00291 } 00292 00293 00294 00295 mrs_real factor = 1; 00296 for (t=0; t < NP_; t++) 00297 { 00298 00299 while (analysisphases(t) > PI) 00300 analysisphases(t) -= TWOPI; 00301 while (analysisphases(t) < -PI) 00302 analysisphases(t) += TWOPI; 00303 00304 // if (ctrl_phaselock_->to<bool>() == true) 00305 // { 00306 // if (t == 0) 00307 // cout << "PHASELOCKED" << endl; 00308 00309 // index_(t) = analysisphases(t); 00310 // factor = 2.25; 00311 // factor = 1.5; 00312 // } 00313 } 00314 00315 factor = 1.5; 00316 00317 for (t=0; t < NP_; t++) 00318 { 00319 frequencies(t) *= Pinc_; 00320 00321 f_ = lastfreq_(t); 00322 finc_ = (frequencies(t) - f_) * Iinv_; 00323 00324 //if ((magnitudes_(t) < 1.0e-06)||(magnitudes_(t) < 0.01 * maxAmp)) 00325 if (magnitudes_(t) < 1.0e-07) 00326 { 00327 magnitudes_(t) = 0.0; 00328 a_ = lastamp_(t); 00329 ainc_ = (magnitudes_(t) - a_)*Iinv_; 00330 } 00331 else 00332 { 00333 a_ = lastamp_(t); 00334 ainc_ = (magnitudes_(t) - a_)*Iinv_; 00335 } 00336 00337 if (t == regions(t)) 00338 { 00339 address_ = index_((mrs_natural)regions(t)); 00340 } 00341 else 00342 { 00343 address_ = index_(t); 00344 } 00345 00346 00347 while (address_ >= L_) 00348 address_ -= L_; 00349 while (address_ < 0) 00350 address_ += L_; 00351 00352 00353 00354 if (ainc_ != 0.0 || a_ != 0.0) 00355 { 00356 peaks(t) = magnitudes_(t); 00357 00358 // accumulate I samples from each oscillator 00359 // into output slice 00360 for (c=0; c < I_; ++c) 00361 { 00362 naddress_ = (mrs_natural)address_; 00363 temp_(c) += a_ * factor * table_(naddress_); 00364 address_ += f_; 00365 00366 while (address_ >= L_) 00367 address_ -= L_; 00368 while (address_ < 0) 00369 address_ += L_; 00370 00371 a_ += ainc_; 00372 f_ += finc_; 00373 } 00374 00375 } 00376 00377 index_(t) = address_; 00378 lastamp_(t) = magnitudes_(t); 00379 lastfreq_(t) = frequencies(t); 00380 00381 } 00382 00383 ctrl_phaselock_->setValue(false); 00384 00385 00386 00387 for (t=0; t < Nw_; t++) 00388 out(0,t) = temp_(t); 00389 for (t=0; t < Nw_-I_; t++) 00390 temp_(t) = temp_(t+I_); 00391 for (t=Nw_-I_; t<Nw_; t++) 00392 temp_(t) = 0.0; 00393 00394 00395 00396 00397 }