Marsyas
0.6.0-alpha
|
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 }