![]() |
Mixxx
|
00001 /* 00002 * Copyright (c) 2001-2002 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 #include "TonalAnalysis.hxx" 00023 #include "ChordExtractor.hxx" 00024 #include "ProcessingFactory.hxx" 00025 00026 00027 namespace CLAM 00028 { 00029 00030 namespace Hidden 00031 { 00032 static const char * metadata[] = { 00033 "key", "TonalAnalysis", 00034 "category", "Analysis", 00035 "description", "TonalAnalysis", 00036 0 00037 }; 00038 static FactoryRegistrator<ProcessingFactory, TonalAnalysis> reg = metadata; 00039 } 00040 00041 00042 // TonalAnalysisConfig method definition 00043 void TonalAnalysisConfig::DefaultInit(void) 00044 { 00045 AddAll(); 00046 00047 UpdateData(); 00048 00049 SetFilterInertia(0.7); 00050 SetTunningEnabled(true); 00051 SetPeakWindowingEnabled(true); 00052 SetHopRatio(8.0); 00053 SetSegmentationMethod(1); 00054 } 00055 00056 00057 TonalAnalysis::TonalAnalysis( const TonalAnalysisConfig& cfg ) 00058 : _input("Audio Input",this) 00059 , _pcp("Pitch Profile",this) 00060 , _chordCorrelation("Chord Correlation",this) 00061 , _segmentation("Chord Segmentation", this) 00062 , _chromaPeaks("Chroma Peaks",this) 00063 , _tunning("Tunning",this) 00064 , _implementation( 0 ) 00065 , _currentTime( 0 ) 00066 { 00067 Configure( cfg ); 00068 } 00069 00070 TonalAnalysis::~TonalAnalysis() 00071 { 00072 if (_implementation) delete _implementation; 00073 } 00074 00075 bool TonalAnalysis::ConcreteConfigure( const ProcessingConfig& c ) 00076 { 00077 CopyAsConcreteConfig(_config, c); 00078 00079 if (_implementation) delete _implementation; 00080 _implementation = new Simac::ChordExtractor; 00081 00082 _implementation->filterInertia( _config.GetFilterInertia() ); 00083 _implementation->enableTunning( _config.GetTunningEnabled() ); 00084 _implementation->enablePeakWindowing( _config.GetPeakWindowingEnabled() ); 00085 _implementation->hopRatio( _config.GetHopRatio() ); 00086 unsigned segmentationMethod = _config.HasSegmentationMethod() ? _config.GetSegmentationMethod() : 0; 00087 _implementation->segmentationMethod( segmentationMethod ); 00088 00089 _input.SetSize( _implementation->frameSize() ); 00090 _input.SetHop( _implementation->hop() ); 00091 _floatBuffer.resize(_implementation->frameSize()); 00092 return true; 00093 } 00094 00095 bool TonalAnalysis::ConcreteStart() 00096 { 00097 _currentTime = 0.0; 00098 return true; 00099 } 00100 00101 bool TonalAnalysis::ConcreteStop() 00102 { 00103 _implementation->clear(); 00104 return true; 00105 } 00106 00107 bool TonalAnalysis::Do() 00108 { 00109 if( !AbleToExecute() ) return true; 00110 CLAM::TData * input = &(_input.GetAudio().GetBuffer()[0]); 00111 for (unsigned i = 0; i < _implementation->frameSize(); i++) 00112 _floatBuffer[i] = input[i]; 00113 _implementation->doIt(&_floatBuffer[0], _currentTime); 00114 00115 std::vector<TData> & pcp = _pcp.GetData(); 00116 pcp.resize(_implementation->pcp().size()); 00117 for (unsigned i = 0; i < _implementation->pcp().size(); i++) 00118 pcp[i] = _implementation->pcp()[i]; 00119 _pcp.Produce(); 00120 00121 std::vector<TData> & chordCorrelation = _chordCorrelation.GetData(); 00122 chordCorrelation.resize(_implementation->chordCorrelation().size()); 00123 for (unsigned i = 0; i < _implementation->chordCorrelation().size(); i++) 00124 chordCorrelation[i] = _implementation->chordCorrelation()[i]; 00125 _chordCorrelation.Produce(); 00126 00127 DiscontinuousSegmentation & segmentation = _segmentation.GetData(); 00128 segmentation = _implementation->segmentation(); 00129 for (unsigned i=0; i<segmentation.onsets().size(); i++) 00130 { 00131 unsigned chordIndex = _implementation->chordIndexes()[i]; 00132 std::string chordName = _implementation->root(chordIndex) + " " + _implementation->mode(chordIndex); 00133 segmentation.setLabel(i,chordName); 00134 } 00135 segmentation.dragOffset(segmentation.onsets().size()-1, _currentTime ); 00136 00137 _segmentation.Produce(); 00138 00139 00140 std::vector<std::pair<TData,TData> > & chromaPeaks = _chromaPeaks.GetData(); 00141 chromaPeaks.resize(_implementation->peaks().size()); //TODO processing time resize!!!! 00142 for (unsigned i = 0; i < _implementation->peaks().size(); i++) 00143 chromaPeaks[i] = _implementation->peaks()[i]; 00144 _chromaPeaks.Produce(); 00145 00146 std::pair<TData,TData> & tunning = _tunning.GetData(); 00147 tunning = _implementation->instantTunning(); 00148 // tunning.first=_implementation->tunning(); 00149 // tunning.second=_implementation->tunningStrength(); 00150 _tunning.Produce(); 00151 00152 _input.Consume(); 00153 00154 _currentTime += _implementation->hop()/44100.0; 00155 00156 return true; 00157 } 00158 00159 00160 00161 } // namespace CLAM 00162 00163 00164