Mercurial > hg > audio-file-loader
view src/testApp.cpp @ 1:ba2a17cf81bf
first working version of audio file loder. Loads bach clip from the apps->audio-file-loader->bin->data->sounds foler. Three classes: SoundFileLoader does the loading and parsing of thefile with libSndFile. audio samples are kept in AudioFile and analysis of features are kept in AudioAnalysis, at this stage just chromagramm and basic energy
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Sun, 04 Sep 2011 22:45:35 +0100 |
parents | bcb0d40158f4 |
children |
line wrap: on
line source
#include "testApp.h" #include "stdio.h" #include "aubio.h" #include <iostream> #include <cstring> #include <string> #include <cstdlib> const double samplingFrequency = 44100.0; //-------------------------------------------------------------- void testApp::setup(){ ofBackground(255,255,255); // 2 output channels, // 0 input channels // 22050 samples per second // 256 samples per buffer // 4 num buffers (latency) //nb THIS CODE WOULD BE USEFUL IF WE EVER WANTED REAL-TIME INPUT - VIA ofSoundSteam // 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; audioScale = 1000.0; //int readcount = 0; // counts number of samples read from sound file //string inputFilename = "sound/GetIntoTheGroove.wav";// input file name placed in bin moveOn = true; //loading audio files const char *infilename = "../../../data/sound/bach4_short1.wav"; loadNewAudio(infilename); audioPlaying = false; drawSpectralDifferenceFunction = false; screenToDraw = 1; } void testApp::initialiseVariables(){ // chromoGramm.initialise(FRAMESIZE,2048);//framesize 512 and hopsize 2048 } //-------------------------------------------------------------- void testApp::update(){ audioPosition = loadedAudio.getPosition() * fileLoader.totalNumberOfFrames;//frameIndex;//the position in number of frames fileLoader.chromaAnalysis.currentPlayingFrame = audioPosition; audioPosition = (int) audioPosition % fileLoader.chromaAnalysis.scrollWidth ; audioPosition /= fileLoader.chromaAnalysis.scrollWidth; fileLoader.audioHolder.playPosition = loadedAudio.getPosition() * fileLoader.audioHolder.audioVector.size(); } //-------------------------------------------------------------- void testApp::draw(){ switch (screenToDraw){ case 0: if (drawSpectralDifferenceFunction) fileLoader.chromaAnalysis.drawSpectralDifference(); else drawDoubleMatrix(&fileLoader.chromaAnalysis.chromaMatrix); fileLoader.chromaAnalysis.drawEnergyVectorFromPointer(); ofSetColor(0xFFFFFF); ofLine(audioPosition*width, 0, audioPosition*width, height); break; case 1: // audioHolder.drawAudioVectorMillis(1000, 1000+audioScale); fileLoader.audioHolder.drawAudioVectorSamples(fileLoader.audioHolder.playPosition - fileLoader.audioHolder.audioScaleSamples*0.5, fileLoader.audioHolder.playPosition+fileLoader.audioHolder.audioScaleSamples*0.5); ofSetColor(100,100,100); ofLine(width/2, 0, width/2, height); break; } //ofSetColor(255,0,0); //drawEnergyVectorFromPointer(&audioVector); ofDrawBitmapString(soundFileName,80,480); } void testApp::drawDoubleMatrix(DoubleMatrix* dMatrix){ //used to draw the chromagram matrix int matrixSize = (*dMatrix).size(); if (matrixSize > 0){ float screenHeight = ofGetHeight() ; float screenWidth = ofGetWidth(); float heightFactor = 8; int i, j, startingFrame; startingFrame = fileLoader.chromaAnalysis.currentPlayingFrame / fileLoader.chromaAnalysis.scrollWidth;//i.e. number of scroll widths in startingFrame *= fileLoader.chromaAnalysis.scrollWidth;//starting frame in terms of energy frames startingFrame /= CHROMA_CONVERSION_FACTOR; //in terms of chroma frames float chromoLength = fileLoader.chromaAnalysis.scrollWidth/CHROMA_CONVERSION_FACTOR; for (i = 0; i < chromoLength; i++){ j = i + startingFrame; for (int y = 0;y < 12;y++){ if (j < matrixSize) ofSetColor(0,0,255 * (*dMatrix)[j][11-y]); else ofSetColor(0,0,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::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 : file %s okay, ", infilename); printf("number of channels is %i\n", sfinfo.channels); sndfileInfoString = "Opened okay "; }; } */ /* void testApp::processAudioToDoubleMatrix(Chromagram* chromaG, DoubleMatrix* myDoubleMatrix, DoubleVector* energyVector){ myDoubleMatrix->clear(); energyVector->clear(); audioHolder.audioVector.clear(); audioHolder.audioMatrix.clear(); // energyIndex = 0; // frameIndex = 0; // chromaIndex = 0;// WHY NEED THIS? chromaG->initialise(FRAMESIZE,2048);//framesize 512 and hopsize 2048 chromaG->maximumChromaValue = 0; // HERE IS THE CLASSIC LOADING FILE CODE //DEALS WITH MORE THAN MONO int channels = sfinfo.channels; int blocksize = FRAMESIZE; float buf [channels * blocksize] ; int k, m, readcount ; DoubleVector d; while ((readcount = sf_readf_float (infile, buf, blocksize)) > 0){ for (k = 0 ; k < readcount ; k++){ d.clear(); for (m = 0 ; m < channels ; m++){ d.push_back(buf [k * channels + m]); // fprintf (outfile, " % 12.10f", buf [k * channels + m]) ; // fprintf (outfile, "\n") ; if (m == 0){ //makes the vector hold the mono file //this is the one we use for chromagram analysis etc audioHolder.audioVector.push_back(buf[k * channels + 0]); frame[k] = buf[k*channels + 0]; } } audioHolder.audioMatrix.push_back(d); //storing the full soundfile in multiple channels in the audioMatrix } 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); } myDoubleMatrix->push_back(d); //There was a method to detect chord but deleted // chord.C_Detect(chromoGramm.chroma,chromoGramm.chroma_low); // rootChord[chromaIndex] = chord.root; }//end if chromagRamm ready // frameIndex++; //get energy of the current frame and wait double energyValue = getEnergyOfFrame(); energyVector->push_back(energyValue); }//end 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; } } printf("size of energy vector is %d \n", (int) energyVector->size()); totalNumberOfFrames = (int) energyVector->size();//frameIndex;//used to use this - but switch to energy vector's size instead // printf("Total frames %i energy index %i and Chroma index %i \n", frameIndex, energyIndex, chromaIndex); printf("audio vector size is %i\n", (int) audioHolder.audioVector.size()); audioHolder.length = (int) audioHolder.audioVector.size(); } */ //-------------------------------------------------------------- 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 == 'q') screenToDraw = 1 - screenToDraw; if (key == OF_KEY_DOWN){ if (fileLoader.chromaAnalysis.scrollWidth > 600) fileLoader.chromaAnalysis.scrollWidth += 400; else fileLoader.chromaAnalysis.scrollWidth *= 2; } if (key == OF_KEY_RIGHT){ loadedAudio.setPosition(min(1.0, loadedAudio.getPosition() + (fileLoader.audioHolder.audioScaleSamples/(4.0*fileLoader.audioHolder.audioVector.size()))) ); // audioHolder.playPosition = loadedAudio.getPosition() * audioHolder.audioVector.size(); } if (key == OF_KEY_LEFT){ loadedAudio.setPosition(max(0.0, loadedAudio.getPosition() - (fileLoader.audioHolder.audioScaleSamples/(4.0*fileLoader.audioHolder.audioVector.size())))); // audioHolder.playPosition = loadedAudio.getPosition() * audioHolder.audioVector.size(); } if (key == OF_KEY_UP){ if (fileLoader.chromaAnalysis.scrollWidth > 600) fileLoader.chromaAnalysis.scrollWidth -= 400; else fileLoader.chromaAnalysis.scrollWidth /= 2; } if (key == ' '){ if (!audioPlaying) { loadedAudio.play(); loadedAudio.setPaused(false); audioPlaying = true; audioPaused = false; } else{ audioPaused = !audioPaused; loadedAudio.setPaused(audioPaused); } } if (key == OF_KEY_RETURN){ audioPlaying = false; loadedAudio.setPaused(true); loadedAudio.setPosition(0.0); } if (key == 'o'){ openNewAudioFileWithdialogBox(); } if (key == 'd'){ drawSpectralDifferenceFunction = !drawSpectralDifferenceFunction; } if (key == 'u'){ audioScale *= 2.; fileLoader.audioHolder.audioScaleSamples *= 2.; } if (key == 'j'){ audioScale /= 2.; fileLoader.audioHolder.audioScaleSamples /= 2.; } } //-------------------------------------------------------------- void testApp::keyReleased (int key){ } void testApp::openNewAudioFileWithdialogBox(){ //open audio file string *filePtr; filePtr = &soundFileName; if (getFilenameFromDialogBox(filePtr)){ printf("Mainfile: Loaded name okay :\n'%s' \n", soundFileName.c_str()); } 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); xIndex = (int)(pan*fileLoader.chromaAnalysis.energyVector.size()); } //-------------------------------------------------------------- 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; } //-------------------------------------------------------------- void testApp::audioRequested (float * output, int bufferSize, int nChannels){ //pan = 0.5f; float leftScale = 1 - pan; float rightScale = pan; } //-------------------------------------------------------------- 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 canceled. "; } } void testApp::loadNewAudio(string soundFileName){ loadedAudio.loadSound(soundFileName); //snd file method const char *infilename = soundFileName.c_str() ; fileLoader.loadLibSndFile(infilename); audioPlaying = false; } /* double testApp::getEnergyOfFrame(){ float totalEnergyInFrame = 0; for (int i = 0;i<FRAMESIZE;i++){ totalEnergyInFrame += (frame[i] * frame[i]); } totalEnergyInFrame = sqrt(totalEnergyInFrame); return totalEnergyInFrame; } */ //JUNK METHODS BEFORE SWITCHING TO VECTORS TO HOLD ENERGY AND CHROMA //THESE ARE BETTER AS THEY ARE DYNAMIC /* void testApp::drawChromoGram(){ 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(255*chromoGramVector[j][11-y],0,0); ofRect(i*screenWidth/chromoLength,y*screenHeight/12,screenWidth/chromoLength,screenHeight/12); }//end y }//end i } */ /* void testApp::drawChromaMatrix(){ 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,255*chromaMatrix[j][11-y],0); ofRect(i*screenWidth/chromoLength,y*screenHeight/12,screenWidth/chromoLength,screenHeight/12); }//end y }//end i } */ /* int readcount = 1; // counts number of samples read from sound file printf("processing audio from doublematrix \n"); while(readcount != 0 && moveOn == true) { // read FRAMESIZE samples from 'infile' and save in 'data' readcount = sf_read_float(infile, frame, FRAMESIZE); for (int i = 0;i < FRAMESIZE;i++) audioHolder.audioVector.push_back(frame[i]); printf("frame%f\n", frame[0]); //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); } myDoubleMatrix->push_back(d); //There was a method to detect chord but deleted // chord.C_Detect(chromoGramm.chroma,chromoGramm.chroma_low); // rootChord[chromaIndex] = chord.root; }//end if chromagRamm ready //printf("calling drawSndFile %i", frameIndex); // frameIndex++; //get energy of the current frame and wait double energyValue = getEnergyOfFrame(); energyVector->push_back(energyValue); }//end while readcount void testApp::drawEnergyVectorFromPointer(DoubleVector* energyVec){ ofSetColor(0xFF0066); 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; if (j < (*energyVec).size()) ofLine(i*screenWidth/scrollWidth, screenHeight - ((*energyVec)[j]*screenHeight/heightFactor), screenWidth*(i+1)/scrollWidth, screenHeight - ((*energyVec)[j+1]*screenHeight/heightFactor)); } } void testApp::drawSpectralDifference(DoubleMatrix* dMatrix){ int matrixSize = (*dMatrix).size(); if (matrixSize > 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 float chromoLength = scrollWidth/CHROMA_CONVERSION_FACTOR; for (i = 1; i < chromoLength; i++){//changed to add 1 j = i + startingFrame; for (int y = 0;y < 12;y++){ if (j < matrixSize) difference = (*dMatrix)[j][11-y] - (*dMatrix)[j-1][11-y]; else difference = 0; 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"); } } */