Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/Krumhansl_key_finder.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 "../common_source.h"
00020 #include "Krumhansl_key_finder.h"
00021 
00022 using std::ostringstream;
00023 using namespace Marsyas;
00024 
00025 Krumhansl_key_finder::Krumhansl_key_finder(mrs_string name) : MarSystem("Krumhansl_key_finder", name)
00026 {
00028   addControls();
00029 }
00030 
00031 Krumhansl_key_finder::Krumhansl_key_finder(const Krumhansl_key_finder& a) : MarSystem(a)
00032 {
00033 
00034   ctrl_key_ = getctrl("mrs_natural/key");
00035   ctrl_key_name_ = getctrl("mrs_string/key_name");
00036 
00037 }
00038 
00039 
00040 Krumhansl_key_finder::~Krumhansl_key_finder()
00041 {
00042 }
00043 
00044 MarSystem*
00045 Krumhansl_key_finder::clone() const
00046 {
00047   return new Krumhansl_key_finder(*this);
00048 }
00049 
00050 void
00051 Krumhansl_key_finder::addControls()
00052 {
00054   addctrl("mrs_natural/key", 0, ctrl_key_);
00055   addctrl("mrs_string/key_name", "C", ctrl_key_name_);
00056 
00057 }
00058 
00059 
00060 void
00061 Krumhansl_key_finder::myUpdate(MarControlPtr sender)
00062 {
00063   MRSDIAG("Krumhansl_key_finder.cpp - Krumhansl_key_finder:myUpdate");
00064 
00066   MarSystem::myUpdate(sender);
00067 
00068 
00069   major_profile_.create(12);
00070   minor_profile_.create(12);
00071   scores_.create(24);
00072 
00073 
00074   major_profile_(0) = 6.35;
00075   major_profile_(1) = 2.23;
00076   major_profile_(2) = 3.48;
00077   major_profile_(3) = 2.33;
00078   major_profile_(4) = 4.38;
00079   major_profile_(5) = 4.09;
00080   major_profile_(6) = 2.52;
00081   major_profile_(7) = 5.19;
00082   major_profile_(8) = 2.39;
00083   major_profile_(9) = 3.66;
00084   major_profile_(10) = 2.29;
00085   major_profile_(11) = 2.88;
00086 
00087 
00088   minor_profile_(0) = 6.33;
00089   minor_profile_(1) = 2.68;
00090   minor_profile_(2) = 3.52;
00091   minor_profile_(3) = 5.38;
00092   minor_profile_(4) = 2.6;
00093   minor_profile_(5) = 3.53;
00094   minor_profile_(6) = 2.54;
00095   minor_profile_(7) = 4.75;
00096   minor_profile_(8) = 3.98;
00097   minor_profile_(9) = 2.69;
00098   minor_profile_(10) = 3.34;
00099   minor_profile_(11) = 3.17;
00100 
00101   key_names_.push_back("A");
00102   key_names_.push_back("A#");
00103   key_names_.push_back("B");
00104   key_names_.push_back("C");
00105   key_names_.push_back("C#");
00106   key_names_.push_back("D");
00107   key_names_.push_back("D#");
00108   key_names_.push_back("E");
00109   key_names_.push_back("F");
00110   key_names_.push_back("F#");
00111   key_names_.push_back("G");
00112   key_names_.push_back("G#");
00113 
00114 
00115   key_names_.push_back("a");
00116   key_names_.push_back("a#");
00117   key_names_.push_back("b");
00118   key_names_.push_back("c");
00119   key_names_.push_back("c#");
00120   key_names_.push_back("d");
00121   key_names_.push_back("d#");
00122   key_names_.push_back("e");
00123   key_names_.push_back("f");
00124   key_names_.push_back("f#");
00125   key_names_.push_back("g");
00126   key_names_.push_back("g#");
00127 
00128 
00129 
00130 }
00131 
00132 void
00133 Krumhansl_key_finder::myProcess(realvec& in, realvec& out)
00134 {
00135 
00136   scores_.setval(0.0);
00137 
00138   // Correlate with each major/minor key profile
00139   // for (k = 0; k < 12; k++)
00140   //    {
00141   //        for (o = 0; o < inObservations_; o++)
00142   //        {
00143   //            scores_(k) += in((o+k)%12,0) * major_profile_(o);
00144   //        }
00145   //    }
00146 
00147 
00148   for (mrs_natural o = 0; o < inObservations_; o++)
00149     for (mrs_natural k=0; k < 12; k++)
00150     {
00151       scores_(k)    += (in((o+k)%12,0)  * major_profile_(o));
00152       scores_(k+12) += (in((o+k)%12,0)  * minor_profile_(o));
00153 
00154     }
00155 
00156 
00157   mrs_real max_score = 0.0;
00158   mrs_natural max_index = 0;
00159 
00160   for (mrs_natural k=0; k < 24; k++)
00161   {
00162     if (scores_(k) >= max_score)
00163     {
00164       max_score = scores_(k);
00165       max_index = k;
00166     }
00167   }
00168 
00169 
00170   ctrl_key_->setValue(max_index, NOUPDATE);
00171   ctrl_key_name_->setValue(key_names_[max_index], NOUPDATE);
00172 
00173   out.setval(0.0);
00174   if (max_index >= 12)
00175     max_index = max_index -12;
00176   out(max_index,0) = 1.0;
00177 }