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;
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 }