annotate src/timeWarp.cpp @ 17:ffb563f6e4cd tip

Timewarp uncomitted changes
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Fri, 06 Jan 2012 00:20:42 +0000
parents ff1702b723f3
children
rev   line source
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