Marsyas  0.5.0-beta1
/Users/jleben/code/marsyas/src/marsyas/marsystems/ADRess.cpp
Go to the documentation of this file.
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 }