Mercurial > hg > audio-time-warp
view src/testApp.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 |
line wrap: on
line source
#include "testApp.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 //-------------------------------------------------------------- /* 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(){ doCausalAlignment = true; ofBackground(255,255,255); // 2 output channels, // 0 input channels // 22050 samples per second // 256 samples per buffer // 4 num buffers (latency) // ofSetDataPathRoot("../bin/data/"); //DONT NEED ANY OF THIS sampleRate = 44100; phase = 0; phaseAdder = 0.0f; phaseAdderTarget = 0.0f; volume = 0.1f; bNoise = false; lAudio = new float[256]; rAudio = new float[256]; ofSoundStreamSetup(2,0,this, sampleRate,256, 4); //UNTIL HERE ofSetFrameRate(60); fvec_t * my_fvec_t; aubio_onset_t* my_aubio_result; aubio_onsetdetection_t * my_onset_detection; scrollWidth = 1600; conversionFactor = 1.0;//CHROMA_CONVERSION_FACTOR; chromoLength = (float) scrollWidth / conversionFactor;// CHROMA_CONVERSION_FACTOR; // chromaConversionRatio = scrollWidth / (float) conversionFactor; // printf("initial CHROMOLENGTH %f , conv ratio %f\n", chromoLength, chromaConversionRatio); sfinfo.format = 0; moveOn = true; chromaG.initialise(FRAMESIZE, CHROMAGRAM_FRAMESIZE); onset = new OnsetDetectionFunction(512,1024,6,1); //loading audio files //loadSoundFiles(); //this os load soundfiles string fullFileName = "/Users/andrew/Documents/work/programming/of_preRelease_v0061_osx_FAT/apps/my_openFrameworks/chromaReader13audioTimeWarp3/bin/data/sound/Bach_short1.wav"; secondFileName = "/Users/andrew/Documents/work/programming/of_preRelease_v0061_osx_FAT/apps/my_openFrameworks/chromaReader13audioTimeWarp3/bin/data/sound/Bach_short2.wav"; loadNewAudio(fullFileName); /* const char *infile_name = fullFileName.c_str();// "../../../data/sound/Bach_short1.wav"; // loadLibSndFile(infile_name); string loadfilename = fullFileName;//"sound/Bach_short1.wav";// loadedAudio.loadSound(loadfilename); playingAudio = &loadedAudio; //end load soninf ifiels processAudioToDoubleMatrix(&tw.chromaMatrix, &tw.firstEnergyVector); */ // secondFileName = "../../../data/sound/Bach_short2.wav"; loadSecondAudio(secondFileName);//i.e. load same as first file backwardsAlignmentIndex = 0;//remember that this goes backwards! tw.initialiseVariables(); calculateSimilarityAndAlignment(); //set not to play audioPlaying = false; drawSecondMatrix = false; drawSpectralDifferenceFunction = false; drawSimilarity = true; screenHeight = ofGetHeight() ; screenWidth = ofGetWidth(); initialiseVariables(); } void testApp::calculateSimilarityAndAlignment(){ tw.initialiseVariables(); //here is the main TimeWarp similarity matrix calc, the minimum alignment matrix via dtw and then the backwards path estimate double timeBefore = ofGetElapsedTimef(); tw.calculateChromaSimilarityMatrix(&tw.chromaMatrix, &tw.secondMatrix, &tw.chromaSimilarityMatrix); double elapsedTime = ofGetElapsedTimef() - timeBefore; printf("CHROMA SIMILARITY ONLY TAKES %2.2f seconds\n", elapsedTime); dontDoJunkAlignment(); if (doCausalAlignment) calculateCausalAlignment(); else{ //tw.calculateAlignmentMatrix(tw.firstChromaEnergyMatrix, tw.secondChromaEnergyMatrix, &tw.alignmentMeasureMatrix); tw.calculateAlignmentMatrix(tw.chromaMatrix, tw.secondMatrix, &tw.alignmentMeasureMatrix); tw.calculateMinimumAlignmentPath(&tw.alignmentMeasureMatrix, &tw.backwardsAlignmentPath, false); } backwardsAlignmentIndex = tw.backwardsAlignmentPath[0].size()-1; printf("index size is %i\n", backwardsAlignmentIndex); setConversionRatio(); printVariousMatrixInfo(); } void testApp::doPathBugCheck(){ //bug check if (tw.forwardsAlignmentPath.size() > 0 && tw.forwardsAlignmentPath[1][0] != 0){ tw.forwardsAlignmentPath[1][0] = 0;//sometimes is large rndm number printf("BUG IN FORWARDS PATH FIXED!!!\n"); } } void testApp::calculateCausalAlignment(){ calculateForwardsAlignment(); doPathBugCheck(); tw.copyForwardsPathToBackwardsPath(); } void testApp::setConversionRatio(){ conversionFactor = (int) round(tw.firstEnergyVector.size() / tw.chromaMatrix.size()); chromaConversionRatio = (int) round(tw.firstEnergyVector.size() / tw.chromaMatrix.size()); chromoLength = scrollWidth / (float)conversionFactor;// CHROMA_CONVERSION_FACTOR; printf("scrollwidth %i, conversion factor %i, chromo length %i\n", scrollWidth, (int)conversionFactor, (int)chromoLength); } void testApp::printVariousMatrixInfo(){ printf("large SIM SIZE%i, chrom size %ix%i\n", (int)tw.similarityMatrix.size(), (int)tw.chromaMatrix.size(), (int)tw.chromaMatrix[0].size()); if (tw.similarityMatrix.size() > 0 && tw.chromaSimilarityMatrix.size() > 0){ printf("SIM SIZE %i, and %i \n",(int) tw.similarityMatrix.size(), (int) tw.similarityMatrix[0].size()); printf("chomra sim size %i, and %i\n", (int) tw.chromaSimilarityMatrix.size(), (int)tw.chromaSimilarityMatrix[0].size()); } //tw.printBackwardsPath(0, tw.forwardsAlignmentPath[0].size()-1, &tw.forwardsAlignmentPath); printf("backwards path size is [0]:%i, [1]%i, \n", (int)tw.backwardsAlignmentPath[0].size(), (int)tw.backwardsAlignmentPath[1].size()); printf("backwards path size is %i, FORWARDS SIZE IS %i\n", (int)tw.backwardsAlignmentPath[0].size(), (int)tw.forwardsAlignmentPath[0].size()); //printf("BACKWARDS PATH::\n"); //tw.printBackwardsPath(0, (int)tw.backwardsAlignmentPath[0].size(), &tw.backwardsAlignmentPath); } void testApp::initialiseVariables(){ chromaIndex = 0; // chromoGramm.initialise(FRAMESIZE,2048);//framesize 512 and hopsize 2048 audioPosition = 0; if (tw.backwardsAlignmentPath.size() > 0) backwardsAlignmentIndex = tw.backwardsAlignmentPath[0].size()-1;//go back to beginning for drawing numberOfScrollWidthsForFirstFile = 0; numberOfScrollWidthsForSecondFile = 0; (*playingAudio).setPaused(true); audioPlaying = false; audioPaused = true; // tw.initialiseVariables(); } void testApp::calculateForwardsAlignment(){ tw.forwardsAlignmentPath.clear(); //causal part int hopsize = 200; int frameSize = 800; int startFrameY = 0; int startFrameX = 0; tw.anchorPoints.clear(); for (int startFrameX = 0;startFrameX < tw.firstEnergyVector.size(); startFrameX += hopsize){//tw.firstChromaEnergyMatrix.size() //replace this with a while startFrame < end of file tw.addAnchorPoints(startFrameX, startFrameY); //NEED TO ASSUME WE DON'T HAVE double timeBefore = ofGetElapsedTimef(); printf("PART SIM: startFrameX %i, startFrameY: %i\n", startFrameX, startFrameY); //NEW FUNCTION - calls only the energy and uses the stored chromagram tw.calculatePartJointSimilarityMatrix(&tw.firstEnergyVector, &tw.secondEnergyVector, &tw.chromaSimilarityMatrix, &tw.tmpSimilarityMatrix, startFrameX, startFrameY, startFrameX+frameSize, startFrameY + 3*frameSize); // printf("TMP size of tmp sim is %i\n", (int)tw.tmpSimilarityMatrix.size()); double elapsedTime = ofGetElapsedTimef() - timeBefore; // printf("PART SIM MATRIX CAL TAKES %f\n", elapsedTime); //change part sim to have a y limit too //check if we can not calculate alignment matrix for chunks of the sim matrix where it is off diagonal tw.calculatePartAlignmentMatrix(tw.tmpSimilarityMatrix.size()-1, tw.tmpSimilarityMatrix[0].size()-1, &tw.tmpAlignmentMeasureMatrix, &tw.tmpSimilarityMatrix); //get alignment measure minimum //find minimum path between only the section we are interested in //write new function to find minimum backwards path from the index we choose (not the final corner) // int myIndex = tw.findMinimumOfMatrixColumn(tw.tmpAlignmentMeasureMatrix, tw.tmpSimilarityMatrix.size()-1); /* printf("my index is %i\n", myIndex); for (int i = 0;i< tw.alignmentMeasureMatrix[tw.similarityMatrix.size()-1].size() - 1;i++){ printf("Alignment[%i] : %f\n", i, tw.alignmentMeasureMatrix[tw.similarityMatrix.size()-1][i]); } */ printf("\n CALC PART ALIGNMENT MIN PATH\n"); tw.calculateMinimumAlignmentPath(&tw.tmpAlignmentMeasureMatrix, &tw.tmpBackwardsPath, true);//true is for greedy calculation printf("\n PART ALIGNMENT GENERATES THIS BACKWARDS PATH:: \n"); tw.extendForwardAlignmentPath(hopsize, &tw.tmpBackwardsPath, startFrameX, startFrameY); startFrameY = tw.forwardsAlignmentPath[1][(tw.forwardsAlignmentPath[0].size()-1)]; }//end for startFrameX } //-------------------------------------------------------------- void testApp::update(){ textString = "energy index ["; textString += ofToString(xIndex); textString += "] = "; textString += ofToString(energy[xIndex]); // chordString = "Chord : "; // chordString += ofToString(rootChord[currentPlayingFrame/conversionFactor]);//CHROMA_CONVERSION_FACTOR]); audioPosition = (*playingAudio).getPosition(); if (firstAudioFilePlaying){ audioPosition *= tw.firstEnergyVector.size(); updateAlignmentPathIndex(0); } else { audioPosition *= tw.secondEnergyVector.size(); updateAlignmentPathIndex(1); } //if(!audioPaused) //printScoreForRow(audioPosition/CHROMA_CONVERSION_FACTOR, (audioPosition/CHROMA_CONVERSION_FACTOR)+10); currentPlayingFrame = audioPosition; audioPosition = (int) audioPosition % scrollWidth ; audioPosition /= scrollWidth; ofSoundUpdate(); } void testApp::updateAlignmentPathIndex(int identifier){ if (tw.backwardsAlignmentPath.size() > 0){ if (backwardsAlignmentIndex >= tw.backwardsAlignmentPath[identifier].size()) backwardsAlignmentIndex = tw.backwardsAlignmentPath[identifier].size()-1; //this is the alignment where we are currently playing - i.e. switching between files int chromaPosition = audioPosition;///conversionFactor;//CHROMA_CONVERSION_FACTOR; while (tw.backwardsAlignmentPath[identifier][backwardsAlignmentIndex] < chromaPosition && backwardsAlignmentIndex > 0) { backwardsAlignmentIndex--; } } } //-------------------------------------------------------------- void testApp::draw(){ if (drawSimilarity){ //drawSimilarityMatrix(); drawChromaSimilarityMatrix();//new fn with alignment causal including energy vector //but chroma sim used for representation } else drawDoubleMatrix(&tw.tmpSimilarityMatrix); //drawChromoGram(); } void testApp::drawEnergyVectorFromPointer(DoubleVector* energyVec){ float screenHeight = ofGetHeight() ; float screenWidth = ofGetWidth(); float heightFactor = 1; int i, j, startingFrame; startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in startingFrame *= scrollWidth; for (i = 0; i < scrollWidth - 1; i++){ j = min(i + startingFrame, (int)energyVec->size()-1); ofLine(i*screenWidth/scrollWidth, screenHeight - ((*energyVec)[j]*screenHeight/heightFactor), screenWidth*(i+1)/scrollWidth, screenHeight - ((*energyVec)[j+1]*screenHeight/heightFactor)); } } void testApp::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 /= conversionFactor;// CHROMA_CONVERSION_FACTOR; //in terms of chroma frames for (i = 1; i < chromoLength; i++){//changed to add 1 j = min(i + startingFrame, (int) dMatrix->size()-1 );//in case out of range 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 testApp::drawChromoGram(){ DoubleMatrix* dptr; DoubleVector* eptr; string whichFileString; if (drawSecondMatrix){ dptr = &tw.secondMatrix; eptr = &tw.secondEnergyVector; whichFileString = "second file"; }else { dptr = &tw.chromaMatrix; eptr = &tw.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 testApp::drawDoubleMatrix(DoubleMatrix* dMatrix){ if ((*dMatrix).size()>0){ int matrixWidth = (*dMatrix).size(); int matrixHeight = (*dMatrix)[0].size(); 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 /= conversionFactor;//CHROMA_CONVERSION_FACTOR; //in terms of chroma frames 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++){ ofSetColor(0,0,255 * (*dMatrix)[j][11-y]);//, 0; ofRect(i*screenWidth/chromoLength,y*screenHeight/12,screenWidth/chromoLength,screenHeight/12); }//end y }//end i */ float ratio = max(matrixWidth/screenWidth,matrixHeight/screenHeight); for (int x = 0; x < screenWidth; x+= 5){ //j = min(i + startingFrame, (int) dMatrix->size()-1 ) ; for (int y = 0;y < screenHeight;y+= 5){ int xIndex = (int)(x*ratio); int yIndex = (int)(y*ratio); if (xIndex < matrixWidth && yIndex < matrixHeight) ofSetColor(0,0,255 * (*dMatrix)[xIndex][yIndex]);//, 0; else ofSetColor(0,0,0); ofRect(x,y,5,5);//screenWidth/matrixWidth,screenHeight/matrixHeight); }//end y }//end i }///end if matrix has content else{ printf("Error - please load audio first"); } } void testApp::drawSimilarityMatrix(){ int simHeight = (tw.similarityMatrix[0]).size(); int simWidth = tw.similarityMatrix.size(); int sizeOfMatrix = (int) tw.similarityMatrix.size();//tw.chromaMatrix.size(); int sizeOfSecondMatrix = (int) tw.similarityMatrix[0].size(); //in chromagram frames int startingXframe = tw.chromaSimilarityMatrix.size() / (scrollWidth/conversionFactor); int startingYframe = tw.chromaSimilarityMatrix[0].size() / (scrollWidth/conversionFactor); if (tw.backwardsAlignmentPath.size() > 0){ startingXframe = tw.backwardsAlignmentPath[0][backwardsAlignmentIndex] / (scrollWidth/conversionFactor); startingYframe = tw.backwardsAlignmentPath[1][backwardsAlignmentIndex] / (scrollWidth/conversionFactor); } startingXframe = startingXframe * scrollWidth/conversionFactor; startingYframe = startingYframe * scrollWidth/conversionFactor; // int startingFrame = findStartWidthFrame(); // startingFrame = numberOfScrollWidthsForFirstFile * scrollWidth/conversionFactor; //need to fix for second file too int *indexOfAlignmentPathTested; int lengthOfPath = 0; if (tw.backwardsAlignmentPath.size() > 0) lengthOfPath = tw.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 = tw.similarityMatrix[xcoord][ycoord]*255; ofSetColor(colour,0,0); ofRect(x,y,1,1); } } ofSetColor(0,255,255); // drawAlignmentPath(startingXframe, startingYframe, &tw.tmpBackwardsPath); drawForwardsAlignmentPath(startingXframe, startingYframe); // ofSetColor(0,0,255); // drawAlignmentPath(startingXframe, startingYframe, &tw.backwardsAlignmentPath); //SET TEXT ofSetColor(255 ,255,255); 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);// && tw.backwardsAlignmentPath.size() > 0 if (firstAudioFilePlaying){// && tw.alignmentMeasureMatrix.size() > 0 ofLine(audioPosition*screenWidth, 0, audioPosition*screenWidth, height); checkIfAudioPositionExceedsWidthForFirstFile(); // drawAlignmentmeasureValues(currentPlayingFrame); } else{ ofLine(0, audioPosition*screenHeight, screenWidth, audioPosition*screenHeight); } ofDrawBitmapString(textString,80,580); ofDrawBitmapString(userInfoString,80,80); } void testApp::drawChromaSimilarityMatrix(){ //scrollwidth is width in terms of the similarity matrix size (or energy size if we are being accurate) //need to get rid of dependency on sim matirx and only use chrom sim matrix // int simHeight = (tw.similarityMatrix[0]).size(); // int simWidth = tw.similarityMatrix.size(); // int sizeOfMatrix = (int) tw.similarityMatrix.size();//tw.chromaMatrix.size(); // int sizeOfSecondMatrix = (int) tw.similarityMatrix[0].size(); float chromogramScrollWidth = (scrollWidth/conversionFactor); //frames needed in energy still //in chromagram frames int startingXframe = (tw.firstEnergyVector.size() / scrollWidth); int startingYframe = (tw.secondEnergyVector.size() / scrollWidth);//secondMatrix // printf("DRAW SIM SIZE start frames %i x %i \n", startingXframe, startingYframe); if (tw.backwardsAlignmentPath.size() > 0 ){ startingXframe = (tw.backwardsAlignmentPath[0][backwardsAlignmentIndex]/ scrollWidth); startingYframe = max(0 , (int)(tw.backwardsAlignmentPath[1][backwardsAlignmentIndex]/ scrollWidth));//*conversionFactor //FIX THE 1 - ASDDED AS DEBUG // printf("alignment index %i, VERSUS DRAW SIM SIZE %i x %i \n", backwardsAlignmentIndex, startingXframe, startingYframe); } //PROBLEM IS THAT THE y value startYframe is not correctly incremented //tmp // startingXframe = 0; // startingYframe = 0; // int startingFrame = findStartWidthFrame(); // startingFrame = numberOfScrollWidthsForFirstFile * scrollWidth/conversionFactor; startingXframe *= scrollWidth;// /conversionFactor; startingYframe *= scrollWidth;// /conversionFactor; //need to fix for second file too int *indexOfAlignmentPathTested; int lengthOfPath = 0; if (tw.backwardsAlignmentPath.size() > 0) lengthOfPath = tw.backwardsAlignmentPath[0].size()-1; indexOfAlignmentPathTested = &lengthOfPath; int xcoord, ycoord; for (int x = 0;x < screenWidth;x++) { for (int y =0;y < screenHeight;y++){ xcoord = (x / screenWidth) * scrollWidth;//i.e. chromoLength * conversionFactor; xcoord += startingXframe; int xChromaCoord = xcoord / conversionFactor; ycoord = y * chromoLength * conversionFactor/ screenHeight; ycoord += startingYframe; int yChromaCoord = ycoord / conversionFactor; int colour = 0;//0x006644; /* if (xcoord < tw.similarityMatrix.size() && ycoord < tw.similarityMatrix[0].size()){// //nb not optimised colour = tw.similarityMatrix[xcoord][ycoord]*255; } */ if (xChromaCoord < tw.chromaSimilarityMatrix.size() && yChromaCoord < tw.chromaSimilarityMatrix[0].size()){ colour = tw.chromaSimilarityMatrix[xChromaCoord][yChromaCoord]*255; } ofSetColor(colour,0,0); ofRect(x,y,1,1); } } // ofSetColor(0,0,255); // drawAlignmentPath(startingXframe, startingYframe, &tw.backwardsAlignmentPath); //ALIGNMENT PATH doesnt work yet - scae rpobllem ofSetColor(0,255,255); // drawAlignmentPath(startingXframe, startingYframe, &tw.tmpBackwardsPath); drawForwardsAlignmentPathOnChromaSimilarity(startingXframe, startingYframe); drawAnchorPointsOnChromaSimilarity(startingXframe, startingYframe); //SET TEXT ofSetColor(255 ,255,255); string textString; /* textString = "width : "; textString += ofToString(simWidth); textString += " height : "; textString += ofToString(simHeight); */ // textString += " startframe : "; // textString += ofToString(startingFrame); textString += " Xframe : "; textString += ofToString(startingXframe); textString += " back[0] "; textString += ofToString(tw.backwardsAlignmentPath[0][backwardsAlignmentIndex]); textString += " Yframe : "; textString += ofToString(startingYframe); textString += " back[1] "; textString += ofToString(tw.backwardsAlignmentPath[1][backwardsAlignmentIndex]); textString += " currentFrame : "; textString += ofToString(currentPlayingFrame); textString += " backalign index : "; textString += ofToString(backwardsAlignmentIndex); 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);// && tw.backwardsAlignmentPath.size() > 0 if (firstAudioFilePlaying){// && tw.alignmentMeasureMatrix.size() > 0 ofLine(audioPosition*screenWidth, 0, audioPosition*screenWidth, height); checkIfAudioPositionExceedsWidthForFirstFile(); // drawAlignmentmeasureValues(currentPlayingFrame); } else{ ofLine(0, audioPosition*screenHeight, screenWidth, audioPosition*screenHeight); } ofDrawBitmapString(textString,80,580); ofDrawBitmapString(userInfoString,80,80); } void testApp::drawAlignmentmeasureValues(const int& startingYframe){ //draw values: /* int xcoord = currentPlayingFrame / conversionFactor; ofSetColor(255, 255, 255); for (int y = 0;y < chromoLength; y+=max(1, (int)(20 * chromoLength / screenHeight))){ float value = tw.alignmentMeasureMatrix[xcoord][y+startingYframe]; int ycoord = y * screenHeight/chromoLength; ofDrawBitmapString(ofToString(value, 2) , audioPosition*screenWidth , ycoord); } */ } void testApp::checkIfAudioPositionExceedsWidthForFirstFile() { if (currentPlayingFrame > scrollWidth*(numberOfScrollWidthsForFirstFile+1)) numberOfScrollWidthsForFirstFile++; } int testApp::findStartWidthFrame(){ int startingFrame; /* startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in startingFrame *= scrollWidth;//starting frame in terms of energy frames startingFrame /= conversionFactor;// CHROMA_CONVERSION_FACTOR; */ return startingFrame; } void testApp::drawAlignmentPath(int startingChromaXFrame, int startingChromaYFrame, IntMatrix* backPath){ // if (tw.alignmentMeasureMatrix.size() > 0){ if ((*backPath).size() > 0){ //draw alignment path int endingChromaXFrame = startingChromaXFrame + chromoLength; int endingChromaYFrame = startingChromaYFrame + chromoLength; float chromoWidth = screenWidth / chromoLength; float chromoHeight = screenHeight / chromoLength; int index = (*backPath)[0].size()-1; //OPTIMISE XXX while ((*backPath)[0][index] < startingChromaXFrame){ index --; } int printIndex = index; int backAlign = (*backPath)[0][index]; int printxcoord; int xcoord; while ((*backPath)[0][index] < endingChromaXFrame) { // xcoord = min((int)(tw.similarityMatrix.size())-1,(*backPath)[0][index]); xcoord = (*backPath)[0][index]; //int ycoord = min((int)(*backPath)[1][index], (int)(tw.alignmentMeasureMatrix[0].size())-1); int ycoord = (int)(*backPath)[1][index]; printxcoord = xcoord; // int colour = tw.similarityMatrix[xcoord][ycoord]*255; //float value = 0; //if (xcoord < tw.alignmentMeasureMatrix.size() && ycoord < tw.alignmentMeasureMatrix[xcoord].size()) //float value = tw.alignmentMeasureMatrix[xcoord][ycoord] ; xcoord -= startingChromaXFrame; ycoord -= startingChromaYFrame; ofRect(xcoord*chromoWidth, ycoord*chromoHeight, chromoWidth, chromoHeight); index--; } // drawHoverAlignmentValues(); // printf("ALIGN score :[%i] : %f \n", backwardsAlignmentPath[1][backwardsAlignmentIndex], ureMatrix[ 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); }//end if alignment path > 0 //else{ // printf("al measure mat not in range \n"); // } } void testApp::drawForwardsAlignmentPath(int startingChromaXFrame, int startingChromaYFrame){ //using starting frame in energy vector 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 xcoord; //replacing tw.similarityMatrix.size() by first e vec below while (index < tw.forwardsAlignmentPath[0].size() && tw.forwardsAlignmentPath[0][index] < endingChromaXFrame) { xcoord = min((int)(tw.firstEnergyVector.size())-1,tw.forwardsAlignmentPath[0][index]); int ycoord = (int)tw.forwardsAlignmentPath[1][index]; if (tw.alignmentMeasureMatrix.size() > 0) 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::drawForwardsAlignmentPathOnChromaSimilarity(const int& startingXFrame, const int& startingYFrame){ //using starting frame in energy vector if (tw.forwardsAlignmentPath.size() > 0){ int endingChromaXFrame = startingXFrame + scrollWidth; int endingChromaYFrame = startingYFrame + scrollWidth; float energyVectorWidth = screenWidth / scrollWidth; float energyVectorHeight = screenHeight / scrollWidth; int index = max(0, (int)tw.backwardsAlignmentPath[0].size() - backwardsAlignmentIndex); //OPTIMISE XXX while (index > 0 && tw.forwardsAlignmentPath[0][index] > startingXFrame){ //get to NOW index --; } while (tw.forwardsAlignmentPath[0][index] < startingXFrame){ //get to NOW index ++; } int xcoord; //replacing tw.similarityMatrix.size() by fiorst e vec while (index < tw.forwardsAlignmentPath[0].size() && tw.forwardsAlignmentPath[0][index] < endingChromaXFrame) { xcoord = min((int)(tw.firstEnergyVector.size())-1,tw.forwardsAlignmentPath[0][index]); int ycoord = (int)tw.forwardsAlignmentPath[1][index]; if (tw.alignmentMeasureMatrix.size() > 0) 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 -= startingXFrame; ycoord -= startingYFrame; ofSetColor(0,colour,0); ofRect(xcoord*energyVectorWidth, ycoord*energyVectorHeight, energyVectorWidth, energyVectorHeight); index++; }//end while }//end if forwards path exista } void testApp::drawAnchorPointsOnChromaSimilarity(const int& startingXFrame, const int& startingYFrame){ //using starting frame in energy vector if (tw.anchorPoints.size() > 0){ int endingChromaXFrame = startingXFrame + scrollWidth; int endingChromaYFrame = startingYFrame + scrollWidth; float energyVectorWidth = screenWidth / scrollWidth; float energyVectorHeight = screenHeight / scrollWidth; int index = 0; while (index < tw.anchorPoints.size() && tw.anchorPoints[index][0] < startingXFrame){ index ++; } int xcoord; while (index < tw.anchorPoints.size() && tw.anchorPoints[index][0] < endingChromaXFrame) { xcoord = min((int)(tw.firstEnergyVector.size())-1,tw.anchorPoints[index][0]); int ycoord = (int)tw.anchorPoints[index][1]; if (tw.alignmentMeasureMatrix.size() > 0) ycoord = min((int)tw.anchorPoints[index][1], (int)(tw.alignmentMeasureMatrix[0].size())-1); int colour = 255;//tw.similarityMatrix[xcoord][ycoord]*255; //float value = tw.alignmentMeasureMatrix[xcoord][ycoord] ; xcoord -= startingXFrame; ycoord -= startingYFrame; ofSetColor(colour,colour,colour); ofRect((xcoord-1)*energyVectorWidth, (ycoord-1)*energyVectorHeight, 3*energyVectorWidth, 3*energyVectorHeight); index++; }//end while }//end if } void testApp::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/Bach_short1.wav"; loadLibSndFile(infilename); string loadfilename = "sound/Bach_short1.wav";//PicturesMixer6.aif"; loadedAudio.loadSound(loadfilename); playingAudio = &loadedAudio; } void testApp::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 testApp::processAudioToDoubleMatrix(DoubleMatrix* myDoubleMatrix, DoubleVector* energyVector){ //wendy myDoubleMatrix->clear(); energyVector->clear(); chromaG.initialise(FRAMESIZE, CHROMAGRAM_FRAMESIZE);//framesize 512 and hopsize 2048 - already done chromaG.maximumChromaValue = 1; double maximumEnergyValue = 1; 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 && energyVector->size() < FILE_LIMIT) { // read FRAMESIZE samples from 'infile' and save in 'data' readcount = sf_read_float(infile, frame, FRAMESIZE); double doubleFrame[FRAMESIZE]; for (int k = 0;k< FRAMESIZE;k++){ doubleFrame[k] = frame[k]; } //8192 samples per chroma frame //processing frame - downsampled to 11025Hz chromaG.processframe(frame); if (chromaG.chromaready) { DoubleVector d; for (int i = 0;i<12;i++){ d.push_back(chromaG.rawChroma[i]);// / chromaG->maximumChromaValue); } //this would do chord detection myDoubleMatrix->push_back(d); //so now is storing at d[i][current_index] }//end if chromagRamm ready // double energyValue = getEnergyOfFrame(); double energyValue = onset->getDFsample(doubleFrame); energyVector->push_back(energyValue); if (energyValue > maximumEnergyValue) maximumEnergyValue = energyValue; }//end while readcount printf("Max chroma value is %f \n", chromaG.maximumChromaValue); printf("length of chromagram is %d frames\n", (int)myDoubleMatrix->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 (*myDoubleMatrix)[i][j] /= chromaG.maximumChromaValue; } } 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() / (int)energyVector->size(); // int size = myDoubleMatrix->size() * CHROMA_CONVERSION_FACTOR; } //-------------------------------------------------------------- void testApp::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/conversionFactor;// CHROMA_CONVERSION_FACTOR; } if (key == OF_KEY_UP){ if (scrollWidth > 600) scrollWidth -= 400; else scrollWidth /= 2; chromoLength = scrollWidth/conversionFactor;// CHROMA_CONVERSION_FACTOR; } if (key == OF_KEY_LEFT){ (*playingAudio).setSpeed(-4); backwardsAlignmentIndex = tw.backwardsAlignmentPath[0].size()-1; } if (key == OF_KEY_RIGHT){ (*playingAudio).setSpeed(4); } 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'){ tw.clearVectors(); 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); initialiseVariables(); backwardsAlignmentIndex = 0; calculateSimilarityAndAlignment(); } if (key == 'f'){ tw.printBackwardsPath(0, (int) tw.forwardsAlignmentPath[0].size(), &tw.forwardsAlignmentPath); } if (key == 'b'){ tw.printBackwardsPath(0, (int) tw.backwardsAlignmentPath[0].size(), &tw.backwardsAlignmentPath); } if (key == 's'){ drawSimilarity = !drawSimilarity; } if (key == 'm'){ drawSecondMatrix = !drawSecondMatrix; } if (key == 'd'){ drawSpectralDifferenceFunction = !drawSpectralDifferenceFunction; } } //-------------------------------------------------------------- void testApp::keyReleased (int key){ if (key == OF_KEY_LEFT || OF_KEY_RIGHT){ (*playingAudio).setSpeed(1); if (tw.backwardsAlignmentPath.size() > 0) backwardsAlignmentIndex = tw.backwardsAlignmentPath[0].size()-1; } } void testApp::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 testApp::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 testApp::mouseDragged(int x, int y, int button){ width = ofGetWidth(); pan = (float)x / (float)width; } //-------------------------------------------------------------- void testApp::mousePressed(int x, int y, int button){ bNoise = true; //moveOn = true; } //-------------------------------------------------------------- void testApp::mouseReleased(int x, int y, int button){ bNoise = false; } //-------------------------------------------------------------- void testApp::windowResized(int w, int h){ width = w; height = h; screenHeight = ofGetHeight() ; screenWidth = ofGetWidth(); } //-------------------------------------------------------------- void testApp::audioRequested (float * output, int bufferSize, int nChannels){ //pan = 0.5f; float leftScale = 1 - pan; float rightScale = pan; // sin (n) seems to have trouble when n is very large, so we // keep phase in the range of 0-TWO_PI like this: while (phase > TWO_PI){ phase -= TWO_PI; } } //-------------------------------------------------------------- bool testApp::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 testApp::openFileDialogBox(){ // 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 soundFileName = URL;//"URL to open: \n "+URL; }else { soundFileName = "OPEN cancelled. "; } } void testApp::loadNewAudio(string soundFileName){ //need to add in clear fns // tw.chromaMatrix.clear(); // tw.firstEnergyVector.clear(); loadedAudio.loadSound(soundFileName); playingAudio = &loadedAudio; //snd file method const char *infilename = soundFileName.c_str() ; loadLibSndFile(infilename); // loadFirstAudioFile(); processAudioToDoubleMatrix(&tw.chromaMatrix, &tw.firstEnergyVector); audioPlaying = false; } void testApp::loadFirstAudioFile(){ processAudioToDoubleMatrix(&tw.chromaMatrix, &tw.firstEnergyVector); } void testApp::loadSecondAudio(string sndFileName){ secondAudio.loadSound(sndFileName); const char *infilenme = sndFileName.c_str() ; loadLibSndFile(infilenme); processAudioToDoubleMatrix(&tw.secondMatrix, &tw.secondEnergyVector); } void testApp::swapBetweenPlayingFilesUsingAlignmentMatch(){ float tmpConvFac = conversionFactor; conversionFactor = 1.0; ofSoundUpdate(); //swapping between files //printf("current playing (energy scale) frame was %i \n", currentPlayingFrame); float oldPosition = (*playingAudio).getPosition(); printf("\n playing position is %f \n", oldPosition);//and conv factor %f \n", (*playingAudio).getPosition(), conversionFactor); float currentPlayingFileLength; float newFileLength; //(*playingAudio).stop(); (*playingAudio).setPaused(true); int newIndicator; if (firstAudioFilePlaying){ playingAudio = &secondAudio; newIndicator = 1; currentPlayingFileLength = tw.firstEnergyVector.size(); newFileLength = tw.secondEnergyVector.size(); } else{ playingAudio = &loadedAudio; newIndicator = 0; currentPlayingFileLength = tw.secondEnergyVector.size(); newFileLength = tw.firstEnergyVector.size(); } //printf("new indicator %i \n", newIndicator); printf("playing pos according to energy frames is %f; ", (currentPlayingFrame/((float)tw.backwardsAlignmentPath[1-newIndicator][0])) );//* conversionFactor)) );//CHROMA_CONVERSION_FACTOR printf("Current frame %f, predicts new frame to be roughly %f \n", (oldPosition*tw.backwardsAlignmentPath[newIndicator][0]), (oldPosition*tw.backwardsAlignmentPath[1-newIndicator][0])); printf("file lenbgths are now %i and other %i\n", tw.backwardsAlignmentPath[newIndicator][0], tw.backwardsAlignmentPath[1-newIndicator][0]); printf("compared to energy vec lengths %i and %i\n", tw.firstEnergyVector.size(), tw.secondEnergyVector.size()); currentChromaFrame = round(oldPosition * currentPlayingFileLength); // currentChromaFrame = currentPlayingFrame;// / conversionFactor; printf("current chroma frame %i \n", currentChromaFrame);//and using energy frames would have been %i \n", currentChromaFrame, currentPlayingFrame / conversionFactor);//CHROMA_CONVERSION_FACTOR); int matchingFrame = findMatchFromAlignment(firstAudioFilePlaying); float relativePosition = matchingFrame / newFileLength;// tw.backwardsAlignmentPath[newIndicator][0]; //i.e. the position as float [0,1] 0:beginning, 1 is end (*playingAudio).setPaused(false); (*playingAudio).setPosition(relativePosition); printf("matching frame is %i \n", matchingFrame, tw.backwardsAlignmentPath[newIndicator][0]); printf("new playing position is %f and back align index %i \n", (*playingAudio).getPosition(), backwardsAlignmentIndex); firstAudioFilePlaying = !firstAudioFilePlaying; conversionFactor = tmpConvFac; } int testApp::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 = backwardsAlignmentIndex;// tw.backwardsAlignmentPath[indicator].size()-1; while (tw.backwardsAlignmentPath[indicator][frame] > currentChromaFrame && backwardsAlignmentIndex < tw.backwardsAlignmentPath[indicator].size()-1){ frame++; } while (tw.backwardsAlignmentPath[indicator][frame] < currentChromaFrame && frame > 0){ frame--; } //printf("frame found is %i \n", frame); int frameToSwitchTo = tw.backwardsAlignmentPath[oppositeIndicator][frame]; float calculatedPosition = (currentChromaFrame / (float) tw.backwardsAlignmentPath[indicator][0]); printf("(length was %i)\n", tw.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) tw.backwardsAlignmentPath[oppositeIndicator][0]) ); return frameToSwitchTo; } void testApp::printSimilarityMatrix(int sizeToPrint){ printf("\n _ _ _ _\n"); printf("Similarity Matrix \n"); int i,j; DoubleVector d; int rowSize = sizeToPrint; for (int j = 0;j < rowSize;j++){ printf("row %i : ", j); for (i = 0;i < rowSize;i++){ printf("%f , ", tw.similarityMatrix[i][j] ); } printf("\n"); } printf("...............\n"); } void testApp::printAlignmentMatrix(const DoubleMatrix& alignmentMatrix){ int size = alignmentMatrix.size(); printf("\n _ _ _ _\n"); printf("align size is %i \n", size); int i,j; DoubleVector d; int rowSize = alignmentMatrix.size(); d = alignmentMatrix[0];//choose initial size for (int j = 0;j < d.size();j++){ printf("row %i : ", j); for (i = 0;i < rowSize;i++){ d = alignmentMatrix[i]; // printf("row %i , col %i, val : %f \n", i, j, alignmentMeasureMatrix[i][j] ); printf("%f , ", alignmentMatrix[i][j] ); } printf("\n"); } printf("...............\n"); } void testApp::printScoreForRow(int row, int max){ printf("alignment scores row %i \n", row); float minimum = tw.alignmentMeasureMatrix[row][0]; int minimumIndex = 0; for (int i =0;i < max;i++){ printf("[%i] %f ", i, tw.alignmentMeasureMatrix[row][i]); if (tw.alignmentMeasureMatrix[row][i] < minimum) { minimum = tw.alignmentMeasureMatrix[row][i] ; minimumIndex = i; } printf(" \n"); } printf("Minimum [%i] : %f \n", minimumIndex, minimum); printf("ALIGN score :[%i] : %f \n", tw.backwardsAlignmentPath[1][backwardsAlignmentIndex], tw.alignmentMeasureMatrix[tw.backwardsAlignmentPath[0][backwardsAlignmentIndex] ][ (int) tw.backwardsAlignmentPath[1][backwardsAlignmentIndex] ]); } void testApp::dontDoJunkAlignment(){ if (1 == 2){ //dont do joint as matrix is too large - energyvec x energyvec //needs doing in parts double timeBefore = ofGetElapsedTimef(); tw.calculateJointSimilarityMatrix(&tw.firstEnergyVector, &tw.secondEnergyVector, &tw.chromaSimilarityMatrix, &tw.similarityMatrix); double elapsedTime = ofGetElapsedTimef() - timeBefore; printf("JOINT SIMILARITY TAKES %6.2f seconds\n", elapsedTime); //this has been replaced by the joint function } // the big similarity measure //timeBefore = ofGetElapsedTimef(); //tw.calculateSimilarityMatrixWithPointers(&tw.firstChromaEnergyMatrix, &tw.secondChromaEnergyMatrix, &tw.similarityMatrix); //elapsedTime = ofGetElapsedTimef() - timeBefore; //printf("CREATING BIG SIMILARITY MATRIX TAKES %f\n", elapsedTime); //bug is here above - needed to make sim matrix visible //new fn // tw.calculateSimilarityMatrixFromChromagramAndEnergy(&tw.firstEnergyVector, &tw.chromaMatrix, &tw.secondEnergyVector, tw.secondMatrix, &tw.similarityMatrix); // tw.calculateAlignmentMatrix(tw.firstChromaEnergyMatrix, tw.secondChromaEnergyMatrix, &tw.alignmentMeasureMatrix); // tw.calculateMinimumAlignmentPath(&tw.alignmentMeasureMatrix, &tw.backwardsAlignmentPath, false); } /* void testApp::pushSimCoxde(){ /* for (int i = 0;i < tw.tmpSimilarityMatrix.size();i++){ DoubleVector v; v = tw.tmpSimilarityMatrix[i]; tw.similarityMatrix.push_back(v); } */ /* void testApp::calculateSimilarityMatrix(){ similarityMatrix.clear(); printf("calculating similarity matrix..."); userInfoString = "calculating similarity matrix..."; double distance, firstSum, secondSum; for (int x = 0;x < tw.chromaMatrix.size();x++){ DoubleVector d; for (int y = 0;y < tw.secondMatrix.size();y++){ //d.push_back( drand48() ); 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 userInfoString += "; size ="; userInfoString += ofToString(similarityMatrix.size() , 0); printf("..sim size: %i, height: %i \n", similarityMatrix.size(), (chromaMatrix[0]).size()); }//end self sim */ /* void testApp::calculateAlignmentMatrix(){ //initialise alignment alignmentMeasureMatrix.clear(); DoubleVector d; d.push_back(getDistance(0,0)); alignmentMeasureMatrix.push_back(d); bool chromaCalculated = false; bool secondCalculated = false; while (!chromaCalculated || !secondCalculated) { if (!chromaCalculated) chromaCalculated = extendAlignmentAlong(); if (!secondCalculated) secondCalculated = extendAlignmentUp(); } } bool testApp::extendAlignmentUp(){ DoubleVector d; d = alignmentMeasureMatrix[0]; int heightSize = d.size(); if (heightSize < secondMatrix.size()){ //then we haven't finished yet for (int i = 0;i < alignmentMeasureMatrix.size();i++){ double value = getDistance(i, heightSize); value += getMinimum(i, heightSize, value); alignmentMeasureMatrix[i].push_back(value); } } if (alignmentMeasureMatrix[0].size() == secondMatrix.size()) return true; else return false; } bool testApp::extendAlignmentAlong(){ DoubleVector d; int widthSize = alignmentMeasureMatrix.size(); if (widthSize < chromaMatrix.size()){ //then we can extend along double value = getDistance(widthSize, 0); value += getMinimum(widthSize, 0, value); d.push_back(value); alignmentMeasureMatrix.push_back(d); for (int j = 1;j < alignmentMeasureMatrix[widthSize - 1].size();j++){ value = getDistance(widthSize, j); value += getMinimum(widthSize, j, value); alignmentMeasureMatrix[widthSize].push_back(value); } //alignmentMeasureMatrix.push_back(d); } if (alignmentMeasureMatrix.size() == chromaMatrix.size()) return true; else return false; } void testApp::calculateMinimumAlignmentPath(){ //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 //minimumAlignmentPath.clear(); backwardsAlignmentPath.clear(); printf("Finding minimum Path \n"); IntVector v; v.push_back(chromaMatrix.size()-1); backwardsAlignmentPath.push_back(v); v.clear(); v.push_back(secondMatrix.size()-1); 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 %i : %i \n", backwardsAlignmentPath[0][indexOfBackwardsPath], backwardsAlignmentPath[1][indexOfBackwardsPath]); } //printf("final index of backwards path is %i and i is %i \n", backwardsAlignmentPath[0].size()-1, indexOfBackwardsPath); backwardsAlignmentIndex = backwardsAlignmentPath[0].size()-1;//remember that this goes backwards! } bool testApp::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 testApp::testForNewAlignmentMinimum(double *previousMinimum, int i, int j){ bool newMinimumFound = false; if (alignmentMeasureMatrix[i][j] < *previousMinimum){ *previousMinimum = alignmentMeasureMatrix[i][j]; newMinimumFound = true; } 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; } */