CLAM-Development
1.1
|
00001 /* 00002 * Copyright (c) 2001-2006 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 * 00020 */ 00021 00022 #ifndef ChordCorrelator_hxx 00023 #define ChordCorrelator_hxx 00024 #include <list> 00025 #include <vector> 00026 #include <cmath> 00027 #include <sstream> 00028 00029 namespace Simac 00030 { 00031 00041 class ChordCorrelator 00042 { 00043 public: 00044 static std::string PitchNames(unsigned index) 00045 { 00046 static const char * PitchNames[] = {"G","G#","A","A#","B","C","C#","D","D#","E","F","F#"}; 00047 return PitchNames[index]; 00048 } 00049 enum Pitch {G,Ab,A,Bb,B,C,Db,D,Eb,E,F,Gb}; 00050 typedef unsigned ChordMode; 00051 typedef std::vector<double> PCP; 00052 typedef std::vector<double> ChordCorrelation; 00053 00054 struct ChordModePatterns 00055 { 00056 double pattern[12]; 00057 const char * name; 00058 unsigned nRoots; 00059 }; 00060 00061 static ChordModePatterns * chordModePatterns() 00062 { 00063 static ChordModePatterns patterns[] = 00064 { 00065 {{1,1,1,1,1,1,1,1,1,1,1,1}, "None", 1}, 00066 {{1,0,0,0,1,0,0,1,0,0,0,0}, "Major", 12}, 00067 {{1,0,0,1,0,0,0,1,0,0,0,0}, "Minor", 12}, 00068 {{1,0,0,0,1,0,0,1,0,0,0,1}, "Major7", 12}, // Cmaj7 00069 {{1,0,0,0,1,0,0,1,0,0,1,0}, "Dominant7", 12}, // C7 00070 {{1,0,0,1,0,0,0,1,0,0,0,1}, "MinorMajor7",12}, // Cm/maj7 00071 {{1,0,0,1,0,0,0,1,0,0,1,0}, "Minor7", 12}, // Cm7 00072 // {{1,0,1,0,0,0,0,1,0,0,0,0}, "Suspended2", 12}, // Csus2 00073 // {{1,0,0,0,0,1,0,1,0,0,0,0}, "Suspended4", 12}, // Csus4 00074 // {{1,0,0,0,1,0,0,1,0,1,0,0}, "Major6", 12}, // C6 00075 // {{1,0,0,1,0,0,0,1,0,1,0,0}, "Minor6", 12}, // Cm6 00076 // {{1,0,1,0,1,0,0,1,0,1,0,0}, "6/9", 12}, // C6/9 00077 {{1,0,0,0,1,0,0,0,1,0,0,0}, "Augmented", 4}, // Caug 00078 {{1,0,0,1,0,0,1,0,0,0,0,0}, "Diminished", 12}, // Cdim 00079 {{1,0,0,1,0,0,1,0,0,0,1,0}, "Diminished7",12}, // Cdim7 00080 // {{1,0,0,0,0,0,0,1,0,0,0,0}, "Fifth", 12}, // C5 00081 {{0,0,0,0,0,0,0,0,0,0,0,0}, 0, 0} 00082 }; 00083 return patterns; 00084 } 00085 00086 struct ChordPattern { 00087 double pattern[12]; 00088 Pitch root; 00089 ChordMode mode; 00090 double normalization; 00091 00092 }; 00093 public: 00094 ChordCorrelator(ChordModePatterns * modePatterns = chordModePatterns()) 00095 { 00096 for (unsigned mode=0; modePatterns[mode].name; mode++) 00097 { 00098 _chordModeNames.push_back(modePatterns[mode].name); 00099 double * basePattern = modePatterns[mode].pattern; 00100 double normalizationFactor = 0.0; 00101 for (unsigned i = 0; i<12; i++) 00102 normalizationFactor += basePattern[i]; 00103 00104 for (unsigned root=0; root<modePatterns[mode].nRoots; root++) 00105 { 00106 ChordPattern pattern; 00107 pattern.root = Pitch(root); 00108 pattern.mode = mode; 00109 pattern.normalization = normalizationFactor; 00110 for (unsigned i=root; i<12; i++) 00111 pattern.pattern[i] = basePattern[i-root]; 00112 for (unsigned i=0; i<root; i++) 00113 pattern.pattern[i] = basePattern[12+i-root]; 00114 _chordPatterns.push_back(pattern); 00115 } 00116 } 00117 for (unsigned i=0; i<_chordPatterns.size(); i++) 00118 { 00119 std::vector<double> singleRow; 00120 for (unsigned j=0; j<_chordPatterns.size(); j++) 00121 { 00122 double chordPatternCorrelation = 0; 00123 for (unsigned k=0; k<12; k++) 00124 { 00125 chordPatternCorrelation += (_chordPatterns[i].pattern[k] * _chordPatterns[j].pattern[k]); 00126 } 00127 chordPatternCorrelation /= (_chordPatterns[i].normalization + _chordPatterns[j].normalization) / 2.0; 00128 singleRow.push_back(chordPatternCorrelation); 00129 //singleRow.push_back(1.0); 00130 } 00131 _chordPatternsSimilarity.push_back(singleRow); 00132 } 00133 _output.resize(_chordPatterns.size()); 00134 } 00135 void DumpChordPatterns(std::ostream & os) 00136 { 00137 for (unsigned pattern=0; pattern<_chordPatterns.size(); pattern++) 00138 { 00139 for (unsigned i=0; i<12; i++) 00140 os << _chordPatterns[pattern].pattern[i] << " "; 00141 os << _chordPatterns[pattern].normalization << " "; 00142 os << PitchNames(_chordPatterns[pattern].root) << " "; 00143 os << _chordModeNames[_chordPatterns[pattern].mode] << "\n"; 00144 } 00145 } 00146 std::string root(unsigned chordIndex) const 00147 { 00148 return PitchNames(_chordPatterns[chordIndex].root); 00149 } 00150 std::string mode(unsigned chordIndex) const 00151 { 00152 return _chordModeNames[_chordPatterns[chordIndex].mode]; 00153 } 00154 std::string chordRepresentation(unsigned chordIndex) const 00155 { 00156 std::ostringstream os; 00157 os << PitchNames(_chordPatterns[chordIndex].root) << "_"; 00158 os << _chordModeNames[_chordPatterns[chordIndex].mode]; 00159 return os.str(); 00160 } 00161 std::vector< std::vector<double> > chordPatternsSimilarity() const 00162 { 00163 return _chordPatternsSimilarity; 00164 } 00165 ~ChordCorrelator() 00166 { 00167 } 00168 void doIt(const PCP & pcp) 00169 { 00170 for (unsigned int i=0; i<_chordPatterns.size(); i++) 00171 { 00172 _output[i]=0.0; 00173 double * chordPattern = _chordPatterns[i].pattern; 00174 for (unsigned pitch=0; pitch<12; pitch++) 00175 { 00176 _output[i]+= chordPattern[pitch] * pcp[pitch]; 00177 } 00178 _output[i]/=_chordPatterns[i].normalization; 00179 } 00180 } 00181 const std::vector<double> & output() const 00182 { 00183 return _output; 00184 } 00185 private: 00186 std::vector<ChordPattern> _chordPatterns; 00187 std::vector< std::vector<double> > _chordPatternsSimilarity; 00188 std::vector<std::string> _chordModeNames; 00189 ChordCorrelation _output; 00190 }; 00191 00192 } // namespace Simac 00193 00194 #endif// ChordCorrelator_hxx 00195