Marsyas  0.5.0-beta1
/Users/jleben/code/marsyas/src/marsyas/marsystems/ConstQFiltering.cpp
Go to the documentation of this file.
00001 #include "ConstQFiltering.h"
00002 
00003 using std::ostringstream;
00004 using namespace Marsyas;
00005 
00006 ConstQFiltering::ConstQFiltering(mrs_string name):MarSystem("ConstQFiltering", name)
00007 {
00008   addControls();
00009 }
00010 
00011 ConstQFiltering::ConstQFiltering(const ConstQFiltering& a):MarSystem(a)
00012 {
00013   ctrl_qValue_ = getctrl("mrs_real/qValue");
00014   ctrl_lowFreq_ = getctrl("mrs_real/lowFreq");
00015   ctrl_highFreq_ = getctrl("mrs_real/highFreq");
00016   ctrl_width_ = getctrl("mrs_natural/width");
00017   ctrl_channels_ = getctrl("mrs_natural/channels");
00018   ctrl_time_ = getctrl("mrs_realvec/time");
00019   ctrl_freq_ = getctrl("mrs_realvec/freq");
00020 }
00021 
00022 ConstQFiltering::~ConstQFiltering()
00023 {
00024 }
00025 
00026 MarSystem*
00027 ConstQFiltering::clone() const
00028 {
00029   return new ConstQFiltering(*this);
00030 }
00031 
00032 void
00033 ConstQFiltering::addControls()
00034 {
00035   addControl("mrs_real/qValue", 60.0, ctrl_qValue_);
00036   addControl("mrs_real/lowFreq", 60.0, ctrl_lowFreq_);
00037   addControl("mrs_real/highFreq", 6000.0, ctrl_highFreq_);
00038   addControl("mrs_natural/width", 2048, ctrl_width_);
00039   addControl("mrs_natural/channels", 256, ctrl_channels_);
00040   addControl("mrs_realvec/time", time_, ctrl_time_);
00041   addControl("mrs_realvec/freq", freq_, ctrl_freq_);
00042 }
00043 
00044 void ConstQFiltering::myUpdate(MarControlPtr sender)
00045 {
00046   (void) sender;  //suppress warning of unused parameter(s)
00047 
00048   mrs_natural h, i;
00049   mrs_real f, bw;
00050   mrs_real lowFreq_, highFreq_;
00051   mrs_natural width_, channels_;
00052   mrs_real qValue_;
00053 
00054   lowFreq_ = ctrl_lowFreq_->to<mrs_real>();
00055   highFreq_ = ctrl_highFreq_->to<mrs_real>();
00056   width_ = ctrl_width_->to<mrs_natural>();
00057   channels_ = ctrl_channels_->to<mrs_natural>();
00058   qValue_ = ctrl_qValue_->to<mrs_real>();
00059 
00060   time_.create(width_);
00061   freq_.create(channels_);
00062 
00063   updControl("mrs_natural/onSamples", width_);
00064   updControl("mrs_natural/onObservations", channels_*2);
00065   updControl("mrs_real/osrate", israte_);
00066 
00067   fil_.create(channels_,width_);
00068   fshift_.create(channels_);
00069   for(h=0; h<channels_; h++) {
00070     freq_(h) = exp(log(lowFreq_)+(log(highFreq_)-log(lowFreq_))/(double)(channels_-1)*(double)h);
00071     bw = freq_(h)/(double)qValue_;
00072     fshift_(h) = (int)(freq_(h)/(israte_/(double)inSamples_));
00073     for(i=0; i<width_/2; ++i) {
00074       f = (double)(i+fshift_(h))/(double)inSamples_*israte_;
00075       fil_(h,i) = exp(-(f-freq_(h))*(f-freq_(h))/(2.0*bw*bw));
00076     }
00077     for(i=width_/2; i<width_; ++i) {
00078       f = (double)(i+fshift_(h)-width_)/(double)inSamples_*(double)israte_;
00079       fil_(h,i) = exp(-(f-freq_(h))*(f-freq_(h))/(2.0*bw*bw));
00080     }
00081   }
00082   for(i=0; i<width_; ++i) {
00083     time_(i) = (double)inSamples_/width_/israte_*i*1000.0;
00084   }
00085 
00086   spec1_.create(inSamples_,1);
00087   spec2_.create(width_*2,1);
00088 
00089   ctrl_time_->setValue(time_);
00090   ctrl_freq_->setValue(freq_);
00091 }
00092 
00093 void
00094 ConstQFiltering::myProcess(realvec& in, realvec& out)
00095 {
00096   mrs_natural h,i;
00097   mrs_real *tmp;
00098   //mrs_real lowFreq_, highFreq_;
00099   mrs_natural width_, channels_;
00100   //mrs_real qValue_;
00101 
00102   //lowFreq_ = ctrl_lowFreq_->to<mrs_real>();
00103   //highFreq_ = ctrl_highFreq_->to<mrs_real>();
00104   width_ = ctrl_width_->to<mrs_natural>();
00105   channels_ = ctrl_channels_->to<mrs_natural>();
00106   //qValue_ = ctrl_qValue_->to<mrs_real>();
00107 
00108   if(inSamples_>0) {
00109     for(i=0; i<inSamples_; ++i) {
00110       spec1_(i,0) = in(0,i);
00111     }
00112     tmp = spec1_.getData();
00113     fft1_.rfft(tmp, inSamples_/2, FFT_FORWARD);
00114     for(h=0; h<channels_; h++) {
00115       for(i=0; i<width_*2; ++i) {
00116         spec2_(i,0) = 0.0;
00117       }
00118       for(i=0; i<width_/2 && fshift_(h)+i<inSamples_/2; ++i) {
00119         spec2_(2*i,0) = fil_(h,i)*spec1_((mrs_natural)(2*(fshift_(h)+i)),0);
00120         spec2_(2*i+1,0) = fil_(h,i)*spec1_((mrs_natural)(2*(fshift_(h)+i)+1),0);
00121       }
00122       for(i=width_-1; i>=width_/2 && fshift_(h)+i-width_>=0; i--) {
00123         spec2_(2*i,0) = fil_(h,i)*spec1_((mrs_natural)(2*(fshift_(h)+i-width_)),0);
00124         spec2_(2*i+1,0) = fil_(h,i)*spec1_((mrs_natural)(2*(fshift_(h)+i-width_)+1),0);
00125       }
00126 
00127       tmp = spec2_.getData();
00128       fft2_.cfft(tmp, width_, FFT_INVERSE);
00129       for(i=0; i<width_; ++i) {
00130         out(2*h,i) = spec2_(2*i,0)*cos(fshift_(h)/width_*i) - spec2_(2*i+1,0)*sin(fshift_(h)/width_*i);
00131         out(2*h+1,i) = spec2_(2*i,0)*sin(fshift_(h)/width_*i) + spec2_(2*i+1,0)*cos(fshift_(h)/width_*i);
00132       }
00133     }
00134   }
00135 }