Mercurial > hg > precise-onset-detection
view ofxPreciseOnsetDetectorOffline/PreciseOnsetDetectorOffline.cpp @ 2:7ec1ed0b2eb0
Added offline precise onset detection, outputting precise locations in seconds to text file
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Mon, 30 Dec 2013 14:08:42 +0000 |
parents | |
children | 50f62c48b421 |
line wrap: on
line source
/* * PreciseOnsetDetectorOffline.cpp * ofxPreciseOnsetDetectionOffline * * Created by Andrew Robertson on 25/12/2013. * Copyright 2013 QMUL. All rights reserved. * */ //add a retrigger threshold #include "PreciseOnsetDetectorOffline.h" PreciseOnsetDetectorOffline::PreciseOnsetDetectorOffline(){ frameSize = 1024; hopSize = 512; preciseLocator.setup(frameSize); writeOutput = true;//write output to txt when loading file - stored at sample location as file } PreciseOnsetDetectorOffline::~PreciseOnsetDetectorOffline(){ } void PreciseOnsetDetectorOffline::load(std::string filename){ //name for output file is same dir and filename as aif/wav but with _preciseOnsets.txt added //eg 'song.wav' is 'song.wav_preciseOnsets.txt' processAudioForBeatTimes(filename); } int PreciseOnsetDetectorOffline::processAudioForBeatTimes(std::string audiofile){ //originally from BeatAnnotationViewer project BeatWriter writer; dfValues.clear(); onsetLocations.clear(); onsetPositionFrames.clear(); // static double frame[FRAMESIZE]; // to hold a single frame double buffer[frameSize]; double dfval; for (int i = 0;i < frameSize;i++) { buffer[i] = 0; } //detfun = new df(1,(FRAMESIZE*2),0); // initialises with hopsize = 512, framesize = 1024, complex spectral difference DF and hanning window detectionFunction = new OnsetDetectionFunction(); SNDFILE *infile, *outfile ; // define input and output sound files SF_INFO sfinfo ; // struct to hold info about sound file int readcount ; // counts number of samples read from sound file const char *infilename = audiofile.c_str(); //"/Users/andrew/Music/Station To Station 2/3-03 Panic In Detroit (Live Nassau Coliseum '76).wav";//"ledzep.wav" ; // input file name // const char *outfilename = "output.wav" ; // output file name // Open Input File if (! (infile = sf_open (infilename, SFM_READ, &sfinfo))) { // Open failed printf ("Not able to open input file %s.\n", infilename) ; // Print the error message from libsndfile. puts (sf_strerror (NULL)) ; return 1; } ; printf("opened '%s'\n", audiofile.c_str()); loadedFilename = audiofile; //STEREO OKAY //HERE IS THE CLASSIC LOADING FILE CODE //DEALS WITH MORE THAN MONO int channels = sfinfo.channels; samples = sfinfo.frames; printf("Number of channels %i, samples %i\n", channels, samples); //for writing output std::string outputFilename = audiofile+"_preciseOnsets.txt"; if (writeOutput) writer.openFile(outputFilename); int blocksize = hopSize;//FRAMESIZE; float buf [channels * blocksize] ; float frame[blocksize]; int k, m; readcount = 1; int counter = 0; //DoubleVector d; while ((readcount = sf_readf_float (infile, buf, blocksize)) > 0){ for (k = 0 ; k < readcount ; k++){ //d.clear(); frame[k] = 0; for (m = 0 ; m < channels ; m++){ frame[k] += buf[k*channels + 0];//sum the channels together //d.push_back(buf [k * channels + m]); } frame[k] /= channels;//average of the channels } //add to our buffer for pocessing for (int i = 0; i< frameSize-hopSize;i++) { buffer[i] = buffer[i+hopSize]; buffer[i+hopSize] = frame[i]; } // for (int i = 0; i < frameSize; i++) // printf("buffer[%i] %.5f\n", i, buffer[i]); dfval = detectionFunction->getDFsample(buffer); // compute detection function sample dfValues.push_back(dfval); printf("det val %i: %f\n", counter, dfval); if (peakProcess.peakProcessing(dfval)){ printf("BANG\n"); onsetPositionFrames.push_back(counter); int precisesample = preciseLocator.findExactOnset(&buffer[0]); //so exact sample is int exactsample = (counter-1)*hopSize;//chunks in from beginning //as we have just added hopsize samples in, the beginning of the frame is -1 from counter exactsample += precisesample; //printf("PreciseSample %i, %i\n", precisesample, exactsample); if (writeOutput) writer.writeBeatTime(exactsample/44100.); onsetLocations.push_back(exactsample/44100.); } counter++; printf("read %i samples\n", readcount); //was sf_write_double(outfile, frame, readcount) ; }//end readcount //END STEREO OKAY // Close input file sf_close (infile); if (writeOutput) writer.closeFile(); delete detectionFunction; detectionFunction = NULL; return 0; } void PreciseOnsetDetectorOffline::update(){ } void PreciseOnsetDetectorOffline::draw(){ //do vizualisation in a specialised class } void PreciseOnsetDetectorOffline::printOnsetLocations(){ for (int i = 0; i < (int)onsetLocations.size(); i++) printf("Onset[%i]: %.3f\n", i, onsetLocations[i]); }