annotate dsp/chromagram/ChromaProcess.cpp @ 16:2e3f5d2d62c1

* Move dsp/maths to maths ; bring PCA and HMM across from Soundbite
author cannam
date Wed, 09 Jan 2008 10:31:29 +0000
parents d7116e3183f8
children
rev   line source
cannam@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@0 2
cannam@0 3 /*
cannam@0 4 QM DSP Library
cannam@0 5
cannam@0 6 Centre for Digital Music, Queen Mary, University of London.
cannam@0 7 This file copyright 2005-2006 Christian Landone.
cannam@0 8 All rights reserved.
cannam@0 9 */
cannam@0 10
cannam@0 11
cannam@0 12 #include "ChromaProcess.h"
cannam@16 13 #include "maths/Histogram.h"
cannam@0 14 #include <math.h>
cannam@0 15 //////////////////////////////////////////////////////////////////////
cannam@0 16 // Construction/Destruction
cannam@0 17 //////////////////////////////////////////////////////////////////////
cannam@0 18
cannam@0 19 ChromaProcess::ChromaProcess()
cannam@0 20 {
cannam@0 21
cannam@0 22 }
cannam@0 23
cannam@0 24 ChromaProcess::~ChromaProcess()
cannam@0 25 {
cannam@0 26
cannam@0 27 }
cannam@0 28
cannam@0 29 int ChromaProcess::findChromaBias( vector<double> chromaVector, unsigned int BPO, unsigned int frames )
cannam@0 30 {
cannam@0 31 vector<double> newChroma;
cannam@0 32 vector<int> peakIndex;
cannam@0 33 vector<int> modPeakIndex;
cannam@0 34
cannam@0 35 unsigned int chromaLength = chromaVector.size();
cannam@0 36
cannam@0 37 unsigned int newLength = chromaLength + (2*BPO);
cannam@0 38
cannam@0 39 newChroma.resize( newLength );
cannam@0 40 newChroma.clear();
cannam@0 41
cannam@0 42 modPeakIndex.resize( newLength );
cannam@0 43 modPeakIndex.clear();
cannam@0 44
cannam@0 45 //adds last row at the top and first row at the bottom to create
cannam@0 46 //circularity - effectively adds 2 to the bpo-length of the vectors:
cannam@0 47
cannam@0 48 for( unsigned int i = 0; i < BPO; i++ )
cannam@0 49 {
cannam@0 50 newChroma.push_back( chromaVector[ chromaLength - BPO + i ] );
cannam@0 51 }
cannam@0 52
cannam@0 53 for( unsigned i = 0; i < chromaLength; i++ )
cannam@0 54 {
cannam@0 55 newChroma.push_back( chromaVector[ i ] );
cannam@0 56 }
cannam@0 57
cannam@0 58 for( unsigned i = 0; i < BPO; i++ )
cannam@0 59 {
cannam@0 60 newChroma.push_back( chromaVector[ i ] );
cannam@0 61 }
cannam@0 62
cannam@0 63 // pick peaks in the chroma
cannam@0 64 peakIndex = getPeaks( newChroma, BPO );
cannam@0 65
cannam@0 66 // modularises to res = bpo/12 bins:
cannam@0 67 // corrects the mod value for bin 3
cannam@0 68 modPeakIndex = mod( peakIndex, 3 );
cannam@0 69
cannam@0 70 // finds the highest concentration of peaks on the bpo/12 bin resolution
cannam@0 71 THistogram<int> m_hist(3);
cannam@0 72
cannam@0 73 double ave, adev, sdev, var, skew, ccurt;
cannam@0 74
cannam@0 75 m_hist.compute(modPeakIndex);
cannam@0 76
cannam@0 77 m_hist.getMoments( modPeakIndex, ave, adev, sdev, var, skew, ccurt );
cannam@0 78
cannam@0 79 vector <double> histogram = m_hist.geTHistogramD();
cannam@0 80 //////////////////////////////////////////////////////////////////////////////
cannam@0 81
cannam@0 82 ///////////////////////////////////////////////////////////////////////////
cannam@0 83 // Find actual bias from histogram
cannam@0 84 int minIdx, maxIdx;
cannam@0 85 double min, max;
cannam@0 86
cannam@0 87 findHistMaxMin( histogram, &max, &maxIdx, &min, &minIdx );
cannam@0 88
cannam@0 89 /*
cannam@0 90 FILE* foutchroma = fopen("../testdata/newchroma.bin","wb");
cannam@0 91 FILE* foutpeaks = fopen("../testdata/peaks.bin","wb");
cannam@0 92
cannam@0 93
cannam@0 94 fwrite( &chromaVector[0], sizeof(double), chromaVector.size(), foutchroma );
cannam@0 95 fwrite( &histogram[0], sizeof(double), histogram.size(), foutpeaks );
cannam@0 96
cannam@0 97 fclose( foutchroma );
cannam@0 98 fclose( foutpeaks );
cannam@0 99 */
cannam@0 100 return maxIdx - 1;
cannam@0 101 }
cannam@0 102
cannam@0 103
cannam@0 104 vector <int> ChromaProcess::getPeaks(vector <double> chroma, unsigned int BPO)
cannam@0 105 {
cannam@0 106 vector <int> peaks;
cannam@0 107
cannam@0 108 double pre = 0;
cannam@0 109 double post = 0;
cannam@0 110 double current = 0;
cannam@0 111
cannam@0 112 unsigned int BPOCounter = 0;
cannam@0 113 unsigned int mult = 0;
cannam@0 114 unsigned int idx = 0;
cannam@0 115
cannam@0 116 for( unsigned int i = 0; i < chroma.size() - 0; i++ )
cannam@0 117 {
cannam@0 118 BPOCounter++;
cannam@0 119
cannam@0 120 pre = chroma[ i ];
cannam@0 121 current = chroma[ i + 1 ];
cannam@0 122 post = chroma[ i + 2 ];
cannam@0 123
cannam@0 124 if( (current > 0) && (current > pre) && (current > post) )
cannam@0 125 {
cannam@0 126 peaks.push_back( BPOCounter + 1);
cannam@0 127 }
cannam@0 128
cannam@0 129
cannam@0 130 if( BPOCounter == (BPO - 2 ) )
cannam@0 131 {
cannam@0 132 BPOCounter = 0;
cannam@0 133 i+=2;
cannam@0 134 }
cannam@0 135
cannam@0 136 }
cannam@0 137
cannam@0 138 /*
cannam@0 139 for( unsigned int i = 1; i < chroma.size() - 1; i++ )
cannam@0 140 {
cannam@0 141 BPOCounter++ ;
cannam@0 142
cannam@0 143 pre = chroma[ i - 1 ];
cannam@0 144 current = chroma[ i ];
cannam@0 145 post = chroma[ i + 1 ];
cannam@0 146
cannam@0 147 if( (current > 0) && (current > pre) && (current > post) )
cannam@0 148 {
cannam@0 149 peaks.push_back( BPOCounter + 1 );
cannam@0 150 }
cannam@0 151
cannam@0 152 if( BPOCounter == (PO - 1) )
cannam@0 153 {
cannam@0 154 BPOCounter = 1;
cannam@0 155 i+=2;
cannam@0 156 }
cannam@0 157 }
cannam@0 158 */
cannam@0 159 return peaks;
cannam@0 160 }
cannam@0 161
cannam@0 162 vector <int> ChromaProcess::mod(vector <int> input, int res)
cannam@0 163 {
cannam@0 164 vector <int> result;
cannam@0 165
cannam@0 166 for( unsigned int i = 0; i < input.size(); i++ )
cannam@0 167 {
cannam@0 168 int val = input[ i ];
cannam@0 169 int res = val - res * floor( (double)val / (double)res );
cannam@0 170
cannam@0 171 if( val != 0 )
cannam@0 172 {
cannam@0 173 if( res == 0 )
cannam@0 174 res = 3;
cannam@0 175
cannam@0 176 result.push_back( res );
cannam@0 177 }
cannam@0 178 else
cannam@0 179 {
cannam@0 180 result.push_back( val );
cannam@0 181 }
cannam@0 182 }
cannam@0 183 return result;
cannam@0 184 }
cannam@0 185
cannam@0 186 void ChromaProcess::findHistMaxMin( vector<double> hist, double* max, int* maxIdx, double* min, int* minIdx )
cannam@0 187 {
cannam@0 188 double temp = 0.0;
cannam@0 189 unsigned int vecLength = hist.size();
cannam@0 190
cannam@0 191 *minIdx = 0;
cannam@0 192 *maxIdx = 0;
cannam@0 193
cannam@0 194 *min = hist[0];
cannam@0 195 *max = *min;
cannam@0 196
cannam@0 197 for( unsigned int u = 0; u < vecLength; u++ )
cannam@0 198 {
cannam@0 199 temp = hist[ u ];
cannam@0 200
cannam@0 201 if( temp < *min )
cannam@0 202 {
cannam@0 203 *min = temp ;
cannam@0 204 *minIdx = u;
cannam@0 205 }
cannam@0 206 if( temp > *max )
cannam@0 207 {
cannam@0 208 *max = temp ;
cannam@0 209 *maxIdx = u;
cannam@0 210 }
cannam@0 211
cannam@0 212 }
cannam@0 213 }