Mercurial > hg > midi-score-follower
comparison jnmr/DynamicVector.cpp @ 33:fa527df85c2c
Added the JNMR code which now features chopping after loading all events, easier that way
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Mon, 12 Dec 2011 12:46:17 +0000 |
parents | |
children | 6c8a048720c3 |
comparison
equal
deleted
inserted
replaced
32:f91b7b019350 | 33:fa527df85c2c |
---|---|
1 /* | |
2 * DynamicVector.cpp | |
3 * midiCannamReader | |
4 * | |
5 * Created by Andrew on 18/07/2011. | |
6 * Copyright 2011 QMUL. All rights reserved. | |
7 * | |
8 */ | |
9 | |
10 | |
11 #include "DynamicVector.h" | |
12 | |
13 DynamicVector::DynamicVector(){ | |
14 length = 0; | |
15 arraySize = 0; | |
16 maximumValue = 0; | |
17 MAPestimate = 0; | |
18 offset = 0; | |
19 scalar = 1; | |
20 integratedEstimate = length/2; | |
21 | |
22 gaussianLookupMean = (double) GAUSSIAN_LOOKUP_LENGTH/2; | |
23 gaussianLookupStdDev = (double)(GAUSSIAN_LOOKUP_LENGTH/16); | |
24 double factor = 1.0;//(1.0 / (gaussianLookupStdDev*sqrt(2*PI)) );//1.0;//-1.0/(2*PI*sqrt(gaussianLookupStdDev)); | |
25 for (int i = 0;i < GAUSSIAN_LOOKUP_LENGTH;i++){ | |
26 gaussianLookupTable[i] = factor*exp(-1.0*(i-gaussianLookupMean)*(i-gaussianLookupMean)/(2.0*gaussianLookupStdDev*gaussianLookupStdDev)); | |
27 } | |
28 | |
29 } | |
30 | |
31 void DynamicVector::copyFromDynamicVector(const DynamicVector& dynamicVec){ | |
32 if (dynamicVec.length == length){ | |
33 for (int i = 0;i < length;i++) | |
34 array[i] = dynamicVec.array[i]; | |
35 } | |
36 else{ | |
37 printf("CANNOT COPY VECTORS OF NON SAME LENGTH!!\n"); | |
38 } | |
39 } | |
40 | |
41 void DynamicVector::createVector(int len){ | |
42 array.clear(); | |
43 for (int i = 0; i < len;i++){ | |
44 array.push_back(0); | |
45 } | |
46 length = len; | |
47 arraySize = array.size(); | |
48 integratedEstimate = length/2; | |
49 } | |
50 | |
51 | |
52 double DynamicVector::getMaximum(){ | |
53 int i; | |
54 double max = 0; | |
55 for (i=0;i < length;i++){ | |
56 if (array[i] > max){ | |
57 max = array[i]; | |
58 MAPestimate = i; | |
59 } | |
60 } | |
61 maximumValue = max; | |
62 return max; | |
63 } | |
64 | |
65 double DynamicVector::getIntegratedEstimate(){ | |
66 //returns the index of the integrated average - where the probability distribution is centred | |
67 integratedEstimate = 0; | |
68 double integratedTotal = 0; | |
69 for (int i = 0;i < length;i++){ | |
70 integratedEstimate += array[i]*i; | |
71 integratedTotal += array[i]; | |
72 } | |
73 if (integratedTotal > 0){ | |
74 integratedEstimate /= integratedTotal; | |
75 } | |
76 return integratedEstimate; | |
77 } | |
78 | |
79 void DynamicVector::updateIntegratedEstimate(){ | |
80 //returns the index of the integrated average - where the probability distribution is centred | |
81 integratedEstimate = 0; | |
82 double integratedTotal = 0; | |
83 for (int i = 0;i < length;i++){ | |
84 integratedEstimate += array[i]*i; | |
85 integratedTotal += array[i]; | |
86 } | |
87 if (integratedTotal > 0){ | |
88 integratedEstimate /= integratedTotal; | |
89 } | |
90 | |
91 } | |
92 | |
93 void DynamicVector::updateLimitedIntegratedEstimate(){ | |
94 //returns the index of the integrated average - where the probability distribution is centred | |
95 //but limited round the MAP estimate | |
96 double tmp = getMaximum(); | |
97 int limit = min(MAPestimate, length - MAPestimate); | |
98 int start = max(0, MAPestimate - limit); | |
99 int end = min(MAPestimate + limit, length-1); | |
100 | |
101 integratedEstimate = 0; | |
102 double integratedTotal = 0; | |
103 for (int i = start;i <= end;i++){ | |
104 integratedEstimate += array[i]*i; | |
105 integratedTotal += array[i]; | |
106 } | |
107 if (integratedTotal > 0){ | |
108 integratedEstimate /= integratedTotal; | |
109 } | |
110 | |
111 } | |
112 | |
113 | |
114 void DynamicVector::zero(){ | |
115 for (int i = 0;i < array.size();i++) | |
116 array[i] = 0; | |
117 } | |
118 | |
119 void DynamicVector::renormalise(){ | |
120 double tmpMax = getMaximum(); | |
121 if (tmpMax > 0){ | |
122 // printf("renormalise : max is %f and size is %i\n", tmpMax, arraySize); | |
123 for (int i = 0;i < array.size();i++) | |
124 array[i] /= tmpMax; | |
125 | |
126 } | |
127 //printArray(); | |
128 } | |
129 | |
130 void DynamicVector::doProduct(DynamicVector& arrayOne, DynamicVector& arrayTwo){ | |
131 | |
132 for (int i = 0;i < arrayOne.length;i++) | |
133 array[i] = arrayOne.array[i] * arrayTwo.array[i]; | |
134 } | |
135 | |
136 | |
137 void DynamicVector::printArray(){ | |
138 for (int i = 0;i < arraySize;i++){ | |
139 printf("[%i] = %f\n", i, array[i]); | |
140 } | |
141 } | |
142 | |
143 void DynamicVector::translateDistribution(int translationIndex){ | |
144 int tmpIndex; | |
145 DoubleVector tmpArray; | |
146 int i; | |
147 | |
148 for (i=0;i < arraySize;i++){ | |
149 tmpArray.push_back(array[i]); | |
150 } | |
151 //translate values | |
152 for (i=0;i < arraySize;i++){ | |
153 tmpIndex = (i + translationIndex + arraySize)%arraySize; | |
154 array[tmpIndex] = tmpArray[i]; | |
155 } | |
156 tmpArray.clear(); | |
157 //now delete tmp array | |
158 } | |
159 | |
160 void DynamicVector::addGaussianShape(const double& mean, const double& StdDev, double factor){ | |
161 | |
162 int i; | |
163 double std_dev_factor = (2*StdDev*StdDev); | |
164 factor *= (1/(StdDev*sqrt(2*PI))); | |
165 int maxVal = min((int) array.size(), (int)(mean + 4.8*StdDev)); | |
166 int minVal = max(0, (int)(mean - 4.8*StdDev)); | |
167 | |
168 for (i=minVal;i < maxVal;i++){ | |
169 array[i] += factor*exp(-1*(i-mean)*(i-mean)/(std_dev_factor)); | |
170 } | |
171 | |
172 // addGaussianShapeByLookupTable(mean, StdDev, factor); | |
173 } | |
174 | |
175 void DynamicVector::addGaussianShapeByLookupTable(double& mean, double& StdDev, double factor){ | |
176 int i; | |
177 int lookupIndex ; | |
178 factor *= (1/(StdDev*sqrt(2*PI))); | |
179 for (i=0;i<array.size()-1;i++){ | |
180 lookupIndex = round(getLookupIndex(i, mean, StdDev)); | |
181 array[i] += factor*gaussianLookupTable[lookupIndex]; | |
182 } | |
183 //printf("ADDED GAUSSIAN SHAPE %i\n", (int)array.size()); | |
184 } | |
185 | |
186 double DynamicVector::getLookupIndex(const int& i, const double& mean, const double& StdDev){ | |
187 | |
188 double Z = ((double)i - mean)/StdDev; | |
189 double lookupIndex = Z*gaussianLookupStdDev + gaussianLookupMean; | |
190 | |
191 if (lookupIndex < 0) | |
192 lookupIndex = 0; | |
193 | |
194 if (lookupIndex >= GAUSSIAN_LOOKUP_LENGTH) | |
195 lookupIndex = GAUSSIAN_LOOKUP_LENGTH-1; | |
196 | |
197 // (i - mean)*(i-mean)*(GAUSSIAN_LOOKUP_LENGTH*GAUSSIAN_LOOKUP_LENGTH/16.0)/(StdDev*StdDev); | |
198 return lookupIndex; | |
199 } | |
200 | |
201 void DynamicVector::addTriangularShape(double mean, double width, double factor){ | |
202 int i; | |
203 | |
204 for (i= max(0., (double)(mean - width));i < min((mean+width), (double)array.size());i++){ | |
205 array[i] += factor * abs(i - mean) / mean; | |
206 } | |
207 | |
208 } | |
209 | |
210 void DynamicVector::addConstant(const double& value){ | |
211 for (int i=0;i<array.size();i++){ | |
212 array[i] += value; | |
213 } | |
214 } | |
215 | |
216 | |
217 void DynamicVector::addToIndex(const int& index, const double& constant){ | |
218 array[index] += constant; | |
219 } | |
220 | |
221 | |
222 double DynamicVector::getIndexInRealTerms(const int& index){ | |
223 if (index < arraySize) | |
224 return (offset + scalar*index); | |
225 else | |
226 return 0; | |
227 } | |
228 | |
229 double DynamicVector::getRealTermsAsIndex(double value){ | |
230 value -= offset; | |
231 value /= scalar; | |
232 | |
233 return value; | |
234 | |
235 } | |
236 | |
237 double DynamicVector::getValueAtMillis(const double& millis){ | |
238 | |
239 int index = round(getRealTermsAsIndex(millis)); | |
240 if (index >= 0 && index < length) | |
241 return array[index]; | |
242 else | |
243 return 0; | |
244 } | |
245 | |
246 void DynamicVector::drawVector(const int& minIndex, const int& maxIndex){ | |
247 | |
248 | |
249 double stepSize = ofGetWidth() / (double)(maxIndex - minIndex); | |
250 double screenHeight = (double) ofGetHeight(); | |
251 double maxVal = getMaximum(); | |
252 | |
253 int startInt = max(1,minIndex+1); | |
254 int endInt = min(maxIndex, (int)array.size()); | |
255 double heightConstant = screenHeight / maxVal; | |
256 int lastHeightPixel = heightConstant * (maxVal - array[startInt-1]); | |
257 int newHeightPixel; | |
258 for (int i = startInt;i < endInt;i++){ | |
259 newHeightPixel = (int) heightConstant * (maxVal - array[i]); | |
260 ofLine (stepSize*(i-1), lastHeightPixel, stepSize*i, newHeightPixel); | |
261 lastHeightPixel = newHeightPixel; | |
262 } | |
263 | |
264 } | |
265 | |
266 | |
267 void DynamicVector::drawConstrainedVector(const int& minIndex, const int& maxIndex, const int& minScreenIndex, const int& maxScreenIndex){ | |
268 //constrain the height and width | |
269 | |
270 double stepSize = (maxScreenIndex - minScreenIndex) / (double)(maxIndex - minIndex);//step size in pixels per array bin | |
271 double screenHeight = ofGetHeight(); | |
272 double maxVal = getMaximum(); | |
273 | |
274 //OPTIMIZE!! XXX could just add stepsize each time | |
275 //not add minindex each time | |
276 int i = max(1,minIndex+1); | |
277 // ofDrawBitmapString("i = "+ofToString(i)+" :: screen min: "+ofToString(minScreenIndex + stepSize*(i-minIndex-1)), 20, 640); | |
278 | |
279 while ((minScreenIndex + stepSize*(i-minIndex)) < 0) | |
280 i++;//only draw what is on the screen | |
281 | |
282 for ( ; i < min(maxIndex+1, (int)array.size());i++){ | |
283 ofLine (minScreenIndex + (stepSize*(i-minIndex-1)), screenHeight * (1 - array[i-1] / maxVal), | |
284 minScreenIndex + (stepSize*(i-minIndex)), screenHeight * (1 - array[i] / maxVal) ); | |
285 | |
286 } | |
287 | |
288 ofLine(minScreenIndex, screenHeight, minScreenIndex, screenHeight/2); | |
289 ofLine(maxScreenIndex, screenHeight, maxScreenIndex, screenHeight/2); | |
290 | |
291 // ofDrawBitmapString(ofToString(stepSize, 2)+" "+ofToString(maxScreenIndex - minScreenIndex, 0), 20, 600); | |
292 | |
293 } |