Mercurial > hg > qm-dsp
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 } |