adamstark@38: //======================================================================= adamstark@38: /** @file OnsetDetectionFunction.cpp adamstark@38: * @brief A class for calculating onset detection functions adamstark@38: * @author Adam Stark adamstark@38: * @copyright Copyright (C) 2008-2014 Queen Mary University of London adamstark@38: * adamstark@38: * This program is free software: you can redistribute it and/or modify adamstark@38: * it under the terms of the GNU General Public License as published by adamstark@38: * the Free Software Foundation, either version 3 of the License, or adamstark@38: * (at your option) any later version. adamstark@38: * adamstark@38: * This program is distributed in the hope that it will be useful, adamstark@38: * but WITHOUT ANY WARRANTY; without even the implied warranty of adamstark@38: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the adamstark@38: * GNU General Public License for more details. adamstark@38: * adamstark@38: * You should have received a copy of the GNU General Public License adamstark@38: * along with this program. If not, see . adamstark@38: */ adamstark@38: //======================================================================= adamstark@38: adamstark@38: #include adamstark@38: #include "OnsetDetectionFunction.h" adamstark@38: adamstark@52: //======================================================================= adamstark@38: OnsetDetectionFunction :: OnsetDetectionFunction(int arg_hsize,int arg_fsize,int arg_df_type,int arg_win_type) adamstark@38: { adamstark@38: // indicate that we have not initialised yet adamstark@38: initialised = 0; adamstark@38: adamstark@38: // set pi adamstark@38: pi = 3.14159265358979; adamstark@38: adamstark@38: // initialise with arguments to constructor adamstark@38: initialise(arg_hsize,arg_fsize,arg_df_type,arg_win_type); adamstark@38: } adamstark@38: adamstark@38: adamstark@52: //======================================================================= adamstark@38: OnsetDetectionFunction :: ~OnsetDetectionFunction() adamstark@38: { adamstark@38: // destroy fft plan adamstark@38: fftw_destroy_plan(p); adamstark@38: fftw_free(in); adamstark@38: fftw_free(out); adamstark@38: adamstark@38: // deallocate memory adamstark@38: delete [] frame; adamstark@38: frame = NULL; adamstark@38: delete [] window; adamstark@38: window = NULL; adamstark@38: delete [] wframe; adamstark@38: wframe = NULL; adamstark@38: delete [] mag; adamstark@38: mag = NULL; adamstark@38: delete [] mag_old; adamstark@38: mag_old = NULL; adamstark@38: delete [] phase; adamstark@38: phase = NULL; adamstark@38: delete [] phase_old; adamstark@38: phase_old = NULL; adamstark@38: delete [] phase_old_2; adamstark@38: phase_old_2 = NULL; adamstark@38: } adamstark@38: adamstark@52: //======================================================================= adamstark@38: void OnsetDetectionFunction :: initialise(int arg_hsize,int arg_fsize,int arg_df_type,int arg_win_type) adamstark@38: { adamstark@38: if (initialised == 1) // if we have already initialised some buffers and an FFT plan adamstark@38: { adamstark@38: ////////////////////////////////// adamstark@38: // TIDY UP FIRST - If initialise is called after the class has been initialised adamstark@38: // then we want to free up memory and cancel existing FFT plans adamstark@38: adamstark@38: // destroy fft plan adamstark@38: fftw_destroy_plan(p); adamstark@38: fftw_free(in); adamstark@38: fftw_free(out); adamstark@38: adamstark@38: adamstark@38: // deallocate memory adamstark@38: delete [] frame; adamstark@38: frame = NULL; adamstark@38: delete [] window; adamstark@38: window = NULL; adamstark@38: delete [] wframe; adamstark@38: wframe = NULL; adamstark@38: delete [] mag; adamstark@38: mag = NULL; adamstark@38: delete [] mag_old; adamstark@38: mag_old = NULL; adamstark@38: delete [] phase; adamstark@38: phase = NULL; adamstark@38: delete [] phase_old; adamstark@38: phase_old = NULL; adamstark@38: delete [] phase_old_2; adamstark@38: phase_old_2 = NULL; adamstark@38: adamstark@38: ////// END TIDY UP /////////////// adamstark@38: ////////////////////////////////// adamstark@38: } adamstark@38: adamstark@38: hopsize = arg_hsize; // set hopsize adamstark@38: framesize = arg_fsize; // set framesize adamstark@38: adamstark@38: df_type = arg_df_type; // set detection function type adamstark@38: adamstark@38: // initialise buffers adamstark@38: frame = new double[framesize]; adamstark@38: window = new double[framesize]; adamstark@38: wframe = new double[framesize]; adamstark@38: adamstark@38: mag = new double[framesize]; adamstark@38: mag_old = new double[framesize]; adamstark@38: adamstark@38: phase = new double[framesize]; adamstark@38: phase_old = new double[framesize]; adamstark@38: phase_old_2 = new double[framesize]; adamstark@38: adamstark@38: adamstark@38: // set the window to the specified type adamstark@38: switch (arg_win_type){ adamstark@57: case RectangularWindow: adamstark@38: set_win_rectangular(); // Rectangular window adamstark@38: break; adamstark@57: case HanningWindow: adamstark@38: set_win_hanning(); // Hanning Window adamstark@38: break; adamstark@57: case HammingWindow: adamstark@38: set_win_hamming(); // Hamming Window adamstark@38: break; adamstark@57: case BlackmanWindow: adamstark@38: set_win_blackman(); // Blackman Window adamstark@38: break; adamstark@57: case TukeyWindow: adamstark@38: set_win_tukey(); // Tukey Window adamstark@38: break; adamstark@38: default: adamstark@38: set_win_hanning(); // DEFAULT: Hanning Window adamstark@38: } adamstark@38: adamstark@38: adamstark@38: adamstark@38: adamstark@38: // initialise previous magnitude spectrum to zero adamstark@38: for (int i = 0;i < framesize;i++) adamstark@38: { adamstark@38: mag_old[i] = 0.0; adamstark@38: phase_old[i] = 0.0; adamstark@38: phase_old_2[i] = 0.0; adamstark@38: frame[i] = 0.0; adamstark@38: } adamstark@38: adamstark@38: energy_sum_old = 0.0; // initialise previous energy sum value to zero adamstark@38: adamstark@38: /* Init fft */ adamstark@38: in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * framesize); // complex array to hold fft data adamstark@38: out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * framesize); // complex array to hold fft data adamstark@38: p = fftw_plan_dft_1d(framesize, in, out, FFTW_FORWARD, FFTW_ESTIMATE); // FFT plan initialisation adamstark@38: adamstark@38: initialised = 1; adamstark@38: } adamstark@38: adamstark@52: //======================================================================= adamstark@38: void OnsetDetectionFunction :: set_df_type(int arg_df_type) adamstark@38: { adamstark@38: df_type = arg_df_type; // set detection function type adamstark@38: } adamstark@38: adamstark@52: //======================================================================= adamstark@53: double OnsetDetectionFunction :: getDFsample(double *inputbuffer) adamstark@38: { adamstark@38: double df_sample; adamstark@38: adamstark@38: // shift audio samples back in frame by hop size adamstark@38: for (int i = 0; i < (framesize-hopsize);i++) adamstark@38: { adamstark@38: frame[i] = frame[i+hopsize]; adamstark@38: } adamstark@38: adamstark@38: // add new samples to frame from input buffer adamstark@38: int j = 0; adamstark@38: for (int i = (framesize-hopsize);i < framesize;i++) adamstark@38: { adamstark@38: frame[i] = inputbuffer[j]; adamstark@38: j++; adamstark@38: } adamstark@38: adamstark@38: switch (df_type){ adamstark@57: case EnergyEnvelope: adamstark@57: { adamstark@57: // calculate energy envelope detection function sample adamstark@57: df_sample = energy_envelope(); adamstark@38: break; adamstark@57: } adamstark@57: case EnergyDifference: adamstark@57: { adamstark@57: // calculate half-wave rectified energy difference detection function sample adamstark@57: df_sample = energy_difference(); adamstark@38: break; adamstark@57: } adamstark@57: case SpectralDifference: adamstark@57: { adamstark@57: // calculate spectral difference detection function sample adamstark@57: df_sample = spectral_difference(); adamstark@38: break; adamstark@57: } adamstark@57: case SpectralDifferenceHWR: adamstark@57: { adamstark@57: // calculate spectral difference detection function sample (half wave rectified) adamstark@57: df_sample = spectral_difference_hwr(); adamstark@38: break; adamstark@57: } adamstark@57: case PhaseDeviation: adamstark@57: { adamstark@57: // calculate phase deviation detection function sample (half wave rectified) adamstark@57: df_sample = phase_deviation(); adamstark@38: break; adamstark@57: } adamstark@57: case ComplexSpectralDifference: adamstark@57: { adamstark@57: // calcualte complex spectral difference detection function sample adamstark@57: df_sample = complex_spectral_difference(); adamstark@38: break; adamstark@57: } adamstark@57: case ComplexSpectralDifferenceHWR: adamstark@57: { adamstark@57: // calcualte complex spectral difference detection function sample (half-wave rectified) adamstark@57: df_sample = complex_spectral_difference_hwr(); adamstark@38: break; adamstark@57: } adamstark@57: case HighFrequencyContent: adamstark@57: { adamstark@57: // calculate high frequency content detection function sample adamstark@57: df_sample = high_frequency_content(); adamstark@38: break; adamstark@57: } adamstark@57: case HighFrequencySpectralDifference: adamstark@57: { adamstark@57: // calculate high frequency spectral difference detection function sample adamstark@57: df_sample = high_frequency_spectral_difference(); adamstark@38: break; adamstark@57: } adamstark@57: case HighFrequencySpectralDifferenceHWR: adamstark@57: { adamstark@57: // calculate high frequency spectral difference detection function (half-wave rectified) adamstark@57: df_sample = high_frequency_spectral_difference_hwr(); adamstark@57: break; adamstark@57: } adamstark@38: default: adamstark@57: { adamstark@38: df_sample = 1.0; adamstark@57: } adamstark@38: } adamstark@38: adamstark@38: return df_sample; adamstark@38: } adamstark@38: adamstark@38: adamstark@52: //======================================================================= adamstark@38: void OnsetDetectionFunction :: perform_FFT() adamstark@38: { adamstark@38: int fsize2 = (framesize/2); adamstark@38: adamstark@38: // window frame and copy to complex array, swapping the first and second half of the signal adamstark@38: for (int i = 0;i < fsize2;i++) adamstark@38: { adamstark@38: in[i][0] = frame[i+fsize2] * window[i+fsize2]; adamstark@38: in[i][1] = 0.0; adamstark@38: in[i+fsize2][0] = frame[i] * window[i]; adamstark@38: in[i+fsize2][1] = 0.0; adamstark@38: } adamstark@38: adamstark@38: // perform the fft adamstark@38: fftw_execute(p); adamstark@38: } adamstark@38: adamstark@38: //////////////////////////////////////////////////////////////////////////////////////////////// adamstark@38: //////////////////////////////////////////////////////////////////////////////////////////////// adamstark@38: ////////////////////////////// Methods for Detection Functions ///////////////////////////////// adamstark@38: adamstark@52: //======================================================================= adamstark@38: double OnsetDetectionFunction :: energy_envelope() adamstark@38: { adamstark@38: double sum; adamstark@38: adamstark@38: sum = 0; // initialise sum adamstark@38: adamstark@38: // sum the squares of the samples adamstark@38: for (int i = 0;i < framesize;i++) adamstark@38: { adamstark@38: sum = sum + (frame[i]*frame[i]); adamstark@38: } adamstark@38: adamstark@38: return sum; // return sum adamstark@38: } adamstark@38: adamstark@52: //======================================================================= adamstark@38: double OnsetDetectionFunction :: energy_difference() adamstark@38: { adamstark@38: double sum; adamstark@38: double sample; adamstark@38: adamstark@38: sum = 0; // initialise sum adamstark@38: adamstark@38: // sum the squares of the samples adamstark@38: for (int i = 0;i < framesize;i++) adamstark@38: { adamstark@38: sum = sum + (frame[i]*frame[i]); adamstark@38: } adamstark@38: adamstark@38: sample = sum - energy_sum_old; // sample is first order difference in energy adamstark@38: adamstark@38: energy_sum_old = sum; // store energy value for next calculation adamstark@38: adamstark@38: if (sample > 0) adamstark@38: { adamstark@38: return sample; // return difference adamstark@38: } adamstark@38: else adamstark@38: { adamstark@38: return 0; adamstark@38: } adamstark@38: } adamstark@38: adamstark@52: //======================================================================= adamstark@38: double OnsetDetectionFunction :: spectral_difference() adamstark@38: { adamstark@38: double diff; adamstark@38: double sum; adamstark@38: adamstark@38: // perform the FFT adamstark@38: perform_FFT(); adamstark@38: adamstark@38: // compute first (N/2)+1 mag values adamstark@38: for (int i = 0;i < (framesize/2)+1;i++) adamstark@38: { adamstark@38: mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2)); adamstark@38: } adamstark@38: // mag spec symmetric above (N/2)+1 so copy previous values adamstark@38: for (int i = (framesize/2)+1;i < framesize;i++) adamstark@38: { adamstark@38: mag[i] = mag[framesize-i]; adamstark@38: } adamstark@38: adamstark@38: sum = 0; // initialise sum to zero adamstark@38: adamstark@38: for (int i = 0;i < framesize;i++) adamstark@38: { adamstark@38: // calculate difference adamstark@38: diff = mag[i] - mag_old[i]; adamstark@38: adamstark@38: // ensure all difference values are positive adamstark@38: if (diff < 0) adamstark@38: { adamstark@38: diff = diff*-1; adamstark@38: } adamstark@38: adamstark@38: // add difference to sum adamstark@38: sum = sum+diff; adamstark@38: adamstark@38: // store magnitude spectrum bin for next detection function sample calculation adamstark@38: mag_old[i] = mag[i]; adamstark@38: } adamstark@38: adamstark@38: return sum; adamstark@38: } adamstark@38: adamstark@52: //======================================================================= adamstark@38: double OnsetDetectionFunction :: spectral_difference_hwr() adamstark@38: { adamstark@38: double diff; adamstark@38: double sum; adamstark@38: adamstark@38: // perform the FFT adamstark@38: perform_FFT(); adamstark@38: adamstark@38: // compute first (N/2)+1 mag values adamstark@38: for (int i = 0;i < (framesize/2)+1;i++) adamstark@38: { adamstark@38: mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2)); adamstark@38: } adamstark@38: // mag spec symmetric above (N/2)+1 so copy previous values adamstark@38: for (int i = (framesize/2)+1;i < framesize;i++) adamstark@38: { adamstark@38: mag[i] = mag[framesize-i]; adamstark@38: } adamstark@38: adamstark@38: sum = 0; // initialise sum to zero adamstark@38: adamstark@38: for (int i = 0;i < framesize;i++) adamstark@38: { adamstark@38: // calculate difference adamstark@38: diff = mag[i] - mag_old[i]; adamstark@38: adamstark@38: // only add up positive differences adamstark@38: if (diff > 0) adamstark@38: { adamstark@38: // add difference to sum adamstark@38: sum = sum+diff; adamstark@38: } adamstark@38: adamstark@38: adamstark@38: adamstark@38: // store magnitude spectrum bin for next detection function sample calculation adamstark@38: mag_old[i] = mag[i]; adamstark@38: } adamstark@38: adamstark@38: return sum; adamstark@38: } adamstark@38: adamstark@38: adamstark@52: //======================================================================= adamstark@38: double OnsetDetectionFunction :: phase_deviation() adamstark@38: { adamstark@38: double dev,pdev; adamstark@38: double sum; adamstark@38: adamstark@38: // perform the FFT adamstark@38: perform_FFT(); adamstark@38: adamstark@38: sum = 0; // initialise sum to zero adamstark@38: adamstark@38: // compute phase values from fft output and sum deviations adamstark@38: for (int i = 0;i < framesize;i++) adamstark@38: { adamstark@38: // calculate phase value adamstark@38: phase[i] = atan2(out[i][1],out[i][0]); adamstark@38: adamstark@38: // calculate magnitude value adamstark@38: mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2)); adamstark@38: adamstark@38: adamstark@38: // if bin is not just a low energy bin then examine phase deviation adamstark@38: if (mag[i] > 0.1) adamstark@38: { adamstark@38: dev = phase[i] - (2*phase_old[i]) + phase_old_2[i]; // phase deviation adamstark@38: pdev = princarg(dev); // wrap into [-pi,pi] range adamstark@38: adamstark@38: // make all values positive adamstark@38: if (pdev < 0) adamstark@38: { adamstark@38: pdev = pdev*-1; adamstark@38: } adamstark@38: adamstark@38: // add to sum adamstark@38: sum = sum + pdev; adamstark@38: } adamstark@38: adamstark@38: // store values for next calculation adamstark@38: phase_old_2[i] = phase_old[i]; adamstark@38: phase_old[i] = phase[i]; adamstark@38: } adamstark@38: adamstark@38: return sum; adamstark@38: } adamstark@38: adamstark@52: //======================================================================= adamstark@38: double OnsetDetectionFunction :: complex_spectral_difference() adamstark@38: { adamstark@38: double dev,pdev; adamstark@38: double sum; adamstark@38: double mag_diff,phase_diff; adamstark@38: double value; adamstark@38: adamstark@38: // perform the FFT adamstark@38: perform_FFT(); adamstark@38: adamstark@38: sum = 0; // initialise sum to zero adamstark@38: adamstark@38: // compute phase values from fft output and sum deviations adamstark@38: for (int i = 0;i < framesize;i++) adamstark@38: { adamstark@38: // calculate phase value adamstark@38: phase[i] = atan2(out[i][1],out[i][0]); adamstark@38: adamstark@38: // calculate magnitude value adamstark@38: mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2)); adamstark@38: adamstark@38: adamstark@38: // phase deviation adamstark@38: dev = phase[i] - (2*phase_old[i]) + phase_old_2[i]; adamstark@38: adamstark@38: // wrap into [-pi,pi] range adamstark@38: pdev = princarg(dev); adamstark@38: adamstark@38: adamstark@38: // calculate magnitude difference (real part of Euclidean distance between complex frames) adamstark@38: mag_diff = mag[i] - mag_old[i]; adamstark@38: adamstark@38: // calculate phase difference (imaginary part of Euclidean distance between complex frames) adamstark@38: phase_diff = -mag[i]*sin(pdev); adamstark@38: adamstark@38: adamstark@38: adamstark@38: // square real and imaginary parts, sum and take square root adamstark@38: value = sqrt(pow(mag_diff,2) + pow(phase_diff,2)); adamstark@38: adamstark@38: adamstark@38: // add to sum adamstark@38: sum = sum + value; adamstark@38: adamstark@38: adamstark@38: // store values for next calculation adamstark@38: phase_old_2[i] = phase_old[i]; adamstark@38: phase_old[i] = phase[i]; adamstark@38: mag_old[i] = mag[i]; adamstark@38: } adamstark@38: adamstark@38: return sum; adamstark@38: } adamstark@38: adamstark@52: //======================================================================= adamstark@38: double OnsetDetectionFunction :: complex_spectral_difference_hwr() adamstark@38: { adamstark@38: double dev,pdev; adamstark@38: double sum; adamstark@38: double mag_diff,phase_diff; adamstark@38: double value; adamstark@38: adamstark@38: // perform the FFT adamstark@38: perform_FFT(); adamstark@38: adamstark@38: sum = 0; // initialise sum to zero adamstark@38: adamstark@38: // compute phase values from fft output and sum deviations adamstark@38: for (int i = 0;i < framesize;i++) adamstark@38: { adamstark@38: // calculate phase value adamstark@38: phase[i] = atan2(out[i][1],out[i][0]); adamstark@38: adamstark@38: // calculate magnitude value adamstark@38: mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2)); adamstark@38: adamstark@38: adamstark@38: // phase deviation adamstark@38: dev = phase[i] - (2*phase_old[i]) + phase_old_2[i]; adamstark@38: adamstark@38: // wrap into [-pi,pi] range adamstark@38: pdev = princarg(dev); adamstark@38: adamstark@38: adamstark@38: // calculate magnitude difference (real part of Euclidean distance between complex frames) adamstark@38: mag_diff = mag[i] - mag_old[i]; adamstark@38: adamstark@38: // if we have a positive change in magnitude, then include in sum, otherwise ignore (half-wave rectification) adamstark@38: if (mag_diff > 0) adamstark@38: { adamstark@38: // calculate phase difference (imaginary part of Euclidean distance between complex frames) adamstark@38: phase_diff = -mag[i]*sin(pdev); adamstark@38: adamstark@38: // square real and imaginary parts, sum and take square root adamstark@38: value = sqrt(pow(mag_diff,2) + pow(phase_diff,2)); adamstark@38: adamstark@38: // add to sum adamstark@38: sum = sum + value; adamstark@38: } adamstark@38: adamstark@38: // store values for next calculation adamstark@38: phase_old_2[i] = phase_old[i]; adamstark@38: phase_old[i] = phase[i]; adamstark@38: mag_old[i] = mag[i]; adamstark@38: } adamstark@38: adamstark@38: return sum; adamstark@38: } adamstark@38: adamstark@38: adamstark@52: //======================================================================= adamstark@38: double OnsetDetectionFunction :: high_frequency_content() adamstark@38: { adamstark@38: double sum; adamstark@38: adamstark@38: // perform the FFT adamstark@38: perform_FFT(); adamstark@38: adamstark@38: sum = 0; // initialise sum to zero adamstark@38: adamstark@38: // compute phase values from fft output and sum deviations adamstark@38: for (int i = 0;i < framesize;i++) adamstark@38: { adamstark@38: // calculate magnitude value adamstark@38: mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2)); adamstark@38: adamstark@38: adamstark@38: sum = sum + (mag[i]*((double) (i+1))); adamstark@38: adamstark@38: // store values for next calculation adamstark@38: mag_old[i] = mag[i]; adamstark@38: } adamstark@38: adamstark@38: return sum; adamstark@38: } adamstark@38: adamstark@52: //======================================================================= adamstark@38: double OnsetDetectionFunction :: high_frequency_spectral_difference() adamstark@38: { adamstark@38: double sum; adamstark@38: double mag_diff; adamstark@38: adamstark@38: // perform the FFT adamstark@38: perform_FFT(); adamstark@38: adamstark@38: sum = 0; // initialise sum to zero adamstark@38: adamstark@38: // compute phase values from fft output and sum deviations adamstark@38: for (int i = 0;i < framesize;i++) adamstark@38: { adamstark@38: // calculate magnitude value adamstark@38: mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2)); adamstark@38: adamstark@38: // calculate difference adamstark@38: mag_diff = mag[i] - mag_old[i]; adamstark@38: adamstark@38: if (mag_diff < 0) adamstark@38: { adamstark@38: mag_diff = -mag_diff; adamstark@38: } adamstark@38: adamstark@38: sum = sum + (mag_diff*((double) (i+1))); adamstark@38: adamstark@38: // store values for next calculation adamstark@38: mag_old[i] = mag[i]; adamstark@38: } adamstark@38: adamstark@38: return sum; adamstark@38: } adamstark@38: adamstark@52: //======================================================================= adamstark@38: double OnsetDetectionFunction :: high_frequency_spectral_difference_hwr() adamstark@38: { adamstark@38: double sum; adamstark@38: double mag_diff; adamstark@38: adamstark@38: // perform the FFT adamstark@38: perform_FFT(); adamstark@38: adamstark@38: sum = 0; // initialise sum to zero adamstark@38: adamstark@38: // compute phase values from fft output and sum deviations adamstark@38: for (int i = 0;i < framesize;i++) adamstark@38: { adamstark@38: // calculate magnitude value adamstark@38: mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2)); adamstark@38: adamstark@38: // calculate difference adamstark@38: mag_diff = mag[i] - mag_old[i]; adamstark@38: adamstark@38: if (mag_diff > 0) adamstark@38: { adamstark@38: sum = sum + (mag_diff*((double) (i+1))); adamstark@38: } adamstark@38: adamstark@38: // store values for next calculation adamstark@38: mag_old[i] = mag[i]; adamstark@38: } adamstark@38: adamstark@38: return sum; adamstark@38: } adamstark@38: adamstark@38: adamstark@38: //////////////////////////////////////////////////////////////////////////////////////////////// adamstark@38: //////////////////////////////////////////////////////////////////////////////////////////////// adamstark@38: ////////////////////////////// Methods to Calculate Windows //////////////////////////////////// adamstark@38: adamstark@52: //======================================================================= adamstark@38: void OnsetDetectionFunction :: set_win_hanning() adamstark@38: { adamstark@38: double N; // variable to store framesize minus 1 adamstark@38: adamstark@38: N = (double) (framesize-1); // framesize minus 1 adamstark@38: adamstark@38: // Hanning window calculation adamstark@38: for (int n = 0;n < framesize;n++) adamstark@38: { adamstark@38: window[n] = 0.5*(1-cos(2*pi*(n/N))); adamstark@38: } adamstark@38: } adamstark@38: adamstark@52: //======================================================================= adamstark@38: void OnsetDetectionFunction :: set_win_hamming() adamstark@38: { adamstark@38: double N; // variable to store framesize minus 1 adamstark@38: double n_val; // double version of index 'n' adamstark@38: adamstark@38: N = (double) (framesize-1); // framesize minus 1 adamstark@38: n_val = 0; adamstark@38: adamstark@38: // Hamming window calculation adamstark@38: for (int n = 0;n < framesize;n++) adamstark@38: { adamstark@38: window[n] = 0.54 - (0.46*cos(2*pi*(n_val/N))); adamstark@38: n_val = n_val+1; adamstark@38: } adamstark@38: } adamstark@38: adamstark@52: //======================================================================= adamstark@38: void OnsetDetectionFunction :: set_win_blackman() adamstark@38: { adamstark@38: double N; // variable to store framesize minus 1 adamstark@38: double n_val; // double version of index 'n' adamstark@38: adamstark@38: N = (double) (framesize-1); // framesize minus 1 adamstark@38: n_val = 0; adamstark@38: adamstark@38: // Blackman window calculation adamstark@38: for (int n = 0;n < framesize;n++) adamstark@38: { adamstark@38: window[n] = 0.42 - (0.5*cos(2*pi*(n_val/N))) + (0.08*cos(4*pi*(n_val/N))); adamstark@38: n_val = n_val+1; adamstark@38: } adamstark@38: } adamstark@38: adamstark@52: //======================================================================= adamstark@38: void OnsetDetectionFunction :: set_win_tukey() adamstark@38: { adamstark@38: double N; // variable to store framesize minus 1 adamstark@38: double n_val; // double version of index 'n' adamstark@38: double alpha; // alpha [default value = 0.5]; adamstark@38: adamstark@38: alpha = 0.5; adamstark@38: adamstark@38: N = (double) (framesize-1); // framesize minus 1 adamstark@38: adamstark@38: // Tukey window calculation adamstark@38: adamstark@38: n_val = (double) (-1*((framesize/2)))+1; adamstark@38: adamstark@38: for (int n = 0;n < framesize;n++) // left taper adamstark@38: { adamstark@38: if ((n_val >= 0) && (n_val <= (alpha*(N/2)))) adamstark@38: { adamstark@38: window[n] = 1.0; adamstark@38: } adamstark@38: else if ((n_val <= 0) && (n_val >= (-1*alpha*(N/2)))) adamstark@38: { adamstark@38: window[n] = 1.0; adamstark@38: } adamstark@38: else adamstark@38: { adamstark@38: window[n] = 0.5*(1+cos(pi*(((2*n_val)/(alpha*N))-1))); adamstark@38: } adamstark@38: adamstark@38: n_val = n_val+1; adamstark@38: } adamstark@38: adamstark@38: } adamstark@38: adamstark@52: //======================================================================= adamstark@38: void OnsetDetectionFunction :: set_win_rectangular() adamstark@38: { adamstark@38: // Rectangular window calculation adamstark@38: for (int n = 0;n < framesize;n++) adamstark@38: { adamstark@38: window[n] = 1.0; adamstark@38: } adamstark@38: } adamstark@38: adamstark@38: adamstark@38: adamstark@38: //////////////////////////////////////////////////////////////////////////////////////////////// adamstark@38: //////////////////////////////////////////////////////////////////////////////////////////////// adamstark@38: ///////////////////////////////// Other Handy Methods ////////////////////////////////////////// adamstark@38: adamstark@52: //======================================================================= adamstark@38: double OnsetDetectionFunction :: princarg(double phaseval) adamstark@38: { adamstark@38: // if phase value is less than or equal to -pi then add 2*pi adamstark@38: while (phaseval <= (-pi)) adamstark@38: { adamstark@38: phaseval = phaseval + (2*pi); adamstark@38: } adamstark@38: adamstark@38: // if phase value is larger than pi, then subtract 2*pi adamstark@38: while (phaseval > pi) adamstark@38: { adamstark@38: phaseval = phaseval - (2*pi); adamstark@38: } adamstark@38: adamstark@38: return phaseval; adamstark@38: } adamstark@38: adamstark@38: adamstark@38: adamstark@38: adamstark@38: adamstark@38: adamstark@38: adamstark@38: adamstark@38: adamstark@38: adamstark@38: adamstark@38: adamstark@38: