andrew@0
|
1 /*
|
andrew@3
|
2 * TimeWarp.cpp
|
andrew@0
|
3 * chromaReader13
|
andrew@0
|
4 *
|
andrew@0
|
5 * Created by Andrew on 16/05/2011.
|
andrew@0
|
6 * Copyright 2011 QMUL. All rights reserved.
|
andrew@0
|
7 *
|
andrew@0
|
8 */
|
andrew@0
|
9
|
andrew@3
|
10 #include "TimeWarp.h"
|
andrew@0
|
11
|
andrew@0
|
12 #include "stdio.h"
|
andrew@0
|
13 #include "aubio.h"
|
andrew@0
|
14 #include <iostream>
|
andrew@0
|
15 #include <cstring>
|
andrew@0
|
16 #include <string>
|
andrew@0
|
17 #include <cstdlib>
|
andrew@0
|
18
|
andrew@0
|
19 //FIX CHORDS IN THE NEW POINTER VERSION OF THE PROCESS AUDIO FN
|
andrew@0
|
20
|
andrew@0
|
21 //BUG IN WHETHER SECOND SONG LOADED OR NOT
|
andrew@0
|
22
|
andrew@0
|
23
|
andrew@0
|
24 //CHECK THAT DTW will not call beyond the limits of the two chroma if different sizes
|
andrew@0
|
25
|
andrew@0
|
26 //CALC DTW on different sizes
|
andrew@0
|
27
|
andrew@0
|
28 //CHECK CORRECT BEST ALIGNMENT METHOD FOR DTW
|
andrew@0
|
29
|
andrew@0
|
30 //RE-DO DRAW SO THAT IT DOES NOT CALCULATE EVERY POINT BUT DOES IN SQUARE CHUNKS
|
andrew@0
|
31
|
andrew@0
|
32 //UPDATE START FRAME SO ALIGNMENT IS ALWAYS ON SCREEN
|
andrew@0
|
33 //--------------------------------------------------------------
|
andrew@3
|
34 // destructor
|
andrew@3
|
35 TimeWarp :: TimeWarp(){
|
andrew@14
|
36 //diagonalPenalty = 1;//favours diagonal over other paths
|
andrew@14
|
37 //diagonalPenalty = 2;//penalises diagonal so all path gradients equal weighting
|
andrew@8
|
38
|
andrew@16
|
39 useDotProduct = false;////true - dot, falseo: Euclidean dist
|
andrew@3
|
40 }
|
andrew@0
|
41
|
andrew@3
|
42 // destructor
|
andrew@3
|
43 TimeWarp :: ~TimeWarp(){
|
andrew@4
|
44
|
andrew@3
|
45 chromaMatrix.clear();
|
andrew@3
|
46 secondMatrix.clear();
|
andrew@3
|
47 firstEnergyVector.clear();
|
andrew@3
|
48 secondEnergyVector.clear();
|
andrew@3
|
49 similarityMatrix.clear();
|
andrew@3
|
50 alignmentMeasureMatrix.clear();
|
andrew@5
|
51 conversionFactor = 16;
|
andrew@4
|
52 //matrixPtr.clear();
|
andrew@3
|
53 //chromoGramm.~ChromoGram();
|
andrew@3
|
54 //secondChromoGramm;
|
andrew@10
|
55 anchorPoints.clear();
|
andrew@3
|
56
|
andrew@3
|
57
|
andrew@3
|
58 }
|
andrew@8
|
59
|
andrew@8
|
60
|
andrew@8
|
61 void TimeWarp::clearVectors(){
|
andrew@8
|
62 firstEnergyVector.clear();
|
andrew@8
|
63 secondEnergyVector.clear();
|
andrew@8
|
64 chromaMatrix.clear();
|
andrew@8
|
65 secondMatrix.clear();
|
andrew@8
|
66 similarityMatrix.clear();
|
andrew@8
|
67 chromaSimilarityMatrix.clear();
|
andrew@8
|
68 tmpSimilarityMatrix.clear();
|
andrew@8
|
69 alignmentMeasureMatrix.clear();
|
andrew@8
|
70 tmpAlignmentMeasureMatrix.clear();
|
andrew@8
|
71 minimumAlignmentPath.clear();
|
andrew@8
|
72 partBackwardsAlignmentPath.clear();
|
andrew@14
|
73 forwardsAlignmentPath.clear();
|
andrew@14
|
74 anchorPoints.clear();
|
andrew@8
|
75 }
|
andrew@3
|
76
|
andrew@3
|
77 void TimeWarp::initialiseVariables(){
|
andrew@14
|
78 similarityMatrix.clear();
|
andrew@14
|
79 chromaSimilarityMatrix.clear();
|
andrew@14
|
80 tmpSimilarityMatrix.clear();
|
andrew@14
|
81 alignmentMeasureMatrix.clear();
|
andrew@14
|
82 tmpAlignmentMeasureMatrix.clear();
|
andrew@14
|
83 minimumAlignmentPath.clear();
|
andrew@14
|
84 partBackwardsAlignmentPath.clear();
|
andrew@14
|
85 forwardsAlignmentPath.clear();
|
andrew@14
|
86 anchorPoints.clear();
|
andrew@14
|
87
|
andrew@14
|
88 //diagonalPenalty = 1;
|
andrew@1
|
89 //chromoGramm.initialise(FRAMESIZE,2048);//framesize 512 and hopsize 2048
|
andrew@0
|
90
|
andrew@0
|
91 }
|
andrew@0
|
92
|
andrew@0
|
93
|
andrew@4
|
94 void TimeWarp::createCombinedMatrix(DoubleMatrix myChromaMatrix, DoubleVector energyVector, DoubleMatrix* chromaEnergyMatrix){
|
andrew@4
|
95 chromaEnergyMatrix->clear();
|
andrew@4
|
96 int sizeRatio = energyVector.size() / myChromaMatrix.size();//
|
andrew@4
|
97 printf("COMBINE: size of my chroma is %i\n", (int) myChromaMatrix.size());// energyVector.size() / myChromaMatrix.size();
|
andrew@4
|
98 printf("COMBINED: size ratio of energy to chroma is %i \n", sizeRatio);
|
andrew@4
|
99 int chromaSize = myChromaMatrix.size();
|
andrew@4
|
100 // printf("index is %i\n", index);
|
andrew@4
|
101
|
andrew@4
|
102 for (int i = 0;i < energyVector.size();i++){
|
andrew@4
|
103 DoubleVector d;
|
andrew@4
|
104 int index = min(chromaSize-1, (int) floor(i/sizeRatio));
|
andrew@4
|
105
|
andrew@4
|
106 for (int y = 0;y < 12;y++){
|
andrew@4
|
107 d.push_back(myChromaMatrix[index][y]);//
|
andrew@4
|
108 }
|
andrew@4
|
109
|
andrew@4
|
110
|
andrew@4
|
111 d.push_back(energyVector[i]);
|
andrew@4
|
112 (*chromaEnergyMatrix).push_back(d);
|
andrew@4
|
113 }
|
andrew@4
|
114 printf("COMBINED: size of chroma energy is %i\n", (int)(*chromaEnergyMatrix).size());
|
andrew@4
|
115
|
andrew@5
|
116 // int x = (int)(*chromaEnergyMatrix).size()/3;
|
andrew@4
|
117 // printf("energy[%i] %f \n", x, energyVector[x]);
|
andrew@3
|
118 /*
|
andrew@4
|
119 for (int y = 0;y < 13;y++){
|
andrew@4
|
120 printf("chroma[%i][%i] %f \n", x, y, myChromaMatrix[x/sizeRatio][y]);
|
andrew@4
|
121 printf("c[%i][%i] %f \n", x, y, (*chromaEnergyMatrix)[x][y]);
|
andrew@0
|
122 }
|
andrew@4
|
123 printf("\n");
|
andrew@4
|
124 */
|
andrew@4
|
125
|
andrew@0
|
126 }
|
andrew@0
|
127
|
andrew@3
|
128 void TimeWarp::calculateSimilarityMatrix(){
|
andrew@5
|
129 calculateSimilarityMatrixWithPointers(&chromaMatrix, &secondMatrix, &similarityMatrix);
|
andrew@4
|
130
|
andrew@4
|
131 /*
|
andrew@0
|
132 similarityMatrix.clear();
|
andrew@4
|
133 printf("calculating similarity matrix...")
|
andrew@0
|
134 // userInfoString = "calculating similarity matrix...";
|
andrew@0
|
135
|
andrew@0
|
136 double distance, firstSum, secondSum;
|
andrew@0
|
137
|
andrew@0
|
138 for (int x = 0;x < chromaMatrix.size();x++){
|
andrew@0
|
139 DoubleVector d;
|
andrew@4
|
140
|
andrew@4
|
141
|
andrew@4
|
142 for (int y = 0;y < secondMatrix.size();y++){
|
andrew@0
|
143
|
andrew@0
|
144 distance = 0;
|
andrew@0
|
145 firstSum = 0;
|
andrew@0
|
146 secondSum = 0;
|
andrew@4
|
147
|
andrew@0
|
148 for (int z = 0;z < chromaMatrix[x].size();z++){//z is the twelve chromagram values
|
andrew@0
|
149
|
andrew@0
|
150 distance += chromaMatrix[x][z] * secondMatrix[y][z];
|
andrew@0
|
151
|
andrew@0
|
152 firstSum += chromaMatrix[x][z] * chromaMatrix[x][z];
|
andrew@0
|
153 secondSum += secondMatrix[y][z] * secondMatrix[y][z];
|
andrew@0
|
154 }
|
andrew@0
|
155
|
andrew@0
|
156 if (firstSum > 0 && secondSum > 0)
|
andrew@0
|
157 distance /= sqrt(firstSum * secondSum);
|
andrew@0
|
158
|
andrew@0
|
159
|
andrew@0
|
160 d.push_back( distance);
|
andrew@0
|
161
|
andrew@0
|
162 } //end for y
|
andrew@0
|
163
|
andrew@0
|
164 similarityMatrix.push_back(d);
|
andrew@0
|
165
|
andrew@0
|
166 }//end for x
|
andrew@4
|
167 */
|
andrew@4
|
168 // printf("..sim size: %i, height: %i \n", (int) similarityMatrix.size(), (int) (chromaMatrix[0]).size());
|
andrew@0
|
169
|
andrew@0
|
170 }//end self sim
|
andrew@0
|
171
|
andrew@0
|
172
|
andrew@0
|
173
|
andrew@4
|
174
|
andrew@5
|
175 void TimeWarp::calculateSimilarityMatrixWithPointers(DoubleMatrix* firstChromaMatrix, DoubleMatrix* secondChromaMatrix, DoubleMatrix* simMatrix){
|
andrew@5
|
176 printf("Calculate similarity : pointers : size %i x %i ", (int) (*firstChromaMatrix).size(), (int) (*secondChromaMatrix).size());
|
andrew@0
|
177
|
andrew@8
|
178 simMatrix->clear();
|
andrew@4
|
179
|
andrew@4
|
180 double distance, firstSum, secondSum;
|
andrew@4
|
181
|
andrew@5
|
182 for (int x = 0;x < (*firstChromaMatrix).size();x++){
|
andrew@4
|
183 DoubleVector d;
|
andrew@4
|
184
|
andrew@5
|
185 for (int y = 0;y < (*secondChromaMatrix).size();y++){
|
andrew@4
|
186
|
andrew@15
|
187 if (useDotProduct)
|
andrew@15
|
188 distance = getChromaSimilarity(x, y, firstChromaMatrix, secondChromaMatrix);
|
andrew@15
|
189 else
|
andrew@15
|
190 distance = getEuclideanDistance(x, y, firstChromaMatrix, secondChromaMatrix);
|
andrew@4
|
191
|
andrew@4
|
192 d.push_back( distance);
|
andrew@4
|
193 } //end for y
|
andrew@4
|
194
|
andrew@4
|
195 (*simMatrix).push_back(d);
|
andrew@4
|
196
|
andrew@4
|
197 }//end for x
|
andrew@4
|
198
|
andrew@4
|
199 printf("..sim size: %i, height: %i \n", (int) (*simMatrix).size(), (int) (*simMatrix)[0].size());
|
andrew@4
|
200
|
andrew@4
|
201 }//end self sim
|
andrew@4
|
202
|
andrew@4
|
203
|
andrew@5
|
204 void TimeWarp::calculateJointSimilarityMatrix(DoubleVector* energyVectorOne, DoubleVector* energyVectorTwo, DoubleMatrix* chromaSimilarityMatrix, DoubleMatrix* simMatrix){
|
andrew@5
|
205
|
andrew@5
|
206 //requires a chromagram similarity first this already done
|
andrew@5
|
207 //calculateSimilarityMatrixWithPointers(chromaMatrixOne, chromaMatrixTwo, &chromaSimilarityMatrix);
|
andrew@5
|
208
|
andrew@5
|
209 conversionFactor = (int) round((*energyVectorOne).size() / (*chromaSimilarityMatrix).size() );
|
andrew@5
|
210
|
andrew@12
|
211 printf("tw.ROUNDED CONVERSION FACTOR IS %i\n", conversionFactor);
|
andrew@12
|
212 printf("tw.CHROMA SIM SIZE %i\n", (int) (*chromaSimilarityMatrix).size());
|
andrew@5
|
213
|
andrew@8
|
214 simMatrix->clear();
|
andrew@5
|
215
|
andrew@5
|
216 double energyProportion = 0.3;
|
andrew@5
|
217 double chromaProportion = 1 - energyProportion;
|
andrew@5
|
218
|
andrew@5
|
219 double distance, firstSum, secondSum;
|
andrew@5
|
220
|
andrew@12
|
221 //lets try not actually doing calculation
|
andrew@12
|
222
|
andrew@5
|
223 for (int x = 0;x < (*energyVectorOne).size();x++){
|
andrew@5
|
224 DoubleVector d;
|
andrew@5
|
225
|
andrew@5
|
226 for (int y = 0;y < (*energyVectorTwo).size();y++){
|
andrew@5
|
227
|
andrew@5
|
228 //create chroma similarity first
|
andrew@5
|
229
|
andrew@5
|
230 // distance = (*energyVectorOne)[x] * (*energyVectorTwo)[y];//energy similarity
|
andrew@5
|
231
|
andrew@5
|
232 //now need the chroma part
|
andrew@5
|
233 int chromaIndexX = min(x / conversionFactor, (int)(*chromaSimilarityMatrix).size()-1);
|
andrew@5
|
234 int chromaIndexY = min(y / conversionFactor, (int)(*chromaSimilarityMatrix)[chromaIndexX].size()-1);
|
andrew@5
|
235
|
andrew@5
|
236 double chromaComponent = (*chromaSimilarityMatrix)[chromaIndexX][chromaIndexY];
|
andrew@5
|
237 // getChromaSimilarity(chromaIndexX, chromaIndexY, firstChromaMatrix, secondChromaMatrix);
|
andrew@5
|
238
|
andrew@5
|
239
|
andrew@5
|
240 distance *= energyProportion;
|
andrew@5
|
241 distance += chromaProportion * chromaComponent;
|
andrew@5
|
242
|
andrew@5
|
243 //distance = getJointChromaAndEnergyDistance(energyVectorOne, firstChromaMatrix, energyVectorTwo, secondChromaMatrix, x, y, conversionFactor, energyProportion, chromaProportion);
|
andrew@5
|
244
|
andrew@5
|
245
|
andrew@5
|
246
|
andrew@5
|
247 d.push_back( distance);
|
andrew@5
|
248 } //end for y
|
andrew@5
|
249
|
andrew@5
|
250 (*simMatrix).push_back(d);
|
andrew@5
|
251
|
andrew@5
|
252 }//end for x
|
andrew@12
|
253
|
andrew@12
|
254 printf("..sim size: %i, height: %i \n", (int) (*simMatrix).size(), (int) (*simMatrix)[0].size());
|
andrew@12
|
255
|
andrew@12
|
256
|
andrew@5
|
257
|
andrew@5
|
258 }
|
andrew@5
|
259
|
andrew@5
|
260 double TimeWarp::getJointChromaAndEnergyDistance(DoubleVector* energyVectorOne, DoubleMatrix* firstChromaMatrix, DoubleVector* energyVectorTwo, DoubleMatrix* secondChromaMatrix, int energyIndexX, int energyIndexY, double energyProportion, double chromaProportion){
|
andrew@5
|
261 //create chroma similarity first
|
andrew@5
|
262 double distance = 0;
|
andrew@5
|
263
|
andrew@5
|
264 if (energyIndexX >= 0 && energyIndexY >= 0 && energyIndexX < (*energyVectorOne).size() && energyIndexY < (*energyVectorTwo).size()){
|
andrew@5
|
265
|
andrew@5
|
266 distance = (*energyVectorOne)[energyIndexX] * (*energyVectorTwo)[energyIndexY];//energy similarity
|
andrew@5
|
267
|
andrew@5
|
268 //now need the chroma part
|
andrew@5
|
269 int chromaIndexX = min(energyIndexX / conversionFactor, (int)(*firstChromaMatrix).size()-1);
|
andrew@5
|
270 int chromaIndexY = min(energyIndexY / conversionFactor, (int)(*secondChromaMatrix).size()-1);
|
andrew@5
|
271 double chromaComponent = getChromaSimilarity(chromaIndexX, chromaIndexY, firstChromaMatrix, secondChromaMatrix);
|
andrew@5
|
272
|
andrew@5
|
273 distance *= energyProportion;
|
andrew@5
|
274 distance += chromaProportion * chromaComponent;
|
andrew@5
|
275 }
|
andrew@5
|
276 return distance;
|
andrew@5
|
277 }
|
andrew@5
|
278
|
andrew@5
|
279
|
andrew@5
|
280
|
andrew@5
|
281 void TimeWarp::calculateChromaSimilarityMatrix(DoubleMatrix* firstChromaMatrix, DoubleMatrix* secondChromaMatrix, DoubleMatrix* simMatrix){
|
andrew@5
|
282 //calculates the chroma only similarity matrix - used to reduce computation later when doing the joint energy and chroma matrix
|
andrew@5
|
283 for (int x = 0;x < (*firstChromaMatrix).size();x++){
|
andrew@5
|
284 DoubleVector d;
|
andrew@5
|
285 for (int y = 0;y < (*secondChromaMatrix).size();y++){
|
andrew@5
|
286 double distance;
|
andrew@15
|
287 if (useDotProduct)
|
andrew@5
|
288 distance = getChromaSimilarity(x, y, firstChromaMatrix, secondChromaMatrix);
|
andrew@15
|
289 else
|
andrew@15
|
290 distance = getEuclideanDistance(x, y, firstChromaMatrix, secondChromaMatrix);
|
andrew@15
|
291
|
andrew@5
|
292 d.push_back( distance);
|
andrew@5
|
293 }
|
andrew@5
|
294 (*simMatrix).push_back(d);
|
andrew@5
|
295 }
|
andrew@5
|
296 printf("CHROMA ONLY SIM SIZE %i x %i\n", (int)(*simMatrix).size(), (int)(*simMatrix)[0].size());
|
andrew@5
|
297
|
andrew@5
|
298 }
|
andrew@5
|
299
|
andrew@5
|
300 double TimeWarp::getChromaSimilarity(int x, int y, DoubleMatrix* firstChromaMatrix, DoubleMatrix* secondChromaMatrix){
|
andrew@5
|
301
|
andrew@5
|
302 double distance = 0;
|
andrew@5
|
303 double firstSum = 0;
|
andrew@5
|
304 double secondSum = 0;
|
andrew@5
|
305
|
andrew@5
|
306 if (x >= 0 && x < (*firstChromaMatrix).size() && y >= 0 && y < (*secondChromaMatrix).size()){
|
andrew@5
|
307 for (int z = 0;z < (*firstChromaMatrix)[x].size();z++){//z is the twelve chromagram values
|
andrew@5
|
308
|
andrew@5
|
309 distance += (*firstChromaMatrix)[x][z] * (*secondChromaMatrix)[y][z];
|
andrew@5
|
310 firstSum += (*firstChromaMatrix)[x][z] * (*firstChromaMatrix)[x][z];
|
andrew@5
|
311 secondSum += (*secondChromaMatrix)[y][z] * (*secondChromaMatrix)[y][z];
|
andrew@5
|
312 }
|
andrew@5
|
313
|
andrew@5
|
314 if (firstSum > 0 && secondSum > 0)
|
andrew@5
|
315 distance /= sqrt(firstSum)*sqrt(secondSum);
|
andrew@5
|
316 }
|
andrew@5
|
317
|
andrew@5
|
318 return distance;
|
andrew@5
|
319
|
andrew@5
|
320 }
|
andrew@5
|
321
|
andrew@5
|
322
|
andrew@15
|
323 double TimeWarp::getEuclideanDistance(int x, int y, DoubleMatrix* firstChromaMatrix, DoubleMatrix* secondChromaMatrix){
|
andrew@15
|
324
|
andrew@15
|
325 double distance = 0;
|
andrew@15
|
326 double newDistance = 0;
|
andrew@15
|
327
|
andrew@15
|
328 if (x >= 0 && x < (*firstChromaMatrix).size() && y >= 0 && y < (*secondChromaMatrix).size()){
|
andrew@15
|
329 for (int z = 0;z < (*firstChromaMatrix)[x].size();z++){//z is the twelve chromagram values
|
andrew@15
|
330 newDistance = (*firstChromaMatrix)[x][z] - (*secondChromaMatrix)[y][z];
|
andrew@15
|
331 distance += newDistance*newDistance;
|
andrew@15
|
332 }
|
andrew@15
|
333 }
|
andrew@15
|
334
|
andrew@15
|
335 return 1-sqrt(distance);
|
andrew@15
|
336
|
andrew@15
|
337 }
|
andrew@15
|
338
|
andrew@15
|
339
|
andrew@10
|
340 void TimeWarp::addAnchorPoints(const int& startFrameX, const int& startFrameY){
|
andrew@10
|
341 IntVector v;
|
andrew@10
|
342 v.push_back(startFrameX);
|
andrew@10
|
343 v.push_back(startFrameY);
|
andrew@10
|
344 anchorPoints.push_back(v);
|
andrew@10
|
345 }
|
andrew@5
|
346
|
andrew@4
|
347 void TimeWarp::calculateAlignmentMatrix(DoubleMatrix firstMatrix, DoubleMatrix secondMatrix, DoubleMatrix* alignmentMatrix){//, DoubleMatrix simMatrix
|
andrew@4
|
348 printf("starting Alignment calculation\n");
|
andrew@0
|
349 //initialise alignment
|
andrew@8
|
350 alignmentMatrix->clear();
|
andrew@8
|
351
|
andrew@0
|
352 DoubleVector d;
|
andrew@0
|
353 d.push_back(getDistance(0,0));
|
andrew@4
|
354 (*alignmentMatrix).push_back(d);
|
andrew@0
|
355
|
andrew@0
|
356 bool chromaCalculated = false;
|
andrew@0
|
357 bool secondCalculated = false;
|
andrew@0
|
358
|
andrew@0
|
359 while (!chromaCalculated || !secondCalculated) {
|
andrew@0
|
360
|
andrew@0
|
361 if (!chromaCalculated)
|
andrew@4
|
362 chromaCalculated = extendAlignmentAlong((int) firstMatrix.size(), alignmentMatrix);
|
andrew@0
|
363
|
andrew@0
|
364 if (!secondCalculated)
|
andrew@4
|
365 secondCalculated = extendAlignmentUp((int) secondMatrix.size(), alignmentMatrix);
|
andrew@0
|
366
|
andrew@0
|
367 }
|
andrew@4
|
368 printf("Alignment matrix calculated, size %i\n", (int) (*alignmentMatrix).size());
|
andrew@0
|
369 }
|
andrew@0
|
370
|
andrew@4
|
371 bool TimeWarp::extendAlignmentUp(int endIndexY, DoubleMatrix *alignmentMatrix){
|
andrew@0
|
372 DoubleVector d;
|
andrew@4
|
373 d = (*alignmentMatrix)[0];//alignmentMatrix[0];//
|
andrew@0
|
374 int heightSize = d.size();
|
andrew@4
|
375 if (heightSize < endIndexY){
|
andrew@0
|
376 //then we haven't finished yet
|
andrew@4
|
377 for (int i = 0;i < (*alignmentMatrix).size();i++){
|
andrew@0
|
378 double value = getDistance(i, heightSize);
|
andrew@4
|
379 value += getRestrictedMinimum(i, heightSize, value, 0, 0);//min values 0
|
andrew@4
|
380 (*alignmentMatrix)[i].push_back(value);//
|
andrew@0
|
381 }
|
andrew@0
|
382 }
|
andrew@4
|
383 if ((*alignmentMatrix)[0].size() == endIndexY)
|
andrew@0
|
384 return true;
|
andrew@0
|
385 else
|
andrew@0
|
386 return false;
|
andrew@0
|
387
|
andrew@0
|
388 }
|
andrew@0
|
389
|
andrew@0
|
390
|
andrew@4
|
391 bool TimeWarp::extendAlignmentAlong(int endIndexX, DoubleMatrix* alignmentMatrix){
|
andrew@0
|
392 DoubleVector d;
|
andrew@4
|
393 //firstMatrix.size()
|
andrew@4
|
394 int widthSize = (*alignmentMatrix).size();
|
andrew@4
|
395 if (widthSize < endIndexX){//firstMatrix.size()
|
andrew@0
|
396 //then we can extend along
|
andrew@0
|
397 double value = getDistance(widthSize, 0);
|
andrew@4
|
398 value += getRestrictedMinimum(widthSize, 0, value, 0, 0);
|
andrew@0
|
399
|
andrew@0
|
400 d.push_back(value);
|
andrew@4
|
401 (*alignmentMatrix).push_back(d);
|
andrew@0
|
402
|
andrew@4
|
403 for (int j = 1;j < (*alignmentMatrix)[widthSize - 1].size();j++){
|
andrew@0
|
404 value = getDistance(widthSize, j);
|
andrew@0
|
405 value += getMinimum(widthSize, j, value);
|
andrew@4
|
406 (*alignmentMatrix)[widthSize].push_back(value);
|
andrew@0
|
407 }
|
andrew@0
|
408
|
andrew@0
|
409 }
|
andrew@0
|
410
|
andrew@4
|
411 if ((*alignmentMatrix).size() == endIndexX)
|
andrew@0
|
412 return true;
|
andrew@0
|
413 else
|
andrew@0
|
414 return false;
|
andrew@0
|
415
|
andrew@0
|
416 }
|
andrew@0
|
417
|
andrew@0
|
418
|
andrew@4
|
419
|
andrew@5
|
420 void TimeWarp::calculatePartSimilarityMatrix(DoubleMatrix* firstChromaMatrix, DoubleMatrix* secondChromaMatrix, DoubleMatrix* simMatrix, int startX, int startY, int endX){
|
andrew@4
|
421 // printf("Calculate similarity : pointers : size %i x %i ", (int) firstChromaMatrix.size(), (int) secondChromaMatrix.size());
|
andrew@4
|
422
|
andrew@8
|
423 simMatrix->clear();
|
andrew@4
|
424
|
andrew@4
|
425 double distance, firstSum, secondSum;
|
andrew@5
|
426 endX = min (endX, (int)(*firstChromaMatrix).size()-1);//in case out of size
|
andrew@4
|
427
|
andrew@4
|
428 for (int x = startX;x <= endX;x++){
|
andrew@4
|
429 DoubleVector d;
|
andrew@4
|
430
|
andrew@5
|
431 for (int y = startY;y < (*secondChromaMatrix).size();y++){
|
andrew@15
|
432
|
andrew@15
|
433 if (useDotProduct)
|
andrew@15
|
434 distance = getChromaSimilarity(x, y, firstChromaMatrix, secondChromaMatrix);
|
andrew@15
|
435 else
|
andrew@15
|
436 distance = getEuclideanDistance(x, y, firstChromaMatrix, secondChromaMatrix);
|
andrew@4
|
437
|
andrew@4
|
438 d.push_back( distance);
|
andrew@4
|
439 } //end for y
|
andrew@4
|
440
|
andrew@4
|
441 (*simMatrix).push_back(d);
|
andrew@4
|
442
|
andrew@4
|
443 }//end for x
|
andrew@4
|
444
|
andrew@4
|
445 printf("..part sim size: %i, height: %i \n", (int) (*simMatrix).size(), (int) (*simMatrix)[0].size());
|
andrew@4
|
446
|
andrew@4
|
447 }//end self sim
|
andrew@4
|
448
|
andrew@4
|
449
|
andrew@4
|
450
|
andrew@4
|
451
|
andrew@9
|
452 void TimeWarp::calculatePartJointSimilarityMatrix(DoubleVector* firstEnergyVector, DoubleVector* secondEnergyVector, DoubleMatrix* chromaSimMatrix, DoubleMatrix* simMatrix, int startX, int startY, int endX, int endY){
|
andrew@5
|
453 printf("PART SIM CALC Calculate similarity : pointers : size %i x %i ", startX, startY);//(int) (*firstEnergyVector).size(), (int) (*secondEnergyVector).size());
|
andrew@5
|
454
|
andrew@5
|
455 conversionFactor = (int) round((*firstEnergyVector).size() / (*chromaSimMatrix).size() );
|
andrew@8
|
456 simMatrix->clear();
|
andrew@5
|
457
|
andrew@14
|
458 double energyProportion = 0.2;
|
andrew@5
|
459 double chromaProportion = 1 - energyProportion;
|
andrew@5
|
460 double distance, firstSum, secondSum;
|
andrew@5
|
461
|
andrew@5
|
462 endX = min (endX, (int)(*firstEnergyVector).size()-1);//in case out of size
|
andrew@14
|
463 endY = min( endY+1, (int)(*secondEnergyVector).size());
|
andrew@14
|
464 int lastChromaYvalue = 0;
|
andrew@14
|
465 int chromaIndexY = 0;
|
andrew@14
|
466 double chromaComponent = 0;
|
andrew@14
|
467 double chromaContribution = 0;
|
andrew@14
|
468 DoubleVector d;
|
andrew@5
|
469 for (int x = startX;x <= endX;x++){
|
andrew@14
|
470 d.clear();
|
andrew@5
|
471
|
andrew@14
|
472 //now need the chroma part
|
andrew@14
|
473 int chromaIndexX = min(x / conversionFactor, (int)(*chromaSimMatrix).size()-1);
|
andrew@14
|
474
|
andrew@14
|
475 for (int y = startY;y < endY;y++){
|
andrew@15
|
476 chromaIndexY = min(y / conversionFactor, (int)(*chromaSimMatrix)[chromaIndexX].size()-1);
|
andrew@15
|
477
|
andrew@9
|
478 //was thinking to restrict the y part too, but not working yet
|
andrew@15
|
479 if (chromaIndexY != lastChromaYvalue){
|
andrew@15
|
480
|
andrew@14
|
481 chromaComponent = (*chromaSimMatrix)[chromaIndexX][chromaIndexY];
|
andrew@15
|
482 lastChromaYvalue = chromaIndexY;
|
andrew@15
|
483 chromaContribution = chromaProportion * chromaComponent;
|
andrew@14
|
484 }
|
andrew@5
|
485
|
andrew@5
|
486 distance = (*firstEnergyVector)[x] * (*secondEnergyVector)[y];//energy similarity
|
andrew@14
|
487 distance *= energyProportion;
|
andrew@14
|
488 distance += chromaContribution;
|
andrew@5
|
489
|
andrew@15
|
490 distance = chromaComponent;
|
andrew@5
|
491
|
andrew@5
|
492 d.push_back( distance);
|
andrew@5
|
493 } //end for y
|
andrew@5
|
494
|
andrew@5
|
495 (*simMatrix).push_back(d);
|
andrew@5
|
496
|
andrew@5
|
497 }//end for x
|
andrew@5
|
498
|
andrew@5
|
499
|
andrew@5
|
500 printf("..part JOINT sim size: %i, height: %i \n", (int) (*simMatrix).size(), (int) (*simMatrix)[0].size());
|
andrew@5
|
501
|
andrew@5
|
502 }//end self sim
|
andrew@5
|
503
|
andrew@5
|
504
|
andrew@5
|
505
|
andrew@5
|
506
|
andrew@5
|
507
|
andrew@5
|
508 void TimeWarp::calculatePartAlignmentMatrix(int endIndexX, int endIndexY, DoubleMatrix* alignmentMatrix, DoubleMatrix* simMatrix){
|
andrew@5
|
509 printf("starting PART Alignment calculation : sim matrix size %i %i\n", (int)(*simMatrix).size(), (int)(*simMatrix)[0].size());
|
andrew@4
|
510 //initialise alignment
|
andrew@8
|
511 alignmentMatrix->clear();
|
andrew@8
|
512
|
andrew@4
|
513 DoubleVector d;
|
andrew@5
|
514 d.push_back(getDistanceFromMatrix(0,0, simMatrix));
|
andrew@5
|
515 printf("first distance\n");
|
andrew@4
|
516 (*alignmentMatrix).push_back(d);
|
andrew@4
|
517
|
andrew@4
|
518 bool chromaCalculated = false;
|
andrew@4
|
519 bool secondCalculated = false;
|
andrew@4
|
520
|
andrew@4
|
521 while (!chromaCalculated || !secondCalculated) {
|
andrew@4
|
522
|
andrew@4
|
523 if (!chromaCalculated)
|
andrew@5
|
524 chromaCalculated = extendRestrictedAlignmentAlong(endIndexX, alignmentMatrix, simMatrix);
|
andrew@4
|
525
|
andrew@4
|
526 if (!secondCalculated)
|
andrew@5
|
527 secondCalculated = extendRestrictedAlignmentUp(endIndexY, alignmentMatrix, simMatrix);
|
andrew@4
|
528
|
andrew@4
|
529 }
|
andrew@5
|
530 printf("PART Alignment matrix calculated, size %i by %i\n", (int) (*alignmentMatrix).size() , (int) (*alignmentMatrix)[0].size());
|
andrew@4
|
531 }
|
andrew@4
|
532
|
andrew@4
|
533
|
andrew@4
|
534
|
andrew@4
|
535
|
andrew@4
|
536
|
andrew@4
|
537
|
andrew@5
|
538 bool TimeWarp::extendRestrictedAlignmentUp(int endIndexY, DoubleMatrix *alignmentMatrix, DoubleMatrix* simMatrix){
|
andrew@4
|
539 //adds one more value to all the columns after startX
|
andrew@5
|
540
|
andrew@4
|
541 DoubleVector d;
|
andrew@4
|
542 d = (*alignmentMatrix)[0];//alignmentMatrix[0];//
|
andrew@4
|
543 int heightSize = d.size();
|
andrew@4
|
544 if (heightSize < endIndexY){
|
andrew@5
|
545 //would change 0 to startX if we varied this
|
andrew@5
|
546 for (int i = 0;i < (*alignmentMatrix).size();i++){//was < (*alignmentMatrix).size()
|
andrew@5
|
547 // printf("restruicted up %i, %i\n", i, heightSize);
|
andrew@5
|
548 double value = getDistanceFromMatrix(i, heightSize, simMatrix);
|
andrew@5
|
549 value += getMinimumFromMatrix(i, heightSize, value, alignmentMatrix);//min values 0
|
andrew@4
|
550 (*alignmentMatrix)[i].push_back(value);//
|
andrew@4
|
551 }
|
andrew@4
|
552 }
|
andrew@4
|
553 if ((*alignmentMatrix)[0].size() == endIndexY)
|
andrew@4
|
554 return true;
|
andrew@4
|
555 else
|
andrew@4
|
556 return false;
|
andrew@4
|
557
|
andrew@4
|
558 }
|
andrew@4
|
559
|
andrew@4
|
560
|
andrew@5
|
561 bool TimeWarp::extendRestrictedAlignmentAlong(int endIndexX, DoubleMatrix* alignmentMatrix, DoubleMatrix* simMatrix){
|
andrew@4
|
562 DoubleVector d;
|
andrew@4
|
563 //firstMatrix.size()
|
andrew@4
|
564 int widthSize = (*alignmentMatrix).size();
|
andrew@4
|
565 if (widthSize < endIndexX){//firstMatrix.size()
|
andrew@5
|
566 // printf("restruicted along %i\n", widthSize);
|
andrew@4
|
567 //then we can extend along
|
andrew@5
|
568 double value = getDistanceFromMatrix(widthSize, 0, simMatrix);
|
andrew@5
|
569 value += getMinimumFromMatrix(widthSize, 0, value, alignmentMatrix);
|
andrew@4
|
570
|
andrew@4
|
571 d.push_back(value);
|
andrew@4
|
572 (*alignmentMatrix).push_back(d);
|
andrew@4
|
573
|
andrew@4
|
574 for (int j = 1;j < (*alignmentMatrix)[widthSize - 1].size();j++){
|
andrew@5
|
575 // printf("restruicted along %i %i\n", widthSize, j);
|
andrew@5
|
576 value = getDistanceFromMatrix(widthSize, j, simMatrix);
|
andrew@5
|
577 value += getMinimumFromMatrix(widthSize, j, value, alignmentMatrix);
|
andrew@4
|
578 (*alignmentMatrix)[widthSize].push_back(value);
|
andrew@4
|
579 }
|
andrew@4
|
580
|
andrew@4
|
581 }
|
andrew@4
|
582
|
andrew@4
|
583 if ((*alignmentMatrix).size() == endIndexX)
|
andrew@4
|
584 return true;
|
andrew@4
|
585 else
|
andrew@4
|
586 return false;
|
andrew@4
|
587
|
andrew@4
|
588 }
|
andrew@4
|
589
|
andrew@4
|
590
|
andrew@5
|
591
|
andrew@5
|
592 void TimeWarp::calculateMinimumAlignmentPath(DoubleMatrix* alignmentMatrix, IntMatrix* backPath, bool pickMinimumFlag){
|
andrew@0
|
593 //this requires one pass of the DTW algorithm and then works backwards from (N,M)
|
andrew@0
|
594 //to find the optimal path to (0,0), where N and M are the lengths of the two chromoVectors respectively
|
andrew@1
|
595
|
andrew@5
|
596 (*backPath).clear();
|
andrew@0
|
597
|
andrew@5
|
598 // printf("Finding minimum Path %i vs sim size %i\n", (int)chromaMatrix.size(), (int)similarityMatrix.size() );
|
andrew@5
|
599
|
andrew@5
|
600 printf("Finding minimum Path of alignment matrix %i vs sim size %i\n", (int)(*alignmentMatrix).size(), (int)(*alignmentMatrix)[0].size() );
|
andrew@5
|
601 // printf("compares to sim %ix%i\n", similarityMatrix.size()-1, similarityMatrix[0].size()-1);
|
andrew@0
|
602 IntVector v;
|
andrew@5
|
603 // v.push_back(similarityMatrix.size()-1);//chromaMatrix.size()-1 - old way
|
andrew@5
|
604
|
andrew@5
|
605 //here we start at the corner of the alignment matrix
|
andrew@5
|
606 //could change to greedy? - i.e. the best / minimum of the last vector
|
andrew@5
|
607 v.push_back((*alignmentMatrix).size()-1);
|
andrew@5
|
608 (*backPath).push_back(v);
|
andrew@0
|
609 v.clear();
|
andrew@5
|
610 //v.push_back(similarityMatrix[0].size()-1);//secondMatrix
|
andrew@5
|
611 int endIndex = (*alignmentMatrix)[(*alignmentMatrix).size()-1].size()-1;
|
andrew@5
|
612 if (pickMinimumFlag){
|
andrew@5
|
613 endIndex = getMinimumIndexOfColumnFromMatrix((int)(*alignmentMatrix).size()-1, alignmentMatrix);
|
andrew@5
|
614 //i.e. get index of minimum in the last column
|
andrew@5
|
615 }
|
andrew@5
|
616 v.push_back(endIndex);//and the y size
|
andrew@5
|
617 printf("CALUCLATE MINIMUM PUSHED BACK %i\n", endIndex);
|
andrew@5
|
618
|
andrew@5
|
619
|
andrew@5
|
620 (*backPath).push_back(v);
|
andrew@0
|
621 //so now backwards path[0][0] = size(chroma) and path[1][0] = size(secondMatrix)
|
andrew@5
|
622 printf("backwards path initialised to %i : %i \n", (*backPath)[0][0], (*backPath)[1][0]);
|
andrew@0
|
623
|
andrew@0
|
624
|
andrew@0
|
625 int indexOfBackwardsPath = 0;
|
andrew@5
|
626 while (!findPreviousMinimumInBackwardsPath(alignmentMatrix, backPath)) {
|
andrew@0
|
627 indexOfBackwardsPath++;
|
andrew@5
|
628 // printf("backwards path index %i: path: %i : %i \n", indexOfBackwardsPath, backwardsAlignmentPath[0][indexOfBackwardsPath], backwardsAlignmentPath[1][indexOfBackwardsPath]);
|
andrew@0
|
629
|
andrew@0
|
630 }
|
andrew@5
|
631 printf("final index of backwards path is %i and i is %i \n", (int) (*backPath)[0].size()-1, indexOfBackwardsPath);
|
andrew@0
|
632
|
andrew@0
|
633 // backwardsAlignmentIndex = backwardsAlignmentPath[0].size()-1;//remember that this goes backwards!
|
andrew@0
|
634
|
andrew@0
|
635 }
|
andrew@0
|
636
|
andrew@0
|
637
|
andrew@5
|
638
|
andrew@5
|
639 bool TimeWarp::findPreviousMinimumInBackwardsPath(DoubleMatrix* alignmentMatrix, IntMatrix* backPath){
|
andrew@5
|
640 int chromaPosition, secondPosition;
|
andrew@5
|
641 int i,j;
|
andrew@5
|
642 i = (*backPath)[0][(*backPath)[0].size()-1];
|
andrew@5
|
643 j = (*backPath)[1][(*backPath)[1].size()-1];
|
andrew@5
|
644 //printf("FIND PREVIOUS MINIMUM %i %i \n", i, j);
|
andrew@5
|
645
|
andrew@5
|
646 double newMinimum;
|
andrew@5
|
647 double *ptr;
|
andrew@5
|
648 ptr = &newMinimum;
|
andrew@5
|
649 newMinimum = (*alignmentMatrix)[i][j];
|
andrew@5
|
650 DoubleVector d;
|
andrew@5
|
651
|
andrew@5
|
652
|
andrew@5
|
653 bool finishedAligning = true;
|
andrew@5
|
654
|
andrew@5
|
655 if (i > 0){
|
andrew@5
|
656 if (testForNewAlignmentMinimum(ptr, i-1, j, alignmentMatrix)){
|
andrew@5
|
657 chromaPosition = i-1;
|
andrew@5
|
658 secondPosition = j;
|
andrew@5
|
659 finishedAligning = false;
|
andrew@5
|
660 }
|
andrew@5
|
661
|
andrew@5
|
662 if (j>0 && testForNewAlignmentMinimum(ptr, i-1, j-1, alignmentMatrix)){
|
andrew@5
|
663 chromaPosition = i-1;
|
andrew@5
|
664 secondPosition = j-1;
|
andrew@5
|
665 finishedAligning = false;
|
andrew@5
|
666 }
|
andrew@5
|
667 }
|
andrew@5
|
668
|
andrew@5
|
669 if (j > 0 && testForNewAlignmentMinimum(ptr, i, j-1, alignmentMatrix)){
|
andrew@5
|
670 chromaPosition = i;
|
andrew@5
|
671 secondPosition = j-1;
|
andrew@5
|
672 //newMinimum = alignmentMeasureMatrix[chromaPosition][secondPosition];
|
andrew@5
|
673 finishedAligning = false;
|
andrew@5
|
674 }
|
andrew@5
|
675
|
andrew@5
|
676 if (!finishedAligning){
|
andrew@5
|
677 (*backPath)[0].push_back(chromaPosition);
|
andrew@5
|
678 (*backPath)[1].push_back(secondPosition);
|
andrew@5
|
679 }
|
andrew@5
|
680
|
andrew@5
|
681 return finishedAligning;
|
andrew@5
|
682
|
andrew@5
|
683 }
|
andrew@5
|
684
|
andrew@5
|
685
|
andrew@5
|
686
|
andrew@5
|
687 bool TimeWarp::testForNewAlignmentMinimum(double *previousMinimum, int i, int j, DoubleMatrix* alignmentMatrix){
|
andrew@5
|
688 bool newMinimumFound = false;
|
andrew@5
|
689 if ((*alignmentMatrix)[i][j] < *previousMinimum){
|
andrew@5
|
690 *previousMinimum = (*alignmentMatrix)[i][j];
|
andrew@5
|
691 newMinimumFound = true;
|
andrew@5
|
692 }
|
andrew@5
|
693
|
andrew@5
|
694 return newMinimumFound;
|
andrew@5
|
695 }
|
andrew@5
|
696
|
andrew@5
|
697
|
andrew@5
|
698
|
andrew@5
|
699
|
andrew@5
|
700
|
andrew@8
|
701 void TimeWarp::printBackwardsPath(int startIndex, int endIndex, const IntMatrix* backPath){
|
andrew@5
|
702 if (endIndex <= (*backPath)[0].size()){
|
andrew@8
|
703 printf("size of path is %i by %i\n", (int) (*backPath).size(), (int) (*backPath)[0].size());
|
andrew@5
|
704 for (int i = startIndex;i < endIndex;i++){
|
andrew@6
|
705 printf("Path[%i]:: %i : %i \n", i, (*backPath)[0][i], (*backPath)[1][i]);
|
andrew@5
|
706 }
|
andrew@5
|
707 }
|
andrew@5
|
708 }
|
andrew@5
|
709
|
andrew@5
|
710
|
andrew@5
|
711 void TimeWarp::extendForwardAlignmentPath(int endX, IntMatrix* backPath, int anchorPointX, int anchorPointY){
|
andrew@5
|
712 //andchor points are the starting index so if we have already done up to
|
andrew@4
|
713 int forwardsIndex = forwardsAlignmentPath.size();
|
andrew@5
|
714 int indexX = (*backPath)[0].size() - 1;
|
andrew@4
|
715
|
andrew@4
|
716 if (forwardsIndex == 0){
|
andrew@4
|
717 printf("initialise forwards path..\n");
|
andrew@4
|
718 IntVector v;
|
andrew@4
|
719
|
andrew@5
|
720 v.push_back((*backPath)[0][indexX]);//chromaMatrix.size()-1
|
andrew@4
|
721 forwardsAlignmentPath.push_back(v);
|
andrew@4
|
722 v.clear();
|
andrew@4
|
723 v.push_back(forwardsAlignmentPath[0][indexX]);//secondMatrix
|
andrew@4
|
724 forwardsAlignmentPath.push_back(v);
|
andrew@4
|
725 indexX--;
|
andrew@5
|
726 printf("FORWARDS PATH STARTED AS %i, %i\n", forwardsAlignmentPath[0][0], forwardsAlignmentPath[0][1]);
|
andrew@5
|
727 }
|
andrew@5
|
728 else{
|
andrew@5
|
729 //forwards path has been started and we need anchor point
|
andrew@5
|
730
|
andrew@4
|
731 }
|
andrew@4
|
732
|
andrew@5
|
733
|
andrew@5
|
734 while ((*backPath)[0][indexX] <= endX){
|
andrew@5
|
735 addNewForwardsPath(indexX, backPath, anchorPointX, anchorPointY);
|
andrew@5
|
736 // printf("Forwards path from index %i:: path %i : %i\n", indexX, forwardsAlignmentPath[0][forwardsIndex], forwardsAlignmentPath[1][forwardsIndex]);
|
andrew@4
|
737 indexX--;
|
andrew@4
|
738 forwardsIndex++;
|
andrew@4
|
739 }
|
andrew@4
|
740
|
andrew@4
|
741 }
|
andrew@4
|
742
|
andrew@5
|
743 void TimeWarp::addNewForwardsPath(int indexX, IntMatrix* backPath, int anchorPointX, int anchorPointY){
|
andrew@5
|
744 //pushes back
|
andrew@5
|
745 if (indexX < (*backPath)[0].size()){
|
andrew@5
|
746 forwardsAlignmentPath[0].push_back((int)(*backPath)[0][indexX]+ anchorPointX);
|
andrew@5
|
747 forwardsAlignmentPath[1].push_back((int)(*backPath)[1][indexX] + anchorPointY);
|
andrew@4
|
748 }
|
andrew@4
|
749 }
|
andrew@4
|
750
|
andrew@4
|
751
|
andrew@4
|
752
|
andrew@5
|
753 void TimeWarp::copyForwardsPathToBackwardsPath(){
|
andrew@5
|
754
|
andrew@5
|
755 backwardsAlignmentPath.clear();
|
andrew@5
|
756
|
andrew@5
|
757 int index = forwardsAlignmentPath[0].size()-1;
|
andrew@5
|
758 printf("COPY FORWARDS INDEX %i\n", index);
|
andrew@5
|
759 IntVector d;
|
andrew@5
|
760 d.push_back(forwardsAlignmentPath[0][index]);
|
andrew@5
|
761 backwardsAlignmentPath.push_back(d);
|
andrew@5
|
762 d.clear();
|
andrew@5
|
763 d.push_back(forwardsAlignmentPath[1][index]);
|
andrew@5
|
764 backwardsAlignmentPath.push_back(d);
|
andrew@5
|
765
|
andrew@5
|
766 while (index > 0){
|
andrew@5
|
767 index--;
|
andrew@5
|
768 // IntVector d;
|
andrew@5
|
769 // d.push_back(forwardsAlignmentPath[0][index]);
|
andrew@5
|
770 // d.push_back(forwardsAlignmentPath[1][index]);
|
andrew@5
|
771 backwardsAlignmentPath[0].push_back(forwardsAlignmentPath[0][index]);
|
andrew@5
|
772 backwardsAlignmentPath[1].push_back(forwardsAlignmentPath[1][index]);
|
andrew@5
|
773 }
|
andrew@5
|
774
|
andrew@5
|
775 }
|
andrew@5
|
776
|
andrew@5
|
777 /*
|
andrew@5
|
778 //DONT NEED THIS
|
andrew@4
|
779 void TimeWarp::calculatePartMinimumAlignmentPath(int startX, int startY, int endX, int endY, DoubleMatrix alignmentMatrix){
|
andrew@4
|
780 //this requires one pass of the DTW algorithm and then works backwards from (N,M)
|
andrew@4
|
781 //to find the optimal path to (0,0), where N and M are the lengths of the two chromoVectors respectively
|
andrew@4
|
782
|
andrew@4
|
783 partBackwardsAlignmentPath.clear();
|
andrew@4
|
784
|
andrew@4
|
785 printf("Finding PART minimum Path %i vs sim size %i\n", (int)chromaMatrix.size(), (int)similarityMatrix.size() );
|
andrew@4
|
786
|
andrew@4
|
787 if (endX < similarityMatrix.size()){
|
andrew@4
|
788 IntVector v;
|
andrew@4
|
789 v.push_back(endX);
|
andrew@4
|
790 partBackwardsAlignmentPath.push_back(v);
|
andrew@4
|
791
|
andrew@4
|
792 v.clear();
|
andrew@4
|
793
|
andrew@4
|
794 if (endY < similarityMatrix[0].size()){
|
andrew@4
|
795 v.push_back(endY);
|
andrew@4
|
796 partBackwardsAlignmentPath.push_back(v);
|
andrew@4
|
797 }
|
andrew@4
|
798 //so now backwards path[0][0] = endX and path[1][0] = endY
|
andrew@4
|
799
|
andrew@4
|
800 printf("PART backwards path %i : %i \n", partBackwardsAlignmentPath[0][0], partBackwardsAlignmentPath[1][0]);
|
andrew@4
|
801 int indexOfPartBackwardsPath = 0;
|
andrew@5
|
802
|
andrew@4
|
803
|
andrew@4
|
804 while (!findPreviousMinimumInBackwardsPath()) {
|
andrew@4
|
805 indexOfBackwardsPath++;
|
andrew@4
|
806 // printf("backwards path %i : %i \n", backwardsAlignmentPath[0][indexOfBackwardsPath], backwardsAlignmentPath[1][indexOfBackwardsPath]);
|
andrew@4
|
807
|
andrew@4
|
808 }
|
andrew@5
|
809
|
andrew@4
|
810 printf("final index of backwards path is %i and i is %i \n", (int) backwardsAlignmentPath[0].size()-1, indexOfPartBackwardsPath);
|
andrew@4
|
811 }//end if endX within size
|
andrew@4
|
812
|
andrew@4
|
813 // backwardsAlignmentIndex = backwardsAlignmentPath[0].size()-1;//remember that this goes backwards!
|
andrew@4
|
814
|
andrew@4
|
815 }
|
andrew@4
|
816
|
andrew@5
|
817 */
|
andrew@0
|
818
|
andrew@0
|
819
|
andrew@3
|
820 int TimeWarp::findMinimumOfVector(DoubleVector *d){
|
andrew@0
|
821 int minimumIndex = 0;
|
andrew@0
|
822 double minimumValue = (*d)[0];
|
andrew@0
|
823 for (int i = 0;i < d->size();i++){
|
andrew@0
|
824 if ((*d)[i] < minimumValue){
|
andrew@0
|
825 minimumIndex = i;
|
andrew@0
|
826 minimumValue = (*d)[i];
|
andrew@0
|
827 }
|
andrew@0
|
828 }
|
andrew@0
|
829
|
andrew@0
|
830 return minimumIndex;
|
andrew@0
|
831 }
|
andrew@0
|
832
|
andrew@5
|
833
|
andrew@5
|
834
|
andrew@5
|
835 int TimeWarp::findMinimumOfMatrixColumn(DoubleMatrix d, int column){
|
andrew@5
|
836 int minimumIndex = 0;
|
andrew@5
|
837
|
andrew@5
|
838 double minimumValue = d[column][0];
|
andrew@5
|
839 for (int i = 0;i < d.size();i++){
|
andrew@5
|
840 if (d[column][i] < minimumValue){
|
andrew@5
|
841 minimumIndex = i;
|
andrew@5
|
842 minimumValue = d[column][i];
|
andrew@5
|
843 }
|
andrew@5
|
844 }
|
andrew@5
|
845
|
andrew@5
|
846 return minimumIndex;
|
andrew@5
|
847 }
|
andrew@5
|
848
|
andrew@5
|
849
|
andrew@5
|
850
|
andrew@3
|
851 double TimeWarp::getDistance(int i, int j){
|
andrew@0
|
852 return (1 - similarityMatrix[i][j]);
|
andrew@0
|
853 }
|
andrew@0
|
854
|
andrew@3
|
855 double TimeWarp::getMinimum(int i, int j, float newValue){
|
andrew@0
|
856 double minimumValue = 0;
|
andrew@0
|
857
|
andrew@0
|
858 if (i > 0){
|
andrew@0
|
859 minimumValue = alignmentMeasureMatrix[i-1][j];
|
andrew@0
|
860 if (j > 0){
|
andrew@0
|
861 minimumValue = min(minimumValue, alignmentMeasureMatrix[i-1][j-1] + newValue ) ;//penalises diagonal by 2
|
andrew@0
|
862 minimumValue = min(minimumValue, alignmentMeasureMatrix[i][j-1]);
|
andrew@0
|
863 }
|
andrew@0
|
864 }
|
andrew@0
|
865 else{//i.e. i == 0
|
andrew@0
|
866 if (j > 0)
|
andrew@0
|
867 minimumValue = alignmentMeasureMatrix[i][j-1];
|
andrew@0
|
868 }
|
andrew@0
|
869
|
andrew@0
|
870 return minimumValue;
|
andrew@0
|
871 }
|
andrew@0
|
872
|
andrew@4
|
873
|
andrew@5
|
874
|
andrew@5
|
875
|
andrew@5
|
876 double TimeWarp::getDistanceFromMatrix(int i, int j, DoubleMatrix* simMatrix){
|
andrew@5
|
877 // return (1 - (*simMatrix)[i][j]);
|
andrew@5
|
878
|
andrew@5
|
879 if (i < (*simMatrix).size() && j < (*simMatrix)[i].size()){
|
andrew@5
|
880 // printf("distance returning %i% i : %f\n", i, j, (1 - (*simMatrix)[i][j]) );
|
andrew@5
|
881 return (1 - (*simMatrix)[i][j]);
|
andrew@5
|
882 }
|
andrew@5
|
883 else{
|
andrew@5
|
884 printf("ERROR IN MATRIX CALCULATION - OUT OF LIMITS! %i, %i, size of sim matrix: %ix%i\n", i, j, (int)(*simMatrix).size(), (int)(*simMatrix)[i].size());
|
andrew@5
|
885 return 0;
|
andrew@5
|
886 }
|
andrew@5
|
887
|
andrew@5
|
888 }
|
andrew@5
|
889
|
andrew@5
|
890 double TimeWarp::getMinimumFromMatrix(int i, int j, float newValue, DoubleMatrix* alignMatrix){
|
andrew@5
|
891 double minimumValue = 0;
|
andrew@5
|
892 if (i > 0){
|
andrew@5
|
893 minimumValue = (*alignMatrix)[i-1][j];
|
andrew@5
|
894 if (j > 0){
|
andrew@15
|
895 //minimumValue = min(minimumValue, (*alignMatrix)[i-1][j-1] + newValue ) ;//penalises diagonal by 2
|
andrew@15
|
896 minimumValue = min(minimumValue, (*alignMatrix)[i-1][j-1] ) ;//favours diagonal
|
andrew@5
|
897 minimumValue = min(minimumValue, (*alignMatrix)[i][j-1]);
|
andrew@5
|
898 }
|
andrew@5
|
899 }
|
andrew@5
|
900 else{//i.e. i == 0
|
andrew@5
|
901 if (j > 0)
|
andrew@5
|
902 minimumValue = (*alignMatrix)[i][j-1];
|
andrew@5
|
903 }
|
andrew@5
|
904 return minimumValue;
|
andrew@5
|
905 }
|
andrew@5
|
906
|
andrew@5
|
907
|
andrew@5
|
908
|
andrew@5
|
909
|
andrew@5
|
910 int TimeWarp::getMinimumIndexOfColumnFromMatrix(int i, DoubleMatrix* matrix){
|
andrew@5
|
911 int minimumIndex = 0;
|
andrew@5
|
912 double minimumValue;
|
andrew@5
|
913 if (i >= 0 && i < (*matrix).size()){
|
andrew@5
|
914 int height = (*matrix)[i].size();
|
andrew@5
|
915 int j = 0;
|
andrew@5
|
916 minimumValue = (*matrix)[i][j];
|
andrew@5
|
917 while (j < height){
|
andrew@5
|
918 if ((*matrix)[i][j] < minimumValue){
|
andrew@5
|
919 minimumIndex = j;
|
andrew@5
|
920 minimumValue = (*matrix)[i][j];
|
andrew@5
|
921 }//end if new value
|
andrew@5
|
922 j++;
|
andrew@5
|
923 }
|
andrew@5
|
924 }else{
|
andrew@5
|
925 printf("ERROR FROM GETTING MINIMIM!!! - zero - out of bounds, received %i and size is %i\n", i, (*matrix).size());
|
andrew@5
|
926 }
|
andrew@5
|
927 return minimumIndex;
|
andrew@5
|
928 }
|
andrew@5
|
929
|
andrew@5
|
930
|
andrew@5
|
931
|
andrew@4
|
932 double TimeWarp::getRestrictedMinimum(int i, int j, float newValue, int minX, int minY){
|
andrew@4
|
933 double minimumValue = 0;
|
andrew@4
|
934
|
andrew@4
|
935 if (i > minX){
|
andrew@4
|
936 minimumValue = alignmentMeasureMatrix[i-1][j];
|
andrew@4
|
937 if (j > minY){
|
andrew@4
|
938 minimumValue = min(minimumValue, alignmentMeasureMatrix[i-1][j-1] + newValue ) ;//penalises diagonal by 2
|
andrew@4
|
939 minimumValue = min(minimumValue, alignmentMeasureMatrix[i][j-1]);
|
andrew@4
|
940 }
|
andrew@4
|
941 }
|
andrew@4
|
942 else{//i.e. i == 0
|
andrew@4
|
943 if (j > minY)
|
andrew@4
|
944 minimumValue = alignmentMeasureMatrix[i][j-1];
|
andrew@4
|
945 }
|
andrew@4
|
946
|
andrew@4
|
947 return minimumValue;
|
andrew@4
|
948 }
|
andrew@4
|
949
|
andrew@4
|
950
|
andrew@4
|
951
|
andrew@4
|
952 //--------------part backwards alignment------------------------
|
andrew@5
|
953 /*
|
andrew@4
|
954 bool TimeWarp::findPreviousMinimumInPartBackwardsPath(){
|
andrew@4
|
955
|
andrew@4
|
956 int firstPosition, secondPosition;
|
andrew@4
|
957 int i,j;
|
andrew@4
|
958 i = backwardsAlignmentPath[0][backwardsAlignmentPath[0].size()-1];
|
andrew@4
|
959 j = backwardsAlignmentPath[1][backwardsAlignmentPath[1].size()-1];
|
andrew@4
|
960
|
andrew@4
|
961 double newMinimum;
|
andrew@4
|
962 double *ptr;
|
andrew@4
|
963 ptr = &newMinimum;
|
andrew@4
|
964 newMinimum = alignmentMeasureMatrix[i][j];
|
andrew@4
|
965 DoubleVector d;
|
andrew@4
|
966
|
andrew@4
|
967
|
andrew@4
|
968 bool finishedAligning = true;
|
andrew@4
|
969
|
andrew@4
|
970 if (i > 0){
|
andrew@4
|
971 if (testForNewAlignmentMinimum(ptr, i-1, j)){
|
andrew@4
|
972 firstPosition = i-1;
|
andrew@4
|
973 secondPosition = j;
|
andrew@4
|
974 finishedAligning = false;
|
andrew@4
|
975 }
|
andrew@4
|
976
|
andrew@4
|
977 if (j>0 && testForNewAlignmentMinimum(ptr, i-1, j-1)){
|
andrew@4
|
978 firstPosition = i-1;
|
andrew@4
|
979 secondPosition = j-1;
|
andrew@4
|
980 finishedAligning = false;
|
andrew@4
|
981 }
|
andrew@4
|
982 }
|
andrew@4
|
983
|
andrew@4
|
984 if (j > 0 && testForNewAlignmentMinimum(ptr, i, j-1)){
|
andrew@4
|
985 firstPosition = i;
|
andrew@4
|
986 secondPosition = j-1;
|
andrew@4
|
987 //newMinimum = alignmentMeasureMatrix[chromaPosition][secondPosition];
|
andrew@4
|
988 finishedAligning = false;
|
andrew@4
|
989 }
|
andrew@4
|
990
|
andrew@4
|
991 if (!finishedAligning){
|
andrew@4
|
992 backwardsAlignmentPath[0].push_back(firstPosition);
|
andrew@4
|
993 backwardsAlignmentPath[1].push_back(secondPosition);
|
andrew@4
|
994 }
|
andrew@4
|
995
|
andrew@4
|
996 return finishedAligning;
|
andrew@4
|
997
|
andrew@4
|
998 }
|
andrew@4
|
999
|
andrew@5
|
1000 */
|
andrew@4
|
1001
|
andrew@4
|
1002
|
andrew@4
|
1003
|
andrew@4
|
1004
|
andrew@0
|
1005 //--------------------------------------------------------------
|
andrew@0
|
1006 /*
|
andrew@3
|
1007 void TimeWarp::update(){
|
andrew@0
|
1008 textString = "energy index [";
|
andrew@0
|
1009 textString += ofToString(xIndex);
|
andrew@0
|
1010 textString += "] = ";
|
andrew@0
|
1011 textString += ofToString(energy[xIndex]);
|
andrew@0
|
1012
|
andrew@0
|
1013 chordString = "Chord : ";
|
andrew@0
|
1014 chordString += ofToString(rootChord[currentPlayingFrame/CHROMA_CONVERSION_FACTOR]);
|
andrew@0
|
1015
|
andrew@0
|
1016 if (firstAudioFilePlaying){
|
andrew@0
|
1017 audioPosition = (*playingAudio).getPosition() * firstEnergyVector.size();
|
andrew@0
|
1018 updateAlignmentPathIndex(0);
|
andrew@0
|
1019 }
|
andrew@0
|
1020 else {
|
andrew@0
|
1021 audioPosition = (*playingAudio).getPosition() * secondEnergyVector.size();
|
andrew@0
|
1022 updateAlignmentPathIndex(1);
|
andrew@0
|
1023 }
|
andrew@0
|
1024
|
andrew@0
|
1025 //if(!audioPaused)
|
andrew@0
|
1026 //printScoreForRow(audioPosition/CHROMA_CONVERSION_FACTOR, (audioPosition/CHROMA_CONVERSION_FACTOR)+10);
|
andrew@0
|
1027
|
andrew@0
|
1028 //the position in number of frames
|
andrew@0
|
1029 //totalNumberOfFrames was used but is the most recently loaded file length
|
andrew@0
|
1030
|
andrew@0
|
1031 currentPlayingFrame = audioPosition;
|
andrew@0
|
1032 audioPosition = (int) audioPosition % scrollWidth ;
|
andrew@0
|
1033 audioPosition /= scrollWidth;
|
andrew@0
|
1034
|
andrew@0
|
1035 ofSoundUpdate();
|
andrew@0
|
1036
|
andrew@0
|
1037
|
andrew@0
|
1038 }
|
andrew@0
|
1039 */
|
andrew@0
|
1040
|
andrew@0
|
1041 /*
|
andrew@3
|
1042 void TimeWarp::updateAlignmentPathIndex(int identifier){
|
andrew@0
|
1043
|
andrew@0
|
1044 // int chromaPosition = audioPosition/CHROMA_CONVERSION_FACTOR;
|
andrew@0
|
1045
|
andrew@0
|
1046 while (backwardsAlignmentPath[identifier][backwardsAlignmentIndex] < chromaPosition)
|
andrew@0
|
1047 {
|
andrew@0
|
1048 backwardsAlignmentIndex--;
|
andrew@0
|
1049 }
|
andrew@0
|
1050
|
andrew@0
|
1051 }
|
andrew@0
|
1052 */
|
andrew@0
|
1053
|
andrew@0
|
1054 //--------------------------------------------------------------
|
andrew@0
|
1055 /*
|
andrew@3
|
1056 void TimeWarp::draw(){
|
andrew@0
|
1057
|
andrew@0
|
1058 if (drawSimilarity)
|
andrew@0
|
1059 drawSimilarityMatrix();
|
andrew@0
|
1060 else
|
andrew@0
|
1061 drawChromoGram();
|
andrew@0
|
1062
|
andrew@0
|
1063
|
andrew@0
|
1064 }
|
andrew@0
|
1065
|
andrew@0
|
1066
|
andrew@3
|
1067 void TimeWarp::drawEnergyVectorFromPointer(DoubleVector* energyVec){
|
andrew@0
|
1068
|
andrew@0
|
1069 float screenHeight = ofGetHeight() ;
|
andrew@0
|
1070 float screenWidth = ofGetWidth();
|
andrew@0
|
1071 float heightFactor = 8;
|
andrew@0
|
1072 int i, j, startingFrame;
|
andrew@0
|
1073 startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in
|
andrew@0
|
1074 startingFrame *= scrollWidth;
|
andrew@0
|
1075
|
andrew@0
|
1076 for (i = 0; i < scrollWidth - 1; i++){
|
andrew@0
|
1077 j = i + startingFrame;
|
andrew@0
|
1078 ofLine(i*screenWidth/scrollWidth, screenHeight - ((*energyVec)[j]*screenHeight/heightFactor),
|
andrew@0
|
1079 screenWidth*(i+1)/scrollWidth, screenHeight - ((*energyVec)[j+1]*screenHeight/heightFactor));
|
andrew@0
|
1080
|
andrew@0
|
1081 }
|
andrew@0
|
1082 }
|
andrew@0
|
1083
|
andrew@3
|
1084 void TimeWarp::drawSpectralDifference(DoubleMatrix* dMatrix){
|
andrew@0
|
1085 if ((*dMatrix).size()>0){
|
andrew@0
|
1086
|
andrew@0
|
1087 float screenHeight = ofGetHeight() ;
|
andrew@0
|
1088 float screenWidth = ofGetWidth();
|
andrew@0
|
1089 float heightFactor = 8;
|
andrew@0
|
1090 double difference;
|
andrew@0
|
1091 int i, j, startingFrame;
|
andrew@0
|
1092 startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in
|
andrew@0
|
1093 startingFrame *= scrollWidth;//starting frame in terms of energy frames
|
andrew@0
|
1094 startingFrame /= CHROMA_CONVERSION_FACTOR; //in terms of chroma frames
|
andrew@0
|
1095
|
andrew@0
|
1096
|
andrew@0
|
1097 for (i = 1; i < chromoLength; i++){//changed to add 1
|
andrew@0
|
1098 j = i + startingFrame;
|
andrew@0
|
1099 for (int y = 0;y < 12;y++){
|
andrew@0
|
1100 difference = (*dMatrix)[j][11-y] - (*dMatrix)[j-1][11-y];
|
andrew@0
|
1101 if (difference < 0)
|
andrew@0
|
1102 difference = 0;//half wave rectify
|
andrew@0
|
1103
|
andrew@0
|
1104 ofSetColor(0,0,255 * difference);//, 0;
|
andrew@0
|
1105 ofRect(i*screenWidth/chromoLength,y*screenHeight/12,screenWidth/chromoLength,screenHeight/12);
|
andrew@0
|
1106 }//end y
|
andrew@0
|
1107 }//end i
|
andrew@0
|
1108
|
andrew@0
|
1109 }///end if matrix has content
|
andrew@0
|
1110 else{
|
andrew@0
|
1111 printf("Error - please load audio first");
|
andrew@0
|
1112 }
|
andrew@0
|
1113
|
andrew@0
|
1114 }
|
andrew@0
|
1115
|
andrew@0
|
1116
|
andrew@3
|
1117 void TimeWarp::drawChromoGram(){
|
andrew@0
|
1118
|
andrew@0
|
1119 DoubleMatrix* dptr;
|
andrew@0
|
1120 DoubleVector* eptr;
|
andrew@0
|
1121 string whichFileString;
|
andrew@0
|
1122
|
andrew@0
|
1123 if (drawSecondMatrix){
|
andrew@0
|
1124
|
andrew@0
|
1125 dptr = &secondMatrix;
|
andrew@0
|
1126
|
andrew@0
|
1127 eptr = &secondEnergyVector;
|
andrew@0
|
1128
|
andrew@0
|
1129 whichFileString = "second file";
|
andrew@0
|
1130
|
andrew@0
|
1131 }else {
|
andrew@0
|
1132
|
andrew@0
|
1133 dptr = &chromaMatrix;
|
andrew@0
|
1134 eptr = &firstEnergyVector;
|
andrew@0
|
1135 whichFileString = "first file";
|
andrew@0
|
1136 }
|
andrew@0
|
1137
|
andrew@0
|
1138
|
andrew@0
|
1139
|
andrew@0
|
1140 if (drawSpectralDifferenceFunction)
|
andrew@0
|
1141 drawSpectralDifference(dptr);
|
andrew@0
|
1142 else
|
andrew@0
|
1143 drawDoubleMatrix(dptr);
|
andrew@0
|
1144
|
andrew@0
|
1145 ofSetColor(0xFF6666);
|
andrew@0
|
1146 drawEnergyVectorFromPointer(eptr);
|
andrew@0
|
1147
|
andrew@0
|
1148 ofDrawBitmapString(textString,80,480);
|
andrew@0
|
1149
|
andrew@0
|
1150
|
andrew@0
|
1151 ofSetColor(0xFFFFFF);
|
andrew@0
|
1152 ofLine(audioPosition*width, 0, audioPosition*width, height);
|
andrew@0
|
1153
|
andrew@0
|
1154
|
andrew@0
|
1155 ofDrawBitmapString(chordString,80,580);
|
andrew@0
|
1156
|
andrew@0
|
1157 ofDrawBitmapString(soundFileName,80,480);
|
andrew@0
|
1158
|
andrew@0
|
1159 ofDrawBitmapString(whichFileString,80,80);
|
andrew@0
|
1160
|
andrew@0
|
1161 }
|
andrew@0
|
1162
|
andrew@3
|
1163 void TimeWarp::drawDoubleMatrix(DoubleMatrix* dMatrix){
|
andrew@0
|
1164 if ((*dMatrix).size()>0){
|
andrew@0
|
1165
|
andrew@0
|
1166 float screenHeight = ofGetHeight() ;
|
andrew@0
|
1167 float screenWidth = ofGetWidth();
|
andrew@0
|
1168 float heightFactor = 8;
|
andrew@0
|
1169 int i, j, startingFrame;
|
andrew@0
|
1170 startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in
|
andrew@0
|
1171 startingFrame *= scrollWidth;//starting frame in terms of energy frames
|
andrew@0
|
1172 startingFrame /= CHROMA_CONVERSION_FACTOR; //in terms of chroma frames
|
andrew@0
|
1173
|
andrew@0
|
1174 float chromoLength = scrollWidth/CHROMA_CONVERSION_FACTOR;
|
andrew@0
|
1175 for (i = 0; i < chromoLength; i++){
|
andrew@0
|
1176 j = i + startingFrame;
|
andrew@0
|
1177 for (int y = 0;y < 12;y++){
|
andrew@0
|
1178 ofSetColor(0,0,255 * (*dMatrix)[j][11-y]);//, 0;
|
andrew@0
|
1179 ofRect(i*screenWidth/chromoLength,y*screenHeight/12,screenWidth/chromoLength,screenHeight/12);
|
andrew@0
|
1180 }//end y
|
andrew@0
|
1181 }//end i
|
andrew@0
|
1182
|
andrew@0
|
1183 }///end if matrix has content
|
andrew@0
|
1184 else{
|
andrew@0
|
1185 printf("Error - please load audio first");
|
andrew@0
|
1186 }
|
andrew@0
|
1187
|
andrew@0
|
1188
|
andrew@0
|
1189 }
|
andrew@0
|
1190
|
andrew@0
|
1191
|
andrew@3
|
1192 void TimeWarp::drawSimilarityMatrix(){
|
andrew@0
|
1193
|
andrew@0
|
1194 int simHeight = (similarityMatrix[0]).size();
|
andrew@0
|
1195 int simWidth = similarityMatrix.size();
|
andrew@0
|
1196
|
andrew@0
|
1197 int sizeOfMatrix = chromaMatrix.size();
|
andrew@0
|
1198 int sizeOfSecondMatrix = secondMatrix.size();
|
andrew@0
|
1199
|
andrew@0
|
1200 int startingXframe = backwardsAlignmentPath[0][backwardsAlignmentIndex] / (scrollWidth/CHROMA_CONVERSION_FACTOR);
|
andrew@0
|
1201 int startingYframe = backwardsAlignmentPath[1][backwardsAlignmentIndex] / (scrollWidth/CHROMA_CONVERSION_FACTOR);
|
andrew@0
|
1202
|
andrew@0
|
1203 int startingFrame = findStartWidthFrame();
|
andrew@0
|
1204 startingFrame = numberOfScrollWidthsForFirstFile * scrollWidth/CHROMA_CONVERSION_FACTOR;
|
andrew@0
|
1205
|
andrew@0
|
1206 startingXframe = startingXframe * scrollWidth/CHROMA_CONVERSION_FACTOR;
|
andrew@0
|
1207 startingYframe = startingYframe * scrollWidth/CHROMA_CONVERSION_FACTOR;
|
andrew@0
|
1208 //need to fix for second file too
|
andrew@0
|
1209
|
andrew@0
|
1210 int *indexOfAlignmentPathTested;
|
andrew@0
|
1211 int lengthOfPath = backwardsAlignmentPath[0].size()-1;
|
andrew@0
|
1212 indexOfAlignmentPathTested = &lengthOfPath;
|
andrew@0
|
1213
|
andrew@0
|
1214 int xcoord;
|
andrew@0
|
1215 for (int x = 0;x < screenWidth;x++)
|
andrew@0
|
1216 {
|
andrew@0
|
1217 for (int y =0;y < screenHeight;y++){
|
andrew@0
|
1218
|
andrew@0
|
1219 xcoord = (x / screenWidth) * chromoLength;//was simWidth
|
andrew@0
|
1220 //xcoord += startingFrame;
|
andrew@0
|
1221 xcoord += startingXframe;
|
andrew@0
|
1222
|
andrew@0
|
1223 int ycoord = y * chromoLength/ screenHeight;
|
andrew@0
|
1224 //ycoord += startingFrame;
|
andrew@0
|
1225 ycoord += startingYframe;
|
andrew@0
|
1226
|
andrew@0
|
1227 int colour = 0;
|
andrew@0
|
1228 //int ycoord = y * simHeight/ screenHeight;
|
andrew@0
|
1229 //y += startingFrame;
|
andrew@0
|
1230 if (xcoord < sizeOfMatrix && ycoord < sizeOfSecondMatrix)
|
andrew@0
|
1231 colour = similarityMatrix[xcoord][ycoord]*255;
|
andrew@0
|
1232
|
andrew@0
|
1233
|
andrew@0
|
1234 ofSetColor(colour,0,0);
|
andrew@0
|
1235
|
andrew@0
|
1236 ofRect(x,y,1,1);
|
andrew@0
|
1237
|
andrew@0
|
1238 }
|
andrew@0
|
1239 }
|
andrew@0
|
1240
|
andrew@0
|
1241 drawAlignmentPath(startingXframe, startingYframe);
|
andrew@0
|
1242
|
andrew@0
|
1243 //SET TEXT
|
andrew@0
|
1244 string textString;
|
andrew@0
|
1245 textString = "width : ";
|
andrew@0
|
1246 textString += ofToString(simWidth);
|
andrew@0
|
1247
|
andrew@0
|
1248 textString += " height : ";
|
andrew@0
|
1249 textString += ofToString(simHeight);
|
andrew@0
|
1250
|
andrew@0
|
1251 textString += " startframe : ";
|
andrew@0
|
1252 textString += ofToString(startingFrame);
|
andrew@0
|
1253
|
andrew@0
|
1254 textString += " Xframe : ";
|
andrew@0
|
1255 textString += ofToString(startingXframe);
|
andrew@0
|
1256
|
andrew@0
|
1257 textString += " Yframe : ";
|
andrew@0
|
1258 textString += ofToString(startingYframe);
|
andrew@0
|
1259
|
andrew@0
|
1260 textString += " currentFrame : ";
|
andrew@0
|
1261 textString += ofToString(currentPlayingFrame);
|
andrew@0
|
1262
|
andrew@0
|
1263 textString += " scrollwidth: ";
|
andrew@0
|
1264 textString += ofToString(scrollWidth);
|
andrew@0
|
1265
|
andrew@0
|
1266 textString += " xcoord: ";
|
andrew@0
|
1267 textString += ofToString(xcoord);
|
andrew@0
|
1268
|
andrew@0
|
1269 textString += " Clength: ";
|
andrew@0
|
1270 textString += ofToString(chromoLength);
|
andrew@0
|
1271
|
andrew@0
|
1272 textString += " no.Scrolls: ";
|
andrew@0
|
1273 textString += ofToString(numberOfScrollWidthsForFirstFile);
|
andrew@0
|
1274 //END SET TEXT
|
andrew@0
|
1275
|
andrew@0
|
1276 ofSetColor(0x0000FF);
|
andrew@0
|
1277 if (firstAudioFilePlaying){
|
andrew@0
|
1278 ofLine(audioPosition*screenWidth, 0, audioPosition*screenWidth, height);
|
andrew@0
|
1279 checkIfAudioPositionExceedsWidthForFirstFile();
|
andrew@0
|
1280
|
andrew@0
|
1281 //draw values:
|
andrew@0
|
1282 xcoord = currentPlayingFrame / CHROMA_CONVERSION_FACTOR;
|
andrew@0
|
1283 ofSetColor(255, 255, 255);
|
andrew@0
|
1284 for (int y = 0;y < chromoLength; y+=max(1, (int)(20 * chromoLength / screenHeight))){
|
andrew@0
|
1285
|
andrew@0
|
1286 float value = alignmentMeasureMatrix[xcoord][y+startingYframe];
|
andrew@0
|
1287 int ycoord = y * screenHeight/chromoLength;
|
andrew@0
|
1288 ofDrawBitmapString(ofToString(value, 2) , audioPosition*screenWidth , ycoord);
|
andrew@0
|
1289 }
|
andrew@0
|
1290 }
|
andrew@0
|
1291 else{
|
andrew@0
|
1292 ofLine(0, audioPosition*screenHeight, screenWidth, audioPosition*screenHeight);
|
andrew@0
|
1293 }
|
andrew@0
|
1294
|
andrew@0
|
1295 ofDrawBitmapString(textString,80,580);
|
andrew@0
|
1296
|
andrew@0
|
1297 ofDrawBitmapString(userInfoString,80,80);
|
andrew@0
|
1298
|
andrew@0
|
1299 }
|
andrew@0
|
1300
|
andrew@0
|
1301
|
andrew@0
|
1302
|
andrew@3
|
1303 void TimeWarp::drawAlignmentPath(int startingChromaXFrame, int startingChromaYFrame){
|
andrew@0
|
1304 //draw alignment path
|
andrew@0
|
1305 int endingChromaXFrame = startingChromaXFrame + chromoLength;
|
andrew@0
|
1306 int endingChromaYFrame = startingChromaYFrame + chromoLength;
|
andrew@0
|
1307
|
andrew@0
|
1308 float chromoWidth = screenWidth / chromoLength;
|
andrew@0
|
1309 float chromoHeight = screenHeight / chromoLength;
|
andrew@0
|
1310
|
andrew@0
|
1311 int index = backwardsAlignmentPath[0].size()-1;
|
andrew@0
|
1312 //OPTIMISE XXX
|
andrew@0
|
1313
|
andrew@0
|
1314
|
andrew@0
|
1315 while (backwardsAlignmentPath[0][index] < startingChromaXFrame){
|
andrew@0
|
1316 index --;
|
andrew@0
|
1317 }
|
andrew@0
|
1318
|
andrew@0
|
1319 int printIndex = index;
|
andrew@0
|
1320 int backAlign = backwardsAlignmentPath[0][index];
|
andrew@0
|
1321 int printxcoord;
|
andrew@0
|
1322 int xcoord;
|
andrew@0
|
1323
|
andrew@0
|
1324 while (backwardsAlignmentPath[0][index] < endingChromaXFrame) {
|
andrew@0
|
1325 xcoord = backwardsAlignmentPath[0][index];
|
andrew@0
|
1326 int ycoord = backwardsAlignmentPath[1][index];
|
andrew@0
|
1327
|
andrew@0
|
1328 printxcoord = xcoord;
|
andrew@0
|
1329 int colour = similarityMatrix[xcoord][ycoord]*255;
|
andrew@0
|
1330
|
andrew@0
|
1331 float value = alignmentMeasureMatrix[xcoord][ycoord] ;
|
andrew@0
|
1332
|
andrew@0
|
1333
|
andrew@0
|
1334 xcoord -= startingChromaXFrame;
|
andrew@0
|
1335 ycoord -= startingChromaYFrame;
|
andrew@0
|
1336 ofSetColor(0,0,colour);
|
andrew@0
|
1337 ofRect(xcoord*chromoWidth, ycoord*chromoHeight, chromoWidth, chromoHeight);
|
andrew@0
|
1338 // ofSetColor(255, 255, 255);
|
andrew@0
|
1339 // ofDrawBitmapString(ofToString(value, 2), xcoord*chromoWidth, ycoord*chromoHeight);
|
andrew@0
|
1340 index--;
|
andrew@0
|
1341 }
|
andrew@0
|
1342
|
andrew@0
|
1343 // drawHoverAlignmentValues();
|
andrew@0
|
1344 // printf("ALIGN score :[%i] : %f \n", backwardsAlignmentPath[1][backwardsAlignmentIndex], alignmentMeasureMatrix[ backwardsAlignmentPath[0][backwardsAlignmentIndex] ][ (int) backwardsAlignmentPath[1][backwardsAlignmentIndex] ]);
|
andrew@0
|
1345
|
andrew@0
|
1346
|
andrew@0
|
1347 //SET TEXT
|
andrew@0
|
1348 string textString;
|
andrew@0
|
1349 textString = "ALIGNMENT PATH ";
|
andrew@0
|
1350
|
andrew@0
|
1351 textString += "backward A index ";
|
andrew@0
|
1352 textString += ofToString(backwardsAlignmentIndex);
|
andrew@0
|
1353
|
andrew@0
|
1354 textString += " starting X frame ";
|
andrew@0
|
1355 textString += ofToString(startingChromaXFrame);
|
andrew@0
|
1356
|
andrew@0
|
1357 textString += " initial xcoord ";
|
andrew@0
|
1358 textString += ofToString(printxcoord);
|
andrew@0
|
1359
|
andrew@0
|
1360 textString += " first index ";
|
andrew@0
|
1361 textString += ofToString(printIndex);
|
andrew@0
|
1362
|
andrew@0
|
1363 textString += " backalign[index] ";
|
andrew@0
|
1364 textString += ofToString(backAlign);
|
andrew@0
|
1365
|
andrew@0
|
1366 textString += " final xcoord ";
|
andrew@0
|
1367 textString += ofToString(xcoord);
|
andrew@0
|
1368
|
andrew@0
|
1369
|
andrew@0
|
1370
|
andrew@0
|
1371
|
andrew@0
|
1372 ofSetColor(255,255,255);
|
andrew@0
|
1373 ofDrawBitmapString(textString,80,640);
|
andrew@0
|
1374
|
andrew@0
|
1375 }
|
andrew@0
|
1376
|
andrew@0
|
1377
|
andrew@0
|
1378
|
andrew@0
|
1379 */
|
andrew@0
|
1380 /*
|
andrew@3
|
1381 void TimeWarp::checkIfAudioPositionExceedsWidthForFirstFile()
|
andrew@0
|
1382 {
|
andrew@0
|
1383 if (currentPlayingFrame > scrollWidth*(numberOfScrollWidthsForFirstFile+1))
|
andrew@0
|
1384 numberOfScrollWidthsForFirstFile++;
|
andrew@0
|
1385 }
|
andrew@0
|
1386
|
andrew@3
|
1387 int TimeWarp::findStartWidthFrame(){
|
andrew@0
|
1388 int startingFrame;
|
andrew@0
|
1389 startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in
|
andrew@0
|
1390 startingFrame *= scrollWidth;//starting frame in terms of energy frames
|
andrew@0
|
1391 startingFrame /= CHROMA_CONVERSION_FACTOR;
|
andrew@0
|
1392
|
andrew@0
|
1393 return startingFrame;
|
andrew@0
|
1394 }
|
andrew@0
|
1395
|
andrew@0
|
1396 */
|
andrew@0
|
1397
|
andrew@0
|
1398 /*
|
andrew@3
|
1399 void TimeWarp::loadSoundFiles(){
|
andrew@0
|
1400
|
andrew@0
|
1401 //assume libsndfile looks in the folder where the app is run
|
andrew@0
|
1402 //therefore ../../../ gets to the bin folder
|
andrew@0
|
1403 //we then need data/sounds/to get to the sound folder
|
andrew@0
|
1404 //this is different to the usual OF default folder
|
andrew@0
|
1405 //was const char
|
andrew@0
|
1406 const char *infilename = "../../../data/sound/1-01BachBWV 846.wav";
|
andrew@0
|
1407 loadLibSndFile(infilename);
|
andrew@0
|
1408
|
andrew@0
|
1409 string loadfilename = "sound/1-01BachBWV 846.wav";//PicturesMixer6.aif";
|
andrew@0
|
1410 loadedAudio.loadSound(loadfilename);
|
andrew@0
|
1411 playingAudio = &loadedAudio;
|
andrew@0
|
1412
|
andrew@0
|
1413 }
|
andrew@0
|
1414
|
andrew@3
|
1415 void TimeWarp::loadLibSndFile(const char *infilename){
|
andrew@0
|
1416
|
andrew@0
|
1417 if (!sf_close(infile)){
|
andrew@0
|
1418 printf("closed sndfile okay \n");
|
andrew@0
|
1419 }
|
andrew@0
|
1420
|
andrew@0
|
1421 // Open Input File with lib snd file
|
andrew@0
|
1422 if (! (infile = sf_open (infilename, SFM_READ, &sfinfo)))
|
andrew@0
|
1423 { // Open failed
|
andrew@0
|
1424 printf ("SF OPEN routine Not able to open input file %s.\n", infilename) ;
|
andrew@0
|
1425 // Print the error message from libsndfile.
|
andrew@0
|
1426 puts (sf_strerror (NULL)) ;
|
andrew@0
|
1427
|
andrew@0
|
1428 } else{
|
andrew@0
|
1429 printf("SF OPEN opened file %s okay.\n", infilename);
|
andrew@0
|
1430 sndfileInfoString = "Opened okay ";
|
andrew@0
|
1431
|
andrew@0
|
1432 };
|
andrew@0
|
1433
|
andrew@0
|
1434 }
|
andrew@0
|
1435 */
|
andrew@0
|
1436 /*
|
andrew@3
|
1437 void TimeWarp::processAudioToDoubleMatrix(Chromagram* chromaG, DoubleMatrix* myDoubleMatrix, DoubleVector* energyVector){
|
andrew@0
|
1438 //wendy
|
andrew@0
|
1439 myDoubleMatrix->clear();
|
andrew@0
|
1440 energyVector->clear();
|
andrew@0
|
1441
|
andrew@0
|
1442 energyIndex = 0;
|
andrew@0
|
1443
|
andrew@0
|
1444 chromaG->initialise(FRAMESIZE,2048);//framesize 512 and hopsize 2048
|
andrew@0
|
1445 chromaG->maximumChromaValue = 0;
|
andrew@0
|
1446
|
andrew@0
|
1447 int readcount = 1; // counts number of samples read from sound file
|
andrew@0
|
1448 printf("processing audio from doublematrix \n");
|
andrew@0
|
1449 printf("readcount %i", readcount);
|
andrew@0
|
1450 while(readcount != 0 && moveOn == true)
|
andrew@0
|
1451 {
|
andrew@0
|
1452
|
andrew@0
|
1453 // read FRAMESIZE samples from 'infile' and save in 'data'
|
andrew@0
|
1454 readcount = sf_read_float(infile, frame, FRAMESIZE);
|
andrew@0
|
1455 //processing frame - downsampled to 11025Hz
|
andrew@0
|
1456 //8192 samples per chroma frame
|
andrew@0
|
1457
|
andrew@0
|
1458 chromaG->processframe(frame);
|
andrew@0
|
1459
|
andrew@0
|
1460 if (chromaG->chromaready)
|
andrew@0
|
1461 {
|
andrew@0
|
1462 DoubleVector d;
|
andrew@0
|
1463
|
andrew@0
|
1464 for (int i = 0;i<12;i++){
|
andrew@0
|
1465 //chromoGramVector[chromaIndex][i] = chromoGramm.rawChroma[i] / chromoGramm.maximumChromaValue;
|
andrew@0
|
1466 d.push_back(chromaG->rawChroma[i]);// / chromaG->maximumChromaValue);
|
andrew@0
|
1467
|
andrew@0
|
1468 }
|
andrew@0
|
1469 //this would do chord detection
|
andrew@0
|
1470
|
andrew@0
|
1471 myDoubleMatrix->push_back(d);
|
andrew@0
|
1472
|
andrew@0
|
1473
|
andrew@0
|
1474 }//end if chromagRamm ready
|
andrew@0
|
1475
|
andrew@0
|
1476
|
andrew@0
|
1477
|
andrew@0
|
1478 putEnergyInFrame();
|
andrew@0
|
1479 //get energy of the current frame and wait
|
andrew@0
|
1480 double energyValue = getEnergyOfFrame();
|
andrew@0
|
1481 energyVector->push_back(energyValue);
|
andrew@0
|
1482
|
andrew@0
|
1483
|
andrew@0
|
1484 }//end while readcount
|
andrew@0
|
1485
|
andrew@0
|
1486 printf("Max chroma value is %f \n", chromaG->maximumChromaValue);
|
andrew@0
|
1487
|
andrew@0
|
1488 //normalise
|
andrew@0
|
1489 int length = myDoubleMatrix->size();
|
andrew@0
|
1490 printf("length of chromagram is %d frames\n", length);
|
andrew@0
|
1491 length = (*myDoubleMatrix)[0].size();
|
andrew@0
|
1492 printf("height of dmatrix is %d\n", length);
|
andrew@0
|
1493
|
andrew@0
|
1494 for (int i = 0; i < myDoubleMatrix->size();i++){
|
andrew@0
|
1495 for (int j = 0; j < ((*myDoubleMatrix)[0]).size();j++){
|
andrew@0
|
1496 (*myDoubleMatrix)[i][j] /= chromaG->maximumChromaValue;
|
andrew@0
|
1497 }
|
andrew@0
|
1498 }
|
andrew@0
|
1499
|
andrew@0
|
1500 int size;
|
andrew@0
|
1501 size = energyVector->size();
|
andrew@0
|
1502 printf("size of energy vector is %d \n", size);
|
andrew@0
|
1503
|
andrew@0
|
1504
|
andrew@0
|
1505 // int size = myDoubleMatrix->size() * CHROMA_CONVERSION_FACTOR;
|
andrew@0
|
1506 // printf("size of double matrix is %d and frame index %d", size, frameIndex);
|
andrew@0
|
1507
|
andrew@0
|
1508 // printf("Total frames %i energy index %i and Chroma index %i \n", frameIndex, energyIndex, chromaIndex);
|
andrew@0
|
1509
|
andrew@0
|
1510
|
andrew@0
|
1511 }
|
andrew@0
|
1512 */
|
andrew@0
|
1513
|
andrew@0
|
1514 //--------------------------------------------------------------
|
andrew@0
|
1515 /*
|
andrew@3
|
1516 void TimeWarp::keyPressed (int key){
|
andrew@0
|
1517 if (key == '-'){
|
andrew@0
|
1518 volume -= 0.05;
|
andrew@0
|
1519 volume = MAX(volume, 0);
|
andrew@0
|
1520 } else if (key == '+'){
|
andrew@0
|
1521 volume += 0.05;
|
andrew@0
|
1522 volume = MIN(volume, 1);
|
andrew@0
|
1523 }
|
andrew@0
|
1524
|
andrew@0
|
1525 if (key == OF_KEY_DOWN){
|
andrew@0
|
1526 if (scrollWidth > 600)
|
andrew@0
|
1527 scrollWidth += 400;
|
andrew@0
|
1528 else
|
andrew@0
|
1529 scrollWidth *= 2;
|
andrew@0
|
1530
|
andrew@0
|
1531 chromoLength = scrollWidth/CHROMA_CONVERSION_FACTOR;
|
andrew@0
|
1532 }
|
andrew@0
|
1533
|
andrew@0
|
1534 if (key == OF_KEY_UP){
|
andrew@0
|
1535 if (scrollWidth > 600)
|
andrew@0
|
1536 scrollWidth -= 400;
|
andrew@0
|
1537 else
|
andrew@0
|
1538 scrollWidth /= 2;
|
andrew@0
|
1539
|
andrew@0
|
1540 chromoLength = scrollWidth/CHROMA_CONVERSION_FACTOR;
|
andrew@0
|
1541 }
|
andrew@0
|
1542
|
andrew@0
|
1543 if (key == OF_KEY_LEFT){
|
andrew@0
|
1544
|
andrew@0
|
1545 (*playingAudio).setSpeed(-2);
|
andrew@0
|
1546 backwardsAlignmentIndex = backwardsAlignmentPath[0].size()-1;
|
andrew@0
|
1547 }
|
andrew@0
|
1548
|
andrew@0
|
1549 if (key == OF_KEY_RIGHT){
|
andrew@0
|
1550
|
andrew@0
|
1551 (*playingAudio).setSpeed(2);
|
andrew@0
|
1552 }
|
andrew@0
|
1553
|
andrew@0
|
1554 if (key == OF_KEY_RETURN){
|
andrew@0
|
1555 loadedAudio.stop();
|
andrew@0
|
1556 audioPlaying = false;
|
andrew@0
|
1557 audioPaused = true;
|
andrew@0
|
1558 initialiseVariables();
|
andrew@0
|
1559 }
|
andrew@0
|
1560
|
andrew@0
|
1561 if (key == ' '){
|
andrew@0
|
1562 if (!audioPlaying) {
|
andrew@0
|
1563 (*playingAudio).play();
|
andrew@0
|
1564 (*playingAudio).setPaused(false);
|
andrew@0
|
1565 secondAudio.play();
|
andrew@0
|
1566 secondAudio.setPaused(true);
|
andrew@0
|
1567
|
andrew@0
|
1568 firstAudioFilePlaying = true;
|
andrew@0
|
1569
|
andrew@0
|
1570 audioPlaying = true;
|
andrew@0
|
1571 audioPaused = false;
|
andrew@0
|
1572 }
|
andrew@0
|
1573 else{
|
andrew@0
|
1574 audioPaused = !audioPaused;
|
andrew@0
|
1575 (*playingAudio).setPaused(audioPaused);
|
andrew@0
|
1576 }
|
andrew@0
|
1577
|
andrew@0
|
1578 }
|
andrew@0
|
1579
|
andrew@0
|
1580 if (key == 'p'){
|
andrew@0
|
1581 swapBetweenPlayingFilesUsingAlignmentMatch();
|
andrew@0
|
1582
|
andrew@0
|
1583 }
|
andrew@0
|
1584
|
andrew@0
|
1585 if (key == 'o'){
|
andrew@0
|
1586 openNewAudioFileWithdialogBox();
|
andrew@0
|
1587 }
|
andrew@0
|
1588
|
andrew@0
|
1589 if (key == 'l'){
|
andrew@0
|
1590 //open audio file
|
andrew@0
|
1591 string *filePtr, secondFileName;
|
andrew@0
|
1592 filePtr = &secondFileName;
|
andrew@0
|
1593 //so filePtr points to secondFileName
|
andrew@0
|
1594
|
andrew@0
|
1595 if (getFilenameFromDialogBox(filePtr)){
|
andrew@0
|
1596 printf("Loaded name okay :\n'%s' \n", secondFileName.c_str());
|
andrew@0
|
1597 }
|
andrew@0
|
1598
|
andrew@0
|
1599 loadSecondAudio(secondFileName);
|
andrew@0
|
1600
|
andrew@0
|
1601 calculateSimilarityMatrix();
|
andrew@0
|
1602 calculateAlignmentMatrix();
|
andrew@0
|
1603 calculateMinimumAlignmentPath();
|
andrew@0
|
1604
|
andrew@0
|
1605 }
|
andrew@0
|
1606
|
andrew@0
|
1607 if (key == 's'){
|
andrew@0
|
1608 drawSimilarity = !drawSimilarity;
|
andrew@0
|
1609 }
|
andrew@0
|
1610
|
andrew@0
|
1611
|
andrew@0
|
1612 if (key == 'm'){
|
andrew@0
|
1613 drawSecondMatrix = !drawSecondMatrix;
|
andrew@0
|
1614 }
|
andrew@0
|
1615
|
andrew@0
|
1616 if (key == 'd'){
|
andrew@0
|
1617 drawSpectralDifferenceFunction = !drawSpectralDifferenceFunction;
|
andrew@0
|
1618 }
|
andrew@0
|
1619
|
andrew@0
|
1620 }
|
andrew@0
|
1621
|
andrew@0
|
1622 //--------------------------------------------------------------
|
andrew@3
|
1623 void TimeWarp::keyReleased (int key){
|
andrew@0
|
1624 if (key == OF_KEY_LEFT || OF_KEY_RIGHT){
|
andrew@0
|
1625 (*playingAudio).setSpeed(1);
|
andrew@0
|
1626 backwardsAlignmentIndex = backwardsAlignmentPath[0].size()-1;
|
andrew@0
|
1627 }
|
andrew@0
|
1628
|
andrew@0
|
1629 }
|
andrew@0
|
1630 */
|
andrew@0
|
1631 /*
|
andrew@3
|
1632 void TimeWarp::openNewAudioFileWithdialogBox(){
|
andrew@0
|
1633
|
andrew@0
|
1634 //open audio file
|
andrew@0
|
1635 string *filePtr;
|
andrew@0
|
1636 filePtr = &soundFileName;
|
andrew@0
|
1637
|
andrew@0
|
1638 if (getFilenameFromDialogBox(filePtr)){
|
andrew@0
|
1639 printf("Mainfile: Loaded name okay :\n'%s' \n", soundFileName.c_str());
|
andrew@0
|
1640 }
|
andrew@0
|
1641
|
andrew@0
|
1642 //openFileDialogBox(); - replaced this lone by call to openFile Dialoguebox
|
andrew@0
|
1643 loadNewAudio(soundFileName);
|
andrew@0
|
1644
|
andrew@0
|
1645 }
|
andrew@0
|
1646 */
|
andrew@0
|
1647 /*
|
andrew@0
|
1648 //--------------------------------------------------------------
|
andrew@3
|
1649 void TimeWarp::mouseMoved(int x, int y ){
|
andrew@0
|
1650 width = ofGetWidth();
|
andrew@0
|
1651 pan = (float)x / (float)width;
|
andrew@0
|
1652 float height = (float)ofGetHeight();
|
andrew@0
|
1653 float heightPct = ((height-y) / height);
|
andrew@0
|
1654 targetFrequency = 2000.0f * heightPct;
|
andrew@0
|
1655 phaseAdderTarget = (targetFrequency / (float) sampleRate) * TWO_PI;
|
andrew@0
|
1656 xIndex = (int)(pan*ENERGY_LENGTH);
|
andrew@0
|
1657 }
|
andrew@0
|
1658
|
andrew@0
|
1659 //--------------------------------------------------------------
|
andrew@3
|
1660 void TimeWarp::mouseDragged(int x, int y, int button){
|
andrew@0
|
1661 width = ofGetWidth();
|
andrew@0
|
1662 pan = (float)x / (float)width;
|
andrew@0
|
1663 }
|
andrew@0
|
1664
|
andrew@0
|
1665 //--------------------------------------------------------------
|
andrew@3
|
1666 void TimeWarp::mousePressed(int x, int y, int button){
|
andrew@0
|
1667 bNoise = true;
|
andrew@0
|
1668 moveOn = true;
|
andrew@0
|
1669 }
|
andrew@0
|
1670
|
andrew@0
|
1671
|
andrew@0
|
1672 //--------------------------------------------------------------
|
andrew@3
|
1673 void TimeWarp::mouseReleased(int x, int y, int button){
|
andrew@0
|
1674 bNoise = false;
|
andrew@0
|
1675 }
|
andrew@0
|
1676
|
andrew@0
|
1677 //--------------------------------------------------------------
|
andrew@3
|
1678 void TimeWarp::windowResized(int w, int h){
|
andrew@0
|
1679 width = w;
|
andrew@0
|
1680 height = h;
|
andrew@0
|
1681 screenHeight = ofGetHeight() ;
|
andrew@0
|
1682 screenWidth = ofGetWidth();
|
andrew@0
|
1683
|
andrew@0
|
1684 }
|
andrew@0
|
1685 */
|
andrew@0
|
1686
|
andrew@0
|
1687 //--------------------------------------------------------------
|
andrew@0
|
1688 /*
|
andrew@0
|
1689
|
andrew@3
|
1690 bool TimeWarp::getFilenameFromDialogBox(string* fileNameToSave){
|
andrew@0
|
1691 //this uses a pointer structure within the loader and returns true if the dialogue box was used successfully
|
andrew@0
|
1692 // first, create a string that will hold the URL
|
andrew@0
|
1693 string URL;
|
andrew@0
|
1694
|
andrew@0
|
1695 // openFile(string& URL) returns 1 if a file was picked
|
andrew@0
|
1696 // returns 0 when something went wrong or the user pressed 'cancel'
|
andrew@0
|
1697 int response = ofxFileDialogOSX::openFile(URL);
|
andrew@0
|
1698 if(response){
|
andrew@0
|
1699 // now you can use the URL
|
andrew@0
|
1700 *fileNameToSave = URL;
|
andrew@0
|
1701 //printf("\n filename is %s \n", soundFileName.c_str());
|
andrew@0
|
1702 return true;
|
andrew@0
|
1703 }
|
andrew@0
|
1704 else {
|
andrew@0
|
1705 // soundFileName = "OPEN canceled. ";
|
andrew@0
|
1706 printf("\n open file cancelled \n");
|
andrew@0
|
1707 return false;
|
andrew@0
|
1708 }
|
andrew@0
|
1709
|
andrew@0
|
1710 }
|
andrew@0
|
1711 */
|
andrew@0
|
1712
|
andrew@0
|
1713
|
andrew@0
|
1714 /*
|
andrew@3
|
1715 void TimeWarp::putEnergyInFrame(){
|
andrew@0
|
1716
|
andrew@0
|
1717
|
andrew@0
|
1718 float totalEnergyInFrame = 0;
|
andrew@0
|
1719
|
andrew@0
|
1720 for (int i = 0;i<FRAMESIZE;i++){
|
andrew@0
|
1721
|
andrew@0
|
1722 totalEnergyInFrame += (frame[i] * frame[i]);
|
andrew@0
|
1723
|
andrew@0
|
1724 }
|
andrew@0
|
1725 totalEnergyInFrame = sqrt(totalEnergyInFrame);
|
andrew@0
|
1726
|
andrew@0
|
1727 if (energyIndex < ENERGY_LENGTH){
|
andrew@0
|
1728 energy[energyIndex] = totalEnergyInFrame;
|
andrew@0
|
1729 energyIndex++;
|
andrew@0
|
1730 }
|
andrew@0
|
1731
|
andrew@0
|
1732 }
|
andrew@0
|
1733 */
|
andrew@0
|
1734
|
andrew@0
|
1735
|
andrew@0
|
1736
|
andrew@0
|
1737 /*
|
andrew@3
|
1738 void TimeWarp::printAlignmentMatrix(){
|
andrew@0
|
1739
|
andrew@0
|
1740 int size = alignmentMeasureMatrix.size();
|
andrew@0
|
1741 printf("\n _ _ _ _\n");
|
andrew@0
|
1742 printf("align size is %i \n", size);
|
andrew@0
|
1743
|
andrew@0
|
1744 int i,j;
|
andrew@0
|
1745 DoubleVector d;
|
andrew@0
|
1746 int rowSize = alignmentMeasureMatrix.size();
|
andrew@0
|
1747 d = alignmentMeasureMatrix[0];//choose initial size
|
andrew@0
|
1748
|
andrew@0
|
1749 for (int j = 0;j < d.size();j++){
|
andrew@0
|
1750 printf("row %i : ", j);
|
andrew@0
|
1751
|
andrew@0
|
1752 for (i = 0;i < rowSize;i++){
|
andrew@0
|
1753 d = alignmentMeasureMatrix[i];
|
andrew@0
|
1754
|
andrew@0
|
1755 // printf("row %i , col %i, val : %f \n", i, j, alignmentMeasureMatrix[i][j] );
|
andrew@0
|
1756 printf("%f , ", alignmentMeasureMatrix[i][j] );
|
andrew@0
|
1757 }
|
andrew@0
|
1758 printf("\n");
|
andrew@0
|
1759 }
|
andrew@0
|
1760 printf("...............\n");
|
andrew@0
|
1761
|
andrew@0
|
1762 }
|
andrew@0
|
1763
|
andrew@0
|
1764
|
andrew@3
|
1765 void TimeWarp::printScoreForRow(int row, int max){
|
andrew@0
|
1766 printf("alignment scores row %i \n", row);
|
andrew@0
|
1767 float minimum = alignmentMeasureMatrix[row][0];
|
andrew@0
|
1768 int minimumIndex = 0;
|
andrew@0
|
1769 for (int i =0;i < max;i++){
|
andrew@0
|
1770 printf("[%i] %f ", i, alignmentMeasureMatrix[row][i]);
|
andrew@0
|
1771 if (alignmentMeasureMatrix[row][i] < minimum)
|
andrew@0
|
1772 {
|
andrew@0
|
1773 minimum = alignmentMeasureMatrix[row][i] ;
|
andrew@0
|
1774 minimumIndex = i;
|
andrew@0
|
1775 }
|
andrew@0
|
1776 printf(" \n");
|
andrew@0
|
1777 }
|
andrew@0
|
1778 printf("Minimum [%i] : %f \n", minimumIndex, minimum);
|
andrew@0
|
1779 printf("ALIGN score :[%i] : %f \n", backwardsAlignmentPath[1][backwardsAlignmentIndex], alignmentMeasureMatrix[ backwardsAlignmentPath[0][backwardsAlignmentIndex] ][ (int) backwardsAlignmentPath[1][backwardsAlignmentIndex] ]);
|
andrew@0
|
1780
|
andrew@0
|
1781
|
andrew@0
|
1782 }
|
andrew@0
|
1783 */
|
andrew@0
|
1784
|
andrew@0
|
1785
|
andrew@0
|
1786
|
andrew@0
|
1787
|
andrew@0
|
1788 /*
|
andrew@3
|
1789 void TimeWarp::swapBetweenPlayingFilesUsingAlignmentMatch(){
|
andrew@0
|
1790 ofSoundUpdate();
|
andrew@0
|
1791 //swapping between files
|
andrew@0
|
1792 //printf("current playing (energy scale) frame was %i \n", currentPlayingFrame);
|
andrew@0
|
1793 float oldPosition = (*playingAudio).getPosition();
|
andrew@0
|
1794 printf("playing position is %f \n", (*playingAudio).getPosition());
|
andrew@0
|
1795
|
andrew@0
|
1796 //(*playingAudio).stop();
|
andrew@0
|
1797 (*playingAudio).setPaused(true);
|
andrew@0
|
1798 int newIndicator;
|
andrew@0
|
1799 if (firstAudioFilePlaying){
|
andrew@0
|
1800 playingAudio = &secondAudio;
|
andrew@0
|
1801 newIndicator = 1;
|
andrew@0
|
1802 }
|
andrew@0
|
1803 else{
|
andrew@0
|
1804 playingAudio = &loadedAudio;
|
andrew@0
|
1805 newIndicator = 0;
|
andrew@0
|
1806 }
|
andrew@0
|
1807 printf("new indicator %i \n", newIndicator);
|
andrew@0
|
1808
|
andrew@0
|
1809 printf("playing pos according to energy frames is %f \n ",
|
andrew@0
|
1810 (currentPlayingFrame/((float)backwardsAlignmentPath[1-newIndicator][0]*CHROMA_CONVERSION_FACTOR)) );
|
andrew@0
|
1811
|
andrew@0
|
1812 printf("predicts frame to be %f \n", (oldPosition*backwardsAlignmentPath[1-newIndicator][0]));
|
andrew@0
|
1813
|
andrew@0
|
1814 currentChromaFrame = oldPosition * (float) backwardsAlignmentPath[1-newIndicator][0];
|
andrew@0
|
1815 printf("current chroma frame %i and using energy frames would have been %i \n", currentChromaFrame, currentPlayingFrame / CHROMA_CONVERSION_FACTOR);
|
andrew@0
|
1816 int matchingFrame = findMatchFromAlignment(firstAudioFilePlaying);
|
andrew@0
|
1817
|
andrew@0
|
1818 float relativePosition = matchingFrame / (float) backwardsAlignmentPath[newIndicator][0];
|
andrew@0
|
1819 //i.e. the position as float [0,1] 0:beginning, 1 is end
|
andrew@0
|
1820
|
andrew@0
|
1821 (*playingAudio).setPaused(false);
|
andrew@0
|
1822 // secondAudio.setPosition(relativePosition);//XXX tmp line
|
andrew@0
|
1823 (*playingAudio).setPosition(relativePosition);
|
andrew@0
|
1824
|
andrew@0
|
1825 printf("matching frame is %i and length is %i \n", matchingFrame, backwardsAlignmentPath[newIndicator][0]);
|
andrew@0
|
1826 printf("new playing position is %f \n", (*playingAudio).getPosition());
|
andrew@0
|
1827
|
andrew@0
|
1828 firstAudioFilePlaying = !firstAudioFilePlaying;
|
andrew@0
|
1829
|
andrew@0
|
1830
|
andrew@0
|
1831 }
|
andrew@0
|
1832 */
|
andrew@0
|
1833 /*
|
andrew@3
|
1834 int TimeWarp::findMatchFromAlignment(bool whichFileToTest){
|
andrew@0
|
1835 //could use technique from middle of file and go either way to reduce latency for long search?
|
andrew@0
|
1836 //- (not that this is a problem yet)
|
andrew@0
|
1837 int indicator;
|
andrew@0
|
1838 if (whichFileToTest)
|
andrew@0
|
1839 indicator = 0;
|
andrew@0
|
1840 else
|
andrew@0
|
1841 indicator = 1;
|
andrew@0
|
1842
|
andrew@0
|
1843 int oppositeIndicator = 1 - indicator;
|
andrew@0
|
1844
|
andrew@0
|
1845 int frame = backwardsAlignmentPath[indicator].size()-1;
|
andrew@0
|
1846
|
andrew@0
|
1847 // int currentChromaFrame = currentPlayingFrame / CHROMA_CONVERSION_FACTOR;
|
andrew@0
|
1848 //trying this instead
|
andrew@0
|
1849
|
andrew@0
|
1850
|
andrew@0
|
1851
|
andrew@0
|
1852 while (backwardsAlignmentPath[indicator][frame] < currentChromaFrame){
|
andrew@0
|
1853 frame--;
|
andrew@0
|
1854 }
|
andrew@0
|
1855 //printf("frame found is %i \n", frame);
|
andrew@0
|
1856 int frameToSwitchTo = backwardsAlignmentPath[oppositeIndicator][frame];
|
andrew@0
|
1857
|
andrew@0
|
1858 float calculatedPosition = (currentChromaFrame / (float) backwardsAlignmentPath[indicator][0]);
|
andrew@0
|
1859
|
andrew@0
|
1860 printf("(length was %i)\n", backwardsAlignmentPath[indicator][0]);
|
andrew@0
|
1861
|
andrew@0
|
1862 printf("compares to position calculated from chroma length %f \n", calculatedPosition);
|
andrew@0
|
1863 printf("current frame %i maps to new frame %i \n", currentChromaFrame, frameToSwitchTo);
|
andrew@0
|
1864 printf("relative position of new frame is %f \n", (frameToSwitchTo / (float) backwardsAlignmentPath[oppositeIndicator][0]) );
|
andrew@0
|
1865 return frameToSwitchTo;
|
andrew@0
|
1866
|
andrew@0
|
1867 }
|
andrew@0
|
1868
|
andrew@0
|
1869 */
|
andrew@4
|
1870
|
andrew@4
|
1871
|
andrew@4
|
1872
|
andrew@4
|
1873 /*
|
andrew@4
|
1874 double TimeWarp::getEnergyOfFrame(){
|
andrew@4
|
1875
|
andrew@4
|
1876
|
andrew@4
|
1877 float totalEnergyInFrame = 0;
|
andrew@4
|
1878
|
andrew@4
|
1879 for (int i = 0;i<FRAMESIZE;i++){
|
andrew@4
|
1880
|
andrew@4
|
1881 totalEnergyInFrame += (frame[i] * frame[i]);
|
andrew@4
|
1882
|
andrew@4
|
1883 }
|
andrew@4
|
1884 totalEnergyInFrame = sqrt(totalEnergyInFrame);
|
andrew@4
|
1885
|
andrew@4
|
1886 return totalEnergyInFrame;
|
andrew@4
|
1887 }
|
andrew@4
|
1888 */
|
andrew@4
|
1889
|