Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2011 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 "ADRess.h" 00020 #include <algorithm> 00021 00022 using std::ostringstream; 00023 using std::min; 00024 using std::max; 00025 00026 00027 using namespace Marsyas; 00028 00029 ADRess::ADRess(mrs_string name):MarSystem("ADRess", name) 00030 { 00031 addControls(); 00032 } 00033 00034 ADRess::ADRess(const ADRess& a) : MarSystem(a) 00035 { 00036 ctrl_beta_ = getctrl("mrs_natural/beta"); 00037 } 00038 00039 ADRess::~ADRess() 00040 { 00041 } 00042 00043 MarSystem* 00044 ADRess::clone() const 00045 { 00046 return new ADRess(*this); 00047 } 00048 00049 void 00050 ADRess::addControls() 00051 { 00052 addctrl("mrs_natural/beta", 100, ctrl_beta_); 00053 } 00054 00055 void 00056 ADRess::myUpdate(MarControlPtr sender) 00057 { 00058 (void) sender; //suppress warning of unused parameter(s) 00059 00060 N2_ = inObservations_ / 2; //i.e. we get two vertically stacked spectrums at the input 00061 N4_ = N2_/2 + 1; //i.e. for each spectrum, we have N/2+1 spectral bins 00062 00063 ctrl_onSamples_->setValue(1 + ctrl_beta_->to<mrs_natural>()+1, NOUPDATE);//one column for the phases, the others for the panning map [0:beta] 00064 ctrl_onObservations_->setValue(N4_*2, NOUPDATE); //output data for N/2+1 spectral bins, stacked vertically for each channel 00065 ctrl_osrate_->setValue(ctrl_israte_, NOUPDATE); 00066 00067 ostringstream oss; 00068 for(mrs_natural n=0; n< N4_; ++n) 00069 oss << "Left_bin_" << n <<","; 00070 for(mrs_natural n=0; n< N4_; ++n) 00071 oss << "Right_bin_" << n <<","; 00072 ctrl_onObsNames_->setValue(oss.str(), NOUPDATE); 00073 } 00074 00075 void 00076 ADRess::myProcess(realvec& in, realvec& out) 00077 { 00078 mrs_real a, b, g; 00079 mrs_natural beta = ctrl_beta_->to<mrs_natural>(); 00080 00081 for (mrs_natural k=0; k < N4_; k++) 00082 { 00083 minAZr_ = MAXREAL; 00084 minAZl_ = MAXREAL; 00085 maxAZr_ = MINREAL; 00086 maxAZl_ = MINREAL; 00087 00088 //get left channel spectrum bin 00089 if (k==0) //DC bin (i.e. 0) 00090 { 00091 rel_ = in(0,0); 00092 iml_ = 0.0; 00093 } 00094 else if (k == N4_-1) //Nyquist bin (i.e. N/2) 00095 { 00096 rel_ = in(1, 0); 00097 iml_ = 0.0; 00098 } 00099 else //all other bins 00100 { 00101 rel_ = in(2*k, 0); 00102 iml_ = in(2*k+1, 0); 00103 } 00104 00105 //get right channel spectrum bin 00106 if (k==0) //DC bin (i.e. 0) 00107 { 00108 rer_ = in(N2_,0); 00109 imr_ = 0.0; 00110 } 00111 else if (k == N4_-1) //Nyquist bin (i.e. N/2) 00112 { 00113 rer_ = in(N2_+1, 0); 00114 imr_ = 0.0; 00115 } 00116 else //all other bins 00117 { 00118 rer_ = in(N2_ + 2*k, 0); 00119 imr_ = in(N2_ + 2*k+1, 0); 00120 } 00121 00122 //store phases in first column of the output 00123 out(k,0) = 0;//atan2(iml_, rel_); //left channel phases 00124 out(k+N4_, 0) = 0;//atan2(imr_, rer_); //right channel phases 00125 00126 for(mrs_natural i=0; i <= beta; ++i) 00127 { 00128 g = i*1.0/beta; 00129 00130 //left freq-azimuth map (AZl) 00131 a = rer_ - g*rel_; 00132 b = imr_ - g*iml_; 00133 out(k,i+1) = sqrt(a*a + b*b); 00134 //get maximums and minimums 00135 if(out(k,i+1) > maxAZl_) 00136 maxAZl_ = out(k,i+1); 00137 if(out(k,i+1) < minAZl_) 00138 minAZl_ = out(k,i+1); 00139 00140 //right freq-azimuth map (AZr) 00141 a = rel_ - g*rer_; 00142 b = iml_ - g*imr_; 00143 out(k+N4_,i+1) = sqrt(a*a + b*b); 00144 //get maximums and minimums 00145 if(out(k+N4_,i+1) > maxAZr_) 00146 maxAZr_ = out(k+N4_,i+1); 00147 if(out(k+N4_,i+1) < minAZr_) 00148 minAZr_ = out(k+N4_,i+1); 00149 } 00150 00151 //compute the magnitudes of the frequency dependent nulls 00152 for(mrs_natural i=0; i <= beta; ++i) 00153 { 00154 //left channel 00155 if(out(k,i+1)== min(minAZl_, minAZr_)) 00156 { 00157 out(k,i+1) = max(maxAZl_, maxAZr_) - min(minAZl_,minAZr_); 00158 //just filter out bins with amplitude inferior to -100dB 00159 if(20.0*log10(out(k,i+1)*out(k,i+1)+0.000000001)<-100.0) 00160 out(k,i+1) = 0.0; 00161 } 00162 else 00163 out(k,i+1) = 0.0; 00164 //right channel 00165 if(out(k+N4_,i+1) == min(minAZl_, minAZr_)) 00166 { 00167 out(k+N4_,i+1) = max(maxAZl_, maxAZr_) - min(minAZl_,minAZr_); 00168 //just filter out bins with amplitude inferior to -100dB 00169 if(20.0*log10(out(k+N4_,i+1)*out(k+N4_,i+1)+0.000000001)<-100.0) 00170 out(k+N4_,i+1) = 0.0; 00171 } 00172 else 00173 out(k+N4_,i+1) = 0.0; 00174 } 00175 } 00176 00177 // MATLAB_PUT(out, "out"); 00178 // MATLAB_EVAL("AZl = out(1:end/2,2:end);"); 00179 // MATLAB_EVAL("AZr = out(end/2+1:end,2:end);"); 00180 // MATLAB_EVAL("panMap = [AZl(:,1:end-1),AZr(:,end:-1:1)];figure(1);imagesc(panMap);"); 00181 }