Mercurial > hg > audio-time-warp
changeset 4:f40577e6b30d
revised this to work with onset and chroma and looking now to do sequential DTW
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Wed, 08 Jun 2011 17:35:56 +0100 |
parents | d0242d0a48e8 |
children | 0d51e93bfe74 |
files | src/TimeWarp.cpp src/TimeWarp.h src/testApp.cpp src/testApp.h src/timeWarp.cpp src/timeWarp.h |
diffstat | 6 files changed, 2309 insertions(+), 309 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/TimeWarp.cpp Wed Jun 08 17:35:56 2011 +0100 @@ -0,0 +1,1531 @@ +/* + * TimeWarp.cpp + * chromaReader13 + * + * Created by Andrew on 16/05/2011. + * Copyright 2011 QMUL. All rights reserved. + * + */ + +#include "TimeWarp.h" + +#include "stdio.h" +#include "aubio.h" +#include <iostream> +#include <cstring> +#include <string> +#include <cstdlib> + +//FIX CHORDS IN THE NEW POINTER VERSION OF THE PROCESS AUDIO FN + +//BUG IN WHETHER SECOND SONG LOADED OR NOT + + +//CHECK THAT DTW will not call beyond the limits of the two chroma if different sizes + +//CALC DTW on different sizes + +//CHECK CORRECT BEST ALIGNMENT METHOD FOR DTW + +//RE-DO DRAW SO THAT IT DOES NOT CALCULATE EVERY POINT BUT DOES IN SQUARE CHUNKS + +//UPDATE START FRAME SO ALIGNMENT IS ALWAYS ON SCREEN +//-------------------------------------------------------------- +// destructor +TimeWarp :: TimeWarp(){ + diagonalPenalty = 2;//penalises diagonal so all path gradients equal weighting +} + +// destructor +TimeWarp :: ~TimeWarp(){ + + chromaMatrix.clear(); + secondMatrix.clear(); + firstEnergyVector.clear(); + secondEnergyVector.clear(); + similarityMatrix.clear(); + alignmentMeasureMatrix.clear(); + + //matrixPtr.clear(); + //chromoGramm.~ChromoGram(); + //secondChromoGramm; + + + +} + +void TimeWarp::initialiseVariables(){ + diagonalPenalty = 1;//penalises diagonal so all path gradients equal weighting + + //chromoGramm.initialise(FRAMESIZE,2048);//framesize 512 and hopsize 2048 + +} + + +void TimeWarp::createCombinedMatrix(DoubleMatrix myChromaMatrix, DoubleVector energyVector, DoubleMatrix* chromaEnergyMatrix){ + chromaEnergyMatrix->clear(); + int sizeRatio = energyVector.size() / myChromaMatrix.size();// + printf("COMBINE: size of my chroma is %i\n", (int) myChromaMatrix.size());// energyVector.size() / myChromaMatrix.size(); + printf("COMBINED: size ratio of energy to chroma is %i \n", sizeRatio); + int chromaSize = myChromaMatrix.size(); +// printf("index is %i\n", index); + + for (int i = 0;i < energyVector.size();i++){ + DoubleVector d; + int index = min(chromaSize-1, (int) floor(i/sizeRatio)); + + for (int y = 0;y < 12;y++){ + d.push_back(myChromaMatrix[index][y]);// + } + + + d.push_back(energyVector[i]); + (*chromaEnergyMatrix).push_back(d); + } + printf("COMBINED: size of chroma energy is %i\n", (int)(*chromaEnergyMatrix).size()); + + int x = (int)(*chromaEnergyMatrix).size()/3; +// printf("energy[%i] %f \n", x, energyVector[x]); +/* + for (int y = 0;y < 13;y++){ + printf("chroma[%i][%i] %f \n", x, y, myChromaMatrix[x/sizeRatio][y]); + printf("c[%i][%i] %f \n", x, y, (*chromaEnergyMatrix)[x][y]); + } + printf("\n"); +*/ + +} + +void TimeWarp::calculateSimilarityMatrix(){ + calculateSimilarityMatrixWithPointers(chromaMatrix, secondMatrix, &similarityMatrix); + + /* + similarityMatrix.clear(); + printf("calculating similarity matrix...") + // userInfoString = "calculating similarity matrix..."; + + double distance, firstSum, secondSum; + + for (int x = 0;x < chromaMatrix.size();x++){ + DoubleVector d; + + + for (int y = 0;y < secondMatrix.size();y++){ + + distance = 0; + firstSum = 0; + secondSum = 0; + + for (int z = 0;z < chromaMatrix[x].size();z++){//z is the twelve chromagram values + + distance += chromaMatrix[x][z] * secondMatrix[y][z]; + + firstSum += chromaMatrix[x][z] * chromaMatrix[x][z]; + secondSum += secondMatrix[y][z] * secondMatrix[y][z]; + } + + if (firstSum > 0 && secondSum > 0) + distance /= sqrt(firstSum * secondSum); + + + d.push_back( distance); + + } //end for y + + similarityMatrix.push_back(d); + + }//end for x + */ +// printf("..sim size: %i, height: %i \n", (int) similarityMatrix.size(), (int) (chromaMatrix[0]).size()); + +}//end self sim + + + + +void TimeWarp::calculateSimilarityMatrixWithPointers(DoubleMatrix firstChromaMatrix, DoubleMatrix secondChromaMatrix, DoubleMatrix* simMatrix){ + printf("Calculate similarity : pointers : size %i x %i ", (int) firstChromaMatrix.size(), (int) secondChromaMatrix.size()); + + (*simMatrix).clear(); + + double distance, firstSum, secondSum; + + for (int x = 0;x < firstChromaMatrix.size();x++){ + DoubleVector d; + + for (int y = 0;y < secondChromaMatrix.size();y++){ + + distance = 0; + firstSum = 0; + secondSum = 0; + + for (int z = 0;z < firstChromaMatrix[x].size();z++){//z is the twelve chromagram values + distance += firstChromaMatrix[x][z] * secondChromaMatrix[y][z]; + firstSum += firstChromaMatrix[x][z] * firstChromaMatrix[x][z]; + secondSum += secondChromaMatrix[y][z] * secondChromaMatrix[y][z]; + } + + if (firstSum > 0 && secondSum > 0) + distance /= sqrt(firstSum)*sqrt(secondSum); + + d.push_back( distance); + } //end for y + + (*simMatrix).push_back(d); + + }//end for x + + printf("..sim size: %i, height: %i \n", (int) (*simMatrix).size(), (int) (*simMatrix)[0].size()); + +}//end self sim + + +void TimeWarp::calculateAlignmentMatrix(DoubleMatrix firstMatrix, DoubleMatrix secondMatrix, DoubleMatrix* alignmentMatrix){//, DoubleMatrix simMatrix + printf("starting Alignment calculation\n"); + //initialise alignment + (*alignmentMatrix).clear(); + DoubleVector d; + d.push_back(getDistance(0,0)); + (*alignmentMatrix).push_back(d); + + bool chromaCalculated = false; + bool secondCalculated = false; + + while (!chromaCalculated || !secondCalculated) { + + if (!chromaCalculated) + chromaCalculated = extendAlignmentAlong((int) firstMatrix.size(), alignmentMatrix); + + if (!secondCalculated) + secondCalculated = extendAlignmentUp((int) secondMatrix.size(), alignmentMatrix); + + } + printf("Alignment matrix calculated, size %i\n", (int) (*alignmentMatrix).size()); +} + +bool TimeWarp::extendAlignmentUp(int endIndexY, DoubleMatrix *alignmentMatrix){ + DoubleVector d; + d = (*alignmentMatrix)[0];//alignmentMatrix[0];// + int heightSize = d.size(); + if (heightSize < endIndexY){ + //then we haven't finished yet + for (int i = 0;i < (*alignmentMatrix).size();i++){ + double value = getDistance(i, heightSize); + value += getRestrictedMinimum(i, heightSize, value, 0, 0);//min values 0 + (*alignmentMatrix)[i].push_back(value);// + } + } + if ((*alignmentMatrix)[0].size() == endIndexY) + return true; + else + return false; + +} + + +bool TimeWarp::extendAlignmentAlong(int endIndexX, DoubleMatrix* alignmentMatrix){ + DoubleVector d; + //firstMatrix.size() + int widthSize = (*alignmentMatrix).size(); + if (widthSize < endIndexX){//firstMatrix.size() + //then we can extend along + double value = getDistance(widthSize, 0); + value += getRestrictedMinimum(widthSize, 0, value, 0, 0); + + d.push_back(value); + (*alignmentMatrix).push_back(d); + + for (int j = 1;j < (*alignmentMatrix)[widthSize - 1].size();j++){ + value = getDistance(widthSize, j); + value += getMinimum(widthSize, j, value); + (*alignmentMatrix)[widthSize].push_back(value); + } + + } + + if ((*alignmentMatrix).size() == endIndexX) + return true; + else + return false; + +} + + + +void TimeWarp::calculatePartSimilarityMatrix(DoubleMatrix firstChromaMatrix, DoubleMatrix secondChromaMatrix, DoubleMatrix* simMatrix, int startX, int startY, int endX){ +// printf("Calculate similarity : pointers : size %i x %i ", (int) firstChromaMatrix.size(), (int) secondChromaMatrix.size()); + + (*simMatrix).clear(); + + double distance, firstSum, secondSum; + endX = min (endX, (int)firstChromaMatrix.size()-1);//in case out of size + + for (int x = startX;x <= endX;x++){ + DoubleVector d; + + for (int y = startY;y < secondChromaMatrix.size();y++){ + + distance = 0; + firstSum = 0; + secondSum = 0; + + for (int z = 0;z < firstChromaMatrix[x].size();z++){//z is the twelve chromagram values + distance += firstChromaMatrix[x][z] * secondChromaMatrix[y][z]; + firstSum += firstChromaMatrix[x][z] * firstChromaMatrix[x][z]; + secondSum += secondChromaMatrix[y][z] * secondChromaMatrix[y][z]; + } + + if (firstSum > 0 && secondSum > 0) + distance /= sqrt(firstSum)*sqrt(secondSum); + + d.push_back( distance); + } //end for y + + (*simMatrix).push_back(d); + + }//end for x + + printf("..part sim size: %i, height: %i \n", (int) (*simMatrix).size(), (int) (*simMatrix)[0].size()); + +}//end self sim + + + + +/* +void TimeWarp::calculatePartAlignmentMatrix(int startIndexX, int startIndexY, int endIndexX, int endIndexY, DoubleMatrix* alignmentMatrix){ + printf("starting PART Alignment calculation\n"); + //initialise alignment + (*alignmentMatrix).clear(); + DoubleVector d; + d.push_back(getDistance(0,0)); + (*alignmentMatrix).push_back(d); + + bool chromaCalculated = false; + bool secondCalculated = false; + + while (!chromaCalculated || !secondCalculated) { + + if (!chromaCalculated) + chromaCalculated = extendRestrictedAlignmentAlong(startIndexX, startIndexY, endIndexX, alignmentMatrix); + + if (!secondCalculated) + secondCalculated = extendAlignmentUp(endIndexY, alignmentMatrix); + + } + printf("PART Alignment matrix calculated, size %i\n", (int) (*alignmentMatrix).size()); +} + + + + + + +bool TimeWarp::extendRestrictedAlignmentUp(int startX, int startY, int endIndexY, DoubleMatrix *alignmentMatrix){ + //adds one more value to all the columns after startX + DoubleVector d; + d = (*alignmentMatrix)[0];//alignmentMatrix[0];// + int heightSize = d.size(); + if (heightSize < endIndexY){ + for (int i = startX;i < (*alignmentMatrix).size();i++){//was < (*alignmentMatrix).size() + double value = getDistance(i, heightSize); + value += getRestrictedMinimum(i, heightSize, value, startX, startY);//min values 0 + (*alignmentMatrix)[i].push_back(value);// + } + } + if ((*alignmentMatrix)[0].size() == endIndexY) + return true; + else + return false; + +} + + +bool TimeWarp::extendRestrictedAlignmentAlong(int startX, int startY, int endIndexX, DoubleMatrix* alignmentMatrix){ + DoubleVector d; + //firstMatrix.size() + int widthSize = (*alignmentMatrix).size(); + if (widthSize < endIndexX){//firstMatrix.size() + //then we can extend along + double value = getDistance(widthSize, 0); + value += getRestrictedMinimum(widthSize, 0, value, startX, startY); + + d.push_back(value); + (*alignmentMatrix).push_back(d); + + for (int j = 1;j < (*alignmentMatrix)[widthSize - 1].size();j++){ + value = getDistance(widthSize, j); + value += getMinimum(widthSize, j, value); + (*alignmentMatrix)[widthSize].push_back(value); + } + + } + + if ((*alignmentMatrix).size() == endIndexX) + return true; + else + return false; + +} +*/ + + +void TimeWarp::calculateMinimumAlignmentPath(DoubleMatrix alignmentMatrix){ + //this requires one pass of the DTW algorithm and then works backwards from (N,M) + //to find the optimal path to (0,0), where N and M are the lengths of the two chromoVectors respectively + + backwardsAlignmentPath.clear(); + + printf("Finding minimum Path %i vs sim size %i\n", (int)chromaMatrix.size(), (int)similarityMatrix.size() ); + IntVector v; + v.push_back(similarityMatrix.size()-1);//chromaMatrix.size()-1 + backwardsAlignmentPath.push_back(v); + v.clear(); + v.push_back(similarityMatrix[0].size()-1);//secondMatrix + backwardsAlignmentPath.push_back(v); + //so now backwards path[0][0] = size(chroma) and path[1][0] = size(secondMatrix) +// printf("backwards path %i : %i \n", backwardsAlignmentPath[0][0], backwardsAlignmentPath[1][0]); + + + int indexOfBackwardsPath = 0; + while (!findPreviousMinimumInBackwardsPath()) { + indexOfBackwardsPath++; + // printf("backwards path index %i: path: %i : %i \n", indexOfBackwardsPath, backwardsAlignmentPath[0][indexOfBackwardsPath], backwardsAlignmentPath[1][indexOfBackwardsPath]); + + } + printf("final index of backwards path is %i and i is %i \n", (int) backwardsAlignmentPath[0].size()-1, indexOfBackwardsPath); + + // backwardsAlignmentIndex = backwardsAlignmentPath[0].size()-1;//remember that this goes backwards! + +} + + +void TimeWarp::extendForwardAlignmentPath(int endX){ +int forwardsIndex = forwardsAlignmentPath.size(); + int indexX = backwardsAlignmentPath[0].size() - 1; + + if (forwardsIndex == 0){ + printf("initialise forwards path..\n"); + IntVector v; + + v.push_back(backwardsAlignmentPath[0][indexX]);//chromaMatrix.size()-1 + forwardsAlignmentPath.push_back(v); + v.clear(); + v.push_back(forwardsAlignmentPath[0][indexX]);//secondMatrix + forwardsAlignmentPath.push_back(v); + indexX--; + } + + while (backwardsAlignmentPath[0][indexX] <= endX){ + addNewForwardsPath(indexX); + printf("Forwards path from index %i:: path %i : %i\n", indexX, forwardsAlignmentPath[0][forwardsIndex], forwardsAlignmentPath[1][forwardsIndex]); + indexX--; + forwardsIndex++; + } + +} + +void TimeWarp::addNewForwardsPath(int indexX){ + if (indexX < backwardsAlignmentPath[0].size()){ + forwardsAlignmentPath[0].push_back((int)backwardsAlignmentPath[0][indexX]); + forwardsAlignmentPath[1].push_back((int)backwardsAlignmentPath[1][indexX]); + } +} + + + +void TimeWarp::calculatePartMinimumAlignmentPath(int startX, int startY, int endX, int endY, DoubleMatrix alignmentMatrix){ + //this requires one pass of the DTW algorithm and then works backwards from (N,M) + //to find the optimal path to (0,0), where N and M are the lengths of the two chromoVectors respectively + + partBackwardsAlignmentPath.clear(); + + printf("Finding PART minimum Path %i vs sim size %i\n", (int)chromaMatrix.size(), (int)similarityMatrix.size() ); + + if (endX < similarityMatrix.size()){ + IntVector v; + v.push_back(endX); + partBackwardsAlignmentPath.push_back(v); + + v.clear(); + + if (endY < similarityMatrix[0].size()){ + v.push_back(endY); + partBackwardsAlignmentPath.push_back(v); + } + //so now backwards path[0][0] = endX and path[1][0] = endY + + printf("PART backwards path %i : %i \n", partBackwardsAlignmentPath[0][0], partBackwardsAlignmentPath[1][0]); + int indexOfPartBackwardsPath = 0; + /* + + while (!findPreviousMinimumInBackwardsPath()) { + indexOfBackwardsPath++; + // printf("backwards path %i : %i \n", backwardsAlignmentPath[0][indexOfBackwardsPath], backwardsAlignmentPath[1][indexOfBackwardsPath]); + + } + */ + printf("final index of backwards path is %i and i is %i \n", (int) backwardsAlignmentPath[0].size()-1, indexOfPartBackwardsPath); + }//end if endX within size + + // backwardsAlignmentIndex = backwardsAlignmentPath[0].size()-1;//remember that this goes backwards! + +} + + + +bool TimeWarp::findPreviousMinimumInBackwardsPath(){ + int chromaPosition, secondPosition; + int i,j; + i = backwardsAlignmentPath[0][backwardsAlignmentPath[0].size()-1]; + j = backwardsAlignmentPath[1][backwardsAlignmentPath[1].size()-1]; + + double newMinimum; + double *ptr; + ptr = &newMinimum; + newMinimum = alignmentMeasureMatrix[i][j]; + DoubleVector d; + + + bool finishedAligning = true; + + if (i > 0){ + if (testForNewAlignmentMinimum(ptr, i-1, j)){ + chromaPosition = i-1; + secondPosition = j; + finishedAligning = false; + } + + if (j>0 && testForNewAlignmentMinimum(ptr, i-1, j-1)){ + chromaPosition = i-1; + secondPosition = j-1; + finishedAligning = false; + } + } + + if (j > 0 && testForNewAlignmentMinimum(ptr, i, j-1)){ + chromaPosition = i; + secondPosition = j-1; + //newMinimum = alignmentMeasureMatrix[chromaPosition][secondPosition]; + finishedAligning = false; + } + + if (!finishedAligning){ + backwardsAlignmentPath[0].push_back(chromaPosition); + backwardsAlignmentPath[1].push_back(secondPosition); + } + + return finishedAligning; + +} + + + +bool TimeWarp::testForNewAlignmentMinimum(double *previousMinimum, int i, int j){ + bool newMinimumFound = false; + if (alignmentMeasureMatrix[i][j] < *previousMinimum){ + *previousMinimum = alignmentMeasureMatrix[i][j]; + newMinimumFound = true; + } + + return newMinimumFound; +} + + +int TimeWarp::findMinimumOfVector(DoubleVector *d){ + int minimumIndex = 0; + double minimumValue = (*d)[0]; + for (int i = 0;i < d->size();i++){ + if ((*d)[i] < minimumValue){ + minimumIndex = i; + minimumValue = (*d)[i]; + } + } + + return minimumIndex; +} + +double TimeWarp::getDistance(int i, int j){ + return (1 - similarityMatrix[i][j]); +} + +double TimeWarp::getMinimum(int i, int j, float newValue){ + double minimumValue = 0; + + if (i > 0){ + minimumValue = alignmentMeasureMatrix[i-1][j]; + if (j > 0){ + minimumValue = min(minimumValue, alignmentMeasureMatrix[i-1][j-1] + newValue ) ;//penalises diagonal by 2 + minimumValue = min(minimumValue, alignmentMeasureMatrix[i][j-1]); + } + } + else{//i.e. i == 0 + if (j > 0) + minimumValue = alignmentMeasureMatrix[i][j-1]; + } + + return minimumValue; +} + + +double TimeWarp::getRestrictedMinimum(int i, int j, float newValue, int minX, int minY){ + double minimumValue = 0; + + if (i > minX){ + minimumValue = alignmentMeasureMatrix[i-1][j]; + if (j > minY){ + minimumValue = min(minimumValue, alignmentMeasureMatrix[i-1][j-1] + newValue ) ;//penalises diagonal by 2 + minimumValue = min(minimumValue, alignmentMeasureMatrix[i][j-1]); + } + } + else{//i.e. i == 0 + if (j > minY) + minimumValue = alignmentMeasureMatrix[i][j-1]; + } + + return minimumValue; +} + + + +//--------------part backwards alignment------------------------ + +bool TimeWarp::findPreviousMinimumInPartBackwardsPath(){ + + int firstPosition, secondPosition; + int i,j; + i = backwardsAlignmentPath[0][backwardsAlignmentPath[0].size()-1]; + j = backwardsAlignmentPath[1][backwardsAlignmentPath[1].size()-1]; + + double newMinimum; + double *ptr; + ptr = &newMinimum; + newMinimum = alignmentMeasureMatrix[i][j]; + DoubleVector d; + + + bool finishedAligning = true; + + if (i > 0){ + if (testForNewAlignmentMinimum(ptr, i-1, j)){ + firstPosition = i-1; + secondPosition = j; + finishedAligning = false; + } + + if (j>0 && testForNewAlignmentMinimum(ptr, i-1, j-1)){ + firstPosition = i-1; + secondPosition = j-1; + finishedAligning = false; + } + } + + if (j > 0 && testForNewAlignmentMinimum(ptr, i, j-1)){ + firstPosition = i; + secondPosition = j-1; + //newMinimum = alignmentMeasureMatrix[chromaPosition][secondPosition]; + finishedAligning = false; + } + + if (!finishedAligning){ + backwardsAlignmentPath[0].push_back(firstPosition); + backwardsAlignmentPath[1].push_back(secondPosition); + } + + return finishedAligning; + +} + + + + + + + + + +//-------------------------------------------------------------- +/* +void TimeWarp::update(){ + textString = "energy index ["; + textString += ofToString(xIndex); + textString += "] = "; + textString += ofToString(energy[xIndex]); + + chordString = "Chord : "; + chordString += ofToString(rootChord[currentPlayingFrame/CHROMA_CONVERSION_FACTOR]); + + if (firstAudioFilePlaying){ + audioPosition = (*playingAudio).getPosition() * firstEnergyVector.size(); + updateAlignmentPathIndex(0); + } + else { + audioPosition = (*playingAudio).getPosition() * secondEnergyVector.size(); + updateAlignmentPathIndex(1); + } + + //if(!audioPaused) + //printScoreForRow(audioPosition/CHROMA_CONVERSION_FACTOR, (audioPosition/CHROMA_CONVERSION_FACTOR)+10); + + //the position in number of frames + //totalNumberOfFrames was used but is the most recently loaded file length + + currentPlayingFrame = audioPosition; + audioPosition = (int) audioPosition % scrollWidth ; + audioPosition /= scrollWidth; + + ofSoundUpdate(); + + +} +*/ + +/* + void TimeWarp::updateAlignmentPathIndex(int identifier){ + +// int chromaPosition = audioPosition/CHROMA_CONVERSION_FACTOR; + + while (backwardsAlignmentPath[identifier][backwardsAlignmentIndex] < chromaPosition) + { + backwardsAlignmentIndex--; + } + +} + */ + +//-------------------------------------------------------------- +/* + void TimeWarp::draw(){ + + if (drawSimilarity) + drawSimilarityMatrix(); + else + drawChromoGram(); + + +} + + +void TimeWarp::drawEnergyVectorFromPointer(DoubleVector* energyVec){ + + float screenHeight = ofGetHeight() ; + float screenWidth = ofGetWidth(); + float heightFactor = 8; + int i, j, startingFrame; + startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in + startingFrame *= scrollWidth; + + for (i = 0; i < scrollWidth - 1; i++){ + j = i + startingFrame; + ofLine(i*screenWidth/scrollWidth, screenHeight - ((*energyVec)[j]*screenHeight/heightFactor), + screenWidth*(i+1)/scrollWidth, screenHeight - ((*energyVec)[j+1]*screenHeight/heightFactor)); + + } +} + +void TimeWarp::drawSpectralDifference(DoubleMatrix* dMatrix){ + if ((*dMatrix).size()>0){ + + float screenHeight = ofGetHeight() ; + float screenWidth = ofGetWidth(); + float heightFactor = 8; + double difference; + int i, j, startingFrame; + startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in + startingFrame *= scrollWidth;//starting frame in terms of energy frames + startingFrame /= CHROMA_CONVERSION_FACTOR; //in terms of chroma frames + + + for (i = 1; i < chromoLength; i++){//changed to add 1 + j = i + startingFrame; + for (int y = 0;y < 12;y++){ + difference = (*dMatrix)[j][11-y] - (*dMatrix)[j-1][11-y]; + if (difference < 0) + difference = 0;//half wave rectify + + ofSetColor(0,0,255 * difference);//, 0; + ofRect(i*screenWidth/chromoLength,y*screenHeight/12,screenWidth/chromoLength,screenHeight/12); + }//end y + }//end i + + }///end if matrix has content + else{ + printf("Error - please load audio first"); + } + +} + + +void TimeWarp::drawChromoGram(){ + + DoubleMatrix* dptr; + DoubleVector* eptr; + string whichFileString; + + if (drawSecondMatrix){ + + dptr = &secondMatrix; + + eptr = &secondEnergyVector; + + whichFileString = "second file"; + + }else { + + dptr = &chromaMatrix; + eptr = &firstEnergyVector; + whichFileString = "first file"; + } + + + + if (drawSpectralDifferenceFunction) + drawSpectralDifference(dptr); + else + drawDoubleMatrix(dptr); + + ofSetColor(0xFF6666); + drawEnergyVectorFromPointer(eptr); + + ofDrawBitmapString(textString,80,480); + + + ofSetColor(0xFFFFFF); + ofLine(audioPosition*width, 0, audioPosition*width, height); + + + ofDrawBitmapString(chordString,80,580); + + ofDrawBitmapString(soundFileName,80,480); + + ofDrawBitmapString(whichFileString,80,80); + +} + +void TimeWarp::drawDoubleMatrix(DoubleMatrix* dMatrix){ + if ((*dMatrix).size()>0){ + + float screenHeight = ofGetHeight() ; + float screenWidth = ofGetWidth(); + float heightFactor = 8; + int i, j, startingFrame; + startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in + startingFrame *= scrollWidth;//starting frame in terms of energy frames + startingFrame /= CHROMA_CONVERSION_FACTOR; //in terms of chroma frames + + float chromoLength = scrollWidth/CHROMA_CONVERSION_FACTOR; + for (i = 0; i < chromoLength; i++){ + j = i + startingFrame; + for (int y = 0;y < 12;y++){ + ofSetColor(0,0,255 * (*dMatrix)[j][11-y]);//, 0; + ofRect(i*screenWidth/chromoLength,y*screenHeight/12,screenWidth/chromoLength,screenHeight/12); + }//end y + }//end i + + }///end if matrix has content + else{ + printf("Error - please load audio first"); + } + + +} + + +void TimeWarp::drawSimilarityMatrix(){ + + int simHeight = (similarityMatrix[0]).size(); + int simWidth = similarityMatrix.size(); + + int sizeOfMatrix = chromaMatrix.size(); + int sizeOfSecondMatrix = secondMatrix.size(); + + int startingXframe = backwardsAlignmentPath[0][backwardsAlignmentIndex] / (scrollWidth/CHROMA_CONVERSION_FACTOR); + int startingYframe = backwardsAlignmentPath[1][backwardsAlignmentIndex] / (scrollWidth/CHROMA_CONVERSION_FACTOR); + + int startingFrame = findStartWidthFrame(); + startingFrame = numberOfScrollWidthsForFirstFile * scrollWidth/CHROMA_CONVERSION_FACTOR; + + startingXframe = startingXframe * scrollWidth/CHROMA_CONVERSION_FACTOR; + startingYframe = startingYframe * scrollWidth/CHROMA_CONVERSION_FACTOR; + //need to fix for second file too + + int *indexOfAlignmentPathTested; + int lengthOfPath = backwardsAlignmentPath[0].size()-1; + indexOfAlignmentPathTested = &lengthOfPath; + + int xcoord; + for (int x = 0;x < screenWidth;x++) + { + for (int y =0;y < screenHeight;y++){ + + xcoord = (x / screenWidth) * chromoLength;//was simWidth + //xcoord += startingFrame; + xcoord += startingXframe; + + int ycoord = y * chromoLength/ screenHeight; + //ycoord += startingFrame; + ycoord += startingYframe; + + int colour = 0; + //int ycoord = y * simHeight/ screenHeight; + //y += startingFrame; + if (xcoord < sizeOfMatrix && ycoord < sizeOfSecondMatrix) + colour = similarityMatrix[xcoord][ycoord]*255; + + + ofSetColor(colour,0,0); + + ofRect(x,y,1,1); + + } + } + + drawAlignmentPath(startingXframe, startingYframe); + + //SET TEXT + string textString; + textString = "width : "; + textString += ofToString(simWidth); + + textString += " height : "; + textString += ofToString(simHeight); + + textString += " startframe : "; + textString += ofToString(startingFrame); + + textString += " Xframe : "; + textString += ofToString(startingXframe); + + textString += " Yframe : "; + textString += ofToString(startingYframe); + + textString += " currentFrame : "; + textString += ofToString(currentPlayingFrame); + + textString += " scrollwidth: "; + textString += ofToString(scrollWidth); + + textString += " xcoord: "; + textString += ofToString(xcoord); + + textString += " Clength: "; + textString += ofToString(chromoLength); + + textString += " no.Scrolls: "; + textString += ofToString(numberOfScrollWidthsForFirstFile); + //END SET TEXT + + ofSetColor(0x0000FF); + if (firstAudioFilePlaying){ + ofLine(audioPosition*screenWidth, 0, audioPosition*screenWidth, height); + checkIfAudioPositionExceedsWidthForFirstFile(); + + //draw values: + xcoord = currentPlayingFrame / CHROMA_CONVERSION_FACTOR; + ofSetColor(255, 255, 255); + for (int y = 0;y < chromoLength; y+=max(1, (int)(20 * chromoLength / screenHeight))){ + + float value = alignmentMeasureMatrix[xcoord][y+startingYframe]; + int ycoord = y * screenHeight/chromoLength; + ofDrawBitmapString(ofToString(value, 2) , audioPosition*screenWidth , ycoord); + } + } + else{ + ofLine(0, audioPosition*screenHeight, screenWidth, audioPosition*screenHeight); + } + + ofDrawBitmapString(textString,80,580); + + ofDrawBitmapString(userInfoString,80,80); + +} + + + + void TimeWarp::drawAlignmentPath(int startingChromaXFrame, int startingChromaYFrame){ + //draw alignment path + int endingChromaXFrame = startingChromaXFrame + chromoLength; + int endingChromaYFrame = startingChromaYFrame + chromoLength; + + float chromoWidth = screenWidth / chromoLength; + float chromoHeight = screenHeight / chromoLength; + + int index = backwardsAlignmentPath[0].size()-1; + //OPTIMISE XXX + + + while (backwardsAlignmentPath[0][index] < startingChromaXFrame){ + index --; + } + + int printIndex = index; + int backAlign = backwardsAlignmentPath[0][index]; + int printxcoord; + int xcoord; + + while (backwardsAlignmentPath[0][index] < endingChromaXFrame) { + xcoord = backwardsAlignmentPath[0][index]; + int ycoord = backwardsAlignmentPath[1][index]; + + printxcoord = xcoord; + int colour = similarityMatrix[xcoord][ycoord]*255; + + float value = alignmentMeasureMatrix[xcoord][ycoord] ; + + + xcoord -= startingChromaXFrame; + ycoord -= startingChromaYFrame; + ofSetColor(0,0,colour); + ofRect(xcoord*chromoWidth, ycoord*chromoHeight, chromoWidth, chromoHeight); + // ofSetColor(255, 255, 255); + // ofDrawBitmapString(ofToString(value, 2), xcoord*chromoWidth, ycoord*chromoHeight); + index--; + } + + // drawHoverAlignmentValues(); + // printf("ALIGN score :[%i] : %f \n", backwardsAlignmentPath[1][backwardsAlignmentIndex], alignmentMeasureMatrix[ backwardsAlignmentPath[0][backwardsAlignmentIndex] ][ (int) backwardsAlignmentPath[1][backwardsAlignmentIndex] ]); + + + //SET TEXT + string textString; + textString = "ALIGNMENT PATH "; + + textString += "backward A index "; + textString += ofToString(backwardsAlignmentIndex); + + textString += " starting X frame "; + textString += ofToString(startingChromaXFrame); + + textString += " initial xcoord "; + textString += ofToString(printxcoord); + + textString += " first index "; + textString += ofToString(printIndex); + + textString += " backalign[index] "; + textString += ofToString(backAlign); + + textString += " final xcoord "; + textString += ofToString(xcoord); + + + + + ofSetColor(255,255,255); + ofDrawBitmapString(textString,80,640); + + } + + + +*/ +/* +void TimeWarp::checkIfAudioPositionExceedsWidthForFirstFile() +{ + if (currentPlayingFrame > scrollWidth*(numberOfScrollWidthsForFirstFile+1)) + numberOfScrollWidthsForFirstFile++; +} + +int TimeWarp::findStartWidthFrame(){ + int startingFrame; + startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in + startingFrame *= scrollWidth;//starting frame in terms of energy frames + startingFrame /= CHROMA_CONVERSION_FACTOR; + + return startingFrame; +} + +*/ + +/* +void TimeWarp::loadSoundFiles(){ + + //assume libsndfile looks in the folder where the app is run + //therefore ../../../ gets to the bin folder + //we then need data/sounds/to get to the sound folder + //this is different to the usual OF default folder + //was const char + const char *infilename = "../../../data/sound/1-01BachBWV 846.wav"; + loadLibSndFile(infilename); + + string loadfilename = "sound/1-01BachBWV 846.wav";//PicturesMixer6.aif"; + loadedAudio.loadSound(loadfilename); + playingAudio = &loadedAudio; + +} + +void TimeWarp::loadLibSndFile(const char *infilename){ + + if (!sf_close(infile)){ + printf("closed sndfile okay \n"); + } + + // Open Input File with lib snd file + if (! (infile = sf_open (infilename, SFM_READ, &sfinfo))) + { // Open failed + printf ("SF OPEN routine Not able to open input file %s.\n", infilename) ; + // Print the error message from libsndfile. + puts (sf_strerror (NULL)) ; + + } else{ + printf("SF OPEN opened file %s okay.\n", infilename); + sndfileInfoString = "Opened okay "; + + }; + +} + */ +/* +void TimeWarp::processAudioToDoubleMatrix(Chromagram* chromaG, DoubleMatrix* myDoubleMatrix, DoubleVector* energyVector){ + //wendy + myDoubleMatrix->clear(); + energyVector->clear(); + + energyIndex = 0; + + chromaG->initialise(FRAMESIZE,2048);//framesize 512 and hopsize 2048 + chromaG->maximumChromaValue = 0; + + int readcount = 1; // counts number of samples read from sound file + printf("processing audio from doublematrix \n"); + printf("readcount %i", readcount); + while(readcount != 0 && moveOn == true) + { + + // read FRAMESIZE samples from 'infile' and save in 'data' + readcount = sf_read_float(infile, frame, FRAMESIZE); + //processing frame - downsampled to 11025Hz + //8192 samples per chroma frame + + chromaG->processframe(frame); + + if (chromaG->chromaready) + { + DoubleVector d; + + for (int i = 0;i<12;i++){ + //chromoGramVector[chromaIndex][i] = chromoGramm.rawChroma[i] / chromoGramm.maximumChromaValue; + d.push_back(chromaG->rawChroma[i]);// / chromaG->maximumChromaValue); + + } + //this would do chord detection + + myDoubleMatrix->push_back(d); + + + }//end if chromagRamm ready + + + + putEnergyInFrame(); + //get energy of the current frame and wait + double energyValue = getEnergyOfFrame(); + energyVector->push_back(energyValue); + + + }//end while readcount + + printf("Max chroma value is %f \n", chromaG->maximumChromaValue); + + //normalise + int length = myDoubleMatrix->size(); + printf("length of chromagram is %d frames\n", length); + length = (*myDoubleMatrix)[0].size(); + printf("height of dmatrix is %d\n", length); + + for (int i = 0; i < myDoubleMatrix->size();i++){ + for (int j = 0; j < ((*myDoubleMatrix)[0]).size();j++){ + (*myDoubleMatrix)[i][j] /= chromaG->maximumChromaValue; + } + } + + int size; + size = energyVector->size(); + printf("size of energy vector is %d \n", size); + + + // int size = myDoubleMatrix->size() * CHROMA_CONVERSION_FACTOR; + // printf("size of double matrix is %d and frame index %d", size, frameIndex); + +// printf("Total frames %i energy index %i and Chroma index %i \n", frameIndex, energyIndex, chromaIndex); + + +} +*/ + +//-------------------------------------------------------------- +/* +void TimeWarp::keyPressed (int key){ + if (key == '-'){ + volume -= 0.05; + volume = MAX(volume, 0); + } else if (key == '+'){ + volume += 0.05; + volume = MIN(volume, 1); + } + + if (key == OF_KEY_DOWN){ + if (scrollWidth > 600) + scrollWidth += 400; + else + scrollWidth *= 2; + + chromoLength = scrollWidth/CHROMA_CONVERSION_FACTOR; + } + + if (key == OF_KEY_UP){ + if (scrollWidth > 600) + scrollWidth -= 400; + else + scrollWidth /= 2; + + chromoLength = scrollWidth/CHROMA_CONVERSION_FACTOR; + } + + if (key == OF_KEY_LEFT){ + + (*playingAudio).setSpeed(-2); + backwardsAlignmentIndex = backwardsAlignmentPath[0].size()-1; + } + + if (key == OF_KEY_RIGHT){ + + (*playingAudio).setSpeed(2); + } + + if (key == OF_KEY_RETURN){ + loadedAudio.stop(); + audioPlaying = false; + audioPaused = true; + initialiseVariables(); + } + + if (key == ' '){ + if (!audioPlaying) { + (*playingAudio).play(); + (*playingAudio).setPaused(false); + secondAudio.play(); + secondAudio.setPaused(true); + + firstAudioFilePlaying = true; + + audioPlaying = true; + audioPaused = false; + } + else{ + audioPaused = !audioPaused; + (*playingAudio).setPaused(audioPaused); + } + + } + + if (key == 'p'){ + swapBetweenPlayingFilesUsingAlignmentMatch(); + + } + + if (key == 'o'){ + openNewAudioFileWithdialogBox(); + } + + if (key == 'l'){ + //open audio file + string *filePtr, secondFileName; + filePtr = &secondFileName; + //so filePtr points to secondFileName + + if (getFilenameFromDialogBox(filePtr)){ + printf("Loaded name okay :\n'%s' \n", secondFileName.c_str()); + } + + loadSecondAudio(secondFileName); + + calculateSimilarityMatrix(); + calculateAlignmentMatrix(); + calculateMinimumAlignmentPath(); + + } + + if (key == 's'){ + drawSimilarity = !drawSimilarity; + } + + + if (key == 'm'){ + drawSecondMatrix = !drawSecondMatrix; + } + + if (key == 'd'){ + drawSpectralDifferenceFunction = !drawSpectralDifferenceFunction; + } + +} + +//-------------------------------------------------------------- +void TimeWarp::keyReleased (int key){ + if (key == OF_KEY_LEFT || OF_KEY_RIGHT){ + (*playingAudio).setSpeed(1); + backwardsAlignmentIndex = backwardsAlignmentPath[0].size()-1; + } + +} +*/ +/* +void TimeWarp::openNewAudioFileWithdialogBox(){ + + //open audio file + string *filePtr; + filePtr = &soundFileName; + + if (getFilenameFromDialogBox(filePtr)){ + printf("Mainfile: Loaded name okay :\n'%s' \n", soundFileName.c_str()); + } + + //openFileDialogBox(); - replaced this lone by call to openFile Dialoguebox + loadNewAudio(soundFileName); + +} + */ +/* +//-------------------------------------------------------------- +void TimeWarp::mouseMoved(int x, int y ){ + width = ofGetWidth(); + pan = (float)x / (float)width; + float height = (float)ofGetHeight(); + float heightPct = ((height-y) / height); + targetFrequency = 2000.0f * heightPct; + phaseAdderTarget = (targetFrequency / (float) sampleRate) * TWO_PI; + xIndex = (int)(pan*ENERGY_LENGTH); +} + +//-------------------------------------------------------------- +void TimeWarp::mouseDragged(int x, int y, int button){ + width = ofGetWidth(); + pan = (float)x / (float)width; +} + +//-------------------------------------------------------------- +void TimeWarp::mousePressed(int x, int y, int button){ + bNoise = true; + moveOn = true; +} + + +//-------------------------------------------------------------- +void TimeWarp::mouseReleased(int x, int y, int button){ + bNoise = false; +} + +//-------------------------------------------------------------- +void TimeWarp::windowResized(int w, int h){ + width = w; + height = h; + screenHeight = ofGetHeight() ; + screenWidth = ofGetWidth(); + +} +*/ + +//-------------------------------------------------------------- +/* + +bool TimeWarp::getFilenameFromDialogBox(string* fileNameToSave){ + //this uses a pointer structure within the loader and returns true if the dialogue box was used successfully + // first, create a string that will hold the URL + string URL; + + // openFile(string& URL) returns 1 if a file was picked + // returns 0 when something went wrong or the user pressed 'cancel' + int response = ofxFileDialogOSX::openFile(URL); + if(response){ + // now you can use the URL + *fileNameToSave = URL; + //printf("\n filename is %s \n", soundFileName.c_str()); + return true; + } + else { + // soundFileName = "OPEN canceled. "; + printf("\n open file cancelled \n"); + return false; + } + +} +*/ + + +/* +void TimeWarp::putEnergyInFrame(){ + + + float totalEnergyInFrame = 0; + + for (int i = 0;i<FRAMESIZE;i++){ + + totalEnergyInFrame += (frame[i] * frame[i]); + + } + totalEnergyInFrame = sqrt(totalEnergyInFrame); + + if (energyIndex < ENERGY_LENGTH){ + energy[energyIndex] = totalEnergyInFrame; + energyIndex++; + } + +} + */ + + + +/* +void TimeWarp::printAlignmentMatrix(){ + + int size = alignmentMeasureMatrix.size(); + printf("\n _ _ _ _\n"); + printf("align size is %i \n", size); + + int i,j; + DoubleVector d; + int rowSize = alignmentMeasureMatrix.size(); + d = alignmentMeasureMatrix[0];//choose initial size + + for (int j = 0;j < d.size();j++){ + printf("row %i : ", j); + + for (i = 0;i < rowSize;i++){ + d = alignmentMeasureMatrix[i]; + + // printf("row %i , col %i, val : %f \n", i, j, alignmentMeasureMatrix[i][j] ); + printf("%f , ", alignmentMeasureMatrix[i][j] ); + } + printf("\n"); + } + printf("...............\n"); + +} + + +void TimeWarp::printScoreForRow(int row, int max){ + printf("alignment scores row %i \n", row); + float minimum = alignmentMeasureMatrix[row][0]; + int minimumIndex = 0; + for (int i =0;i < max;i++){ + printf("[%i] %f ", i, alignmentMeasureMatrix[row][i]); + if (alignmentMeasureMatrix[row][i] < minimum) + { + minimum = alignmentMeasureMatrix[row][i] ; + minimumIndex = i; + } + printf(" \n"); + } + printf("Minimum [%i] : %f \n", minimumIndex, minimum); + printf("ALIGN score :[%i] : %f \n", backwardsAlignmentPath[1][backwardsAlignmentIndex], alignmentMeasureMatrix[ backwardsAlignmentPath[0][backwardsAlignmentIndex] ][ (int) backwardsAlignmentPath[1][backwardsAlignmentIndex] ]); + + +} +*/ + + + + +/* + void TimeWarp::swapBetweenPlayingFilesUsingAlignmentMatch(){ + ofSoundUpdate(); + //swapping between files + //printf("current playing (energy scale) frame was %i \n", currentPlayingFrame); + float oldPosition = (*playingAudio).getPosition(); + printf("playing position is %f \n", (*playingAudio).getPosition()); + + //(*playingAudio).stop(); + (*playingAudio).setPaused(true); + int newIndicator; + if (firstAudioFilePlaying){ + playingAudio = &secondAudio; + newIndicator = 1; + } + else{ + playingAudio = &loadedAudio; + newIndicator = 0; + } + printf("new indicator %i \n", newIndicator); + + printf("playing pos according to energy frames is %f \n ", + (currentPlayingFrame/((float)backwardsAlignmentPath[1-newIndicator][0]*CHROMA_CONVERSION_FACTOR)) ); + + printf("predicts frame to be %f \n", (oldPosition*backwardsAlignmentPath[1-newIndicator][0])); + + currentChromaFrame = oldPosition * (float) backwardsAlignmentPath[1-newIndicator][0]; + printf("current chroma frame %i and using energy frames would have been %i \n", currentChromaFrame, currentPlayingFrame / CHROMA_CONVERSION_FACTOR); + int matchingFrame = findMatchFromAlignment(firstAudioFilePlaying); + + float relativePosition = matchingFrame / (float) backwardsAlignmentPath[newIndicator][0]; + //i.e. the position as float [0,1] 0:beginning, 1 is end + + (*playingAudio).setPaused(false); + // secondAudio.setPosition(relativePosition);//XXX tmp line + (*playingAudio).setPosition(relativePosition); + + printf("matching frame is %i and length is %i \n", matchingFrame, backwardsAlignmentPath[newIndicator][0]); + printf("new playing position is %f \n", (*playingAudio).getPosition()); + + firstAudioFilePlaying = !firstAudioFilePlaying; + + + } + */ +/* + int TimeWarp::findMatchFromAlignment(bool whichFileToTest){ + //could use technique from middle of file and go either way to reduce latency for long search? + //- (not that this is a problem yet) + int indicator; + if (whichFileToTest) + indicator = 0; + else + indicator = 1; + + int oppositeIndicator = 1 - indicator; + + int frame = backwardsAlignmentPath[indicator].size()-1; + + // int currentChromaFrame = currentPlayingFrame / CHROMA_CONVERSION_FACTOR; + //trying this instead + + + + while (backwardsAlignmentPath[indicator][frame] < currentChromaFrame){ + frame--; + } + //printf("frame found is %i \n", frame); + int frameToSwitchTo = backwardsAlignmentPath[oppositeIndicator][frame]; + + float calculatedPosition = (currentChromaFrame / (float) backwardsAlignmentPath[indicator][0]); + + printf("(length was %i)\n", backwardsAlignmentPath[indicator][0]); + + printf("compares to position calculated from chroma length %f \n", calculatedPosition); + printf("current frame %i maps to new frame %i \n", currentChromaFrame, frameToSwitchTo); + printf("relative position of new frame is %f \n", (frameToSwitchTo / (float) backwardsAlignmentPath[oppositeIndicator][0]) ); + return frameToSwitchTo; + + } + + */ + + + +/* + double TimeWarp::getEnergyOfFrame(){ + + + float totalEnergyInFrame = 0; + + for (int i = 0;i<FRAMESIZE;i++){ + + totalEnergyInFrame += (frame[i] * frame[i]); + + } + totalEnergyInFrame = sqrt(totalEnergyInFrame); + + return totalEnergyInFrame; + } + */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/TimeWarp.h Wed Jun 08 17:35:56 2011 +0100 @@ -0,0 +1,125 @@ +/* + * TimeWarp.h + * chromaReader13 + * + * Created by Andrew on 16/05/2011. + * Copyright 2011 QMUL. All rights reserved. + * + */ + +#ifndef _TIME_WARP +#define _TIME_WARP + + +#include "ofMain.h" +#include "chromaGram.h" +#include "ChordDetect.h" +#include "sndfile.h" +#include "ofxFileDialogOSX.h" + + +#define FRAMESIZE 512 +#define ENERGY_LENGTH 80000 +#define CHROMA_LENGTH 12000 +#define CHROMA_CONVERSION_FACTOR 16 //16 times as many frames in energy as in chroma +//length in terms of frames (at 512 samples per frame - there are 90 per second) => 900: 10 seconds +#define ALIGNMENT_FRAMESIZE 128 + +class TimeWarp : public ofBaseApp{ + +public: + TimeWarp(); // constructor + ~TimeWarp(); + + void initialiseVariables(); + + //variables + typedef std::vector<double> DoubleVector; + typedef std::vector<DoubleVector> DoubleMatrix; + + DoubleMatrix chromaMatrix; + DoubleMatrix secondMatrix; + DoubleMatrix* matrixPtr; + + DoubleVector firstEnergyVector; + DoubleVector secondEnergyVector; + + DoubleMatrix firstChromaEnergyMatrix; + DoubleMatrix secondChromaEnergyMatrix; + + Chromagram chromoGramm; + Chromagram secondChromoGramm; + + DoubleMatrix similarityMatrix; + DoubleMatrix tmpSimilarityMatrix; + DoubleMatrix alignmentMeasureMatrix; + DoubleMatrix tmpAlignmentMeasureMatrix; + DoubleVector minimumAlignmentPath; + + double partAlignmentMeasureMatrix[ALIGNMENT_FRAMESIZE][ALIGNMENT_FRAMESIZE]; + + typedef std::vector<int> IntVector; + typedef std::vector<IntVector> IntMatrix; + IntMatrix backwardsAlignmentPath; + IntMatrix tmpBackwardsPath; + + int backwardsAlignmentIndex; + + IntMatrix partBackwardsAlignmentPath; + IntMatrix forwardsAlignmentPath; + + int partBackwardsAlignmentIndex; + + + void createCombinedMatrix(DoubleMatrix myChromaMatrix, DoubleVector energyVector, DoubleMatrix* chromaEnergyMatrix); + + void calculateSimilarityMatrix(); + + + + + //new addition + void calculateSimilarityMatrixWithPointers(DoubleMatrix firstChromaMatrix, DoubleMatrix secondChromaMatrix, DoubleMatrix* simMatrix); + DoubleMatrix superAlignmentMeasureMatrix; //for the onset + chromagram alignment + DoubleVector superMinimumAlignmentPath; + //end new additions + + int findStartWidthFrame(); + + + + + + void calculateAlignmentMatrix(DoubleMatrix firstMatrix, DoubleMatrix secondMatrix, DoubleMatrix *alignmentMatrix); + double getDistance(int i, int j); + + double getRestrictedMinimum(int i, int j, float newValue, int minX, int minY); + bool extendRestrictedAlignmentUp(int startX, int startY, int endIndexY, DoubleMatrix *alignmentMatrix); + bool extendRestrictedAlignmentAlong(int startX, int startY, int endIndexX, DoubleMatrix* alignmentMatrix); + + double getMinimum(int i, int j, float newValue); + bool extendAlignmentUp(int endIndexY, DoubleMatrix *alignmentMatrix); + bool extendAlignmentAlong(int endIndexX, DoubleMatrix *alignmentMatrix); + void calculateMinimumAlignmentPath(DoubleMatrix alignmentMatrix); + void extendForwardAlignmentPath(int endX); + + + bool findPreviousMinimumInBackwardsPath(); + bool testForNewAlignmentMinimum(double *previousMinimum, int i, int j); + + int findMinimumOfVector(DoubleVector *d); + + + void addNewForwardsPath(int indexX); + + void calculatePartSimilarityMatrix(DoubleMatrix firstChromaMatrix, DoubleMatrix secondChromaMatrix, DoubleMatrix* simMatrix, int startX, int startY, int endX); + +// void calculatePartAlignmentMatrix(int startIndexX, int startIndexY, int endIndexX, int endIndexY, DoubleMatrix* alignmentMatrix); + void calculatePartMinimumAlignmentPath(int startX, int startY, int endX, int endY, DoubleMatrix alignmentMatrix); + bool findPreviousMinimumInPartBackwardsPath(); + + float diagonalPenalty; + +}; + +#endif
--- a/src/testApp.cpp Thu May 19 16:23:49 2011 +0100 +++ b/src/testApp.cpp Wed Jun 08 17:35:56 2011 +0100 @@ -23,6 +23,24 @@ //UPDATE START FRAME SO ALIGNMENT IS ALWAYS ON SCREEN //-------------------------------------------------------------- + +/* + Main functions here: + + Load file from a dialogue box with LibSndFile + We then iterate through all the samples and call our relevant functions in the timeWarp object - i.e. onset, chroma + and do the calculations for similarity and alignment + + + TO DO: + Find continual alignment between the playing file and the non-playing file + - show the current location in the energy amd chroma draw fn for the non-playing file + + simplify the loading procedure + + */ + + void testApp::setup(){ ofBackground(255,255,255); @@ -57,7 +75,9 @@ aubio_onsetdetection_t * my_onset_detection; scrollWidth = 1600; - chromoLength = scrollWidth/CHROMA_CONVERSION_FACTOR; + + conversionFactor = 1;//CHROMA_CONVERSION_FACTOR; + chromoLength = scrollWidth / conversionFactor;// CHROMA_CONVERSION_FACTOR; sfinfo.format = 0; @@ -71,9 +91,11 @@ //loading audio files loadSoundFiles(); + soundFileName = "../../../data/sound/Bach_short2.wav"; + loadFirstAudioFile(); - secondFileName = "../../../data/sound/1-01BachBWV 846_v2.wav"; + secondFileName = "../../../data/sound/Bach_short2.wav"; loadSecondAudio(secondFileName);//i.e. load same as first file @@ -81,10 +103,7 @@ tw.initialiseVariables(); - //here is the main timewarp similarity matrix calc, the minimum alignment matrix via dtw and then the backwards path estimate - tw.calculateSimilarityMatrix(); - tw.calculateAlignmentMatrix(); - tw.calculateMinimumAlignmentPath(); + calculateSimilarityAndAlignment(); printf("\n gettem hereafter!"); //set not to play @@ -105,6 +124,33 @@ } +void testApp::calculateSimilarityAndAlignment(){ + //here is the main TimeWarp similarity matrix calc, the minimum alignment matrix via dtw and then the backwards path estimate + +// tw.calculateSimilarityMatrixWithPointers(tw.chromaMatrix, tw.secondMatrix, &tw.similarityMatrix); +// tw.calculateAlignmentMatrix(tw.chromaMatrix, tw.secondMatrix, &tw.alignmentMeasureMatrix); + + tw.calculateSimilarityMatrixWithPointers(tw.firstChromaEnergyMatrix, tw.secondChromaEnergyMatrix, &tw.similarityMatrix); + tw.calculateAlignmentMatrix(tw.firstChromaEnergyMatrix, tw.secondChromaEnergyMatrix, &tw.alignmentMeasureMatrix); + tw.calculateMinimumAlignmentPath(tw.alignmentMeasureMatrix); + + int hopsize = 200; + int startFrameY = 0; + for (int startFrameX = 0;startFrameX < 400;startFrameX += hopsize){ + tw.calculatePartSimilarityMatrix(tw.firstChromaEnergyMatrix, tw.secondChromaEnergyMatrix, &tw.tmpSimilarityMatrix, startFrameX, startFrameY, startFrameX+400); + tw.calculateAlignmentMatrix(tw.firstChromaEnergyMatrix, tw.secondChromaEnergyMatrix, &tw.tmpAlignmentMeasureMatrix); + tw.calculateMinimumAlignmentPath(tw.tmpAlignmentMeasureMatrix); + tw.extendForwardAlignmentPath(200); + } + +// tw.calculatePartMinimumAlignmentPath(0, 0, 100, 100, &tw.partAlignmentMeasureMatrix); + + printf("ENERGY SIZE:%i, SIM SIZE:%i\n",(int)tw.firstEnergyVector.size(), (int)tw.similarityMatrix.size()); + conversionFactor = (int)(tw.firstEnergyVector.size() / tw.similarityMatrix.size()); + printf("CONVERSION factor %i\n", conversionFactor); + chromoLength = scrollWidth / conversionFactor;// CHROMA_CONVERSION_FACTOR; +} + void testApp::initialiseVariables(){ chromaIndex = 0; @@ -130,8 +176,8 @@ textString += "] = "; textString += ofToString(energy[xIndex]); - chordString = "Chord : "; - chordString += ofToString(rootChord[currentPlayingFrame/CHROMA_CONVERSION_FACTOR]); +// chordString = "Chord : "; +// chordString += ofToString(rootChord[currentPlayingFrame/conversionFactor]);//CHROMA_CONVERSION_FACTOR]); if (firstAudioFilePlaying){ audioPosition = (*playingAudio).getPosition() * tw.firstEnergyVector.size(); @@ -144,9 +190,7 @@ //if(!audioPaused) //printScoreForRow(audioPosition/CHROMA_CONVERSION_FACTOR, (audioPosition/CHROMA_CONVERSION_FACTOR)+10); - - //the position in number of frames - //totalNumberOfFrames was used but is the most recently loaded file length + currentPlayingFrame = audioPosition; audioPosition = (int) audioPosition % scrollWidth ; @@ -161,7 +205,7 @@ //this is the alignment where we are currently playing - i.e. switching between files - int chromaPosition = audioPosition/CHROMA_CONVERSION_FACTOR; + int chromaPosition = audioPosition/conversionFactor;//CHROMA_CONVERSION_FACTOR; while (tw.backwardsAlignmentPath[identifier][backwardsAlignmentIndex] < chromaPosition) { @@ -209,7 +253,7 @@ int i, j, startingFrame; startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in startingFrame *= scrollWidth;//starting frame in terms of energy frames - startingFrame /= CHROMA_CONVERSION_FACTOR; //in terms of chroma frames + startingFrame /= conversionFactor;// CHROMA_CONVERSION_FACTOR; //in terms of chroma frames for (i = 1; i < chromoLength; i++){//changed to add 1 @@ -286,9 +330,9 @@ int i, j, startingFrame; startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in startingFrame *= scrollWidth;//starting frame in terms of energy frames - startingFrame /= CHROMA_CONVERSION_FACTOR; //in terms of chroma frames + startingFrame /= conversionFactor;//CHROMA_CONVERSION_FACTOR; //in terms of chroma frames - float chromoLength = scrollWidth/CHROMA_CONVERSION_FACTOR; + float chromoLength = scrollWidth/conversionFactor;// CHROMA_CONVERSION_FACTOR; for (i = 0; i < chromoLength; i++){ j = min(i + startingFrame, (int) dMatrix->size()-1 ) ; for (int y = 0;y < 12;y++){ @@ -311,17 +355,17 @@ int simHeight = (tw.similarityMatrix[0]).size(); int simWidth = tw.similarityMatrix.size(); - int sizeOfMatrix = tw.chromaMatrix.size(); - int sizeOfSecondMatrix = tw.secondMatrix.size(); + int sizeOfMatrix = (int) tw.similarityMatrix.size();//tw.chromaMatrix.size(); + int sizeOfSecondMatrix = (int) tw.similarityMatrix[0].size(); - int startingXframe = tw.backwardsAlignmentPath[0][backwardsAlignmentIndex] / (scrollWidth/CHROMA_CONVERSION_FACTOR); - int startingYframe = tw.backwardsAlignmentPath[1][backwardsAlignmentIndex] / (scrollWidth/CHROMA_CONVERSION_FACTOR); + int startingXframe = tw.backwardsAlignmentPath[0][backwardsAlignmentIndex] / (scrollWidth/conversionFactor); + int startingYframe = tw.backwardsAlignmentPath[1][backwardsAlignmentIndex] / (scrollWidth/conversionFactor); int startingFrame = findStartWidthFrame(); - startingFrame = numberOfScrollWidthsForFirstFile * scrollWidth/CHROMA_CONVERSION_FACTOR; + startingFrame = numberOfScrollWidthsForFirstFile * scrollWidth/conversionFactor; - startingXframe = startingXframe * scrollWidth/CHROMA_CONVERSION_FACTOR; - startingYframe = startingYframe * scrollWidth/CHROMA_CONVERSION_FACTOR; + startingXframe = startingXframe * scrollWidth/conversionFactor; + startingYframe = startingYframe * scrollWidth/conversionFactor; //need to fix for second file too int *indexOfAlignmentPathTested; @@ -356,6 +400,7 @@ } drawAlignmentPath(startingXframe, startingYframe); + drawForwardsAlignmentPath(startingXframe, startingYframe); //SET TEXT string textString; @@ -396,7 +441,7 @@ checkIfAudioPositionExceedsWidthForFirstFile(); //draw values: - xcoord = currentPlayingFrame / CHROMA_CONVERSION_FACTOR; + xcoord = currentPlayingFrame / conversionFactor; ofSetColor(255, 255, 255); for (int y = 0;y < chromoLength; y+=max(1, (int)(20 * chromoLength / screenHeight))){ @@ -426,7 +471,7 @@ int startingFrame; startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in startingFrame *= scrollWidth;//starting frame in terms of energy frames - startingFrame /= CHROMA_CONVERSION_FACTOR; + startingFrame /= conversionFactor;// CHROMA_CONVERSION_FACTOR; return startingFrame; } @@ -453,8 +498,8 @@ int xcoord; while (tw.backwardsAlignmentPath[0][index] < endingChromaXFrame) { - xcoord = tw.backwardsAlignmentPath[0][index]; - int ycoord = tw.backwardsAlignmentPath[1][index]; + xcoord = min((int)(tw.similarityMatrix.size())-1,tw.backwardsAlignmentPath[0][index]); + int ycoord = min((int)tw.backwardsAlignmentPath[1][index], (int)(tw.alignmentMeasureMatrix[0].size())-1); printxcoord = xcoord; int colour = tw.similarityMatrix[xcoord][ycoord]*255; @@ -510,6 +555,52 @@ + +void testApp::drawForwardsAlignmentPath(int startingChromaXFrame, int startingChromaYFrame){ + if (tw.forwardsAlignmentPath.size() > 0){ + int endingChromaXFrame = startingChromaXFrame + chromoLength; + int endingChromaYFrame = startingChromaYFrame + chromoLength; + + float chromoWidth = screenWidth / chromoLength; + float chromoHeight = screenHeight / chromoLength; + + int index = 0; + //OPTIMISE XXX + + while (tw.forwardsAlignmentPath[0][index] < startingChromaXFrame){ + //get to NOW + index ++; + } + +// int printIndex = index; +// int forwardsAlign = tw.forwardsAlignmentPath[0][index]; +// int printxcoord; + int xcoord; + + while (index < tw.forwardsAlignmentPath[0].size() && tw.forwardsAlignmentPath[0][index] < endingChromaXFrame) { + xcoord = min((int)(tw.similarityMatrix.size())-1,tw.forwardsAlignmentPath[0][index]); + int ycoord = min((int)tw.forwardsAlignmentPath[1][index], (int)(tw.alignmentMeasureMatrix[0].size())-1); + +// printxcoord = xcoord; + int colour = 255;//tw.similarityMatrix[xcoord][ycoord]*255; + //float value = tw.alignmentMeasureMatrix[xcoord][ycoord] ; + + xcoord -= startingChromaXFrame; + ycoord -= startingChromaYFrame; + ofSetColor(0,colour,0); + ofRect(xcoord*chromoWidth, ycoord*chromoHeight, chromoWidth, chromoHeight); + index++; + }//end while + + }//end if forwards path exista + +} + + + + + + void testApp::loadSoundFiles(){ //assume libsndfile looks in the folder where the app is run @@ -517,10 +608,10 @@ //we then need data/sounds/to get to the sound folder //this is different to the usual OF default folder //was const char - const char *infilename = "../../../data/sound/1-01BachBWV 846.wav"; + const char *infilename = "../../../data/sound/Bach_short1.wav"; loadLibSndFile(infilename); - string loadfilename = "sound/1-01BachBWV 846.wav";//PicturesMixer6.aif"; + string loadfilename = "sound/Bach_short1.wav";//PicturesMixer6.aif"; loadedAudio.loadSound(loadfilename); playingAudio = &loadedAudio; @@ -598,18 +689,14 @@ energyVector->push_back(energyValue); if (energyValue > maximumEnergyValue) maximumEnergyValue = energyValue; - + }//end while readcount printf("Max chroma value is %f \n", chromaG.maximumChromaValue); - - //normalise - //int length = myDoubleMatrix->size(); printf("length of chromagram is %d frames\n", (int)myDoubleMatrix->size()); - //length = (*myDoubleMatrix)[0].size(); - printf("height of dmatrix is %d\n", (int)(*myDoubleMatrix)[0].size()); - + printf("height of dmatrix is %d\n", (int)(*myDoubleMatrix)[0].size()); + //normalise chroma matrix for (int i = 0; i < myDoubleMatrix->size();i++){ for (int j = 0; j < ((*myDoubleMatrix)[0]).size();j++){ //non-causal normalisation @@ -617,15 +704,15 @@ } } - printf("size of energy vector is %d \n", (int)energyVector->size()); - + + printf("size of energy vector is %d \n", (int)energyVector->size()); + //non causal normalisation for (int i = 0; i < energyVector->size();i++){ (*energyVector)[i] /= maximumEnergyValue; } - totalNumberOfFrames = (int)energyVector->size(); - - chromaConversionRatio = myDoubleMatrix->size() / totalNumberOfFrames; +// totalNumberOfFrames = (int)energyVector->size(); + chromaConversionRatio = myDoubleMatrix->size() / (int)energyVector->size(); // int size = myDoubleMatrix->size() * CHROMA_CONVERSION_FACTOR; @@ -648,7 +735,7 @@ else scrollWidth *= 2; - chromoLength = scrollWidth/CHROMA_CONVERSION_FACTOR; + chromoLength = scrollWidth/conversionFactor;// CHROMA_CONVERSION_FACTOR; } if (key == OF_KEY_UP){ @@ -657,7 +744,7 @@ else scrollWidth /= 2; - chromoLength = scrollWidth/CHROMA_CONVERSION_FACTOR; + chromoLength = scrollWidth/conversionFactor;// CHROMA_CONVERSION_FACTOR; } if (key == OF_KEY_LEFT){ @@ -718,11 +805,8 @@ loadSecondAudio(secondFileName); - tw.calculateSimilarityMatrix(); - tw.calculateAlignmentMatrix(); - //printf("yabbo"); - tw.calculateMinimumAlignmentPath(); - //printf("got here!"); + calculateSimilarityAndAlignment(); + } if (key == 's'){ @@ -784,7 +868,7 @@ //-------------------------------------------------------------- void testApp::mousePressed(int x, int y, int button){ bNoise = true; - moveOn = true; + //moveOn = true; } @@ -889,6 +973,7 @@ eptr = &(tw.firstEnergyVector); */ processAudioToDoubleMatrix(&tw.chromaMatrix, &tw.firstEnergyVector); + tw.createCombinedMatrix(tw.chromaMatrix, tw.firstEnergyVector, &tw.firstChromaEnergyMatrix); } @@ -899,34 +984,21 @@ const char *infilename = soundFileName.c_str() ; loadLibSndFile(infilename); - Chromagram* cptr; +/* Chromagram* cptr; DoubleMatrix* dptr; DoubleVector* eptr; cptr = &(tw.secondChromoGramm); dptr = &(tw.secondMatrix); eptr = &(tw.secondEnergyVector); + */ - processAudioToDoubleMatrix(dptr, eptr);//chromaMatrix); + processAudioToDoubleMatrix(&tw.secondMatrix, &tw.secondEnergyVector);//dptr, eptr);//chromaMatrix); + tw.createCombinedMatrix(tw.secondMatrix, tw.secondEnergyVector, &tw.secondChromaEnergyMatrix); } -double testApp::getEnergyOfFrame(){ - - - float totalEnergyInFrame = 0; - - for (int i = 0;i<FRAMESIZE;i++){ - - totalEnergyInFrame += (frame[i] * frame[i]); - - } - totalEnergyInFrame = sqrt(totalEnergyInFrame); - - return totalEnergyInFrame; -} - void testApp::swapBetweenPlayingFilesUsingAlignmentMatch(){ ofSoundUpdate(); //swapping between files @@ -945,17 +1017,16 @@ playingAudio = &loadedAudio; newIndicator = 0; } + printf("new indicator %i \n", newIndicator); - printf("playing pos according to energy frames is %f \n ", - (currentPlayingFrame/((float)tw.backwardsAlignmentPath[1-newIndicator][0]*CHROMA_CONVERSION_FACTOR)) ); - - printf("predicts frame to be %f \n", (oldPosition*tw.backwardsAlignmentPath[1-newIndicator][0])); + (currentPlayingFrame/((float)tw.backwardsAlignmentPath[1-newIndicator][0]* conversionFactor)) );//CHROMA_CONVERSION_FACTOR + printf("predicts frame to be %f \n", (oldPosition*tw.backwardsAlignmentPath[1-newIndicator][0])); currentChromaFrame = oldPosition * (float) tw.backwardsAlignmentPath[1-newIndicator][0]; - printf("current chroma frame %i and using energy frames would have been %i \n", currentChromaFrame, currentPlayingFrame / CHROMA_CONVERSION_FACTOR); - int matchingFrame = findMatchFromAlignment(firstAudioFilePlaying); - + printf("current chroma frame %i and using energy frames would have been %i \n", currentChromaFrame, currentPlayingFrame / conversionFactor);//CHROMA_CONVERSION_FACTOR); + + int matchingFrame = findMatchFromAlignment(firstAudioFilePlaying); float relativePosition = matchingFrame / (float) tw.backwardsAlignmentPath[newIndicator][0]; //i.e. the position as float [0,1] 0:beginning, 1 is end @@ -1001,45 +1072,6 @@ } -/* -int testApp::findMinimumOfVector(DoubleVector *d){ - int minimumIndex = 0; - double minimumValue = (*d)[0]; - for (int i = 0;i < d->size();i++){ - if ((*d)[i] < minimumValue){ - minimumIndex = i; - minimumValue = (*d)[i]; - } - } - - return minimumIndex; -} - */ -/* -double testApp::getDistance(int i, int j){ - return (1 - similarityMatrix[i][j]); -} - -double testApp::getMinimum(int i, int j, float newValue){ - double minimumValue = 0; - - if (i > 0){ - minimumValue = tw.alignmentMeasureMatrix[i-1][j]; - if (j > 0){ - minimumValue = min(minimumValue, alignmentMeasureMatrix[i-1][j-1] + newValue ) ;//penalises diagonal by 2 - minimumValue = min(minimumValue, alignmentMeasureMatrix[i][j-1]); - } - } - else{//i.e. i == 0 - if (j > 0) - minimumValue = tw.alignmentMeasureMatrix[i][j-1]; - } - - return minimumValue; -} - -*/ - void testApp::printSimilarityMatrix(int sizeToPrint){ printf("\n _ _ _ _\n"); @@ -1320,3 +1352,44 @@ return newMinimumFound; } */ + + +/* + int testApp::findMinimumOfVector(DoubleVector *d){ + int minimumIndex = 0; + double minimumValue = (*d)[0]; + for (int i = 0;i < d->size();i++){ + if ((*d)[i] < minimumValue){ + minimumIndex = i; + minimumValue = (*d)[i]; + } + } + + return minimumIndex; + } + */ +/* + double testApp::getDistance(int i, int j){ + return (1 - similarityMatrix[i][j]); + } + + double testApp::getMinimum(int i, int j, float newValue){ + double minimumValue = 0; + + if (i > 0){ + minimumValue = tw.alignmentMeasureMatrix[i-1][j]; + if (j > 0){ + minimumValue = min(minimumValue, alignmentMeasureMatrix[i-1][j-1] + newValue ) ;//penalises diagonal by 2 + minimumValue = min(minimumValue, alignmentMeasureMatrix[i][j-1]); + } + } + else{//i.e. i == 0 + if (j > 0) + minimumValue = tw.alignmentMeasureMatrix[i][j-1]; + } + + return minimumValue; + } + + */ +
--- a/src/testApp.h Thu May 19 16:23:49 2011 +0100 +++ b/src/testApp.h Wed Jun 08 17:35:56 2011 +0100 @@ -42,7 +42,7 @@ void audioRequested (float * input, int bufferSize, int nChannels); void loadSndfile(); - double getEnergyOfFrame(); + //double getEnergyOfFrame(); void drawChromoGram(); @@ -50,8 +50,9 @@ void loadFirstAudioFile(); void initialiseVariables(); - - typedef std::vector<double> DoubleVector; + void calculateSimilarityAndAlignment(); + + typedef std::vector<double> DoubleVector; typedef std::vector<DoubleVector> DoubleMatrix; // DoubleMatrix chromaMatrix; @@ -77,6 +78,7 @@ // DoubleVector minimumAlignmentPath; void drawAlignmentPath(int startingChromaXFrame, int startingChromaYFrame); + void drawForwardsAlignmentPath(int startingChromaXFrame, int startingChromaYFrame); int findStartWidthFrame(); void printScoreForRow(int row, int max); @@ -126,7 +128,7 @@ //int* firstAudioLength, secondAudioLength; - string soundFileName, secondFileName; + string firstFileName, secondFileName, soundFileName; float screenHeight, screenWidth; @@ -176,7 +178,7 @@ float audioPosition; float width, height; int chromaIndex; - int totalNumberOfFrames; + // int totalNumberOfFrames; int currentPlayingFrame; int currentChromaFrame ; string chordString; @@ -191,9 +193,11 @@ SF_INFO sfinfo ; // struct to hold info about sound file int chromaConversionRatio;//not needed but could be useful - timeWarp tw; + TimeWarp tw; Chromagram chromaG; OnsetDetectionFunction* onset; + + int conversionFactor; }; #endif
--- a/src/timeWarp.cpp Thu May 19 16:23:49 2011 +0100 +++ b/src/timeWarp.cpp Wed Jun 08 17:35:56 2011 +0100 @@ -38,15 +38,15 @@ // destructor TimeWarp :: ~TimeWarp(){ + chromaMatrix.clear(); secondMatrix.clear(); - //matrixPtr.clear(); firstEnergyVector.clear(); secondEnergyVector.clear(); similarityMatrix.clear(); alignmentMeasureMatrix.clear(); - + //matrixPtr.clear(); //chromoGramm.~ChromoGram(); //secondChromoGramm; @@ -55,46 +55,67 @@ } void TimeWarp::initialiseVariables(){ - diagonalPenalty = 2;//penalises diagonal so all path gradients equal weighting + diagonalPenalty = 1;//penalises diagonal so all path gradients equal weighting //chromoGramm.initialise(FRAMESIZE,2048);//framesize 512 and hopsize 2048 } +void TimeWarp::createCombinedMatrix(DoubleMatrix myChromaMatrix, DoubleVector energyVector, DoubleMatrix* chromaEnergyMatrix){ + chromaEnergyMatrix->clear(); + int sizeRatio = energyVector.size() / myChromaMatrix.size();// + printf("COMBINE: size of my chroma is %i\n", (int) myChromaMatrix.size());// energyVector.size() / myChromaMatrix.size(); + printf("COMBINED: size ratio of energy to chroma is %i \n", sizeRatio); + int chromaSize = myChromaMatrix.size(); +// printf("index is %i\n", index); + + for (int i = 0;i < energyVector.size();i++){ + DoubleVector d; + int index = min(chromaSize-1, (int) floor(i/sizeRatio)); + + for (int y = 0;y < 12;y++){ + d.push_back(myChromaMatrix[index][y]);// + } + + + d.push_back(energyVector[i]); + (*chromaEnergyMatrix).push_back(d); + } + printf("COMBINED: size of chroma energy is %i\n", (int)(*chromaEnergyMatrix).size()); + + int x = (int)(*chromaEnergyMatrix).size()/3; +// printf("energy[%i] %f \n", x, energyVector[x]); /* -double TimeWarp::getEnergyOfFrame(){ - - - float totalEnergyInFrame = 0; - - for (int i = 0;i<FRAMESIZE;i++){ - - totalEnergyInFrame += (frame[i] * frame[i]); - + for (int y = 0;y < 13;y++){ + printf("chroma[%i][%i] %f \n", x, y, myChromaMatrix[x/sizeRatio][y]); + printf("c[%i][%i] %f \n", x, y, (*chromaEnergyMatrix)[x][y]); } - totalEnergyInFrame = sqrt(totalEnergyInFrame); - - return totalEnergyInFrame; + printf("\n"); +*/ + } - */ - - void TimeWarp::calculateSimilarityMatrix(){ + calculateSimilarityMatrixWithPointers(chromaMatrix, secondMatrix, &similarityMatrix); + + /* similarityMatrix.clear(); - printf("calculating similarity matrix..."); + printf("calculating similarity matrix...") // userInfoString = "calculating similarity matrix..."; double distance, firstSum, secondSum; for (int x = 0;x < chromaMatrix.size();x++){ DoubleVector d; - for (int y = 0;y < secondMatrix.size();y++){ + + + for (int y = 0;y < secondMatrix.size();y++){ distance = 0; firstSum = 0; secondSum = 0; + for (int z = 0;z < chromaMatrix[x].size();z++){//z is the twelve chromagram values distance += chromaMatrix[x][z] * secondMatrix[y][z]; @@ -114,21 +135,58 @@ similarityMatrix.push_back(d); }//end for x - // userInfoString += "; size ="; - // userInfoString += ofToString(similarityMatrix.size() , 0); - printf("..sim size: %i, height: %i \n", (int) similarityMatrix.size(), (int) (chromaMatrix[0]).size()); + */ +// printf("..sim size: %i, height: %i \n", (int) similarityMatrix.size(), (int) (chromaMatrix[0]).size()); }//end self sim -void TimeWarp::calculateAlignmentMatrix(){ + +void TimeWarp::calculateSimilarityMatrixWithPointers(DoubleMatrix firstChromaMatrix, DoubleMatrix secondChromaMatrix, DoubleMatrix* simMatrix){ + printf("Calculate similarity : pointers : size %i x %i ", (int) firstChromaMatrix.size(), (int) secondChromaMatrix.size()); + (*simMatrix).clear(); + + double distance, firstSum, secondSum; + + for (int x = 0;x < firstChromaMatrix.size();x++){ + DoubleVector d; + + for (int y = 0;y < secondChromaMatrix.size();y++){ + + distance = 0; + firstSum = 0; + secondSum = 0; + + for (int z = 0;z < firstChromaMatrix[x].size();z++){//z is the twelve chromagram values + distance += firstChromaMatrix[x][z] * secondChromaMatrix[y][z]; + firstSum += firstChromaMatrix[x][z] * firstChromaMatrix[x][z]; + secondSum += secondChromaMatrix[y][z] * secondChromaMatrix[y][z]; + } + + if (firstSum > 0 && secondSum > 0) + distance /= sqrt(firstSum)*sqrt(secondSum); + + d.push_back( distance); + } //end for y + + (*simMatrix).push_back(d); + + }//end for x + + printf("..sim size: %i, height: %i \n", (int) (*simMatrix).size(), (int) (*simMatrix)[0].size()); + +}//end self sim + + +void TimeWarp::calculateAlignmentMatrix(DoubleMatrix firstMatrix, DoubleMatrix secondMatrix, DoubleMatrix* alignmentMatrix){//, DoubleMatrix simMatrix + printf("starting Alignment calculation\n"); //initialise alignment - alignmentMeasureMatrix.clear(); + (*alignmentMatrix).clear(); DoubleVector d; d.push_back(getDistance(0,0)); - alignmentMeasureMatrix.push_back(d); + (*alignmentMatrix).push_back(d); bool chromaCalculated = false; bool secondCalculated = false; @@ -136,28 +194,28 @@ while (!chromaCalculated || !secondCalculated) { if (!chromaCalculated) - chromaCalculated = extendAlignmentAlong(); + chromaCalculated = extendAlignmentAlong((int) firstMatrix.size(), alignmentMatrix); if (!secondCalculated) - secondCalculated = extendAlignmentUp(); + secondCalculated = extendAlignmentUp((int) secondMatrix.size(), alignmentMatrix); } - + printf("Alignment matrix calculated, size %i\n", (int) (*alignmentMatrix).size()); } -bool TimeWarp::extendAlignmentUp(){ +bool TimeWarp::extendAlignmentUp(int endIndexY, DoubleMatrix *alignmentMatrix){ DoubleVector d; - d = alignmentMeasureMatrix[0];//alignmentMatrix[0];// + d = (*alignmentMatrix)[0];//alignmentMatrix[0];// int heightSize = d.size(); - if (heightSize < secondMatrix.size()){ + if (heightSize < endIndexY){ //then we haven't finished yet - for (int i = 0;i < alignmentMeasureMatrix.size();i++){ + for (int i = 0;i < (*alignmentMatrix).size();i++){ double value = getDistance(i, heightSize); - value += getMinimum(i, heightSize, value); - alignmentMeasureMatrix[i].push_back(value);// + value += getRestrictedMinimum(i, heightSize, value, 0, 0);//min values 0 + (*alignmentMatrix)[i].push_back(value);// } } - if (alignmentMeasureMatrix[0].size() == secondMatrix.size()) + if ((*alignmentMatrix)[0].size() == endIndexY) return true; else return false; @@ -165,26 +223,27 @@ } -bool TimeWarp::extendAlignmentAlong(){ +bool TimeWarp::extendAlignmentAlong(int endIndexX, DoubleMatrix* alignmentMatrix){ DoubleVector d; - int widthSize = alignmentMeasureMatrix.size(); - if (widthSize < chromaMatrix.size()){ + //firstMatrix.size() + int widthSize = (*alignmentMatrix).size(); + if (widthSize < endIndexX){//firstMatrix.size() //then we can extend along double value = getDistance(widthSize, 0); - value += getMinimum(widthSize, 0, value); + value += getRestrictedMinimum(widthSize, 0, value, 0, 0); d.push_back(value); - alignmentMeasureMatrix.push_back(d); + (*alignmentMatrix).push_back(d); - for (int j = 1;j < alignmentMeasureMatrix[widthSize - 1].size();j++){ + for (int j = 1;j < (*alignmentMatrix)[widthSize - 1].size();j++){ value = getDistance(widthSize, j); value += getMinimum(widthSize, j, value); - alignmentMeasureMatrix[widthSize].push_back(value); + (*alignmentMatrix)[widthSize].push_back(value); } } - if (alignmentMeasureMatrix.size() == chromaMatrix.size()) + if ((*alignmentMatrix).size() == endIndexX) return true; else return false; @@ -192,27 +251,146 @@ } -void TimeWarp::calculateMinimumAlignmentPath(){ + +void TimeWarp::calculatePartSimilarityMatrix(DoubleMatrix firstChromaMatrix, DoubleMatrix secondChromaMatrix, DoubleMatrix* simMatrix, int startX, int startY, int endX){ +// printf("Calculate similarity : pointers : size %i x %i ", (int) firstChromaMatrix.size(), (int) secondChromaMatrix.size()); + + (*simMatrix).clear(); + + double distance, firstSum, secondSum; + endX = min (endX, (int)firstChromaMatrix.size()-1);//in case out of size + + for (int x = startX;x <= endX;x++){ + DoubleVector d; + + for (int y = startY;y < secondChromaMatrix.size();y++){ + + distance = 0; + firstSum = 0; + secondSum = 0; + + for (int z = 0;z < firstChromaMatrix[x].size();z++){//z is the twelve chromagram values + distance += firstChromaMatrix[x][z] * secondChromaMatrix[y][z]; + firstSum += firstChromaMatrix[x][z] * firstChromaMatrix[x][z]; + secondSum += secondChromaMatrix[y][z] * secondChromaMatrix[y][z]; + } + + if (firstSum > 0 && secondSum > 0) + distance /= sqrt(firstSum)*sqrt(secondSum); + + d.push_back( distance); + } //end for y + + (*simMatrix).push_back(d); + + }//end for x + + printf("..part sim size: %i, height: %i \n", (int) (*simMatrix).size(), (int) (*simMatrix)[0].size()); + +}//end self sim + + + + +/* +void TimeWarp::calculatePartAlignmentMatrix(int startIndexX, int startIndexY, int endIndexX, int endIndexY, DoubleMatrix* alignmentMatrix){ + printf("starting PART Alignment calculation\n"); + //initialise alignment + (*alignmentMatrix).clear(); + DoubleVector d; + d.push_back(getDistance(0,0)); + (*alignmentMatrix).push_back(d); + + bool chromaCalculated = false; + bool secondCalculated = false; + + while (!chromaCalculated || !secondCalculated) { + + if (!chromaCalculated) + chromaCalculated = extendRestrictedAlignmentAlong(startIndexX, startIndexY, endIndexX, alignmentMatrix); + + if (!secondCalculated) + secondCalculated = extendAlignmentUp(endIndexY, alignmentMatrix); + + } + printf("PART Alignment matrix calculated, size %i\n", (int) (*alignmentMatrix).size()); +} + + + + + + +bool TimeWarp::extendRestrictedAlignmentUp(int startX, int startY, int endIndexY, DoubleMatrix *alignmentMatrix){ + //adds one more value to all the columns after startX + DoubleVector d; + d = (*alignmentMatrix)[0];//alignmentMatrix[0];// + int heightSize = d.size(); + if (heightSize < endIndexY){ + for (int i = startX;i < (*alignmentMatrix).size();i++){//was < (*alignmentMatrix).size() + double value = getDistance(i, heightSize); + value += getRestrictedMinimum(i, heightSize, value, startX, startY);//min values 0 + (*alignmentMatrix)[i].push_back(value);// + } + } + if ((*alignmentMatrix)[0].size() == endIndexY) + return true; + else + return false; + +} + + +bool TimeWarp::extendRestrictedAlignmentAlong(int startX, int startY, int endIndexX, DoubleMatrix* alignmentMatrix){ + DoubleVector d; + //firstMatrix.size() + int widthSize = (*alignmentMatrix).size(); + if (widthSize < endIndexX){//firstMatrix.size() + //then we can extend along + double value = getDistance(widthSize, 0); + value += getRestrictedMinimum(widthSize, 0, value, startX, startY); + + d.push_back(value); + (*alignmentMatrix).push_back(d); + + for (int j = 1;j < (*alignmentMatrix)[widthSize - 1].size();j++){ + value = getDistance(widthSize, j); + value += getMinimum(widthSize, j, value); + (*alignmentMatrix)[widthSize].push_back(value); + } + + } + + if ((*alignmentMatrix).size() == endIndexX) + return true; + else + return false; + +} +*/ + + +void TimeWarp::calculateMinimumAlignmentPath(DoubleMatrix alignmentMatrix){ //this requires one pass of the DTW algorithm and then works backwards from (N,M) //to find the optimal path to (0,0), where N and M are the lengths of the two chromoVectors respectively backwardsAlignmentPath.clear(); - printf("Finding minimum Path \n"); + printf("Finding minimum Path %i vs sim size %i\n", (int)chromaMatrix.size(), (int)similarityMatrix.size() ); IntVector v; - v.push_back(chromaMatrix.size()-1); + v.push_back(similarityMatrix.size()-1);//chromaMatrix.size()-1 backwardsAlignmentPath.push_back(v); v.clear(); - v.push_back(secondMatrix.size()-1); + v.push_back(similarityMatrix[0].size()-1);//secondMatrix backwardsAlignmentPath.push_back(v); //so now backwards path[0][0] = size(chroma) and path[1][0] = size(secondMatrix) - printf("backwards path %i : %i \n", backwardsAlignmentPath[0][0], backwardsAlignmentPath[1][0]); +// printf("backwards path %i : %i \n", backwardsAlignmentPath[0][0], backwardsAlignmentPath[1][0]); int indexOfBackwardsPath = 0; while (!findPreviousMinimumInBackwardsPath()) { indexOfBackwardsPath++; - printf("backwards path %i : %i \n", backwardsAlignmentPath[0][indexOfBackwardsPath], backwardsAlignmentPath[1][indexOfBackwardsPath]); + // printf("backwards path index %i: path: %i : %i \n", indexOfBackwardsPath, backwardsAlignmentPath[0][indexOfBackwardsPath], backwardsAlignmentPath[1][indexOfBackwardsPath]); } printf("final index of backwards path is %i and i is %i \n", (int) backwardsAlignmentPath[0].size()-1, indexOfBackwardsPath); @@ -222,6 +400,80 @@ } +void TimeWarp::extendForwardAlignmentPath(int endX){ +int forwardsIndex = forwardsAlignmentPath.size(); + int indexX = backwardsAlignmentPath[0].size() - 1; + + if (forwardsIndex == 0){ + printf("initialise forwards path..\n"); + IntVector v; + + v.push_back(backwardsAlignmentPath[0][indexX]);//chromaMatrix.size()-1 + forwardsAlignmentPath.push_back(v); + v.clear(); + v.push_back(forwardsAlignmentPath[0][indexX]);//secondMatrix + forwardsAlignmentPath.push_back(v); + indexX--; + } + + while (backwardsAlignmentPath[0][indexX] <= endX){ + addNewForwardsPath(indexX); + printf("Forwards path from index %i:: path %i : %i\n", indexX, forwardsAlignmentPath[0][forwardsIndex], forwardsAlignmentPath[1][forwardsIndex]); + indexX--; + forwardsIndex++; + } + +} + +void TimeWarp::addNewForwardsPath(int indexX){ + if (indexX < backwardsAlignmentPath[0].size()){ + forwardsAlignmentPath[0].push_back((int)backwardsAlignmentPath[0][indexX]); + forwardsAlignmentPath[1].push_back((int)backwardsAlignmentPath[1][indexX]); + } +} + + + +void TimeWarp::calculatePartMinimumAlignmentPath(int startX, int startY, int endX, int endY, DoubleMatrix alignmentMatrix){ + //this requires one pass of the DTW algorithm and then works backwards from (N,M) + //to find the optimal path to (0,0), where N and M are the lengths of the two chromoVectors respectively + + partBackwardsAlignmentPath.clear(); + + printf("Finding PART minimum Path %i vs sim size %i\n", (int)chromaMatrix.size(), (int)similarityMatrix.size() ); + + if (endX < similarityMatrix.size()){ + IntVector v; + v.push_back(endX); + partBackwardsAlignmentPath.push_back(v); + + v.clear(); + + if (endY < similarityMatrix[0].size()){ + v.push_back(endY); + partBackwardsAlignmentPath.push_back(v); + } + //so now backwards path[0][0] = endX and path[1][0] = endY + + printf("PART backwards path %i : %i \n", partBackwardsAlignmentPath[0][0], partBackwardsAlignmentPath[1][0]); + int indexOfPartBackwardsPath = 0; + /* + + while (!findPreviousMinimumInBackwardsPath()) { + indexOfBackwardsPath++; + // printf("backwards path %i : %i \n", backwardsAlignmentPath[0][indexOfBackwardsPath], backwardsAlignmentPath[1][indexOfBackwardsPath]); + + } + */ + printf("final index of backwards path is %i and i is %i \n", (int) backwardsAlignmentPath[0].size()-1, indexOfPartBackwardsPath); + }//end if endX within size + + // backwardsAlignmentIndex = backwardsAlignmentPath[0].size()-1;//remember that this goes backwards! + +} + + + bool TimeWarp::findPreviousMinimumInBackwardsPath(){ int chromaPosition, secondPosition; int i,j; @@ -315,6 +567,83 @@ return minimumValue; } + +double TimeWarp::getRestrictedMinimum(int i, int j, float newValue, int minX, int minY){ + double minimumValue = 0; + + if (i > minX){ + minimumValue = alignmentMeasureMatrix[i-1][j]; + if (j > minY){ + minimumValue = min(minimumValue, alignmentMeasureMatrix[i-1][j-1] + newValue ) ;//penalises diagonal by 2 + minimumValue = min(minimumValue, alignmentMeasureMatrix[i][j-1]); + } + } + else{//i.e. i == 0 + if (j > minY) + minimumValue = alignmentMeasureMatrix[i][j-1]; + } + + return minimumValue; +} + + + +//--------------part backwards alignment------------------------ + +bool TimeWarp::findPreviousMinimumInPartBackwardsPath(){ + + int firstPosition, secondPosition; + int i,j; + i = backwardsAlignmentPath[0][backwardsAlignmentPath[0].size()-1]; + j = backwardsAlignmentPath[1][backwardsAlignmentPath[1].size()-1]; + + double newMinimum; + double *ptr; + ptr = &newMinimum; + newMinimum = alignmentMeasureMatrix[i][j]; + DoubleVector d; + + + bool finishedAligning = true; + + if (i > 0){ + if (testForNewAlignmentMinimum(ptr, i-1, j)){ + firstPosition = i-1; + secondPosition = j; + finishedAligning = false; + } + + if (j>0 && testForNewAlignmentMinimum(ptr, i-1, j-1)){ + firstPosition = i-1; + secondPosition = j-1; + finishedAligning = false; + } + } + + if (j > 0 && testForNewAlignmentMinimum(ptr, i, j-1)){ + firstPosition = i; + secondPosition = j-1; + //newMinimum = alignmentMeasureMatrix[chromaPosition][secondPosition]; + finishedAligning = false; + } + + if (!finishedAligning){ + backwardsAlignmentPath[0].push_back(firstPosition); + backwardsAlignmentPath[1].push_back(secondPosition); + } + + return finishedAligning; + +} + + + + + + + + + //-------------------------------------------------------------- /* void TimeWarp::update(){ @@ -1180,3 +1509,23 @@ } */ + + + +/* + double TimeWarp::getEnergyOfFrame(){ + + + float totalEnergyInFrame = 0; + + for (int i = 0;i<FRAMESIZE;i++){ + + totalEnergyInFrame += (frame[i] * frame[i]); + + } + totalEnergyInFrame = sqrt(totalEnergyInFrame); + + return totalEnergyInFrame; + } + */ +
--- a/src/timeWarp.h Thu May 19 16:23:49 2011 +0100 +++ b/src/timeWarp.h Wed Jun 08 17:35:56 2011 +0100 @@ -1,5 +1,5 @@ /* - * timeWarp.h + * TimeWarp.h * chromaReader13 * * Created by Andrew on 16/05/2011. @@ -23,33 +23,14 @@ #define CHROMA_LENGTH 12000 #define CHROMA_CONVERSION_FACTOR 16 //16 times as many frames in energy as in chroma //length in terms of frames (at 512 samples per frame - there are 90 per second) => 900: 10 seconds +#define ALIGNMENT_FRAMESIZE 128 -class timeWarp : public ofBaseApp{ +class TimeWarp : public ofBaseApp{ public: - - /* - void setup(); - void update(); - void draw(); - - void keyPressed (int key); - void keyReleased(int key); - void mouseMoved(int x, int y ); - void mouseDragged(int x, int y, int button); - void mousePressed(int x, int y, int button); - void mouseReleased(int x, int y, int button); - void windowResized(int w, int h); - - void audioRequested (float * input, int bufferSize, int nChannels); - void loadSndfile(); - */ - - double getEnergyOfFrame(); - void putEnergyInFrame(); + TimeWarp(); // constructor + ~TimeWarp(); -// void drawChromoGram(); -// void loadFirstAudioFile(); void initialiseVariables(); //variables @@ -59,149 +40,86 @@ DoubleMatrix chromaMatrix; DoubleMatrix secondMatrix; DoubleMatrix* matrixPtr; - -// void drawDoubleMatrix(DoubleMatrix* dMatrix);//DoubleMatrix* dMatrix); WOULD BE NICE TO USE POINTER BUT NOT WORKING YET -// void drawSpectralDifference(DoubleMatrix* dMatrix); - + DoubleVector firstEnergyVector; DoubleVector secondEnergyVector; - - DoubleMatrix similarityMatrix; - - void calculateSimilarityMatrix(); -// bool drawSimilarity; -// void drawSimilarityMatrix(); -// void printSimilarityMatrix(int sizeToPrint); + DoubleMatrix firstChromaEnergyMatrix; + DoubleMatrix secondChromaEnergyMatrix; Chromagram chromoGramm; Chromagram secondChromoGramm; - - DoubleMatrix alignmentMeasureMatrix;//just the choma alignment + DoubleMatrix similarityMatrix; + DoubleMatrix tmpSimilarityMatrix; + DoubleMatrix alignmentMeasureMatrix; + DoubleMatrix tmpAlignmentMeasureMatrix; DoubleVector minimumAlignmentPath; - //new addition - DoubleMatrix superAlignmentMeasureMatrix; //for the onset + chromagram alignment - DoubleVector superMinimumAlignmentPath; - -// void drawAlignmentPath(int startingChromaXFrame, int startingChromaYFrame); - int findStartWidthFrame(); - -// void printScoreForRow(int row, int max); - -// int numberOfScrollWidthsForFirstFile; -// int numberOfScrollWidthsForSecondFile; -// void checkIfAudioPositionExceedsWidthForFirstFile(); + double partAlignmentMeasureMatrix[ALIGNMENT_FRAMESIZE][ALIGNMENT_FRAMESIZE]; typedef std::vector<int> IntVector; typedef std::vector<IntVector> IntMatrix; + IntMatrix backwardsAlignmentPath; + IntMatrix tmpBackwardsPath; -// void updateAlignmentPathIndex(int idenifier); + int backwardsAlignmentIndex; - IntMatrix backwardsAlignmentPath; - int backwardsAlignmentIndex; + IntMatrix partBackwardsAlignmentPath; + IntMatrix forwardsAlignmentPath; + + int partBackwardsAlignmentIndex; + + + void createCombinedMatrix(DoubleMatrix myChromaMatrix, DoubleVector energyVector, DoubleMatrix* chromaEnergyMatrix); + + void calculateSimilarityMatrix(); + + + + + //new addition + void calculateSimilarityMatrixWithPointers(DoubleMatrix firstChromaMatrix, DoubleMatrix secondChromaMatrix, DoubleMatrix* simMatrix); + DoubleMatrix superAlignmentMeasureMatrix; //for the onset + chromagram alignment + DoubleVector superMinimumAlignmentPath; + //end new additions + + int findStartWidthFrame(); + + + + + + void calculateAlignmentMatrix(DoubleMatrix firstMatrix, DoubleMatrix secondMatrix, DoubleMatrix *alignmentMatrix); + double getDistance(int i, int j); + + double getRestrictedMinimum(int i, int j, float newValue, int minX, int minY); + bool extendRestrictedAlignmentUp(int startX, int startY, int endIndexY, DoubleMatrix *alignmentMatrix); + bool extendRestrictedAlignmentAlong(int startX, int startY, int endIndexX, DoubleMatrix* alignmentMatrix); + + double getMinimum(int i, int j, float newValue); + bool extendAlignmentUp(int endIndexY, DoubleMatrix *alignmentMatrix); + bool extendAlignmentAlong(int endIndexX, DoubleMatrix *alignmentMatrix); + void calculateMinimumAlignmentPath(DoubleMatrix alignmentMatrix); + void extendForwardAlignmentPath(int endX); + bool findPreviousMinimumInBackwardsPath(); bool testForNewAlignmentMinimum(double *previousMinimum, int i, int j); - void calculateAlignmentMatrix(); - double getDistance(int i, int j); -// void printAlignmentMatrix(); - double getMinimum(int i, int j, float newValue); - bool extendAlignmentUp(); - bool extendAlignmentAlong(); - void calculateMinimumAlignmentPath(); int findMinimumOfVector(DoubleVector *d); -// void swapBetweenPlayingFilesUsingAlignmentMatch(); -// int findMatchFromAlignment(bool whichFileToTest); -// void drawEnergyVectorFromPointer(DoubleVector* energyVec); -// void processAudioToDoubleMatrix(Chromagram* chromaG, DoubleMatrix* myDoubleMatrix, DoubleVector* energyVector); + void addNewForwardsPath(int indexX); + + void calculatePartSimilarityMatrix(DoubleMatrix firstChromaMatrix, DoubleMatrix secondChromaMatrix, DoubleMatrix* simMatrix, int startX, int startY, int endX); - - - - - - -// void loadNewAudio(string soundFileName); -// void loadSecondAudio(string soundFileName); - -// void loadSoundFiles(); -// void openFileDialogBox(); -// void loadLibSndFile(const char * filename); -// bool getFilenameFromDialogBox(string* fileNameToSave); -// void openNewAudioFileWithdialogBox(); - - //int* firstAudioLength, secondAudioLength; - -// string soundFileName, secondFileName; - -// float screenHeight, screenWidth; - - -// bool moveOn; -// bool drawSpectralDifferenceFunction; - - float frame[FRAMESIZE]; +// void calculatePartAlignmentMatrix(int startIndexX, int startIndexY, int endIndexX, int endIndexY, DoubleMatrix* alignmentMatrix); + void calculatePartMinimumAlignmentPath(int startX, int startY, int endX, int endY, DoubleMatrix alignmentMatrix); + bool findPreviousMinimumInPartBackwardsPath(); float diagonalPenalty; -// int frameIndex; - -// float chromoGramVector[CHROMA_LENGTH][12]; -// int rootChord[CHROMA_LENGTH]; - -// int energyIndex; -// int totalFrames; - -// int scrollWidth;// 1600 -// float chromoLength; - -// bool audioPlaying, audioPaused; -// bool drawSecondMatrix; - -/* - - - //------------------- for the simple sine wave synthesis - float targetFrequency; - float phase; - float phaseAdder; - float phaseAdderTarget; - - string sndfileInfoString, textString; - int xIndex; - - bool firstAudioFilePlaying; - ofSoundPlayer loadedAudio; - ofSoundPlayer secondAudio; - ofSoundPlayer *playingAudio; - - */ -// float audioPosition; -// float width, height; -// int chromaIndex; -// int totalNumberOfFrames; -// int currentPlayingFrame; -// int currentChromaFrame ; - -// string chordString; - - //Chromagram* chromoGrammPtr; - - - - -// string userInfoString; -// ChordDetect chord; - //sndfile part -// SNDFILE *infile; // define input and output sound files -// SF_INFO sfinfo ; // struct to hold info about sound file - - }; #endif