comparison dsp/chromagram/ChromaProcess.cpp @ 0:d7116e3183f8

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