00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "PeakSynthOscBank.h"
00020 #include "peakView.h"
00021
00022
00023 using std::ostringstream;
00024 using std::cout;
00025 using std::endl;
00026
00027 using namespace Marsyas;
00028
00029 PeakSynthOscBank::PeakSynthOscBank(mrs_string name):MarSystem("PeakSynthOscBank",name)
00030 {
00031 psize_ = 0;
00032 size_ = 0;
00033
00034 addControls();
00035 }
00036
00037 PeakSynthOscBank::PeakSynthOscBank(const PeakSynthOscBank& a):MarSystem(a)
00038 {
00039 ctrl_harmonize_ = getctrl("mrs_realvec/harmonize");
00040 }
00041
00042 PeakSynthOscBank::~PeakSynthOscBank()
00043 {
00044 }
00045
00046 MarSystem*
00047 PeakSynthOscBank::clone() const
00048 {
00049 return new PeakSynthOscBank(*this);
00050 }
00051
00052 void
00053 PeakSynthOscBank::addControls()
00054 {
00055 addctrl("mrs_natural/Interpolation", MRS_DEFAULT_SLICE_NSAMPLES/4);
00056 setctrlState("mrs_natural/Interpolation", true);
00057 addctrl("mrs_real/PitchShift", 1.0);
00058 setctrlState("mrs_real/PitchShift", true);
00059 addctrl("mrs_real/SynthesisThreshold", 0.0);
00060 setctrlState("mrs_real/SynthesisThreshold", true);
00061 addctrl("mrs_realvec/harmonize", realvec(), ctrl_harmonize_);
00062 setctrlState("mrs_realvec/harmonize", true);
00063 }
00064
00065 void
00066 PeakSynthOscBank::myUpdate(MarControlPtr sender)
00067 {
00068 (void) sender;
00069 setctrl("mrs_natural/onSamples", getctrl("mrs_natural/Interpolation"));
00070 setctrl("mrs_natural/onObservations", (mrs_natural)1);
00071 setctrl("mrs_real/osrate", getctrl("mrs_real/israte"));
00072
00073 inObservations_ = getctrl("mrs_natural/inObservations")->to<mrs_natural>();
00074
00075 nbH_ = (ctrl_harmonize_->to<mrs_realvec>().getSize()-1)/2;
00076
00077 if (!nbH_)
00078 {
00079 MarControlAccessor acc(ctrl_harmonize_, NOUPDATE);
00080 realvec& harmonize = acc.to<mrs_realvec>();
00081 harmonize.stretch(3);
00082 harmonize(1) = 1.0;
00083 harmonize(2) = 1.0;
00084 }
00085
00086 size_ = 2048*nbH_;
00087
00088
00089 {
00090 lastamp_.stretch(size_);
00091 nextamp_.stretch(size_);
00092 lastfreq_.stretch(size_);
00093 nextfreq_.stretch(size_);
00094 index_.stretch(size_);
00095 nextindex_.stretch(size_);
00096 N_ = inObservations_/peakView::nbPkParameters;
00097
00098 L_ = 8192;
00099 table_.stretch(L_);
00100
00101 for (mrs_natural t=0; t < L_; t++)
00102 {
00103 table_(t) = cos(TWOPI * t/L_);
00104 }
00105 psize_ = size_;
00106 }
00107
00108 P_ = getctrl("mrs_real/PitchShift")->to<mrs_real>();
00109 I_ = getctrl("mrs_natural/Interpolation")->to<mrs_natural>();
00110 S_ = getctrl("mrs_real/SynthesisThreshold")->to<mrs_real>();
00111 R_ = getctrl("mrs_real/osrate")->to<mrs_real>();
00112 }
00113
00114 void
00115 PeakSynthOscBank::myProcess(realvec& in, realvec& out)
00116 {
00117 mrs_natural t,c;
00118 out.setval(0.0);
00119
00120 if (P_ > 1.0)
00121 NP_ = (mrs_natural)(N_/P_);
00122 else
00123 NP_ = N_;
00124
00125 Iinv_ = (mrs_real)(1.0 / I_);
00126 Pinc_ = P_ * L_ / R_;
00127
00128 nextamp_.setval(0);
00129 nextfreq_.setval(0);
00130 nextindex_.setval(0);
00131
00132
00133
00134
00135 if(nbH_)
00136 {
00137 for(mrs_natural j=0 ; j<nbH_ ; j++)
00138 {
00139 mrs_real mulF = ctrl_harmonize_->to<mrs_realvec>()(1+j*2);
00140 mrs_real mulA = ctrl_harmonize_->to<mrs_realvec>()(2+j*2);
00141
00142 for (t=0; t < NP_; t++)
00143 {
00144 mrs_natural index = (mrs_natural) ceil(in(t)/R_*2048*2+0.5);
00145 if (in(t) == 0.0 || index >= 2048)
00146 break;
00147 index+=j*2048;
00148
00149
00150
00151 if(nextfreq_(index))
00152 {
00153 cout << "PROBLEM"<<endl;
00154 }
00155 nextamp_(index) = in(t+NP_)*mulA;
00156 nextfreq_(index) = in(t)*Pinc_*mulF;
00157 }
00158 }
00159 }
00160
00161 for (mrs_natural t=0; t < nextamp_.getSize(); t++)
00162 {
00163
00164 if(lastfreq_(t) && nextfreq_(t))
00165 {
00166 f_ = lastfreq_(t);
00167 finc_ = (nextfreq_(t) - f_)*Iinv_;
00168 }
00169 else if(nextfreq_(t))
00170 {
00171 f_ = nextfreq_(t);
00172 finc_=0;
00173 }
00174 else
00175 {
00176 f_ = lastfreq_(t);
00177 finc_=0;
00178 }
00179
00180 a_ = lastamp_(t);
00181 ainc_ = (nextamp_(t) - a_)*Iinv_;
00182
00183 address_ = index_(t);
00184
00185
00186 if ((a_ != 0.0 || ainc_!=0.0))
00187 {
00188
00189
00190 for (c=0; c < I_; ++c)
00191 {
00192 naddress_ = (mrs_natural)address_ % L_;
00193 out(0, c) += a_ * table_(naddress_);
00194 address_ += f_;
00195
00196 while (address_ >= L_)
00197 address_ -= L_;
00198 while (address_ < 0)
00199 address_ += L_;
00200
00201 a_ += ainc_;
00202 f_ += finc_;
00203 }
00204
00205 }
00206 nextindex_(t) = address_;
00207 }
00208
00209 lastamp_ = nextamp_;
00210 lastfreq_ = nextfreq_;
00211 index_ = nextindex_;
00212 }