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 "../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 }