All Downloads are FREE. Search and download functionalities are using the official Maven repository.

be.tarsos.dsp.onsets.PercussionOnsetDetector Maven / Gradle / Ivy

There is a newer version: 2.4-1
Show newest version
/*
*      _______                       _____   _____ _____  
*     |__   __|                     |  __ \ / ____|  __ \ 
*        | | __ _ _ __ ___  ___  ___| |  | | (___ | |__) |
*        | |/ _` | '__/ __|/ _ \/ __| |  | |\___ \|  ___/ 
*        | | (_| | |  \__ \ (_) \__ \ |__| |____) | |     
*        |_|\__,_|_|  |___/\___/|___/_____/|_____/|_|     
*                                                         
* -------------------------------------------------------------
*
* TarsosDSP is developed by Joren Six at IPEM, University Ghent
*  
* -------------------------------------------------------------
*
*  Info: http://0110.be/tag/TarsosDSP
*  Github: https://github.com/JorenSix/TarsosDSP
*  Releases: http://0110.be/releases/TarsosDSP/
*  
*  TarsosDSP includes modified source code by various authors,
*  for credits and info, see README.
* 
*/


package be.tarsos.dsp.onsets;

import be.tarsos.dsp.AudioEvent;
import be.tarsos.dsp.AudioProcessor;
import be.tarsos.dsp.util.fft.FFT;

/**
 * 

* Estimates the locations of percussive onsets using a simple method described * in "Drum Source Separation using Percussive Feature Detection and Spectral * Modulation" by Dan Barry, Derry Fitzgerald, Eugene Coyle and Bob Lawlor, * ISSC 2005. *

*

* Implementation based on a VAMP plugin example by Chris Cannam at Queen Mary, London: * *

 *  Centre for Digital Music, Queen Mary, University of London.
 *  Copyright 2006 Chris Cannam.
 *    
 *  Permission is hereby granted, free of charge, to any person
 *  obtaining a copy of this software and associated documentation
 *  files (the "Software"), to deal in the Software without
 *  restriction, including without limitation the rights to use, copy,
 *  modify, merge, publish, distribute, sublicense, and/or sell copies
 *  of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 *  
 *  The above copyright notice and this permission notice shall be
 *  included in all copies or substantial portions of the Software.
 *  
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
 *  ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 *  CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *  
 *  Except as contained in this notice, the names of the Centre for
 *  Digital Music; Queen Mary, University of London; and Chris Cannam
 *  shall not be used in advertising or otherwise to promote the sale,
 *  use or other dealings in this Software without prior written
 *  authorization.
 * 
* *

* * @author Joren Six * @author Chris Cannam */ public class PercussionOnsetDetector implements AudioProcessor, OnsetDetector { public static final double DEFAULT_THRESHOLD = 8; public static final double DEFAULT_SENSITIVITY = 20; private final FFT fft; private final float[] priorMagnitudes; private final float[] currentMagnitudes; private float dfMinus1, dfMinus2; private OnsetHandler handler; private final float sampleRate;//samples per second (Hz) private long processedSamples;//in samples /** * Sensitivity of peak detector applied to broadband detection function (%). * In [0-100]. */ private final double sensitivity; /** * Energy rise within a frequency bin necessary to count toward broadband * total (dB). In [0-20]. * */ private final double threshold; /** * Create a new percussion onset detector. With a default sensitivity and threshold. * * @param sampleRate * The sample rate in Hz (used to calculate timestamps) * @param bufferSize * The size of the buffer in samples. * @param bufferOverlap * The overlap of buffers in samples. * @param handler * An interface implementor to handle percussion onset events. */ public PercussionOnsetDetector(float sampleRate, int bufferSize, int bufferOverlap, OnsetHandler handler) { this(sampleRate, bufferSize, handler, DEFAULT_SENSITIVITY, DEFAULT_THRESHOLD); } /** * Create a new percussion onset detector. * * @param sampleRate * The sample rate in Hz (used to calculate timestamps) * @param bufferSize * The size of the buffer in samples. * @param handler * An interface implementor to handle percussion onset events. * @param sensitivity * Sensitivity of the peak detector applied to broadband * detection function (%). In [0-100]. * @param threshold * Energy rise within a frequency bin necessary to count toward * broadband total (dB). In [0-20]. */ public PercussionOnsetDetector(float sampleRate, int bufferSize, OnsetHandler handler, double sensitivity, double threshold) { fft = new FFT(bufferSize / 2); this.threshold = threshold; this.sensitivity = sensitivity; priorMagnitudes = new float[bufferSize / 2]; currentMagnitudes = new float[bufferSize / 2]; this.handler = handler; this.sampleRate = sampleRate; } @Override public boolean process(AudioEvent audioEvent) { float[] audioFloatBuffer = audioEvent.getFloatBuffer(); this.processedSamples += audioFloatBuffer.length; this.processedSamples -= audioEvent.getOverlap(); fft.forwardTransform(audioFloatBuffer); fft.modulus(audioFloatBuffer, currentMagnitudes); int binsOverThreshold = 0; for (int i = 0; i < currentMagnitudes.length; i++) { if (priorMagnitudes[i] > 0.f) { double diff = 10 * Math.log10(currentMagnitudes[i] / priorMagnitudes[i]); if (diff >= threshold) { binsOverThreshold++; } } priorMagnitudes[i] = currentMagnitudes[i]; } if (dfMinus2 < dfMinus1 && dfMinus1 >= binsOverThreshold && dfMinus1 > ((100 - sensitivity) * audioFloatBuffer.length) / 200) { float timeStamp = processedSamples / sampleRate; handler.handleOnset(timeStamp,-1); } dfMinus2 = dfMinus1; dfMinus1 = binsOverThreshold; return true; } @Override public void processingFinished() { } @Override public void setHandler(OnsetHandler handler) { this.handler = handler; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy