andrew@0: #include "testApp.h" andrew@0: #include "stdio.h" andrew@0: #include "aubio.h" andrew@0: #include andrew@0: #include andrew@0: #include andrew@0: #include andrew@0: andrew@0: andrew@0: const double samplingFrequency = 44100.0; andrew@0: andrew@0: //-------------------------------------------------------------- andrew@0: void testApp::setup(){ andrew@0: andrew@0: ofBackground(255,255,255); andrew@0: andrew@1: andrew@0: // 2 output channels, andrew@0: // 0 input channels andrew@0: // 22050 samples per second andrew@0: // 256 samples per buffer andrew@0: // 4 num buffers (latency) andrew@0: andrew@0: //nb THIS CODE WOULD BE USEFUL IF WE EVER WANTED REAL-TIME INPUT - VIA ofSoundSteam andrew@0: andrew@0: andrew@0: // ofSetDataPathRoot("../bin/data/"); andrew@0: andrew@0: //DONT NEED ANY OF THIS andrew@0: sampleRate = 44100; andrew@0: // phase = 0; andrew@0: // phaseAdder = 0.0f; andrew@0: // phaseAdderTarget = 0.0f; andrew@0: volume = 0.1f; andrew@0: bNoise = false; andrew@0: lAudio = new float[256]; andrew@0: rAudio = new float[256]; andrew@0: ofSoundStreamSetup(2,0,this, sampleRate,256, 4); andrew@0: //UNTIL HERE andrew@0: andrew@0: andrew@0: ofSetFrameRate(60); andrew@0: andrew@1: // fvec_t * my_fvec_t; andrew@1: // aubio_onset_t* my_aubio_result; andrew@1: // aubio_onsetdetection_t * my_onset_detection; andrew@0: andrew@0: audioScale = 1000.0; andrew@0: andrew@1: andrew@0: andrew@0: //int readcount = 0; // counts number of samples read from sound file andrew@0: andrew@0: //string inputFilename = "sound/GetIntoTheGroove.wav";// input file name placed in bin andrew@0: andrew@1: andrew@0: andrew@0: moveOn = true; andrew@0: andrew@0: //loading audio files andrew@0: andrew@0: const char *infilename = "../../../data/sound/bach4_short1.wav"; andrew@0: loadNewAudio(infilename); andrew@0: andrew@0: audioPlaying = false; andrew@0: andrew@0: drawSpectralDifferenceFunction = false; andrew@0: andrew@0: screenToDraw = 1; andrew@0: andrew@0: andrew@0: } andrew@0: andrew@0: andrew@0: void testApp::initialiseVariables(){ andrew@0: andrew@1: // chromoGramm.initialise(FRAMESIZE,2048);//framesize 512 and hopsize 2048 andrew@0: } andrew@0: andrew@0: andrew@0: //-------------------------------------------------------------- andrew@0: void testApp::update(){ andrew@0: andrew@1: audioPosition = loadedAudio.getPosition() * fileLoader.totalNumberOfFrames;//frameIndex;//the position in number of frames andrew@1: fileLoader.chromaAnalysis.currentPlayingFrame = audioPosition; andrew@1: audioPosition = (int) audioPosition % fileLoader.chromaAnalysis.scrollWidth ; andrew@1: audioPosition /= fileLoader.chromaAnalysis.scrollWidth; andrew@0: andrew@1: fileLoader.audioHolder.playPosition = loadedAudio.getPosition() * fileLoader.audioHolder.audioVector.size(); andrew@0: } andrew@0: andrew@0: //-------------------------------------------------------------- andrew@0: void testApp::draw(){ andrew@0: switch (screenToDraw){ andrew@0: case 0: andrew@0: if (drawSpectralDifferenceFunction) andrew@1: fileLoader.chromaAnalysis.drawSpectralDifference(); andrew@0: else andrew@1: drawDoubleMatrix(&fileLoader.chromaAnalysis.chromaMatrix); andrew@0: andrew@1: fileLoader.chromaAnalysis.drawEnergyVectorFromPointer(); andrew@1: andrew@0: ofSetColor(0xFFFFFF); andrew@0: ofLine(audioPosition*width, 0, audioPosition*width, height); andrew@0: break; andrew@0: case 1: andrew@0: // audioHolder.drawAudioVectorMillis(1000, 1000+audioScale); andrew@1: fileLoader.audioHolder.drawAudioVectorSamples(fileLoader.audioHolder.playPosition - fileLoader.audioHolder.audioScaleSamples*0.5, fileLoader.audioHolder.playPosition+fileLoader.audioHolder.audioScaleSamples*0.5); andrew@0: ofSetColor(100,100,100); andrew@0: ofLine(width/2, 0, width/2, height); andrew@0: break; andrew@0: } andrew@0: andrew@0: andrew@0: andrew@0: //ofSetColor(255,0,0); andrew@0: //drawEnergyVectorFromPointer(&audioVector); andrew@0: andrew@0: andrew@0: andrew@0: ofDrawBitmapString(soundFileName,80,480); andrew@0: andrew@0: } andrew@0: andrew@0: andrew@0: andrew@0: void testApp::drawDoubleMatrix(DoubleMatrix* dMatrix){ andrew@0: //used to draw the chromagram matrix andrew@0: int matrixSize = (*dMatrix).size(); andrew@0: if (matrixSize > 0){ andrew@0: andrew@0: float screenHeight = ofGetHeight() ; andrew@0: float screenWidth = ofGetWidth(); andrew@0: float heightFactor = 8; andrew@0: int i, j, startingFrame; andrew@1: startingFrame = fileLoader.chromaAnalysis.currentPlayingFrame / fileLoader.chromaAnalysis.scrollWidth;//i.e. number of scroll widths in andrew@1: startingFrame *= fileLoader.chromaAnalysis.scrollWidth;//starting frame in terms of energy frames andrew@0: startingFrame /= CHROMA_CONVERSION_FACTOR; //in terms of chroma frames andrew@0: andrew@1: float chromoLength = fileLoader.chromaAnalysis.scrollWidth/CHROMA_CONVERSION_FACTOR; andrew@0: for (i = 0; i < chromoLength; i++){ andrew@0: j = i + startingFrame; andrew@0: for (int y = 0;y < 12;y++){ andrew@0: andrew@0: if (j < matrixSize) andrew@0: ofSetColor(0,0,255 * (*dMatrix)[j][11-y]); andrew@0: else andrew@0: ofSetColor(0,0,0); andrew@0: andrew@0: ofRect(i*screenWidth/chromoLength,y*screenHeight/12,screenWidth/chromoLength,screenHeight/12); andrew@0: }//end y andrew@0: }//end i andrew@0: andrew@0: }///end if matrix has content andrew@0: else{ andrew@0: printf("Error - please load audio first"); andrew@0: } andrew@0: andrew@0: andrew@0: } andrew@0: andrew@0: andrew@0: andrew@1: /* andrew@0: void testApp::loadLibSndFile(const char *infilename){ andrew@0: andrew@0: if (!sf_close(infile)){ andrew@0: printf("closed sndfile okay \n"); andrew@0: } andrew@0: andrew@0: // Open Input File with lib snd file andrew@0: if (! (infile = sf_open (infilename, SFM_READ, &sfinfo))) andrew@0: { // Open failed andrew@0: printf ("SF OPEN routine Not able to open input file %s.\n", infilename) ; andrew@0: // Print the error message from libsndfile. andrew@0: puts (sf_strerror (NULL)) ; andrew@0: andrew@0: } else{ andrew@0: printf("SF OPEN : file %s okay, ", infilename); andrew@0: printf("number of channels is %i\n", sfinfo.channels); andrew@0: sndfileInfoString = "Opened okay "; andrew@0: andrew@0: }; andrew@0: andrew@0: } andrew@1: */ andrew@1: /* andrew@0: void testApp::processAudioToDoubleMatrix(Chromagram* chromaG, DoubleMatrix* myDoubleMatrix, DoubleVector* energyVector){ andrew@0: andrew@0: myDoubleMatrix->clear(); andrew@0: energyVector->clear(); andrew@0: andrew@0: audioHolder.audioVector.clear(); andrew@0: audioHolder.audioMatrix.clear(); andrew@0: andrew@0: // energyIndex = 0; andrew@0: // frameIndex = 0; andrew@0: // chromaIndex = 0;// WHY NEED THIS? andrew@0: chromaG->initialise(FRAMESIZE,2048);//framesize 512 and hopsize 2048 andrew@0: chromaG->maximumChromaValue = 0; andrew@0: andrew@0: andrew@0: andrew@0: andrew@0: // HERE IS THE CLASSIC LOADING FILE CODE andrew@0: //DEALS WITH MORE THAN MONO andrew@0: int channels = sfinfo.channels; andrew@0: int blocksize = FRAMESIZE; andrew@0: andrew@0: float buf [channels * blocksize] ; andrew@0: int k, m, readcount ; andrew@0: andrew@0: DoubleVector d; andrew@0: while ((readcount = sf_readf_float (infile, buf, blocksize)) > 0){ andrew@0: for (k = 0 ; k < readcount ; k++){ andrew@0: d.clear(); andrew@0: for (m = 0 ; m < channels ; m++){ andrew@0: d.push_back(buf [k * channels + m]); andrew@0: // fprintf (outfile, " % 12.10f", buf [k * channels + m]) ; andrew@0: // fprintf (outfile, "\n") ; andrew@0: if (m == 0){ andrew@0: //makes the vector hold the mono file andrew@0: //this is the one we use for chromagram analysis etc andrew@0: audioHolder.audioVector.push_back(buf[k * channels + 0]); andrew@0: frame[k] = buf[k*channels + 0]; andrew@0: } andrew@0: andrew@0: } andrew@0: audioHolder.audioMatrix.push_back(d); andrew@0: //storing the full soundfile in multiple channels in the audioMatrix andrew@0: } andrew@0: andrew@0: andrew@0: chromaG->processframe(frame); andrew@0: andrew@0: if (chromaG->chromaready) andrew@0: { andrew@0: DoubleVector d; andrew@0: andrew@0: for (int i = 0;i<12;i++){ andrew@0: //chromoGramVector[chromaIndex][i] = chromoGramm.rawChroma[i] / chromoGramm.maximumChromaValue; andrew@0: d.push_back(chromaG->rawChroma[i]);// / chromaG->maximumChromaValue); andrew@0: andrew@0: } andrew@0: andrew@0: myDoubleMatrix->push_back(d); andrew@0: andrew@0: //There was a method to detect chord but deleted andrew@0: // chord.C_Detect(chromoGramm.chroma,chromoGramm.chroma_low); andrew@0: // rootChord[chromaIndex] = chord.root; andrew@0: andrew@0: andrew@0: }//end if chromagRamm ready andrew@0: andrew@0: // frameIndex++; andrew@0: andrew@0: //get energy of the current frame and wait andrew@0: double energyValue = getEnergyOfFrame(); andrew@0: energyVector->push_back(energyValue); andrew@0: andrew@0: andrew@0: andrew@0: }//end readcount andrew@0: andrew@0: andrew@0: andrew@0: printf("Max chroma value is %f \n", chromaG->maximumChromaValue); andrew@0: andrew@0: andrew@0: andrew@0: //normalise andrew@0: int length = myDoubleMatrix->size(); andrew@0: printf("length of chromagram is %d frames\n", length); andrew@0: length = ((*myDoubleMatrix)[0]).size(); andrew@0: printf("height of dmatrix is %d\n", length); andrew@0: andrew@0: for (int i = 0; i < myDoubleMatrix->size();i++){ andrew@0: for (int j = 0; j < ((*myDoubleMatrix)[0]).size();j++){ andrew@0: (*myDoubleMatrix)[i][j] /= chromaG->maximumChromaValue; andrew@0: } andrew@0: } andrew@0: andrew@0: andrew@0: printf("size of energy vector is %d \n", (int) energyVector->size()); andrew@0: andrew@0: totalNumberOfFrames = (int) energyVector->size();//frameIndex;//used to use this - but switch to energy vector's size instead andrew@0: andrew@0: // printf("Total frames %i energy index %i and Chroma index %i \n", frameIndex, energyIndex, chromaIndex); andrew@0: andrew@0: printf("audio vector size is %i\n", (int) audioHolder.audioVector.size()); andrew@0: audioHolder.length = (int) audioHolder.audioVector.size(); andrew@0: } andrew@0: andrew@1: */ andrew@0: //-------------------------------------------------------------- andrew@0: void testApp::keyPressed (int key){ andrew@0: if (key == '-'){ andrew@0: volume -= 0.05; andrew@0: volume = MAX(volume, 0); andrew@0: } else if (key == '+'){ andrew@0: volume += 0.05; andrew@0: volume = MIN(volume, 1); andrew@0: } andrew@0: andrew@0: if (key == 'q') andrew@0: screenToDraw = 1 - screenToDraw; andrew@0: andrew@0: if (key == OF_KEY_DOWN){ andrew@1: if (fileLoader.chromaAnalysis.scrollWidth > 600) andrew@1: fileLoader.chromaAnalysis.scrollWidth += 400; andrew@0: else andrew@1: fileLoader.chromaAnalysis.scrollWidth *= 2; andrew@0: } andrew@0: andrew@0: if (key == OF_KEY_RIGHT){ andrew@1: loadedAudio.setPosition(min(1.0, loadedAudio.getPosition() + (fileLoader.audioHolder.audioScaleSamples/(4.0*fileLoader.audioHolder.audioVector.size()))) ); andrew@0: // audioHolder.playPosition = loadedAudio.getPosition() * audioHolder.audioVector.size(); andrew@0: } andrew@0: andrew@0: if (key == OF_KEY_LEFT){ andrew@1: loadedAudio.setPosition(max(0.0, loadedAudio.getPosition() - (fileLoader.audioHolder.audioScaleSamples/(4.0*fileLoader.audioHolder.audioVector.size())))); andrew@0: // audioHolder.playPosition = loadedAudio.getPosition() * audioHolder.audioVector.size(); andrew@0: } andrew@0: andrew@0: andrew@0: if (key == OF_KEY_UP){ andrew@1: if (fileLoader.chromaAnalysis.scrollWidth > 600) andrew@1: fileLoader.chromaAnalysis.scrollWidth -= 400; andrew@0: else andrew@1: fileLoader.chromaAnalysis.scrollWidth /= 2; andrew@0: } andrew@0: andrew@0: if (key == ' '){ andrew@0: if (!audioPlaying) { andrew@0: loadedAudio.play(); andrew@0: loadedAudio.setPaused(false); andrew@0: audioPlaying = true; andrew@0: audioPaused = false; andrew@0: } andrew@0: else{ andrew@0: audioPaused = !audioPaused; andrew@0: loadedAudio.setPaused(audioPaused); andrew@0: } andrew@0: andrew@0: } andrew@0: andrew@0: if (key == OF_KEY_RETURN){ andrew@0: audioPlaying = false; andrew@0: loadedAudio.setPaused(true); andrew@0: loadedAudio.setPosition(0.0); andrew@0: } andrew@0: andrew@0: andrew@0: if (key == 'o'){ andrew@0: openNewAudioFileWithdialogBox(); andrew@0: } andrew@0: andrew@0: andrew@0: if (key == 'd'){ andrew@0: drawSpectralDifferenceFunction = !drawSpectralDifferenceFunction; andrew@0: } andrew@0: andrew@0: if (key == 'u'){ andrew@0: audioScale *= 2.; andrew@1: fileLoader.audioHolder.audioScaleSamples *= 2.; andrew@0: } andrew@0: andrew@0: if (key == 'j'){ andrew@0: audioScale /= 2.; andrew@1: fileLoader.audioHolder.audioScaleSamples /= 2.; andrew@0: } andrew@0: } andrew@0: andrew@0: //-------------------------------------------------------------- andrew@0: void testApp::keyReleased (int key){ andrew@0: andrew@0: } andrew@0: andrew@0: void testApp::openNewAudioFileWithdialogBox(){ andrew@0: andrew@0: //open audio file andrew@0: string *filePtr; andrew@0: filePtr = &soundFileName; andrew@0: andrew@0: if (getFilenameFromDialogBox(filePtr)){ andrew@0: printf("Mainfile: Loaded name okay :\n'%s' \n", soundFileName.c_str()); andrew@0: } andrew@0: andrew@0: loadNewAudio(soundFileName); andrew@0: andrew@0: } andrew@0: andrew@0: //-------------------------------------------------------------- andrew@0: void testApp::mouseMoved(int x, int y ){ andrew@0: width = ofGetWidth(); andrew@0: pan = (float)x / (float)width; andrew@0: float height = (float)ofGetHeight(); andrew@0: float heightPct = ((height-y) / height); andrew@1: xIndex = (int)(pan*fileLoader.chromaAnalysis.energyVector.size()); andrew@0: } andrew@0: andrew@0: //-------------------------------------------------------------- andrew@0: void testApp::mouseDragged(int x, int y, int button){ andrew@0: width = ofGetWidth(); andrew@0: pan = (float)x / (float)width; andrew@0: } andrew@0: andrew@0: //-------------------------------------------------------------- andrew@0: void testApp::mousePressed(int x, int y, int button){ andrew@0: bNoise = true; andrew@0: moveOn = true; andrew@0: } andrew@0: andrew@0: andrew@0: //-------------------------------------------------------------- andrew@0: void testApp::mouseReleased(int x, int y, int button){ andrew@0: bNoise = false; andrew@0: } andrew@0: andrew@0: //-------------------------------------------------------------- andrew@0: void testApp::windowResized(int w, int h){ andrew@0: width = w; andrew@0: height = h; andrew@0: } andrew@0: //-------------------------------------------------------------- andrew@0: void testApp::audioRequested (float * output, int bufferSize, int nChannels){ andrew@0: //pan = 0.5f; andrew@0: float leftScale = 1 - pan; andrew@0: float rightScale = pan; andrew@0: andrew@0: } andrew@0: andrew@0: andrew@0: //-------------------------------------------------------------- andrew@0: andrew@0: andrew@0: bool testApp::getFilenameFromDialogBox(string* fileNameToSave){ andrew@0: //this uses a pointer structure within the loader and returns true if the dialogue box was used successfully andrew@0: // first, create a string that will hold the URL andrew@0: string URL; andrew@0: andrew@0: // openFile(string& URL) returns 1 if a file was picked andrew@0: // returns 0 when something went wrong or the user pressed 'cancel' andrew@0: int response = ofxFileDialogOSX::openFile(URL); andrew@0: if(response){ andrew@0: // now you can use the URL andrew@0: *fileNameToSave = URL; andrew@0: //printf("\n filename is %s \n", soundFileName.c_str()); andrew@0: return true; andrew@0: } andrew@0: else { andrew@0: // soundFileName = "OPEN canceled. "; andrew@0: printf("\n open file cancelled \n"); andrew@0: return false; andrew@0: } andrew@0: andrew@0: } andrew@0: andrew@0: void testApp::openFileDialogBox(){ andrew@0: andrew@0: // first, create a string that will hold the URL andrew@0: string URL; andrew@0: andrew@0: // openFile(string& URL) returns 1 if a file was picked andrew@0: // returns 0 when something went wrong or the user pressed 'cancel' andrew@0: int response = ofxFileDialogOSX::openFile(URL); andrew@0: if(response){ andrew@0: // now you can use the URL andrew@0: soundFileName = URL;//"URL to open: \n "+URL; andrew@0: }else { andrew@0: soundFileName = "OPEN canceled. "; andrew@0: } andrew@0: andrew@0: andrew@0: andrew@0: } andrew@0: andrew@0: andrew@0: void testApp::loadNewAudio(string soundFileName){ andrew@0: andrew@0: loadedAudio.loadSound(soundFileName); andrew@0: andrew@0: //snd file method andrew@0: const char *infilename = soundFileName.c_str() ; andrew@1: fileLoader.loadLibSndFile(infilename); andrew@0: andrew@1: andrew@0: andrew@0: audioPlaying = false; andrew@0: } andrew@0: andrew@0: andrew@0: andrew@0: andrew@0: andrew@1: /* andrew@1: andrew@0: double testApp::getEnergyOfFrame(){ andrew@0: andrew@0: float totalEnergyInFrame = 0; andrew@0: andrew@0: for (int i = 0;iprocessframe(frame); andrew@0: andrew@0: if (chromaG->chromaready) andrew@0: { andrew@0: DoubleVector d; andrew@0: andrew@0: for (int i = 0;i<12;i++){ andrew@0: //chromoGramVector[chromaIndex][i] = chromoGramm.rawChroma[i] / chromoGramm.maximumChromaValue; andrew@0: d.push_back(chromaG->rawChroma[i]);// / chromaG->maximumChromaValue); andrew@0: andrew@0: } andrew@0: andrew@0: myDoubleMatrix->push_back(d); andrew@0: andrew@0: //There was a method to detect chord but deleted andrew@0: // chord.C_Detect(chromoGramm.chroma,chromoGramm.chroma_low); andrew@0: // rootChord[chromaIndex] = chord.root; andrew@0: andrew@0: andrew@0: }//end if chromagRamm ready andrew@0: andrew@0: //printf("calling drawSndFile %i", frameIndex); andrew@0: // frameIndex++; andrew@0: andrew@0: //get energy of the current frame and wait andrew@0: double energyValue = getEnergyOfFrame(); andrew@0: energyVector->push_back(energyValue); andrew@0: andrew@0: andrew@0: }//end while readcount andrew@0: andrew@0: andrew@1: void testApp::drawEnergyVectorFromPointer(DoubleVector* energyVec){ andrew@1: andrew@1: ofSetColor(0xFF0066); andrew@1: float screenHeight = ofGetHeight() ; andrew@1: float screenWidth = ofGetWidth(); andrew@1: float heightFactor = 8; andrew@1: int i, j, startingFrame; andrew@1: startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in andrew@1: startingFrame *= scrollWidth; andrew@1: andrew@1: for (i = 0; i < scrollWidth - 1; i++){ andrew@1: j = i + startingFrame; andrew@1: if (j < (*energyVec).size()) andrew@1: ofLine(i*screenWidth/scrollWidth, screenHeight - ((*energyVec)[j]*screenHeight/heightFactor), andrew@1: screenWidth*(i+1)/scrollWidth, screenHeight - ((*energyVec)[j+1]*screenHeight/heightFactor)); andrew@1: andrew@1: } andrew@1: } andrew@1: andrew@1: void testApp::drawSpectralDifference(DoubleMatrix* dMatrix){ andrew@1: int matrixSize = (*dMatrix).size(); andrew@1: if (matrixSize > 0){ andrew@1: andrew@1: float screenHeight = ofGetHeight() ; andrew@1: float screenWidth = ofGetWidth(); andrew@1: float heightFactor = 8; andrew@1: double difference; andrew@1: int i, j, startingFrame; andrew@1: startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in andrew@1: startingFrame *= scrollWidth;//starting frame in terms of energy frames andrew@1: startingFrame /= CHROMA_CONVERSION_FACTOR; //in terms of chroma frames andrew@1: andrew@1: float chromoLength = scrollWidth/CHROMA_CONVERSION_FACTOR; andrew@1: for (i = 1; i < chromoLength; i++){//changed to add 1 andrew@1: j = i + startingFrame; andrew@1: for (int y = 0;y < 12;y++){ andrew@1: andrew@1: if (j < matrixSize) andrew@1: difference = (*dMatrix)[j][11-y] - (*dMatrix)[j-1][11-y]; andrew@1: else andrew@1: difference = 0; andrew@1: andrew@1: if (difference < 0) andrew@1: difference = 0;//half wave rectify andrew@1: andrew@1: ofSetColor(0,0,255 * difference);//, 0; andrew@1: ofRect(i*screenWidth/chromoLength,y*screenHeight/12,screenWidth/chromoLength,screenHeight/12); andrew@1: }//end y andrew@1: }//end i andrew@1: andrew@1: }///end if matrix has content andrew@1: else{ andrew@1: printf("Error - please load audio first"); andrew@1: } andrew@1: andrew@1: } andrew@1: andrew@0: */