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